Merge tag 'wireless-drivers-for-davem-2015-11-20' of git://git.kernel.org/pub/scm...
authorDavid S. Miller <davem@davemloft.net>
Mon, 23 Nov 2015 01:40:22 +0000 (20:40 -0500)
committerDavid S. Miller <davem@davemloft.net>
Mon, 23 Nov 2015 01:40:22 +0000 (20:40 -0500)
Kalle Valo says:

====================
iwlwifi

* bump API to firmware 19 - not released yet.
* fix D3 flows (Luca)
* new device IDs (Oren)
* fix NULL pointer dereference (Avri)

ath10k

* fix invalid NSS for 4x4 devices
* add QCA9377 hw1.0 support
* fix QCA6174 regression with CE5 usage

wil6210

* new maintainer - Maya Erez

rtlwifi

* rtl8821ae: Fix lockups on boot
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
864 files changed:
Documentation/ABI/testing/sysfs-driver-st [new file with mode: 0644]
Documentation/SubmittingPatches
Documentation/devicetree/bindings/input/touchscreen/tsc2005.txt
Documentation/devicetree/bindings/mips/img/xilfpga.txt [new file with mode: 0644]
Documentation/devicetree/bindings/pwm/brcm,bcm7038-pwm.txt [new file with mode: 0644]
Documentation/devicetree/bindings/pwm/pwm-berlin.txt [new file with mode: 0644]
Documentation/devicetree/bindings/pwm/pwm-mtk-disp.txt [new file with mode: 0644]
Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
Documentation/devicetree/bindings/pwm/renesas,pwm-rcar.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/ak4554.c [deleted file]
Documentation/devicetree/bindings/sound/ak4554.txt [new file with mode: 0644]
Documentation/devicetree/bindings/thermal/rockchip-thermal.txt
Documentation/devicetree/bindings/thermal/ti_soc_thermal.txt
Documentation/devicetree/bindings/ufs/ufs-qcom.txt [new file with mode: 0644]
Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
Documentation/dontdiff
Documentation/email-clients.txt
Documentation/filesystems/Makefile
Documentation/filesystems/configfs/Makefile [deleted file]
Documentation/filesystems/configfs/configfs.txt
Documentation/filesystems/configfs/configfs_example_explicit.c [deleted file]
Documentation/filesystems/configfs/configfs_example_macros.c [deleted file]
Documentation/filesystems/overlayfs.txt
Documentation/networking/can.txt
Documentation/nvdimm/nvdimm.txt
Documentation/scsi/st.txt
Documentation/target/tcm_mod_builder.py
MAINTAINERS
Makefile
arch/arc/include/asm/processor.h
arch/arc/kernel/entry-arcv2.S
arch/arc/kernel/entry-compact.S
arch/arc/kernel/entry.S
arch/arc/lib/memcpy-archs.S
arch/arc/mm/tlbex.S
arch/arc/plat-sim/platform.c
arch/arm64/Kconfig
arch/arm64/Kconfig.debug
arch/arm64/configs/defconfig
arch/arm64/include/asm/atomic_ll_sc.h
arch/arm64/include/asm/atomic_lse.h
arch/arm64/include/asm/pgtable.h
arch/arm64/include/uapi/asm/kvm.h
arch/arm64/kernel/cpufeature.c
arch/arm64/kernel/smp.c
arch/arm64/kernel/suspend.c
arch/arm64/kernel/vdso/Makefile
arch/arm64/mm/mmu.c
arch/arm64/net/bpf_jit.h
arch/arm64/net/bpf_jit_comp.c
arch/h8300/Kconfig
arch/h8300/Makefile
arch/h8300/boot/compressed/Makefile
arch/h8300/boot/compressed/head.S
arch/h8300/boot/compressed/misc.c
arch/h8300/boot/compressed/vmlinux.lds
arch/h8300/boot/dts/edosk2674.dts
arch/h8300/include/asm/io.h
arch/h8300/include/asm/thread_info.h
arch/h8300/kernel/setup.c
arch/h8300/kernel/vmlinux.lds.S
arch/mips/Kbuild
arch/mips/Kbuild.platforms
arch/mips/Kconfig
arch/mips/Kconfig.debug
arch/mips/Makefile
arch/mips/bcm47xx/setup.c
arch/mips/bcm47xx/sprom.c
arch/mips/bcm63xx/boards/board_bcm963xx.c
arch/mips/bcm63xx/cpu.c
arch/mips/bcm63xx/dev-pcmcia.c
arch/mips/bcm63xx/irq.c
arch/mips/bcm63xx/setup.c
arch/mips/bcm63xx/timer.c
arch/mips/bmips/setup.c
arch/mips/boot/dts/Makefile
arch/mips/boot/dts/brcm/bcm7346.dtsi
arch/mips/boot/dts/brcm/bcm7358.dtsi
arch/mips/boot/dts/brcm/bcm7360.dtsi
arch/mips/boot/dts/brcm/bcm7362.dtsi
arch/mips/boot/dts/brcm/bcm7425.dtsi
arch/mips/boot/dts/brcm/bcm97346dbsmb.dts
arch/mips/boot/dts/brcm/bcm97358svmb.dts
arch/mips/boot/dts/brcm/bcm97360svmb.dts
arch/mips/boot/dts/brcm/bcm97362svmb.dts
arch/mips/boot/dts/mti/malta.dts
arch/mips/boot/dts/xilfpga/Makefile [new file with mode: 0644]
arch/mips/boot/dts/xilfpga/microAptiv.dtsi [new file with mode: 0644]
arch/mips/boot/dts/xilfpga/nexys4ddr.dts [new file with mode: 0644]
arch/mips/cavium-octeon/setup.c
arch/mips/configs/bigsur_defconfig
arch/mips/configs/bmips_be_defconfig
arch/mips/configs/bmips_stb_defconfig
arch/mips/configs/capcella_defconfig
arch/mips/configs/e55_defconfig
arch/mips/configs/fuloong2e_defconfig
arch/mips/configs/lasat_defconfig
arch/mips/configs/lemote2f_defconfig
arch/mips/configs/malta_defconfig
arch/mips/configs/malta_kvm_defconfig
arch/mips/configs/malta_kvm_guest_defconfig
arch/mips/configs/malta_qemu_32r6_defconfig
arch/mips/configs/maltaaprp_defconfig
arch/mips/configs/maltasmvp_eva_defconfig
arch/mips/configs/maltaup_defconfig
arch/mips/configs/maltaup_xpa_defconfig
arch/mips/configs/mpc30x_defconfig
arch/mips/configs/xilfpga_defconfig [new file with mode: 0644]
arch/mips/include/asm/abi.h
arch/mips/include/asm/atomic.h
arch/mips/include/asm/bcache.h
arch/mips/include/asm/cdmm.h
arch/mips/include/asm/clocksource.h [new file with mode: 0644]
arch/mips/include/asm/compat.h
arch/mips/include/asm/cpu-features.h
arch/mips/include/asm/debug.h [new file with mode: 0644]
arch/mips/include/asm/elf.h
arch/mips/include/asm/fw/fw.h
arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
arch/mips/include/asm/mach-malta/malta-dtshim.h [new file with mode: 0644]
arch/mips/include/asm/mach-ralink/mt7620.h
arch/mips/include/asm/mach-ralink/ralink_regs.h
arch/mips/include/asm/mach-ralink/rt305x.h
arch/mips/include/asm/mach-xilfpga/irq.h [new file with mode: 0644]
arch/mips/include/asm/mips-cm.h
arch/mips/include/asm/mips-cpc.h
arch/mips/include/asm/mipsregs.h
arch/mips/include/asm/page.h
arch/mips/include/asm/processor.h
arch/mips/include/asm/vdso.h
arch/mips/include/uapi/asm/Kbuild
arch/mips/include/uapi/asm/auxvec.h [new file with mode: 0644]
arch/mips/jz4740/board-qi_lb60.c
arch/mips/kernel/Makefile
arch/mips/kernel/cps-vec-ns16550.S [new file with mode: 0644]
arch/mips/kernel/cps-vec.S
arch/mips/kernel/cpu-probe.c
arch/mips/kernel/csrc-r4k.c
arch/mips/kernel/idle.c
arch/mips/kernel/mips-cm.c
arch/mips/kernel/mips-cpc.c
arch/mips/kernel/mips-r2-to-r6-emul.c
arch/mips/kernel/segment.c
arch/mips/kernel/setup.c
arch/mips/kernel/signal.c
arch/mips/kernel/signal32.c
arch/mips/kernel/signal_n32.c
arch/mips/kernel/smp-cps.c
arch/mips/kernel/smp-gic.c
arch/mips/kernel/spinlock_test.c
arch/mips/kernel/stacktrace.c
arch/mips/kernel/traps.c
arch/mips/kernel/unaligned.c
arch/mips/kernel/vdso.c
arch/mips/kernel/vmlinux.lds.S
arch/mips/kvm/locore.S
arch/mips/lantiq/clk.c
arch/mips/lantiq/clk.h
arch/mips/lantiq/irq.c
arch/mips/lantiq/prom.c
arch/mips/lantiq/xway/clk.c
arch/mips/lantiq/xway/prom.c
arch/mips/lantiq/xway/reset.c
arch/mips/lantiq/xway/sysctrl.c
arch/mips/lib/Makefile
arch/mips/lib/bswapdi.c [new file with mode: 0644]
arch/mips/lib/bswapsi.c [new file with mode: 0644]
arch/mips/loongson64/Kconfig
arch/mips/loongson64/common/Makefile
arch/mips/loongson64/lemote-2f/Makefile
arch/mips/math-emu/me-debugfs.c
arch/mips/mm/Makefile
arch/mips/mm/sc-debugfs.c [new file with mode: 0644]
arch/mips/mm/sc-mips.c
arch/mips/mm/tlbex.c
arch/mips/mti-malta/Makefile
arch/mips/mti-malta/malta-dtshim.c [new file with mode: 0644]
arch/mips/mti-malta/malta-init.c
arch/mips/mti-malta/malta-memory.c
arch/mips/mti-malta/malta-setup.c
arch/mips/netlogic/xlp/dt.c
arch/mips/pci/pci-rt3883.c
arch/mips/pistachio/init.c
arch/mips/ralink/cevt-rt3352.c
arch/mips/ralink/early_printk.c
arch/mips/ralink/mt7620.c
arch/mips/ralink/of.c
arch/mips/ralink/prom.c
arch/mips/ralink/reset.c
arch/mips/ralink/rt288x.c
arch/mips/ralink/rt305x.c
arch/mips/ralink/rt3883.c
arch/mips/vdso/.gitignore [new file with mode: 0644]
arch/mips/vdso/Makefile [new file with mode: 0644]
arch/mips/vdso/elf.S [new file with mode: 0644]
arch/mips/vdso/genvdso.c [new file with mode: 0644]
arch/mips/vdso/genvdso.h [new file with mode: 0644]
arch/mips/vdso/gettimeofday.c [new file with mode: 0644]
arch/mips/vdso/sigreturn.S [new file with mode: 0644]
arch/mips/vdso/vdso.h [new file with mode: 0644]
arch/mips/vdso/vdso.lds.S [new file with mode: 0644]
arch/mips/xilfpga/Kconfig [new file with mode: 0644]
arch/mips/xilfpga/Makefile [new file with mode: 0644]
arch/mips/xilfpga/Platform [new file with mode: 0644]
arch/mips/xilfpga/init.c [new file with mode: 0644]
arch/mips/xilfpga/intc.c [new file with mode: 0644]
arch/mips/xilfpga/time.c [new file with mode: 0644]
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/kvm/book3s_hv_rmhandlers.S
arch/s390/include/asm/cio.h
arch/s390/include/asm/elf.h
arch/s390/include/asm/ipl.h
arch/s390/include/asm/pci_dma.h
arch/s390/include/asm/trace/diag.h
arch/s390/include/uapi/asm/unistd.h
arch/s390/kernel/compat_wrapper.c
arch/s390/kernel/diag.c
arch/s390/kernel/head.S
arch/s390/kernel/ipl.c
arch/s390/kernel/process.c
arch/s390/kernel/sclp.c
arch/s390/kernel/setup.c
arch/s390/kernel/syscalls.S
arch/s390/kernel/trace.c
arch/s390/mm/init.c
arch/s390/mm/mmap.c
arch/s390/pci/pci_dma.c
arch/unicore32/kernel/puv3-nb0916.c
arch/x86/include/asm/i8259.h
arch/x86/include/asm/kvm_host.h
arch/x86/include/asm/vmx.h
arch/x86/include/uapi/asm/svm.h
arch/x86/kernel/apic/vector.c
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/cpu/intel.c
arch/x86/kernel/cpu/perf_event_intel_rapl.c
arch/x86/kernel/head_64.S
arch/x86/kernel/i8259.c
arch/x86/kernel/setup.c
arch/x86/kernel/verify_cpu.S
arch/x86/kvm/lapic.c
arch/x86/kvm/mmu.c
arch/x86/kvm/mmu.h
arch/x86/kvm/paging_tmpl.h
arch/x86/kvm/svm.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/mm/dump_pagetables.c
block/blk-core.c
block/blk-mq.c
block/blk-mq.h
crypto/algif_hash.c
crypto/asymmetric_keys/x509_cert_parser.c
drivers/acpi/acpi_platform.c
drivers/acpi/acpi_video.c
drivers/acpi/glue.c
drivers/acpi/scan.c
drivers/acpi/thermal.c
drivers/acpi/video_detect.c
drivers/ata/libata-scsi.c
drivers/base/power/domain.c
drivers/base/power/opp/core.c
drivers/base/power/opp/cpu.c
drivers/base/power/opp/opp.h
drivers/base/property.c
drivers/block/brd.c
drivers/block/rbd.c
drivers/char/tpm/tpm-chip.c
drivers/char/tpm/tpm2-cmd.c
drivers/char/tpm/tpm_of.c
drivers/char/tpm/tpm_tis.c
drivers/clk/h8300/clk-div.c
drivers/clocksource/mips-gic-timer.c
drivers/cpufreq/arm_big_little.c
drivers/cpufreq/cppc_cpufreq.c
drivers/cpufreq/cpufreq_governor.c
drivers/cpufreq/intel_pstate.c
drivers/cpufreq/s5pv210-cpufreq.c
drivers/crypto/ccp/ccp-platform.c
drivers/crypto/qat/qat_common/adf_ctl_drv.c
drivers/firewire/ohci.c
drivers/gpu/drm/drm_irq.c
drivers/gpu/drm/rockchip/rockchip_drm_drv.c
drivers/gpu/drm/sti/Kconfig
drivers/gpu/drm/sti/Makefile
drivers/gpu/drm/sti/sti_awg_utils.c
drivers/gpu/drm/sti/sti_compositor.c
drivers/gpu/drm/sti/sti_crtc.c
drivers/gpu/drm/sti/sti_drv.c
drivers/gpu/drm/sti/sti_drv.h
drivers/gpu/drm/sti/sti_dvo.c
drivers/gpu/drm/sti/sti_gdp.c
drivers/gpu/drm/sti/sti_hda.c
drivers/gpu/drm/sti/sti_hdmi.c
drivers/gpu/drm/sti/sti_hqvdp.c
drivers/gpu/drm/sti/sti_mixer.c
drivers/gpu/drm/sti/sti_plane.c
drivers/gpu/drm/sti/sti_tvout.c
drivers/gpu/drm/sti/sti_vtac.c
drivers/gpu/drm/sti/sti_vtg.c
drivers/gpu/drm/sti/sti_vtg.h
drivers/hwmon/Kconfig
drivers/hwmon/applesmc.c
drivers/hwmon/scpi-hwmon.c
drivers/hwtracing/stm/policy.c
drivers/infiniband/ulp/srp/ib_srp.c
drivers/infiniband/ulp/srpt/ib_srpt.c
drivers/input/mouse/elantech.c
drivers/input/serio/parkbd.c
drivers/input/touchscreen/Kconfig
drivers/input/touchscreen/Makefile
drivers/input/touchscreen/tsc2004.c [new file with mode: 0644]
drivers/input/touchscreen/tsc2005.c
drivers/input/touchscreen/tsc200x-core.c [new file with mode: 0644]
drivers/input/touchscreen/tsc200x-core.h [new file with mode: 0644]
drivers/iommu/s390-iommu.c
drivers/irqchip/irq-mips-gic.c
drivers/message/fusion/mptctl.c
drivers/message/fusion/mptsas.c
drivers/misc/spear13xx_pcie_gadget.c
drivers/net/ethernet/Kconfig
drivers/net/ethernet/Makefile
drivers/net/ethernet/amd/xgbe/xgbe-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/cadence/macb.c
drivers/net/ethernet/cadence/macb.h
drivers/net/ethernet/dec/tulip/tulip_core.c
drivers/net/ethernet/dec/tulip/winbond-840.c
drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
drivers/net/ethernet/renesas/ravb_main.c
drivers/net/ethernet/ti/cpsw-common.c
drivers/net/ethernet/via/via-velocity.c
drivers/net/ipvlan/ipvlan_core.c
drivers/net/macvlan.c
drivers/net/netconsole.c
drivers/net/phy/marvell.c
drivers/net/phy/phy.c
drivers/net/usb/qmi_wwan.c
drivers/net/wan/hdlc_fr.c
drivers/nvdimm/e820.c
drivers/nvdimm/pmem.c
drivers/nvme/host/pci.c
drivers/of/of_pci.c
drivers/of/of_reserved_mem.c
drivers/pci/probe.c
drivers/platform/chrome/Kconfig
drivers/platform/chrome/Makefile
drivers/platform/chrome/chromeos_laptop.c
drivers/platform/chrome/cros_ec_dev.c
drivers/platform/chrome/cros_ec_lightbar.c
drivers/platform/chrome/cros_ec_lpc.c
drivers/platform/chrome/cros_ec_vbc.c [new file with mode: 0644]
drivers/platform/x86/Kconfig
drivers/platform/x86/asus-wmi.c
drivers/platform/x86/ideapad-laptop.c
drivers/platform/x86/intel_menlow.c
drivers/platform/x86/thinkpad_acpi.c
drivers/pwm/Kconfig
drivers/pwm/Makefile
drivers/pwm/core.c
drivers/pwm/pwm-atmel-hlcdc.c
drivers/pwm/pwm-berlin.c [new file with mode: 0644]
drivers/pwm/pwm-brcmstb.c [new file with mode: 0644]
drivers/pwm/pwm-lpss-pci.c
drivers/pwm/pwm-lpss-platform.c
drivers/pwm/pwm-lpss.c
drivers/pwm/pwm-lpss.h
drivers/pwm/pwm-mtk-disp.c [new file with mode: 0644]
drivers/pwm/pwm-pca9685.c
drivers/pwm/pwm-rcar.c [new file with mode: 0644]
drivers/pwm/pwm-sun4i.c
drivers/pwm/sysfs.c
drivers/s390/cio/chsc.c
drivers/s390/cio/chsc.h
drivers/s390/cio/cio.c
drivers/s390/cio/css.c
drivers/s390/crypto/Makefile
drivers/s390/crypto/ap_bus.c
drivers/s390/crypto/zcrypt_api.c
drivers/s390/crypto/zcrypt_api.h
drivers/s390/crypto/zcrypt_msgtype50.c
drivers/s390/crypto/zcrypt_msgtype6.c
drivers/scsi/53c700.c
drivers/scsi/FlashPoint.c
drivers/scsi/Kconfig
drivers/scsi/Makefile
drivers/scsi/aacraid/aachba.c
drivers/scsi/aacraid/aacraid.h
drivers/scsi/aacraid/comminit.c
drivers/scsi/aacraid/commsup.c
drivers/scsi/aacraid/linit.c
drivers/scsi/aacraid/rx.c
drivers/scsi/aacraid/sa.c
drivers/scsi/aacraid/src.c
drivers/scsi/advansys.c
drivers/scsi/aic7xxx/aic79xx_osm.c
drivers/scsi/aic7xxx/aic7xxx_osm.c
drivers/scsi/aic94xx/aic94xx_init.c
drivers/scsi/be2iscsi/be_main.c
drivers/scsi/be2iscsi/be_main.h
drivers/scsi/be2iscsi/be_mgmt.c
drivers/scsi/be2iscsi/be_mgmt.h
drivers/scsi/bfa/bfad_im.c
drivers/scsi/bnx2fc/57xx_hsi_bnx2fc.h
drivers/scsi/bnx2fc/Kconfig
drivers/scsi/bnx2fc/bnx2fc.h
drivers/scsi/bnx2fc/bnx2fc_constants.h
drivers/scsi/bnx2fc/bnx2fc_debug.c
drivers/scsi/bnx2fc/bnx2fc_debug.h
drivers/scsi/bnx2fc/bnx2fc_els.c
drivers/scsi/bnx2fc/bnx2fc_fcoe.c
drivers/scsi/bnx2fc/bnx2fc_hwi.c
drivers/scsi/bnx2fc/bnx2fc_io.c
drivers/scsi/bnx2fc/bnx2fc_tgt.c
drivers/scsi/csiostor/csio_scsi.c
drivers/scsi/esas2r/esas2r_main.c
drivers/scsi/esp_scsi.c
drivers/scsi/fcoe/fcoe.c
drivers/scsi/fnic/fnic_main.c
drivers/scsi/hosts.c
drivers/scsi/hpsa.c
drivers/scsi/hpsa.h
drivers/scsi/hpsa_cmd.h
drivers/scsi/ibmvscsi/ibmvfc.c
drivers/scsi/ibmvscsi/ibmvscsi.c
drivers/scsi/ibmvscsi/ibmvscsi.h
drivers/scsi/ipr.c
drivers/scsi/ipr.h
drivers/scsi/isci/init.c
drivers/scsi/libfc/fc_npiv.c
drivers/scsi/lpfc/lpfc_els.c
drivers/scsi/lpfc/lpfc_scsi.c
drivers/scsi/megaraid/megaraid_sas.h
drivers/scsi/megaraid/megaraid_sas_base.c
drivers/scsi/megaraid/megaraid_sas_fp.c
drivers/scsi/megaraid/megaraid_sas_fusion.c
drivers/scsi/megaraid/megaraid_sas_fusion.h
drivers/scsi/mpt2sas/Kconfig [deleted file]
drivers/scsi/mpt2sas/Makefile [deleted file]
drivers/scsi/mpt2sas/mpi/mpi2.h [deleted file]
drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h [deleted file]
drivers/scsi/mpt2sas/mpi/mpi2_init.h [deleted file]
drivers/scsi/mpt2sas/mpi/mpi2_ioc.h [deleted file]
drivers/scsi/mpt2sas/mpi/mpi2_raid.h [deleted file]
drivers/scsi/mpt2sas/mpi/mpi2_sas.h [deleted file]
drivers/scsi/mpt2sas/mpi/mpi2_tool.h [deleted file]
drivers/scsi/mpt2sas/mpi/mpi2_type.h [deleted file]
drivers/scsi/mpt2sas/mpt2sas_base.c [deleted file]
drivers/scsi/mpt2sas/mpt2sas_base.h [deleted file]
drivers/scsi/mpt2sas/mpt2sas_config.c [deleted file]
drivers/scsi/mpt2sas/mpt2sas_ctl.c [deleted file]
drivers/scsi/mpt2sas/mpt2sas_ctl.h [deleted file]
drivers/scsi/mpt2sas/mpt2sas_debug.h [deleted file]
drivers/scsi/mpt2sas/mpt2sas_scsih.c [deleted file]
drivers/scsi/mpt2sas/mpt2sas_transport.c [deleted file]
drivers/scsi/mpt3sas/Kconfig
drivers/scsi/mpt3sas/Makefile
drivers/scsi/mpt3sas/mpt3sas_base.c
drivers/scsi/mpt3sas/mpt3sas_base.h
drivers/scsi/mpt3sas/mpt3sas_config.c
drivers/scsi/mpt3sas/mpt3sas_ctl.c
drivers/scsi/mpt3sas/mpt3sas_ctl.h
drivers/scsi/mpt3sas/mpt3sas_debug.h
drivers/scsi/mpt3sas/mpt3sas_scsih.c
drivers/scsi/mpt3sas/mpt3sas_transport.c
drivers/scsi/mpt3sas/mpt3sas_warpdrive.c [new file with mode: 0644]
drivers/scsi/mvsas/mv_init.c
drivers/scsi/mvumi.c
drivers/scsi/pm8001/pm8001_defs.h
drivers/scsi/pm8001/pm8001_init.c
drivers/scsi/pm8001/pm8001_sas.h
drivers/scsi/pm8001/pm80xx_hwi.c
drivers/scsi/pmcraid.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qla2xxx/tcm_qla2xxx.c
drivers/scsi/qla4xxx/ql4_os.c
drivers/scsi/scsi.c
drivers/scsi/scsi_scan.c
drivers/scsi/scsi_sysfs.c
drivers/scsi/sd.c
drivers/scsi/sg.c
drivers/scsi/snic/snic_main.c
drivers/scsi/st.c
drivers/scsi/stex.c
drivers/scsi/storvsc_drv.c
drivers/scsi/ufs/Kconfig
drivers/scsi/ufs/ufs-qcom.c
drivers/scsi/ufs/ufs-qcom.h
drivers/scsi/ufs/ufshcd-pltfrm.c
drivers/scsi/ufs/ufshcd-pltfrm.h [new file with mode: 0644]
drivers/scsi/ufs/ufshcd.c
drivers/scsi/ufs/ufshcd.h
drivers/target/iscsi/iscsi_target_configfs.c
drivers/target/iscsi/iscsi_target_stat.c
drivers/target/loopback/tcm_loop.c
drivers/target/sbp/sbp_target.c
drivers/target/target_core_configfs.c
drivers/target/target_core_fabric_configfs.c
drivers/target/target_core_internal.h
drivers/target/target_core_stat.c
drivers/target/tcm_fc/tfc_cmd.c
drivers/target/tcm_fc/tfc_conf.c
drivers/target/tcm_fc/tfc_io.c
drivers/target/tcm_fc/tfc_sess.c
drivers/thermal/Kconfig
drivers/thermal/Makefile
drivers/thermal/armada_thermal.c
drivers/thermal/cpu_cooling.c
drivers/thermal/devfreq_cooling.c [new file with mode: 0644]
drivers/thermal/imx_thermal.c
drivers/thermal/rockchip_thermal.c
drivers/thermal/samsung/exynos_tmu.c
drivers/thermal/ti-soc-thermal/Kconfig
drivers/thermal/ti-soc-thermal/Makefile
drivers/thermal/ti-soc-thermal/omap3-thermal-data.c [new file with mode: 0644]
drivers/thermal/ti-soc-thermal/ti-bandgap.c
drivers/thermal/ti-soc-thermal/ti-bandgap.h
drivers/usb/gadget/configfs.c
drivers/usb/gadget/function/f_acm.c
drivers/usb/gadget/function/f_ecm.c
drivers/usb/gadget/function/f_eem.c
drivers/usb/gadget/function/f_hid.c
drivers/usb/gadget/function/f_loopback.c
drivers/usb/gadget/function/f_mass_storage.c
drivers/usb/gadget/function/f_midi.c
drivers/usb/gadget/function/f_ncm.c
drivers/usb/gadget/function/f_obex.c
drivers/usb/gadget/function/f_phonet.c
drivers/usb/gadget/function/f_printer.c
drivers/usb/gadget/function/f_rndis.c
drivers/usb/gadget/function/f_serial.c
drivers/usb/gadget/function/f_sourcesink.c
drivers/usb/gadget/function/f_subset.c
drivers/usb/gadget/function/f_uac1.c
drivers/usb/gadget/function/f_uac2.c
drivers/usb/gadget/function/u_ether_configfs.h
drivers/usb/gadget/function/uvc_configfs.c
drivers/usb/gadget/legacy/tcm_usb_gadget.c
drivers/usb/storage/uas.c
drivers/vfio/Kconfig
drivers/vfio/pci/vfio_pci.c
drivers/vfio/pci/vfio_pci_config.c
drivers/vfio/platform/Makefile
drivers/vfio/platform/reset/Kconfig
drivers/vfio/platform/reset/Makefile
drivers/vfio/platform/reset/vfio_platform_amdxgbe.c [new file with mode: 0644]
drivers/vfio/platform/reset/vfio_platform_calxedaxgmac.c
drivers/vfio/platform/vfio_amba.c
drivers/vfio/platform/vfio_platform.c
drivers/vfio/platform/vfio_platform_common.c
drivers/vfio/platform/vfio_platform_irq.c
drivers/vfio/platform/vfio_platform_private.h
drivers/vfio/vfio.c
drivers/vfio/vfio_iommu_type1.c
drivers/vhost/scsi.c
drivers/xen/xen-scsiback.c
fs/9p/Makefile
fs/9p/acl.c
fs/9p/cache.h
fs/9p/xattr.c
fs/9p/xattr.h
fs/9p/xattr_security.c [deleted file]
fs/9p/xattr_trusted.c [deleted file]
fs/9p/xattr_user.c [deleted file]
fs/binfmt_elf.c
fs/block_dev.c
fs/btrfs/disk-io.c
fs/btrfs/extent-tree.c
fs/btrfs/file.c
fs/btrfs/inode.c
fs/btrfs/qgroup.c
fs/btrfs/scrub.c
fs/btrfs/volumes.c
fs/btrfs/xattr.c
fs/buffer.c
fs/cachefiles/namei.c
fs/cachefiles/rdwr.c
fs/ceph/cache.c
fs/ceph/caps.c
fs/ceph/file.c
fs/ceph/inode.c
fs/ceph/mds_client.c
fs/ceph/mds_client.h
fs/ceph/super.h
fs/cifs/cifsfs.c
fs/cifs/cifsglob.h
fs/cifs/connect.c
fs/cifs/ioctl.c
fs/cifs/smb2file.c
fs/cifs/smb2ops.c
fs/cifs/smb2pdu.c
fs/cifs/smb2pdu.h
fs/cifs/smbfsctl.h
fs/configfs/file.c
fs/dax.c
fs/debugfs/inode.c
fs/dlm/config.c
fs/ext2/xattr.c
fs/ext2/xattr_security.c
fs/ext2/xattr_trusted.c
fs/ext2/xattr_user.c
fs/ext4/inode.c
fs/ext4/xattr.c
fs/ext4/xattr_security.c
fs/ext4/xattr_trusted.c
fs/ext4/xattr_user.c
fs/f2fs/xattr.c
fs/fscache/netfs.c
fs/fscache/page.c
fs/gfs2/xattr.c
fs/hfsplus/xattr.c
fs/hfsplus/xattr_security.c
fs/hfsplus/xattr_trusted.c
fs/hfsplus/xattr_user.c
fs/jffs2/security.c
fs/jffs2/xattr.c
fs/jffs2/xattr_trusted.c
fs/jffs2/xattr_user.c
fs/lockd/host.c
fs/lockd/mon.c
fs/lockd/netns.h
fs/lockd/svc.c
fs/lockd/svc4proc.c
fs/lockd/svcproc.c
fs/nfs/nfs4proc.c
fs/nfsd/nfs3xdr.c
fs/nfsd/nfs4layouts.c
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4state.c
fs/nfsd/nfscache.c
fs/nfsd/nfsfh.c
fs/nfsd/nfsfh.h
fs/nfsd/state.h
fs/nfsd/trace.c
fs/nfsd/trace.h
fs/nfsd/vfs.c
fs/nfsd/vfs.h
fs/nfsd/xdr4.h
fs/nilfs2/file.c
fs/ocfs2/cluster/heartbeat.c
fs/ocfs2/cluster/nodemanager.c
fs/ocfs2/xattr.c
fs/pipe.c
fs/posix_acl.c
fs/reiserfs/xattr.c
fs/reiserfs/xattr_security.c
fs/reiserfs/xattr_trusted.c
fs/reiserfs/xattr_user.c
fs/squashfs/xattr.c
fs/sysfs/group.c
fs/ubifs/super.c
fs/ubifs/ubifs.h
fs/ubifs/xattr.c
fs/xattr.c
fs/xfs/Makefile
fs/xfs/kmem.c
fs/xfs/libxfs/xfs_alloc.c
fs/xfs/libxfs/xfs_alloc.h
fs/xfs/libxfs/xfs_attr.c
fs/xfs/libxfs/xfs_attr_leaf.c
fs/xfs/libxfs/xfs_attr_remote.c
fs/xfs/libxfs/xfs_bmap.c
fs/xfs/libxfs/xfs_bmap.h
fs/xfs/libxfs/xfs_btree.c
fs/xfs/libxfs/xfs_btree.h
fs/xfs/libxfs/xfs_da_btree.c
fs/xfs/libxfs/xfs_dir2.c
fs/xfs/libxfs/xfs_dir2_block.c
fs/xfs/libxfs/xfs_dir2_data.c
fs/xfs/libxfs/xfs_dir2_leaf.c
fs/xfs/libxfs/xfs_dir2_node.c
fs/xfs/libxfs/xfs_format.h
fs/xfs/libxfs/xfs_fs.h
fs/xfs/libxfs/xfs_ialloc.c
fs/xfs/libxfs/xfs_sb.c
fs/xfs/libxfs/xfs_symlink_remote.c
fs/xfs/xfs_acl.c
fs/xfs/xfs_acl.h
fs/xfs/xfs_aops.c
fs/xfs/xfs_aops.h
fs/xfs/xfs_attr_list.c
fs/xfs/xfs_bmap_util.c
fs/xfs/xfs_buf.c
fs/xfs/xfs_dir2_readdir.c
fs/xfs/xfs_dquot.c
fs/xfs/xfs_file.c
fs/xfs/xfs_icache.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_inode_item.c
fs/xfs/xfs_inode_item.h
fs/xfs/xfs_ioctl.c
fs/xfs/xfs_ioctl32.c
fs/xfs/xfs_iomap.c
fs/xfs/xfs_iops.c
fs/xfs/xfs_linux.h
fs/xfs/xfs_log.c
fs/xfs/xfs_log.h
fs/xfs/xfs_log_priv.h
fs/xfs/xfs_log_recover.c
fs/xfs/xfs_message.c
fs/xfs/xfs_mount.c
fs/xfs/xfs_mount.h
fs/xfs/xfs_pnfs.c
fs/xfs/xfs_qm.c
fs/xfs/xfs_stats.c
fs/xfs/xfs_stats.h
fs/xfs/xfs_super.c
fs/xfs/xfs_sysctl.c
fs/xfs/xfs_sysfs.c
fs/xfs/xfs_sysfs.h
fs/xfs/xfs_trace.h
fs/xfs/xfs_trans.c
fs/xfs/xfs_trans_ail.c
fs/xfs/xfs_trans_inode.c
fs/xfs/xfs_xattr.c
include/acpi/acpi_bus.h
include/asm-generic/uaccess.h
include/linux/acpi.h
include/linux/blk_types.h
include/linux/buffer_head.h
include/linux/ceph/libceph.h
include/linux/ceph/messenger.h
include/linux/configfs.h
include/linux/context_tracking.h
include/linux/devfreq_cooling.h [new file with mode: 0644]
include/linux/dns_resolver.h
include/linux/fs.h
include/linux/irqchip/mips-gic.h
include/linux/kvm_host.h
include/linux/lockd/lockd.h
include/linux/marvell_phy.h
include/linux/math64.h
include/linux/mfd/cros_ec.h
include/linux/netdevice.h
include/linux/of.h
include/linux/of_address.h
include/linux/of_pci.h
include/linux/property.h
include/linux/pwm.h
include/linux/sunrpc/cache.h
include/linux/sysfs.h
include/linux/thermal.h
include/linux/usb/gadget_configfs.h
include/linux/vfio.h
include/linux/xattr.h
include/scsi/scsi_host.h
include/scsi/scsi_tcq.h
include/target/configfs_macros.h [deleted file]
include/target/target_core_base.h
include/target/target_core_fabric_configfs.h [deleted file]
include/trace/events/thermal.h
include/uapi/drm/drm_fourcc.h
include/uapi/linux/vfio.h
kernel/context_tracking.c
kernel/events/core.c
kernel/irq/internals.h
kernel/irq/pm.c
kernel/irq/proc.c
kernel/sched/fair.c
kernel/time/timer.c
kernel/trace/trace.c
kernel/trace/trace.h
kernel/trace/trace_functions_graph.c
net/8021q/vlan_core.c
net/ceph/auth_x.c
net/ceph/ceph_common.c
net/ceph/crypto.h
net/ceph/messenger.c
net/ceph/osd_client.c
net/core/dev.c
net/core/neighbour.c
net/core/rtnetlink.c
net/core/scm.c
net/core/skbuff.c
net/dns_resolver/dns_query.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_timer.c
net/ipv4/udp.c
net/ipv6/ip6_tunnel.c
net/packet/af_packet.c
net/sunrpc/auth_gss/auth_gss.c
net/sunrpc/cache.c
net/sunrpc/svcsock.c
net/tipc/link.c
net/unix/af_unix.c
samples/Kconfig
samples/Makefile
samples/configfs/Makefile [new file with mode: 0644]
samples/configfs/configfs_sample.c [new file with mode: 0644]
sound/firewire/Kconfig
sound/pci/Kconfig
sound/pci/ctxfi/ctamixer.c
sound/pci/ctxfi/ctamixer.h
sound/pci/ctxfi/ctdaio.c
sound/pci/ctxfi/ctdaio.h
sound/pci/ctxfi/ctresource.c
sound/pci/ctxfi/ctresource.h
sound/pci/ctxfi/ctsrc.c
sound/pci/ctxfi/ctsrc.h
sound/pci/hda/hda_jack.c
sound/pci/hda/hda_jack.h
sound/pci/hda/patch_hdmi.c
sound/sound_core.c
sound/usb/quirks.c
tools/include/linux/list.h
tools/lib/bpf/.gitignore
tools/lib/bpf/Makefile
tools/lib/bpf/libbpf.c
tools/lib/bpf/libbpf.h
tools/lib/lockdep/common.c
tools/lib/lockdep/include/liblockdep/common.h
tools/lib/lockdep/uinclude/linux/compiler.h
tools/lib/lockdep/uinclude/linux/lockdep.h
tools/perf/Documentation/perf-trace.txt
tools/perf/Makefile
tools/perf/builtin-sched.c
tools/perf/builtin-stat.c
tools/perf/tests/.gitignore [new file with mode: 0644]
tools/perf/tests/Build
tools/perf/tests/attr.c
tools/perf/tests/bpf-script-example.c
tools/perf/tests/bpf-script-test-kbuild.c [new file with mode: 0644]
tools/perf/tests/bpf.c [new file with mode: 0644]
tools/perf/tests/builtin-test.c
tools/perf/tests/code-reading.c
tools/perf/tests/keep-tracking.c
tools/perf/tests/llvm.c
tools/perf/tests/llvm.h [new file with mode: 0644]
tools/perf/tests/make
tools/perf/tests/switch-tracking.c
tools/perf/tests/tests.h
tools/perf/util/annotate.c
tools/perf/util/bpf-loader.c
tools/perf/util/bpf-loader.h
tools/perf/util/llvm-utils.c
tools/perf/util/map.c
tools/perf/util/parse-events.c
tools/perf/util/probe-event.c
tools/perf/util/probe-file.c
tools/perf/util/session.c
tools/perf/util/stat-shadow.c
tools/perf/util/util.c
tools/perf/util/util.h
tools/power/cpupower/debug/i386/dump_psb.c
tools/power/cpupower/man/cpupower-idle-set.1
tools/power/cpupower/utils/cpufreq-info.c
tools/power/cpupower/utils/cpufreq-set.c
tools/power/cpupower/utils/cpuidle-info.c
tools/power/cpupower/utils/cpuidle-set.c
tools/power/cpupower/utils/cpupower-info.c
tools/power/cpupower/utils/cpupower-set.c
tools/power/cpupower/utils/helpers/topology.c
tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c
tools/power/x86/turbostat/turbostat.c
tools/testing/nvdimm/test/nfit.c
tools/thermal/tmon/Makefile

diff --git a/Documentation/ABI/testing/sysfs-driver-st b/Documentation/ABI/testing/sysfs-driver-st
new file mode 100644 (file)
index 0000000..ba5d770
--- /dev/null
@@ -0,0 +1,12 @@
+What:          /sys/bus/scsi/drivers/st/debug_flag
+Date:          October 2015
+Kernel Version:        ?.?
+Contact:       shane.seymour@hpe.com
+Description:
+               This file allows you to turn debug output from the st driver
+               off if you write a '0' to the file or on if you write a '1'.
+               Note that debug output requires that the module be compiled
+               with the #define DEBUG set to a non-zero value (this is the
+               default). If DEBUG is set to 0 then this file will not
+               appear in sysfs as its presence is conditional upon debug
+               output support being compiled into the module.
index 4710e4afef19c40b146e50c9fedff8b9fc308ead..d603fa07823598b87dc48d0e8362a6fcb5a57a32 100644 (file)
@@ -718,8 +718,21 @@ generates appropriate diffstats by default.)
 See more details on the proper patch format in the following
 references.
 
+15) Explicit In-Reply-To headers
+--------------------------------
+
+It can be helpful to manually add In-Reply-To: headers to a patch
+(e.g., when using "git send email") to associate the patch with
+previous relevant discussion, e.g. to link a bug fix to the email with
+the bug report.  However, for a multi-patch series, it is generally
+best to avoid using In-Reply-To: to link to older versions of the
+series.  This way multiple versions of the patch don't become an
+unmanageable forest of references in email clients.  If a link is
+helpful, you can use the https://lkml.kernel.org/ redirector (e.g., in
+the cover email text) to link to an earlier version of the patch series.
+
 
-15) Sending "git pull" requests
+16) Sending "git pull" requests
 -------------------------------
 
 If you have a series of patches, it may be most convenient to have the
index 09089a6d69ed8d1c9b29115e6abce75a6d1a2fcd..b80c04b0e5c028a45ae85f3ba77230b509318037 100644 (file)
@@ -1,14 +1,15 @@
-* Texas Instruments tsc2005 touchscreen controller
+* Texas Instruments tsc2004 and tsc2005 touchscreen controllers
 
 Required properties:
- - compatible                : "ti,tsc2005"
- - reg                       : SPI device address
- - spi-max-frequency         : Maximal SPI speed
+ - compatible                : "ti,tsc2004" or "ti,tsc2005"
+ - reg                       : Device address
  - interrupts                : IRQ specifier
- - reset-gpios               : GPIO specifier
- - vio-supply                 : Regulator specifier
+ - spi-max-frequency         : Maximum SPI clocking speed of the device
+                               (for tsc2005)
 
 Optional properties:
+ - vio-supply                : Regulator specifier
+ - reset-gpios               : GPIO specifier for the controller reset line
  - ti,x-plate-ohms           : integer, resistance of the touchscreen's X plates
                                in ohm (defaults to 280)
  - ti,esd-recovery-timeout-ms : integer, if the touchscreen does not respond after
@@ -18,6 +19,27 @@ Optional properties:
 
 Example:
 
+&i2c3 {
+       tsc2004@48 {
+               compatible = "ti,tsc2004";
+               reg = <0x48>;
+               vio-supply = <&vio>;
+
+               reset-gpios = <&gpio4 8 GPIO_ACTIVE_HIGH>;
+               interrupts-extended = <&gpio1 27 IRQ_TYPE_EDGE_RISING>;
+
+               touchscreen-fuzz-x = <4>;
+               touchscreen-fuzz-y = <7>;
+               touchscreen-fuzz-pressure = <2>;
+               touchscreen-size-x = <4096>;
+               touchscreen-size-y = <4096>;
+               touchscreen-max-pressure = <2048>;
+
+               ti,x-plate-ohms = <280>;
+               ti,esd-recovery-timeout-ms = <8000>;
+       };
+}
+
 &mcspi1 {
        tsc2005@0 {
                compatible = "ti,tsc2005";
diff --git a/Documentation/devicetree/bindings/mips/img/xilfpga.txt b/Documentation/devicetree/bindings/mips/img/xilfpga.txt
new file mode 100644 (file)
index 0000000..57e7ee9
--- /dev/null
@@ -0,0 +1,83 @@
+Imagination University Program MIPSfpga
+=======================================
+
+Under the Imagination University Program, a microAptiv UP core has been
+released for academic usage.
+
+As we are dealing with a MIPS core instantiated on an FPGA, specifications
+are fluid and can be varied in RTL.
+
+This binding document is provided as baseline guidance for the example
+project provided by IMG.
+
+The example project runs on the Nexys4DDR board by Digilent powered by
+the ARTIX-7 FPGA by Xilinx.
+
+Relevant details about the example project and the Nexys4DDR board:
+
+- microAptiv UP core m14Kc
+- 50MHz clock speed
+- 128Mbyte DDR RAM     at 0x0000_0000
+- 8Kbyte RAM           at 0x1000_0000
+- axi_intc             at 0x1020_0000
+- axi_uart16550                at 0x1040_0000
+- axi_gpio             at 0x1060_0000
+- axi_i2c              at 0x10A0_0000
+- custom_gpio          at 0x10C0_0000
+- axi_ethernetlite     at 0x10E0_0000
+- 8Kbyte BootRAM       at 0x1FC0_0000
+
+Required properties:
+--------------------
+ - compatible: Must include "digilent,nexys4ddr","img,xilfpga".
+
+CPU nodes:
+----------
+A "cpus" node is required.  Required properties:
+ - #address-cells: Must be 1.
+ - #size-cells: Must be 0.
+A CPU sub-node is also required for at least CPU 0. Required properties:
+ - device_type: Must be "cpu".
+ - compatible: Must be "mips,m14Kc".
+ - reg: Must be <0>.
+ - clocks: phandle to ext clock for fixed-clock received by MIPS core.
+
+Example:
+
+       compatible = "img,xilfpga","digilent,nexys4ddr";
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "mips,m14Kc";
+                       reg = <0>;
+                       clocks  = <&ext>;
+               };
+       };
+
+       ext: ext {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <50000000>;
+       };
+
+Boot protocol:
+--------------
+
+The BootRAM is a writeable "RAM" in FPGA at 0x1FC0_0000.
+This is for easy reprogrammibility via JTAG.
+
+The BootRAM initializes the cache and the axi_uart peripheral.
+
+DDR initialization is already handled by a HW IP block.
+
+When the example project bitstream is loaded, the cpu_reset button
+needs to be pressed.
+
+The bootram initializes the cache and axi_uart.
+Then outputs MIPSFPGA\n\r on the serial port on the Nexys4DDR board.
+
+At this point, the board is ready to load the Linux kernel
+vmlinux file via JTAG.
diff --git a/Documentation/devicetree/bindings/pwm/brcm,bcm7038-pwm.txt b/Documentation/devicetree/bindings/pwm/brcm,bcm7038-pwm.txt
new file mode 100644 (file)
index 0000000..d9254a6
--- /dev/null
@@ -0,0 +1,20 @@
+Broadcom BCM7038 PWM controller (BCM7xxx Set Top Box PWM controller)
+
+Required properties:
+
+- compatible: must be "brcm,bcm7038-pwm"
+- reg: physical base address and length for this controller
+- #pwm-cells: should be 2. See pwm.txt in this directory for a description
+  of the cells format
+- clocks: a phandle to the reference clock for this block which is fed through
+  its internal variable clock frequency generator
+
+
+Example:
+
+       pwm: pwm@f0408000 {
+               compatible = "brcm,bcm7038-pwm";
+               reg = <0xf0408000 0x28>;
+               #pwm-cells = <2>;
+               clocks = <&upg_fixed>;
+       };
diff --git a/Documentation/devicetree/bindings/pwm/pwm-berlin.txt b/Documentation/devicetree/bindings/pwm/pwm-berlin.txt
new file mode 100644 (file)
index 0000000..82cbe16
--- /dev/null
@@ -0,0 +1,17 @@
+Berlin PWM controller
+
+Required properties:
+- compatible: should be "marvell,berlin-pwm"
+- reg: physical base address and length of the controller's registers
+- clocks: phandle to the input clock
+- #pwm-cells: should be 3. See pwm.txt in this directory for a description of
+  the cells format.
+
+Example:
+
+pwm: pwm@f7f20000 {
+       compatible = "marvell,berlin-pwm";
+       reg = <0xf7f20000 0x40>;
+       clocks = <&chip_clk CLKID_CFG>;
+       #pwm-cells = <3>;
+}
diff --git a/Documentation/devicetree/bindings/pwm/pwm-mtk-disp.txt b/Documentation/devicetree/bindings/pwm/pwm-mtk-disp.txt
new file mode 100644 (file)
index 0000000..f8f59ba
--- /dev/null
@@ -0,0 +1,42 @@
+MediaTek display PWM controller
+
+Required properties:
+ - compatible: should be "mediatek,<name>-disp-pwm":
+   - "mediatek,mt8173-disp-pwm": found on mt8173 SoC.
+   - "mediatek,mt6595-disp-pwm": found on mt6595 SoC.
+ - reg: physical base address and length of the controller's registers.
+ - #pwm-cells: must be 2. See pwm.txt in this directory for a description of
+   the cell format.
+ - clocks: phandle and clock specifier of the PWM reference clock.
+ - clock-names: must contain the following:
+   - "main": clock used to generate PWM signals.
+   - "mm": sync signals from the modules of mmsys.
+ - pinctrl-names: Must contain a "default" entry.
+ - pinctrl-0: One property must exist for each entry in pinctrl-names.
+   See pinctrl/pinctrl-bindings.txt for details of the property values.
+
+Example:
+       pwm0: pwm@1401e000 {
+               compatible = "mediatek,mt8173-disp-pwm",
+                            "mediatek,mt6595-disp-pwm";
+               reg = <0 0x1401e000 0 0x1000>;
+               #pwm-cells = <2>;
+               clocks = <&mmsys CLK_MM_DISP_PWM026M>,
+                        <&mmsys CLK_MM_DISP_PWM0MM>;
+               clock-names = "main", "mm";
+               pinctrl-names = "default";
+               pinctrl-0 = <&disp_pwm0_pins>;
+       };
+
+       backlight_lcd: backlight_lcd {
+               compatible = "pwm-backlight";
+               pwms = <&pwm0 0 1000000>;
+               brightness-levels = <
+                         0  16  32  48  64  80  96 112
+                       128 144 160 176 192 208 224 240
+                       255
+               >;
+               default-brightness-level = <9>;
+               power-supply = <&mt6397_vio18_reg>;
+               enable-gpios = <&pio 95 GPIO_ACTIVE_HIGH>;
+       };
index ae0273e19506289420afc6862df09ad00c6e6a62..cf6068b8e9743ce5bdc7f927c936d7f010ba8e00 100644 (file)
@@ -3,6 +3,8 @@ Allwinner sun4i and sun7i SoC PWM controller
 Required properties:
   - compatible: should be one of:
     - "allwinner,sun4i-a10-pwm"
+    - "allwinner,sun5i-a10s-pwm"
+    - "allwinner,sun5i-a13-pwm"
     - "allwinner,sun7i-a20-pwm"
   - reg: physical base address and length of the controller's registers
   - #pwm-cells: should be 3. See pwm.txt in this directory for a description of
diff --git a/Documentation/devicetree/bindings/pwm/renesas,pwm-rcar.txt b/Documentation/devicetree/bindings/pwm/renesas,pwm-rcar.txt
new file mode 100644 (file)
index 0000000..0822a08
--- /dev/null
@@ -0,0 +1,26 @@
+* Renesas R-Car PWM Timer Controller
+
+Required Properties:
+- compatible: should be "renesas,pwm-rcar" and one of the following.
+ - "renesas,pwm-r8a7778": for R-Car M1A
+ - "renesas,pwm-r8a7779": for R-Car H1
+ - "renesas,pwm-r8a7790": for R-Car H2
+ - "renesas,pwm-r8a7791": for R-Car M2-W
+ - "renesas,pwm-r8a7794": for R-Car E2
+- reg: base address and length of the registers block for the PWM.
+- #pwm-cells: should be 2. See pwm.txt in this directory for a description of
+  the cells format.
+- clocks: clock phandle and specifier pair.
+- pinctrl-0: phandle, referring to a default pin configuration node.
+- pinctrl-names: Set to "default".
+
+Example: R8A7790 (R-Car H2) PWM Timer node
+
+       pwm0: pwm@e6e30000 {
+               compatible = "renesas,pwm-r8a7790", "renesas,pwm-rcar";
+               reg = <0 0xe6e30000 0 0x8>;
+               #pwm-cells = <2>;
+               clocks = <&mstp5_clks R8A7790_CLK_PWM>;
+               pinctrl-0 = <&pwm0_pins>;
+               pinctrl-names = "default";
+       };
diff --git a/Documentation/devicetree/bindings/sound/ak4554.c b/Documentation/devicetree/bindings/sound/ak4554.c
deleted file mode 100644 (file)
index 934fa02..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-AK4554 ADC/DAC
-
-Required properties:
-
-  - compatible : "asahi-kasei,ak4554"
-
-Example:
-
-ak4554-adc-dac {
-       compatible = "asahi-kasei,ak4554";
-};
diff --git a/Documentation/devicetree/bindings/sound/ak4554.txt b/Documentation/devicetree/bindings/sound/ak4554.txt
new file mode 100644 (file)
index 0000000..934fa02
--- /dev/null
@@ -0,0 +1,11 @@
+AK4554 ADC/DAC
+
+Required properties:
+
+  - compatible : "asahi-kasei,ak4554"
+
+Example:
+
+ak4554-adc-dac {
+       compatible = "asahi-kasei,ak4554";
+};
index ef802de4957a38b523686a603ac0e5b2f5756aaa..b38200d2583a5473ebe4c618aa09475128d31100 100644 (file)
@@ -12,6 +12,11 @@ Required properties:
 - resets : Must contain an entry for each entry in reset-names.
           See ../reset/reset.txt for details.
 - reset-names : Must include the name "tsadc-apb".
+- pinctrl-names : The pin control state names;
+- pinctrl-0 : The "init" pinctrl state, it will be set before device probe.
+- pinctrl-1 : The "default" pinctrl state, it will be set after reset the
+             TSADC controller.
+- pinctrl-2 : The "sleep" pinctrl state, it will be in for suspend.
 - #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description.
 - rockchip,hw-tshut-temp : The hardware-controlled shutdown temperature value.
 - rockchip,hw-tshut-mode : The hardware-controlled shutdown mode 0:CRU 1:GPIO.
@@ -27,8 +32,10 @@ tsadc: tsadc@ff280000 {
        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>;
        rockchip,hw-tshut-mode = <0>;
index 0c9222d27fae3dd0a67a8eb2d5a9b470cc20130a..6299dd8de339aeb1ede83b582e5ce3289213af7d 100644 (file)
@@ -10,6 +10,8 @@ to the silicon temperature.
 
 Required properties:
 - compatible : Should be:
+  - "ti,omap34xx-bandgap" : for OMAP34xx bandgap
+  - "ti,omap36xx-bandgap" : for OMAP36xx bandgap
   - "ti,omap4430-bandgap" : for OMAP4430 bandgap
   - "ti,omap4460-bandgap" : for OMAP4460 bandgap
   - "ti,omap4470-bandgap" : for OMAP4470 bandgap
@@ -25,6 +27,18 @@ to each bandgap version, because the mapping may change from
 soc to soc, apart of depending on available features.
 
 Example:
+OMAP34xx:
+bandgap {
+       reg = <0x48002524 0x4>;
+       compatible = "ti,omap34xx-bandgap";
+};
+
+OMAP36xx:
+bandgap {
+       reg = <0x48002524 0x4>;
+       compatible = "ti,omap36xx-bandgap";
+};
+
 OMAP4430:
 bandgap {
        reg = <0x4a002260 0x4 0x4a00232C 0x4>;
diff --git a/Documentation/devicetree/bindings/ufs/ufs-qcom.txt b/Documentation/devicetree/bindings/ufs/ufs-qcom.txt
new file mode 100644 (file)
index 0000000..070baf4
--- /dev/null
@@ -0,0 +1,58 @@
+* Qualcomm Technologies Inc Universal Flash Storage (UFS) PHY
+
+UFSPHY nodes are defined to describe on-chip UFS PHY hardware macro.
+Each UFS PHY node should have its own node.
+
+To bind UFS PHY with UFS host controller, the controller node should
+contain a phandle reference to UFS PHY node.
+
+Required properties:
+- compatible        : compatible list, contains "qcom,ufs-phy-qmp-20nm"
+                     or "qcom,ufs-phy-qmp-14nm" according to the relevant phy in use.
+- reg               : should contain PHY register address space (mandatory),
+- reg-names         : indicates various resources passed to driver (via reg proptery) by name.
+                      Required "reg-names" is "phy_mem".
+- #phy-cells        : This property shall be set to 0
+- vdda-phy-supply   : phandle to main PHY supply for analog domain
+- vdda-pll-supply   : phandle to PHY PLL and Power-Gen block power supply
+- clocks           : List of phandle and clock specifier pairs
+- clock-names       : List of clock input name strings sorted in the same
+                     order as the clocks property. "ref_clk_src", "ref_clk",
+                     "tx_iface_clk" & "rx_iface_clk" are mandatory but
+                     "ref_clk_parent" is optional
+
+Optional properties:
+- vdda-phy-max-microamp : specifies max. load that can be drawn from phy supply
+- vdda-pll-max-microamp : specifies max. load that can be drawn from pll supply
+- vddp-ref-clk-supply   : phandle to UFS device ref_clk pad power supply
+- vddp-ref-clk-max-microamp : specifies max. load that can be drawn from this supply
+- vddp-ref-clk-always-on : specifies if this supply needs to be kept always on
+
+Example:
+
+       ufsphy1: ufsphy@0xfc597000 {
+               compatible = "qcom,ufs-phy-qmp-20nm";
+               reg = <0xfc597000 0x800>;
+               reg-names = "phy_mem";
+               #phy-cells = <0>;
+               vdda-phy-supply = <&pma8084_l4>;
+               vdda-pll-supply = <&pma8084_l12>;
+               vdda-phy-max-microamp = <50000>;
+               vdda-pll-max-microamp = <1000>;
+               clock-names = "ref_clk_src",
+                       "ref_clk_parent",
+                       "ref_clk",
+                       "tx_iface_clk",
+                       "rx_iface_clk";
+               clocks = <&clock_rpm clk_ln_bb_clk>,
+                       <&clock_gcc clk_pcie_1_phy_ldo >,
+                       <&clock_gcc clk_ufs_phy_ldo>,
+                       <&clock_gcc clk_gcc_ufs_tx_cfg_clk>,
+                       <&clock_gcc clk_gcc_ufs_rx_cfg_clk>;
+       };
+
+       ufshc@0xfc598000 {
+               ...
+               phys = <&ufsphy1>;
+               phy-names = "ufsphy";
+       };
index 53579197eca2a86b1b43e0cdf0ac9ba329831693..03c0e989e020a98ec28195896c8f8612686a580e 100644 (file)
@@ -4,11 +4,18 @@ UFSHC nodes are defined to describe on-chip UFS host controllers.
 Each UFS controller instance should have its own node.
 
 Required properties:
-- compatible        : compatible list, contains "jedec,ufs-1.1"
+- compatible           : must contain "jedec,ufs-1.1", may also list one or more
+                                         of the following:
+                                         "qcom,msm8994-ufshc"
+                                         "qcom,msm8996-ufshc"
+                                         "qcom,ufshc"
 - interrupts        : <interrupt mapping for UFS host controller IRQ>
 - reg               : <registers mapping>
 
 Optional properties:
+- phys                  : phandle to UFS PHY node
+- phy-names             : the string "ufsphy" when is found in a node, along
+                          with "phys" attribute, provides phandle to UFS PHY node
 - vdd-hba-supply        : phandle to UFS host controller supply regulator node
 - vcc-supply            : phandle to VCC supply regulator node
 - vccq-supply           : phandle to VCCQ supply regulator node
@@ -54,4 +61,6 @@ Example:
                clocks = <&core 0>, <&ref 0>, <&iface 0>;
                clock-names = "core_clk", "ref_clk", "iface_clk";
                freq-table-hz = <100000000 200000000>, <0 0>, <0 0>;
+               phys = <&ufsphy1>;
+               phy-names = "ufsphy";
        };
index 9de9813d0ec5df101a48428d40cfc9b9d2df6142..8ea834f6b2892a6ed7cccbc399cc5f1f3e887bd0 100644 (file)
@@ -165,7 +165,6 @@ mach-types.h
 machtypes.h
 map
 map_hugetlb
-media
 mconf
 miboot*
 mk_elfconfig
index aba85b39a40096872bc67b4e0303a381ec74693d..2d485dea8cece79d7a2db645a3011a27c76c47b4 100644 (file)
@@ -176,11 +176,47 @@ To use 'vim' with mutt:
 if you want to include the patch inline.
 (a)ttach works fine without "set paste".
 
+You can also generate patches with 'git format-patch' and then use Mutt
+to send them:
+    $ mutt -H 0001-some-bug-fix.patch
+
 Config options:
 It should work with default settings.
 However, it's a good idea to set the "send_charset" to:
   set send_charset="us-ascii:utf-8"
 
+Mutt is highly customizable. Here is a minimum configuration to start
+using Mutt to send patches through Gmail:
+
+# .muttrc
+# ================  IMAP ====================
+set imap_user = 'yourusername@gmail.com'
+set imap_pass = 'yourpassword'
+set spoolfile = imaps://imap.gmail.com/INBOX
+set folder = imaps://imap.gmail.com/
+set record="imaps://imap.gmail.com/[Gmail]/Sent Mail"
+set postponed="imaps://imap.gmail.com/[Gmail]/Drafts"
+set mbox="imaps://imap.gmail.com/[Gmail]/All Mail"
+
+# ================  SMTP  ====================
+set smtp_url = "smtp://username@smtp.gmail.com:587/"
+set smtp_pass = $imap_pass
+set ssl_force_tls = yes # Require encrypted connection
+
+# ================  Composition  ====================
+set editor = `echo \$EDITOR`
+set edit_headers = yes  # See the headers when editing
+set charset = UTF-8     # value of $LANG; also fallback for send_charset
+# Sender, email address, and sign-off line must match
+unset use_domain        # because joe@localhost is just embarrassing
+set realname = "YOUR NAME"
+set from = "username@gmail.com"
+set use_from = yes
+
+The Mutt docs have lots more information:
+    http://dev.mutt.org/trac/wiki/UseCases/Gmail
+    http://dev.mutt.org/doc/manual.html
+
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Pine (TUI)
 
index 13483d192ebb9f80bf541eead154f28c1eb44c0f..883010ce5e35bcd88885b0a5eeff68e82676029f 100644 (file)
@@ -1,5 +1,3 @@
-subdir-y := configfs
-
 # List of programs to build
 hostprogs-y := dnotify_test
 
diff --git a/Documentation/filesystems/configfs/Makefile b/Documentation/filesystems/configfs/Makefile
deleted file mode 100644 (file)
index be7ec5e..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-ifneq ($(CONFIG_CONFIGFS_FS),)
-obj-m += configfs_example_explicit.o configfs_example_macros.o
-endif
index b40fec9d3f53b6402a4a21ba74f170c466d73300..af68efdbbfaddb0827b29f1fc4fb4b0eacc43b3a 100644 (file)
@@ -160,12 +160,6 @@ among other things.  For that, it needs a type.
 
        struct configfs_item_operations {
                void (*release)(struct config_item *);
-               ssize_t (*show_attribute)(struct config_item *,
-                                         struct configfs_attribute *,
-                                         char *);
-               ssize_t (*store_attribute)(struct config_item *,
-                                          struct configfs_attribute *,
-                                          const char *, size_t);
                int (*allow_link)(struct config_item *src,
                                  struct config_item *target);
                int (*drop_link)(struct config_item *src,
@@ -183,9 +177,7 @@ The most basic function of a config_item_type is to define what
 operations can be performed on a config_item.  All items that have been
 allocated dynamically will need to provide the ct_item_ops->release()
 method.  This method is called when the config_item's reference count
-reaches zero.  Items that wish to display an attribute need to provide
-the ct_item_ops->show_attribute() method.  Similarly, storing a new
-attribute value uses the store_attribute() method.
+reaches zero.
 
 [struct configfs_attribute]
 
@@ -193,6 +185,8 @@ attribute value uses the store_attribute() method.
                char                    *ca_name;
                struct module           *ca_owner;
                umode_t                  ca_mode;
+               ssize_t (*show)(struct config_item *, char *);
+               ssize_t (*store)(struct config_item *, const char *, size_t);
        };
 
 When a config_item wants an attribute to appear as a file in the item's
@@ -202,10 +196,10 @@ config_item_type->ct_attrs.  When the item appears in configfs, the
 attribute file will appear with the configfs_attribute->ca_name
 filename.  configfs_attribute->ca_mode specifies the file permissions.
 
-If an attribute is readable and the config_item provides a
-ct_item_ops->show_attribute() method, that method will be called
-whenever userspace asks for a read(2) on the attribute.  The converse
-will happen for write(2).
+If an attribute is readable and provides a ->show method, that method will
+be called whenever userspace asks for a read(2) on the attribute.  If an
+attribute is writable and provides a ->store  method, that method will be
+be called whenever userspace asks for a write(2) on the attribute.
 
 [struct config_group]
 
@@ -311,20 +305,10 @@ the subsystem must be ready for it.
 [An Example]
 
 The best example of these basic concepts is the simple_children
-subsystem/group and the simple_child item in configfs_example_explicit.c
-and configfs_example_macros.c.  It shows a trivial object displaying and
-storing an attribute, and a simple group creating and destroying these
-children.
-
-The only difference between configfs_example_explicit.c and
-configfs_example_macros.c is how the attributes of the childless item
-are defined.  The childless item has extended attributes, each with
-their own show()/store() operation.  This follows a convention commonly
-used in sysfs.  configfs_example_explicit.c creates these attributes
-by explicitly defining the structures involved.  Conversely
-configfs_example_macros.c uses some convenience macros from configfs.h
-to define the attributes.  These macros are similar to their sysfs
-counterparts.
+subsystem/group and the simple_child item in
+samples/configfs/configfs_sample.c. It shows a trivial object displaying
+and storing an attribute, and a simple group creating and destroying
+these children.
 
 [Hierarchy Navigation and the Subsystem Mutex]
 
diff --git a/Documentation/filesystems/configfs/configfs_example_explicit.c b/Documentation/filesystems/configfs/configfs_example_explicit.c
deleted file mode 100644 (file)
index 1420233..0000000
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * vim: noexpandtab ts=8 sts=0 sw=8:
- *
- * configfs_example_explicit.c - This file is a demonstration module
- *      containing a number of configfs subsystems.  It explicitly defines
- *      each structure without using the helper macros defined in
- *      configfs.h.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 021110-1307, USA.
- *
- * Based on sysfs:
- *     sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
- *
- * configfs Copyright (C) 2005 Oracle.  All rights reserved.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-
-#include <linux/configfs.h>
-
-
-
-/*
- * 01-childless
- *
- * This first example is a childless subsystem.  It cannot create
- * any config_items.  It just has attributes.
- *
- * Note that we are enclosing the configfs_subsystem inside a container.
- * This is not necessary if a subsystem has no attributes directly
- * on the subsystem.  See the next example, 02-simple-children, for
- * such a subsystem.
- */
-
-struct childless {
-       struct configfs_subsystem subsys;
-       int showme;
-       int storeme;
-};
-
-struct childless_attribute {
-       struct configfs_attribute attr;
-       ssize_t (*show)(struct childless *, char *);
-       ssize_t (*store)(struct childless *, const char *, size_t);
-};
-
-static inline struct childless *to_childless(struct config_item *item)
-{
-       return item ? container_of(to_configfs_subsystem(to_config_group(item)), struct childless, subsys) : NULL;
-}
-
-static ssize_t childless_showme_read(struct childless *childless,
-                                    char *page)
-{
-       ssize_t pos;
-
-       pos = sprintf(page, "%d\n", childless->showme);
-       childless->showme++;
-
-       return pos;
-}
-
-static ssize_t childless_storeme_read(struct childless *childless,
-                                     char *page)
-{
-       return sprintf(page, "%d\n", childless->storeme);
-}
-
-static ssize_t childless_storeme_write(struct childless *childless,
-                                      const char *page,
-                                      size_t count)
-{
-       unsigned long tmp;
-       char *p = (char *) page;
-
-       tmp = simple_strtoul(p, &p, 10);
-       if ((*p != '\0') && (*p != '\n'))
-               return -EINVAL;
-
-       if (tmp > INT_MAX)
-               return -ERANGE;
-
-       childless->storeme = tmp;
-
-       return count;
-}
-
-static ssize_t childless_description_read(struct childless *childless,
-                                         char *page)
-{
-       return sprintf(page,
-"[01-childless]\n"
-"\n"
-"The childless subsystem is the simplest possible subsystem in\n"
-"configfs.  It does not support the creation of child config_items.\n"
-"It only has a few attributes.  In fact, it isn't much different\n"
-"than a directory in /proc.\n");
-}
-
-static struct childless_attribute childless_attr_showme = {
-       .attr   = { .ca_owner = THIS_MODULE, .ca_name = "showme", .ca_mode = S_IRUGO },
-       .show   = childless_showme_read,
-};
-static struct childless_attribute childless_attr_storeme = {
-       .attr   = { .ca_owner = THIS_MODULE, .ca_name = "storeme", .ca_mode = S_IRUGO | S_IWUSR },
-       .show   = childless_storeme_read,
-       .store  = childless_storeme_write,
-};
-static struct childless_attribute childless_attr_description = {
-       .attr = { .ca_owner = THIS_MODULE, .ca_name = "description", .ca_mode = S_IRUGO },
-       .show = childless_description_read,
-};
-
-static struct configfs_attribute *childless_attrs[] = {
-       &childless_attr_showme.attr,
-       &childless_attr_storeme.attr,
-       &childless_attr_description.attr,
-       NULL,
-};
-
-static ssize_t childless_attr_show(struct config_item *item,
-                                  struct configfs_attribute *attr,
-                                  char *page)
-{
-       struct childless *childless = to_childless(item);
-       struct childless_attribute *childless_attr =
-               container_of(attr, struct childless_attribute, attr);
-       ssize_t ret = 0;
-
-       if (childless_attr->show)
-               ret = childless_attr->show(childless, page);
-       return ret;
-}
-
-static ssize_t childless_attr_store(struct config_item *item,
-                                   struct configfs_attribute *attr,
-                                   const char *page, size_t count)
-{
-       struct childless *childless = to_childless(item);
-       struct childless_attribute *childless_attr =
-               container_of(attr, struct childless_attribute, attr);
-       ssize_t ret = -EINVAL;
-
-       if (childless_attr->store)
-               ret = childless_attr->store(childless, page, count);
-       return ret;
-}
-
-static struct configfs_item_operations childless_item_ops = {
-       .show_attribute         = childless_attr_show,
-       .store_attribute        = childless_attr_store,
-};
-
-static struct config_item_type childless_type = {
-       .ct_item_ops    = &childless_item_ops,
-       .ct_attrs       = childless_attrs,
-       .ct_owner       = THIS_MODULE,
-};
-
-static struct childless childless_subsys = {
-       .subsys = {
-               .su_group = {
-                       .cg_item = {
-                               .ci_namebuf = "01-childless",
-                               .ci_type = &childless_type,
-                       },
-               },
-       },
-};
-
-
-/* ----------------------------------------------------------------- */
-
-/*
- * 02-simple-children
- *
- * This example merely has a simple one-attribute child.  Note that
- * there is no extra attribute structure, as the child's attribute is
- * known from the get-go.  Also, there is no container for the
- * subsystem, as it has no attributes of its own.
- */
-
-struct simple_child {
-       struct config_item item;
-       int storeme;
-};
-
-static inline struct simple_child *to_simple_child(struct config_item *item)
-{
-       return item ? container_of(item, struct simple_child, item) : NULL;
-}
-
-static struct configfs_attribute simple_child_attr_storeme = {
-       .ca_owner = THIS_MODULE,
-       .ca_name = "storeme",
-       .ca_mode = S_IRUGO | S_IWUSR,
-};
-
-static struct configfs_attribute *simple_child_attrs[] = {
-       &simple_child_attr_storeme,
-       NULL,
-};
-
-static ssize_t simple_child_attr_show(struct config_item *item,
-                                     struct configfs_attribute *attr,
-                                     char *page)
-{
-       ssize_t count;
-       struct simple_child *simple_child = to_simple_child(item);
-
-       count = sprintf(page, "%d\n", simple_child->storeme);
-
-       return count;
-}
-
-static ssize_t simple_child_attr_store(struct config_item *item,
-                                      struct configfs_attribute *attr,
-                                      const char *page, size_t count)
-{
-       struct simple_child *simple_child = to_simple_child(item);
-       unsigned long tmp;
-       char *p = (char *) page;
-
-       tmp = simple_strtoul(p, &p, 10);
-       if (!p || (*p && (*p != '\n')))
-               return -EINVAL;
-
-       if (tmp > INT_MAX)
-               return -ERANGE;
-
-       simple_child->storeme = tmp;
-
-       return count;
-}
-
-static void simple_child_release(struct config_item *item)
-{
-       kfree(to_simple_child(item));
-}
-
-static struct configfs_item_operations simple_child_item_ops = {
-       .release                = simple_child_release,
-       .show_attribute         = simple_child_attr_show,
-       .store_attribute        = simple_child_attr_store,
-};
-
-static struct config_item_type simple_child_type = {
-       .ct_item_ops    = &simple_child_item_ops,
-       .ct_attrs       = simple_child_attrs,
-       .ct_owner       = THIS_MODULE,
-};
-
-
-struct simple_children {
-       struct config_group group;
-};
-
-static inline struct simple_children *to_simple_children(struct config_item *item)
-{
-       return item ? container_of(to_config_group(item), struct simple_children, group) : NULL;
-}
-
-static struct config_item *simple_children_make_item(struct config_group *group, const char *name)
-{
-       struct simple_child *simple_child;
-
-       simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL);
-       if (!simple_child)
-               return ERR_PTR(-ENOMEM);
-
-       config_item_init_type_name(&simple_child->item, name,
-                                  &simple_child_type);
-
-       simple_child->storeme = 0;
-
-       return &simple_child->item;
-}
-
-static struct configfs_attribute simple_children_attr_description = {
-       .ca_owner = THIS_MODULE,
-       .ca_name = "description",
-       .ca_mode = S_IRUGO,
-};
-
-static struct configfs_attribute *simple_children_attrs[] = {
-       &simple_children_attr_description,
-       NULL,
-};
-
-static ssize_t simple_children_attr_show(struct config_item *item,
-                                        struct configfs_attribute *attr,
-                                        char *page)
-{
-       return sprintf(page,
-"[02-simple-children]\n"
-"\n"
-"This subsystem allows the creation of child config_items.  These\n"
-"items have only one attribute that is readable and writeable.\n");
-}
-
-static void simple_children_release(struct config_item *item)
-{
-       kfree(to_simple_children(item));
-}
-
-static struct configfs_item_operations simple_children_item_ops = {
-       .release        = simple_children_release,
-       .show_attribute = simple_children_attr_show,
-};
-
-/*
- * Note that, since no extra work is required on ->drop_item(),
- * no ->drop_item() is provided.
- */
-static struct configfs_group_operations simple_children_group_ops = {
-       .make_item      = simple_children_make_item,
-};
-
-static struct config_item_type simple_children_type = {
-       .ct_item_ops    = &simple_children_item_ops,
-       .ct_group_ops   = &simple_children_group_ops,
-       .ct_attrs       = simple_children_attrs,
-       .ct_owner       = THIS_MODULE,
-};
-
-static struct configfs_subsystem simple_children_subsys = {
-       .su_group = {
-               .cg_item = {
-                       .ci_namebuf = "02-simple-children",
-                       .ci_type = &simple_children_type,
-               },
-       },
-};
-
-
-/* ----------------------------------------------------------------- */
-
-/*
- * 03-group-children
- *
- * This example reuses the simple_children group from above.  However,
- * the simple_children group is not the subsystem itself, it is a
- * child of the subsystem.  Creation of a group in the subsystem creates
- * a new simple_children group.  That group can then have simple_child
- * children of its own.
- */
-
-static struct config_group *group_children_make_group(struct config_group *group, const char *name)
-{
-       struct simple_children *simple_children;
-
-       simple_children = kzalloc(sizeof(struct simple_children),
-                                 GFP_KERNEL);
-       if (!simple_children)
-               return ERR_PTR(-ENOMEM);
-
-       config_group_init_type_name(&simple_children->group, name,
-                                   &simple_children_type);
-
-       return &simple_children->group;
-}
-
-static struct configfs_attribute group_children_attr_description = {
-       .ca_owner = THIS_MODULE,
-       .ca_name = "description",
-       .ca_mode = S_IRUGO,
-};
-
-static struct configfs_attribute *group_children_attrs[] = {
-       &group_children_attr_description,
-       NULL,
-};
-
-static ssize_t group_children_attr_show(struct config_item *item,
-                                       struct configfs_attribute *attr,
-                                       char *page)
-{
-       return sprintf(page,
-"[03-group-children]\n"
-"\n"
-"This subsystem allows the creation of child config_groups.  These\n"
-"groups are like the subsystem simple-children.\n");
-}
-
-static struct configfs_item_operations group_children_item_ops = {
-       .show_attribute = group_children_attr_show,
-};
-
-/*
- * Note that, since no extra work is required on ->drop_item(),
- * no ->drop_item() is provided.
- */
-static struct configfs_group_operations group_children_group_ops = {
-       .make_group     = group_children_make_group,
-};
-
-static struct config_item_type group_children_type = {
-       .ct_item_ops    = &group_children_item_ops,
-       .ct_group_ops   = &group_children_group_ops,
-       .ct_attrs       = group_children_attrs,
-       .ct_owner       = THIS_MODULE,
-};
-
-static struct configfs_subsystem group_children_subsys = {
-       .su_group = {
-               .cg_item = {
-                       .ci_namebuf = "03-group-children",
-                       .ci_type = &group_children_type,
-               },
-       },
-};
-
-/* ----------------------------------------------------------------- */
-
-/*
- * We're now done with our subsystem definitions.
- * For convenience in this module, here's a list of them all.  It
- * allows the init function to easily register them.  Most modules
- * will only have one subsystem, and will only call register_subsystem
- * on it directly.
- */
-static struct configfs_subsystem *example_subsys[] = {
-       &childless_subsys.subsys,
-       &simple_children_subsys,
-       &group_children_subsys,
-       NULL,
-};
-
-static int __init configfs_example_init(void)
-{
-       int ret;
-       int i;
-       struct configfs_subsystem *subsys;
-
-       for (i = 0; example_subsys[i]; i++) {
-               subsys = example_subsys[i];
-
-               config_group_init(&subsys->su_group);
-               mutex_init(&subsys->su_mutex);
-               ret = configfs_register_subsystem(subsys);
-               if (ret) {
-                       printk(KERN_ERR "Error %d while registering subsystem %s\n",
-                              ret,
-                              subsys->su_group.cg_item.ci_namebuf);
-                       goto out_unregister;
-               }
-       }
-
-       return 0;
-
-out_unregister:
-       for (i--; i >= 0; i--)
-               configfs_unregister_subsystem(example_subsys[i]);
-
-       return ret;
-}
-
-static void __exit configfs_example_exit(void)
-{
-       int i;
-
-       for (i = 0; example_subsys[i]; i++)
-               configfs_unregister_subsystem(example_subsys[i]);
-}
-
-module_init(configfs_example_init);
-module_exit(configfs_example_exit);
-MODULE_LICENSE("GPL");
diff --git a/Documentation/filesystems/configfs/configfs_example_macros.c b/Documentation/filesystems/configfs/configfs_example_macros.c
deleted file mode 100644 (file)
index 327dfbc..0000000
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * vim: noexpandtab ts=8 sts=0 sw=8:
- *
- * configfs_example_macros.c - This file is a demonstration module
- *      containing a number of configfs subsystems.  It uses the helper
- *      macros defined by configfs.h
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 021110-1307, USA.
- *
- * Based on sysfs:
- *     sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
- *
- * configfs Copyright (C) 2005 Oracle.  All rights reserved.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-
-#include <linux/configfs.h>
-
-
-
-/*
- * 01-childless
- *
- * This first example is a childless subsystem.  It cannot create
- * any config_items.  It just has attributes.
- *
- * Note that we are enclosing the configfs_subsystem inside a container.
- * This is not necessary if a subsystem has no attributes directly
- * on the subsystem.  See the next example, 02-simple-children, for
- * such a subsystem.
- */
-
-struct childless {
-       struct configfs_subsystem subsys;
-       int showme;
-       int storeme;
-};
-
-static inline struct childless *to_childless(struct config_item *item)
-{
-       return item ? container_of(to_configfs_subsystem(to_config_group(item)), struct childless, subsys) : NULL;
-}
-
-CONFIGFS_ATTR_STRUCT(childless);
-#define CHILDLESS_ATTR(_name, _mode, _show, _store)    \
-struct childless_attribute childless_attr_##_name = __CONFIGFS_ATTR(_name, _mode, _show, _store)
-#define CHILDLESS_ATTR_RO(_name, _show)        \
-struct childless_attribute childless_attr_##_name = __CONFIGFS_ATTR_RO(_name, _show);
-
-static ssize_t childless_showme_read(struct childless *childless,
-                                    char *page)
-{
-       ssize_t pos;
-
-       pos = sprintf(page, "%d\n", childless->showme);
-       childless->showme++;
-
-       return pos;
-}
-
-static ssize_t childless_storeme_read(struct childless *childless,
-                                     char *page)
-{
-       return sprintf(page, "%d\n", childless->storeme);
-}
-
-static ssize_t childless_storeme_write(struct childless *childless,
-                                      const char *page,
-                                      size_t count)
-{
-       unsigned long tmp;
-       char *p = (char *) page;
-
-       tmp = simple_strtoul(p, &p, 10);
-       if (!p || (*p && (*p != '\n')))
-               return -EINVAL;
-
-       if (tmp > INT_MAX)
-               return -ERANGE;
-
-       childless->storeme = tmp;
-
-       return count;
-}
-
-static ssize_t childless_description_read(struct childless *childless,
-                                         char *page)
-{
-       return sprintf(page,
-"[01-childless]\n"
-"\n"
-"The childless subsystem is the simplest possible subsystem in\n"
-"configfs.  It does not support the creation of child config_items.\n"
-"It only has a few attributes.  In fact, it isn't much different\n"
-"than a directory in /proc.\n");
-}
-
-CHILDLESS_ATTR_RO(showme, childless_showme_read);
-CHILDLESS_ATTR(storeme, S_IRUGO | S_IWUSR, childless_storeme_read,
-              childless_storeme_write);
-CHILDLESS_ATTR_RO(description, childless_description_read);
-
-static struct configfs_attribute *childless_attrs[] = {
-       &childless_attr_showme.attr,
-       &childless_attr_storeme.attr,
-       &childless_attr_description.attr,
-       NULL,
-};
-
-CONFIGFS_ATTR_OPS(childless);
-static struct configfs_item_operations childless_item_ops = {
-       .show_attribute         = childless_attr_show,
-       .store_attribute        = childless_attr_store,
-};
-
-static struct config_item_type childless_type = {
-       .ct_item_ops    = &childless_item_ops,
-       .ct_attrs       = childless_attrs,
-       .ct_owner       = THIS_MODULE,
-};
-
-static struct childless childless_subsys = {
-       .subsys = {
-               .su_group = {
-                       .cg_item = {
-                               .ci_namebuf = "01-childless",
-                               .ci_type = &childless_type,
-                       },
-               },
-       },
-};
-
-
-/* ----------------------------------------------------------------- */
-
-/*
- * 02-simple-children
- *
- * This example merely has a simple one-attribute child.  Note that
- * there is no extra attribute structure, as the child's attribute is
- * known from the get-go.  Also, there is no container for the
- * subsystem, as it has no attributes of its own.
- */
-
-struct simple_child {
-       struct config_item item;
-       int storeme;
-};
-
-static inline struct simple_child *to_simple_child(struct config_item *item)
-{
-       return item ? container_of(item, struct simple_child, item) : NULL;
-}
-
-static struct configfs_attribute simple_child_attr_storeme = {
-       .ca_owner = THIS_MODULE,
-       .ca_name = "storeme",
-       .ca_mode = S_IRUGO | S_IWUSR,
-};
-
-static struct configfs_attribute *simple_child_attrs[] = {
-       &simple_child_attr_storeme,
-       NULL,
-};
-
-static ssize_t simple_child_attr_show(struct config_item *item,
-                                     struct configfs_attribute *attr,
-                                     char *page)
-{
-       ssize_t count;
-       struct simple_child *simple_child = to_simple_child(item);
-
-       count = sprintf(page, "%d\n", simple_child->storeme);
-
-       return count;
-}
-
-static ssize_t simple_child_attr_store(struct config_item *item,
-                                      struct configfs_attribute *attr,
-                                      const char *page, size_t count)
-{
-       struct simple_child *simple_child = to_simple_child(item);
-       unsigned long tmp;
-       char *p = (char *) page;
-
-       tmp = simple_strtoul(p, &p, 10);
-       if (!p || (*p && (*p != '\n')))
-               return -EINVAL;
-
-       if (tmp > INT_MAX)
-               return -ERANGE;
-
-       simple_child->storeme = tmp;
-
-       return count;
-}
-
-static void simple_child_release(struct config_item *item)
-{
-       kfree(to_simple_child(item));
-}
-
-static struct configfs_item_operations simple_child_item_ops = {
-       .release                = simple_child_release,
-       .show_attribute         = simple_child_attr_show,
-       .store_attribute        = simple_child_attr_store,
-};
-
-static struct config_item_type simple_child_type = {
-       .ct_item_ops    = &simple_child_item_ops,
-       .ct_attrs       = simple_child_attrs,
-       .ct_owner       = THIS_MODULE,
-};
-
-
-struct simple_children {
-       struct config_group group;
-};
-
-static inline struct simple_children *to_simple_children(struct config_item *item)
-{
-       return item ? container_of(to_config_group(item), struct simple_children, group) : NULL;
-}
-
-static struct config_item *simple_children_make_item(struct config_group *group, const char *name)
-{
-       struct simple_child *simple_child;
-
-       simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL);
-       if (!simple_child)
-               return ERR_PTR(-ENOMEM);
-
-       config_item_init_type_name(&simple_child->item, name,
-                                  &simple_child_type);
-
-       simple_child->storeme = 0;
-
-       return &simple_child->item;
-}
-
-static struct configfs_attribute simple_children_attr_description = {
-       .ca_owner = THIS_MODULE,
-       .ca_name = "description",
-       .ca_mode = S_IRUGO,
-};
-
-static struct configfs_attribute *simple_children_attrs[] = {
-       &simple_children_attr_description,
-       NULL,
-};
-
-static ssize_t simple_children_attr_show(struct config_item *item,
-                                        struct configfs_attribute *attr,
-                                        char *page)
-{
-       return sprintf(page,
-"[02-simple-children]\n"
-"\n"
-"This subsystem allows the creation of child config_items.  These\n"
-"items have only one attribute that is readable and writeable.\n");
-}
-
-static void simple_children_release(struct config_item *item)
-{
-       kfree(to_simple_children(item));
-}
-
-static struct configfs_item_operations simple_children_item_ops = {
-       .release        = simple_children_release,
-       .show_attribute = simple_children_attr_show,
-};
-
-/*
- * Note that, since no extra work is required on ->drop_item(),
- * no ->drop_item() is provided.
- */
-static struct configfs_group_operations simple_children_group_ops = {
-       .make_item      = simple_children_make_item,
-};
-
-static struct config_item_type simple_children_type = {
-       .ct_item_ops    = &simple_children_item_ops,
-       .ct_group_ops   = &simple_children_group_ops,
-       .ct_attrs       = simple_children_attrs,
-       .ct_owner       = THIS_MODULE,
-};
-
-static struct configfs_subsystem simple_children_subsys = {
-       .su_group = {
-               .cg_item = {
-                       .ci_namebuf = "02-simple-children",
-                       .ci_type = &simple_children_type,
-               },
-       },
-};
-
-
-/* ----------------------------------------------------------------- */
-
-/*
- * 03-group-children
- *
- * This example reuses the simple_children group from above.  However,
- * the simple_children group is not the subsystem itself, it is a
- * child of the subsystem.  Creation of a group in the subsystem creates
- * a new simple_children group.  That group can then have simple_child
- * children of its own.
- */
-
-static struct config_group *group_children_make_group(struct config_group *group, const char *name)
-{
-       struct simple_children *simple_children;
-
-       simple_children = kzalloc(sizeof(struct simple_children),
-                                 GFP_KERNEL);
-       if (!simple_children)
-               return ERR_PTR(-ENOMEM);
-
-       config_group_init_type_name(&simple_children->group, name,
-                                   &simple_children_type);
-
-       return &simple_children->group;
-}
-
-static struct configfs_attribute group_children_attr_description = {
-       .ca_owner = THIS_MODULE,
-       .ca_name = "description",
-       .ca_mode = S_IRUGO,
-};
-
-static struct configfs_attribute *group_children_attrs[] = {
-       &group_children_attr_description,
-       NULL,
-};
-
-static ssize_t group_children_attr_show(struct config_item *item,
-                                       struct configfs_attribute *attr,
-                                       char *page)
-{
-       return sprintf(page,
-"[03-group-children]\n"
-"\n"
-"This subsystem allows the creation of child config_groups.  These\n"
-"groups are like the subsystem simple-children.\n");
-}
-
-static struct configfs_item_operations group_children_item_ops = {
-       .show_attribute = group_children_attr_show,
-};
-
-/*
- * Note that, since no extra work is required on ->drop_item(),
- * no ->drop_item() is provided.
- */
-static struct configfs_group_operations group_children_group_ops = {
-       .make_group     = group_children_make_group,
-};
-
-static struct config_item_type group_children_type = {
-       .ct_item_ops    = &group_children_item_ops,
-       .ct_group_ops   = &group_children_group_ops,
-       .ct_attrs       = group_children_attrs,
-       .ct_owner       = THIS_MODULE,
-};
-
-static struct configfs_subsystem group_children_subsys = {
-       .su_group = {
-               .cg_item = {
-                       .ci_namebuf = "03-group-children",
-                       .ci_type = &group_children_type,
-               },
-       },
-};
-
-/* ----------------------------------------------------------------- */
-
-/*
- * We're now done with our subsystem definitions.
- * For convenience in this module, here's a list of them all.  It
- * allows the init function to easily register them.  Most modules
- * will only have one subsystem, and will only call register_subsystem
- * on it directly.
- */
-static struct configfs_subsystem *example_subsys[] = {
-       &childless_subsys.subsys,
-       &simple_children_subsys,
-       &group_children_subsys,
-       NULL,
-};
-
-static int __init configfs_example_init(void)
-{
-       int ret;
-       int i;
-       struct configfs_subsystem *subsys;
-
-       for (i = 0; example_subsys[i]; i++) {
-               subsys = example_subsys[i];
-
-               config_group_init(&subsys->su_group);
-               mutex_init(&subsys->su_mutex);
-               ret = configfs_register_subsystem(subsys);
-               if (ret) {
-                       printk(KERN_ERR "Error %d while registering subsystem %s\n",
-                              ret,
-                              subsys->su_group.cg_item.ci_namebuf);
-                       goto out_unregister;
-               }
-       }
-
-       return 0;
-
-out_unregister:
-       for (i--; i >= 0; i--)
-               configfs_unregister_subsystem(example_subsys[i]);
-
-       return ret;
-}
-
-static void __exit configfs_example_exit(void)
-{
-       int i;
-
-       for (i = 0; example_subsys[i]; i++)
-               configfs_unregister_subsystem(example_subsys[i]);
-}
-
-module_init(configfs_example_init);
-module_exit(configfs_example_exit);
-MODULE_LICENSE("GPL");
index 6db0e5d1da07ee52d13f5997b84b3b10ef43e2dd..28091457b71ae89357530b351322f6a59c35bc9e 100644 (file)
@@ -1,4 +1,5 @@
-Written by: Neil Brown <neilb@suse.de>
+Written by: Neil Brown
+Please see MAINTAINERS file for where to send questions.
 
 Overlay Filesystem
 ==================
index 4636b94518da706012dc0677ef9fc6bd5265b1f4..05fd83bb35967a2d92c9fac588a15fb2b3532beb 100644 (file)
@@ -681,7 +681,7 @@ solution for a couple of reasons:
     addr.can_family = AF_CAN;
     addr.can_ifindex = ifr.ifr_ifindex;
 
-    connect(s, (struct sockaddr *)&addr, sizeof(addr))
+    connect(s, (struct sockaddr *)&addr, sizeof(addr));
 
     (..)
 
index 197a0b6b058215c60f3d79f3f40cc2aca4504013..e894de69915a38d3abd81b40e4b0e21a261fadcd 100644 (file)
@@ -62,6 +62,12 @@ DAX: File system extensions to bypass the page cache and block layer to
 mmap persistent memory, from a PMEM block device, directly into a
 process address space.
 
+DSM: Device Specific Method: ACPI method to to control specific
+device - in this case the firmware.
+
+DCR: NVDIMM Control Region Structure defined in ACPI 6 Section 5.2.25.5.
+It defines a vendor-id, device-id, and interface format for a given DIMM.
+
 BTT: Block Translation Table: Persistent memory is byte addressable.
 Existing software may have an expectation that the power-fail-atomicity
 of writes is at least one sector, 512 bytes.  The BTT is an indirection
@@ -133,16 +139,16 @@ device driver:
     registered, can be immediately attached to nd_pmem.
 
     2. BLK (nd_blk.ko): This driver performs I/O using a set of platform
-    defined apertures.  A set of apertures will all access just one DIMM.
-    Multiple windows allow multiple concurrent accesses, much like
+    defined apertures.  A set of apertures will access just one DIMM.
+    Multiple windows (apertures) allow multiple concurrent accesses, much like
     tagged-command-queuing, and would likely be used by different threads or
     different CPUs.
 
     The NFIT specification defines a standard format for a BLK-aperture, but
     the spec also allows for vendor specific layouts, and non-NFIT BLK
-    implementations may other designs for BLK I/O.  For this reason "nd_blk"
-    calls back into platform-specific code to perform the I/O.  One such
-    implementation is defined in the "Driver Writer's Guide" and "DSM
+    implementations may have other designs for BLK I/O.  For this reason
+    "nd_blk" calls back into platform-specific code to perform the I/O.
+    One such implementation is defined in the "Driver Writer's Guide" and "DSM
     Interface Example".
 
 
@@ -152,7 +158,7 @@ Why BLK?
 While PMEM provides direct byte-addressable CPU-load/store access to
 NVDIMM storage, it does not provide the best system RAS (recovery,
 availability, and serviceability) model.  An access to a corrupted
-system-physical-address address causes a cpu exception while an access
+system-physical-address address causes a CPU exception while an access
 to a corrupted address through an BLK-aperture causes that block window
 to raise an error status in a register.  The latter is more aligned with
 the standard error model that host-bus-adapter attached disks present.
@@ -162,7 +168,7 @@ data could be interleaved in an opaque hardware specific manner across
 several DIMMs.
 
 PMEM vs BLK
-BLK-apertures solve this RAS problem, but their presence is also the
+BLK-apertures solve these RAS problems, but their presence is also the
 major contributing factor to the complexity of the ND subsystem.  They
 complicate the implementation because PMEM and BLK alias in DPA space.
 Any given DIMM's DPA-range may contribute to one or more
@@ -220,8 +226,8 @@ socket.  Each unique interface (BLK or PMEM) to DPA space is identified
 by a region device with a dynamically assigned id (REGION0 - REGION5).
 
     1. The first portion of DIMM0 and DIMM1 are interleaved as REGION0. A
-    single PMEM namespace is created in the REGION0-SPA-range that spans
-    DIMM0 and DIMM1 with a user-specified name of "pm0.0". Some of that
+    single PMEM namespace is created in the REGION0-SPA-range that spans most
+    of DIMM0 and DIMM1 with a user-specified name of "pm0.0". Some of that
     interleaved system-physical-address range is reclaimed as BLK-aperture
     accessed space starting at DPA-offset (a) into each DIMM.  In that
     reclaimed space we create two BLK-aperture "namespaces" from REGION2 and
@@ -230,13 +236,13 @@ by a region device with a dynamically assigned id (REGION0 - REGION5).
 
     2. In the last portion of DIMM0 and DIMM1 we have an interleaved
     system-physical-address range, REGION1, that spans those two DIMMs as
-    well as DIMM2 and DIMM3.  Some of REGION1 allocated to a PMEM namespace
-    named "pm1.0" the rest is reclaimed in 4 BLK-aperture namespaces (for
+    well as DIMM2 and DIMM3.  Some of REGION1 is allocated to a PMEM namespace
+    named "pm1.0", the rest is reclaimed in 4 BLK-aperture namespaces (for
     each DIMM in the interleave set), "blk2.1", "blk3.1", "blk4.0", and
     "blk5.0".
 
     3. The portion of DIMM2 and DIMM3 that do not participate in the REGION1
-    interleaved system-physical-address range (i.e. the DPA address below
+    interleaved system-physical-address range (i.e. the DPA address past
     offset (b) are also included in the "blk4.0" and "blk5.0" namespaces.
     Note, that this example shows that BLK-aperture namespaces don't need to
     be contiguous in DPA-space.
@@ -252,15 +258,15 @@ LIBNVDIMM Kernel Device Model and LIBNDCTL Userspace API
 
 What follows is a description of the LIBNVDIMM sysfs layout and a
 corresponding object hierarchy diagram as viewed through the LIBNDCTL
-api.  The example sysfs paths and diagrams are relative to the Example
+API.  The example sysfs paths and diagrams are relative to the Example
 NVDIMM Platform which is also the LIBNVDIMM bus used in the LIBNDCTL unit
 test.
 
 LIBNDCTL: Context
-Every api call in the LIBNDCTL library requires a context that holds the
+Every API call in the LIBNDCTL library requires a context that holds the
 logging parameters and other library instance state.  The library is
 based on the libabc template:
-https://git.kernel.org/cgit/linux/kernel/git/kay/libabc.git/
+https://git.kernel.org/cgit/linux/kernel/git/kay/libabc.git
 
 LIBNDCTL: instantiate a new library context example
 
@@ -409,7 +415,7 @@ Bit 31:28 Reserved
 LIBNVDIMM/LIBNDCTL: Region
 ----------------------
 
-A generic REGION device is registered for each PMEM range orBLK-aperture
+A generic REGION device is registered for each PMEM range or BLK-aperture
 set.  Per the example there are 6 regions: 2 PMEM and 4 BLK-aperture
 sets on the "nfit_test.0" bus.  The primary role of regions are to be a
 container of "mappings".  A mapping is a tuple of <DIMM,
@@ -509,7 +515,7 @@ At first glance it seems since NFIT defines just PMEM and BLK interface
 types that we should simply name REGION devices with something derived
 from those type names.  However, the ND subsystem explicitly keeps the
 REGION name generic and expects userspace to always consider the
-region-attributes for 4 reasons:
+region-attributes for four reasons:
 
     1. There are already more than two REGION and "namespace" types.  For
     PMEM there are two subtypes.  As mentioned previously we have PMEM where
@@ -698,8 +704,8 @@ static int configure_namespace(struct ndctl_region *region,
 
 Why the Term "namespace"?
 
-    1. Why not "volume" for instance?  "volume" ran the risk of confusing ND
-    as a volume manager like device-mapper.
+    1. Why not "volume" for instance?  "volume" ran the risk of confusing
+    ND (libnvdimm subsystem) to a volume manager like device-mapper.
 
     2. The term originated to describe the sub-devices that can be created
     within a NVME controller (see the nvme specification:
@@ -774,13 +780,14 @@ block" needs to be destroyed.  Note, that to destroy a BTT the media
 needs to be written in raw mode.  By default, the kernel will autodetect
 the presence of a BTT and disable raw mode.  This autodetect behavior
 can be suppressed by enabling raw mode for the namespace via the
-ndctl_namespace_set_raw_mode() api.
+ndctl_namespace_set_raw_mode() API.
 
 
 Summary LIBNDCTL Diagram
 ------------------------
 
-For the given example above, here is the view of the objects as seen by the LIBNDCTL api:
+For the given example above, here is the view of the objects as seen by the
+LIBNDCTL API:
             +---+
             |CTX|    +---------+   +--------------+  +---------------+
             +-+-+  +-> REGION0 +---> NAMESPACE0.0 +--> PMEM8 "pm0.0" |
index f29fa550665af92dba9248113de5be639c10c885..b3211af63b7956c1f4325a87fb08b52de959692a 100644 (file)
@@ -569,7 +569,9 @@ Debugging code is now compiled in by default but debugging is turned off
 with the kernel module parameter debug_flag defaulting to 0.  Debugging
 can still be switched on and off with an ioctl.  To enable debug at
 module load time add debug_flag=1 to the module load options, the
-debugging output is not voluminous.
+debugging output is not voluminous. Debugging can also be enabled
+and disabled by writing a '0' (disable) or '1' (enable) to the sysfs
+file /sys/bus/scsi/drivers/st/debug_flag.
 
 If the tape seems to hang, I would be very interested to hear where
 the driver is waiting. With the command 'ps -l' you can see the state
index cda56df9b8a7ce591f3eb254cad1d423c0a856c5..7d370c9b1450c5fc5a2230d086026fa1c7d59ab7 100755 (executable)
@@ -203,8 +203,6 @@ def tcm_mod_build_configfs(proto_ident, fabric_mod_dir_var, fabric_mod_name):
        buf += "#include <scsi/scsi_proto.h>\n\n"
        buf += "#include <target/target_core_base.h>\n"
        buf += "#include <target/target_core_fabric.h>\n"
-       buf += "#include <target/target_core_fabric_configfs.h>\n"
-       buf += "#include <target/configfs_macros.h>\n\n"
        buf += "#include \"" + fabric_mod_name + "_base.h\"\n"
        buf += "#include \"" + fabric_mod_name + "_fabric.h\"\n\n"
 
@@ -283,19 +281,6 @@ def tcm_mod_build_configfs(proto_ident, fabric_mod_dir_var, fabric_mod_name):
        buf += "                                struct " + fabric_mod_name + "_" + fabric_mod_port + ", " + fabric_mod_port + "_wwn);\n"
        buf += "        kfree(" + fabric_mod_port + ");\n"
        buf += "}\n\n"
-       buf += "static ssize_t " + fabric_mod_name + "_wwn_show_attr_version(\n"
-       buf += "        struct target_fabric_configfs *tf,\n"
-       buf += "        char *page)\n"
-       buf += "{\n"
-       buf += "        return sprintf(page, \"" + fabric_mod_name.upper() + " fabric module %s on %s/%s\"\n"
-       buf += "                \"on \"UTS_RELEASE\"\\n\", " + fabric_mod_name.upper() + "_VERSION, utsname()->sysname,\n"
-       buf += "                utsname()->machine);\n"
-       buf += "}\n\n"
-       buf += "TF_WWN_ATTR_RO(" + fabric_mod_name + ", version);\n\n"
-       buf += "static struct configfs_attribute *" + fabric_mod_name + "_wwn_attrs[] = {\n"
-       buf += "        &" + fabric_mod_name + "_wwn_version.attr,\n"
-       buf += "        NULL,\n"
-       buf += "};\n\n"
 
        buf += "static const struct target_core_fabric_ops " + fabric_mod_name + "_ops = {\n"
        buf += "        .module                         = THIS_MODULE,\n"
@@ -328,8 +313,6 @@ def tcm_mod_build_configfs(proto_ident, fabric_mod_dir_var, fabric_mod_name):
        buf += "        .fabric_drop_wwn                = " + fabric_mod_name + "_drop_" + fabric_mod_port + ",\n"
        buf += "        .fabric_make_tpg                = " + fabric_mod_name + "_make_tpg,\n"
        buf += "        .fabric_drop_tpg                = " + fabric_mod_name + "_drop_tpg,\n"
-       buf += "\n"
-       buf += "        .tfc_wwn_attrs                  = " + fabric_mod_name + "_wwn_attrs,\n"
        buf += "};\n\n"
 
        buf += "static int __init " + fabric_mod_name + "_init(void)\n"
index c5bee001fbdcc4b36435dc64744c855552501624..e87b1bef6ea8171c5f8648c590f0661495e3e6e4 100644 (file)
@@ -2210,6 +2210,7 @@ F:        drivers/leds/leds-blinkm.c
 
 BLOCK LAYER
 M:     Jens Axboe <axboe@kernel.dk>
+L:     linux-block@vger.kernel.org
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git
 S:     Maintained
 F:     block/
@@ -2545,7 +2546,7 @@ F:        arch/c6x/
 
 CACHEFILES: FS-CACHE BACKEND FOR CACHING ON MOUNTED FILESYSTEMS
 M:     David Howells <dhowells@redhat.com>
-L:     linux-cachefs@redhat.com
+L:     linux-cachefs@redhat.com (moderated for non-subscribers)
 S:     Supported
 F:     Documentation/filesystems/caching/cachefiles.txt
 F:     fs/cachefiles/
@@ -4558,7 +4559,7 @@ F:        include/linux/frontswap.h
 
 FS-CACHE: LOCAL CACHING FOR NETWORK FILESYSTEMS
 M:     David Howells <dhowells@redhat.com>
-L:     linux-cachefs@redhat.com
+L:     linux-cachefs@redhat.com (moderated for non-subscribers)
 S:     Supported
 F:     Documentation/filesystems/caching/
 F:     fs/fscache/
@@ -5505,7 +5506,8 @@ S:        Supported
 F:     drivers/idle/intel_idle.c
 
 INTEL PSTATE DRIVER
-M:     Kristen Carlson Accardi <kristen@linux.intel.com>
+M:     Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+M:     Len Brown <lenb@kernel.org>
 L:     linux-pm@vger.kernel.org
 S:     Supported
 F:     drivers/cpufreq/intel_pstate.c
@@ -6914,13 +6916,21 @@ F:      drivers/scsi/megaraid.*
 F:     drivers/scsi/megaraid/
 
 MELLANOX ETHERNET DRIVER (mlx4_en)
-M:     Amir Vadai <amirv@mellanox.com>
+M:     Eugenia Emantayev <eugenia@mellanox.com>
 L:     netdev@vger.kernel.org
 S:     Supported
 W:     http://www.mellanox.com
 Q:     http://patchwork.ozlabs.org/project/netdev/list/
 F:     drivers/net/ethernet/mellanox/mlx4/en_*
 
+MELLANOX ETHERNET DRIVER (mlx5e)
+M:     Saeed Mahameed <saeedm@mellanox.com>
+L:     netdev@vger.kernel.org
+S:     Supported
+W:     http://www.mellanox.com
+Q:     http://patchwork.ozlabs.org/project/netdev/list/
+F:     drivers/net/ethernet/mellanox/mlx5/core/en_*
+
 MELLANOX ETHERNET SWITCH DRIVERS
 M:     Jiri Pirko <jiri@mellanox.com>
 M:     Ido Schimmel <idosch@mellanox.com>
@@ -10291,7 +10301,7 @@ F:      include/net/switchdev.h
 
 SYNOPSYS ARC ARCHITECTURE
 M:     Vineet Gupta <vgupta@synopsys.com>
-L:     linux-snps-arc@lists.infraded.org
+L:     linux-snps-arc@lists.infradead.org
 S:     Supported
 F:     arch/arc/
 F:     Documentation/devicetree/bindings/arc/*
@@ -10878,9 +10888,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 26de6c3298b1284c8971b47ec9271ea5d3adf90f..3a0234f50f36fb45461fe235c1a91addd4d6214b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 4
-PATCHLEVEL = 3
+PATCHLEVEL = 4
 SUBLEVEL = 0
-EXTRAVERSION =
+EXTRAVERSION = -rc1
 NAME = Blurry Fish Butt
 
 # *DOCUMENTATION*
index 44545354e9e85616b703f531787ed74def265bf5..1d694c1ef6d6bf33ccb17745db6e58e816915875 100644 (file)
@@ -57,11 +57,7 @@ struct task_struct;
  * A lot of busy-wait loops in SMP are based off of non-volatile data otherwise
  * get optimised away by gcc
  */
-#ifdef CONFIG_SMP
 #define cpu_relax()    __asm__ __volatile__ ("" : : : "memory")
-#else
-#define cpu_relax()    do { } while (0)
-#endif
 
 #define cpu_relax_lowlatency() cpu_relax()
 
index 445e63a10754fbdb0be82663af03f489282cfce5..cbfec79137bf77735fa675d0eb2be57da217ba63 100644 (file)
@@ -91,6 +91,25 @@ ENTRY(EV_DCError)
        flag 1
 END(EV_DCError)
 
+; ---------------------------------------------
+; Memory Error Exception Handler
+;   - Unlike ARCompact, handles Bus errors for both User/Kernel mode,
+;     Instruction fetch or Data access, under a single Exception Vector
+; ---------------------------------------------
+
+ENTRY(mem_service)
+
+       EXCEPTION_PROLOGUE
+
+       lr  r0, [efa]
+       mov r1, sp
+
+       FAKE_RET_FROM_EXCPN
+
+       bl  do_memory_error
+       b   ret_from_exception
+END(mem_service)
+
 ENTRY(EV_Misaligned)
 
        EXCEPTION_PROLOGUE
index 59f52035b4ea34a582b50b80e5db48893c1dc7bf..431433929189c8b63e8b3efe41ef03030fa8b86f 100644 (file)
@@ -142,16 +142,12 @@ int1_saved_reg:
        .zero 4
 
 /* Each Interrupt level needs its own scratch */
-#ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS
-
 ARCFP_DATA int2_saved_reg
        .type   int2_saved_reg, @object
        .size   int2_saved_reg, 4
 int2_saved_reg:
        .zero 4
 
-#endif
-
 ; ---------------------------------------------
        .section .text, "ax",@progbits
 
@@ -215,6 +211,31 @@ END(handle_interrupt_level2)
 
 #endif
 
+; ---------------------------------------------
+; User Mode Memory Bus Error Interrupt Handler
+; (Kernel mode memory errors handled via seperate exception vectors)
+; ---------------------------------------------
+ENTRY(mem_service)
+
+       INTERRUPT_PROLOGUE 2
+
+       mov r0, ilink2
+       mov r1, sp
+
+       ; User process needs to be killed with SIGBUS, but first need to get
+       ; out of the L2 interrupt context (drop to pure kernel mode) and jump
+       ; off to "C" code where SIGBUS in enqueued
+       lr  r3, [status32]
+       bclr r3, r3, STATUS_A2_BIT
+       or  r3, r3, (STATUS_E1_MASK|STATUS_E2_MASK)
+       sr  r3, [status32_l2]
+       mov ilink2, 1f
+       rtie
+1:
+       bl  do_memory_error
+       b   ret_from_exception
+END(mem_service)
+
 ; ---------------------------------------------
 ;  Level 1 ISR
 ; ---------------------------------------------
index 589abf5172d6a19047337e315fb2ff5ad1fab8a4..2efb0625331d6d5a6b6f8b1558a05e6e3cc5679e 100644 (file)
@@ -92,23 +92,6 @@ ENTRY(instr_service)
        b   ret_from_exception
 END(instr_service)
 
-; ---------------------------------------------
-; Memory Error Exception Handler
-; ---------------------------------------------
-
-ENTRY(mem_service)
-
-       EXCEPTION_PROLOGUE
-
-       lr  r0, [efa]
-       mov r1, sp
-
-       FAKE_RET_FROM_EXCPN
-
-       bl  do_memory_error
-       b   ret_from_exception
-END(mem_service)
-
 ; ---------------------------------------------
 ; Machine Check Exception Handler
 ; ---------------------------------------------
index 0cab0b8a57c5665e6686e9bef843fbfa51f141fd..f96c75edf30af5b38ecb7aa73710bc523dbfd366 100644 (file)
@@ -50,26 +50,26 @@ ENTRY(memcpy)
 
 ;;; if size <= 8
        cmp     r2, 8
-       bls.d   @smallchunk
+       bls.d   @.Lsmallchunk
        mov.f   lp_count, r2
 
        and.f   r4, r0, 0x03
        rsub    lp_count, r4, 4
-       lpnz    @aligndestination
+       lpnz    @.Laligndestination
        ;; LOOP BEGIN
        ldb.ab  r5, [r1,1]
        sub     r2, r2, 1
        stb.ab  r5, [r3,1]
-aligndestination:
+.Laligndestination:
 
 ;;; Check the alignment of the source
        and.f   r4, r1, 0x03
-       bnz.d   @sourceunaligned
+       bnz.d   @.Lsourceunaligned
 
 ;;; CASE 0: Both source and destination are 32bit aligned
 ;;; Convert len to Dwords, unfold x4
        lsr.f   lp_count, r2, ZOLSHFT
-       lpnz    @copy32_64bytes
+       lpnz    @.Lcopy32_64bytes
        ;; LOOP START
        LOADX (r6, r1)
        PREFETCH_READ (r1)
@@ -81,25 +81,25 @@ aligndestination:
        STOREX (r8, r3)
        STOREX (r10, r3)
        STOREX (r4, r3)
-copy32_64bytes:
+.Lcopy32_64bytes:
 
        and.f   lp_count, r2, ZOLAND ;Last remaining 31 bytes
-smallchunk:
-       lpnz    @copyremainingbytes
+.Lsmallchunk:
+       lpnz    @.Lcopyremainingbytes
        ;; LOOP START
        ldb.ab  r5, [r1,1]
        stb.ab  r5, [r3,1]
-copyremainingbytes:
+.Lcopyremainingbytes:
 
        j       [blink]
 ;;; END CASE 0
 
-sourceunaligned:
+.Lsourceunaligned:
        cmp     r4, 2
-       beq.d   @unalignedOffby2
+       beq.d   @.LunalignedOffby2
        sub     r2, r2, 1
 
-       bhi.d   @unalignedOffby3
+       bhi.d   @.LunalignedOffby3
        ldb.ab  r5, [r1, 1]
 
 ;;; CASE 1: The source is unaligned, off by 1
@@ -114,7 +114,7 @@ sourceunaligned:
        or      r5, r5, r6
 
        ;; Both src and dst are aligned
-       lpnz    @copy8bytes_1
+       lpnz    @.Lcopy8bytes_1
        ;; LOOP START
        ld.ab   r6, [r1, 4]
        prefetch [r1, 28]       ;Prefetch the next read location
@@ -131,7 +131,7 @@ sourceunaligned:
 
        st.ab   r7, [r3, 4]
        st.ab   r9, [r3, 4]
-copy8bytes_1:
+.Lcopy8bytes_1:
 
        ;; Write back the remaining 16bits
        EXTRACT_1 (r6, r5, 16)
@@ -141,14 +141,14 @@ copy8bytes_1:
        stb.ab  r5, [r3, 1]
 
        and.f   lp_count, r2, 0x07 ;Last 8bytes
-       lpnz    @copybytewise_1
+       lpnz    @.Lcopybytewise_1
        ;; LOOP START
        ldb.ab  r6, [r1,1]
        stb.ab  r6, [r3,1]
-copybytewise_1:
+.Lcopybytewise_1:
        j       [blink]
 
-unalignedOffby2:
+.LunalignedOffby2:
 ;;; CASE 2: The source is unaligned, off by 2
        ldh.ab  r5, [r1, 2]
        sub     r2, r2, 1
@@ -159,7 +159,7 @@ unalignedOffby2:
 #ifdef __BIG_ENDIAN__
        asl.nz  r5, r5, 16
 #endif
-       lpnz    @copy8bytes_2
+       lpnz    @.Lcopy8bytes_2
        ;; LOOP START
        ld.ab   r6, [r1, 4]
        prefetch [r1, 28]       ;Prefetch the next read location
@@ -176,7 +176,7 @@ unalignedOffby2:
 
        st.ab   r7, [r3, 4]
        st.ab   r9, [r3, 4]
-copy8bytes_2:
+.Lcopy8bytes_2:
 
 #ifdef __BIG_ENDIAN__
        lsr.nz  r5, r5, 16
@@ -184,14 +184,14 @@ copy8bytes_2:
        sth.ab  r5, [r3, 2]
 
        and.f   lp_count, r2, 0x07 ;Last 8bytes
-       lpnz    @copybytewise_2
+       lpnz    @.Lcopybytewise_2
        ;; LOOP START
        ldb.ab  r6, [r1,1]
        stb.ab  r6, [r3,1]
-copybytewise_2:
+.Lcopybytewise_2:
        j       [blink]
 
-unalignedOffby3:
+.LunalignedOffby3:
 ;;; CASE 3: The source is unaligned, off by 3
 ;;; Hence, I need to read 1byte for achieve the 32bit alignment
 
@@ -201,7 +201,7 @@ unalignedOffby3:
 #ifdef __BIG_ENDIAN__
        asl.ne  r5, r5, 24
 #endif
-       lpnz    @copy8bytes_3
+       lpnz    @.Lcopy8bytes_3
        ;; LOOP START
        ld.ab   r6, [r1, 4]
        prefetch [r1, 28]       ;Prefetch the next read location
@@ -218,7 +218,7 @@ unalignedOffby3:
 
        st.ab   r7, [r3, 4]
        st.ab   r9, [r3, 4]
-copy8bytes_3:
+.Lcopy8bytes_3:
 
 #ifdef __BIG_ENDIAN__
        lsr.nz  r5, r5, 24
@@ -226,11 +226,11 @@ copy8bytes_3:
        stb.ab  r5, [r3, 1]
 
        and.f   lp_count, r2, 0x07 ;Last 8bytes
-       lpnz    @copybytewise_3
+       lpnz    @.Lcopybytewise_3
        ;; LOOP START
        ldb.ab  r6, [r1,1]
        stb.ab  r6, [r3,1]
-copybytewise_3:
+.Lcopybytewise_3:
        j       [blink]
 
 END(memcpy)
index 63860adc4814083dd5365d83ffd790fa6d390ab4..f1967eeb32e757bb906580fecfce84a309df9983 100644 (file)
@@ -88,7 +88,7 @@ ex_saved_reg1:
 #ifdef CONFIG_SMP
        sr  r0, [ARC_REG_SCRATCH_DATA0] ; freeup r0 to code with
        GET_CPU_ID  r0                  ; get to per cpu scratch mem,
-       lsl r0, r0, L1_CACHE_SHIFT      ; cache line wide per cpu
+       asl r0, r0, L1_CACHE_SHIFT      ; cache line wide per cpu
        add r0, @ex_saved_reg1, r0
 #else
        st    r0, [@ex_saved_reg1]
@@ -107,7 +107,7 @@ ex_saved_reg1:
 .macro TLBMISS_RESTORE_REGS
 #ifdef CONFIG_SMP
        GET_CPU_ID  r0                  ; get to per cpu scratch mem
-       lsl r0, r0, L1_CACHE_SHIFT      ; each is cache line wide
+       asl r0, r0, L1_CACHE_SHIFT      ; each is cache line wide
        add r0, @ex_saved_reg1, r0
        ld_s  r3, [r0,12]
        ld_s  r2, [r0, 8]
@@ -256,7 +256,7 @@ ex_saved_reg1:
 
 .macro CONV_PTE_TO_TLB
        and    r3, r0, PTE_BITS_RWX     ;          r  w  x
-       lsl    r2, r3, 3                ; Kr Kw Kx 0  0  0 (GLOBAL, kernel only)
+       asl    r2, r3, 3                ; Kr Kw Kx 0  0  0 (GLOBAL, kernel only)
        and.f  0,  r0, _PAGE_GLOBAL
        or.z   r2, r2, r3               ; Kr Kw Kx Ur Uw Ux (!GLOBAL, user page)
 
index dde692812bc16ac70bc3bfba24fc14ba71d158a2..e4fe5145680889edd270edbc4d23655afdedf660 100644 (file)
@@ -10,7 +10,6 @@
 
 #include <linux/init.h>
 #include <asm/mach_desc.h>
-#include <asm/mcip.h>
 
 /*----------------------- Machine Descriptions ------------------------------
  *
index 851fe11c6069d47a714a87840d6a18a3278d0af8..9ac16a482ff1e690b9b6aa66a09225cec831966b 100644 (file)
@@ -27,6 +27,7 @@ config ARM64
        select CPU_PM if (SUSPEND || CPU_IDLE)
        select DCACHE_WORD_ACCESS
        select EDAC_SUPPORT
+       select FRAME_POINTER
        select GENERIC_ALLOCATOR
        select GENERIC_CLOCKEVENTS
        select GENERIC_CLOCKEVENTS_BROADCAST
index c24d6adc0420c78bb0efbf747101c87c0be9e81a..04fb73b973f155b477425ff1841e370f0ba87d41 100644 (file)
@@ -2,10 +2,6 @@ menu "Kernel hacking"
 
 source "lib/Kconfig.debug"
 
-config FRAME_POINTER
-       bool
-       default y
-
 config ARM64_PTDUMP
        bool "Export kernel pagetable layout to userspace via debugfs"
        depends on DEBUG_KERNEL
index 2f71f9cdd39c90be282b09d44bb0e795ab0181c6..bdd7aa358d2a5bc232dc510e789e61939416f700 100644 (file)
@@ -224,3 +224,4 @@ CONFIG_CRYPTO_GHASH_ARM64_CE=y
 CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
 CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
 CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y
+CONFIG_CRYPTO_CRC32_ARM64=y
index 74d0b8eb0799cb6635b999f7afb1c7e7c0a361bf..f61c84f6ba021aa9cd149c8b927680d86f6328b7 100644 (file)
@@ -233,7 +233,7 @@ __CMPXCHG_CASE( ,  ,  mb_8, dmb ish,  , l, "memory")
 #undef __CMPXCHG_CASE
 
 #define __CMPXCHG_DBL(name, mb, rel, cl)                               \
-__LL_SC_INLINE int                                                     \
+__LL_SC_INLINE long                                                    \
 __LL_SC_PREFIX(__cmpxchg_double##name(unsigned long old1,              \
                                      unsigned long old2,               \
                                      unsigned long new1,               \
index 1fce7908e6904a43791a385b5df76ef080ebefa2..197e06afbf71947eb505a893e53b73be73543be9 100644 (file)
@@ -387,7 +387,7 @@ __CMPXCHG_CASE(x,  ,  mb_8, al, "memory")
 #define __LL_SC_CMPXCHG_DBL(op)        __LL_SC_CALL(__cmpxchg_double##op)
 
 #define __CMPXCHG_DBL(name, mb, cl...)                                 \
-static inline int __cmpxchg_double##name(unsigned long old1,           \
+static inline long __cmpxchg_double##name(unsigned long old1,          \
                                         unsigned long old2,            \
                                         unsigned long new1,            \
                                         unsigned long new2,            \
index f3acf421ded4f55616abd7b68a7dcf83081e6f38..9819a9426b69a936017e508a6cab907040c9c67a 100644 (file)
@@ -80,6 +80,7 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
 #define _PAGE_DEFAULT          (PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL))
 
 #define PAGE_KERNEL            __pgprot(_PAGE_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE)
+#define PAGE_KERNEL_RO         __pgprot(_PAGE_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_RDONLY)
 #define PAGE_KERNEL_EXEC       __pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_WRITE)
 #define PAGE_KERNEL_EXEC_CONT  __pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_CONT)
 
index 0cd7b5947dfcfc635c8f6c7de4480f8b015d8fd6..2d4ca4bb0dd34a18ed6bfde2d5fa4e4319402903 100644 (file)
@@ -32,7 +32,7 @@
 
 #ifndef __ASSEMBLY__
 #include <linux/psci.h>
-#include <asm/types.h>
+#include <linux/types.h>
 #include <asm/ptrace.h>
 
 #define __KVM_HAVE_GUEST_DEBUG
index 52f0d7a5a1c2e0ea0629d51da7204723bd531f66..c8cf89223b5a8ceb3564e77cc5a6893e5c8eb99d 100644 (file)
@@ -696,7 +696,7 @@ static void cap_set_hwcap(const struct arm64_cpu_capabilities *cap)
 }
 
 /* Check if we have a particular HWCAP enabled */
-static bool cpus_have_hwcap(const struct arm64_cpu_capabilities *cap)
+static bool __maybe_unused cpus_have_hwcap(const struct arm64_cpu_capabilities *cap)
 {
        bool rc;
 
index 2bbdc0e4fd140581706d17b54b8a9089b77e7630..b1adc51b2c2e7682212554ba8276b5e7c25fbff5 100644 (file)
@@ -473,7 +473,7 @@ acpi_parse_gic_cpu_interface(struct acpi_subtable_header *header,
  * cpu logical map array containing MPIDR values related to logical
  * cpus. Assumes that cpu_logical_map(0) has already been initialized.
  */
-void __init of_parse_and_init_cpus(void)
+static void __init of_parse_and_init_cpus(void)
 {
        struct device_node *dn = NULL;
 
index 40f7b33a22dafce27c3491d181170760916aec04..fce95e17cf7f268fdfc0dd5c2d91e00b1152fb3f 100644 (file)
@@ -41,7 +41,7 @@ void notrace __cpu_suspend_save(struct cpu_suspend_ctx *ptr,
  * time the notifier runs debug exceptions might have been enabled already,
  * with HW breakpoints registers content still in an unknown state.
  */
-void (*hw_breakpoint_restore)(void *);
+static void (*hw_breakpoint_restore)(void *);
 void __init cpu_suspend_set_dbg_restorer(void (*hw_bp_restore)(void *))
 {
        /* Prevent multiple restore hook initializations */
index f6fe17d88da55d0b212b4d6ffe900f962e1e7bd5..b467fd0a384b36b87fe76ef7e50b4a28bda8bd01 100644 (file)
@@ -15,6 +15,9 @@ ccflags-y := -shared -fno-common -fno-builtin
 ccflags-y += -nostdlib -Wl,-soname=linux-vdso.so.1 \
                $(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
 
+# Disable gcov profiling for VDSO code
+GCOV_PROFILE := n
+
 # Workaround for bare-metal (ELF) toolchains that neglect to pass -shared
 # down to collect2, resulting in silent corruption of the vDSO image.
 ccflags-y += -Wl,-shared
index c2fa6b56613c23ba111c94310df522454e2ea732..e3f563c81c4802c1f9c519fe2bfc7317f8ab5467 100644 (file)
@@ -146,7 +146,7 @@ static void alloc_init_pte(pmd_t *pmd, unsigned long addr,
                if (((addr | next | phys) & ~CONT_MASK) == 0) {
                        /* a block of CONT_PTES  */
                        __populate_init_pte(pte, addr, next, phys,
-                                           prot | __pgprot(PTE_CONT));
+                                           __pgprot(pgprot_val(prot) | PTE_CONT));
                } else {
                        /*
                         * If the range being split is already inside of a
@@ -165,7 +165,7 @@ static void alloc_init_pte(pmd_t *pmd, unsigned long addr,
        } while (addr != end);
 }
 
-void split_pud(pud_t *old_pud, pmd_t *pmd)
+static void split_pud(pud_t *old_pud, pmd_t *pmd)
 {
        unsigned long addr = pud_pfn(*old_pud) << PAGE_SHIFT;
        pgprot_t prot = __pgprot(pud_val(*old_pud) ^ addr);
@@ -447,7 +447,7 @@ static void __init map_mem(void)
        memblock_set_current_limit(MEMBLOCK_ALLOC_ANYWHERE);
 }
 
-void __init fixup_executable(void)
+static void __init fixup_executable(void)
 {
 #ifdef CONFIG_DEBUG_RODATA
        /* now that we are actually fully mapped, make the start/end more fine grained */
@@ -691,7 +691,7 @@ void __set_fixmap(enum fixed_addresses idx,
 void *__init fixmap_remap_fdt(phys_addr_t dt_phys)
 {
        const u64 dt_virt_base = __fix_to_virt(FIX_FDT);
-       pgprot_t prot = PAGE_KERNEL | PTE_RDONLY;
+       pgprot_t prot = PAGE_KERNEL_RO;
        int size, offset;
        void *dt_virt;
 
index 98a26ce82d266f164021a9a7d93b2694bad7641d..aee5637ea436f2b5333af25c1db408790a6e0ac5 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * BPF JIT compiler for ARM64
  *
- * Copyright (C) 2014 Zi Shen Lim <zlim.lnx@gmail.com>
+ * Copyright (C) 2014-2015 Zi Shen Lim <zlim.lnx@gmail.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
@@ -35,6 +35,7 @@
        aarch64_insn_gen_comp_branch_imm(0, offset, Rt, A64_VARIANT(sf), \
                AARCH64_INSN_BRANCH_COMP_##type)
 #define A64_CBZ(sf, Rt, imm19) A64_COMP_BRANCH(sf, Rt, (imm19) << 2, ZERO)
+#define A64_CBNZ(sf, Rt, imm19) A64_COMP_BRANCH(sf, Rt, (imm19) << 2, NONZERO)
 
 /* Conditional branch (immediate) */
 #define A64_COND_BRANCH(cond, offset) \
index 64a8bc12f4a2e0de0334040bee748bad57a0a75b..7cf032bebf8c8fec26e6efe2d8c618737756973c 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * BPF JIT compiler for ARM64
  *
- * Copyright (C) 2014 Zi Shen Lim <zlim.lnx@gmail.com>
+ * Copyright (C) 2014-2015 Zi Shen Lim <zlim.lnx@gmail.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
@@ -50,7 +50,7 @@ static const int bpf2a64[] = {
        [BPF_REG_8] = A64_R(21),
        [BPF_REG_9] = A64_R(22),
        /* read-only frame pointer to access stack */
-       [BPF_REG_FP] = A64_FP,
+       [BPF_REG_FP] = A64_R(25),
        /* temporary register for internal BPF JIT */
        [TMP_REG_1] = A64_R(23),
        [TMP_REG_2] = A64_R(24),
@@ -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,35 @@ 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
+        *
+        *                         high
+        * original A64_SP =>   0:+-----+ BPF prologue
+        *                        |FP/LR|
+        * current A64_FP =>  -16:+-----+
+        *                        | ... | callee saved registers
+        *                        +-----+
+        *                        |     | x25/x26
+        * BPF fp register => -80:+-----+ <= (BPF_FP)
+        *                        |     |
+        *                        | ... | BPF prog stack
+        *                        |     |
+        *                        +-----+ <= (BPF_FP - MAX_BPF_STACK)
+        *                        |RSVD | JIT scratchpad
+        * current A64_SP =>      +-----+ <= (BPF_FP - STACK_SIZE)
+        *                        |     |
+        *                        | ... | Function call stack
+        *                        |     |
+        *                        +-----+
+        *                          low
+        *
+        */
+
+       /* Save FP and LR registers to stay align with ARM64 AAPCS */
+       emit(A64_PUSH(A64_FP, A64_LR, A64_SP), ctx);
+       emit(A64_MOV(1, A64_FP, A64_SP), ctx);
 
        /* Save callee-saved register */
        emit(A64_PUSH(r6, r7, A64_SP), ctx);
@@ -161,11 +192,14 @@ static void build_prologue(struct jit_ctx *ctx)
        if (ctx->tmp_used)
                emit(A64_PUSH(tmp1, tmp2, A64_SP), ctx);
 
-       /* Set up frame pointer */
+       /* Save fp (x25) and x26. SP requires 16 bytes alignment */
+       emit(A64_PUSH(fp, A64_R(26), A64_SP), ctx);
+
+       /* Set up BPF prog stack base register (x25) */
        emit(A64_MOV(1, fp, A64_SP), ctx);
 
-       /* Set up BPF stack */
-       emit(A64_SUB_I(1, A64_SP, A64_SP, stack_size), ctx);
+       /* Set up function call stack */
+       emit(A64_SUB_I(1, A64_SP, A64_SP, STACK_SIZE), ctx);
 
        /* Clear registers A and X */
        emit_a64_mov_i64(ra, 0, ctx);
@@ -182,13 +216,12 @@ 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);
 
        /* Restore callee-saved register */
        if (ctx->tmp_used)
@@ -196,8 +229,8 @@ static void build_epilogue(struct jit_ctx *ctx)
        emit(A64_POP(r8, r9, A64_SP), ctx);
        emit(A64_POP(r6, r7, A64_SP), ctx);
 
-       /* Restore frame pointer */
-       emit(A64_MOV(1, fp, A64_SP), ctx);
+       /* Restore FP/LR registers */
+       emit(A64_POP(A64_FP, A64_LR, A64_SP), ctx);
 
        /* Set return value */
        emit(A64_MOV(1, A64_R(0), r0), ctx);
@@ -225,6 +258,17 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
        u8 jmp_cond;
        s32 jmp_offset;
 
+#define check_imm(bits, imm) do {                              \
+       if ((((imm) > 0) && ((imm) >> (bits))) ||               \
+           (((imm) < 0) && (~(imm) >> (bits)))) {              \
+               pr_info("[%2d] imm=%d(0x%x) out of range\n",    \
+                       i, imm, imm);                           \
+               return -EINVAL;                                 \
+       }                                                       \
+} while (0)
+#define check_imm19(imm) check_imm(19, imm)
+#define check_imm26(imm) check_imm(26, imm)
+
        switch (code) {
        /* dst = src */
        case BPF_ALU | BPF_MOV | BPF_X:
@@ -258,15 +302,33 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
                break;
        case BPF_ALU | BPF_DIV | BPF_X:
        case BPF_ALU64 | BPF_DIV | BPF_X:
-               emit(A64_UDIV(is64, dst, dst, src), ctx);
-               break;
        case BPF_ALU | BPF_MOD | BPF_X:
        case BPF_ALU64 | BPF_MOD | BPF_X:
-               ctx->tmp_used = 1;
-               emit(A64_UDIV(is64, tmp, dst, src), ctx);
-               emit(A64_MUL(is64, tmp, tmp, src), ctx);
-               emit(A64_SUB(is64, dst, dst, tmp), ctx);
+       {
+               const u8 r0 = bpf2a64[BPF_REG_0];
+
+               /* if (src == 0) return 0 */
+               jmp_offset = 3; /* skip ahead to else path */
+               check_imm19(jmp_offset);
+               emit(A64_CBNZ(is64, src, jmp_offset), ctx);
+               emit(A64_MOVZ(1, r0, 0, 0), ctx);
+               jmp_offset = epilogue_offset(ctx);
+               check_imm26(jmp_offset);
+               emit(A64_B(jmp_offset), ctx);
+               /* else */
+               switch (BPF_OP(code)) {
+               case BPF_DIV:
+                       emit(A64_UDIV(is64, dst, dst, src), ctx);
+                       break;
+               case BPF_MOD:
+                       ctx->tmp_used = 1;
+                       emit(A64_UDIV(is64, tmp, dst, src), ctx);
+                       emit(A64_MUL(is64, tmp, tmp, src), ctx);
+                       emit(A64_SUB(is64, dst, dst, tmp), ctx);
+                       break;
+               }
                break;
+       }
        case BPF_ALU | BPF_LSH | BPF_X:
        case BPF_ALU64 | BPF_LSH | BPF_X:
                emit(A64_LSLV(is64, dst, dst, src), ctx);
@@ -393,17 +455,6 @@ emit_bswap_uxt:
                emit(A64_ASR(is64, dst, dst, imm), ctx);
                break;
 
-#define check_imm(bits, imm) do {                              \
-       if ((((imm) > 0) && ((imm) >> (bits))) ||               \
-           (((imm) < 0) && (~(imm) >> (bits)))) {              \
-               pr_info("[%2d] imm=%d(0x%x) out of range\n",    \
-                       i, imm, imm);                           \
-               return -EINVAL;                                 \
-       }                                                       \
-} while (0)
-#define check_imm19(imm) check_imm(19, imm)
-#define check_imm26(imm) check_imm(26, imm)
-
        /* JUMP off */
        case BPF_JMP | BPF_JA:
                jmp_offset = bpf2a64_offset(i + off, i, ctx);
@@ -606,7 +657,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 db589167838c01051ecbf6cf1c0289b6fbc60546..dd3ac75776ad982973d0ae2f5f2ccd0e58a53c7e 100644 (file)
@@ -16,6 +16,7 @@ config H8300
        select OF_EARLY_FLATTREE
        select HAVE_MEMBLOCK
        select HAVE_DMA_ATTRS
+       select CLKSRC_OF
 
 config RWSEM_GENERIC_SPINLOCK
        def_bool y
index 0d2d96e52d9fed374928fdd0be0466aca66827f1..e1c02ca230cb0a9dbd985b59b0646eb86f0d9891 100644 (file)
@@ -22,7 +22,9 @@ KBUILD_CFLAGS += -DUTS_SYSNAME=\"uClinux\"
 KBUILD_AFLAGS += $(aflags-y)
 LDFLAGS += $(ldflags-y)
 
+ifeq ($(CROSS_COMPILE),)
 CROSS_COMPILE := h8300-unknown-linux-
+endif
 
 core-y += arch/$(ARCH)/kernel/ arch/$(ARCH)/mm/
 ifneq '$(CONFIG_H8300_BUILTIN_DTB)' '""'
index 87d03b7ee97eeca9300544026bc62a4e6c04562f..d7bc3fa7f2c6b6b58ff35a5d97f1087d1d2c0b65 100644 (file)
@@ -14,11 +14,12 @@ OBJECTS = $(obj)/head.o $(obj)/misc.o
 # in order to suppress error message.
 #
 CONFIG_MEMORY_START     ?= 0x00400000
-CONFIG_BOOT_LINK_OFFSET ?= 0x00140000
+CONFIG_BOOT_LINK_OFFSET ?= 0x00280000
 IMAGE_OFFSET := $(shell printf "0x%08x" $$(($(CONFIG_MEMORY_START)+$(CONFIG_BOOT_LINK_OFFSET))))
 
 LIBGCC := $(shell $(CROSS-COMPILE)$(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
-LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -estartup $(obj)/vmlinux.lds
+LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -estartup -T $(obj)/vmlinux.lds \
+       --defsym output=$(CONFIG_MEMORY_START)
 
 $(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o $(LIBGCC) FORCE
        $(call if_changed,ld)
index 74c0d8cc40ba8ec8ef65717ca4eb8c9da8be514d..0436350c1df5813950ef04905581a9b07993e8aa 100644 (file)
@@ -9,8 +9,8 @@
        .section        .text..startup,"ax"
        .global startup
 startup:
+       mov.l   #startup, sp
        mov.l   er0, er4
-       mov.l   er0, sp
        mov.l   #__sbss, er0
        mov.l   #__ebss, er1
        sub.l   er0, er1
@@ -24,7 +24,7 @@ startup:
        bne     1b
        jsr     @decompress_kernel
        mov.l   er4, er0
-       jmp     @0x400000
+       jmp     @output
 
        .align  9
 fake_headers_as_bzImage:
index c4f2cfcb117bd6a6b9f1844c3a3313fa5e6be94a..6029c53518951a1253b498d77e1b4d963b9d36b9 100644 (file)
@@ -28,7 +28,7 @@ static unsigned long free_mem_end_ptr;
 
 extern char input_data[];
 extern int input_len;
-static unsigned char *output;
+extern char output[];
 
 #define HEAP_SIZE             0x10000
 
@@ -56,15 +56,10 @@ void *memcpy(void *dest, const void *src, size_t n)
 
 static void error(char *x)
 {
-
        while (1)
                ;       /* Halt */
 }
 
-#define STACK_SIZE (4096)
-long user_stack[STACK_SIZE];
-long *stack_start = &user_stack[STACK_SIZE];
-
 void decompress_kernel(void)
 {
        free_mem_ptr = (unsigned long)&_end;
index a0a3a0ed54ef17450ae9dbe7f7a38e0789098fdd..44fd209db88a69b60b885464d8d36a4f5d9a3f47 100644 (file)
@@ -27,6 +27,6 @@ SECTIONS
                 *(.bss*)
         . = ALIGN(0x4) ;
         __ebss = . ;
-        __end = . ;
         }
+        _end = . ;
 }
index dfb5c102f8dad0c4a60065d1bfa6d6d2e5dd20ae..4ce9fa874a577e559d5e916a24ddfb71eef6fcdd 100644 (file)
@@ -7,7 +7,7 @@
 
        chosen {
                bootargs = "console=ttySC2,38400";
-               stdout-path = <&sci2>;
+               stdout-path = &sci2;
        };
        aliases {
                serial0 = &sci0;
                compatible = "renesas,h8s2678-pll-clock";
                clocks = <&xclk>;
                #clock-cells = <0>;
-               reg = <0xfee03b 2>, <0xfee045 2>;
+               reg = <0xffff3b 1>, <0xffff45 1>;
        };
        core_clk: core_clk {
                compatible = "renesas,h8300-div-clock";
                clocks = <&pllclk>;
                #clock-cells = <0>;
-               reg = <0xfee03b 2>;
+               reg = <0xffff3b 1>;
                renesas,width = <3>;
        };
        fclk: fclk {
index 1d09b2f2e0fefd9625cd7e39f92e5e40dce2152f..bb837cded268446bbd67d7610daf374807d502bb 100644 (file)
@@ -36,20 +36,20 @@ static inline void ctrl_outl(unsigned long b, unsigned long addr)
        *(volatile unsigned long *)addr = b;
 }
 
-static inline void ctrl_bclr(int b, unsigned long addr)
+static inline void ctrl_bclr(int b, unsigned char *addr)
 {
        if (__builtin_constant_p(b))
-               __asm__("bclr %1,%0" : : "WU"(addr), "i"(b));
+               __asm__("bclr %1,%0" : "+WU"(*addr): "i"(b));
        else
-               __asm__("bclr %w1,%0" : : "WU"(addr), "r"(b));
+               __asm__("bclr %w1,%0" : "+WU"(*addr): "r"(b));
 }
 
-static inline void ctrl_bset(int b, unsigned long addr)
+static inline void ctrl_bset(int b, unsigned char *addr)
 {
        if (__builtin_constant_p(b))
-               __asm__("bset %1,%0" : : "WU"(addr), "i"(b));
+               __asm__("bset %1,%0" : "+WU"(*addr): "i"(b));
        else
-               __asm__("bset %w1,%0" : : "WU"(addr), "r"(b));
+               __asm__("bset %w1,%0" : "+WU"(*addr): "r"(b));
 }
 
 #endif /* __KERNEL__ */
index 544c30785ad4b81ced562cc7624430c22d99403b..b408fe660cf8ceab685de783220a2db991b4dfc3 100644 (file)
 
 #ifdef __KERNEL__
 
+/*
+ * Size of kernel stack for each process. This must be a power of 2...
+ */
+#define THREAD_SIZE_ORDER      1
+#define THREAD_SIZE            8192    /* 2 pages */
+
 #ifndef __ASSEMBLY__
 
 /*
@@ -46,14 +52,6 @@ struct thread_info {
 #define init_thread_info       (init_thread_union.thread_info)
 #define init_stack             (init_thread_union.stack)
 
-
-/*
- * Size of kernel stack for each process. This must be a power of 2...
- */
-#define THREAD_SIZE_ORDER      1
-#define THREAD_SIZE            8192    /* 2 pages */
-
-
 /* how to get the thread information struct from C */
 static inline struct thread_info *current_thread_info(void)
 {
index 0fd1fe65c0b8bc9710d6aed34a852f4f91618272..c772abe6d19ce0d4ff06f12c8d5fb004905c26c5 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/clk-provider.h>
 #include <linux/memblock.h>
 #include <linux/screen_info.h>
+#include <linux/clocksource.h>
 
 #include <asm/setup.h>
 #include <asm/irq.h>
@@ -252,4 +253,5 @@ void __init calibrate_delay(void)
 void __init time_init(void)
 {
        of_clk_init(NULL);
+       clocksource_probe();
 }
index 7c302dcf52494b51dabd50dd9dd31f8bb7e8b918..cb5dfb02c88d412cd67b33827da834a3770d0c7f 100644 (file)
@@ -1,5 +1,6 @@
 #include <asm-generic/vmlinux.lds.h>
 #include <asm/page.h>
+#include <asm/thread_info.h>
 
 #define ROMTOP 0x000000
 #define RAMTOP 0x400000
@@ -42,11 +43,10 @@ SECTIONS
        . = RAMTOP;
        _ramstart = .;
 #define ADDR(x) ROMEND
-#else
 #endif
        _sdata = . ;
        __data_start = . ;
-       RW_DATA_SECTION(0,0,0)
+       RW_DATA_SECTION(0, PAGE_SIZE, THREAD_SIZE)
 #if defined(CONFIG_ROMKERNEL)
 #undef ADDR
 #endif
index dd295335891a03dc2cfbb657883135749f38083e..5c3f688a5232f2690007a8e92a12ba76ae11b4a5 100644 (file)
@@ -17,6 +17,7 @@ obj- := $(platform-)
 obj-y += kernel/
 obj-y += mm/
 obj-y += net/
+obj-y += vdso/
 
 ifdef CONFIG_KVM
 obj-y += kvm/
index a424e46b50afaa85f5e081f5f9ee8e31887816bb..a96c81d1d22e6afce0973161639024e93346fd0b 100644 (file)
@@ -33,6 +33,7 @@ platforms += sibyte
 platforms += sni
 platforms += txx9
 platforms += vr41xx
+platforms += xilfpga
 
 # include the platform specific files
 include $(patsubst %, $(srctree)/arch/mips/%/Platform, $(platforms))
index e3aa5b0b4ef17771fbd2afa1557f29ee6a7a2b3d..71683a8533723866872de04f7194d07a28f33045 100644 (file)
@@ -5,6 +5,7 @@ config MIPS
        select ARCH_MIGHT_HAVE_PC_PARPORT
        select ARCH_MIGHT_HAVE_PC_SERIO
        select ARCH_USE_CMPXCHG_LOCKREF if 64BIT
+       select ARCH_USE_BUILTIN_BSWAP
        select HAVE_CONTEXT_TRACKING
        select HAVE_GENERIC_DMA_COHERENT
        select HAVE_IDE
@@ -60,6 +61,8 @@ config MIPS
        select SYSCTL_EXCEPTION_TRACE
        select HAVE_VIRT_CPU_ACCOUNTING_GEN
        select HAVE_IRQ_TIME_ACCOUNTING
+       select GENERIC_TIME_VSYSCALL
+       select ARCH_CLOCKSOURCE_DATA
 
 menu "Machine selection"
 
@@ -401,6 +404,28 @@ config MACH_PISTACHIO
        help
          This enables support for the IMG Pistachio SoC platform.
 
+config MACH_XILFPGA
+       bool "MIPSfpga Xilinx based boards"
+       select ARCH_REQUIRE_GPIOLIB
+       select BOOT_ELF32
+       select BOOT_RAW
+       select BUILTIN_DTB
+       select CEVT_R4K
+       select COMMON_CLK
+       select CSRC_R4K
+       select IRQ_MIPS_CPU
+       select LIBFDT
+       select MIPS_CPU_SCACHE
+       select SYS_HAS_EARLY_PRINTK
+       select SYS_HAS_CPU_MIPS32_R2
+       select SYS_SUPPORTS_32BIT_KERNEL
+       select SYS_SUPPORTS_LITTLE_ENDIAN
+       select SYS_SUPPORTS_ZBOOT_UART16550
+       select USE_OF
+       select USE_GENERIC_EARLY_PRINTK_8250
+       help
+         This enables support for the IMG University Program MIPSfpga platform.
+
 config MIPS_MALTA
        bool "MIPS Malta board"
        select ARCH_MAY_HAVE_PC_FDC
@@ -424,6 +449,7 @@ config MIPS_MALTA
        select MIPS_L1_CACHE_SHIFT_6
        select PCI_GT64XXX_PCI0
        select MIPS_MSC
+       select SMP_UP if SMP
        select SWAP_IO_SPACE
        select SYS_HAS_CPU_MIPS32_R1
        select SYS_HAS_CPU_MIPS32_R2
@@ -449,6 +475,8 @@ config MIPS_MALTA
        select SYS_SUPPORTS_ZBOOT
        select USE_OF
        select ZONE_DMA32 if 64BIT
+       select BUILTIN_DTB
+       select LIBFDT
        help
          This enables support for the MIPS Technologies Malta evaluation
          board.
@@ -964,6 +992,7 @@ source "arch/mips/loongson32/Kconfig"
 source "arch/mips/loongson64/Kconfig"
 source "arch/mips/netlogic/Kconfig"
 source "arch/mips/paravirt/Kconfig"
+source "arch/mips/xilfpga/Kconfig"
 
 endmenu
 
@@ -1036,6 +1065,9 @@ config CSRC_R4K
 config CSRC_SB1250
        bool
 
+config MIPS_CLOCK_VSYSCALL
+       def_bool CSRC_R4K || CLKSRC_MIPS_GIC
+
 config GPIO_TXX9
        select ARCH_REQUIRE_GPIOLIB
        bool
@@ -2529,6 +2561,9 @@ choice
        help
         Allows the configuration of the timer frequency.
 
+       config HZ_24
+               bool "24 HZ" if SYS_SUPPORTS_24HZ || SYS_SUPPORTS_ARBIT_HZ
+
        config HZ_48
                bool "48 HZ" if SYS_SUPPORTS_48HZ || SYS_SUPPORTS_ARBIT_HZ
 
@@ -2552,6 +2587,9 @@ choice
 
 endchoice
 
+config SYS_SUPPORTS_24HZ
+       bool
+
 config SYS_SUPPORTS_48HZ
        bool
 
@@ -2575,13 +2613,18 @@ config SYS_SUPPORTS_1024HZ
 
 config SYS_SUPPORTS_ARBIT_HZ
        bool
-       default y if !SYS_SUPPORTS_48HZ && !SYS_SUPPORTS_100HZ && \
-                    !SYS_SUPPORTS_128HZ && !SYS_SUPPORTS_250HZ && \
-                    !SYS_SUPPORTS_256HZ && !SYS_SUPPORTS_1000HZ && \
+       default y if !SYS_SUPPORTS_24HZ && \
+                    !SYS_SUPPORTS_48HZ && \
+                    !SYS_SUPPORTS_100HZ && \
+                    !SYS_SUPPORTS_128HZ && \
+                    !SYS_SUPPORTS_250HZ && \
+                    !SYS_SUPPORTS_256HZ && \
+                    !SYS_SUPPORTS_1000HZ && \
                     !SYS_SUPPORTS_1024HZ
 
 config HZ
        int
+       default 24 if HZ_24
        default 48 if HZ_48
        default 100 if HZ_100
        default 128 if HZ_128
@@ -2685,7 +2728,7 @@ config BUILTIN_DTB
        bool
 
 choice
-       prompt "Kernel appended dtb support" if OF
+       prompt "Kernel appended dtb support" if USE_OF
        default MIPS_NO_APPENDED_DTB
 
        config MIPS_NO_APPENDED_DTB
@@ -2693,6 +2736,20 @@ choice
                help
                  Do not enable appended dtb support.
 
+       config MIPS_ELF_APPENDED_DTB
+               bool "vmlinux"
+               help
+                 With this option, the boot code will look for a device tree binary
+                 DTB) included in the vmlinux ELF section .appended_dtb. By default
+                 it is empty and the DTB can be appended using binutils command
+                 objcopy:
+
+                   objcopy --update-section .appended_dtb=<filename>.dtb vmlinux
+
+                 This is meant as a backward compatiblity convenience for those
+                 systems with a bootloader that can't be upgraded to accommodate
+                 the documented boot protocol using a device tree.
+
        config MIPS_RAW_APPENDED_DTB
                bool "vmlinux.bin"
                help
@@ -2729,6 +2786,25 @@ choice
                  if you don't intend to always append a DTB.
 endchoice
 
+choice
+       prompt "Kernel command line type" if !CMDLINE_OVERRIDE
+       default MIPS_CMDLINE_FROM_DTB if USE_OF && !ATH79 && !MACH_INGENIC && \
+                                        !MIPS_MALTA && !MIPS_SEAD3 && \
+                                        !CAVIUM_OCTEON_SOC
+       default MIPS_CMDLINE_FROM_BOOTLOADER
+
+       config MIPS_CMDLINE_FROM_DTB
+               depends on USE_OF
+               bool "Dtb kernel arguments if available"
+
+       config MIPS_CMDLINE_DTB_EXTEND
+               depends on USE_OF
+               bool "Extend dtb kernel arguments with bootloader arguments"
+
+       config MIPS_CMDLINE_FROM_BOOTLOADER
+               bool "Bootloader kernel arguments if available"
+endchoice
+
 endmenu
 
 config LOCKDEP_SUPPORT
@@ -2739,6 +2815,10 @@ config STACKTRACE_SUPPORT
        bool
        default y
 
+config HAVE_LATENCYTOP_SUPPORT
+       bool
+       default y
+
 config PGTABLE_LEVELS
        int
        default 3 if 64BIT && !PAGE_SIZE_64KB
index e250524021aca8ec7e1b79bfd0b4f088d96f109d..f0e314ceb8baa84d36ea6664772f71df46ad003f 100644 (file)
@@ -113,4 +113,76 @@ config SPINLOCK_TEST
        help
          Add several files to the debugfs to test spinlock speed.
 
+if CPU_MIPSR6
+
+choice
+       prompt "Compact branch policy"
+       default MIPS_COMPACT_BRANCHES_OPTIMAL
+
+config MIPS_COMPACT_BRANCHES_NEVER
+       bool "Never (force delay slot branches)"
+       help
+         Pass the -mcompact-branches=never flag to the compiler in order to
+         force it to always emit branches with delay slots, and make no use
+         of the compact branch instructions introduced by MIPSr6. This is
+         useful if you suspect there may be an issue with compact branches in
+         either the compiler or the CPU.
+
+config MIPS_COMPACT_BRANCHES_OPTIMAL
+       bool "Optimal (use where beneficial)"
+       help
+         Pass the -mcompact-branches=optimal flag to the compiler in order for
+         it to make use of compact branch instructions where it deems them
+         beneficial, and use branches with delay slots elsewhere. This is the
+         default compiler behaviour, and should be used unless you have a
+         reason to choose otherwise.
+
+config MIPS_COMPACT_BRANCHES_ALWAYS
+       bool "Always (force compact branches)"
+       help
+         Pass the -mcompact-branches=always flag to the compiler in order to
+         force it to always emit compact branches, making no use of branch
+         instructions with delay slots. This can result in more compact code
+         which may be beneficial in some scenarios.
+
+endchoice
+
+endif # CPU_MIPSR6
+
+config SCACHE_DEBUGFS
+       bool "L2 cache debugfs entries"
+       depends on DEBUG_FS
+       help
+         Enable this to allow parts of the L2 cache configuration, such as
+         whether or not prefetching is enabled, to be exposed to userland
+         via debugfs.
+
+         If unsure, say N.
+
+menuconfig MIPS_CPS_NS16550
+       bool "CPS SMP NS16550 UART output"
+       depends on MIPS_CPS
+       help
+         Output debug information via an ns16550 compatible UART if exceptions
+         occur early in the boot process of a secondary core.
+
+if MIPS_CPS_NS16550
+
+config MIPS_CPS_NS16550_BASE
+       hex "UART Base Address"
+       default 0x1b0003f8 if MIPS_MALTA
+       help
+         The base address of the ns16550 compatible UART on which to output
+         debug information from the early stages of core startup.
+
+config MIPS_CPS_NS16550_SHIFT
+       int "UART Register Shift"
+       default 0 if MIPS_MALTA
+       help
+         The number of bits to shift ns16550 register indices by in order to
+         form their addresses. That is, log base 2 of the span between
+         adjacent ns16550 registers in the system.
+
+endif # MIPS_CPS_NS16550
+
 endmenu
index 252e347958f383354a597323078512846f592d52..3f70ba54ae21e909973ad9913eb71151fcc50492 100644 (file)
@@ -204,6 +204,10 @@ toolchain-msa                              := $(call cc-option-yn,$(mips-cflags) -mhard-float -mfp64 -Wa$(
 cflags-$(toolchain-msa)                        += -DTOOLCHAIN_SUPPORTS_MSA
 endif
 
+cflags-$(CONFIG_MIPS_COMPACT_BRANCHES_NEVER)   += -mcompact-branches=never
+cflags-$(CONFIG_MIPS_COMPACT_BRANCHES_OPTIMAL) += -mcompact-branches=optimal
+cflags-$(CONFIG_MIPS_COMPACT_BRANCHES_ALWAYS)  += -mcompact-branches=always
+
 #
 # Firmware support
 #
index 17503a05938e6c3848e950acd366361fd768ab0d..6d38948f0f1ed4a95f29d883cd7fb4abe65ed327 100644 (file)
@@ -105,11 +105,28 @@ static int bcm47xx_get_invariants(struct ssb_bus *bus,
                                  struct ssb_init_invariants *iv)
 {
        char buf[20];
+       int len, err;
 
        /* Fill boardinfo structure */
        memset(&iv->boardinfo, 0 , sizeof(struct ssb_boardinfo));
 
-       bcm47xx_fill_ssb_boardinfo(&iv->boardinfo, NULL);
+       len = bcm47xx_nvram_getenv("boardvendor", buf, sizeof(buf));
+       if (len > 0) {
+               err = kstrtou16(strim(buf), 0, &iv->boardinfo.vendor);
+               if (err)
+                       pr_warn("Couldn't parse nvram board vendor entry with value \"%s\"\n",
+                               buf);
+       }
+       if (!iv->boardinfo.vendor)
+               iv->boardinfo.vendor = SSB_BOARDVENDOR_BCM;
+
+       len = bcm47xx_nvram_getenv("boardtype", buf, sizeof(buf));
+       if (len > 0) {
+               err = kstrtou16(strim(buf), 0, &iv->boardinfo.type);
+               if (err)
+                       pr_warn("Couldn't parse nvram board type entry with value \"%s\"\n",
+                               buf);
+       }
 
        memset(&iv->sprom, 0, sizeof(struct ssb_sprom));
        bcm47xx_fill_sprom(&iv->sprom, NULL, false);
index 2d5c7a7f24bb943669d7c43fb66bee1482ff6412..a7e569c7968ea7e8bc1a1ce3e629fc54cc2710ee 100644 (file)
@@ -60,9 +60,9 @@ static int get_nvram_var(const char *prefix, const char *postfix,
 }
 
 #define NVRAM_READ_VAL(type)                                           \
-static void nvram_read_ ## type (const char *prefix,                   \
-                                const char *postfix, const char *name, \
-                                type *val, type allset, bool fallback) \
+static void nvram_read_ ## type(const char *prefix,                    \
+                               const char *postfix, const char *name,  \
+                               type *val, type allset, bool fallback)  \
 {                                                                      \
        char buf[100];                                                  \
        int err;                                                        \
@@ -422,7 +422,10 @@ static void bcm47xx_fill_sprom_path_r4589(struct ssb_sprom *sprom,
        int i;
 
        for (i = 0; i < ARRAY_SIZE(sprom->core_pwr_info); i++) {
-               struct ssb_sprom_core_pwr_info *pwr_info = &sprom->core_pwr_info[i];
+               struct ssb_sprom_core_pwr_info *pwr_info;
+
+               pwr_info = &sprom->core_pwr_info[i];
+
                snprintf(postfix, sizeof(postfix), "%i", i);
                nvram_read_u8(prefix, postfix, "maxp2ga",
                              &pwr_info->maxpwr_2g, 0, fallback);
@@ -470,7 +473,10 @@ static void bcm47xx_fill_sprom_path_r45(struct ssb_sprom *sprom,
        int i;
 
        for (i = 0; i < ARRAY_SIZE(sprom->core_pwr_info); i++) {
-               struct ssb_sprom_core_pwr_info *pwr_info = &sprom->core_pwr_info[i];
+               struct ssb_sprom_core_pwr_info *pwr_info;
+
+               pwr_info = &sprom->core_pwr_info[i];
+
                snprintf(postfix, sizeof(postfix), "%i", i);
                nvram_read_u16(prefix, postfix, "pa2gw3a",
                               &pwr_info->pa_2g[3], 0, fallback);
@@ -535,10 +541,11 @@ static void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom,
        nvram_read_macaddr(prefix, "il0macaddr", sprom->il0mac, fallback);
 
        /* The address prefix 00:90:4C is used by Broadcom in their initial
-          configuration. When a mac address with the prefix 00:90:4C is used
-          all devices from the same series are sharing the same mac address.
-          To prevent mac address collisions we replace them with a mac address
-          based on the base address. */
+        * configuration. When a mac address with the prefix 00:90:4C is used
+        * all devices from the same series are sharing the same mac address.
+        * To prevent mac address collisions we replace them with a mac address
+        * based on the base address.
+        */
        if (!bcm47xx_is_valid_mac(sprom->il0mac)) {
                u8 mac[6];
 
@@ -592,32 +599,23 @@ void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix,
        bcm47xx_sprom_fill_auto(sprom, prefix, fallback);
 }
 
-#ifdef CONFIG_BCM47XX_SSB
-void bcm47xx_fill_ssb_boardinfo(struct ssb_boardinfo *boardinfo,
-                               const char *prefix)
-{
-       nvram_read_u16(prefix, NULL, "boardvendor", &boardinfo->vendor, 0,
-                      true);
-       if (!boardinfo->vendor)
-               boardinfo->vendor = SSB_BOARDVENDOR_BCM;
-
-       nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0, true);
-}
-#endif
-
 #if defined(CONFIG_BCM47XX_SSB)
 static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out)
 {
        char prefix[10];
 
-       if (bus->bustype == SSB_BUSTYPE_PCI) {
+       switch (bus->bustype) {
+       case SSB_BUSTYPE_SSB:
+               bcm47xx_fill_sprom(out, NULL, false);
+               return 0;
+       case SSB_BUSTYPE_PCI:
                memset(out, 0, sizeof(struct ssb_sprom));
                snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
                         bus->host_pci->bus->number + 1,
                         PCI_SLOT(bus->host_pci->devfn));
                bcm47xx_fill_sprom(out, prefix, false);
                return 0;
-       } else {
+       default:
                pr_warn("Unable to fill SPROM for given bustype.\n");
                return -EINVAL;
        }
index 33727e7f0c79f756a004dc4d5fd964b31b3d6058..b2097c0d2ed78b554ab321c6620767d3ccd29f71 100644 (file)
@@ -7,6 +7,8 @@
  * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org>
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
@@ -31,7 +33,6 @@
 
 #include <uapi/linux/bcm933xx_hcs.h>
 
-#define PFX    "board_bcm963xx: "
 
 #define HCS_OFFSET_128K                        0x20000
 
@@ -740,7 +741,7 @@ int bcm63xx_get_fallback_sprom(struct ssb_bus *bus, struct ssb_sprom *out)
                memcpy(out, &bcm63xx_sprom, sizeof(struct ssb_sprom));
                return 0;
        } else {
-               printk(KERN_ERR PFX "unable to fill SPROM for given bustype.\n");
+               pr_err("unable to fill SPROM for given bustype\n");
                return -EINVAL;
        }
 }
@@ -784,7 +785,7 @@ void __init board_prom_init(void)
                         cfe[5], cfe[6], cfe[7], cfe[8], cfe[9]);
        else
                strcpy(cfe_version, "unknown");
-       printk(KERN_INFO PFX "CFE version: %s\n", cfe_version);
+       pr_info("CFE version: %s\n", cfe_version);
 
        bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET);
 
@@ -808,8 +809,7 @@ void __init board_prom_init(void)
                char name[17];
                memcpy(name, board_name, 16);
                name[16] = 0;
-               printk(KERN_ERR PFX "unknown bcm963xx board: %s\n",
-                      name);
+               pr_err("unknown bcm963xx board: %s\n", name);
                return;
        }
 
@@ -854,7 +854,7 @@ void __init board_setup(void)
 {
        if (!board.name[0])
                panic("unable to detect bcm963xx board");
-       printk(KERN_INFO PFX "board name: %s\n", board.name);
+       pr_info("board name: %s\n", board.name);
 
        /* make sure we're running on expected cpu */
        if (bcm63xx_get_cpu_id() != board.expected_cpu_id)
@@ -910,7 +910,7 @@ int __init board_register_devices(void)
                memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
                if (ssb_arch_register_fallback_sprom(
                                &bcm63xx_get_fallback_sprom) < 0)
-                       pr_err(PFX "failed to register fallback SPROM\n");
+                       pr_err("failed to register fallback SPROM\n");
        }
 #endif
 
index 307ec8b8e41c1eb12129844c9744ed9dd9441fb7..1c7c3fbfa1f330afae049d30e48b731cd6b46499 100644 (file)
@@ -376,10 +376,10 @@ void __init bcm63xx_cpu_init(void)
        bcm63xx_cpu_freq = detect_cpu_clock();
        bcm63xx_memory_size = detect_memory_size();
 
-       printk(KERN_INFO "Detected Broadcom 0x%04x CPU revision %02x\n",
-              bcm63xx_cpu_id, bcm63xx_cpu_rev);
-       printk(KERN_INFO "CPU frequency is %u MHz\n",
-              bcm63xx_cpu_freq / 1000000);
-       printk(KERN_INFO "%uMB of RAM installed\n",
-              bcm63xx_memory_size >> 20);
+       pr_info("Detected Broadcom 0x%04x CPU revision %02x\n",
+               bcm63xx_cpu_id, bcm63xx_cpu_rev);
+       pr_info("CPU frequency is %u MHz\n",
+               bcm63xx_cpu_freq / 1000000);
+       pr_info("%uMB of RAM installed\n",
+               bcm63xx_memory_size >> 20);
 }
index a551bab5ecb94b2aafce31787cea8e6bb31dbd10..9496cd23695149d992e254e7ad2830d9d9860719 100644 (file)
@@ -139,6 +139,6 @@ int __init bcm63xx_pcmcia_register(void)
        return platform_device_register(&bcm63xx_pcmcia_device);
 
 out_err:
-       printk(KERN_ERR "unable to set pcmcia chip select\n");
+       pr_err("unable to set pcmcia chip select\n");
        return ret;
 }
index 1a47ec2a09062b59bf76b1b4de9270435698b88e..c96139097ae270c9fbf6252d086611159bd6503d 100644 (file)
@@ -311,7 +311,7 @@ static int bcm63xx_external_irq_set_type(struct irq_data *d,
                break;
 
        default:
-               printk(KERN_ERR "bogus flow type combination given !\n");
+               pr_err("bogus flow type combination given !\n");
                return -EINVAL;
        }
 
index 240fb4ffa55c8625ef26354e29cff25c58f63b68..2be9caaa208530757af7ab41eaa6104c9a0616da 100644 (file)
@@ -24,7 +24,7 @@
 
 void bcm63xx_machine_halt(void)
 {
-       printk(KERN_INFO "System halted\n");
+       pr_info("System halted\n");
        while (1)
                ;
 }
@@ -34,7 +34,7 @@ static void bcm6348_a1_reboot(void)
        u32 reg;
 
        /* soft reset all blocks */
-       printk(KERN_INFO "soft-resetting all blocks ...\n");
+       pr_info("soft-resetting all blocks ...\n");
        reg = bcm_perf_readl(PERF_SOFTRESET_REG);
        reg &= ~SOFTRESET_6348_ALL;
        bcm_perf_writel(reg, PERF_SOFTRESET_REG);
@@ -46,7 +46,7 @@ static void bcm6348_a1_reboot(void)
        mdelay(10);
 
        /* Jump to the power on address. */
-       printk(KERN_INFO "jumping to reset vector.\n");
+       pr_info("jumping to reset vector.\n");
        /* set high vectors (base at 0xbfc00000 */
        set_c0_status(ST0_BEV | ST0_ERL);
        /* run uncached in kseg0 */
@@ -110,7 +110,7 @@ void bcm63xx_machine_reboot(void)
        if (BCMCPU_IS_6348() && (bcm63xx_get_cpu_rev() == 0xa1))
                bcm6348_a1_reboot();
 
-       printk(KERN_INFO "triggering watchdog soft-reset...\n");
+       pr_info("triggering watchdog soft-reset...\n");
        if (BCMCPU_IS_6328()) {
                bcm_wdt_writel(1, WDT_SOFTRESET_REG);
        } else {
index 5f11359815688d5350a56cce5704971e4e533b1a..2110359c00e5cb79cf1b04b21c73c83e81f79ea8 100644 (file)
@@ -195,7 +195,7 @@ int bcm63xx_timer_init(void)
        irq = bcm63xx_get_irq_number(IRQ_TIMER);
        ret = request_irq(irq, timer_interrupt, 0, "bcm63xx_timer", NULL);
        if (ret) {
-               printk(KERN_ERR "bcm63xx_timer: failed to register irq\n");
+               pr_err("%s: failed to register irq\n", __func__);
                return ret;
        }
 
index 526ec2789bb9ef0ba208079d307f9580c408c7ec..5b16d2955fbb864afae0103753bd8d0d115eba0e 100644 (file)
@@ -157,7 +157,6 @@ void __init plat_mem_setup(void)
                panic("no dtb found");
 
        __dt_setup_arch(dtb);
-       strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
 
        for (q = bmips_quirk_list; q->quirk_fn; q++) {
                if (of_flat_dt_is_compatible(of_get_flat_dt_root(),
index bac7b8dab9a4907db6733da6e66a6a85fe89a92d..a0bf516ec3948827acbc526c6ebac5a7827e1a22 100644 (file)
@@ -6,6 +6,7 @@ dts-dirs        += mti
 dts-dirs       += netlogic
 dts-dirs       += qca
 dts-dirs       += ralink
+dts-dirs       += xilfpga
 
 obj-y          := $(addsuffix /, $(dts-dirs))
 
index d817bb46b934fd1cb81388dd0d492f55c74171ed..d4bf52cfcf170ee8ac84daa874495e0a6420e542 100644 (file)
                        compatible = "brcm,bcm7120-l2-intc";
                        reg = <0x406780 0x8>;
 
-                       brcm,int-map-mask = <0x44>;
+                       brcm,int-map-mask = <0x44>, <0xf000000>;
                        brcm,int-fwd-mask = <0x70000>;
 
                        interrupt-controller;
                        #interrupt-cells = <1>;
 
                        interrupt-parent = <&periph_intc>;
-                       interrupts = <59>;
+                       interrupts = <59>, <57>;
+                       interrupt-names = "upg_main", "upg_bsc";
+               };
+
+               upg_aon_irq0_intc: upg_aon_irq0_intc@408b80 {
+                       compatible = "brcm,bcm7120-l2-intc";
+                       reg = <0x408b80 0x8>;
+
+                       brcm,int-map-mask = <0x40>, <0x8000000>, <0x100000>;
+                       brcm,int-fwd-mask = <0>;
+                       brcm,irq-can-wake;
+
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <60>, <58>, <62>;
+                       interrupt-names = "upg_main_aon", "upg_bsc_aon",
+                                         "upg_spi";
                };
 
                sun_top_ctrl: syscon@404000 {
                        status = "disabled";
                };
 
+               bsca: i2c@406200 {
+                     clock-frequency = <390000>;
+                     compatible = "brcm,brcmstb-i2c";
+                     interrupt-parent = <&upg_irq0_intc>;
+                     reg = <0x406200 0x58>;
+                     interrupts = <24>;
+                     interrupt-names = "upg_bsca";
+                     status = "disabled";
+               };
+
+               bscb: i2c@406280 {
+                     clock-frequency = <390000>;
+                     compatible = "brcm,brcmstb-i2c";
+                     interrupt-parent = <&upg_irq0_intc>;
+                     reg = <0x406280 0x58>;
+                     interrupts = <25>;
+                     interrupt-names = "upg_bscb";
+                     status = "disabled";
+               };
+
+               bscc: i2c@406300 {
+                     clock-frequency = <390000>;
+                     compatible = "brcm,brcmstb-i2c";
+                     interrupt-parent = <&upg_irq0_intc>;
+                     reg = <0x406300 0x58>;
+                     interrupts = <26>;
+                     interrupt-names = "upg_bscc";
+                     status = "disabled";
+               };
+
+               bscd: i2c@406380 {
+                     clock-frequency = <390000>;
+                     compatible = "brcm,brcmstb-i2c";
+                     interrupt-parent = <&upg_irq0_intc>;
+                     reg = <0x406380 0x58>;
+                     interrupts = <27>;
+                     interrupt-names = "upg_bscd";
+                     status = "disabled";
+               };
+
+               bsce: i2c@408980 {
+                     clock-frequency = <390000>;
+                     compatible = "brcm,brcmstb-i2c";
+                     interrupt-parent = <&upg_aon_irq0_intc>;
+                     reg = <0x408980 0x58>;
+                     interrupts = <27>;
+                     interrupt-names = "upg_bsce";
+                     status = "disabled";
+               };
+
                enet0: ethernet@430000 {
                        phy-mode = "internal";
                        phy-handle = <&phy1>;
                        interrupts = <76>;
                        status = "disabled";
                };
+
+               sata: sata@181000 {
+                       compatible = "brcm,bcm7425-ahci", "brcm,sata3-ahci";
+                       reg-names = "ahci", "top-ctrl";
+                       reg = <0x181000 0xa9c>, <0x180020 0x1c>;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <40>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       brcm,broken-ncq;
+                       brcm,broken-phy;
+                       status = "disabled";
+
+                       sata0: sata-port@0 {
+                               reg = <0>;
+                               phys = <&sata_phy0>;
+                       };
+
+                       sata1: sata-port@1 {
+                               reg = <1>;
+                               phys = <&sata_phy1>;
+                       };
+               };
+
+               sata_phy: sata-phy@1800000 {
+                       compatible = "brcm,bcm7425-sata-phy", "brcm,phy-sata3";
+                       reg = <0x180100 0x0eff>;
+                       reg-names = "phy";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+
+                       sata_phy0: sata-phy@0 {
+                               reg = <0>;
+                               #phy-cells = <0>;
+                       };
+
+                       sata_phy1: sata-phy@1 {
+                               reg = <1>;
+                               #phy-cells = <0>;
+                       };
+               };
        };
 };
index 277a90adc1a78cb07834dd7c870ac374cc1557da..8e2501694d03fbd93827aeda79ef22f7cfd5d094 100644 (file)
                        compatible = "brcm,bcm7120-l2-intc";
                        reg = <0x406600 0x8>;
 
-                       brcm,int-map-mask = <0x44>;
+                       brcm,int-map-mask = <0x44>, <0x7000000>;
                        brcm,int-fwd-mask = <0x70000>;
 
                        interrupt-controller;
                        #interrupt-cells = <1>;
 
                        interrupt-parent = <&periph_intc>;
-                       interrupts = <56>;
+                       interrupts = <56>, <54>;
+                       interrupt-names = "upg_main", "upg_bsc";
+               };
+
+               upg_aon_irq0_intc: upg_aon_irq0_intc@408b80 {
+                       compatible = "brcm,bcm7120-l2-intc";
+                       reg = <0x408b80 0x8>;
+
+                       brcm,int-map-mask = <0x40>, <0x8000000>, <0x100000>;
+                       brcm,int-fwd-mask = <0>;
+                       brcm,irq-can-wake;
+
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <57>, <55>, <59>;
+                       interrupt-names = "upg_main_aon", "upg_bsc_aon",
+                                         "upg_spi";
                };
 
                sun_top_ctrl: syscon@404000 {
                        status = "disabled";
                };
 
+               bsca: i2c@406200 {
+                     clock-frequency = <390000>;
+                     compatible = "brcm,brcmstb-i2c";
+                     interrupt-parent = <&upg_irq0_intc>;
+                     reg = <0x406200 0x58>;
+                     interrupts = <24>;
+                     interrupt-names = "upg_bsca";
+                     status = "disabled";
+               };
+
+               bscb: i2c@406280 {
+                     clock-frequency = <390000>;
+                     compatible = "brcm,brcmstb-i2c";
+                     interrupt-parent = <&upg_irq0_intc>;
+                     reg = <0x406280 0x58>;
+                     interrupts = <25>;
+                     interrupt-names = "upg_bscb";
+                     status = "disabled";
+               };
+
+               bscc: i2c@406300 {
+                     clock-frequency = <390000>;
+                     compatible = "brcm,brcmstb-i2c";
+                     interrupt-parent = <&upg_irq0_intc>;
+                     reg = <0x406300 0x58>;
+                     interrupts = <26>;
+                     interrupt-names = "upg_bscc";
+                     status = "disabled";
+               };
+
+               bscd: i2c@408980 {
+                     clock-frequency = <390000>;
+                     compatible = "brcm,brcmstb-i2c";
+                     interrupt-parent = <&upg_aon_irq0_intc>;
+                     reg = <0x408980 0x58>;
+                     interrupts = <27>;
+                     interrupt-names = "upg_bscd";
+                     status = "disabled";
+               };
+
                enet0: ethernet@430000 {
                        phy-mode = "internal";
                        phy-handle = <&phy1>;
index 9e1e571ba346ad7a240faf5a18a54b3f108e3cc7..7e5f76040fb898b19a4bbc301c8a20f3b9368aa4 100644 (file)
                        compatible = "brcm,bcm7120-l2-intc";
                        reg = <0x406600 0x8>;
 
-                       brcm,int-map-mask = <0x44>;
+                       brcm,int-map-mask = <0x44>, <0x7000000>;
                        brcm,int-fwd-mask = <0x70000>;
 
                        interrupt-controller;
                        #interrupt-cells = <1>;
 
                        interrupt-parent = <&periph_intc>;
-                       interrupts = <56>;
+                       interrupts = <56>, <54>;
+                       interrupt-names = "upg_main", "upg_bsc";
+               };
+
+               upg_aon_irq0_intc: upg_aon_irq0_intc@408b80 {
+                       compatible = "brcm,bcm7120-l2-intc";
+                       reg = <0x408b80 0x8>;
+
+                       brcm,int-map-mask = <0x40>, <0x8000000>, <0x100000>;
+                       brcm,int-fwd-mask = <0>;
+                       brcm,irq-can-wake;
+
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <57>, <55>, <59>;
+                       interrupt-names = "upg_main_aon", "upg_bsc_aon",
+                                         "upg_spi";
                };
 
                sun_top_ctrl: syscon@404000 {
                        status = "disabled";
                };
 
+               bsca: i2c@406200 {
+                     clock-frequency = <390000>;
+                     compatible = "brcm,brcmstb-i2c";
+                     interrupt-parent = <&upg_irq0_intc>;
+                     reg = <0x406200 0x58>;
+                     interrupts = <24>;
+                     interrupt-names = "upg_bsca";
+                     status = "disabled";
+               };
+
+               bscb: i2c@406280 {
+                     clock-frequency = <390000>;
+                     compatible = "brcm,brcmstb-i2c";
+                     interrupt-parent = <&upg_irq0_intc>;
+                     reg = <0x406280 0x58>;
+                     interrupts = <25>;
+                     interrupt-names = "upg_bscb";
+                     status = "disabled";
+               };
+
+               bscc: i2c@406300 {
+                     clock-frequency = <390000>;
+                     compatible = "brcm,brcmstb-i2c";
+                     interrupt-parent = <&upg_irq0_intc>;
+                     reg = <0x406300 0x58>;
+                     interrupts = <26>;
+                     interrupt-names = "upg_bscc";
+                     status = "disabled";
+               };
+
+               bscd: i2c@408980 {
+                     clock-frequency = <390000>;
+                     compatible = "brcm,brcmstb-i2c";
+                     interrupt-parent = <&upg_aon_irq0_intc>;
+                     reg = <0x408980 0x58>;
+                     interrupts = <27>;
+                     interrupt-names = "upg_bscd";
+                     status = "disabled";
+               };
+
                enet0: ethernet@430000 {
                        phy-mode = "internal";
                        phy-handle = <&phy1>;
index 6e65db86fc618471df11f543b2569872d36f85b4..c739ea77acb0dfe17363ec52cf390cace407e54c 100644 (file)
                        compatible = "brcm,bcm7120-l2-intc";
                        reg = <0x406600 0x8>;
 
-                       brcm,int-map-mask = <0x44>;
+                       brcm,int-map-mask = <0x44>, <0x7000000>;
                        brcm,int-fwd-mask = <0x70000>;
 
                        interrupt-controller;
                        #interrupt-cells = <1>;
 
                        interrupt-parent = <&periph_intc>;
-                       interrupts = <56>;
+                       interrupts = <56>, <54>;
+                       interrupt-names = "upg_main", "upg_bsc";
+               };
+
+               upg_aon_irq0_intc: upg_aon_irq0_intc@408b80 {
+                       compatible = "brcm,bcm7120-l2-intc";
+                       reg = <0x408b80 0x8>;
+
+                       brcm,int-map-mask = <0x40>, <0x8000000>, <0x100000>;
+                       brcm,int-fwd-mask = <0>;
+                       brcm,irq-can-wake;
+
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <57>, <55>, <59>;
+                       interrupt-names = "upg_main_aon", "upg_bsc_aon",
+                                         "upg_spi";
                };
 
                sun_top_ctrl: syscon@404000 {
                        status = "disabled";
                };
 
+               bsca: i2c@406200 {
+                     clock-frequency = <390000>;
+                     compatible = "brcm,brcmstb-i2c";
+                     interrupt-parent = <&upg_irq0_intc>;
+                     reg = <0x406200 0x58>;
+                     interrupts = <24>;
+                     interrupt-names = "upg_bsca";
+                     status = "disabled";
+               };
+
+               bscb: i2c@406280 {
+                     clock-frequency = <390000>;
+                     compatible = "brcm,brcmstb-i2c";
+                     interrupt-parent = <&upg_irq0_intc>;
+                     reg = <0x406280 0x58>;
+                     interrupts = <25>;
+                     interrupt-names = "upg_bscb";
+                     status = "disabled";
+               };
+
+               bscd: i2c@408980 {
+                     clock-frequency = <390000>;
+                     compatible = "brcm,brcmstb-i2c";
+                     interrupt-parent = <&upg_aon_irq0_intc>;
+                     reg = <0x408980 0x58>;
+                     interrupts = <27>;
+                     interrupt-names = "upg_bscd";
+                     status = "disabled";
+               };
+
                enet0: ethernet@430000 {
                        phy-mode = "internal";
                        phy-handle = <&phy1>;
                        interrupts = <66>;
                        status = "disabled";
                };
+
+               sata: sata@181000 {
+                       compatible = "brcm,bcm7425-ahci", "brcm,sata3-ahci";
+                       reg-names = "ahci", "top-ctrl";
+                       reg = <0x181000 0xa9c>, <0x180020 0x1c>;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <86>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       brcm,broken-ncq;
+                       brcm,broken-phy;
+                       status = "disabled";
+
+                       sata0: sata-port@0 {
+                               reg = <0>;
+                               phys = <&sata_phy0>;
+                       };
+
+                       sata1: sata-port@1 {
+                               reg = <1>;
+                               phys = <&sata_phy1>;
+                       };
+               };
+
+               sata_phy: sata-phy@1800000 {
+                       compatible = "brcm,bcm7425-sata-phy", "brcm,phy-sata3";
+                       reg = <0x180100 0x0eff>;
+                       reg-names = "phy";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+
+                       sata_phy0: sata-phy@0 {
+                               reg = <0>;
+                               #phy-cells = <0>;
+                       };
+
+                       sata_phy1: sata-phy@1 {
+                               reg = <1>;
+                               #phy-cells = <0>;
+                       };
+               };
        };
 };
index 5b660b617eaddb799d04ad6f2e86f15fd767e17e..e24d41ab4e30f9163605180d78605fc02a477db6 100644 (file)
                        interrupts = <73>;
                        status = "disabled";
                };
+
+               sata: sata@181000 {
+                       compatible = "brcm,bcm7425-ahci", "brcm,sata3-ahci";
+                       reg-names = "ahci", "top-ctrl";
+                       reg = <0x181000 0xa9c>, <0x180020 0x1c>;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <40>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       brcm,broken-ncq;
+                       brcm,broken-phy;
+                       status = "disabled";
+
+                       sata0: sata-port@0 {
+                               reg = <0>;
+                               phys = <&sata_phy0>;
+                       };
+
+                       sata1: sata-port@1 {
+                               reg = <1>;
+                               phys = <&sata_phy1>;
+                       };
+               };
+
+               sata_phy: sata-phy@1800000 {
+                       compatible = "brcm,bcm7425-sata-phy", "brcm,phy-sata3";
+                       reg = <0x180100 0x0eff>;
+                       reg-names = "phy";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+
+                       sata_phy0: sata-phy@0 {
+                               reg = <0>;
+                               #phy-cells = <0>;
+                       };
+
+                       sata_phy1: sata-phy@1 {
+                               reg = <1>;
+                               #phy-cells = <0>;
+                       };
+               };
        };
 };
index 3fe0445b9d37bae86ed53564b09747bd321653dd..d3d28816a0270716d9634b553bcc30962584ef1a 100644 (file)
        status = "okay";
 };
 
+&bsca {
+       status = "okay";
+};
+
+&bscb {
+       status = "okay";
+};
+
+&bscc {
+       status = "okay";
+};
+
+&bscd {
+       status = "okay";
+};
+
+&bsce {
+       status = "okay";
+};
+
 &enet0 {
        status = "okay";
 };
 &ohci3 {
        status = "okay";
 };
+
+&sata {
+       status = "okay";
+};
+
+&sata_phy {
+       status = "okay";
+};
index a8dc01e3031317f577db8e5c5bfc8f08363b045a..02ce6b429dc47b104633491cee178499e677f1f4 100644 (file)
        status = "okay";
 };
 
+&bsca {
+       status = "okay";
+};
+
+&bscb {
+       status = "okay";
+};
+
+&bscc {
+       status = "okay";
+};
+
+&bscd {
+       status = "okay";
+};
+
 &enet0 {
        status = "okay";
 };
index eee8b0e32681541266b70caa5d4b07ff789d35aa..d48462e091f176e6be77eeb301f769b40ef1afbc 100644 (file)
        status = "okay";
 };
 
+&bsca {
+       status = "okay";
+};
+
+&bscb {
+       status = "okay";
+};
+
+&bscc {
+       status = "okay";
+};
+
+&bscd {
+       status = "okay";
+};
+
 &enet0 {
        status = "okay";
 };
index 739c2ef5663b5cec059ee167cbb92451bc010db7..3cfcaebe7f79db34e8c340ba71a1238f327b78c3 100644 (file)
        status = "okay";
 };
 
+&bsca {
+       status = "okay";
+};
+
+&bscb {
+       status = "okay";
+};
+
+&bscd {
+       status = "okay";
+};
+
 &enet0 {
        status = "okay";
 };
 &ohci0 {
        status = "okay";
 };
+
+&sata {
+       status = "okay";
+};
+
+&sata_phy {
+       status = "okay";
+};
index c678115f5b7f7c5b194d321b060b15df58cada4c..b18c46637d21b4ae7b85636d98a3353332022bbc 100644 (file)
@@ -1,5 +1,9 @@
 /dts-v1/;
 
+/memreserve/ 0x00000000 0x00001000;    /* YAMON exception vectors */
+/memreserve/ 0x00001000 0x000ef000;    /* YAMON */
+/memreserve/ 0x000f0000 0x00010000;    /* PIIX4 ISA memory */
+
 / {
        #address-cells = <1>;
        #size-cells = <1>;
diff --git a/arch/mips/boot/dts/xilfpga/Makefile b/arch/mips/boot/dts/xilfpga/Makefile
new file mode 100644 (file)
index 0000000..913a752
--- /dev/null
@@ -0,0 +1,9 @@
+dtb-$(CONFIG_XILFPGA_NEXYS4DDR)        += nexys4ddr.dtb
+
+obj-y                          += $(patsubst %.dtb, %.dtb.o, $(dtb-y))
+
+# Force kbuild to make empty built-in.o if necessary
+obj-                           += dummy.o
+
+always                         := $(dtb-y)
+clean-files    := *.dtb *.dtb.S
diff --git a/arch/mips/boot/dts/xilfpga/microAptiv.dtsi b/arch/mips/boot/dts/xilfpga/microAptiv.dtsi
new file mode 100644 (file)
index 0000000..81d518e
--- /dev/null
@@ -0,0 +1,21 @@
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "img,xilfpga";
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               cpu@0 {
+                       device_type = "cpu";
+                       compatible = "mips,m14Kc";
+                       clocks  = <&ext>;
+                       reg = <0>;
+               };
+       };
+
+       ext: ext {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+       };
+};
diff --git a/arch/mips/boot/dts/xilfpga/nexys4ddr.dts b/arch/mips/boot/dts/xilfpga/nexys4ddr.dts
new file mode 100644 (file)
index 0000000..686ebd1
--- /dev/null
@@ -0,0 +1,46 @@
+/dts-v1/;
+
+#include "microAptiv.dtsi"
+
+/ {
+       compatible = "digilent,nexys4ddr";
+
+       memory {
+               device_type = "memory";
+               reg = <0x0 0x08000000>;
+       };
+
+       cpuintc: interrupt-controller@0 {
+               #address-cells = <0>;
+               #interrupt-cells = <1>;
+               interrupt-controller;
+               compatible = "mti,cpu-interrupt-controller";
+       };
+
+       axi_gpio: gpio@10600000 {
+               #gpio-cells = <1>;
+               compatible = "xlnx,xps-gpio-1.00.a";
+               gpio-controller;
+               reg = <0x10600000 0x10000>;
+               xlnx,all-inputs = <0x0>;
+               xlnx,dout-default = <0x0>;
+               xlnx,gpio-width = <0x16>;
+               xlnx,interrupt-present = <0x0>;
+               xlnx,is-dual = <0x0>;
+               xlnx,tri-default = <0xffffffff>;
+       } ;
+
+       axi_uart16550: serial@10400000 {
+               compatible = "ns16550a";
+               reg = <0x10400000 0x10000>;
+
+               reg-shift = <2>;
+               reg-offset = <0x1000>;
+
+               clocks  = <&ext>;
+       };
+};
+
+&ext {
+       clock-frequency = <50000000>;
+};
index bd634259eab9d6b0f7d1b8e746d0b11c01f0950d..cd7101fb622705c26fa40bfd0f58ca4d23d05dcb 100644 (file)
@@ -1081,6 +1081,7 @@ void __init prom_free_prom_memory(void)
 
 int octeon_prune_device_tree(void);
 
+extern const char __appended_dtb;
 extern const char __dtb_octeon_3xxx_begin;
 extern const char __dtb_octeon_68xx_begin;
 void __init device_tree_init(void)
@@ -1088,11 +1089,19 @@ void __init device_tree_init(void)
        const void *fdt;
        bool do_prune;
 
+#ifdef CONFIG_MIPS_ELF_APPENDED_DTB
+       if (!fdt_check_header(&__appended_dtb)) {
+               fdt = &__appended_dtb;
+               do_prune = false;
+               pr_info("Using appended Device Tree.\n");
+       } else
+#endif
        if (octeon_bootinfo->minor_version >= 3 && octeon_bootinfo->fdt_addr) {
                fdt = phys_to_virt(octeon_bootinfo->fdt_addr);
                if (fdt_check_header(fdt))
                        panic("Corrupt Device Tree passed to kernel.");
                do_prune = false;
+               pr_info("Using passed Device Tree.\n");
        } else if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
                fdt = &__dtb_octeon_68xx_begin;
                do_prune = true;
@@ -1106,8 +1115,6 @@ void __init device_tree_init(void)
        if (do_prune) {
                octeon_prune_device_tree();
                pr_info("Using internal Device Tree.\n");
-       } else {
-               pr_info("Using passed Device Tree.\n");
        }
        unflatten_and_copy_device_tree();
 }
index 1cdff6b6327d2753b41f76e348ee0bde97cc84dc..b3e7a1b61220bdff725a28661e39ab75e0744f72 100644 (file)
@@ -122,20 +122,20 @@ CONFIG_EEPROM_MAX6875=y
 CONFIG_IDE=y
 CONFIG_BLK_DEV_IDECD=y
 CONFIG_BLK_DEV_IDETAPE=y
-CONFIG_IDE_GENERIC=y
-CONFIG_BLK_DEV_GENERIC=y
-CONFIG_BLK_DEV_CMD64X=y
-CONFIG_BLK_DEV_IT8213=m
 CONFIG_BLK_DEV_TC86C001=m
 CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=m
-CONFIG_BLK_DEV_SR=m
+CONFIG_CHR_DEV_ST=y
+CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
 CONFIG_CHR_DEV_SCH=m
 CONFIG_ATA=y
 CONFIG_SATA_SIL24=y
+CONFIG_PATA_CMD64X=y
+CONFIG_PATA_IT8213=m
 CONFIG_PATA_SIL680=y
+CONFIG_ATA_GENERIC=y
+CONFIG_PATA_LEGACY=y
 CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
index f5585c8f35ad83539951a426b7b0871e4fcd8fb2..24dcb90b0f64b993dae12cd30a3e1aa5a6933f58 100644 (file)
@@ -8,7 +8,7 @@ CONFIG_MIPS_O32_FP64_SUPPORT=y
 # CONFIG_SWAP is not set
 CONFIG_NO_HZ=y
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_RD_GZIP is not set
+CONFIG_RD_GZIP=y
 CONFIG_EXPERT=y
 # CONFIG_VM_EVENT_COUNTERS is not set
 # CONFIG_SLUB_DEBUG is not set
@@ -33,6 +33,7 @@ CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 # CONFIG_STANDALONE is not set
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_PRINTK_TIME=y
 CONFIG_BRCMSTB_GISB_ARB=y
 CONFIG_MTD=y
 CONFIG_MTD_CFI=y
index 400a47ec1ef1e3a223da49d61c8abe0cdd2a04e3..4eb5d6e9cf8f1f256cbcf91b653746cb53ee0dde 100644 (file)
@@ -9,7 +9,7 @@ CONFIG_MIPS_O32_FP64_SUPPORT=y
 # CONFIG_SWAP is not set
 CONFIG_NO_HZ=y
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_RD_GZIP is not set
+CONFIG_RD_GZIP=y
 CONFIG_EXPERT=y
 # CONFIG_VM_EVENT_COUNTERS is not set
 # CONFIG_SLUB_DEBUG is not set
@@ -34,6 +34,7 @@ CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 # CONFIG_STANDALONE is not set
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_PRINTK_TIME=y
 CONFIG_BRCMSTB_GISB_ARB=y
 CONFIG_MTD=y
 CONFIG_MTD_CFI=y
index 5135dc0b950aadbd325a0826c5918f8cca5bd6c4..2924ba34a01bf8d4bad7297a002ef2e4161d17ee 100644 (file)
@@ -31,9 +31,9 @@ CONFIG_NETWORK_SECMARK=y
 CONFIG_IP_SCTP=m
 CONFIG_FW_LOADER=m
 CONFIG_BLK_DEV_RAM=y
-# CONFIG_MISC_DEVICES is not set
-CONFIG_IDE=y
-CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+CONFIG_PATA_LEGACY=y
 CONFIG_NETDEVICES=y
 CONFIG_PHYLIB=m
 CONFIG_MARVELL_PHY=m
index 0126e66d60cbbf92a0a59a68abbf06ada87fe599..e94d266c4b97995f23b0b3e9c64fc7cd80adc2cf 100644 (file)
@@ -14,9 +14,9 @@ CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
 # CONFIG_BLK_DEV_BSG is not set
 CONFIG_BLK_DEV_RAM=y
-# CONFIG_MISC_DEVICES is not set
-CONFIG_IDE=y
-CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+CONFIG_PATA_LEGACY=y
 # CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
index a75c65da08b4b7d573c45e0e429acd6dd54300c9..87435897fd50c802725be994843e07e1bc8ac105 100644 (file)
@@ -34,7 +34,7 @@ CONFIG_MIPS32_N32=y
 CONFIG_PM=y
 # CONFIG_SUSPEND is not set
 CONFIG_HIBERNATION=y
-CONFIG_PM_STD_PARTITION="/dev/hda3"
+CONFIG_PM_STD_PARTITION="/dev/sda3"
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -114,20 +114,16 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_RAM=m
 CONFIG_CDROM_PKTCDVD=m
 CONFIG_ATA_OVER_ETH=m
-# CONFIG_MISC_DEVICES is not set
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDECD=y
-CONFIG_IDE_TASK_IOCTL=y
-CONFIG_IDE_GENERIC=y
-CONFIG_BLK_DEV_GENERIC=y
-CONFIG_BLK_DEV_VIA82CXXX=y
-CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=y
 CONFIG_SCSI_CONSTANTS=y
 # CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=y
+CONFIG_PATA_VIA=y
+CONFIG_ATA_GENERIC=y
+CONFIG_PATA_LEGACY=y
 CONFIG_NETDEVICES=y
 CONFIG_MACVLAN=m
 CONFIG_VETH=m
index 0179c7fa014f1c093099198bebe5585057eb93f2..e620a2c3eba478a955ab75303f57f7824d3bf61f 100644 (file)
@@ -35,11 +35,11 @@ CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
 CONFIG_MTD_CFI_AMDSTD=y
-# CONFIG_MISC_DEVICES is not set
-CONFIG_IDE=y
-CONFIG_IDE_GENERIC=y
-CONFIG_BLK_DEV_GENERIC=y
-CONFIG_BLK_DEV_CMD64X=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+CONFIG_PATA_CMD64X=y
+CONFIG_ATA_GENERIC=y
+CONFIG_PATA_LEGACY=y
 CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
 CONFIG_NET_PCI=y
index 54cc3853d259de430f222e2a4f50d907201bd302..004cf52d1b7d81911e5e911a0dcee274be23b869 100644 (file)
@@ -108,16 +108,11 @@ CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=8192
-# CONFIG_MISC_DEVICES is not set
-CONFIG_IDE=y
-CONFIG_IDE_TASK_IOCTL=y
-# CONFIG_IDEPCI_PCIBUS_ORDER is not set
-CONFIG_BLK_DEV_AMD74XX=y
-CONFIG_SCSI=m
-CONFIG_BLK_DEV_SD=m
+CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_SG=m
-CONFIG_SCSI_MULTI_LUN=y
 # CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=y
+CONFIG_PATA_AMD=y
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
index 61a4460d67d32b2c7d8d266f40c316c70aef5e7c..5afb4840aec75c3d41fb7a4fd08b8322d0437904 100644 (file)
@@ -241,14 +241,11 @@ CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_CDROM_PKTCDVD=m
 CONFIG_ATA_OVER_ETH=m
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDECD=y
-CONFIG_IDE_GENERIC=y
 CONFIG_RAID_ATTRS=m
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=m
 CONFIG_CHR_DEV_OSST=m
-CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
 CONFIG_SCSI_CONSTANTS=y
@@ -265,6 +262,7 @@ CONFIG_AIC7XXX_RESET_DELAY_MS=15000
 # CONFIG_AIC7XXX_DEBUG_ENABLE is not set
 CONFIG_ATA=y
 CONFIG_ATA_PIIX=y
+CONFIG_PATA_LEGACY=y
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
index d41742dd26c8131279bc6a898461a043a78335ec..98f13879bb8fda832e3e73355f96af7defdcbc23 100644 (file)
@@ -248,17 +248,12 @@ CONFIG_CDROM_PKTCDVD=m
 CONFIG_ATA_OVER_ETH=m
 CONFIG_IDE=y
 CONFIG_BLK_DEV_IDECD=y
-CONFIG_IDE_GENERIC=y
-CONFIG_BLK_DEV_GENERIC=y
-CONFIG_BLK_DEV_PIIX=y
-CONFIG_BLK_DEV_IT8213=m
 CONFIG_BLK_DEV_TC86C001=m
 CONFIG_RAID_ATTRS=m
-CONFIG_SCSI=m
-CONFIG_BLK_DEV_SD=m
+CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=m
 CONFIG_CHR_DEV_OSST=m
-CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
 CONFIG_SCSI_MULTI_LUN=y
@@ -274,6 +269,13 @@ CONFIG_SCSI_AACRAID=m
 CONFIG_SCSI_AIC7XXX=m
 CONFIG_AIC7XXX_RESET_DELAY_MS=15000
 # CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_ATA=y
+CONFIG_ATA_PIIX=y
+CONFIG_PATA_IT8213=m
+CONFIG_PATA_OLDPIIX=y
+CONFIG_PATA_MPIIX=y
+CONFIG_ATA_GENERIC=y
+CONFIG_PATA_LEGACY=y
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
index a7806e83ea0f1502cf0f78ceb5b0f29a86a07ee4..3b5d5913f548cddaf65f457da86ae245dee9f06d 100644 (file)
@@ -248,17 +248,12 @@ CONFIG_ATA_OVER_ETH=m
 CONFIG_VIRTIO_BLK=y
 CONFIG_IDE=y
 CONFIG_BLK_DEV_IDECD=y
-CONFIG_IDE_GENERIC=y
-CONFIG_BLK_DEV_GENERIC=y
-CONFIG_BLK_DEV_PIIX=y
-CONFIG_BLK_DEV_IT8213=m
 CONFIG_BLK_DEV_TC86C001=m
 CONFIG_RAID_ATTRS=m
-CONFIG_SCSI=m
-CONFIG_BLK_DEV_SD=m
+CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=m
 CONFIG_CHR_DEV_OSST=m
-CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
 CONFIG_SCSI_MULTI_LUN=y
@@ -274,6 +269,13 @@ CONFIG_SCSI_AACRAID=m
 CONFIG_SCSI_AIC7XXX=m
 CONFIG_AIC7XXX_RESET_DELAY_MS=15000
 # CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_ATA=y
+CONFIG_ATA_PIIX=y
+CONFIG_PATA_IT8213=m
+CONFIG_PATA_OLDPIIX=y
+CONFIG_PATA_MPIIX=y
+CONFIG_ATA_GENERIC=y
+CONFIG_PATA_LEGACY=y
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
index 4bce1f8ebe98294ad339bb6715bbf2e342088ffc..7f50dd67aa8d979e7e3515b2ff8537058c8ed0f0 100644 (file)
@@ -80,15 +80,14 @@ CONFIG_NET_CLS_IND=y
 CONFIG_DEVTMPFS=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_IDE=y
-# CONFIG_IDE_PROC_FS is not set
-# CONFIG_IDEPCI_PCIBUS_ORDER is not set
-CONFIG_BLK_DEV_GENERIC=y
-CONFIG_BLK_DEV_PIIX=y
-CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_SG=y
 # CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=y
+CONFIG_ATA_PIIX=y
+CONFIG_PATA_OLDPIIX=y
+CONFIG_PATA_MPIIX=y
+CONFIG_ATA_GENERIC=y
 CONFIG_NETDEVICES=y
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_NET_VENDOR_ADAPTEC is not set
index fb042ce86b4bc1da95d3b9297e6dfe88ed2f5dad..a9d433a17fcf60dd3e434d993958f633effd9df5 100644 (file)
@@ -81,15 +81,14 @@ CONFIG_NET_CLS_IND=y
 CONFIG_DEVTMPFS=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_IDE=y
-# CONFIG_IDE_PROC_FS is not set
-# CONFIG_IDEPCI_PCIBUS_ORDER is not set
-CONFIG_BLK_DEV_GENERIC=y
-CONFIG_BLK_DEV_PIIX=y
-CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_SG=y
 # CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=y
+CONFIG_ATA_PIIX=y
+CONFIG_PATA_OLDPIIX=y
+CONFIG_PATA_MPIIX=y
+CONFIG_ATA_GENERIC=y
 CONFIG_NETDEVICES=y
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_NET_VENDOR_ADAPTEC is not set
index c83338a39917e17bd7cf1edd3f2b126f8339ab0a..2774ef06450596f7582db13c7749ce7a3b76f510 100644 (file)
@@ -85,15 +85,14 @@ CONFIG_NET_CLS_IND=y
 CONFIG_DEVTMPFS=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_IDE=y
-# CONFIG_IDE_PROC_FS is not set
-# CONFIG_IDEPCI_PCIBUS_ORDER is not set
-CONFIG_BLK_DEV_GENERIC=y
-CONFIG_BLK_DEV_PIIX=y
-CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_SG=y
 # CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=y
+CONFIG_ATA_PIIX=y
+CONFIG_PATA_OLDPIIX=y
+CONFIG_PATA_MPIIX=y
+CONFIG_ATA_GENERIC=y
 CONFIG_NETDEVICES=y
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_NET_VENDOR_ADAPTEC is not set
index 62344648eb7a31a0e134db2d7eaf828dd8a012aa..9bbd2218f0bf518ff1c2aeceaec8695317556664 100644 (file)
@@ -80,15 +80,14 @@ CONFIG_NET_CLS_IND=y
 CONFIG_DEVTMPFS=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_IDE=y
-# CONFIG_IDE_PROC_FS is not set
-# CONFIG_IDEPCI_PCIBUS_ORDER is not set
-CONFIG_BLK_DEV_GENERIC=y
-CONFIG_BLK_DEV_PIIX=y
-CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_SG=y
 # CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=y
+CONFIG_ATA_PIIX=y
+CONFIG_PATA_OLDPIIX=y
+CONFIG_PATA_MPIIX=y
+CONFIG_ATA_GENERIC=y
 CONFIG_NETDEVICES=y
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_NET_VENDOR_ADAPTEC is not set
index c388bff091482c9b871d80e86a27386e0fae1e9f..73221573275166e1ae7d044b1bad8dfa1b1f6d65 100644 (file)
@@ -244,17 +244,12 @@ CONFIG_CDROM_PKTCDVD=m
 CONFIG_ATA_OVER_ETH=m
 CONFIG_IDE=y
 CONFIG_BLK_DEV_IDECD=y
-CONFIG_IDE_GENERIC=y
-CONFIG_BLK_DEV_GENERIC=y
-CONFIG_BLK_DEV_PIIX=y
-CONFIG_BLK_DEV_IT8213=m
 CONFIG_BLK_DEV_TC86C001=m
 CONFIG_RAID_ATTRS=m
-CONFIG_SCSI=m
-CONFIG_BLK_DEV_SD=m
+CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=m
 CONFIG_CHR_DEV_OSST=m
-CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
 CONFIG_SCSI_CONSTANTS=y
@@ -269,6 +264,13 @@ CONFIG_SCSI_AACRAID=m
 CONFIG_SCSI_AIC7XXX=m
 CONFIG_AIC7XXX_RESET_DELAY_MS=15000
 # CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_ATA=y
+CONFIG_ATA_PIIX=y
+CONFIG_PATA_IT8213=m
+CONFIG_PATA_OLDPIIX=y
+CONFIG_PATA_MPIIX=y
+CONFIG_ATA_GENERIC=y
+CONFIG_PATA_LEGACY=y
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
index 7a346605c498ae02e5a48245d03b1e028aacce96..a2c045fab6c58b38069db48b4d49dd9755a1789f 100644 (file)
@@ -27,9 +27,9 @@ CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_NETWORK_SECMARK=y
 CONFIG_CONNECTOR=m
 CONFIG_ATA_OVER_ETH=m
-# CONFIG_MISC_DEVICES is not set
-CONFIG_IDE=y
-CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+CONFIG_PATA_LEGACY=y
 CONFIG_NETDEVICES=y
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
diff --git a/arch/mips/configs/xilfpga_defconfig b/arch/mips/configs/xilfpga_defconfig
new file mode 100644 (file)
index 0000000..ed1dce3
--- /dev/null
@@ -0,0 +1,40 @@
+CONFIG_MACH_XILFPGA=y
+# CONFIG_COMPACTION is not set
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_EMBEDDED=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+# CONFIG_BLOCK is not set
+# CONFIG_SUSPEND is not set
+# CONFIG_UEVENT_HELPER is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+# CONFIG_ALLOW_DEV_COREDUMP is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_XILINX=y
+# CONFIG_HWMON is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MIPS_PLATFORM_DEVICES is not set
+# CONFIG_IOMMU_SUPPORT is not set
+# CONFIG_PROC_PAGE_MONITOR is not set
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_PANIC_ON_OOPS=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_FTRACE is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyS0,115200"
index 37f84078e78abbe3f6b85841461c8bccc62d6c9a..940760844e2fe98a8e3958e975b1cbd674786675 100644 (file)
 
 #include <asm/signal.h>
 #include <asm/siginfo.h>
+#include <asm/vdso.h>
 
 struct mips_abi {
        int (* const setup_frame)(void *sig_return, struct ksignal *ksig,
                                  struct pt_regs *regs, sigset_t *set);
-       const unsigned long     signal_return_offset;
        int (* const setup_rt_frame)(void *sig_return, struct ksignal *ksig,
                                     struct pt_regs *regs, sigset_t *set);
-       const unsigned long     rt_signal_return_offset;
        const unsigned long     restart;
 
        unsigned        off_sc_fpregs;
        unsigned        off_sc_fpc_csr;
        unsigned        off_sc_used_math;
+
+       struct mips_vdso_image *vdso;
 };
 
 #endif /* _ASM_ABI_H */
index f82d3af07931656a1f295b07972d6717df89a30d..835b402e4574fa1a27da780da9ae398bbf3bb276 100644 (file)
@@ -507,7 +507,7 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
  * @u: ...unless v is equal to u.
  *
  * Atomically adds @a to @v, so long as it was not @u.
- * Returns the old value of @v.
+ * Returns true iff @v was not @u.
  */
 static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
 {
index 8c34484cea827f516591dd9f3c775d36e81fac7b..a00857b135c348eb104e8dae4dfdda4ccbe8563d 100644 (file)
@@ -9,6 +9,7 @@
 #ifndef _ASM_BCACHE_H
 #define _ASM_BCACHE_H
 
+#include <linux/types.h>
 
 /* Some R4000 / R4400 / R4600 / R5000 machines may have a non-dma-coherent,
    chipset implemented caches. On machines with other CPUs the CPU does the
@@ -18,6 +19,9 @@ struct bcache_ops {
        void (*bc_disable)(void);
        void (*bc_wback_inv)(unsigned long page, unsigned long size);
        void (*bc_inv)(unsigned long page, unsigned long size);
+       void (*bc_prefetch_enable)(void);
+       void (*bc_prefetch_disable)(void);
+       bool (*bc_prefetch_is_enabled)(void);
 };
 
 extern void indy_sc_init(void);
@@ -46,6 +50,26 @@ static inline void bc_inv(unsigned long page, unsigned long size)
        bcops->bc_inv(page, size);
 }
 
+static inline void bc_prefetch_enable(void)
+{
+       if (bcops->bc_prefetch_enable)
+               bcops->bc_prefetch_enable();
+}
+
+static inline void bc_prefetch_disable(void)
+{
+       if (bcops->bc_prefetch_disable)
+               bcops->bc_prefetch_disable();
+}
+
+static inline bool bc_prefetch_is_enabled(void)
+{
+       if (bcops->bc_prefetch_is_enabled)
+               return bcops->bc_prefetch_is_enabled();
+
+       return false;
+}
+
 #else /* !defined(CONFIG_BOARD_SCACHE) */
 
 /* Not R4000 / R4400 / R4600 / R5000.  */
@@ -54,6 +78,9 @@ static inline void bc_inv(unsigned long page, unsigned long size)
 #define bc_disable() do { } while (0)
 #define bc_wback_inv(page, size) do { } while (0)
 #define bc_inv(page, size) do { } while (0)
+#define bc_prefetch_enable() do { } while (0)
+#define bc_prefetch_disable() do { } while (0)
+#define bc_prefetch_is_enabled() 0
 
 #endif /* !defined(CONFIG_BOARD_SCACHE) */
 
index bece2064cc8cbf24f6c36c603b501c6b0dc19edd..c06dbf8ba937093d81b33cd14e00d9c74c944de6 100644 (file)
@@ -84,6 +84,17 @@ void mips_cdmm_driver_unregister(struct mips_cdmm_driver *);
        module_driver(__mips_cdmm_driver, mips_cdmm_driver_register, \
                        mips_cdmm_driver_unregister)
 
+/*
+ * builtin_mips_cdmm_driver() - Helper macro for drivers that don't do anything
+ * special in init and have no exit. This eliminates some boilerplate. Each
+ * driver may only use this macro once, and calling it replaces device_initcall
+ * (or in some cases, the legacy __initcall). This is meant to be a direct
+ * parallel of module_mips_cdmm_driver() above but without the __exit stuff that
+ * is not used for builtin cases.
+ */
+#define builtin_mips_cdmm_driver(__mips_cdmm_driver) \
+       builtin_driver(__mips_cdmm_driver, mips_cdmm_driver_register)
+
 /* drivers/tty/mips_ejtag_fdc.c */
 
 #ifdef CONFIG_MIPS_EJTAG_FDC_EARLYCON
diff --git a/arch/mips/include/asm/clocksource.h b/arch/mips/include/asm/clocksource.h
new file mode 100644 (file)
index 0000000..3deb1d0
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Alex Smith <alex.smith@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __ASM_CLOCKSOURCE_H
+#define __ASM_CLOCKSOURCE_H
+
+#include <linux/types.h>
+
+/* VDSO clocksources. */
+#define VDSO_CLOCK_NONE                0       /* No suitable clocksource. */
+#define VDSO_CLOCK_R4K         1       /* Use the coprocessor 0 count. */
+#define VDSO_CLOCK_GIC         2       /* Use the GIC. */
+
+/**
+ * struct arch_clocksource_data - Architecture-specific clocksource information.
+ * @vdso_clock_mode: Method the VDSO should use to access the clocksource.
+ */
+struct arch_clocksource_data {
+       u8 vdso_clock_mode;
+};
+
+#endif /* __ASM_CLOCKSOURCE_H */
index c4bd54a7f5ce1675de61705a5b8779846e012589..a9580097cba8fe0d7db36793c8f8cf831323579e 100644 (file)
@@ -130,6 +130,8 @@ typedef union compat_sigval {
        compat_uptr_t   sival_ptr;
 } compat_sigval_t;
 
+/* Can't use the generic version because si_code and si_errno are swapped */
+
 #define SI_PAD_SIZE32  (128/sizeof(int) - 3)
 
 typedef struct compat_siginfo {
@@ -138,57 +140,61 @@ typedef struct compat_siginfo {
        int si_errno;
 
        union {
-               int _pad[SI_PAD_SIZE32];
+               int _pad[128 / sizeof(int) - 3];
 
                /* kill() */
                struct {
                        compat_pid_t _pid;      /* sender's pid */
-                       __compat_uid_t _uid;    /* sender's uid */
+                       __compat_uid32_t _uid;  /* sender's uid */
                } _kill;
 
+               /* POSIX.1b timers */
+               struct {
+                       compat_timer_t _tid;    /* timer id */
+                       int _overrun;           /* overrun count */
+                       compat_sigval_t _sigval;        /* same as below */
+               } _timer;
+
+               /* POSIX.1b signals */
+               struct {
+                       compat_pid_t _pid;      /* sender's pid */
+                       __compat_uid32_t _uid;  /* sender's uid */
+                       compat_sigval_t _sigval;
+               } _rt;
+
                /* SIGCHLD */
                struct {
                        compat_pid_t _pid;      /* which child */
-                       __compat_uid_t _uid;    /* sender's uid */
+                       __compat_uid32_t _uid;  /* sender's uid */
                        int _status;            /* exit code */
                        compat_clock_t _utime;
                        compat_clock_t _stime;
                } _sigchld;
 
-               /* IRIX SIGCHLD */
-               struct {
-                       compat_pid_t _pid;      /* which child */
-                       compat_clock_t _utime;
-                       int _status;            /* exit code */
-                       compat_clock_t _stime;
-               } _irix_sigchld;
-
                /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
                struct {
-                       s32 _addr; /* faulting insn/memory ref. */
+                       compat_uptr_t _addr;    /* faulting insn/memory ref. */
+#ifdef __ARCH_SI_TRAPNO
+                       int _trapno;    /* TRAP # which caused the signal */
+#endif
+                       short _addr_lsb; /* LSB of the reported address */
+                       struct {
+                               compat_uptr_t _lower;
+                               compat_uptr_t _upper;
+                       } _addr_bnd;
                } _sigfault;
 
-               /* SIGPOLL, SIGXFSZ (To do ...)  */
+               /* SIGPOLL */
                struct {
-                       int _band;      /* POLL_IN, POLL_OUT, POLL_MSG */
+                       compat_long_t _band; /* POLL_IN, POLL_OUT, POLL_MSG */
                        int _fd;
                } _sigpoll;
 
-               /* POSIX.1b timers */
-               struct {
-                       timer_t _tid;           /* timer id */
-                       int _overrun;           /* overrun count */
-                       compat_sigval_t _sigval;/* same as below */
-                       int _sys_private;       /* not to be passed to user */
-               } _timer;
-
-               /* POSIX.1b signals */
                struct {
-                       compat_pid_t _pid;      /* sender's pid */
-                       __compat_uid_t _uid;    /* sender's uid */
-                       compat_sigval_t _sigval;
-               } _rt;
-
+                       compat_uptr_t _call_addr; /* calling insn */
+                       int _syscall;   /* triggering system call number */
+                       compat_uint_t _arch;    /* AUDIT_ARCH_* of syscall */
+               } _sigsys;
        } _sifields;
 } compat_siginfo_t;
 
index fe67f12ac2393b23705b4a094bbf8c3b7cc77166..d1e04c943f5f7c7d9ec232851e14d9b5c4215496 100644 (file)
 #endif
 
 #ifndef cpu_has_rixi
-# ifdef CONFIG_64BIT
-# define cpu_has_rixi          (cpu_data[0].options & MIPS_CPU_RIXI)
-# else /* CONFIG_32BIT */
-# define cpu_has_rixi          ((cpu_data[0].options & MIPS_CPU_RIXI) && !cpu_has_64bits)
-# endif
+#define cpu_has_rixi           (cpu_data[0].options & MIPS_CPU_RIXI)
 #endif
 
 #ifndef cpu_has_mmips
diff --git a/arch/mips/include/asm/debug.h b/arch/mips/include/asm/debug.h
new file mode 100644 (file)
index 0000000..254f00d
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2015 Imagination Technologies
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __MIPS_ASM_DEBUG_H__
+#define __MIPS_ASM_DEBUG_H__
+
+#include <linux/dcache.h>
+
+/*
+ * mips_debugfs_dir corresponds to the "mips" directory at the top level
+ * of the DebugFS hierarchy. MIPS-specific DebugFS entires should be
+ * placed beneath this directory.
+ */
+extern struct dentry *mips_debugfs_dir;
+
+#endif /* __MIPS_ASM_DEBUG_H__ */
index 53b26933b12cea365457f95172fbde6990043ff1..b01a6ff468e00aab5d185a9dd53023101b34f2b7 100644 (file)
@@ -8,6 +8,7 @@
 #ifndef _ASM_ELF_H
 #define _ASM_ELF_H
 
+#include <linux/auxvec.h>
 #include <linux/fs.h>
 #include <uapi/linux/elf.h>
 
@@ -419,6 +420,12 @@ extern const char *__elf_platform;
 #define ELF_ET_DYN_BASE                (TASK_SIZE / 3 * 2)
 #endif
 
+#define ARCH_DLINFO                                                    \
+do {                                                                   \
+       NEW_AUX_ENT(AT_SYSINFO_EHDR,                                    \
+                   (unsigned long)current->mm->context.vdso);          \
+} while (0)
+
 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
 struct linux_binprm;
 extern int arch_setup_additional_pages(struct linux_binprm *bprm,
index f3e6978aad704c4a15bad1971c55625f2e378f6e..d0ef8b4892bbe6af327a0b351df93f948c413b37 100644 (file)
 
 #include <asm/bootinfo.h>      /* For cleaner code... */
 
-enum fw_memtypes {
-       fw_dontuse,
-       fw_code,
-       fw_free,
-};
-
-typedef struct {
-       unsigned long base;     /* Within KSEG0 */
-       unsigned int size;      /* bytes */
-       enum fw_memtypes type;  /* fw_memtypes */
-} fw_memblock_t;
-
-/* Maximum number of memory block descriptors. */
-#define FW_MAX_MEMBLOCKS       32
-
 extern int fw_argc;
 extern int *_fw_argv;
 extern int *_fw_envp;
@@ -38,7 +23,6 @@ extern int *_fw_envp;
 
 extern void fw_init_cmdline(void);
 extern char *fw_getcmdline(void);
-extern fw_memblock_t *fw_getmdesc(int);
 extern void fw_meminit(void);
 extern char *fw_getenv(char *name);
 extern unsigned long fw_getenvl(char *name);
index 1461c10c1c4c4e9a9c5c3e0ec1384b433e4f312c..71e4096a2145667328f9535d6c3ea93617881154 100644 (file)
@@ -48,11 +48,6 @@ extern enum bcm47xx_bus_type bcm47xx_bus_type;
 void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix,
                        bool fallback);
 
-#ifdef CONFIG_BCM47XX_SSB
-void bcm47xx_fill_ssb_boardinfo(struct ssb_boardinfo *boardinfo,
-                               const char *prefix);
-#endif
-
 void bcm47xx_set_system_type(u16 chip_id);
 
 #endif /* __ASM_BCM47XX_H */
index 133336b493b67c4822e79a2965e93300adbab853..dd6005b75e0c0bb594e657ede11df74b21776852 100644 (file)
 #define SOC_ID_VRX268_2                0x00C /* v1.2 */
 #define SOC_ID_GRX288_2                0x00D /* v1.2 */
 #define SOC_ID_GRX282_2                0x00E /* v1.2 */
+#define SOC_ID_VRX220          0x000
+
+#define SOC_ID_ARX362          0x004
+#define SOC_ID_ARX368          0x005
+#define SOC_ID_ARX382          0x007
+#define SOC_ID_ARX388          0x008
+#define SOC_ID_URX388          0x009
+#define SOC_ID_GRX383          0x010
+#define SOC_ID_GRX369          0x011
+#define SOC_ID_GRX387          0x00F
+#define SOC_ID_GRX389          0x012
 
  /* SoC Types */
 #define SOC_TYPE_DANUBE                0x01
@@ -43,6 +54,9 @@
 #define SOC_TYPE_VR9           0x04 /* v1.1 */
 #define SOC_TYPE_VR9_2         0x05 /* v1.2 */
 #define SOC_TYPE_AMAZON_SE     0x06
+#define SOC_TYPE_AR10          0x07
+#define SOC_TYPE_GRX390                0x08
+#define SOC_TYPE_VRX220                0x09
 
 /* BOOT_SEL - find what boot media we have */
 #define BS_EXT_ROM             0x0
diff --git a/arch/mips/include/asm/mach-malta/malta-dtshim.h b/arch/mips/include/asm/mach-malta/malta-dtshim.h
new file mode 100644 (file)
index 0000000..cfd7776
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __MIPS_MALTA_DTSHIM_H__
+#define __MIPS_MALTA_DTSHIM_H__
+
+#include <linux/init.h>
+
+#ifdef CONFIG_MIPS_MALTA
+
+extern void __init *malta_dt_shim(void *fdt);
+
+#else /* !CONFIG_MIPS_MALTA */
+
+static inline void *malta_dt_shim(void *fdt)
+{
+       return fdt;
+}
+
+#endif /* !CONFIG_MIPS_MALTA */
+
+#endif /* __MIPS_MALTA_DTSHIM_H__ */
index 1976fb815fd10c5275b0e04a1c008812fc847e6c..455d406e8ddf1667e4c2212aacfe985c2eb08be8 100644 (file)
 #ifndef _MT7620_REGS_H_
 #define _MT7620_REGS_H_
 
-enum mt762x_soc_type {
-       MT762X_SOC_UNKNOWN = 0,
-       MT762X_SOC_MT7620A,
-       MT762X_SOC_MT7620N,
-       MT762X_SOC_MT7628AN,
-};
-
 #define MT7620_SYSC_BASE               0x10000000
 
 #define SYSC_REG_CHIP_NAME0            0x00
 #define SYSC_REG_CHIP_NAME1            0x04
+#define SYSC_REG_EFUSE_CFG             0x08
 #define SYSC_REG_CHIP_REV              0x0c
 #define SYSC_REG_SYSTEM_CONFIG0                0x10
 #define SYSC_REG_SYSTEM_CONFIG1                0x14
index bd93014490df39eebce2df057d5b3e84f2130aeb..4c9fba68c8b2490bfaf98b2f1ec8b2fc77f0ed5f 100644 (file)
 #ifndef _RALINK_REGS_H_
 #define _RALINK_REGS_H_
 
+enum ralink_soc_type {
+       RALINK_UNKNOWN = 0,
+       RT2880_SOC,
+       RT3883_SOC,
+       RT305X_SOC_RT3050,
+       RT305X_SOC_RT3052,
+       RT305X_SOC_RT3350,
+       RT305X_SOC_RT3352,
+       RT305X_SOC_RT5350,
+       MT762X_SOC_MT7620A,
+       MT762X_SOC_MT7620N,
+       MT762X_SOC_MT7621AT,
+       MT762X_SOC_MT7628AN,
+       MT762X_SOC_MT7688,
+};
+extern enum ralink_soc_type ralink_soc;
+
 extern __iomem void *rt_sysc_membase;
 extern __iomem void *rt_memc_membase;
 
index 96f731bac79a4a9941f0fb5cc5198621f4ee7f9f..2eea79331a14bf040b164ce294e2ce3a0bb99ba7 100644 (file)
 #ifndef _RT305X_REGS_H_
 #define _RT305X_REGS_H_
 
-enum rt305x_soc_type {
-       RT305X_SOC_UNKNOWN = 0,
-       RT305X_SOC_RT3050,
-       RT305X_SOC_RT3052,
-       RT305X_SOC_RT3350,
-       RT305X_SOC_RT3352,
-       RT305X_SOC_RT5350,
-};
-
-extern enum rt305x_soc_type rt305x_soc;
+extern enum ralink_soc_type ralink_soc;
 
 static inline int soc_is_rt3050(void)
 {
-       return rt305x_soc == RT305X_SOC_RT3050;
+       return ralink_soc == RT305X_SOC_RT3050;
 }
 
 static inline int soc_is_rt3052(void)
 {
-       return rt305x_soc == RT305X_SOC_RT3052;
+       return ralink_soc == RT305X_SOC_RT3052;
 }
 
 static inline int soc_is_rt305x(void)
@@ -41,17 +32,17 @@ static inline int soc_is_rt305x(void)
 
 static inline int soc_is_rt3350(void)
 {
-       return rt305x_soc == RT305X_SOC_RT3350;
+       return ralink_soc == RT305X_SOC_RT3350;
 }
 
 static inline int soc_is_rt3352(void)
 {
-       return rt305x_soc == RT305X_SOC_RT3352;
+       return ralink_soc == RT305X_SOC_RT3352;
 }
 
 static inline int soc_is_rt5350(void)
 {
-       return rt305x_soc == RT305X_SOC_RT5350;
+       return ralink_soc == RT305X_SOC_RT5350;
 }
 
 #define RT305X_SYSC_BASE               0x10000000
diff --git a/arch/mips/include/asm/mach-xilfpga/irq.h b/arch/mips/include/asm/mach-xilfpga/irq.h
new file mode 100644 (file)
index 0000000..0132a5b
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __MIPS_ASM_MACH_XILFPGA_IRQ_H__
+#define __MIPS_ASM_MACH_XILFPGA_IRQ_H__
+
+#define NR_IRQS 32
+
+#include_next <irq.h>
+
+#endif /* __MIPS_ASM_MACH_XILFPGA_IRQ_H__ */
index 1f1927ab42690b284257faa8991f4cff31a3264d..6516e9da51334916b04b6f8689a0857faad5f0ca 100644 (file)
@@ -11,6 +11,7 @@
 #ifndef __MIPS_ASM_MIPS_CM_H__
 #define __MIPS_ASM_MIPS_CM_H__
 
+#include <linux/bitops.h>
 #include <linux/errno.h>
 #include <linux/io.h>
 #include <linux/types.h>
@@ -36,12 +37,12 @@ extern phys_addr_t __mips_cm_phys_base(void);
 /*
  * mips_cm_is64 - determine CM register width
  *
- * The CM register width is processor and CM specific. A 64-bit processor
- * usually has a 64-bit CM and a 32-bit one has a 32-bit CM but a 64-bit
- * processor could come with a 32-bit CM. Moreover, accesses on 64-bit CMs
- * can be done either using regular 64-bit load/store instructions, or 32-bit
- * load/store instruction on 32-bit register pairs. We opt for using 64-bit
- * accesses on 64-bit CMs and kernels and 32-bit in any other case.
+ * The CM register width is determined by the version of the CM, with CM3
+ * introducing 64 bit GCRs and all prior CM versions having 32 bit GCRs.
+ * However we may run a kernel built for MIPS32 on a system with 64 bit GCRs,
+ * or vice-versa. This variable indicates the width of the memory accesses
+ * that the kernel will perform to GCRs, which may differ from the actual
+ * width of the GCRs.
  *
  * It's set to 0 for 32-bit accesses and 1 for 64-bit accesses.
  */
@@ -125,7 +126,17 @@ static inline u32 read32_gcr_##name(void)                  \
                                                                \
 static inline u64 read64_gcr_##name(void)                      \
 {                                                              \
-       return __raw_readq(addr_gcr_##name());                  \
+       void __iomem *addr = addr_gcr_##name();                 \
+       u64 ret;                                                \
+                                                               \
+       if (mips_cm_is64) {                                     \
+               ret = __raw_readq(addr);                        \
+       } else {                                                \
+               ret = __raw_readl(addr);                        \
+               ret |= (u64)__raw_readl(addr + 0x4) << 32;      \
+       }                                                       \
+                                                               \
+       return ret;                                             \
 }                                                              \
                                                                \
 static inline unsigned long read_gcr_##name(void)              \
@@ -195,6 +206,8 @@ BUILD_CM_R_(gic_status,             MIPS_CM_GCB_OFS + 0xd0)
 BUILD_CM_R_(cpc_status,                MIPS_CM_GCB_OFS + 0xf0)
 BUILD_CM_RW(l2_config,         MIPS_CM_GCB_OFS + 0x130)
 BUILD_CM_RW(sys_config2,       MIPS_CM_GCB_OFS + 0x150)
+BUILD_CM_RW(l2_pft_control,    MIPS_CM_GCB_OFS + 0x300)
+BUILD_CM_RW(l2_pft_control_b,  MIPS_CM_GCB_OFS + 0x308)
 
 /* Core Local & Core Other register accessor functions */
 BUILD_CM_Cx_RW(reset_release,  0x00)
@@ -245,11 +258,14 @@ BUILD_CM_Cx_R_(tcid_8_priority,   0x80)
                 ((minor) << CM_GCR_REV_MINOR_SHF))
 
 #define CM_REV_CM2                             CM_ENCODE_REV(6, 0)
+#define CM_REV_CM2_5                           CM_ENCODE_REV(7, 0)
 #define CM_REV_CM3                             CM_ENCODE_REV(8, 0)
 
 /* GCR_ERROR_CAUSE register fields */
 #define CM_GCR_ERROR_CAUSE_ERRTYPE_SHF         27
 #define CM_GCR_ERROR_CAUSE_ERRTYPE_MSK         (_ULCAST_(0x1f) << 27)
+#define CM3_GCR_ERROR_CAUSE_ERRTYPE_SHF                58
+#define CM3_GCR_ERROR_CAUSE_ERRTYPE_MSK                GENMASK_ULL(63, 58)
 #define CM_GCR_ERROR_CAUSE_ERRINFO_SHF         0
 #define CM_GCR_ERROR_CAUSE_ERRINGO_MSK         (_ULCAST_(0x7ffffff) << 0)
 
@@ -321,6 +337,20 @@ BUILD_CM_Cx_R_(tcid_8_priority,    0x80)
 #define CM_GCR_SYS_CONFIG2_MAXVPW_SHF          0
 #define CM_GCR_SYS_CONFIG2_MAXVPW_MSK          (_ULCAST_(0xf) << 0)
 
+/* GCR_L2_PFT_CONTROL register fields */
+#define CM_GCR_L2_PFT_CONTROL_PAGEMASK_SHF     12
+#define CM_GCR_L2_PFT_CONTROL_PAGEMASK_MSK     (_ULCAST_(0xfffff) << 12)
+#define CM_GCR_L2_PFT_CONTROL_PFTEN_SHF                8
+#define CM_GCR_L2_PFT_CONTROL_PFTEN_MSK                (_ULCAST_(0x1) << 8)
+#define CM_GCR_L2_PFT_CONTROL_NPFT_SHF         0
+#define CM_GCR_L2_PFT_CONTROL_NPFT_MSK         (_ULCAST_(0xff) << 0)
+
+/* GCR_L2_PFT_CONTROL_B register fields */
+#define CM_GCR_L2_PFT_CONTROL_B_CEN_SHF                8
+#define CM_GCR_L2_PFT_CONTROL_B_CEN_MSK                (_ULCAST_(0x1) << 8)
+#define CM_GCR_L2_PFT_CONTROL_B_PORTID_SHF     0
+#define CM_GCR_L2_PFT_CONTROL_B_PORTID_MSK     (_ULCAST_(0xff) << 0)
+
 /* GCR_Cx_COHERENCE register fields */
 #define CM_GCR_Cx_COHERENCE_COHDOMAINEN_SHF    0
 #define CM_GCR_Cx_COHERENCE_COHDOMAINEN_MSK    (_ULCAST_(0xff) << 0)
@@ -329,11 +359,15 @@ BUILD_CM_Cx_R_(tcid_8_priority,   0x80)
 #define CM_GCR_Cx_CONFIG_IOCUTYPE_SHF          10
 #define CM_GCR_Cx_CONFIG_IOCUTYPE_MSK          (_ULCAST_(0x3) << 10)
 #define CM_GCR_Cx_CONFIG_PVPE_SHF              0
-#define CM_GCR_Cx_CONFIG_PVPE_MSK              (_ULCAST_(0x1ff) << 0)
+#define CM_GCR_Cx_CONFIG_PVPE_MSK              (_ULCAST_(0x3ff) << 0)
 
 /* GCR_Cx_OTHER register fields */
 #define CM_GCR_Cx_OTHER_CORENUM_SHF            16
 #define CM_GCR_Cx_OTHER_CORENUM_MSK            (_ULCAST_(0xffff) << 16)
+#define CM3_GCR_Cx_OTHER_CORE_SHF              8
+#define CM3_GCR_Cx_OTHER_CORE_MSK              (_ULCAST_(0x3f) << 8)
+#define CM3_GCR_Cx_OTHER_VP_SHF                        0
+#define CM3_GCR_Cx_OTHER_VP_MSK                        (_ULCAST_(0x7) << 0)
 
 /* GCR_Cx_RESET_BASE register fields */
 #define CM_GCR_Cx_RESET_BASE_BEVEXCBASE_SHF    12
@@ -444,4 +478,32 @@ static inline unsigned int mips_cm_vp_id(unsigned int cpu)
        return (core * mips_cm_max_vp_width()) + vp;
 }
 
+#ifdef CONFIG_MIPS_CM
+
+/**
+ * mips_cm_lock_other - lock access to another core
+ * @core: the other core to be accessed
+ * @vp: the VP within the other core to be accessed
+ *
+ * Call before operating upon a core via the 'other' register region in
+ * order to prevent the region being moved during access. Must be followed
+ * by a call to mips_cm_unlock_other.
+ */
+extern void mips_cm_lock_other(unsigned int core, unsigned int vp);
+
+/**
+ * mips_cm_unlock_other - unlock access to another core
+ *
+ * Call after operating upon another core via the 'other' register region.
+ * Must be called after mips_cm_lock_other.
+ */
+extern void mips_cm_unlock_other(void);
+
+#else /* !CONFIG_MIPS_CM */
+
+static inline void mips_cm_lock_other(unsigned int core) { }
+static inline void mips_cm_unlock_other(void) { }
+
+#endif /* !CONFIG_MIPS_CM */
+
 #endif /* __MIPS_ASM_MIPS_CM_H__ */
index f386f32702f17f75782ba9a58ffe5fa0ee37e186..e09035239e5383117947fcabe8920cdf8d7608f1 100644 (file)
@@ -149,7 +149,8 @@ BUILD_CPC_Cx_RW(other,              0x10)
  * core: the other core to be accessed
  *
  * Call before operating upon a core via the 'other' register region in
- * order to prevent the region being moved during access. Must be followed
+ * order to prevent the region being moved during access. Must be called
+ * within the bounds of a mips_cm_{lock,unlock}_other pair, and followed
  * by a call to mips_cpc_unlock_other.
  */
 extern void mips_cpc_lock_other(unsigned int core);
index c64781cf649f86b4ca4eec0fee38ba4c4da523e7..e43aca183c9918d4138f000c4a385659f8523eae 100644 (file)
@@ -50,7 +50,9 @@
 #define CP0_PAGEMASK $5
 #define CP0_WIRED $6
 #define CP0_INFO $7
+#define CP0_HWRENA $7, 0
 #define CP0_BADVADDR $8
+#define CP0_BADINSTR $8, 1
 #define CP0_COUNT $9
 #define CP0_ENTRYHI $10
 #define CP0_COMPARE $11
 #define CP0_CAUSE $13
 #define CP0_EPC $14
 #define CP0_PRID $15
+#define CP0_EBASE $15, 1
+#define CP0_CMGCRBASE $15, 3
 #define CP0_CONFIG $16
+#define CP0_CONFIG3 $16, 3
+#define CP0_CONFIG5 $16, 5
 #define CP0_LLADDR $17
 #define CP0_WATCHLO $18
 #define CP0_WATCHHI $19
 #define R3K_ENTRYLO_N          (_ULCAST_(1) << 11)
 
 /* MIPS32/64 EntryLo bit definitions */
-#ifdef CONFIG_64BIT
-/* as read by dmfc0 */
-#define MIPS_ENTRYLO_XI                (_ULCAST_(1) << 62)
-#define MIPS_ENTRYLO_RI                (_ULCAST_(1) << 63)
-#else
-/* as read by mfc0 */
-#define MIPS_ENTRYLO_XI                (_ULCAST_(1) << 30)
-#define MIPS_ENTRYLO_RI                (_ULCAST_(1) << 31)
-#endif
+#define MIPS_ENTRYLO_PFN_SHIFT 6
+#define MIPS_ENTRYLO_XI                (_ULCAST_(1) << (BITS_PER_LONG - 2))
+#define MIPS_ENTRYLO_RI                (_ULCAST_(1) << (BITS_PER_LONG - 1))
 
 /*
  * Values for PageMask register
index 89dd7fed1a570cf312e74b9216342fa6abbfdf22..ad1fccdb8d13ee3d14e97efe3831bd266ba65a4b 100644 (file)
@@ -33,7 +33,7 @@
 #define PAGE_SHIFT     16
 #endif
 #define PAGE_SIZE      (_AC(1,UL) << PAGE_SHIFT)
-#define PAGE_MASK      (~((1 << PAGE_SHIFT) - 1))
+#define PAGE_MASK      (~(PAGE_SIZE - 1))
 
 /*
  * This is used for calculating the real page sizes
index 59ee6dcf6eed9fd2b336347b0d674070baf9f298..3f832c3dd8f5f1cad76461b47ee00a0b7f85722d 100644 (file)
@@ -36,12 +36,6 @@ extern unsigned int vced_count, vcei_count;
  */
 #define HAVE_ARCH_PICK_MMAP_LAYOUT 1
 
-/*
- * A special page (the vdso) is mapped into all processes at the very
- * top of the virtual memory space.
- */
-#define SPECIAL_PAGES_SIZE PAGE_SIZE
-
 #ifdef CONFIG_32BIT
 #ifdef CONFIG_KVM_GUEST
 /* User space process size is limited to 1GB in KVM Guest Mode */
@@ -80,7 +74,7 @@ extern unsigned int vced_count, vcei_count;
 
 #endif
 
-#define STACK_TOP      ((TASK_SIZE & PAGE_MASK) - SPECIAL_PAGES_SIZE)
+#define STACK_TOP      (TASK_SIZE & PAGE_MASK)
 
 /*
  * This decides where the kernel will search for a free chunk of vm
index cca56aa40ff4a1cd475457c16783bc71855f43c5..8f4ca5dd992b1e8ed28791488c1ebe8403f80d7c 100644 (file)
 /*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Alex Smith <alex.smith@imgtec.com>
  *
- * Copyright (C) 2009 Cavium Networks
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
  */
 
 #ifndef __ASM_VDSO_H
 #define __ASM_VDSO_H
 
-#include <linux/types.h>
+#include <linux/mm_types.h>
 
+#include <asm/barrier.h>
 
-#ifdef CONFIG_32BIT
-struct mips_vdso {
-       u32 signal_trampoline[2];
-       u32 rt_signal_trampoline[2];
+/**
+ * struct mips_vdso_image - Details of a VDSO image.
+ * @data: Pointer to VDSO image data (page-aligned).
+ * @size: Size of the VDSO image data (page-aligned).
+ * @off_sigreturn: Offset of the sigreturn() trampoline.
+ * @off_rt_sigreturn: Offset of the rt_sigreturn() trampoline.
+ * @mapping: Special mapping structure.
+ *
+ * This structure contains details of a VDSO image, including the image data
+ * and offsets of certain symbols required by the kernel. It is generated as
+ * part of the VDSO build process, aside from the mapping page array, which is
+ * populated at runtime.
+ */
+struct mips_vdso_image {
+       void *data;
+       unsigned long size;
+
+       unsigned long off_sigreturn;
+       unsigned long off_rt_sigreturn;
+
+       struct vm_special_mapping mapping;
 };
-#else  /* !CONFIG_32BIT */
-struct mips_vdso {
-       u32 o32_signal_trampoline[2];
-       u32 o32_rt_signal_trampoline[2];
-       u32 rt_signal_trampoline[2];
-       u32 n32_rt_signal_trampoline[2];
+
+/*
+ * The following structures are auto-generated as part of the build for each
+ * ABI by genvdso, see arch/mips/vdso/Makefile.
+ */
+
+extern struct mips_vdso_image vdso_image;
+
+#ifdef CONFIG_MIPS32_O32
+extern struct mips_vdso_image vdso_image_o32;
+#endif
+
+#ifdef CONFIG_MIPS32_N32
+extern struct mips_vdso_image vdso_image_n32;
+#endif
+
+/**
+ * union mips_vdso_data - Data provided by the kernel for the VDSO.
+ * @xtime_sec:         Current real time (seconds part).
+ * @xtime_nsec:                Current real time (nanoseconds part, shifted).
+ * @wall_to_mono_sec:  Wall-to-monotonic offset (seconds part).
+ * @wall_to_mono_nsec: Wall-to-monotonic offset (nanoseconds part).
+ * @seq_count:         Counter to synchronise updates (odd = updating).
+ * @cs_shift:          Clocksource shift value.
+ * @clock_mode:                Clocksource to use for time functions.
+ * @cs_mult:           Clocksource multiplier value.
+ * @cs_cycle_last:     Clock cycle value at last update.
+ * @cs_mask:           Clocksource mask value.
+ * @tz_minuteswest:    Minutes west of Greenwich (from timezone).
+ * @tz_dsttime:                Type of DST correction (from timezone).
+ *
+ * This structure contains data needed by functions within the VDSO. It is
+ * populated by the kernel and mapped read-only into user memory. The time
+ * fields are mirrors of internal data from the timekeeping infrastructure.
+ *
+ * Note: Care should be taken when modifying as the layout must remain the same
+ * for both 64- and 32-bit (for 32-bit userland on 64-bit kernel).
+ */
+union mips_vdso_data {
+       struct {
+               u64 xtime_sec;
+               u64 xtime_nsec;
+               u32 wall_to_mono_sec;
+               u32 wall_to_mono_nsec;
+               u32 seq_count;
+               u32 cs_shift;
+               u8 clock_mode;
+               u32 cs_mult;
+               u64 cs_cycle_last;
+               u64 cs_mask;
+               s32 tz_minuteswest;
+               s32 tz_dsttime;
+       };
+
+       u8 page[PAGE_SIZE];
 };
-#endif /* CONFIG_32BIT */
+
+static inline u32 vdso_data_read_begin(const union mips_vdso_data *data)
+{
+       u32 seq;
+
+       while (true) {
+               seq = ACCESS_ONCE(data->seq_count);
+               if (likely(!(seq & 1))) {
+                       /* Paired with smp_wmb() in vdso_data_write_*(). */
+                       smp_rmb();
+                       return seq;
+               }
+
+               cpu_relax();
+       }
+}
+
+static inline bool vdso_data_read_retry(const union mips_vdso_data *data,
+                                       u32 start_seq)
+{
+       /* Paired with smp_wmb() in vdso_data_write_*(). */
+       smp_rmb();
+       return unlikely(data->seq_count != start_seq);
+}
+
+static inline void vdso_data_write_begin(union mips_vdso_data *data)
+{
+       ++data->seq_count;
+
+       /* Ensure sequence update is written before other data page values. */
+       smp_wmb();
+}
+
+static inline void vdso_data_write_end(union mips_vdso_data *data)
+{
+       /* Ensure data values are written before updating sequence again. */
+       smp_wmb();
+       ++data->seq_count;
+}
 
 #endif /* __ASM_VDSO_H */
index 96fe7395ed8dc8df6d2675bf31626b45133c15e4..f2cf4146114679253195769bab10b859f41026d6 100644 (file)
@@ -1,9 +1,9 @@
 # UAPI Header export list
 include include/uapi/asm-generic/Kbuild.asm
 
-generic-y += auxvec.h
 generic-y += ipcbuf.h
 
+header-y += auxvec.h
 header-y += bitfield.h
 header-y += bitsperlong.h
 header-y += break.h
diff --git a/arch/mips/include/uapi/asm/auxvec.h b/arch/mips/include/uapi/asm/auxvec.h
new file mode 100644 (file)
index 0000000..c9c7195
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Alex Smith <alex.smith@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __ASM_AUXVEC_H
+#define __ASM_AUXVEC_H
+
+/* Location of VDSO image. */
+#define AT_SYSINFO_EHDR                33
+
+#endif /* __ASM_AUXVEC_H */
index 459cb017306c21eb63259b8cb0a406c65080cc8b..934b15b5b575f15b04fae0bf44065440773f7593 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/power_supply.h>
 #include <linux/power/jz4740-battery.h>
 #include <linux/power/gpio-charger.h>
+#include <linux/pwm.h>
 
 #include <asm/mach-jz4740/gpio.h>
 #include <asm/mach-jz4740/jz4740_fb.h>
@@ -34,8 +35,6 @@
 #include <linux/regulator/fixed.h>
 #include <linux/regulator/machine.h>
 
-#include <linux/leds_pwm.h>
-
 #include <asm/mach-jz4740/platform.h>
 
 #include "clock.h"
@@ -399,13 +398,15 @@ static struct platform_device avt2_usb_regulator_device = {
        }
 };
 
+static struct pwm_lookup qi_lb60_pwm_lookup[] = {
+       PWM_LOOKUP("jz4740-pwm", 4, "pwm-beeper", NULL, 0,
+                  PWM_POLARITY_NORMAL),
+};
+
 /* beeper */
 static struct platform_device qi_lb60_pwm_beeper = {
        .name = "pwm-beeper",
        .id = -1,
-       .dev = {
-               .platform_data = (void *)4,
-       },
 };
 
 /* charger */
@@ -491,6 +492,8 @@ static int __init qi_lb60_init_platform_devices(void)
                platform_device_register(&jz4740_usb_ohci_device);
        }
 
+       pwm_add_table(qi_lb60_pwm_lookup, ARRAY_SIZE(qi_lb60_pwm_lookup));
+
        return platform_add_devices(jz_platform_devices,
                                        ARRAY_SIZE(jz_platform_devices));
 
index d982be1ea1c3f3125da9762f3e1b203ae939b1d0..68e2b7db9348f1d168666411544a90bd080d0ae0 100644 (file)
@@ -51,6 +51,7 @@ obj-$(CONFIG_MIPS_MT_FPAFF)   += mips-mt-fpaff.o
 obj-$(CONFIG_MIPS_MT_SMP)      += smp-mt.o
 obj-$(CONFIG_MIPS_CMP)         += smp-cmp.o
 obj-$(CONFIG_MIPS_CPS)         += smp-cps.o cps-vec.o
+obj-$(CONFIG_MIPS_CPS_NS16550) += cps-vec-ns16550.o
 obj-$(CONFIG_MIPS_GIC_IPI)     += smp-gic.o
 obj-$(CONFIG_MIPS_SPRAM)       += spram.o
 
diff --git a/arch/mips/kernel/cps-vec-ns16550.S b/arch/mips/kernel/cps-vec-ns16550.S
new file mode 100644 (file)
index 0000000..6d246ad
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <asm/addrspace.h>
+#include <asm/asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <linux/serial_reg.h>
+
+#define UART_TX_OFS    (UART_TX << CONFIG_MIPS_CPS_NS16550_SHIFT)
+#define UART_LSR_OFS   (UART_LSR << CONFIG_MIPS_CPS_NS16550_SHIFT)
+
+/**
+ * _mips_cps_putc() - write a character to the UART
+ * @a0: ASCII character to write
+ * @t9: UART base address
+ */
+LEAF(_mips_cps_putc)
+1:     lw              t0, UART_LSR_OFS(t9)
+       andi            t0, t0, UART_LSR_TEMT
+       beqz            t0, 1b
+       sb              a0, UART_TX_OFS(t9)
+       jr              ra
+       END(_mips_cps_putc)
+
+/**
+ * _mips_cps_puts() - write a string to the UART
+ * @a0: pointer to NULL-terminated ASCII string
+ * @t9: UART base address
+ *
+ * Write a null-terminated ASCII string to the UART.
+ */
+NESTED(_mips_cps_puts, 0, ra)
+       move            s7, ra
+       move            s6, a0
+
+1:     lb              a0, 0(s6)
+       beqz            a0, 2f
+       jal             _mips_cps_putc
+       PTR_ADDIU       s6, s6, 1
+       b               1b
+
+2:     jr              s7
+       END(_mips_cps_puts)
+
+/**
+ * _mips_cps_putx4 - write a 4b hex value to the UART
+ * @a0: the 4b value to write to the UART
+ * @t9: UART base address
+ *
+ * Write a single hexadecimal character to the UART.
+ */
+NESTED(_mips_cps_putx4, 0, ra)
+       andi            a0, a0, 0xf
+       li              t0, '0'
+       blt             a0, 10, 1f
+       li              t0, 'a'
+       addiu           a0, a0, -10
+1:     addu            a0, a0, t0
+       b               _mips_cps_putc
+       END(_mips_cps_putx4)
+
+/**
+ * _mips_cps_putx8 - write an 8b hex value to the UART
+ * @a0: the 8b value to write to the UART
+ * @t9: UART base address
+ *
+ * Write an 8 bit value (ie. 2 hexadecimal characters) to the UART.
+ */
+NESTED(_mips_cps_putx8, 0, ra)
+       move            s3, ra
+       move            s2, a0
+       srl             a0, a0, 4
+       jal             _mips_cps_putx4
+       move            a0, s2
+       move            ra, s3
+       b               _mips_cps_putx4
+       END(_mips_cps_putx8)
+
+/**
+ * _mips_cps_putx16 - write a 16b hex value to the UART
+ * @a0: the 16b value to write to the UART
+ * @t9: UART base address
+ *
+ * Write a 16 bit value (ie. 4 hexadecimal characters) to the UART.
+ */
+NESTED(_mips_cps_putx16, 0, ra)
+       move            s5, ra
+       move            s4, a0
+       srl             a0, a0, 8
+       jal             _mips_cps_putx8
+       move            a0, s4
+       move            ra, s5
+       b               _mips_cps_putx8
+       END(_mips_cps_putx16)
+
+/**
+ * _mips_cps_putx32 - write a 32b hex value to the UART
+ * @a0: the 32b value to write to the UART
+ * @t9: UART base address
+ *
+ * Write a 32 bit value (ie. 8 hexadecimal characters) to the UART.
+ */
+NESTED(_mips_cps_putx32, 0, ra)
+       move            s7, ra
+       move            s6, a0
+       srl             a0, a0, 16
+       jal             _mips_cps_putx16
+       move            a0, s6
+       move            ra, s7
+       b               _mips_cps_putx16
+       END(_mips_cps_putx32)
+
+#ifdef CONFIG_64BIT
+
+/**
+ * _mips_cps_putx64 - write a 64b hex value to the UART
+ * @a0: the 64b value to write to the UART
+ * @t9: UART base address
+ *
+ * Write a 64 bit value (ie. 16 hexadecimal characters) to the UART.
+ */
+NESTED(_mips_cps_putx64, 0, ra)
+       move            sp, ra
+       move            s8, a0
+       dsrl32          a0, a0, 0
+       jal             _mips_cps_putx32
+       move            a0, s8
+       move            ra, sp
+       b               _mips_cps_putx32
+       END(_mips_cps_putx64)
+
+#define _mips_cps_putxlong _mips_cps_putx64
+
+#else /* !CONFIG_64BIT */
+
+#define _mips_cps_putxlong _mips_cps_putx32
+
+#endif /* !CONFIG_64BIT */
+
+/**
+ * mips_cps_bev_dump() - dump relevant exception state to UART
+ * @a0: pointer to NULL-terminated ASCII string naming the exception
+ *
+ * Write information that may be useful in debugging an exception to the
+ * UART configured by CONFIG_MIPS_CPS_NS16550_*. As this BEV exception
+ * will only be run if something goes horribly wrong very early during
+ * the bringup of a core and it is very likely to be unsafe to perform
+ * memory accesses at that point (cache state indeterminate, EVA may not
+ * be configured, coherence may be disabled) let alone have a stack,
+ * this is all written in assembly using only registers & unmapped
+ * uncached access to the UART registers.
+ */
+LEAF(mips_cps_bev_dump)
+       move            s0, ra
+       move            s1, a0
+
+       li              t9, CKSEG1ADDR(CONFIG_MIPS_CPS_NS16550_BASE)
+
+       PTR_LA          a0, str_newline
+       jal             _mips_cps_puts
+       PTR_LA          a0, str_bev
+       jal             _mips_cps_puts
+       move            a0, s1
+       jal             _mips_cps_puts
+       PTR_LA          a0, str_newline
+       jal             _mips_cps_puts
+       PTR_LA          a0, str_newline
+       jal             _mips_cps_puts
+
+#define DUMP_COP0_REG(reg, name, sz, _mfc0)            \
+       PTR_LA          a0, 8f;                         \
+       jal             _mips_cps_puts;                 \
+       _mfc0           a0, reg;                        \
+       jal             _mips_cps_putx##sz;             \
+       PTR_LA          a0, str_newline;                \
+       jal             _mips_cps_puts;                 \
+       TEXT(name)
+
+       DUMP_COP0_REG(CP0_CAUSE,    "Cause:    0x", 32, mfc0)
+       DUMP_COP0_REG(CP0_STATUS,   "Status:   0x", 32, mfc0)
+       DUMP_COP0_REG(CP0_EBASE,    "EBase:    0x", long, MFC0)
+       DUMP_COP0_REG(CP0_BADVADDR, "BadVAddr: 0x", long, MFC0)
+       DUMP_COP0_REG(CP0_BADINSTR, "BadInstr: 0x", 32, mfc0)
+
+       PTR_LA          a0, str_newline
+       jal             _mips_cps_puts
+       jr              s0
+       END(mips_cps_bev_dump)
+
+.pushsection   .data
+str_bev: .asciiz "BEV Exception: "
+str_newline: .asciiz "\r\n"
+.popsection
index 209ded16806bf5a295ff202258f5b7ff42070940..8fd5a276cad23493f6500d0f4b01515ee20062f5 100644 (file)
 
 .set noreorder
 
+#ifdef CONFIG_64BIT
+# define STATUS_BITDEPS                ST0_KX
+#else
+# define STATUS_BITDEPS                0
+#endif
+
+#ifdef CONFIG_MIPS_CPS_NS16550
+
+#define DUMP_EXCEP(name)               \
+       PTR_LA  a0, 8f;                 \
+       jal     mips_cps_bev_dump;      \
+        nop;                           \
+       TEXT(name)
+
+#else /* !CONFIG_MIPS_CPS_NS16550 */
+
+#define DUMP_EXCEP(name)
+
+#endif /* !CONFIG_MIPS_CPS_NS16550 */
+
        /*
         * Set dest to non-zero if the core supports the MT ASE, else zero. If
         * MT is not supported then branch to nomt.
         */
        .macro  has_mt  dest, nomt
-       mfc0    \dest, CP0_CONFIG
-       bgez    \dest, \nomt
-        mfc0   \dest, CP0_CONFIG, 1
+       mfc0    \dest, CP0_CONFIG, 1
        bgez    \dest, \nomt
         mfc0   \dest, CP0_CONFIG, 2
        bgez    \dest, \nomt
 
 LEAF(mips_cps_core_entry)
        /*
-        * These first 12 bytes will be patched by cps_smp_setup to load the
-        * base address of the CM GCRs into register v1 and the CCA to use into
-        * register s0.
+        * These first 4 bytes will be patched by cps_smp_setup to load the
+        * CCA to use into register s0.
         */
-       .quad   0
        .word   0
 
        /* Check whether we're here due to an NMI */
@@ -71,7 +87,7 @@ not_nmi:
        mtc0    t0, CP0_CAUSE
 
        /* Setup Status */
-       li      t0, ST0_CU1 | ST0_CU0
+       li      t0, ST0_CU1 | ST0_CU0 | ST0_BEV | STATUS_BITDEPS
        mtc0    t0, CP0_STATUS
 
        /*
@@ -151,6 +167,12 @@ dcache_done:
        mtc0    t0, CP0_CONFIG
        ehb
 
+       /* Calculate an uncached address for the CM GCRs */
+       MFC0    v1, CP0_CMGCRBASE
+       PTR_SLL v1, v1, 4
+       PTR_LI  t0, UNCAC_BASE
+       PTR_ADDU v1, v1, t0
+
        /* Enter the coherent domain */
        li      t0, 0xff
        sw      t0, GCR_CL_COHERENCE_OFS(v1)
@@ -188,36 +210,42 @@ dcache_done:
 
 .org 0x200
 LEAF(excep_tlbfill)
+       DUMP_EXCEP("TLB Fill")
        b       .
         nop
        END(excep_tlbfill)
 
 .org 0x280
 LEAF(excep_xtlbfill)
+       DUMP_EXCEP("XTLB Fill")
        b       .
         nop
        END(excep_xtlbfill)
 
 .org 0x300
 LEAF(excep_cache)
+       DUMP_EXCEP("Cache")
        b       .
         nop
        END(excep_cache)
 
 .org 0x380
 LEAF(excep_genex)
+       DUMP_EXCEP("General")
        b       .
         nop
        END(excep_genex)
 
 .org 0x400
 LEAF(excep_intex)
+       DUMP_EXCEP("Interrupt")
        b       .
         nop
        END(excep_intex)
 
 .org 0x480
 LEAF(excep_ejtag)
+       DUMP_EXCEP("EJTAG")
        PTR_LA  k0, ejtag_debug_handler
        jr      k0
         nop
index 09a51d091941be3aa75ae37b53b386714a6d3db5..6b9064499bd3dfb49ef0c09ad3da48034dea0ff2 100644 (file)
@@ -536,8 +536,7 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c)
                c->options |= MIPS_CPU_SEGMENTS;
        if (config3 & MIPS_CONF3_MSA)
                c->ases |= MIPS_ASE_MSA;
-       /* Only tested on 32-bit cores */
-       if ((config3 & MIPS_CONF3_PW) && config_enabled(CONFIG_32BIT)) {
+       if (config3 & MIPS_CONF3_PW) {
                c->htw_seq = 0;
                c->options |= MIPS_CPU_HTW;
        }
index e5ed7ada14334c682218aa567e18414465fea81c..1f910563fdf60b3be0b4dcdca024837638818bf8 100644 (file)
@@ -28,6 +28,43 @@ static u64 notrace r4k_read_sched_clock(void)
        return read_c0_count();
 }
 
+static inline unsigned int rdhwr_count(void)
+{
+       unsigned int count;
+
+       __asm__ __volatile__(
+       "       .set push\n"
+       "       .set mips32r2\n"
+       "       rdhwr   %0, $2\n"
+       "       .set pop\n"
+       : "=r" (count));
+
+       return count;
+}
+
+static bool rdhwr_count_usable(void)
+{
+       unsigned int prev, curr, i;
+
+       /*
+        * Older QEMUs have a broken implementation of RDHWR for the CP0 count
+        * which always returns a constant value. Try to identify this and don't
+        * use it in the VDSO if it is broken. This workaround can be removed
+        * once the fix has been in QEMU stable for a reasonable amount of time.
+        */
+       for (i = 0, prev = rdhwr_count(); i < 100; i++) {
+               curr = rdhwr_count();
+
+               if (curr != prev)
+                       return true;
+
+               prev = curr;
+       }
+
+       pr_warn("Not using R4K clocksource in VDSO due to broken RDHWR\n");
+       return false;
+}
+
 int __init init_r4k_clocksource(void)
 {
        if (!cpu_has_counter || !mips_hpt_frequency)
@@ -36,6 +73,13 @@ int __init init_r4k_clocksource(void)
        /* Calculate a somewhat reasonable rating value */
        clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000;
 
+       /*
+        * R2 onwards makes the count accessible to user mode so it can be used
+        * by the VDSO (HWREna is configured by configure_hwrena()).
+        */
+       if (cpu_has_mips_r2_r6 && rdhwr_count_usable())
+               clocksource_mips.archdata.vdso_clock_mode = VDSO_CLOCK_R4K;
+
        clocksource_register_hz(&clocksource_mips, mips_hpt_frequency);
 
        sched_clock_register(r4k_read_sched_clock, 32, mips_hpt_frequency);
index ab1478d5a4db1b247caa94527925da0d005adf10..46794d64c0bfe3f9779cc43714cc7c3fbb6a10bc 100644 (file)
@@ -134,6 +134,16 @@ void __init check_wait(void)
                return;
        }
 
+       /*
+        * MIPSr6 specifies that masked interrupts should unblock an executing
+        * wait instruction, and thus that it is safe for us to use
+        * r4k_wait_irqoff. Yippee!
+        */
+       if (cpu_has_mips_r6) {
+               cpu_wait = r4k_wait_irqoff;
+               return;
+       }
+
        switch (current_cpu_type()) {
        case CPU_R3081:
        case CPU_R3081E:
@@ -155,12 +165,12 @@ void __init check_wait(void)
        case CPU_4KEC:
        case CPU_4KSC:
        case CPU_5KC:
+       case CPU_5KE:
        case CPU_25KF:
        case CPU_PR4450:
        case CPU_BMIPS3300:
        case CPU_BMIPS4350:
        case CPU_BMIPS4380:
-       case CPU_BMIPS5000:
        case CPU_CAVIUM_OCTEON:
        case CPU_CAVIUM_OCTEON_PLUS:
        case CPU_CAVIUM_OCTEON2:
@@ -171,7 +181,9 @@ void __init check_wait(void)
        case CPU_XLP:
                cpu_wait = r4k_wait;
                break;
-
+       case CPU_BMIPS5000:
+               cpu_wait = r4k_wait_irqoff;
+               break;
        case CPU_RM7000:
                cpu_wait = rm7k_wait_irqoff;
                break;
@@ -196,7 +208,6 @@ void __init check_wait(void)
        case CPU_INTERAPTIV:
        case CPU_M5150:
        case CPU_QEMU_GENERIC:
-       case CPU_I6400:
                cpu_wait = r4k_wait;
                if (read_c0_config7() & MIPS_CONF7_WII)
                        cpu_wait = r4k_wait_irqoff;
index b8ceee576cdfce2e22e1b2d8ffab6f90bf69f6b8..1448c1f43d4e4ae6657b819a5c8ee238a7332e34 100644 (file)
@@ -9,6 +9,8 @@
  */
 
 #include <linux/errno.h>
+#include <linux/percpu.h>
+#include <linux/spinlock.h>
 
 #include <asm/mips-cm.h>
 #include <asm/mipsregs.h>
@@ -136,6 +138,9 @@ static char *cm3_causes[32] = {
        "0x19", "0x1a", "0x1b", "0x1c", "0x1d", "0x1e", "0x1f"
 };
 
+static DEFINE_PER_CPU_ALIGNED(spinlock_t, cm_core_lock);
+static DEFINE_PER_CPU_ALIGNED(unsigned long, cm_core_lock_flags);
+
 phys_addr_t __mips_cm_phys_base(void)
 {
        u32 config3 = read_c0_config3();
@@ -200,6 +205,7 @@ int mips_cm_probe(void)
 {
        phys_addr_t addr;
        u32 base_reg;
+       unsigned cpu;
 
        /*
         * No need to probe again if we have already been
@@ -247,38 +253,70 @@ int mips_cm_probe(void)
        /* determine register width for this CM */
        mips_cm_is64 = config_enabled(CONFIG_64BIT) && (mips_cm_revision() >= CM_REV_CM3);
 
+       for_each_possible_cpu(cpu)
+               spin_lock_init(&per_cpu(cm_core_lock, cpu));
+
        return 0;
 }
 
-void mips_cm_error_report(void)
+void mips_cm_lock_other(unsigned int core, unsigned int vp)
 {
-       unsigned long revision = mips_cm_revision();
+       unsigned curr_core;
+       u32 val;
+
+       preempt_disable();
+       curr_core = current_cpu_data.core;
+       spin_lock_irqsave(&per_cpu(cm_core_lock, curr_core),
+                         per_cpu(cm_core_lock_flags, curr_core));
+
+       if (mips_cm_revision() >= CM_REV_CM3) {
+               val = core << CM3_GCR_Cx_OTHER_CORE_SHF;
+               val |= vp << CM3_GCR_Cx_OTHER_VP_SHF;
+       } else {
+               BUG_ON(vp != 0);
+               val = core << CM_GCR_Cx_OTHER_CORENUM_SHF;
+       }
+
+       write_gcr_cl_other(val);
+
        /*
-        * CM3 has a 64-bit Error cause register with 0:57 containing the error
-        * info and 63:58 the error type. For old CMs, everything is contained
-        * in a single 32-bit register (0:26 and 31:27 respectively). Even
-        * though the cm_error is u64, we will simply ignore the upper word
-        * for CM2.
+        * Ensure the core-other region reflects the appropriate core &
+        * VP before any accesses to it occur.
         */
-       u64 cm_error = read_gcr_error_cause();
-       int cm_error_cause_sft = CM_GCR_ERROR_CAUSE_ERRTYPE_SHF +
-                                ((revision >= CM_REV_CM3) ? 31 : 0);
-       unsigned long cm_addr = read_gcr_error_addr();
-       unsigned long cm_other = read_gcr_error_mult();
+       mb();
+}
+
+void mips_cm_unlock_other(void)
+{
+       unsigned curr_core = current_cpu_data.core;
+
+       spin_unlock_irqrestore(&per_cpu(cm_core_lock, curr_core),
+                              per_cpu(cm_core_lock_flags, curr_core));
+       preempt_enable();
+}
+
+void mips_cm_error_report(void)
+{
+       u64 cm_error, cm_addr, cm_other;
+       unsigned long revision;
        int ocause, cause;
        char buf[256];
 
        if (!mips_cm_present())
                return;
 
-       cause = cm_error >> cm_error_cause_sft;
+       revision = mips_cm_revision();
 
-       if (!cause)
-               /* All good */
-               return;
-
-       ocause = cm_other >> CM_GCR_ERROR_MULT_ERR2ND_SHF;
        if (revision < CM_REV_CM3) { /* CM2 */
+               cm_error = read_gcr_error_cause();
+               cm_addr = read_gcr_error_addr();
+               cm_other = read_gcr_error_mult();
+               cause = cm_error >> CM_GCR_ERROR_CAUSE_ERRTYPE_SHF;
+               ocause = cm_other >> CM_GCR_ERROR_MULT_ERR2ND_SHF;
+
+               if (!cause)
+                       return;
+
                if (cause < 16) {
                        unsigned long cca_bits = (cm_error >> 15) & 7;
                        unsigned long tr_bits = (cm_error >> 12) & 7;
@@ -310,18 +348,30 @@ void mips_cm_error_report(void)
                }
                        pr_err("CM_ERROR=%08llx %s <%s>\n", cm_error,
                               cm2_causes[cause], buf);
-               pr_err("CM_ADDR =%08lx\n", cm_addr);
-               pr_err("CM_OTHER=%08lx %s\n", cm_other, cm2_causes[ocause]);
+               pr_err("CM_ADDR =%08llx\n", cm_addr);
+               pr_err("CM_OTHER=%08llx %s\n", cm_other, cm2_causes[ocause]);
        } else { /* CM3 */
-       /* Used by cause == {1,2,3} */
-               unsigned long core_id_bits = (cm_error >> 22) & 0xf;
-               unsigned long vp_id_bits = (cm_error >> 18) & 0xf;
-               unsigned long cmd_bits = (cm_error >> 14) & 0xf;
-               unsigned long cmd_group_bits = (cm_error >> 11) & 0xf;
-               unsigned long cm3_cca_bits = (cm_error >> 8) & 7;
-               unsigned long mcp_bits = (cm_error >> 5) & 0xf;
-               unsigned long cm3_tr_bits = (cm_error >> 1) & 0xf;
-               unsigned long sched_bit = cm_error & 0x1;
+               ulong core_id_bits, vp_id_bits, cmd_bits, cmd_group_bits;
+               ulong cm3_cca_bits, mcp_bits, cm3_tr_bits, sched_bit;
+
+               cm_error = read64_gcr_error_cause();
+               cm_addr = read64_gcr_error_addr();
+               cm_other = read64_gcr_error_mult();
+               cause = cm_error >> CM3_GCR_ERROR_CAUSE_ERRTYPE_SHF;
+               ocause = cm_other >> CM_GCR_ERROR_MULT_ERR2ND_SHF;
+
+               if (!cause)
+                       return;
+
+               /* Used by cause == {1,2,3} */
+               core_id_bits = (cm_error >> 22) & 0xf;
+               vp_id_bits = (cm_error >> 18) & 0xf;
+               cmd_bits = (cm_error >> 14) & 0xf;
+               cmd_group_bits = (cm_error >> 11) & 0xf;
+               cm3_cca_bits = (cm_error >> 8) & 7;
+               mcp_bits = (cm_error >> 5) & 0xf;
+               cm3_tr_bits = (cm_error >> 1) & 0xf;
+               sched_bit = cm_error & 0x1;
 
                if (cause == 1 || cause == 3) { /* Tag ECC */
                        unsigned long tag_ecc = (cm_error >> 57) & 0x1;
@@ -363,12 +413,14 @@ void mips_cm_error_report(void)
                                 cm3_cmd_group[cmd_group_bits],
                                 cm3_cca_bits, 1 << mcp_bits,
                                 cm3_tr[cm3_tr_bits], sched_bit);
+               } else {
+                       buf[0] = 0;
                }
 
                pr_err("CM_ERROR=%llx %s <%s>\n", cm_error,
                       cm3_causes[cause], buf);
-               pr_err("CM_ADDR =%lx\n", cm_addr);
-               pr_err("CM_OTHER=%lx %s\n", cm_other, cm3_causes[ocause]);
+               pr_err("CM_ADDR =%llx\n", cm_addr);
+               pr_err("CM_OTHER=%llx %s\n", cm_other, cm3_causes[ocause]);
        }
 
        /* reprime cause register */
index 8af4d627b68b96d0d998ee7c4a06176af8234138..566b8d2c092c31de6293f245d81b12a899d40622 100644 (file)
@@ -76,6 +76,12 @@ void mips_cpc_lock_other(unsigned int core)
        spin_lock_irqsave(&per_cpu(cpc_core_lock, curr_core),
                          per_cpu(cpc_core_lock_flags, curr_core));
        write_cpc_cl_other(core << CPC_Cx_OTHER_CORENUM_SHF);
+
+       /*
+        * Ensure the core-other region reflects the appropriate core &
+        * VP before any accesses to it occur.
+        */
+       mb();
 }
 
 void mips_cpc_unlock_other(void)
index f2977f00911b303177fe086f72c0ae6be4a39313..1f5aac7f9ec3588ec3c48a563b057351b1abfe18 100644 (file)
@@ -22,6 +22,7 @@
 #include <asm/asm.h>
 #include <asm/branch.h>
 #include <asm/break.h>
+#include <asm/debug.h>
 #include <asm/fpu.h>
 #include <asm/fpu_emulator.h>
 #include <asm/inst.h>
@@ -2363,7 +2364,6 @@ static const struct file_operations mipsr2_clear_fops = {
 
 static int __init mipsr2_init_debugfs(void)
 {
-       extern struct dentry    *mips_debugfs_dir;
        struct dentry           *mipsr2_emul;
 
        if (!mips_debugfs_dir)
index 076ead2a985948e145864a17a506b2ff3a93bc31..87bc74a5a518c5fca349104a6257a2ea6242710c 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
 #include <asm/cpu.h>
+#include <asm/debug.h>
 #include <asm/mipsregs.h>
 
 static void build_segment_config(char *str, unsigned int cfg)
@@ -91,7 +92,6 @@ static const struct file_operations segments_fops = {
 
 static int __init segments_info(void)
 {
-       extern struct dentry *mips_debugfs_dir;
        struct dentry *segments;
 
        if (cpu_has_segments) {
index 479515109e5badec96942ee594e3a450ab011f11..66aac55df3497f79d39f1b203601eccf3a25a48f 100644 (file)
 #include <asm/cache.h>
 #include <asm/cdmm.h>
 #include <asm/cpu.h>
+#include <asm/debug.h>
 #include <asm/sections.h>
 #include <asm/setup.h>
 #include <asm/smp-ops.h>
 #include <asm/prom.h>
 
+#ifdef CONFIG_MIPS_ELF_APPENDED_DTB
+const char __section(.appended_dtb) __appended_dtb[0x100000];
+#endif /* CONFIG_MIPS_ELF_APPENDED_DTB */
+
 struct cpuinfo_mips cpu_data[NR_CPUS] __read_mostly;
 
 EXPORT_SYMBOL(cpu_data);
@@ -616,6 +621,10 @@ static void __init request_crashkernel(struct resource *res)
 }
 #endif /* !defined(CONFIG_KEXEC)  */
 
+#define USE_PROM_CMDLINE       IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER)
+#define USE_DTB_CMDLINE                IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB)
+#define EXTEND_WITH_PROM       IS_ENABLED(CONFIG_MIPS_CMDLINE_EXTEND)
+
 static void __init arch_mem_init(char **cmdline_p)
 {
        struct memblock_region *reg;
@@ -640,18 +649,24 @@ static void __init arch_mem_init(char **cmdline_p)
        pr_info("Determined physical RAM map:\n");
        print_memory_map();
 
-#ifdef CONFIG_CMDLINE_BOOL
-#ifdef CONFIG_CMDLINE_OVERRIDE
+#if defined(CONFIG_CMDLINE_BOOL) && defined(CONFIG_CMDLINE_OVERRIDE)
        strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
 #else
+       if ((USE_PROM_CMDLINE && arcs_cmdline[0]) ||
+           (USE_DTB_CMDLINE && !boot_command_line[0]))
+               strlcpy(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
+
+       if (EXTEND_WITH_PROM && arcs_cmdline[0]) {
+               strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
+               strlcat(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
+       }
+
+#if defined(CONFIG_CMDLINE_BOOL)
        if (builtin_cmdline[0]) {
-               strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
-               strlcat(arcs_cmdline, builtin_cmdline, COMMAND_LINE_SIZE);
+               strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
+               strlcat(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
        }
-       strlcpy(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
 #endif
-#else
-       strlcpy(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
 #endif
        strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
 
index 2fec67bfc457cc969056f6f46258c0f00992be83..bf792e2839a6f31b5cde496cb84892ded60d5b5f 100644 (file)
@@ -36,7 +36,6 @@
 #include <asm/ucontext.h>
 #include <asm/cpu-features.h>
 #include <asm/war.h>
-#include <asm/vdso.h>
 #include <asm/dsp.h>
 #include <asm/inst.h>
 #include <asm/msa.h>
@@ -752,16 +751,15 @@ static int setup_rt_frame(void *sig_return, struct ksignal *ksig,
 struct mips_abi mips_abi = {
 #ifdef CONFIG_TRAD_SIGNALS
        .setup_frame    = setup_frame,
-       .signal_return_offset = offsetof(struct mips_vdso, signal_trampoline),
 #endif
        .setup_rt_frame = setup_rt_frame,
-       .rt_signal_return_offset =
-               offsetof(struct mips_vdso, rt_signal_trampoline),
        .restart        = __NR_restart_syscall,
 
        .off_sc_fpregs = offsetof(struct sigcontext, sc_fpregs),
        .off_sc_fpc_csr = offsetof(struct sigcontext, sc_fpc_csr),
        .off_sc_used_math = offsetof(struct sigcontext, sc_used_math),
+
+       .vdso           = &vdso_image,
 };
 
 static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
@@ -801,11 +799,11 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
        }
 
        if (sig_uses_siginfo(&ksig->ka))
-               ret = abi->setup_rt_frame(vdso + abi->rt_signal_return_offset,
+               ret = abi->setup_rt_frame(vdso + abi->vdso->off_rt_sigreturn,
                                          ksig, regs, oldset);
        else
-               ret = abi->setup_frame(vdso + abi->signal_return_offset, ksig,
-                                      regs, oldset);
+               ret = abi->setup_frame(vdso + abi->vdso->off_sigreturn,
+                                      ksig, regs, oldset);
 
        signal_setup_done(ret, ksig, 0);
 }
index f7e89524e3166fc23b0ea7ae08c10137d75de74e..4909639aa35ba7fcb3de868c4c28ca92e8f7a54e 100644 (file)
@@ -31,7 +31,6 @@
 #include <asm/ucontext.h>
 #include <asm/fpu.h>
 #include <asm/war.h>
-#include <asm/vdso.h>
 #include <asm/dsp.h>
 
 #include "signal-common.h"
@@ -406,14 +405,12 @@ static int setup_rt_frame_32(void *sig_return, struct ksignal *ksig,
  */
 struct mips_abi mips_abi_32 = {
        .setup_frame    = setup_frame_32,
-       .signal_return_offset =
-               offsetof(struct mips_vdso, o32_signal_trampoline),
        .setup_rt_frame = setup_rt_frame_32,
-       .rt_signal_return_offset =
-               offsetof(struct mips_vdso, o32_rt_signal_trampoline),
        .restart        = __NR_O32_restart_syscall,
 
        .off_sc_fpregs = offsetof(struct sigcontext32, sc_fpregs),
        .off_sc_fpc_csr = offsetof(struct sigcontext32, sc_fpc_csr),
        .off_sc_used_math = offsetof(struct sigcontext32, sc_used_math),
+
+       .vdso           = &vdso_image_o32,
 };
index 0d017fdcaf07aa50c583e644f4dc1f21d9ab80ee..a7bc384305008ece50b78c9ff72364e54c7af2e5 100644 (file)
@@ -38,7 +38,6 @@
 #include <asm/fpu.h>
 #include <asm/cpu-features.h>
 #include <asm/war.h>
-#include <asm/vdso.h>
 
 #include "signal-common.h"
 
@@ -151,11 +150,11 @@ static int setup_rt_frame_n32(void *sig_return, struct ksignal *ksig,
 
 struct mips_abi mips_abi_n32 = {
        .setup_rt_frame = setup_rt_frame_n32,
-       .rt_signal_return_offset =
-               offsetof(struct mips_vdso, n32_rt_signal_trampoline),
        .restart        = __NR_N32_restart_syscall,
 
        .off_sc_fpregs = offsetof(struct sigcontext, sc_fpregs),
        .off_sc_fpc_csr = offsetof(struct sigcontext, sc_fpc_csr),
        .off_sc_used_math = offsetof(struct sigcontext, sc_used_math),
+
+       .vdso           = &vdso_image_n32,
 };
index c88937745b4ea18c7faf699f936f00cd42f9372d..e04c8057b88238956efe64c519dfa3aac41e1ba9 100644 (file)
@@ -8,6 +8,7 @@
  * option) any later version.
  */
 
+#include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/irqchip/mips-gic.h>
 #include <linux/sched.h>
@@ -37,8 +38,9 @@ static unsigned core_vpe_count(unsigned core)
        if (!config_enabled(CONFIG_MIPS_MT_SMP) || !cpu_has_mipsmt)
                return 1;
 
-       write_gcr_cl_other(core << CM_GCR_Cx_OTHER_CORENUM_SHF);
+       mips_cm_lock_other(core, 0);
        cfg = read_gcr_co_config() & CM_GCR_Cx_CONFIG_PVPE_MSK;
+       mips_cm_unlock_other();
        return (cfg >> CM_GCR_Cx_CONFIG_PVPE_SHF) + 1;
 }
 
@@ -133,11 +135,9 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
        /*
         * Patch the start of mips_cps_core_entry to provide:
         *
-        * v1 = CM base address
         * s0 = kseg0 CCA
         */
        entry_code = (u32 *)&mips_cps_core_entry;
-       UASM_i_LA(&entry_code, 3, (long)mips_cm_base);
        uasm_i_addiu(&entry_code, 16, 0, cca);
        blast_dcache_range((unsigned long)&mips_cps_core_entry,
                           (unsigned long)entry_code);
@@ -190,10 +190,11 @@ err_out:
 
 static void boot_core(unsigned core)
 {
-       u32 access;
+       u32 access, stat, seq_state;
+       unsigned timeout;
 
        /* Select the appropriate core */
-       write_gcr_cl_other(core << CM_GCR_Cx_OTHER_CORENUM_SHF);
+       mips_cm_lock_other(core, 0);
 
        /* Set its reset vector */
        write_gcr_co_reset_base(CKSEG1ADDR((unsigned long)mips_cps_core_entry));
@@ -210,12 +211,36 @@ static void boot_core(unsigned core)
                /* Reset the core */
                mips_cpc_lock_other(core);
                write_cpc_co_cmd(CPC_Cx_CMD_RESET);
+
+               timeout = 100;
+               while (true) {
+                       stat = read_cpc_co_stat_conf();
+                       seq_state = stat & CPC_Cx_STAT_CONF_SEQSTATE_MSK;
+
+                       /* U6 == coherent execution, ie. the core is up */
+                       if (seq_state == CPC_Cx_STAT_CONF_SEQSTATE_U6)
+                               break;
+
+                       /* Delay a little while before we start warning */
+                       if (timeout) {
+                               timeout--;
+                               mdelay(10);
+                               continue;
+                       }
+
+                       pr_warn("Waiting for core %u to start... STAT_CONF=0x%x\n",
+                               core, stat);
+                       mdelay(1000);
+               }
+
                mips_cpc_unlock_other();
        } else {
                /* Take the core out of reset */
                write_gcr_co_reset_release(0);
        }
 
+       mips_cm_unlock_other();
+
        /* The core is now powered up */
        bitmap_set(core_power, core, 1);
 }
index 5f0ab5bcd01edc5e454a3d534a996f6ed03697de..9b63829cf929408f3f75054478d6d3e637ff0c99 100644 (file)
@@ -46,9 +46,11 @@ void gic_send_ipi_single(int cpu, unsigned int action)
 
        if (mips_cpc_present() && (core != current_cpu_data.core)) {
                while (!cpumask_test_cpu(cpu, &cpu_coherent_mask)) {
+                       mips_cm_lock_other(core, 0);
                        mips_cpc_lock_other(core);
                        write_cpc_co_cmd(CPC_Cx_CMD_PWRUP);
                        mips_cpc_unlock_other();
+                       mips_cm_unlock_other();
                }
        }
 
index 39f7ab7b04269b6a22b3573fc3f2bc377605d088..f7d86955d1b80b43b4321e1314ea6ceede4224f4 100644 (file)
@@ -5,7 +5,7 @@
 #include <linux/debugfs.h>
 #include <linux/export.h>
 #include <linux/spinlock.h>
-
+#include <asm/debug.h>
 
 static int ss_get(void *data, u64 *val)
 {
@@ -115,8 +115,6 @@ static int multi_get(void *data, u64 *val)
 
 DEFINE_SIMPLE_ATTRIBUTE(fops_multi, multi_get, NULL, "%llu\n");
 
-
-extern struct dentry *mips_debugfs_dir;
 static int __init spinlock_test(void)
 {
        struct dentry *d;
index 1ba775d24d38f890d4e29a2168b533870d7cfb8b..506021f62549d98c7bc8260b300c659fd0118834 100644 (file)
  * Save stack-backtrace addresses into a stack_trace buffer:
  */
 static void save_raw_context_stack(struct stack_trace *trace,
-       unsigned long reg29)
+       unsigned long reg29, int savesched)
 {
        unsigned long *sp = (unsigned long *)reg29;
        unsigned long addr;
 
        while (!kstack_end(sp)) {
                addr = *sp++;
-               if (__kernel_text_address(addr)) {
+               if (__kernel_text_address(addr) &&
+                   (savesched || !in_sched_functions(addr))) {
                        if (trace->skip > 0)
                                trace->skip--;
                        else
@@ -31,7 +32,7 @@ static void save_raw_context_stack(struct stack_trace *trace,
 }
 
 static void save_context_stack(struct stack_trace *trace,
-       struct task_struct *tsk, struct pt_regs *regs)
+       struct task_struct *tsk, struct pt_regs *regs, int savesched)
 {
        unsigned long sp = regs->regs[29];
 #ifdef CONFIG_KALLSYMS
@@ -43,20 +44,22 @@ static void save_context_stack(struct stack_trace *trace,
                        (unsigned long)task_stack_page(tsk);
                if (stack_page && sp >= stack_page &&
                    sp <= stack_page + THREAD_SIZE - 32)
-                       save_raw_context_stack(trace, sp);
+                       save_raw_context_stack(trace, sp, savesched);
                return;
        }
        do {
-               if (trace->skip > 0)
-                       trace->skip--;
-               else
-                       trace->entries[trace->nr_entries++] = pc;
-               if (trace->nr_entries >= trace->max_entries)
-                       break;
+               if (savesched || !in_sched_functions(pc)) {
+                       if (trace->skip > 0)
+                               trace->skip--;
+                       else
+                               trace->entries[trace->nr_entries++] = pc;
+                       if (trace->nr_entries >= trace->max_entries)
+                               break;
+               }
                pc = unwind_stack(tsk, &sp, pc, &ra);
        } while (pc);
 #else
-       save_raw_context_stack(trace, sp);
+       save_raw_context_stack(trace, sp, savesched);
 #endif
 }
 
@@ -82,6 +85,6 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
                regs->cp0_epc = tsk->thread.reg31;
        } else
                prepare_frametrace(regs);
-       save_context_stack(trace, tsk, regs);
+       save_context_stack(trace, tsk, regs, tsk == current);
 }
 EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
index fdb392b27e8109f8b02a1b09b3a3d95cdbd20f14..886cb1976e90f682dafac7a958043d68bc4b6473 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/irq.h>
 #include <linux/perf_event.h>
 
+#include <asm/addrspace.h>
 #include <asm/bootinfo.h>
 #include <asm/branch.h>
 #include <asm/break.h>
@@ -1856,12 +1857,14 @@ void __noreturn nmi_exception_handler(struct pt_regs *regs)
 {
        char str[100];
 
+       nmi_enter();
        raw_notifier_call_chain(&nmi_chain, 0, regs);
        bust_spinlocks(1);
        snprintf(str, 100, "CPU%d NMI taken, CP0_EPC=%lx\n",
                 smp_processor_id(), regs->cp0_epc);
        regs->cp0_epc = read_c0_errorepc();
        die(str, regs);
+       nmi_exit();
 }
 
 #define VECTORSPACING 0x100    /* for EI/VI mode */
@@ -2204,12 +2207,8 @@ void __init trap_init(void)
                ebase = (unsigned long)
                        __alloc_bootmem(size, 1 << fls(size), 0);
        } else {
-#ifdef CONFIG_KVM_GUEST
-#define KVM_GUEST_KSEG0     0x40000000
-        ebase = KVM_GUEST_KSEG0;
-#else
-        ebase = CKSEG0;
-#endif
+               ebase = CAC_BASE;
+
                if (cpu_has_mips_r2_r6)
                        ebase += (read_c0_ebase() & 0x3ffff000);
        }
index 990354dd6bdedb79d77d8ec4291e14e3836dcba3..490cea569d57d0088e50e241f3465c91f07bbcc7 100644 (file)
@@ -85,6 +85,7 @@
 #include <asm/branch.h>
 #include <asm/byteorder.h>
 #include <asm/cop2.h>
+#include <asm/debug.h>
 #include <asm/fpu.h>
 #include <asm/fpu_emulator.h>
 #include <asm/inst.h>
@@ -2295,7 +2296,6 @@ sigbus:
 }
 
 #ifdef CONFIG_DEBUG_FS
-extern struct dentry *mips_debugfs_dir;
 static int __init debugfs_unaligned(void)
 {
        struct dentry *d;
index ed2a278722a9599e9edfaf501bda7f88b66690f7..975e99759bab9ec1ae6aa80a47fa2f97765efcc6 100644 (file)
 /*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Alex Smith <alex.smith@imgtec.com>
  *
- * Copyright (C) 2009, 2010 Cavium Networks, Inc.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
  */
 
-
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/init.h>
 #include <linux/binfmts.h>
 #include <linux/elf.h>
-#include <linux/vmalloc.h>
-#include <linux/unistd.h>
-#include <linux/random.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/irqchip/mips-gic.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/timekeeper_internal.h>
 
+#include <asm/abi.h>
 #include <asm/vdso.h>
-#include <asm/uasm.h>
-#include <asm/processor.h>
+
+/* Kernel-provided data used by the VDSO. */
+static union mips_vdso_data vdso_data __page_aligned_data;
 
 /*
- * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
+ * Mapping for the VDSO data/GIC pages. The real pages are mapped manually, as
+ * what we map and where within the area they are mapped is determined at
+ * runtime.
  */
-#define __NR_O32_sigreturn             4119
-#define __NR_O32_rt_sigreturn          4193
-#define __NR_N32_rt_sigreturn          6211
+static struct page *no_pages[] = { NULL };
+static struct vm_special_mapping vdso_vvar_mapping = {
+       .name = "[vvar]",
+       .pages = no_pages,
+};
 
-static struct page *vdso_page;
-
-static void __init install_trampoline(u32 *tramp, unsigned int sigreturn)
+static void __init init_vdso_image(struct mips_vdso_image *image)
 {
-       uasm_i_addiu(&tramp, 2, 0, sigreturn);  /* li v0, sigreturn */
-       uasm_i_syscall(&tramp, 0);
+       unsigned long num_pages, i;
+
+       BUG_ON(!PAGE_ALIGNED(image->data));
+       BUG_ON(!PAGE_ALIGNED(image->size));
+
+       num_pages = image->size / PAGE_SIZE;
+
+       for (i = 0; i < num_pages; i++) {
+               image->mapping.pages[i] =
+                       virt_to_page(image->data + (i * PAGE_SIZE));
+       }
 }
 
 static int __init init_vdso(void)
 {
-       struct mips_vdso *vdso;
-
-       vdso_page = alloc_page(GFP_KERNEL);
-       if (!vdso_page)
-               panic("Cannot allocate vdso");
-
-       vdso = vmap(&vdso_page, 1, 0, PAGE_KERNEL);
-       if (!vdso)
-               panic("Cannot map vdso");
-       clear_page(vdso);
-
-       install_trampoline(vdso->rt_signal_trampoline, __NR_rt_sigreturn);
-#ifdef CONFIG_32BIT
-       install_trampoline(vdso->signal_trampoline, __NR_sigreturn);
-#else
-       install_trampoline(vdso->n32_rt_signal_trampoline,
-                          __NR_N32_rt_sigreturn);
-       install_trampoline(vdso->o32_signal_trampoline, __NR_O32_sigreturn);
-       install_trampoline(vdso->o32_rt_signal_trampoline,
-                          __NR_O32_rt_sigreturn);
+       init_vdso_image(&vdso_image);
+
+#ifdef CONFIG_MIPS32_O32
+       init_vdso_image(&vdso_image_o32);
 #endif
 
-       vunmap(vdso);
+#ifdef CONFIG_MIPS32_N32
+       init_vdso_image(&vdso_image_n32);
+#endif
 
        return 0;
 }
 subsys_initcall(init_vdso);
 
-static unsigned long vdso_addr(unsigned long start)
+void update_vsyscall(struct timekeeper *tk)
 {
-       unsigned long offset = 0UL;
-
-       if (current->flags & PF_RANDOMIZE) {
-               offset = get_random_int();
-               offset <<= PAGE_SHIFT;
-               if (TASK_IS_32BIT_ADDR)
-                       offset &= 0xfffffful;
-               else
-                       offset &= 0xffffffful;
+       vdso_data_write_begin(&vdso_data);
+
+       vdso_data.xtime_sec = tk->xtime_sec;
+       vdso_data.xtime_nsec = tk->tkr_mono.xtime_nsec;
+       vdso_data.wall_to_mono_sec = tk->wall_to_monotonic.tv_sec;
+       vdso_data.wall_to_mono_nsec = tk->wall_to_monotonic.tv_nsec;
+       vdso_data.cs_shift = tk->tkr_mono.shift;
+
+       vdso_data.clock_mode = tk->tkr_mono.clock->archdata.vdso_clock_mode;
+       if (vdso_data.clock_mode != VDSO_CLOCK_NONE) {
+               vdso_data.cs_mult = tk->tkr_mono.mult;
+               vdso_data.cs_cycle_last = tk->tkr_mono.cycle_last;
+               vdso_data.cs_mask = tk->tkr_mono.mask;
        }
 
-       return STACK_TOP + offset;
+       vdso_data_write_end(&vdso_data);
+}
+
+void update_vsyscall_tz(void)
+{
+       if (vdso_data.clock_mode != VDSO_CLOCK_NONE) {
+               vdso_data.tz_minuteswest = sys_tz.tz_minuteswest;
+               vdso_data.tz_dsttime = sys_tz.tz_dsttime;
+       }
 }
 
 int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 {
-       int ret;
-       unsigned long addr;
+       struct mips_vdso_image *image = current->thread.abi->vdso;
        struct mm_struct *mm = current->mm;
+       unsigned long gic_size, vvar_size, size, base, data_addr, vdso_addr;
+       struct vm_area_struct *vma;
+       struct resource gic_res;
+       int ret;
 
        down_write(&mm->mmap_sem);
 
-       addr = vdso_addr(mm->start_stack);
+       /*
+        * Determine total area size. This includes the VDSO data itself, the
+        * data page, and the GIC user page if present. Always create a mapping
+        * for the GIC user area if the GIC is present regardless of whether it
+        * is the current clocksource, in case it comes into use later on. We
+        * only map a page even though the total area is 64K, as we only need
+        * the counter registers at the start.
+        */
+       gic_size = gic_present ? PAGE_SIZE : 0;
+       vvar_size = gic_size + PAGE_SIZE;
+       size = vvar_size + image->size;
+
+       base = get_unmapped_area(NULL, 0, size, 0, 0);
+       if (IS_ERR_VALUE(base)) {
+               ret = base;
+               goto out;
+       }
+
+       data_addr = base + gic_size;
+       vdso_addr = data_addr + PAGE_SIZE;
 
-       addr = get_unmapped_area(NULL, addr, PAGE_SIZE, 0, 0);
-       if (IS_ERR_VALUE(addr)) {
-               ret = addr;
-               goto up_fail;
+       vma = _install_special_mapping(mm, base, vvar_size,
+                                      VM_READ | VM_MAYREAD,
+                                      &vdso_vvar_mapping);
+       if (IS_ERR(vma)) {
+               ret = PTR_ERR(vma);
+               goto out;
        }
 
-       ret = install_special_mapping(mm, addr, PAGE_SIZE,
-                                     VM_READ|VM_EXEC|
-                                     VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
-                                     &vdso_page);
+       /* Map GIC user page. */
+       if (gic_size) {
+               ret = gic_get_usm_range(&gic_res);
+               if (ret)
+                       goto out;
+
+               ret = io_remap_pfn_range(vma, base,
+                                        gic_res.start >> PAGE_SHIFT,
+                                        gic_size,
+                                        pgprot_noncached(PAGE_READONLY));
+               if (ret)
+                       goto out;
+       }
 
+       /* Map data page. */
+       ret = remap_pfn_range(vma, data_addr,
+                             virt_to_phys(&vdso_data) >> PAGE_SHIFT,
+                             PAGE_SIZE, PAGE_READONLY);
        if (ret)
-               goto up_fail;
+               goto out;
+
+       /* Map VDSO image. */
+       vma = _install_special_mapping(mm, vdso_addr, image->size,
+                                      VM_READ | VM_EXEC |
+                                      VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
+                                      &image->mapping);
+       if (IS_ERR(vma)) {
+               ret = PTR_ERR(vma);
+               goto out;
+       }
 
-       mm->context.vdso = (void *)addr;
+       mm->context.vdso = (void *)vdso_addr;
+       ret = 0;
 
-up_fail:
+out:
        up_write(&mm->mmap_sem);
        return ret;
 }
-
-const char *arch_vma_name(struct vm_area_struct *vma)
-{
-       if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
-               return "[vdso]";
-       return NULL;
-}
index 07d32a4aea60e418892ffb27cbae05c11099a92f..0a93e83cd01479a4abc952e2e41a853dbf4159b9 100644 (file)
@@ -17,7 +17,9 @@ OUTPUT_ARCH(mips)
 ENTRY(kernel_entry)
 PHDRS {
        text PT_LOAD FLAGS(7);  /* RWX */
+#ifndef CONFIG_CAVIUM_OCTEON_SOC
        note PT_NOTE FLAGS(4);  /* R__ */
+#endif /* CAVIUM_OCTEON_SOC */
 }
 
 #ifdef CONFIG_32BIT
@@ -71,7 +73,12 @@ SECTIONS
                __stop___dbe_table = .;
        }
 
-       NOTES :text :note
+#ifdef CONFIG_CAVIUM_OCTEON_SOC
+#define NOTES_HEADER
+#else /* CONFIG_CAVIUM_OCTEON_SOC */
+#define NOTES_HEADER :note
+#endif /* CONFIG_CAVIUM_OCTEON_SOC */
+       NOTES :text NOTES_HEADER
        .dummy : { *(.dummy) } :text
 
        _sdata = .;                     /* Start of data section */
@@ -132,6 +139,11 @@ SECTIONS
        __appended_dtb = .;
        /* leave space for appended DTB */
        . += 0x100000;
+#elif defined(CONFIG_MIPS_ELF_APPENDED_DTB)
+       .appended_dtb : AT(ADDR(.appended_dtb) - LOAD_OFFSET) {
+               *(.appended_dtb)
+               KEEP(*(.appended_dtb))
+       }
 #endif
        /*
         * Align to 64K in attempt to eliminate holes before the
@@ -181,6 +193,7 @@ SECTIONS
        DISCARDS
        /DISCARD/ : {
                /* ABI crap starts here */
+               *(.MIPS.abiflags)
                *(.MIPS.options)
                *(.options)
                *(.pdr)
index c567240386a0f10818b0e06433f4b33b1bf5e6dc..7bab3a4e8f7d90b541b457f4f66138899db6db8a 100644 (file)
 #define PT_HOST_USERLOCAL   PT_EPC
 
 #define CP0_DDATA_LO        $28,3
-#define CP0_CONFIG3         $16,3
-#define CP0_CONFIG5         $16,5
-#define CP0_EBASE           $15,1
-
-#define CP0_INTCTL          $12,1
-#define CP0_SRSCTL          $12,2
-#define CP0_SRSMAP          $12,3
-#define CP0_HWRENA          $7,0
 
 /* Resume Flags */
 #define RESUME_FLAG_HOST        (1<<1)  /* Resume host? */
index 3fc2e6d70c7798f98c6b65b26e8a4f3e024584b2..a0706fd4ce0a0f0b3e9a531b31692fd6e1c0342f 100644 (file)
@@ -99,6 +99,23 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
 }
 EXPORT_SYMBOL(clk_set_rate);
 
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+       if (unlikely(!clk_good(clk)))
+               return 0;
+       if (clk->rates && *clk->rates) {
+               unsigned long *r = clk->rates;
+
+               while (*r && (*r != rate))
+                       r++;
+               if (!*r) {
+                       return clk->rate;
+               }
+       }
+       return rate;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
 int clk_enable(struct clk *clk)
 {
        if (unlikely(!clk_good(clk)))
index 77e4bdb1fe8cae2145b0d9875f1d8b69e3fe5d10..7376ce817eda6c6d23a20f1d1c853c24ccd5eb27 100644 (file)
 #define CLOCK_240M     240000000
 #define CLOCK_250M     250000000
 #define CLOCK_266M     266666666
+#define CLOCK_288M     288888888
 #define CLOCK_300M     300000000
 #define CLOCK_333M     333333333
+#define CLOCK_360M     360000000
 #define CLOCK_393M     393215332
 #define CLOCK_400M     400000000
+#define CLOCK_432M     432000000
 #define CLOCK_450M     450000000
 #define CLOCK_500M     500000000
 #define CLOCK_600M     600000000
+#define CLOCK_666M     666666666
+#define CLOCK_720M     720000000
 
 /* clock out speeds */
 #define CLOCK_32_768K  32768
@@ -80,4 +85,12 @@ extern unsigned long ltq_vr9_cpu_hz(void);
 extern unsigned long ltq_vr9_fpi_hz(void);
 extern unsigned long ltq_vr9_pp32_hz(void);
 
+extern unsigned long ltq_ar10_cpu_hz(void);
+extern unsigned long ltq_ar10_fpi_hz(void);
+extern unsigned long ltq_ar10_pp32_hz(void);
+
+extern unsigned long ltq_grx390_cpu_hz(void);
+extern unsigned long ltq_grx390_fpi_hz(void);
+extern unsigned long ltq_grx390_pp32_hz(void);
+
 #endif
index 2c218c3bbca57be3d029cdb3320b712092bccd46..2e7f60c9fc5dfc9a56f3d5db2aed46fcbffc6002 100644 (file)
@@ -369,8 +369,8 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
                if (of_address_to_resource(node, i, &res))
                        panic("Failed to get icu memory range");
 
-               if (request_mem_region(res.start, resource_size(&res),
-                                       res.name) < 0)
+               if (!request_mem_region(res.start, resource_size(&res),
+                                       res.name))
                        pr_err("Failed to request icu memory");
 
                ltq_icu_membase[i] = ioremap_nocache(res.start,
@@ -449,8 +449,8 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
                if (ret != exin_avail)
                        panic("failed to load external irq resources");
 
-               if (request_mem_region(res.start, resource_size(&res),
-                                                       res.name) < 0)
+               if (!request_mem_region(res.start, resource_size(&res),
+                                                       res.name))
                        pr_err("Failed to request eiu memory");
 
                ltq_eiu_membase = ioremap_nocache(res.start,
index 0db099ecc01648cca11a69cddcaab31c8c0a099e..297bcaa6b5d32b346c25fc9414a1e4690094c092 100644 (file)
@@ -77,8 +77,6 @@ void __init plat_mem_setup(void)
         * parsed resulting in our memory appearing
         */
        __dt_setup_arch(__dtb_start);
-
-       strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
 }
 
 void __init device_tree_init(void)
index 8750dc0a1bf678c5bd8500260816d6070b949aca..07f6d5b0b65ee10ccca231e0abab24d08462332e 100644 (file)
@@ -4,6 +4,7 @@
  *  by the Free Software Foundation.
  *
  *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ *  Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG
  */
 
 #include <linux/io.h>
@@ -25,9 +26,9 @@ static unsigned int ram_clocks[] = {
 /* legacy xway clock */
 #define CGU_SYS                        0x10
 
-/* vr9 clock */
-#define CGU_SYS_VR9            0x0c
-#define CGU_IF_CLK_VR9         0x24
+/* vr9, ar10/grx390 clock */
+#define CGU_SYS_XRX            0x0c
+#define CGU_IF_CLK_AR10                0x24
 
 unsigned long ltq_danube_fpi_hz(void)
 {
@@ -87,8 +88,9 @@ unsigned long ltq_ar9_fpi_hz(void)
        unsigned long sys = ltq_ar9_sys_hz();
 
        if (ltq_cgu_r32(CGU_SYS) & BIT(0))
-               return sys;
-       return sys >> 1;
+               return sys / 3;
+       else
+               return sys / 2;
 }
 
 unsigned long ltq_ar9_cpu_hz(void)
@@ -104,7 +106,7 @@ unsigned long ltq_vr9_cpu_hz(void)
        unsigned int cpu_sel;
        unsigned long clk;
 
-       cpu_sel = (ltq_cgu_r32(CGU_SYS_VR9) >> 4) & 0xf;
+       cpu_sel = (ltq_cgu_r32(CGU_SYS_XRX) >> 4) & 0xf;
 
        switch (cpu_sel) {
        case 0:
@@ -145,7 +147,7 @@ unsigned long ltq_vr9_fpi_hz(void)
        unsigned long clk;
 
        cpu_clk = ltq_vr9_cpu_hz();
-       ocp_sel = ltq_cgu_r32(CGU_SYS_VR9) & 0x3;
+       ocp_sel = ltq_cgu_r32(CGU_SYS_XRX) & 0x3;
 
        switch (ocp_sel) {
        case 0:
@@ -174,15 +176,18 @@ unsigned long ltq_vr9_fpi_hz(void)
 
 unsigned long ltq_vr9_pp32_hz(void)
 {
-       unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 16) & 3;
+       unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 16) & 0x7;
        unsigned long clk;
 
        switch (clksys) {
+       case 0:
+               clk = CLOCK_500M;
+               break;
        case 1:
-               clk = CLOCK_450M;
+               clk = CLOCK_432M;
                break;
        case 2:
-               clk = CLOCK_300M;
+               clk = CLOCK_288M;
                break;
        default:
                clk = CLOCK_500M;
@@ -191,3 +196,158 @@ unsigned long ltq_vr9_pp32_hz(void)
 
        return clk;
 }
+
+unsigned long ltq_ar10_cpu_hz(void)
+{
+       unsigned int clksys;
+       int cpu_fs = (ltq_cgu_r32(CGU_SYS_XRX) >> 8) & 0x1;
+       int freq_div = (ltq_cgu_r32(CGU_SYS_XRX) >> 4) & 0x7;
+
+       switch (cpu_fs) {
+       case 0:
+               clksys = CLOCK_500M;
+               break;
+       case 1:
+               clksys = CLOCK_600M;
+               break;
+       default:
+               clksys = CLOCK_500M;
+               break;
+       }
+
+       switch (freq_div) {
+       case 0:
+               return clksys;
+       case 1:
+               return clksys >> 1;
+       case 2:
+               return clksys >> 2;
+       default:
+               return clksys;
+       }
+}
+
+unsigned long ltq_ar10_fpi_hz(void)
+{
+       int freq_fpi = (ltq_cgu_r32(CGU_IF_CLK_AR10) >> 25) & 0xf;
+
+       switch (freq_fpi) {
+       case 1:
+               return CLOCK_300M;
+       case 5:
+               return CLOCK_250M;
+       case 2:
+               return CLOCK_150M;
+       case 6:
+               return CLOCK_125M;
+
+       default:
+               return CLOCK_125M;
+       }
+}
+
+unsigned long ltq_ar10_pp32_hz(void)
+{
+       unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 16) & 0x7;
+       unsigned long clk;
+
+       switch (clksys) {
+       case 1:
+               clk = CLOCK_250M;
+               break;
+       case 4:
+               clk = CLOCK_400M;
+               break;
+       default:
+               clk = CLOCK_250M;
+               break;
+       }
+
+       return clk;
+}
+
+unsigned long ltq_grx390_cpu_hz(void)
+{
+       unsigned int clksys;
+       int cpu_fs = ((ltq_cgu_r32(CGU_SYS_XRX) >> 9) & 0x3);
+       int freq_div = ((ltq_cgu_r32(CGU_SYS_XRX) >> 4) & 0x7);
+
+       switch (cpu_fs) {
+       case 0:
+               clksys = CLOCK_600M;
+               break;
+       case 1:
+               clksys = CLOCK_666M;
+               break;
+       case 2:
+               clksys = CLOCK_720M;
+               break;
+       default:
+               clksys = CLOCK_600M;
+               break;
+       }
+
+       switch (freq_div) {
+       case 0:
+               return clksys;
+       case 1:
+               return clksys >> 1;
+       case 2:
+               return clksys >> 2;
+       default:
+               return clksys;
+       }
+}
+
+unsigned long ltq_grx390_fpi_hz(void)
+{
+       /* fpi clock is derived from ddr_clk */
+       unsigned int clksys;
+       int cpu_fs = ((ltq_cgu_r32(CGU_SYS_XRX) >> 9) & 0x3);
+       int freq_div = ((ltq_cgu_r32(CGU_SYS_XRX)) & 0x7);
+       switch (cpu_fs) {
+       case 0:
+               clksys = CLOCK_600M;
+               break;
+       case 1:
+               clksys = CLOCK_666M;
+               break;
+       case 2:
+               clksys = CLOCK_720M;
+               break;
+       default:
+               clksys = CLOCK_600M;
+               break;
+       }
+
+       switch (freq_div) {
+       case 1:
+               return clksys >> 1;
+       case 2:
+               return clksys >> 2;
+       default:
+               return clksys >> 1;
+       }
+}
+
+unsigned long ltq_grx390_pp32_hz(void)
+{
+       unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 16) & 0x7;
+       unsigned long clk;
+
+       switch (clksys) {
+       case 1:
+               clk = CLOCK_250M;
+               break;
+       case 2:
+               clk = CLOCK_432M;
+               break;
+       case 4:
+               clk = CLOCK_400M;
+               break;
+       default:
+               clk = CLOCK_250M;
+               break;
+       }
+       return clk;
+}
index 248429ab2622bb7e404c204e08551ef57787ffaa..8f6e02f1e9650b99830a14bd160ddf12856a9ee1 100644 (file)
@@ -4,6 +4,7 @@
  *  by the Free Software Foundation.
  *
  *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ *  Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG
  */
 
 #include <linux/export.h>
 #define SOC_TWINPASS   "Twinpass"
 #define SOC_AMAZON_SE  "Amazon_SE"
 #define SOC_AR9                "AR9"
-#define SOC_GR9                "GR9"
-#define SOC_VR9                "VR9"
+#define SOC_GR9                "GRX200"
+#define SOC_VR9                "xRX200"
+#define SOC_VRX220     "xRX220"
+#define SOC_AR10       "xRX300"
+#define SOC_GRX390     "xRX330"
 
 #define COMP_DANUBE    "lantiq,danube"
 #define COMP_TWINPASS  "lantiq,twinpass"
@@ -28,6 +32,8 @@
 #define COMP_AR9       "lantiq,ar9"
 #define COMP_GR9       "lantiq,gr9"
 #define COMP_VR9       "lantiq,vr9"
+#define COMP_AR10      "lantiq,ar10"
+#define COMP_GRX390    "lantiq,grx390"
 
 #define PART_SHIFT     12
 #define PART_MASK      0x0FFFFFFF
@@ -101,6 +107,12 @@ void __init ltq_soc_detect(struct ltq_soc_info *i)
                i->compatible = COMP_VR9;
                break;
 
+       case SOC_ID_VRX220:
+               i->name = SOC_VRX220;
+               i->type = SOC_TYPE_VRX220;
+               i->compatible = COMP_VR9;
+               break;
+
        case SOC_ID_GRX282_2:
        case SOC_ID_GRX288_2:
                i->name = SOC_GR9;
@@ -108,6 +120,25 @@ void __init ltq_soc_detect(struct ltq_soc_info *i)
                i->compatible = COMP_GR9;
                break;
 
+       case SOC_ID_ARX362:
+       case SOC_ID_ARX368:
+       case SOC_ID_ARX382:
+       case SOC_ID_ARX388:
+       case SOC_ID_URX388:
+               i->name = SOC_AR10;
+               i->type = SOC_TYPE_AR10;
+               i->compatible = COMP_AR10;
+               break;
+
+       case SOC_ID_GRX383:
+       case SOC_ID_GRX369:
+       case SOC_ID_GRX387:
+       case SOC_ID_GRX389:
+               i->name = SOC_GRX390;
+               i->type = SOC_TYPE_GRX390;
+               i->compatible = COMP_GRX390;
+               break;
+
        default:
                unreachable();
                break;
index fe68f9ae47c1487afde62c2bddcf1d5a94ff758a..bc29bb349e94e227fc0b015544d588eddafe5a57 100644 (file)
@@ -4,6 +4,7 @@
  *  by the Free Software Foundation.
  *
  *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ *  Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG
  */
 
 #include <linux/init.h>
@@ -22,9 +23,6 @@
 
 #include "../prom.h"
 
-#define ltq_rcu_w32(x, y)      ltq_w32((x), ltq_rcu_membase + (y))
-#define ltq_rcu_r32(x)         ltq_r32(ltq_rcu_membase + (x))
-
 /* reset request register */
 #define RCU_RST_REQ            0x0010
 /* reset status register */
 /* vr9 gphy registers */
 #define RCU_GFS_ADD0_XRX200    0x0020
 #define RCU_GFS_ADD1_XRX200    0x0068
+/* xRX300 gphy registers */
+#define RCU_GFS_ADD0_XRX300    0x0020
+#define RCU_GFS_ADD1_XRX300    0x0058
+#define RCU_GFS_ADD2_XRX300    0x00AC
+/* xRX330 gphy registers */
+#define RCU_GFS_ADD0_XRX330    0x0020
+#define RCU_GFS_ADD1_XRX330    0x0058
+#define RCU_GFS_ADD2_XRX330    0x00AC
+#define RCU_GFS_ADD3_XRX330    0x0264
+
+/* xbar BE flag */
+#define RCU_AHB_ENDIAN          0x004C
+#define RCU_VR9_BE_AHB1S        0x00000008
 
 /* reboot bit */
 #define RCU_RD_GPHY0_XRX200    BIT(31)
 #define RCU_RD_SRST            BIT(30)
 #define RCU_RD_GPHY1_XRX200    BIT(29)
+/* xRX300 bits */
+#define RCU_RD_GPHY0_XRX300    BIT(31)
+#define RCU_RD_GPHY1_XRX300    BIT(29)
+#define RCU_RD_GPHY2_XRX300    BIT(28)
+/* xRX330 bits */
+#define RCU_RD_GPHY0_XRX330    BIT(31)
+#define RCU_RD_GPHY1_XRX330    BIT(29)
+#define RCU_RD_GPHY2_XRX330    BIT(28)
+#define RCU_RD_GPHY3_XRX330    BIT(10)
 
 /* reset cause */
 #define RCU_STAT_SHIFT         26
 #define RCU_BOOT_SEL(x)                ((x >> 18) & 0x7)
 #define RCU_BOOT_SEL_XRX200(x) (((x >> 17) & 0xf) | ((x >> 8) & 0x10))
 
+/* dwc2 USB configuration registers */
+#define RCU_USB1CFG            0x0018
+#define RCU_USB2CFG            0x0034
+
+/* USB DMA endianness bits */
+#define RCU_USBCFG_HDSEL_BIT   BIT(11)
+#define RCU_USBCFG_HOST_END_BIT        BIT(10)
+#define RCU_USBCFG_SLV_END_BIT BIT(9)
+
+/* USB reset bits */
+#define RCU_USBRESET           0x0010
+
+#define USBRESET_BIT           BIT(4)
+
+#define RCU_USBRESET2          0x0048
+
+#define USB1RESET_BIT          BIT(4)
+#define USB2RESET_BIT          BIT(5)
+
+#define RCU_CFG1A              0x0038
+#define RCU_CFG1B              0x003C
+
+/* USB PMU devices */
+#define PMU_AHBM               BIT(15)
+#define PMU_USB0               BIT(6)
+#define PMU_USB1               BIT(27)
+
+/* USB PHY PMU devices */
+#define PMU_USB0_P             BIT(0)
+#define PMU_USB1_P             BIT(26)
+
 /* remapped base addr of the reset control unit */
 static void __iomem *ltq_rcu_membase;
 static struct device_node *ltq_rcu_np;
+static DEFINE_SPINLOCK(ltq_rcu_lock);
+
+static void ltq_rcu_w32(uint32_t val, uint32_t reg_off)
+{
+       ltq_w32(val, ltq_rcu_membase + reg_off);
+}
+
+static uint32_t ltq_rcu_r32(uint32_t reg_off)
+{
+       return ltq_r32(ltq_rcu_membase + reg_off);
+}
+
+static void ltq_rcu_w32_mask(uint32_t clr, uint32_t set, uint32_t reg_off)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&ltq_rcu_lock, flags);
+       ltq_rcu_w32((ltq_rcu_r32(reg_off) & ~(clr)) | (set), reg_off);
+       spin_unlock_irqrestore(&ltq_rcu_lock, flags);
+}
 
 /* This function is used by the watchdog driver */
 int ltq_reset_cause(void)
@@ -67,15 +138,40 @@ unsigned char ltq_boot_select(void)
        return RCU_BOOT_SEL(val);
 }
 
-/* reset / boot a gphy */
-static struct ltq_xrx200_gphy_reset {
+struct ltq_gphy_reset {
        u32 rd;
        u32 addr;
-} xrx200_gphy[] = {
+};
+
+/* reset / boot a gphy */
+static struct ltq_gphy_reset xrx200_gphy[] = {
        {RCU_RD_GPHY0_XRX200, RCU_GFS_ADD0_XRX200},
        {RCU_RD_GPHY1_XRX200, RCU_GFS_ADD1_XRX200},
 };
 
+/* reset / boot a gphy */
+static struct ltq_gphy_reset xrx300_gphy[] = {
+       {RCU_RD_GPHY0_XRX300, RCU_GFS_ADD0_XRX300},
+       {RCU_RD_GPHY1_XRX300, RCU_GFS_ADD1_XRX300},
+       {RCU_RD_GPHY2_XRX300, RCU_GFS_ADD2_XRX300},
+};
+
+/* reset / boot a gphy */
+static struct ltq_gphy_reset xrx330_gphy[] = {
+       {RCU_RD_GPHY0_XRX330, RCU_GFS_ADD0_XRX330},
+       {RCU_RD_GPHY1_XRX330, RCU_GFS_ADD1_XRX330},
+       {RCU_RD_GPHY2_XRX330, RCU_GFS_ADD2_XRX330},
+       {RCU_RD_GPHY3_XRX330, RCU_GFS_ADD3_XRX330},
+};
+
+static void xrx200_gphy_boot_addr(struct ltq_gphy_reset *phy_regs,
+                                 dma_addr_t dev_addr)
+{
+       ltq_rcu_w32_mask(0, phy_regs->rd, RCU_RST_REQ);
+       ltq_rcu_w32(dev_addr, phy_regs->addr);
+       ltq_rcu_w32_mask(phy_regs->rd, 0,  RCU_RST_REQ);
+}
+
 /* reset and boot a gphy. these phys only exist on xrx200 SoC */
 int xrx200_gphy_boot(struct device *dev, unsigned int id, dma_addr_t dev_addr)
 {
@@ -86,23 +182,34 @@ int xrx200_gphy_boot(struct device *dev, unsigned int id, dma_addr_t dev_addr)
                return -EINVAL;
        }
 
-       clk = clk_get_sys("1f203000.rcu", "gphy");
-       if (IS_ERR(clk))
-               return PTR_ERR(clk);
-
-       clk_enable(clk);
-
-       if (id > 1) {
-               dev_err(dev, "%u is an invalid gphy id\n", id);
-               return -EINVAL;
+       if (of_machine_is_compatible("lantiq,vr9")) {
+               clk = clk_get_sys("1f203000.rcu", "gphy");
+               if (IS_ERR(clk))
+                       return PTR_ERR(clk);
+               clk_enable(clk);
        }
+
        dev_info(dev, "booting GPHY%u firmware at %X\n", id, dev_addr);
 
-       ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | xrx200_gphy[id].rd,
-                       RCU_RST_REQ);
-       ltq_rcu_w32(dev_addr, xrx200_gphy[id].addr);
-       ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~xrx200_gphy[id].rd,
-                       RCU_RST_REQ);
+       if (of_machine_is_compatible("lantiq,vr9")) {
+               if (id >= ARRAY_SIZE(xrx200_gphy)) {
+                       dev_err(dev, "%u is an invalid gphy id\n", id);
+                       return -EINVAL;
+               }
+               xrx200_gphy_boot_addr(&xrx200_gphy[id], dev_addr);
+       } else if (of_machine_is_compatible("lantiq,ar10")) {
+               if (id >= ARRAY_SIZE(xrx300_gphy)) {
+                       dev_err(dev, "%u is an invalid gphy id\n", id);
+                       return -EINVAL;
+               }
+               xrx200_gphy_boot_addr(&xrx300_gphy[id], dev_addr);
+       } else if (of_machine_is_compatible("lantiq,grx390")) {
+               if (id >= ARRAY_SIZE(xrx330_gphy)) {
+                       dev_err(dev, "%u is an invalid gphy id\n", id);
+                       return -EINVAL;
+               }
+               xrx200_gphy_boot_addr(&xrx330_gphy[id], dev_addr);
+       }
        return 0;
 }
 
@@ -200,6 +307,45 @@ static void ltq_machine_power_off(void)
        unreachable();
 }
 
+static void ltq_usb_init(void)
+{
+       /* Power for USB cores 1 & 2 */
+       ltq_pmu_enable(PMU_AHBM);
+       ltq_pmu_enable(PMU_USB0);
+       ltq_pmu_enable(PMU_USB1);
+
+       ltq_rcu_w32(ltq_rcu_r32(RCU_CFG1A) | BIT(0), RCU_CFG1A);
+       ltq_rcu_w32(ltq_rcu_r32(RCU_CFG1B) | BIT(0), RCU_CFG1B);
+
+       /* Enable USB PHY power for cores 1 & 2 */
+       ltq_pmu_enable(PMU_USB0_P);
+       ltq_pmu_enable(PMU_USB1_P);
+
+       /* Configure cores to host mode */
+       ltq_rcu_w32(ltq_rcu_r32(RCU_USB1CFG) & ~RCU_USBCFG_HDSEL_BIT,
+               RCU_USB1CFG);
+       ltq_rcu_w32(ltq_rcu_r32(RCU_USB2CFG) & ~RCU_USBCFG_HDSEL_BIT,
+               RCU_USB2CFG);
+
+       /* Select DMA endianness (Host-endian: big-endian) */
+       ltq_rcu_w32((ltq_rcu_r32(RCU_USB1CFG) & ~RCU_USBCFG_SLV_END_BIT)
+               | RCU_USBCFG_HOST_END_BIT, RCU_USB1CFG);
+       ltq_rcu_w32(ltq_rcu_r32((RCU_USB2CFG) & ~RCU_USBCFG_SLV_END_BIT)
+               | RCU_USBCFG_HOST_END_BIT, RCU_USB2CFG);
+
+       /* Hard reset USB state machines */
+       ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET) | USBRESET_BIT, RCU_USBRESET);
+       udelay(50 * 1000);
+       ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET) & ~USBRESET_BIT, RCU_USBRESET);
+
+       /* Soft reset USB state machines */
+       ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET2)
+               | USB1RESET_BIT | USB2RESET_BIT, RCU_USBRESET2);
+       udelay(50 * 1000);
+       ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET2)
+               & ~(USB1RESET_BIT | USB2RESET_BIT), RCU_USBRESET2);
+}
+
 static int __init mips_reboot_setup(void)
 {
        struct resource res;
@@ -216,13 +362,21 @@ static int __init mips_reboot_setup(void)
        if (of_address_to_resource(ltq_rcu_np, 0, &res))
                panic("Failed to get rcu memory range");
 
-       if (request_mem_region(res.start, resource_size(&res), res.name) < 0)
+       if (!request_mem_region(res.start, resource_size(&res), res.name))
                pr_err("Failed to request rcu memory");
 
        ltq_rcu_membase = ioremap_nocache(res.start, resource_size(&res));
        if (!ltq_rcu_membase)
                panic("Failed to remap core memory");
 
+       if (of_machine_is_compatible("lantiq,ar9") ||
+           of_machine_is_compatible("lantiq,vr9"))
+               ltq_usb_init();
+
+       if (of_machine_is_compatible("lantiq,vr9"))
+               ltq_rcu_w32(ltq_rcu_r32(RCU_AHB_ENDIAN) | RCU_VR9_BE_AHB1S,
+                           RCU_AHB_ENDIAN);
+
        _machine_restart = ltq_machine_restart;
        _machine_halt = ltq_machine_halt;
        pm_power_off = ltq_machine_power_off;
index 2b15491de49462e27e71df6758a49efbd4b29ef4..80554e8f603758f78352b8eb3a8fa4d20df9af7f 100644 (file)
@@ -4,11 +4,13 @@
  *  by the Free Software Foundation.
  *
  *  Copyright (C) 2011-2012 John Crispin <blogic@openwrt.org>
+ *  Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG
  */
 
 #include <linux/ioport.h>
 #include <linux/export.h>
 #include <linux/clkdev.h>
+#include <linux/spinlock.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
 #include <linux/of_address.h>
 #include "../clk.h"
 #include "../prom.h"
 
-/* clock control register */
+/* clock control register for legacy */
 #define CGU_IFCCR      0x0018
 #define CGU_IFCCR_VR9  0x0024
-/* system clock register */
+/* system clock register for legacy */
 #define CGU_SYS                0x0010
 /* pci control register */
 #define CGU_PCICR      0x0034
 #define CGU_PCICR_VR9  0x0038
 /* ephy configuration register */
 #define CGU_EPHY       0x10
+
+/* Legacy PMU register for ar9, ase, danube */
 /* power control register */
 #define PMU_PWDCR      0x1C
 /* power status register */
 /* power status register */
 #define PWDSR(x) ((x) ? (PMU_PWDSR1) : (PMU_PWDSR))
 
+
+/* PMU register for ar10 and grx390 */
+
+/* First register set */
+#define PMU_CLK_SR     0x20 /* status */
+#define PMU_CLK_CR_A   0x24 /* Enable */
+#define PMU_CLK_CR_B   0x28 /* Disable */
+/* Second register set */
+#define PMU_CLK_SR1    0x30 /* status */
+#define PMU_CLK_CR1_A  0x34 /* Enable */
+#define PMU_CLK_CR1_B  0x38 /* Disable */
+/* Third register set */
+#define PMU_ANA_SR     0x40 /* status */
+#define PMU_ANA_CR_A   0x44 /* Enable */
+#define PMU_ANA_CR_B   0x48 /* Disable */
+
+/* Status */
+static u32 pmu_clk_sr[] = {
+       PMU_CLK_SR,
+       PMU_CLK_SR1,
+       PMU_ANA_SR,
+};
+
+/* Enable */
+static u32 pmu_clk_cr_a[] = {
+       PMU_CLK_CR_A,
+       PMU_CLK_CR1_A,
+       PMU_ANA_CR_A,
+};
+
+/* Disable */
+static u32 pmu_clk_cr_b[] = {
+       PMU_CLK_CR_B,
+       PMU_CLK_CR1_B,
+       PMU_ANA_CR_B,
+};
+
+#define PWDCR_EN_XRX(x)                (pmu_clk_cr_a[(x)])
+#define PWDCR_DIS_XRX(x)       (pmu_clk_cr_b[(x)])
+#define PWDSR_XRX(x)           (pmu_clk_sr[(x)])
+
 /* clock gates that we can en/disable */
 #define PMU_USB0_P     BIT(0)
+#define PMU_ASE_SDIO   BIT(2) /* ASE special */
 #define PMU_PCI                BIT(4)
 #define PMU_DMA                BIT(5)
 #define PMU_USB0       BIT(6)
 #define PMU_ASC0       BIT(7)
 #define PMU_EPHY       BIT(7)  /* ase */
+#define PMU_USIF       BIT(7) /* from vr9 until grx390 */
 #define PMU_SPI                BIT(8)
 #define PMU_DFE                BIT(9)
 #define PMU_EBU                BIT(10)
 #define PMU_AHBS       BIT(13) /* vr9 */
 #define PMU_FPI                BIT(14)
 #define PMU_AHBM       BIT(15)
+#define PMU_SDIO       BIT(16) /* danube, ar9, vr9 */
 #define PMU_ASC1       BIT(17)
 #define PMU_PPE_QSB    BIT(18)
 #define PMU_PPE_SLL01  BIT(19)
+#define PMU_DEU                BIT(20)
 #define PMU_PPE_TC     BIT(21)
 #define PMU_PPE_EMA    BIT(22)
 #define PMU_PPE_DPLUM  BIT(23)
+#define PMU_PPE_DP     BIT(23)
 #define PMU_PPE_DPLUS  BIT(24)
 #define PMU_USB1_P     BIT(26)
 #define PMU_USB1       BIT(27)
 #define PMU_GPHY       BIT(30)
 #define PMU_PCIE_CLK   BIT(31)
 
-#define PMU1_PCIE_PHY  BIT(0)
+#define PMU1_PCIE_PHY  BIT(0)  /* vr9-specific,moved in ar10/grx390 */
 #define PMU1_PCIE_CTL  BIT(1)
 #define PMU1_PCIE_PDI  BIT(4)
 #define PMU1_PCIE_MSI  BIT(5)
+#define PMU1_CKE       BIT(6)
+#define PMU1_PCIE1_CTL BIT(17)
+#define PMU1_PCIE1_PDI BIT(20)
+#define PMU1_PCIE1_MSI BIT(21)
+#define PMU1_PCIE2_CTL BIT(25)
+#define PMU1_PCIE2_PDI BIT(26)
+#define PMU1_PCIE2_MSI BIT(27)
+
+#define PMU_ANALOG_USB0_P      BIT(0)
+#define PMU_ANALOG_USB1_P      BIT(1)
+#define PMU_ANALOG_PCIE0_P     BIT(8)
+#define PMU_ANALOG_PCIE1_P     BIT(9)
+#define PMU_ANALOG_PCIE2_P     BIT(10)
+#define PMU_ANALOG_DSL_AFE     BIT(16)
+#define PMU_ANALOG_DCDC_2V5    BIT(17)
+#define PMU_ANALOG_DCDC_1VX    BIT(18)
+#define PMU_ANALOG_DCDC_1V0    BIT(19)
 
 #define pmu_w32(x, y)  ltq_w32((x), pmu_membase + (y))
 #define pmu_r32(x)     ltq_r32(pmu_membase + (x))
 
+#define XBAR_ALWAYS_LAST       0x430
+#define XBAR_FPI_BURST_EN      BIT(1)
+#define XBAR_AHB_BURST_EN      BIT(2)
+
+#define xbar_w32(x, y) ltq_w32((x), ltq_xbar_membase + (y))
+#define xbar_r32(x)    ltq_r32(ltq_xbar_membase + (x))
+
 static void __iomem *pmu_membase;
+static void __iomem *ltq_xbar_membase;
 void __iomem *ltq_cgu_membase;
 void __iomem *ltq_ebu_membase;
 
 static u32 ifccr = CGU_IFCCR;
 static u32 pcicr = CGU_PCICR;
 
+static DEFINE_SPINLOCK(g_pmu_lock);
+
 /* legacy function kept alive to ease clkdev transition */
 void ltq_pmu_enable(unsigned int module)
 {
-       int err = 1000000;
+       int retry = 1000000;
 
+       spin_lock(&g_pmu_lock);
        pmu_w32(pmu_r32(PMU_PWDCR) & ~module, PMU_PWDCR);
-       do {} while (--err && (pmu_r32(PMU_PWDSR) & module));
+       do {} while (--retry && (pmu_r32(PMU_PWDSR) & module));
+       spin_unlock(&g_pmu_lock);
 
-       if (!err)
+       if (!retry)
                panic("activating PMU module failed!");
 }
 EXPORT_SYMBOL(ltq_pmu_enable);
@@ -101,7 +180,15 @@ EXPORT_SYMBOL(ltq_pmu_enable);
 /* legacy function kept alive to ease clkdev transition */
 void ltq_pmu_disable(unsigned int module)
 {
+       int retry = 1000000;
+
+       spin_lock(&g_pmu_lock);
        pmu_w32(pmu_r32(PMU_PWDCR) | module, PMU_PWDCR);
+       do {} while (--retry && (!(pmu_r32(PMU_PWDSR) & module)));
+       spin_unlock(&g_pmu_lock);
+
+       if (!retry)
+               pr_warn("deactivating PMU module failed!");
 }
 EXPORT_SYMBOL(ltq_pmu_disable);
 
@@ -123,9 +210,20 @@ static int pmu_enable(struct clk *clk)
 {
        int retry = 1000000;
 
-       pmu_w32(pmu_r32(PWDCR(clk->module)) & ~clk->bits,
-               PWDCR(clk->module));
-       do {} while (--retry && (pmu_r32(PWDSR(clk->module)) & clk->bits));
+       if (of_machine_is_compatible("lantiq,ar10")
+           || of_machine_is_compatible("lantiq,grx390")) {
+               pmu_w32(clk->bits, PWDCR_EN_XRX(clk->module));
+               do {} while (--retry &&
+                            (!(pmu_r32(PWDSR_XRX(clk->module)) & clk->bits)));
+
+       } else {
+               spin_lock(&g_pmu_lock);
+               pmu_w32(pmu_r32(PWDCR(clk->module)) & ~clk->bits,
+                               PWDCR(clk->module));
+               do {} while (--retry &&
+                            (pmu_r32(PWDSR(clk->module)) & clk->bits));
+               spin_unlock(&g_pmu_lock);
+       }
 
        if (!retry)
                panic("activating PMU module failed!");
@@ -136,8 +234,24 @@ static int pmu_enable(struct clk *clk)
 /* disable a clock gate */
 static void pmu_disable(struct clk *clk)
 {
-       pmu_w32(pmu_r32(PWDCR(clk->module)) | clk->bits,
-               PWDCR(clk->module));
+       int retry = 1000000;
+
+       if (of_machine_is_compatible("lantiq,ar10")
+           || of_machine_is_compatible("lantiq,grx390")) {
+               pmu_w32(clk->bits, PWDCR_DIS_XRX(clk->module));
+               do {} while (--retry &&
+                            (pmu_r32(PWDSR_XRX(clk->module)) & clk->bits));
+       } else {
+               spin_lock(&g_pmu_lock);
+               pmu_w32(pmu_r32(PWDCR(clk->module)) | clk->bits,
+                               PWDCR(clk->module));
+               do {} while (--retry &&
+                            (!(pmu_r32(PWDSR(clk->module)) & clk->bits)));
+               spin_unlock(&g_pmu_lock);
+       }
+
+       if (!retry)
+               pr_warn("deactivating PMU module failed!");
 }
 
 /* the pci enable helper */
@@ -179,6 +293,16 @@ static void pci_ext_disable(struct clk *clk)
        ltq_cgu_w32((1 << 31) | (1 << 30), pcicr);
 }
 
+static void xbar_fpi_burst_disable(void)
+{
+       u32 reg;
+
+       /* bit 1 as 1 --burst; bit 1 as 0 -- single */
+       reg = xbar_r32(XBAR_ALWAYS_LAST);
+       reg &= ~XBAR_FPI_BURST_EN;
+       xbar_w32(reg, XBAR_ALWAYS_LAST);
+}
+
 /* enable a clockout source */
 static int clkout_enable(struct clk *clk)
 {
@@ -202,8 +326,8 @@ static int clkout_enable(struct clk *clk)
 }
 
 /* manage the clock gates via PMU */
-static void clkdev_add_pmu(const char *dev, const char *con,
-                                       unsigned int module, unsigned int bits)
+static void clkdev_add_pmu(const char *dev, const char *con, bool deactivate,
+                          unsigned int module, unsigned int bits)
 {
        struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
 
@@ -214,6 +338,13 @@ static void clkdev_add_pmu(const char *dev, const char *con,
        clk->disable = pmu_disable;
        clk->module = module;
        clk->bits = bits;
+       if (deactivate) {
+               /*
+                * Disable it during the initialization. Module should enable
+                * when used
+                */
+               pmu_disable(clk);
+       }
        clkdev_add(&clk->cl);
 }
 
@@ -312,12 +443,12 @@ void __init ltq_soc_init(void)
                        of_address_to_resource(np_ebu, 0, &res_ebu))
                panic("Failed to get core resources");
 
-       if ((request_mem_region(res_pmu.start, resource_size(&res_pmu),
-                               res_pmu.name) < 0) ||
-               (request_mem_region(res_cgu.start, resource_size(&res_cgu),
-                               res_cgu.name) < 0) ||
-               (request_mem_region(res_ebu.start, resource_size(&res_ebu),
-                               res_ebu.name) < 0))
+       if (!request_mem_region(res_pmu.start, resource_size(&res_pmu),
+                               res_pmu.name) ||
+               !request_mem_region(res_cgu.start, resource_size(&res_cgu),
+                               res_cgu.name) ||
+               !request_mem_region(res_ebu.start, resource_size(&res_ebu),
+                               res_ebu.name))
                pr_err("Failed to request core resources");
 
        pmu_membase = ioremap_nocache(res_pmu.start, resource_size(&res_pmu));
@@ -328,17 +459,37 @@ void __init ltq_soc_init(void)
        if (!pmu_membase || !ltq_cgu_membase || !ltq_ebu_membase)
                panic("Failed to remap core resources");
 
+       if (of_machine_is_compatible("lantiq,vr9")) {
+               struct resource res_xbar;
+               struct device_node *np_xbar =
+                               of_find_compatible_node(NULL, NULL,
+                                                       "lantiq,xbar-xway");
+
+               if (!np_xbar)
+                       panic("Failed to load xbar nodes from devicetree");
+               if (of_address_to_resource(np_pmu, 0, &res_xbar))
+                       panic("Failed to get xbar resources");
+               if (request_mem_region(res_xbar.start, resource_size(&res_xbar),
+                       res_xbar.name) < 0)
+                       panic("Failed to get xbar resources");
+
+               ltq_xbar_membase = ioremap_nocache(res_xbar.start,
+                                                  resource_size(&res_xbar));
+               if (!ltq_xbar_membase)
+                       panic("Failed to remap xbar resources");
+       }
+
        /* make sure to unprotect the memory region where flash is located */
        ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_BUSCON0) & ~EBU_WRDIS, LTQ_EBU_BUSCON0);
 
        /* add our generic xway clocks */
-       clkdev_add_pmu("10000000.fpi", NULL, 0, PMU_FPI);
-       clkdev_add_pmu("1e100400.serial", NULL, 0, PMU_ASC0);
-       clkdev_add_pmu("1e100a00.gptu", NULL, 0, PMU_GPT);
-       clkdev_add_pmu("1e100bb0.stp", NULL, 0, PMU_STP);
-       clkdev_add_pmu("1e104100.dma", NULL, 0, PMU_DMA);
-       clkdev_add_pmu("1e100800.spi", NULL, 0, PMU_SPI);
-       clkdev_add_pmu("1e105300.ebu", NULL, 0, PMU_EBU);
+       clkdev_add_pmu("10000000.fpi", NULL, 0, 0, PMU_FPI);
+       clkdev_add_pmu("1e100400.serial", NULL, 0, 0, PMU_ASC0);
+       clkdev_add_pmu("1e100a00.gptu", NULL, 1, 0, PMU_GPT);
+       clkdev_add_pmu("1e100bb0.stp", NULL, 1, 0, PMU_STP);
+       clkdev_add_pmu("1e104100.dma", NULL, 1, 0, PMU_DMA);
+       clkdev_add_pmu("1e100800.spi", NULL, 1, 0, PMU_SPI);
+       clkdev_add_pmu("1e105300.ebu", NULL, 0, 0, PMU_EBU);
        clkdev_add_clkout();
 
        /* add the soc dependent clocks */
@@ -346,14 +497,30 @@ void __init ltq_soc_init(void)
                ifccr = CGU_IFCCR_VR9;
                pcicr = CGU_PCICR_VR9;
        } else {
-               clkdev_add_pmu("1e180000.etop", NULL, 0, PMU_PPE);
+               clkdev_add_pmu("1e180000.etop", NULL, 1, 0, PMU_PPE);
        }
 
        if (!of_machine_is_compatible("lantiq,ase")) {
-               clkdev_add_pmu("1e100c00.serial", NULL, 0, PMU_ASC1);
+               clkdev_add_pmu("1e100c00.serial", NULL, 0, 0, PMU_ASC1);
                clkdev_add_pci();
        }
 
+       if (of_machine_is_compatible("lantiq,grx390") ||
+           of_machine_is_compatible("lantiq,ar10")) {
+               clkdev_add_pmu("1e101000.usb", "phy", 1, 2, PMU_ANALOG_USB0_P);
+               clkdev_add_pmu("1e106000.usb", "phy", 1, 2, PMU_ANALOG_USB1_P);
+               /* rc 0 */
+               clkdev_add_pmu("1d900000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE0_P);
+               clkdev_add_pmu("1d900000.pcie", "msi", 1, 1, PMU1_PCIE_MSI);
+               clkdev_add_pmu("1d900000.pcie", "pdi", 1, 1, PMU1_PCIE_PDI);
+               clkdev_add_pmu("1d900000.pcie", "ctl", 1, 1, PMU1_PCIE_CTL);
+               /* rc 1 */
+               clkdev_add_pmu("19000000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE1_P);
+               clkdev_add_pmu("19000000.pcie", "msi", 1, 1, PMU1_PCIE1_MSI);
+               clkdev_add_pmu("19000000.pcie", "pdi", 1, 1, PMU1_PCIE1_PDI);
+               clkdev_add_pmu("19000000.pcie", "ctl", 1, 1, PMU1_PCIE1_CTL);
+       }
+
        if (of_machine_is_compatible("lantiq,ase")) {
                if (ltq_cgu_r32(CGU_SYS) & (1 << 5))
                        clkdev_add_static(CLOCK_266M, CLOCK_133M,
@@ -361,28 +528,84 @@ void __init ltq_soc_init(void)
                else
                        clkdev_add_static(CLOCK_133M, CLOCK_133M,
                                                CLOCK_133M, CLOCK_133M);
-               clkdev_add_cgu("1e180000.etop", "ephycgu", CGU_EPHY),
-               clkdev_add_pmu("1e180000.etop", "ephy", 0, PMU_EPHY);
+               clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0);
+               clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P);
+               clkdev_add_pmu("1e180000.etop", "ppe", 1, 0, PMU_PPE);
+               clkdev_add_cgu("1e180000.etop", "ephycgu", CGU_EPHY);
+               clkdev_add_pmu("1e180000.etop", "ephy", 1, 0, PMU_EPHY);
+               clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_ASE_SDIO);
+               clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
+       } else if (of_machine_is_compatible("lantiq,grx390")) {
+               clkdev_add_static(ltq_grx390_cpu_hz(), ltq_grx390_fpi_hz(),
+                                 ltq_grx390_fpi_hz(), ltq_grx390_pp32_hz());
+               clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0);
+               clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1);
+               /* rc 2 */
+               clkdev_add_pmu("1a800000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE2_P);
+               clkdev_add_pmu("1a800000.pcie", "msi", 1, 1, PMU1_PCIE2_MSI);
+               clkdev_add_pmu("1a800000.pcie", "pdi", 1, 1, PMU1_PCIE2_PDI);
+               clkdev_add_pmu("1a800000.pcie", "ctl", 1, 1, PMU1_PCIE2_CTL);
+               clkdev_add_pmu("1e108000.eth", NULL, 1, 0, PMU_SWITCH | PMU_PPE_DP);
+               clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF);
+               clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
+       } else if (of_machine_is_compatible("lantiq,ar10")) {
+               clkdev_add_static(ltq_ar10_cpu_hz(), ltq_ar10_fpi_hz(),
+                                 ltq_ar10_fpi_hz(), ltq_ar10_pp32_hz());
+               clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0);
+               clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1);
+               clkdev_add_pmu("1e108000.eth", NULL, 1, 0, PMU_SWITCH |
+                              PMU_PPE_DP | PMU_PPE_TC);
+               clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF);
+               clkdev_add_pmu("1f203000.rcu", "gphy", 1, 0, PMU_GPHY);
+               clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
+               clkdev_add_pmu("1e116000.mei", "afe", 1, 2, PMU_ANALOG_DSL_AFE);
+               clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
        } else if (of_machine_is_compatible("lantiq,vr9")) {
                clkdev_add_static(ltq_vr9_cpu_hz(), ltq_vr9_fpi_hz(),
                                ltq_vr9_fpi_hz(), ltq_vr9_pp32_hz());
-               clkdev_add_pmu("1d900000.pcie", "phy", 1, PMU1_PCIE_PHY);
-               clkdev_add_pmu("1d900000.pcie", "bus", 0, PMU_PCIE_CLK);
-               clkdev_add_pmu("1d900000.pcie", "msi", 1, PMU1_PCIE_MSI);
-               clkdev_add_pmu("1d900000.pcie", "pdi", 1, PMU1_PCIE_PDI);
-               clkdev_add_pmu("1d900000.pcie", "ctl", 1, PMU1_PCIE_CTL);
-               clkdev_add_pmu("1d900000.pcie", "ahb", 0, PMU_AHBM | PMU_AHBS);
-               clkdev_add_pmu("1e108000.eth", NULL, 0,
+               clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P);
+               clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0 | PMU_AHBM);
+               clkdev_add_pmu("1e106000.usb", "phy", 1, 0, PMU_USB1_P);
+               clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1 | PMU_AHBM);
+               clkdev_add_pmu("1d900000.pcie", "phy", 1, 1, PMU1_PCIE_PHY);
+               clkdev_add_pmu("1d900000.pcie", "bus", 1, 0, PMU_PCIE_CLK);
+               clkdev_add_pmu("1d900000.pcie", "msi", 1, 1, PMU1_PCIE_MSI);
+               clkdev_add_pmu("1d900000.pcie", "pdi", 1, 1, PMU1_PCIE_PDI);
+               clkdev_add_pmu("1d900000.pcie", "ctl", 1, 1, PMU1_PCIE_CTL);
+               clkdev_add_pmu(NULL, "ahb", 1, 0, PMU_AHBM | PMU_AHBS);
+
+               clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF);
+               clkdev_add_pmu("1e108000.eth", NULL, 1, 0,
                                PMU_SWITCH | PMU_PPE_DPLUS | PMU_PPE_DPLUM |
                                PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 |
                                PMU_PPE_QSB | PMU_PPE_TOP);
-               clkdev_add_pmu("1f203000.rcu", "gphy", 0, PMU_GPHY);
+               clkdev_add_pmu("1f203000.rcu", "gphy", 1, 0, PMU_GPHY);
+               clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO);
+               clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
+               clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
        } else if (of_machine_is_compatible("lantiq,ar9")) {
                clkdev_add_static(ltq_ar9_cpu_hz(), ltq_ar9_fpi_hz(),
                                ltq_ar9_fpi_hz(), CLOCK_250M);
-               clkdev_add_pmu("1e180000.etop", "switch", 0, PMU_SWITCH);
+               clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0);
+               clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P);
+               clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1);
+               clkdev_add_pmu("1e106000.usb", "phy", 1, 0, PMU_USB1_P);
+               clkdev_add_pmu("1e180000.etop", "switch", 1, 0, PMU_SWITCH);
+               clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO);
+               clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
+               clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
+               clkdev_add_pmu("1e100400.serial", NULL, 1, 0, PMU_ASC0);
        } else {
                clkdev_add_static(ltq_danube_cpu_hz(), ltq_danube_fpi_hz(),
                                ltq_danube_fpi_hz(), ltq_danube_pp32_hz());
+               clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0);
+               clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P);
+               clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO);
+               clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
+               clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
+               clkdev_add_pmu("1e100400.serial", NULL, 1, 0, PMU_ASC0);
        }
+
+       if (of_machine_is_compatible("lantiq,vr9"))
+               xbar_fpi_burst_disable();
 }
index 1e9e900cd3c382a4a8c3bce2ab7ca2987a1acfcd..0344e575f522982dc4725479d66544d79837b0b4 100644 (file)
@@ -15,4 +15,4 @@ obj-$(CONFIG_CPU_R3000)               += r3k_dump_tlb.o
 obj-$(CONFIG_CPU_TX39XX)       += r3k_dump_tlb.o
 
 # libgcc-style stuff needed in the kernel
-obj-y += ashldi3.o ashrdi3.o cmpdi2.o lshrdi3.o ucmpdi2.o
+obj-y += ashldi3.o ashrdi3.o bswapsi.o bswapdi.o cmpdi2.o lshrdi3.o ucmpdi2.o
diff --git a/arch/mips/lib/bswapdi.c b/arch/mips/lib/bswapdi.c
new file mode 100644 (file)
index 0000000..77e5f9c
--- /dev/null
@@ -0,0 +1,15 @@
+#include <linux/module.h>
+
+unsigned long long __bswapdi2(unsigned long long u)
+{
+       return (((u) & 0xff00000000000000ull) >> 56) |
+              (((u) & 0x00ff000000000000ull) >> 40) |
+              (((u) & 0x0000ff0000000000ull) >> 24) |
+              (((u) & 0x000000ff00000000ull) >>  8) |
+              (((u) & 0x00000000ff000000ull) <<  8) |
+              (((u) & 0x0000000000ff0000ull) << 24) |
+              (((u) & 0x000000000000ff00ull) << 40) |
+              (((u) & 0x00000000000000ffull) << 56);
+}
+
+EXPORT_SYMBOL(__bswapdi2);
diff --git a/arch/mips/lib/bswapsi.c b/arch/mips/lib/bswapsi.c
new file mode 100644 (file)
index 0000000..2b302ff
--- /dev/null
@@ -0,0 +1,11 @@
+#include <linux/module.h>
+
+unsigned int __bswapsi2(unsigned int u)
+{
+       return (((u) & 0xff000000) >> 24) |
+              (((u) & 0x00ff0000) >>  8) |
+              (((u) & 0x0000ff00) <<  8) |
+              (((u) & 0x000000ff) << 24);
+}
+
+EXPORT_SYMBOL(__bswapsi2);
index 497912b38d8ebd82458f225a8b1fc2a5cbaf0d13..8e6e292675b24525f3b50e14e4214fe251914ae1 100644 (file)
@@ -120,11 +120,6 @@ config RS780_HPET
 
          If unsure, say Yes.
 
-config LOONGSON_SUSPEND
-       bool
-       default y
-       depends on CPU_SUPPORTS_CPUFREQ && SUSPEND
-
 config LOONGSON_UART_BASE
        bool
        default y
index f2e8153e44f536213e196002f005bb86da9ef72f..074d9cb15cd20dcb5551a65d99464bc0d0588992 100644 (file)
@@ -23,7 +23,7 @@ obj-$(CONFIG_CS5536) += cs5536/
 # Suspend Support
 #
 
-obj-$(CONFIG_LOONGSON_SUSPEND) += pm.o
+obj-$(CONFIG_SUSPEND) += pm.o
 
 #
 # Big Memory (SWIOTLB) Support
index 4f9eaa328a1601a3ff63beaf14b86b65f960a469..08b8abcbfef537f11bd7a1c2a747665070bc9bf7 100644 (file)
@@ -8,4 +8,4 @@ obj-y += clock.o machtype.o irq.o reset.o ec_kb3310b.o
 # Suspend Support
 #
 
-obj-$(CONFIG_LOONGSON_SUSPEND) += pm.o
+obj-$(CONFIG_SUSPEND) += pm.o
index 506a67a98cdf5cadf12420c17bb89ef4d4af41d9..be650ed7db596bb8b586c7b65bfdddce56f65b3b 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/init.h>
 #include <linux/percpu.h>
 #include <linux/types.h>
+#include <asm/debug.h>
 #include <asm/fpu_emulator.h>
 #include <asm/local.h>
 
@@ -27,7 +28,6 @@ static int fpuemu_stat_get(void *data, u64 *val)
 }
 DEFINE_SIMPLE_ATTRIBUTE(fops_fpuemu_stat, fpuemu_stat_get, NULL, "%llu\n");
 
-extern struct dentry *mips_debugfs_dir;
 static int __init debugfs_fpuemu(void)
 {
        struct dentry *d, *dir;
index 67ede4ef9b8d62c2e0db236fc5890914cebe4ee0..b4c64bd3f723903296c73d75dba3c3e29b861591 100644 (file)
@@ -28,3 +28,4 @@ obj-$(CONFIG_IP22_CPU_SCACHE) += sc-ip22.o
 obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o
 obj-$(CONFIG_RM7000_CPU_SCACHE) += sc-rm7k.o
 obj-$(CONFIG_MIPS_CPU_SCACHE)  += sc-mips.o
+obj-$(CONFIG_SCACHE_DEBUGFS)   += sc-debugfs.o
diff --git a/arch/mips/mm/sc-debugfs.c b/arch/mips/mm/sc-debugfs.c
new file mode 100644 (file)
index 0000000..5eefe32
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <asm/bcache.h>
+#include <asm/debug.h>
+#include <asm/uaccess.h>
+#include <linux/debugfs.h>
+#include <linux/init.h>
+
+static ssize_t sc_prefetch_read(struct file *file, char __user *user_buf,
+                               size_t count, loff_t *ppos)
+{
+       bool enabled = bc_prefetch_is_enabled();
+       char buf[3];
+
+       buf[0] = enabled ? 'Y' : 'N';
+       buf[1] = '\n';
+       buf[2] = 0;
+
+       return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
+}
+
+static ssize_t sc_prefetch_write(struct file *file,
+                                const char __user *user_buf,
+                                size_t count, loff_t *ppos)
+{
+       char buf[32];
+       ssize_t buf_size;
+       bool enabled;
+       int err;
+
+       buf_size = min(count, sizeof(buf) - 1);
+       if (copy_from_user(buf, user_buf, buf_size))
+               return -EFAULT;
+
+       buf[buf_size] = '\0';
+       err = strtobool(buf, &enabled);
+       if (err)
+               return err;
+
+       if (enabled)
+               bc_prefetch_enable();
+       else
+               bc_prefetch_disable();
+
+       return count;
+}
+
+static const struct file_operations sc_prefetch_fops = {
+       .open = simple_open,
+       .llseek = default_llseek,
+       .read = sc_prefetch_read,
+       .write = sc_prefetch_write,
+};
+
+static int __init sc_debugfs_init(void)
+{
+       struct dentry *dir, *file;
+
+       if (!mips_debugfs_dir)
+               return -ENODEV;
+
+       dir = debugfs_create_dir("l2cache", mips_debugfs_dir);
+       if (IS_ERR(dir))
+               return PTR_ERR(dir);
+
+       file = debugfs_create_file("prefetch", S_IRUGO | S_IWUSR, dir,
+                                  NULL, &sc_prefetch_fops);
+       if (IS_ERR(file))
+               return PTR_ERR(file);
+
+       return 0;
+}
+late_initcall(sc_debugfs_init);
index 53ea8391f9bbf9c2ddf81a114e59f52d05ad7abf..3bd0597d9c3da3a56ea6ba083ca05c67bd71c5e7 100644 (file)
@@ -51,11 +51,69 @@ static void mips_sc_disable(void)
        /* L2 cache is permanently enabled */
 }
 
+static void mips_sc_prefetch_enable(void)
+{
+       unsigned long pftctl;
+
+       if (mips_cm_revision() < CM_REV_CM2_5)
+               return;
+
+       /*
+        * If there is one or more L2 prefetch unit present then enable
+        * prefetching for both code & data, for all ports.
+        */
+       pftctl = read_gcr_l2_pft_control();
+       if (pftctl & CM_GCR_L2_PFT_CONTROL_NPFT_MSK) {
+               pftctl &= ~CM_GCR_L2_PFT_CONTROL_PAGEMASK_MSK;
+               pftctl |= PAGE_MASK & CM_GCR_L2_PFT_CONTROL_PAGEMASK_MSK;
+               pftctl |= CM_GCR_L2_PFT_CONTROL_PFTEN_MSK;
+               write_gcr_l2_pft_control(pftctl);
+
+               pftctl = read_gcr_l2_pft_control_b();
+               pftctl |= CM_GCR_L2_PFT_CONTROL_B_PORTID_MSK;
+               pftctl |= CM_GCR_L2_PFT_CONTROL_B_CEN_MSK;
+               write_gcr_l2_pft_control_b(pftctl);
+       }
+}
+
+static void mips_sc_prefetch_disable(void)
+{
+       unsigned long pftctl;
+
+       if (mips_cm_revision() < CM_REV_CM2_5)
+               return;
+
+       pftctl = read_gcr_l2_pft_control();
+       pftctl &= ~CM_GCR_L2_PFT_CONTROL_PFTEN_MSK;
+       write_gcr_l2_pft_control(pftctl);
+
+       pftctl = read_gcr_l2_pft_control_b();
+       pftctl &= ~CM_GCR_L2_PFT_CONTROL_B_PORTID_MSK;
+       pftctl &= ~CM_GCR_L2_PFT_CONTROL_B_CEN_MSK;
+       write_gcr_l2_pft_control_b(pftctl);
+}
+
+static bool mips_sc_prefetch_is_enabled(void)
+{
+       unsigned long pftctl;
+
+       if (mips_cm_revision() < CM_REV_CM2_5)
+               return false;
+
+       pftctl = read_gcr_l2_pft_control();
+       if (!(pftctl & CM_GCR_L2_PFT_CONTROL_NPFT_MSK))
+               return false;
+       return !!(pftctl & CM_GCR_L2_PFT_CONTROL_PFTEN_MSK);
+}
+
 static struct bcache_ops mips_sc_ops = {
        .bc_enable = mips_sc_enable,
        .bc_disable = mips_sc_disable,
        .bc_wback_inv = mips_sc_wback_inv,
-       .bc_inv = mips_sc_inv
+       .bc_inv = mips_sc_inv,
+       .bc_prefetch_enable = mips_sc_prefetch_enable,
+       .bc_prefetch_disable = mips_sc_prefetch_disable,
+       .bc_prefetch_is_enabled = mips_sc_prefetch_is_enabled,
 };
 
 /*
@@ -162,13 +220,13 @@ static inline int __init mips_sc_probe(void)
                return 0;
 
        tmp = (config2 >> 8) & 0x0f;
-       if (0 <= tmp && tmp <= 7)
+       if (tmp <= 7)
                c->scache.sets = 64 << tmp;
        else
                return 0;
 
        tmp = (config2 >> 0) & 0x0f;
-       if (0 <= tmp && tmp <= 7)
+       if (tmp <= 7)
                c->scache.ways = tmp + 1;
        else
                return 0;
@@ -186,6 +244,7 @@ int mips_sc_init(void)
        int found = mips_sc_probe();
        if (found) {
                mips_sc_enable();
+               mips_sc_prefetch_enable();
                bcops = &mips_sc_ops;
        }
        return found;
index 323d1d302f2bd898372c5143c1b8c7fb2714a1ad..32e0be27673fefbeca6839929e61a581c8980902 100644 (file)
@@ -311,6 +311,7 @@ static struct uasm_label labels[128];
 static struct uasm_reloc relocs[128];
 
 static int check_for_high_segbits;
+static bool fill_includes_sw_bits;
 
 static unsigned int kscratch_used_mask;
 
@@ -630,8 +631,14 @@ static void build_tlb_write_entry(u32 **p, struct uasm_label **l,
 static __maybe_unused void build_convert_pte_to_entrylo(u32 **p,
                                                        unsigned int reg)
 {
-       if (cpu_has_rixi) {
-               UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL));
+       if (cpu_has_rixi && _PAGE_NO_EXEC) {
+               if (fill_includes_sw_bits) {
+                       UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL));
+               } else {
+                       UASM_i_SRL(p, reg, reg, ilog2(_PAGE_NO_EXEC));
+                       UASM_i_ROTR(p, reg, reg,
+                                   ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
+               }
        } else {
 #ifdef CONFIG_PHYS_ADDR_T_64BIT
                uasm_i_dsrl_safe(p, reg, reg, ilog2(_PAGE_GLOBAL));
@@ -1005,21 +1012,7 @@ static void build_update_entries(u32 **p, unsigned int tmp, unsigned int ptep)
         * 64bit address support (36bit on a 32bit CPU) in a 32bit
         * Kernel is a special case. Only a few CPUs use it.
         */
-#ifdef CONFIG_PHYS_ADDR_T_64BIT
-       if (cpu_has_64bits) {
-               uasm_i_ld(p, tmp, 0, ptep); /* get even pte */
-               uasm_i_ld(p, ptep, sizeof(pte_t), ptep); /* get odd pte */
-               if (cpu_has_rixi) {
-                       UASM_i_ROTR(p, tmp, tmp, ilog2(_PAGE_GLOBAL));
-                       UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */
-                       UASM_i_ROTR(p, ptep, ptep, ilog2(_PAGE_GLOBAL));
-               } else {
-                       uasm_i_dsrl_safe(p, tmp, tmp, ilog2(_PAGE_GLOBAL)); /* convert to entrylo0 */
-                       UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */
-                       uasm_i_dsrl_safe(p, ptep, ptep, ilog2(_PAGE_GLOBAL)); /* convert to entrylo1 */
-               }
-               UASM_i_MTC0(p, ptep, C0_ENTRYLO1); /* load it */
-       } else {
+       if (config_enabled(CONFIG_PHYS_ADDR_T_64BIT) && !cpu_has_64bits) {
                int pte_off_even = sizeof(pte_t) / 2;
                int pte_off_odd = pte_off_even + sizeof(pte_t);
 #ifdef CONFIG_XPA
@@ -1043,31 +1036,23 @@ static void build_update_entries(u32 **p, unsigned int tmp, unsigned int ptep)
                uasm_i_mthc0(p, tmp, C0_ENTRYLO0);
                uasm_i_mthc0(p, ptep, C0_ENTRYLO1);
 #endif
+               return;
        }
-#else
+
        UASM_i_LW(p, tmp, 0, ptep); /* get even pte */
        UASM_i_LW(p, ptep, sizeof(pte_t), ptep); /* get odd pte */
        if (r45k_bvahwbug())
                build_tlb_probe_entry(p);
-       if (cpu_has_rixi) {
-               UASM_i_ROTR(p, tmp, tmp, ilog2(_PAGE_GLOBAL));
-               if (r4k_250MHZhwbug())
-                       UASM_i_MTC0(p, 0, C0_ENTRYLO0);
-               UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */
-               UASM_i_ROTR(p, ptep, ptep, ilog2(_PAGE_GLOBAL));
-       } else {
-               UASM_i_SRL(p, tmp, tmp, ilog2(_PAGE_GLOBAL)); /* convert to entrylo0 */
-               if (r4k_250MHZhwbug())
-                       UASM_i_MTC0(p, 0, C0_ENTRYLO0);
-               UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */
-               UASM_i_SRL(p, ptep, ptep, ilog2(_PAGE_GLOBAL)); /* convert to entrylo1 */
-               if (r45k_bvahwbug())
-                       uasm_i_mfc0(p, tmp, C0_INDEX);
-       }
+       build_convert_pte_to_entrylo(p, tmp);
+       if (r4k_250MHZhwbug())
+               UASM_i_MTC0(p, 0, C0_ENTRYLO0);
+       UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */
+       build_convert_pte_to_entrylo(p, ptep);
+       if (r45k_bvahwbug())
+               uasm_i_mfc0(p, tmp, C0_INDEX);
        if (r4k_250MHZhwbug())
                UASM_i_MTC0(p, 0, C0_ENTRYLO1);
        UASM_i_MTC0(p, ptep, C0_ENTRYLO1); /* load it */
-#endif
 }
 
 struct mips_huge_tlb_info {
@@ -2299,6 +2284,10 @@ static void config_htw_params(void)
        /* re-initialize the PTI field including the even/odd bit */
        pwfield &= ~MIPS_PWFIELD_PTI_MASK;
        pwfield |= PAGE_SHIFT << MIPS_PWFIELD_PTI_SHIFT;
+       if (CONFIG_PGTABLE_LEVELS >= 3) {
+               pwfield &= ~MIPS_PWFIELD_MDI_MASK;
+               pwfield |= PMD_SHIFT << MIPS_PWFIELD_MDI_SHIFT;
+       }
        /* Set the PTEI right shift */
        ptei = _PAGE_GLOBAL_SHIFT << MIPS_PWFIELD_PTEI_SHIFT;
        pwfield |= ptei;
@@ -2320,9 +2309,11 @@ static void config_htw_params(void)
 
        pwsize = ilog2(PTRS_PER_PGD) << MIPS_PWSIZE_GDW_SHIFT;
        pwsize |= ilog2(PTRS_PER_PTE) << MIPS_PWSIZE_PTW_SHIFT;
+       if (CONFIG_PGTABLE_LEVELS >= 3)
+               pwsize |= ilog2(PTRS_PER_PMD) << MIPS_PWSIZE_MDW_SHIFT;
 
        /* If XPA has been enabled, PTEs are 64-bit in size. */
-       if (read_c0_pagegrain() & PG_ELPA)
+       if (config_enabled(CONFIG_64BITS) || (read_c0_pagegrain() & PG_ELPA))
                pwsize |= 1;
 
        write_c0_pwsize(pwsize);
@@ -2360,6 +2351,41 @@ static void config_xpa_params(void)
 #endif
 }
 
+static void check_pabits(void)
+{
+       unsigned long entry;
+       unsigned pabits, fillbits;
+
+       if (!cpu_has_rixi || !_PAGE_NO_EXEC) {
+               /*
+                * We'll only be making use of the fact that we can rotate bits
+                * into the fill if the CPU supports RIXI, so don't bother
+                * probing this for CPUs which don't.
+                */
+               return;
+       }
+
+       write_c0_entrylo0(~0ul);
+       back_to_back_c0_hazard();
+       entry = read_c0_entrylo0();
+
+       /* clear all non-PFN bits */
+       entry &= ~((1 << MIPS_ENTRYLO_PFN_SHIFT) - 1);
+       entry &= ~(MIPS_ENTRYLO_RI | MIPS_ENTRYLO_XI);
+
+       /* find a lower bound on PABITS, and upper bound on fill bits */
+       pabits = fls_long(entry) + 6;
+       fillbits = max_t(int, (int)BITS_PER_LONG - pabits, 0);
+
+       /* minus the RI & XI bits */
+       fillbits -= min_t(unsigned, fillbits, 2);
+
+       if (fillbits >= ilog2(_PAGE_NO_EXEC))
+               fill_includes_sw_bits = true;
+
+       pr_debug("Entry* registers contain %u fill bits\n", fillbits);
+}
+
 void build_tlb_refill_handler(void)
 {
        /*
@@ -2370,6 +2396,7 @@ void build_tlb_refill_handler(void)
        static int run_once = 0;
 
        output_pgtable_bits_defines();
+       check_pabits();
 
 #ifdef CONFIG_64BIT
        check_for_high_segbits = current_cpu_data.vmbits > (PGDIR_SHIFT + PGD_ORDER + PAGE_SHIFT - 3);
index ea35587a5c2920a0e32c4a00fdc346ac41d4cd9d..5827af77c18e9931c43af5e5df2881f94df44c25 100644 (file)
@@ -5,9 +5,18 @@
 # Copyright (C) 2008 Wind River Systems, Inc.
 #   written by Ralf Baechle <ralf@linux-mips.org>
 #
-obj-y                          := malta-display.o malta-dt.o malta-init.o \
-                                  malta-int.o malta-memory.o malta-platform.o \
-                                  malta-reset.o malta-setup.o malta-time.o
+obj-y                          += malta-display.o
+obj-y                          += malta-dt.o
+obj-y                          += malta-dtshim.o
+obj-y                          += malta-init.o
+obj-y                          += malta-int.o
+obj-y                          += malta-memory.o
+obj-y                          += malta-platform.o
+obj-y                          += malta-reset.o
+obj-y                          += malta-setup.o
+obj-y                          += malta-time.o
 
 obj-$(CONFIG_MIPS_CMP)         += malta-amon.o
 obj-$(CONFIG_MIPS_MALTA_PM)    += malta-pm.o
+
+CFLAGS_malta-dtshim.o = -I$(src)/../../../scripts/dtc/libfdt
diff --git a/arch/mips/mti-malta/malta-dtshim.c b/arch/mips/mti-malta/malta-dtshim.c
new file mode 100644 (file)
index 0000000..f7133ef
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/bug.h>
+#include <linux/kernel.h>
+#include <linux/libfdt.h>
+#include <linux/of_fdt.h>
+#include <linux/sizes.h>
+#include <asm/bootinfo.h>
+#include <asm/fw/fw.h>
+#include <asm/page.h>
+
+static unsigned char fdt_buf[16 << 10] __initdata;
+
+/* determined physical memory size, not overridden by command line args         */
+extern unsigned long physical_memsize;
+
+#define MAX_MEM_ARRAY_ENTRIES 1
+
+static unsigned __init gen_fdt_mem_array(__be32 *mem_array, unsigned long size)
+{
+       unsigned long size_preio;
+       unsigned entries;
+
+       entries = 1;
+       mem_array[0] = cpu_to_be32(PHYS_OFFSET);
+       if (config_enabled(CONFIG_EVA)) {
+               /*
+                * The current Malta EVA configuration is "special" in that it
+                * always makes use of addresses in the upper half of the 32 bit
+                * physical address map, which gives it a contiguous region of
+                * DDR but limits it to 2GB.
+                */
+               mem_array[1] = cpu_to_be32(size);
+       } else {
+               size_preio = min_t(unsigned long, size, SZ_256M);
+               mem_array[1] = cpu_to_be32(size_preio);
+       }
+
+       BUG_ON(entries > MAX_MEM_ARRAY_ENTRIES);
+       return entries;
+}
+
+static void __init append_memory(void *fdt, int root_off)
+{
+       __be32 mem_array[2 * MAX_MEM_ARRAY_ENTRIES];
+       unsigned long memsize;
+       unsigned mem_entries;
+       int i, err, mem_off;
+       char *var, param_name[10], *var_names[] = {
+               "ememsize", "memsize",
+       };
+
+       /* if a memory node already exists, leave it alone */
+       mem_off = fdt_path_offset(fdt, "/memory");
+       if (mem_off >= 0)
+               return;
+
+       /* find memory size from the bootloader environment */
+       for (i = 0; i < ARRAY_SIZE(var_names); i++) {
+               var = fw_getenv(var_names[i]);
+               if (!var)
+                       continue;
+
+               err = kstrtoul(var, 0, &physical_memsize);
+               if (!err)
+                       break;
+
+               pr_warn("Failed to read the '%s' env variable '%s'\n",
+                       var_names[i], var);
+       }
+
+       if (!physical_memsize) {
+               pr_warn("The bootloader didn't provide memsize: defaulting to 32MB\n");
+               physical_memsize = 32 << 20;
+       }
+
+       if (config_enabled(CONFIG_CPU_BIG_ENDIAN)) {
+               /*
+                * SOC-it swaps, or perhaps doesn't swap, when DMA'ing
+                * the last word of physical memory.
+                */
+               physical_memsize -= PAGE_SIZE;
+       }
+
+       /* default to using all available RAM */
+       memsize = physical_memsize;
+
+       /* allow the user to override the usable memory */
+       for (i = 0; i < ARRAY_SIZE(var_names); i++) {
+               snprintf(param_name, sizeof(param_name), "%s=", var_names[i]);
+               var = strstr(arcs_cmdline, param_name);
+               if (!var)
+                       continue;
+
+               memsize = memparse(var + strlen(param_name), NULL);
+       }
+
+       /* if the user says there's more RAM than we thought, believe them */
+       physical_memsize = max_t(unsigned long, physical_memsize, memsize);
+
+       /* append memory to the DT */
+       mem_off = fdt_add_subnode(fdt, root_off, "memory");
+       if (mem_off < 0)
+               panic("Unable to add memory node to DT: %d", mem_off);
+
+       err = fdt_setprop_string(fdt, mem_off, "device_type", "memory");
+       if (err)
+               panic("Unable to set memory node device_type: %d", err);
+
+       mem_entries = gen_fdt_mem_array(mem_array, physical_memsize);
+       err = fdt_setprop(fdt, mem_off, "reg", mem_array,
+                         mem_entries * 2 * sizeof(mem_array[0]));
+       if (err)
+               panic("Unable to set memory regs property: %d", err);
+
+       mem_entries = gen_fdt_mem_array(mem_array, memsize);
+       err = fdt_setprop(fdt, mem_off, "linux,usable-memory", mem_array,
+                         mem_entries * 2 * sizeof(mem_array[0]));
+       if (err)
+               panic("Unable to set linux,usable-memory property: %d", err);
+}
+
+void __init *malta_dt_shim(void *fdt)
+{
+       int root_off, len, err;
+       const char *compat;
+
+       if (fdt_check_header(fdt))
+               panic("Corrupt DT");
+
+       err = fdt_open_into(fdt, fdt_buf, sizeof(fdt_buf));
+       if (err)
+               panic("Unable to open FDT: %d", err);
+
+       root_off = fdt_path_offset(fdt_buf, "/");
+       if (root_off < 0)
+               panic("No / node in DT");
+
+       compat = fdt_getprop(fdt_buf, root_off, "compatible", &len);
+       if (!compat)
+               panic("No root compatible property in DT: %d", len);
+
+       /* if this isn't Malta, leave the DT alone */
+       if (strncmp(compat, "mti,malta", len))
+               return fdt;
+
+       append_memory(fdt_buf, root_off);
+
+       err = fdt_pack(fdt_buf);
+       if (err)
+               panic("Unable to pack FDT: %d\n", err);
+
+       return fdt_buf;
+}
index 53c24784a2f7bd2e8c0ae719f1f07c9ad60dd52b..571148c5fd0baa5ce8656e87574144d90b58e346 100644 (file)
@@ -302,6 +302,7 @@ mips_pci_controller:
                return;
        if (!register_vsmp_smp_ops())
                return;
+       register_up_smp_ops();
 }
 
 void platform_early_l2_init(void)
index dadeb83791828249e3af6d62ad55f1e9a2756a8a..d5f8dae6a7978a5b7e3c62c4c70bef756941a061 100644 (file)
 #include <asm/sections.h>
 #include <asm/fw/fw.h>
 
-static fw_memblock_t mdesc[FW_MAX_MEMBLOCKS];
-
 /* determined physical memory size, not overridden by command line args         */
 unsigned long physical_memsize = 0L;
 
-fw_memblock_t * __init fw_getmdesc(int eva)
-{
-       char *memsize_str, *ememsize_str = NULL, *ptr;
-       unsigned long memsize = 0, ememsize = 0;
-       static char cmdline[COMMAND_LINE_SIZE] __initdata;
-       int tmp;
-
-       /* otherwise look in the environment */
-
-       memsize_str = fw_getenv("memsize");
-       if (memsize_str) {
-               tmp = kstrtoul(memsize_str, 0, &memsize);
-               if (tmp)
-                       pr_warn("Failed to read the 'memsize' env variable.\n");
-       }
-       if (eva) {
-       /* Look for ememsize for EVA */
-               ememsize_str = fw_getenv("ememsize");
-               if (ememsize_str) {
-                       tmp = kstrtoul(ememsize_str, 0, &ememsize);
-                       if (tmp)
-                               pr_warn("Failed to read the 'ememsize' env variable.\n");
-               }
-       }
-       if (!memsize && !ememsize) {
-               pr_warn("memsize not set in YAMON, set to default (32Mb)\n");
-               physical_memsize = 0x02000000;
-       } else {
-               if (memsize > (256 << 20)) { /* memsize should be capped to 256M */
-                       pr_warn("Unsupported memsize value (0x%lx) detected! "
-                               "Using 0x10000000 (256M) instead\n",
-                               memsize);
-                       memsize = 256 << 20;
-               }
-               /* If ememsize is set, then set physical_memsize to that */
-               physical_memsize = ememsize ? : memsize;
-       }
-
-#ifdef CONFIG_CPU_BIG_ENDIAN
-       /* SOC-it swaps, or perhaps doesn't swap, when DMA'ing the last
-          word of physical memory */
-       physical_memsize -= PAGE_SIZE;
-#endif
-
-       /* Check the command line for a memsize directive that overrides
-          the physical/default amount */
-       strcpy(cmdline, arcs_cmdline);
-       ptr = strstr(cmdline, "memsize=");
-       if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' '))
-               ptr = strstr(ptr, " memsize=");
-       /* And now look for ememsize */
-       if (eva) {
-               ptr = strstr(cmdline, "ememsize=");
-               if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' '))
-                       ptr = strstr(ptr, " ememsize=");
-       }
-
-       if (ptr)
-               memsize = memparse(ptr + 8 + (eva ? 1 : 0), &ptr);
-       else
-               memsize = physical_memsize;
-
-       /* Last 64K for HIGHMEM arithmetics */
-       if (memsize > 0x7fff0000)
-               memsize = 0x7fff0000;
-
-       memset(mdesc, 0, sizeof(mdesc));
-
-       mdesc[0].type = fw_dontuse;
-       mdesc[0].base = PHYS_OFFSET;
-       mdesc[0].size = 0x00001000;
-
-       mdesc[1].type = fw_code;
-       mdesc[1].base = mdesc[0].base + 0x00001000UL;
-       mdesc[1].size = 0x000ef000;
-
-       /*
-        * The area 0x000f0000-0x000fffff is allocated for BIOS memory by the
-        * south bridge and PCI access always forwarded to the ISA Bus and
-        * BIOSCS# is always generated.
-        * This mean that this area can't be used as DMA memory for PCI
-        * devices.
-        */
-       mdesc[2].type = fw_dontuse;
-       mdesc[2].base = mdesc[0].base + 0x000f0000UL;
-       mdesc[2].size = 0x00010000;
-
-       mdesc[3].type = fw_dontuse;
-       mdesc[3].base = mdesc[0].base + 0x00100000UL;
-       mdesc[3].size = CPHYSADDR(PFN_ALIGN((unsigned long)&_end)) -
-               0x00100000UL;
-
-       mdesc[4].type = fw_free;
-       mdesc[4].base = mdesc[0].base + CPHYSADDR(PFN_ALIGN(&_end));
-       mdesc[4].size = memsize - CPHYSADDR(mdesc[4].base);
-
-       return &mdesc[0];
-}
-
 static void free_init_pages_eva_malta(void *begin, void *end)
 {
        free_init_pages("unused kernel", __pa_symbol((unsigned long *)begin),
                        __pa_symbol((unsigned long *)end));
 }
 
-static int __init fw_memtype_classify(unsigned int type)
-{
-       switch (type) {
-       case fw_free:
-               return BOOT_MEM_RAM;
-       case fw_code:
-               return BOOT_MEM_ROM_DATA;
-       default:
-               return BOOT_MEM_RESERVED;
-       }
-}
-
 void __init fw_meminit(void)
 {
-       fw_memblock_t *p;
-
-       p = fw_getmdesc(config_enabled(CONFIG_EVA));
-       free_init_pages_eva = (config_enabled(CONFIG_EVA) ?
-                              free_init_pages_eva_malta : NULL);
+       bool eva = config_enabled(CONFIG_EVA);
 
-       while (p->size) {
-               long type;
-               unsigned long base, size;
-
-               type = fw_memtype_classify(p->type);
-               base = p->base;
-               size = p->size;
-
-               add_memory_region(base, size, type);
-               p++;
-       }
+       free_init_pages_eva = eva ? free_init_pages_eva_malta : NULL;
 }
 
 void __init prom_free_prom_memory(void)
index 9d1e7f5ec36cac95dbad432f0a8c1378b5c75195..4740c82fb97a14e95118d05590b66b3192e9f1f5 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/time.h>
 
 #include <asm/fw/fw.h>
+#include <asm/mach-malta/malta-dtshim.h>
 #include <asm/mips-cm.h>
 #include <asm/mips-boards/generic.h>
 #include <asm/mips-boards/malta.h>
@@ -250,8 +251,10 @@ static void __init bonito_quirks_setup(void)
 void __init plat_mem_setup(void)
 {
        unsigned int i;
+       void *fdt = __dtb_start;
 
-       __dt_setup_arch(__dtb_start);
+       fdt = malta_dt_shim(fdt);
+       __dt_setup_arch(fdt);
 
        if (config_enabled(CONFIG_EVA))
                /* EVA has already been configured in mach-malta/kernel-init.h */
index a625bdb6d6aa0e2f23de8c629f34e28803d19d66..856a6e6d296e978a6435707a781bc15df412824e 100644 (file)
@@ -87,7 +87,6 @@ void __init *xlp_dt_init(void *fdtp)
 void __init xlp_early_init_devtree(void)
 {
        __dt_setup_arch(xlp_fdt_blob);
-       strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
 }
 
 void __init device_tree_init(void)
index ed6732f9aa874c2557a93de78e9cb1c816320af1..53a42b07008b99f2043ac1da444b9732c4af8c2b 100644 (file)
@@ -432,8 +432,7 @@ static int rt3883_pci_probe(struct platform_device *pdev)
 
        /* find the interrupt controller child node */
        for_each_child_of_node(np, child) {
-               if (of_get_property(child, "interrupt-controller", NULL) &&
-                   of_node_get(child)) {
+               if (of_get_property(child, "interrupt-controller", NULL)) {
                        rpc->intc_of_node = child;
                        break;
                }
@@ -449,8 +448,7 @@ static int rt3883_pci_probe(struct platform_device *pdev)
        /* find the PCI host bridge child node */
        for_each_child_of_node(np, child) {
                if (child->type &&
-                   of_node_cmp(child->type, "pci") == 0 &&
-                   of_node_get(child)) {
+                   of_node_cmp(child->type, "pci") == 0) {
                        rpc->pci_controller.of_node = child;
                        break;
                }
index 8bd8ebb20a72631501e5365478d10aa0d07b992b..96ba2cc9ad3e34da3948c3103d41629e24c88227 100644 (file)
@@ -58,7 +58,6 @@ void __init plat_mem_setup(void)
                panic("Device-tree not present");
 
        __dt_setup_arch((void *)fw_arg1);
-       strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
 
        plat_setup_iocoherency();
 }
index a8e70a9f274bdf70b0be449bee57c71c513e6fc4..e46f91f971c54f85759067c26b8a5d27d98f6a74 100644 (file)
@@ -48,7 +48,7 @@ static int systick_next_event(unsigned long delta,
        sdev = container_of(evt, struct systick_device, dev);
        count = ioread32(sdev->membase + SYSTICK_COUNT);
        count = (count + delta) % SYSTICK_FREQ;
-       iowrite32(count + delta, sdev->membase + SYSTICK_COMPARE);
+       iowrite32(count, sdev->membase + SYSTICK_COMPARE);
 
        return 0;
 }
index 255d695ec8c609168e92d1b9ec5cafe5020eda1b..3c59ffe5f5f54116785a501ad39abaccd1ad11a5 100644 (file)
 #define MT7628_CHIP_NAME1      0x20203832
 
 #define UART_REG_TX            0x04
+#define UART_REG_LCR           0x0c
 #define UART_REG_LSR           0x14
 #define UART_REG_LSR_RT2880    0x1c
 
 static __iomem void *uart_membase = (__iomem void *) KSEG1ADDR(EARLY_UART_BASE);
 static __iomem void *chipid_membase = (__iomem void *) KSEG1ADDR(CHIPID_BASE);
+static int init_complete;
 
 static inline void uart_w32(u32 val, unsigned reg)
 {
@@ -47,8 +49,32 @@ static inline int soc_is_mt7628(void)
                (__raw_readl(chipid_membase) == MT7628_CHIP_NAME1);
 }
 
+static void find_uart_base(void)
+{
+       int i;
+
+       if (!soc_is_mt7628())
+               return;
+
+       for (i = 0; i < 3; i++) {
+               u32 reg = uart_r32(UART_REG_LCR + (0x100 * i));
+
+               if (!reg)
+                       continue;
+
+               uart_membase = (__iomem void *) KSEG1ADDR(EARLY_UART_BASE +
+                                                         (0x100 * i));
+               break;
+       }
+}
+
 void prom_putchar(unsigned char ch)
 {
+       if (!init_complete) {
+               find_uart_base();
+               init_complete = 1;
+       }
+
        if (IS_ENABLED(CONFIG_SOC_MT7621) || soc_is_mt7628()) {
                uart_w32(ch, UART_TX);
                while ((uart_r32(UART_REG_LSR) & UART_LSR_THRE) == 0)
index 2ea5ff6dc22e6d769cc851347b5c7492535e0596..dfb04fcedb042d9b80621ac3197886a1ea3bccda 100644 (file)
 #define PMU1_CFG               0x8C
 #define DIG_SW_SEL             BIT(25)
 
-/* is this a MT7620 or a MT7628 */
-enum mt762x_soc_type mt762x_soc;
+/* clock scaling */
+#define CLKCFG_FDIV_MASK       0x1f00
+#define CLKCFG_FDIV_USB_VAL    0x0300
+#define CLKCFG_FFRAC_MASK      0x001f
+#define CLKCFG_FFRAC_USB_VAL   0x0003
+
+/* EFUSE bits */
+#define EFUSE_MT7688           0x100000
+
+/* DRAM type bit */
+#define DRAM_TYPE_MT7628_MASK  0x1
 
 /* does the board have sdram or ddram */
 static int dram_type;
@@ -227,6 +236,12 @@ static struct rt2880_pmx_group mt7628an_pinmux_data[] = {
        { 0 }
 };
 
+static inline int is_mt76x8(void)
+{
+       return ralink_soc == MT762X_SOC_MT7628AN ||
+              ralink_soc == MT762X_SOC_MT7688;
+}
+
 static __init u32
 mt7620_calc_rate(u32 ref_rate, u32 mul, u32 div)
 {
@@ -381,7 +396,7 @@ void __init ralink_clk_init(void)
 #define RINT(x)                ((x) / 1000000)
 #define RFRAC(x)       (((x) / 1000) % 1000)
 
-       if (mt762x_soc == MT762X_SOC_MT7628AN) {
+       if (is_mt76x8()) {
                if (xtal_rate == MHZ(40))
                        cpu_rate = MHZ(580);
                else
@@ -423,6 +438,20 @@ void __init ralink_clk_init(void)
        ralink_clk_add("10000b00.spi", sys_rate);
        ralink_clk_add("10000c00.uartlite", periph_rate);
        ralink_clk_add("10180000.wmac", xtal_rate);
+
+       if (IS_ENABLED(CONFIG_USB) && is_mt76x8()) {
+               /*
+                * When the CPU goes into sleep mode, the BUS clock will be
+                * too low for USB to function properly. Adjust the busses
+                * fractional divider to fix this
+                */
+               u32 val = rt_sysc_r32(SYSC_REG_CPU_SYS_CLKCFG);
+
+               val &= ~(CLKCFG_FDIV_MASK | CLKCFG_FFRAC_MASK);
+               val |= CLKCFG_FDIV_USB_VAL | CLKCFG_FFRAC_USB_VAL;
+
+               rt_sysc_w32(val, SYSC_REG_CPU_SYS_CLKCFG);
+       }
 }
 
 void __init ralink_of_remap(void)
@@ -499,20 +528,24 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
 
        if (n0 == MT7620_CHIP_NAME0 && n1 == MT7620_CHIP_NAME1) {
                if (bga) {
-                       mt762x_soc = MT762X_SOC_MT7620A;
+                       ralink_soc = MT762X_SOC_MT7620A;
                        name = "MT7620A";
                        soc_info->compatible = "ralink,mt7620a-soc";
                } else {
-                       mt762x_soc = MT762X_SOC_MT7620N;
+                       ralink_soc = MT762X_SOC_MT7620N;
                        name = "MT7620N";
                        soc_info->compatible = "ralink,mt7620n-soc";
-#ifdef CONFIG_PCI
-                       panic("mt7620n is only supported for non pci kernels");
-#endif
                }
        } else if (n0 == MT7620_CHIP_NAME0 && n1 == MT7628_CHIP_NAME1) {
-               mt762x_soc = MT762X_SOC_MT7628AN;
-               name = "MT7628AN";
+               u32 efuse = __raw_readl(sysc + SYSC_REG_EFUSE_CFG);
+
+               if (efuse & EFUSE_MT7688) {
+                       ralink_soc = MT762X_SOC_MT7688;
+                       name = "MT7688";
+               } else {
+                       ralink_soc = MT762X_SOC_MT7628AN;
+                       name = "MT7628AN";
+               }
                soc_info->compatible = "ralink,mt7628an-soc";
        } else {
                panic("mt762x: unknown SoC, n0:%08x n1:%08x\n", n0, n1);
@@ -525,10 +558,14 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
                (rev & CHIP_REV_ECO_MASK));
 
        cfg0 = __raw_readl(sysc + SYSC_REG_SYSTEM_CONFIG0);
-       dram_type = (cfg0 >> SYSCFG0_DRAM_TYPE_SHIFT) & SYSCFG0_DRAM_TYPE_MASK;
+       if (is_mt76x8())
+               dram_type = cfg0 & DRAM_TYPE_MT7628_MASK;
+       else
+               dram_type = (cfg0 >> SYSCFG0_DRAM_TYPE_SHIFT) &
+                           SYSCFG0_DRAM_TYPE_MASK;
 
        soc_info->mem_base = MT7620_DRAM_BASE;
-       if (mt762x_soc == MT762X_SOC_MT7628AN)
+       if (is_mt76x8())
                mt7628_dram_init(soc_info);
        else
                mt7620_dram_init(soc_info);
@@ -541,7 +578,7 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
        pr_info("Digital PMU set to %s control\n",
                (pmu1 & DIG_SW_SEL) ? ("sw") : ("hw"));
 
-       if (mt762x_soc == MT762X_SOC_MT7628AN)
+       if (is_mt76x8())
                rt2880_pinmux_data = mt7628an_pinmux_data;
        else
                rt2880_pinmux_data = mt7620a_pinmux_data;
index 0d30dcd6324623a3ed6dc635ec653a2619228132..f9eda5d8f82cd54681efbdf65c4f55123a3dfeed 100644 (file)
@@ -74,8 +74,6 @@ void __init plat_mem_setup(void)
         */
        __dt_setup_arch(__dtb_start);
 
-       strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
-
        of_scan_flat_dt(early_init_dt_find_memory, NULL);
        if (memory_dtb)
                of_scan_flat_dt(early_init_dt_scan_memory, NULL);
index 09419f67da3990985be6d0a4db5de6460def0607..39a9142f71be214ed97194edc15f0398a028ffbd 100644 (file)
 #include <asm/bootinfo.h>
 #include <asm/addrspace.h>
 
+#include <asm/mach-ralink/ralink_regs.h>
+
 #include "common.h"
 
 struct ralink_soc_info soc_info;
 struct rt2880_pmx_group *rt2880_pinmux_data = NULL;
 
+enum ralink_soc_type ralink_soc;
+EXPORT_SYMBOL_GPL(ralink_soc);
+
 const char *get_system_type(void)
 {
        return soc_info.sys_type;
index 55c7ec59df3cca8a73259ee84731189a91db49ce..ee117c4bc4a36cc6f974c5efc89751300a535108 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/pm.h>
 #include <linux/io.h>
 #include <linux/of.h>
+#include <linux/delay.h>
 #include <linux/reset-controller.h>
 
 #include <asm/reboot.h>
 #include <asm/mach-ralink/ralink_regs.h>
 
 /* Reset Control */
-#define SYSC_REG_RESET_CTRL     0x034
-#define RSTCTL_RESET_SYSTEM     BIT(0)
+#define SYSC_REG_RESET_CTRL    0x034
+
+#define RSTCTL_RESET_PCI       BIT(26)
+#define RSTCTL_RESET_SYSTEM    BIT(0)
 
 static int ralink_assert_device(struct reset_controller_dev *rcdev,
                                unsigned long id)
@@ -83,6 +86,11 @@ void ralink_rst_init(void)
 
 static void ralink_restart(char *command)
 {
+       if (IS_ENABLED(CONFIG_PCI)) {
+               rt_sysc_m32(0, RSTCTL_RESET_PCI, SYSC_REG_RESET_CTRL);
+               mdelay(50);
+       }
+
        local_irq_disable();
        rt_sysc_w32(RSTCTL_RESET_SYSTEM, SYSC_REG_RESET_CTRL);
        unreachable();
@@ -98,7 +106,6 @@ static int __init mips_reboot_setup(void)
 {
        _machine_restart = ralink_restart;
        _machine_halt = ralink_halt;
-       pm_power_off = ralink_halt;
 
        return 0;
 }
index 738cec865f41a1a371d1c5506f0c4e50b268dce6..844f5cd55c8f1c1e96e20db2a888c22e1fb12327 100644 (file)
@@ -119,4 +119,5 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
        soc_info->mem_size_max = RT2880_MEM_SIZE_MAX;
 
        rt2880_pinmux_data = rt2880_pinmux_data_act;
+       ralink_soc == RT2880_SOC;
 }
index c40776ab67db5e0147d250e83990f6577c693268..9e45725920650bd55350549097f9330403f3ef6a 100644 (file)
@@ -21,8 +21,6 @@
 
 #include "common.h"
 
-enum rt305x_soc_type rt305x_soc;
-
 static struct rt2880_pmx_func i2c_func[] =  { FUNC("i2c", 0, 1, 2) };
 static struct rt2880_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) };
 static struct rt2880_pmx_func uartf_func[] = {
@@ -201,6 +199,7 @@ void __init ralink_clk_init(void)
        }
 
        ralink_clk_add("cpu", cpu_rate);
+       ralink_clk_add("sys", sys_rate);
        ralink_clk_add("10000b00.spi", sys_rate);
        ralink_clk_add("10000100.timer", wdt_rate);
        ralink_clk_add("10000120.watchdog", wdt_rate);
@@ -235,24 +234,24 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
 
                icache_sets = (read_c0_config1() >> 22) & 7;
                if (icache_sets == 1) {
-                       rt305x_soc = RT305X_SOC_RT3050;
+                       ralink_soc = RT305X_SOC_RT3050;
                        name = "RT3050";
                        soc_info->compatible = "ralink,rt3050-soc";
                } else {
-                       rt305x_soc = RT305X_SOC_RT3052;
+                       ralink_soc = RT305X_SOC_RT3052;
                        name = "RT3052";
                        soc_info->compatible = "ralink,rt3052-soc";
                }
        } else if (n0 == RT3350_CHIP_NAME0 && n1 == RT3350_CHIP_NAME1) {
-               rt305x_soc = RT305X_SOC_RT3350;
+               ralink_soc = RT305X_SOC_RT3350;
                name = "RT3350";
                soc_info->compatible = "ralink,rt3350-soc";
        } else if (n0 == RT3352_CHIP_NAME0 && n1 == RT3352_CHIP_NAME1) {
-               rt305x_soc = RT305X_SOC_RT3352;
+               ralink_soc = RT305X_SOC_RT3352;
                name = "RT3352";
                soc_info->compatible = "ralink,rt3352-soc";
        } else if (n0 == RT5350_CHIP_NAME0 && n1 == RT5350_CHIP_NAME1) {
-               rt305x_soc = RT305X_SOC_RT5350;
+               ralink_soc = RT305X_SOC_RT5350;
                name = "RT5350";
                soc_info->compatible = "ralink,rt5350-soc";
        } else {
index 86a535c770d84e4768680b7a58e06acf97a247e8..582995aaaf4e7e8a9848c512d150b515f3628344 100644 (file)
@@ -153,4 +153,6 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
        soc_info->mem_size_max = RT3883_MEM_SIZE_MAX;
 
        rt2880_pinmux_data = rt3883_pinmux_data;
+
+       ralink_soc == RT3883_SOC;
 }
diff --git a/arch/mips/vdso/.gitignore b/arch/mips/vdso/.gitignore
new file mode 100644 (file)
index 0000000..5286a7d
--- /dev/null
@@ -0,0 +1,4 @@
+*.so*
+vdso-*image.c
+genvdso
+vdso*.lds
diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile
new file mode 100644 (file)
index 0000000..ef5f348
--- /dev/null
@@ -0,0 +1,160 @@
+# Objects to go into the VDSO.
+obj-vdso-y := elf.o gettimeofday.o sigreturn.o
+
+# Common compiler flags between ABIs.
+ccflags-vdso := \
+       $(filter -I%,$(KBUILD_CFLAGS)) \
+       $(filter -E%,$(KBUILD_CFLAGS)) \
+       $(filter -march=%,$(KBUILD_CFLAGS))
+cflags-vdso := $(ccflags-vdso) \
+       $(filter -W%,$(filter-out -Wa$(comma)%,$(KBUILD_CFLAGS))) \
+       -O2 -g -fPIC -fno-common -fno-builtin -G 0 -DDISABLE_BRANCH_PROFILING \
+       $(call cc-option, -fno-stack-protector)
+aflags-vdso := $(ccflags-vdso) \
+       $(filter -I%,$(KBUILD_CFLAGS)) \
+       $(filter -E%,$(KBUILD_CFLAGS)) \
+       -D__ASSEMBLY__ -Wa,-gdwarf-2
+
+#
+# For the pre-R6 code in arch/mips/vdso/vdso.h for locating
+# the base address of VDSO, the linker will emit a R_MIPS_PC32
+# relocation in binutils > 2.25 but it will fail with older versions
+# because that relocation is not supported for that symbol. As a result
+# of which we are forced to disable the VDSO symbols when building
+# with < 2.25 binutils on pre-R6 kernels. For more references on why we
+# can't use other methods to get the base address of VDSO please refer to
+# the comments on that file.
+#
+ifndef CONFIG_CPU_MIPSR6
+  ifeq ($(call ld-ifversion, -gt, 22400000, y),)
+    $(warning MIPS VDSO requires binutils > 2.24)
+    obj-vdso-y := $(filter-out gettimeofday.o, $(obj-vdso-y))
+    ccflags-vdso += -DDISABLE_MIPS_VDSO
+  endif
+endif
+
+# VDSO linker flags.
+VDSO_LDFLAGS := \
+       -Wl,-Bsymbolic -Wl,--no-undefined -Wl,-soname=linux-vdso.so.1 \
+       -nostdlib -shared \
+       $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) \
+       $(call cc-ldoption, -Wl$(comma)--build-id)
+
+GCOV_PROFILE := n
+
+#
+# Shared build commands.
+#
+
+quiet_cmd_vdsold = VDSO    $@
+      cmd_vdsold = $(CC) $(c_flags) $(VDSO_LDFLAGS) \
+                   -Wl,-T $(filter %.lds,$^) $(filter %.o,$^) -o $@
+
+hostprogs-y := genvdso
+
+quiet_cmd_genvdso = GENVDSO $@
+define cmd_genvdso
+       cp $< $(<:%.dbg=%) && \
+       $(OBJCOPY) -S $< $(<:%.dbg=%) && \
+       $(obj)/genvdso $< $(<:%.dbg=%) $@ $(VDSO_NAME)
+endef
+
+#
+# Build native VDSO.
+#
+
+native-abi := $(filter -mabi=%,$(KBUILD_CFLAGS))
+
+targets += $(obj-vdso-y)
+targets += vdso.lds vdso.so.dbg vdso.so vdso-image.c
+
+obj-vdso := $(obj-vdso-y:%.o=$(obj)/%.o)
+
+$(obj-vdso): KBUILD_CFLAGS := $(cflags-vdso) $(native-abi)
+$(obj-vdso): KBUILD_AFLAGS := $(aflags-vdso) $(native-abi)
+
+$(obj)/vdso.lds: KBUILD_CPPFLAGS := $(native-abi)
+
+$(obj)/vdso.so.dbg: $(obj)/vdso.lds $(obj-vdso) FORCE
+       $(call if_changed,vdsold)
+
+$(obj)/vdso-image.c: $(obj)/vdso.so.dbg $(obj)/genvdso FORCE
+       $(call if_changed,genvdso)
+
+obj-y += vdso-image.o
+
+#
+# Build O32 VDSO.
+#
+
+# Define these outside the ifdef to ensure they are picked up by clean.
+targets += $(obj-vdso-y:%.o=%-o32.o)
+targets += vdso-o32.lds vdso-o32.so.dbg vdso-o32.so vdso-o32-image.c
+
+ifdef CONFIG_MIPS32_O32
+
+obj-vdso-o32 := $(obj-vdso-y:%.o=$(obj)/%-o32.o)
+
+$(obj-vdso-o32): KBUILD_CFLAGS := $(cflags-vdso) -mabi=32
+$(obj-vdso-o32): KBUILD_AFLAGS := $(aflags-vdso) -mabi=32
+
+$(obj)/%-o32.o: $(src)/%.S FORCE
+       $(call if_changed_dep,as_o_S)
+
+$(obj)/%-o32.o: $(src)/%.c FORCE
+       $(call cmd,force_checksrc)
+       $(call if_changed_rule,cc_o_c)
+
+$(obj)/vdso-o32.lds: KBUILD_CPPFLAGS := -mabi=32
+$(obj)/vdso-o32.lds: $(src)/vdso.lds.S FORCE
+       $(call if_changed_dep,cpp_lds_S)
+
+$(obj)/vdso-o32.so.dbg: $(obj)/vdso-o32.lds $(obj-vdso-o32) FORCE
+       $(call if_changed,vdsold)
+
+$(obj)/vdso-o32-image.c: VDSO_NAME := o32
+$(obj)/vdso-o32-image.c: $(obj)/vdso-o32.so.dbg $(obj)/genvdso FORCE
+       $(call if_changed,genvdso)
+
+obj-y += vdso-o32-image.o
+
+endif
+
+#
+# Build N32 VDSO.
+#
+
+targets += $(obj-vdso-y:%.o=%-n32.o)
+targets += vdso-n32.lds vdso-n32.so.dbg vdso-n32.so vdso-n32-image.c
+
+ifdef CONFIG_MIPS32_N32
+
+obj-vdso-n32 := $(obj-vdso-y:%.o=$(obj)/%-n32.o)
+
+$(obj-vdso-n32): KBUILD_CFLAGS := $(cflags-vdso) -mabi=n32
+$(obj-vdso-n32): KBUILD_AFLAGS := $(aflags-vdso) -mabi=n32
+
+$(obj)/%-n32.o: $(src)/%.S FORCE
+       $(call if_changed_dep,as_o_S)
+
+$(obj)/%-n32.o: $(src)/%.c FORCE
+       $(call cmd,force_checksrc)
+       $(call if_changed_rule,cc_o_c)
+
+$(obj)/vdso-n32.lds: KBUILD_CPPFLAGS := -mabi=n32
+$(obj)/vdso-n32.lds: $(src)/vdso.lds.S FORCE
+       $(call if_changed_dep,cpp_lds_S)
+
+$(obj)/vdso-n32.so.dbg: $(obj)/vdso-n32.lds $(obj-vdso-n32) FORCE
+       $(call if_changed,vdsold)
+
+$(obj)/vdso-n32-image.c: VDSO_NAME := n32
+$(obj)/vdso-n32-image.c: $(obj)/vdso-n32.so.dbg $(obj)/genvdso FORCE
+       $(call if_changed,genvdso)
+
+obj-y += vdso-n32-image.o
+
+endif
+
+# FIXME: Need install rule for debug.
+# Needs to deal with dependency for generation of dbg by cmd_genvdso...
diff --git a/arch/mips/vdso/elf.S b/arch/mips/vdso/elf.S
new file mode 100644 (file)
index 0000000..be37bbb
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Alex Smith <alex.smith@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include "vdso.h"
+
+#include <linux/elfnote.h>
+#include <linux/version.h>
+
+ELFNOTE_START(Linux, 0, "a")
+       .long LINUX_VERSION_CODE
+ELFNOTE_END
+
+/*
+ * The .MIPS.abiflags section must be defined with the FP ABI flags set
+ * to 'any' to be able to link with both old and new libraries.
+ * Newer toolchains are capable of automatically generating this, but we want
+ * to work with older toolchains as well. Therefore, we define the contents of
+ * this section here (under different names), and then genvdso will patch
+ * it to have the correct name and type.
+ *
+ * We base the .MIPS.abiflags section on preprocessor definitions rather than
+ * CONFIG_* because we need to match the particular ABI we are building the
+ * VDSO for.
+ *
+ * See https://dmz-portal.mips.com/wiki/MIPS_O32_ABI_-_FR0_and_FR1_Interlinking
+ * for the .MIPS.abiflags section description.
+ */
+
+       .section .mips_abiflags, "a"
+       .align 3
+__mips_abiflags:
+       .hword  0               /* version */
+       .byte   __mips          /* isa_level */
+
+       /* isa_rev */
+#ifdef __mips_isa_rev
+       .byte   __mips_isa_rev
+#else
+       .byte   0
+#endif
+
+       /* gpr_size */
+#ifdef __mips64
+       .byte   2               /* AFL_REG_64 */
+#else
+       .byte   1               /* AFL_REG_32 */
+#endif
+
+       /* cpr1_size */
+#if (defined(__mips_isa_rev) && __mips_isa_rev >= 6) || defined(__mips64)
+       .byte   2               /* AFL_REG_64 */
+#else
+       .byte   1               /* AFL_REG_32 */
+#endif
+
+       .byte   0               /* cpr2_size (AFL_REG_NONE) */
+       .byte   0               /* fp_abi (Val_GNU_MIPS_ABI_FP_ANY) */
+       .word   0               /* isa_ext */
+       .word   0               /* ases */
+       .word   0               /* flags1 */
+       .word   0               /* flags2 */
diff --git a/arch/mips/vdso/genvdso.c b/arch/mips/vdso/genvdso.c
new file mode 100644 (file)
index 0000000..530a36f
--- /dev/null
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Alex Smith <alex.smith@imgtec.com>
+ *
+ * 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 tool is used to generate the real VDSO images from the raw image. It
+ * first patches up the MIPS ABI flags and GNU attributes sections defined in
+ * elf.S to have the correct name and type. It then generates a C source file
+ * to be compiled into the kernel containing the VDSO image data and a
+ * mips_vdso_image struct for it, including symbol offsets extracted from the
+ * image.
+ *
+ * We need to be passed both a stripped and unstripped VDSO image. The stripped
+ * image is compiled into the kernel, but we must also patch up the unstripped
+ * image's ABI flags sections so that it can be installed and used for
+ * debugging.
+ */
+
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <byteswap.h>
+#include <elf.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/* Define these in case the system elf.h is not new enough to have them. */
+#ifndef SHT_GNU_ATTRIBUTES
+# define SHT_GNU_ATTRIBUTES    0x6ffffff5
+#endif
+#ifndef SHT_MIPS_ABIFLAGS
+# define SHT_MIPS_ABIFLAGS     0x7000002a
+#endif
+
+enum {
+       ABI_O32 = (1 << 0),
+       ABI_N32 = (1 << 1),
+       ABI_N64 = (1 << 2),
+
+       ABI_ALL = ABI_O32 | ABI_N32 | ABI_N64,
+};
+
+/* Symbols the kernel requires offsets for. */
+static struct {
+       const char *name;
+       const char *offset_name;
+       unsigned int abis;
+} vdso_symbols[] = {
+       { "__vdso_sigreturn", "off_sigreturn", ABI_O32 },
+       { "__vdso_rt_sigreturn", "off_rt_sigreturn", ABI_ALL },
+       {}
+};
+
+static const char *program_name;
+static const char *vdso_name;
+static unsigned char elf_class;
+static unsigned int elf_abi;
+static bool need_swap;
+static FILE *out_file;
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+# define HOST_ORDER            ELFDATA2LSB
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+# define HOST_ORDER            ELFDATA2MSB
+#endif
+
+#define BUILD_SWAP(bits)                                               \
+       static uint##bits##_t swap_uint##bits(uint##bits##_t val)       \
+       {                                                               \
+               return need_swap ? bswap_##bits(val) : val;             \
+       }
+
+BUILD_SWAP(16)
+BUILD_SWAP(32)
+BUILD_SWAP(64)
+
+#define __FUNC(name, bits) name##bits
+#define _FUNC(name, bits) __FUNC(name, bits)
+#define FUNC(name) _FUNC(name, ELF_BITS)
+
+#define __ELF(x, bits) Elf##bits##_##x
+#define _ELF(x, bits) __ELF(x, bits)
+#define ELF(x) _ELF(x, ELF_BITS)
+
+/*
+ * Include genvdso.h twice with ELF_BITS defined differently to get functions
+ * for both ELF32 and ELF64.
+ */
+
+#define ELF_BITS 64
+#include "genvdso.h"
+#undef ELF_BITS
+
+#define ELF_BITS 32
+#include "genvdso.h"
+#undef ELF_BITS
+
+static void *map_vdso(const char *path, size_t *_size)
+{
+       int fd;
+       struct stat stat;
+       void *addr;
+       const Elf32_Ehdr *ehdr;
+
+       fd = open(path, O_RDWR);
+       if (fd < 0) {
+               fprintf(stderr, "%s: Failed to open '%s': %s\n", program_name,
+                       path, strerror(errno));
+               return NULL;
+       }
+
+       if (fstat(fd, &stat) != 0) {
+               fprintf(stderr, "%s: Failed to stat '%s': %s\n", program_name,
+                       path, strerror(errno));
+               return NULL;
+       }
+
+       addr = mmap(NULL, stat.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
+                   0);
+       if (addr == MAP_FAILED) {
+               fprintf(stderr, "%s: Failed to map '%s': %s\n", program_name,
+                       path, strerror(errno));
+               return NULL;
+       }
+
+       /* ELF32/64 header formats are the same for the bits we're checking. */
+       ehdr = addr;
+
+       if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0) {
+               fprintf(stderr, "%s: '%s' is not an ELF file\n", program_name,
+                       path);
+               return NULL;
+       }
+
+       elf_class = ehdr->e_ident[EI_CLASS];
+       switch (elf_class) {
+       case ELFCLASS32:
+       case ELFCLASS64:
+               break;
+       default:
+               fprintf(stderr, "%s: '%s' has invalid ELF class\n",
+                       program_name, path);
+               return NULL;
+       }
+
+       switch (ehdr->e_ident[EI_DATA]) {
+       case ELFDATA2LSB:
+       case ELFDATA2MSB:
+               need_swap = ehdr->e_ident[EI_DATA] != HOST_ORDER;
+               break;
+       default:
+               fprintf(stderr, "%s: '%s' has invalid ELF data order\n",
+                       program_name, path);
+               return NULL;
+       }
+
+       if (swap_uint16(ehdr->e_machine) != EM_MIPS) {
+               fprintf(stderr,
+                       "%s: '%s' has invalid ELF machine (expected EM_MIPS)\n",
+                       program_name, path);
+               return NULL;
+       } else if (swap_uint16(ehdr->e_type) != ET_DYN) {
+               fprintf(stderr,
+                       "%s: '%s' has invalid ELF type (expected ET_DYN)\n",
+                       program_name, path);
+               return NULL;
+       }
+
+       *_size = stat.st_size;
+       return addr;
+}
+
+static bool patch_vdso(const char *path, void *vdso)
+{
+       if (elf_class == ELFCLASS64)
+               return patch_vdso64(path, vdso);
+       else
+               return patch_vdso32(path, vdso);
+}
+
+static bool get_symbols(const char *path, void *vdso)
+{
+       if (elf_class == ELFCLASS64)
+               return get_symbols64(path, vdso);
+       else
+               return get_symbols32(path, vdso);
+}
+
+int main(int argc, char **argv)
+{
+       const char *dbg_vdso_path, *vdso_path, *out_path;
+       void *dbg_vdso, *vdso;
+       size_t dbg_vdso_size, vdso_size, i;
+
+       program_name = argv[0];
+
+       if (argc < 4 || argc > 5) {
+               fprintf(stderr,
+                       "Usage: %s <debug VDSO> <stripped VDSO> <output file> [<name>]\n",
+                       program_name);
+               return EXIT_FAILURE;
+       }
+
+       dbg_vdso_path = argv[1];
+       vdso_path = argv[2];
+       out_path = argv[3];
+       vdso_name = (argc > 4) ? argv[4] : "";
+
+       dbg_vdso = map_vdso(dbg_vdso_path, &dbg_vdso_size);
+       if (!dbg_vdso)
+               return EXIT_FAILURE;
+
+       vdso = map_vdso(vdso_path, &vdso_size);
+       if (!vdso)
+               return EXIT_FAILURE;
+
+       /* Patch both the VDSOs' ABI flags sections. */
+       if (!patch_vdso(dbg_vdso_path, dbg_vdso))
+               return EXIT_FAILURE;
+       if (!patch_vdso(vdso_path, vdso))
+               return EXIT_FAILURE;
+
+       if (msync(dbg_vdso, dbg_vdso_size, MS_SYNC) != 0) {
+               fprintf(stderr, "%s: Failed to sync '%s': %s\n", program_name,
+                       dbg_vdso_path, strerror(errno));
+               return EXIT_FAILURE;
+       } else if (msync(vdso, vdso_size, MS_SYNC) != 0) {
+               fprintf(stderr, "%s: Failed to sync '%s': %s\n", program_name,
+                       vdso_path, strerror(errno));
+               return EXIT_FAILURE;
+       }
+
+       out_file = fopen(out_path, "w");
+       if (!out_file) {
+               fprintf(stderr, "%s: Failed to open '%s': %s\n", program_name,
+                       out_path, strerror(errno));
+               return EXIT_FAILURE;
+       }
+
+       fprintf(out_file, "/* Automatically generated - do not edit */\n");
+       fprintf(out_file, "#include <linux/linkage.h>\n");
+       fprintf(out_file, "#include <linux/mm.h>\n");
+       fprintf(out_file, "#include <asm/vdso.h>\n");
+
+       /* Write out the stripped VDSO data. */
+       fprintf(out_file,
+               "static unsigned char vdso_data[PAGE_ALIGN(%zu)] __page_aligned_data = {\n\t",
+               vdso_size);
+       for (i = 0; i < vdso_size; i++) {
+               if (!(i % 10))
+                       fprintf(out_file, "\n\t");
+               fprintf(out_file, "0x%02x, ", ((unsigned char *)vdso)[i]);
+       }
+       fprintf(out_file, "\n};\n");
+
+       /* Preallocate a page array. */
+       fprintf(out_file,
+               "static struct page *vdso_pages[PAGE_ALIGN(%zu) / PAGE_SIZE];\n",
+               vdso_size);
+
+       fprintf(out_file, "struct mips_vdso_image vdso_image%s%s = {\n",
+               (vdso_name[0]) ? "_" : "", vdso_name);
+       fprintf(out_file, "\t.data = vdso_data,\n");
+       fprintf(out_file, "\t.size = PAGE_ALIGN(%zu),\n", vdso_size);
+       fprintf(out_file, "\t.mapping = {\n");
+       fprintf(out_file, "\t\t.name = \"[vdso]\",\n");
+       fprintf(out_file, "\t\t.pages = vdso_pages,\n");
+       fprintf(out_file, "\t},\n");
+
+       /* Calculate and write symbol offsets to <output file> */
+       if (!get_symbols(dbg_vdso_path, dbg_vdso)) {
+               unlink(out_path);
+               return EXIT_FAILURE;
+       }
+
+       fprintf(out_file, "};\n");
+
+       return EXIT_SUCCESS;
+}
diff --git a/arch/mips/vdso/genvdso.h b/arch/mips/vdso/genvdso.h
new file mode 100644 (file)
index 0000000..9433472
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Alex Smith <alex.smith@imgtec.com>
+ *
+ * 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.
+ */
+
+static inline bool FUNC(patch_vdso)(const char *path, void *vdso)
+{
+       const ELF(Ehdr) *ehdr = vdso;
+       void *shdrs;
+       ELF(Shdr) *shdr;
+       char *shstrtab, *name;
+       uint16_t sh_count, sh_entsize, i;
+       unsigned int local_gotno, symtabno, gotsym;
+       ELF(Dyn) *dyn = NULL;
+
+       shdrs = vdso + FUNC(swap_uint)(ehdr->e_shoff);
+       sh_count = swap_uint16(ehdr->e_shnum);
+       sh_entsize = swap_uint16(ehdr->e_shentsize);
+
+       shdr = shdrs + (sh_entsize * swap_uint16(ehdr->e_shstrndx));
+       shstrtab = vdso + FUNC(swap_uint)(shdr->sh_offset);
+
+       for (i = 0; i < sh_count; i++) {
+               shdr = shdrs + (i * sh_entsize);
+               name = shstrtab + swap_uint32(shdr->sh_name);
+
+               /*
+                * Ensure there are no relocation sections - ld.so does not
+                * relocate the VDSO so if there are relocations things will
+                * break.
+                */
+               switch (swap_uint32(shdr->sh_type)) {
+               case SHT_REL:
+               case SHT_RELA:
+                       fprintf(stderr,
+                               "%s: '%s' contains relocation sections\n",
+                               program_name, path);
+                       return false;
+               case SHT_DYNAMIC:
+                       dyn = vdso + FUNC(swap_uint)(shdr->sh_offset);
+                       break;
+               }
+
+               /* Check for existing sections. */
+               if (strcmp(name, ".MIPS.abiflags") == 0) {
+                       fprintf(stderr,
+                               "%s: '%s' already contains a '.MIPS.abiflags' section\n",
+                               program_name, path);
+                       return false;
+               }
+
+               if (strcmp(name, ".mips_abiflags") == 0) {
+                       strcpy(name, ".MIPS.abiflags");
+                       shdr->sh_type = swap_uint32(SHT_MIPS_ABIFLAGS);
+                       shdr->sh_entsize = shdr->sh_size;
+               }
+       }
+
+       /*
+        * Ensure the GOT has no entries other than the standard 2, for the same
+        * reason we check that there's no relocation sections above.
+        * The standard two entries are:
+        * - Lazy resolver
+        * - Module pointer
+        */
+       if (dyn) {
+               local_gotno = symtabno = gotsym = 0;
+
+               while (FUNC(swap_uint)(dyn->d_tag) != DT_NULL) {
+                       switch (FUNC(swap_uint)(dyn->d_tag)) {
+                       /*
+                        * This member holds the number of local GOT entries.
+                        */
+                       case DT_MIPS_LOCAL_GOTNO:
+                               local_gotno = FUNC(swap_uint)(dyn->d_un.d_val);
+                               break;
+                       /*
+                        * This member holds the number of entries in the
+                        * .dynsym section.
+                        */
+                       case DT_MIPS_SYMTABNO:
+                               symtabno = FUNC(swap_uint)(dyn->d_un.d_val);
+                               break;
+                       /*
+                        * This member holds the index of the first dynamic
+                        * symbol table entry that corresponds to an entry in
+                        * the GOT.
+                        */
+                       case DT_MIPS_GOTSYM:
+                               gotsym = FUNC(swap_uint)(dyn->d_un.d_val);
+                               break;
+                       }
+
+                       dyn++;
+               }
+
+               if (local_gotno > 2 || symtabno - gotsym) {
+                       fprintf(stderr,
+                               "%s: '%s' contains unexpected GOT entries\n",
+                               program_name, path);
+                       return false;
+               }
+       }
+
+       return true;
+}
+
+static inline bool FUNC(get_symbols)(const char *path, void *vdso)
+{
+       const ELF(Ehdr) *ehdr = vdso;
+       void *shdrs, *symtab;
+       ELF(Shdr) *shdr;
+       const ELF(Sym) *sym;
+       char *strtab, *name;
+       uint16_t sh_count, sh_entsize, st_count, st_entsize, i, j;
+       uint64_t offset;
+       uint32_t flags;
+
+       shdrs = vdso + FUNC(swap_uint)(ehdr->e_shoff);
+       sh_count = swap_uint16(ehdr->e_shnum);
+       sh_entsize = swap_uint16(ehdr->e_shentsize);
+
+       for (i = 0; i < sh_count; i++) {
+               shdr = shdrs + (i * sh_entsize);
+
+               if (swap_uint32(shdr->sh_type) == SHT_SYMTAB)
+                       break;
+       }
+
+       if (i == sh_count) {
+               fprintf(stderr, "%s: '%s' has no symbol table\n", program_name,
+                       path);
+               return false;
+       }
+
+       /* Get flags */
+       flags = swap_uint32(ehdr->e_flags);
+       if (elf_class == ELFCLASS64)
+               elf_abi = ABI_N64;
+       else if (flags & EF_MIPS_ABI2)
+               elf_abi = ABI_N32;
+       else
+               elf_abi = ABI_O32;
+
+       /* Get symbol table. */
+       symtab = vdso + FUNC(swap_uint)(shdr->sh_offset);
+       st_entsize = FUNC(swap_uint)(shdr->sh_entsize);
+       st_count = FUNC(swap_uint)(shdr->sh_size) / st_entsize;
+
+       /* Get string table. */
+       shdr = shdrs + (swap_uint32(shdr->sh_link) * sh_entsize);
+       strtab = vdso + FUNC(swap_uint)(shdr->sh_offset);
+
+       /* Write offsets for symbols needed by the kernel. */
+       for (i = 0; vdso_symbols[i].name; i++) {
+               if (!(vdso_symbols[i].abis & elf_abi))
+                       continue;
+
+               for (j = 0; j < st_count; j++) {
+                       sym = symtab + (j * st_entsize);
+                       name = strtab + swap_uint32(sym->st_name);
+
+                       if (!strcmp(name, vdso_symbols[i].name)) {
+                               offset = FUNC(swap_uint)(sym->st_value);
+
+                               fprintf(out_file,
+                                       "\t.%s = 0x%" PRIx64 ",\n",
+                                       vdso_symbols[i].offset_name, offset);
+                               break;
+                       }
+               }
+
+               if (j == st_count) {
+                       fprintf(stderr,
+                               "%s: '%s' is missing required symbol '%s'\n",
+                               program_name, path, vdso_symbols[i].name);
+                       return false;
+               }
+       }
+
+       return true;
+}
diff --git a/arch/mips/vdso/gettimeofday.c b/arch/mips/vdso/gettimeofday.c
new file mode 100644 (file)
index 0000000..ce89c9e
--- /dev/null
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Alex Smith <alex.smith@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include "vdso.h"
+
+#include <linux/compiler.h>
+#include <linux/irqchip/mips-gic.h>
+#include <linux/time.h>
+
+#include <asm/clocksource.h>
+#include <asm/io.h>
+#include <asm/mips-cm.h>
+#include <asm/unistd.h>
+#include <asm/vdso.h>
+
+static __always_inline int do_realtime_coarse(struct timespec *ts,
+                                             const union mips_vdso_data *data)
+{
+       u32 start_seq;
+
+       do {
+               start_seq = vdso_data_read_begin(data);
+
+               ts->tv_sec = data->xtime_sec;
+               ts->tv_nsec = data->xtime_nsec >> data->cs_shift;
+       } while (vdso_data_read_retry(data, start_seq));
+
+       return 0;
+}
+
+static __always_inline int do_monotonic_coarse(struct timespec *ts,
+                                              const union mips_vdso_data *data)
+{
+       u32 start_seq;
+       u32 to_mono_sec;
+       u32 to_mono_nsec;
+
+       do {
+               start_seq = vdso_data_read_begin(data);
+
+               ts->tv_sec = data->xtime_sec;
+               ts->tv_nsec = data->xtime_nsec >> data->cs_shift;
+
+               to_mono_sec = data->wall_to_mono_sec;
+               to_mono_nsec = data->wall_to_mono_nsec;
+       } while (vdso_data_read_retry(data, start_seq));
+
+       ts->tv_sec += to_mono_sec;
+       timespec_add_ns(ts, to_mono_nsec);
+
+       return 0;
+}
+
+#ifdef CONFIG_CSRC_R4K
+
+static __always_inline u64 read_r4k_count(void)
+{
+       unsigned int count;
+
+       __asm__ __volatile__(
+       "       .set push\n"
+       "       .set mips32r2\n"
+       "       rdhwr   %0, $2\n"
+       "       .set pop\n"
+       : "=r" (count));
+
+       return count;
+}
+
+#endif
+
+#ifdef CONFIG_CLKSRC_MIPS_GIC
+
+static __always_inline u64 read_gic_count(const union mips_vdso_data *data)
+{
+       void __iomem *gic = get_gic(data);
+       u32 hi, hi2, lo;
+
+       do {
+               hi = __raw_readl(gic + GIC_UMV_SH_COUNTER_63_32_OFS);
+               lo = __raw_readl(gic + GIC_UMV_SH_COUNTER_31_00_OFS);
+               hi2 = __raw_readl(gic + GIC_UMV_SH_COUNTER_63_32_OFS);
+       } while (hi2 != hi);
+
+       return (((u64)hi) << 32) + lo;
+}
+
+#endif
+
+static __always_inline u64 get_ns(const union mips_vdso_data *data)
+{
+       u64 cycle_now, delta, nsec;
+
+       switch (data->clock_mode) {
+#ifdef CONFIG_CSRC_R4K
+       case VDSO_CLOCK_R4K:
+               cycle_now = read_r4k_count();
+               break;
+#endif
+#ifdef CONFIG_CLKSRC_MIPS_GIC
+       case VDSO_CLOCK_GIC:
+               cycle_now = read_gic_count(data);
+               break;
+#endif
+       default:
+               return 0;
+       }
+
+       delta = (cycle_now - data->cs_cycle_last) & data->cs_mask;
+
+       nsec = (delta * data->cs_mult) + data->xtime_nsec;
+       nsec >>= data->cs_shift;
+
+       return nsec;
+}
+
+static __always_inline int do_realtime(struct timespec *ts,
+                                      const union mips_vdso_data *data)
+{
+       u32 start_seq;
+       u64 ns;
+
+       do {
+               start_seq = vdso_data_read_begin(data);
+
+               if (data->clock_mode == VDSO_CLOCK_NONE)
+                       return -ENOSYS;
+
+               ts->tv_sec = data->xtime_sec;
+               ns = get_ns(data);
+       } while (vdso_data_read_retry(data, start_seq));
+
+       ts->tv_nsec = 0;
+       timespec_add_ns(ts, ns);
+
+       return 0;
+}
+
+static __always_inline int do_monotonic(struct timespec *ts,
+                                       const union mips_vdso_data *data)
+{
+       u32 start_seq;
+       u64 ns;
+       u32 to_mono_sec;
+       u32 to_mono_nsec;
+
+       do {
+               start_seq = vdso_data_read_begin(data);
+
+               if (data->clock_mode == VDSO_CLOCK_NONE)
+                       return -ENOSYS;
+
+               ts->tv_sec = data->xtime_sec;
+               ns = get_ns(data);
+
+               to_mono_sec = data->wall_to_mono_sec;
+               to_mono_nsec = data->wall_to_mono_nsec;
+       } while (vdso_data_read_retry(data, start_seq));
+
+       ts->tv_sec += to_mono_sec;
+       ts->tv_nsec = 0;
+       timespec_add_ns(ts, ns + to_mono_nsec);
+
+       return 0;
+}
+
+#ifdef CONFIG_MIPS_CLOCK_VSYSCALL
+
+/*
+ * This is behind the ifdef so that we don't provide the symbol when there's no
+ * possibility of there being a usable clocksource, because there's nothing we
+ * can do without it. When libc fails the symbol lookup it should fall back on
+ * the standard syscall path.
+ */
+int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz)
+{
+       const union mips_vdso_data *data = get_vdso_data();
+       struct timespec ts;
+       int ret;
+
+       ret = do_realtime(&ts, data);
+       if (ret)
+               return ret;
+
+       if (tv) {
+               tv->tv_sec = ts.tv_sec;
+               tv->tv_usec = ts.tv_nsec / 1000;
+       }
+
+       if (tz) {
+               tz->tz_minuteswest = data->tz_minuteswest;
+               tz->tz_dsttime = data->tz_dsttime;
+       }
+
+       return 0;
+}
+
+#endif /* CONFIG_CLKSRC_MIPS_GIC */
+
+int __vdso_clock_gettime(clockid_t clkid, struct timespec *ts)
+{
+       const union mips_vdso_data *data = get_vdso_data();
+       int ret;
+
+       switch (clkid) {
+       case CLOCK_REALTIME_COARSE:
+               ret = do_realtime_coarse(ts, data);
+               break;
+       case CLOCK_MONOTONIC_COARSE:
+               ret = do_monotonic_coarse(ts, data);
+               break;
+       case CLOCK_REALTIME:
+               ret = do_realtime(ts, data);
+               break;
+       case CLOCK_MONOTONIC:
+               ret = do_monotonic(ts, data);
+               break;
+       default:
+               ret = -ENOSYS;
+               break;
+       }
+
+       /* If we return -ENOSYS libc should fall back to a syscall. */
+       return ret;
+}
diff --git a/arch/mips/vdso/sigreturn.S b/arch/mips/vdso/sigreturn.S
new file mode 100644 (file)
index 0000000..715bf59
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Alex Smith <alex.smith@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include "vdso.h"
+
+#include <uapi/asm/unistd.h>
+
+#include <asm/regdef.h>
+#include <asm/asm.h>
+
+       .section        .text
+       .cfi_sections   .debug_frame
+
+LEAF(__vdso_rt_sigreturn)
+       .cfi_startproc
+       .frame  sp, 0, ra
+       .mask   0x00000000, 0
+       .fmask  0x00000000, 0
+       .cfi_signal_frame
+
+       li      v0, __NR_rt_sigreturn
+       syscall
+
+       .cfi_endproc
+       END(__vdso_rt_sigreturn)
+
+#if _MIPS_SIM == _MIPS_SIM_ABI32
+
+LEAF(__vdso_sigreturn)
+       .cfi_startproc
+       .frame  sp, 0, ra
+       .mask   0x00000000, 0
+       .fmask  0x00000000, 0
+       .cfi_signal_frame
+
+       li      v0, __NR_sigreturn
+       syscall
+
+       .cfi_endproc
+       END(__vdso_sigreturn)
+
+#endif
diff --git a/arch/mips/vdso/vdso.h b/arch/mips/vdso/vdso.h
new file mode 100644 (file)
index 0000000..cfb1be4
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Alex Smith <alex.smith@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <asm/sgidefs.h>
+
+#if _MIPS_SIM != _MIPS_SIM_ABI64 && defined(CONFIG_64BIT)
+
+/* Building 32-bit VDSO for the 64-bit kernel. Fake a 32-bit Kconfig. */
+#undef CONFIG_64BIT
+#define CONFIG_32BIT 1
+#ifndef __ASSEMBLY__
+#include <asm-generic/atomic64.h>
+#endif
+#endif
+
+#ifndef __ASSEMBLY__
+
+#include <asm/asm.h>
+#include <asm/page.h>
+#include <asm/vdso.h>
+
+static inline unsigned long get_vdso_base(void)
+{
+       unsigned long addr;
+
+       /*
+        * We can't use cpu_has_mips_r6 since it needs the cpu_data[]
+        * kernel symbol.
+        */
+#ifdef CONFIG_CPU_MIPSR6
+       /*
+        * lapc <symbol> is an alias to addiupc reg, <symbol> - .
+        *
+        * We can't use addiupc because there is no label-label
+        * support for the addiupc reloc
+        */
+       __asm__("lapc   %0, _start                      \n"
+               : "=r" (addr) : :);
+#else
+       /*
+        * Get the base load address of the VDSO. We have to avoid generating
+        * relocations and references to the GOT because ld.so does not peform
+        * relocations on the VDSO. We use the current offset from the VDSO base
+        * and perform a PC-relative branch which gives the absolute address in
+        * ra, and take the difference. The assembler chokes on
+        * "li %0, _start - .", so embed the offset as a word and branch over
+        * it.
+        *
+        */
+
+       __asm__(
+       "       .set push                               \n"
+       "       .set noreorder                          \n"
+       "       bal     1f                              \n"
+       "        nop                                    \n"
+       "       .word   _start - .                      \n"
+       "1:     lw      %0, 0($31)                      \n"
+       "       " STR(PTR_ADDU) " %0, $31, %0           \n"
+       "       .set pop                                \n"
+       : "=r" (addr)
+       :
+       : "$31");
+#endif /* CONFIG_CPU_MIPSR6 */
+
+       return addr;
+}
+
+static inline const union mips_vdso_data *get_vdso_data(void)
+{
+       return (const union mips_vdso_data *)(get_vdso_base() - PAGE_SIZE);
+}
+
+#ifdef CONFIG_CLKSRC_MIPS_GIC
+
+static inline void __iomem *get_gic(const union mips_vdso_data *data)
+{
+       return (void __iomem *)data - PAGE_SIZE;
+}
+
+#endif /* CONFIG_CLKSRC_MIPS_GIC */
+
+#endif /* __ASSEMBLY__ */
diff --git a/arch/mips/vdso/vdso.lds.S b/arch/mips/vdso/vdso.lds.S
new file mode 100644 (file)
index 0000000..8df7dd5
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Alex Smith <alex.smith@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <asm/sgidefs.h>
+
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+OUTPUT_FORMAT("elf64-tradlittlemips", "elf64-tradbigmips", "elf64-tradlittlemips")
+#elif _MIPS_SIM == _MIPS_SIM_NABI32
+OUTPUT_FORMAT("elf32-ntradlittlemips", "elf32-ntradbigmips", "elf32-ntradlittlemips")
+#else
+OUTPUT_FORMAT("elf32-tradlittlemips", "elf32-tradbigmips", "elf32-tradlittlemips")
+#endif
+
+OUTPUT_ARCH(mips)
+
+SECTIONS
+{
+       PROVIDE(_start = .);
+       . = SIZEOF_HEADERS;
+
+       /*
+        * In order to retain compatibility with older toolchains we provide the
+        * ABI flags section ourself. Newer assemblers will automatically
+        * generate .MIPS.abiflags sections so we discard such input sections,
+        * and then manually define our own section here. genvdso will patch
+        * this section to have the correct name/type.
+        */
+       .mips_abiflags  : { *(.mips_abiflags) }         :text :abiflags
+
+       .reginfo        : { *(.reginfo) }               :text :reginfo
+
+       .hash           : { *(.hash) }                  :text
+       .gnu.hash       : { *(.gnu.hash) }
+       .dynsym         : { *(.dynsym) }
+       .dynstr         : { *(.dynstr) }
+       .gnu.version    : { *(.gnu.version) }
+       .gnu.version_d  : { *(.gnu.version_d) }
+       .gnu.version_r  : { *(.gnu.version_r) }
+
+       .note           : { *(.note.*) }                :text :note
+
+       .text           : { *(.text*) }                 :text
+       PROVIDE (__etext = .);
+       PROVIDE (_etext = .);
+       PROVIDE (etext = .);
+
+       .eh_frame_hdr   : { *(.eh_frame_hdr) }          :text :eh_frame_hdr
+       .eh_frame       : { KEEP (*(.eh_frame)) }       :text
+
+       .dynamic        : { *(.dynamic) }               :text :dynamic
+
+       .rodata         : { *(.rodata*) }               :text
+
+       _end = .;
+       PROVIDE(end = .);
+
+       /DISCARD/       : {
+               *(.MIPS.abiflags)
+               *(.gnu.attributes)
+               *(.note.GNU-stack)
+               *(.data .data.* .gnu.linkonce.d.* .sdata*)
+               *(.bss .sbss .dynbss .dynsbss)
+       }
+}
+
+PHDRS
+{
+       /*
+        * Provide a PT_MIPS_ABIFLAGS header to assign the ABI flags section
+        * to. We can specify the header type directly here so no modification
+        * is needed later on.
+        */
+       abiflags        0x70000003;
+
+       /*
+        * The ABI flags header must exist directly after the PT_INTERP header,
+        * so we must explicitly place the PT_MIPS_REGINFO header after it to
+        * stop the linker putting one in at the start.
+        */
+       reginfo         0x70000000;
+
+       text            PT_LOAD         FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */
+       dynamic         PT_DYNAMIC      FLAGS(4);               /* PF_R */
+       note            PT_NOTE         FLAGS(4);               /* PF_R */
+       eh_frame_hdr    PT_GNU_EH_FRAME;
+}
+
+VERSION
+{
+       LINUX_2.6 {
+#ifndef DISABLE_MIPS_VDSO
+       global:
+               __vdso_clock_gettime;
+               __vdso_gettimeofday;
+#endif
+       local: *;
+       };
+}
diff --git a/arch/mips/xilfpga/Kconfig b/arch/mips/xilfpga/Kconfig
new file mode 100644 (file)
index 0000000..42a030a
--- /dev/null
@@ -0,0 +1,9 @@
+choice
+       prompt "Machine type"
+       depends on MACH_XILFPGA
+       default XILFPGA_NEXYS4DDR
+
+config XILFPGA_NEXYS4DDR
+       bool "Nexys4DDR by Digilent"
+
+endchoice
diff --git a/arch/mips/xilfpga/Makefile b/arch/mips/xilfpga/Makefile
new file mode 100644 (file)
index 0000000..a4deec6
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# Makefile for the Xilfpga
+#
+
+obj-y +=       init.o
+obj-y +=       intc.o
+obj-y +=       time.o
diff --git a/arch/mips/xilfpga/Platform b/arch/mips/xilfpga/Platform
new file mode 100644 (file)
index 0000000..ed375af
--- /dev/null
@@ -0,0 +1,3 @@
+platform-$(CONFIG_MACH_XILFPGA) += xilfpga/
+cflags-$(CONFIG_MACH_XILFPGA) += -I$(srctree)/arch/mips/include/asm/mach-xilfpga
+load-$(CONFIG_MACH_XILFPGA) += 0xffffffff80100000
diff --git a/arch/mips/xilfpga/init.c b/arch/mips/xilfpga/init.c
new file mode 100644 (file)
index 0000000..ce2aee2
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Xilfpga platform setup
+ *
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.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.
+ */
+
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
+
+#include <asm/prom.h>
+
+#define XILFPGA_UART_BASE      0xb0401000
+
+const char *get_system_type(void)
+{
+       return "MIPSfpga";
+}
+
+void __init plat_mem_setup(void)
+{
+       __dt_setup_arch(__dtb_start);
+       strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
+}
+
+void __init prom_init(void)
+{
+       setup_8250_early_printk_port(XILFPGA_UART_BASE, 2, 50000);
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
+
+void __init device_tree_init(void)
+{
+       if (!initial_boot_params)
+               return;
+
+       unflatten_and_copy_device_tree();
+}
+
+static int __init plat_of_setup(void)
+{
+       if (!of_have_populated_dt())
+               panic("Device tree not present");
+
+       if (of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL))
+               panic("Failed to populate DT");
+
+       return 0;
+}
+arch_initcall(plat_of_setup);
diff --git a/arch/mips/xilfpga/intc.c b/arch/mips/xilfpga/intc.c
new file mode 100644 (file)
index 0000000..c4d1a71
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Xilfpga interrupt controller setup
+ *
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.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.
+ */
+
+#include <linux/of.h>
+#include <linux/of_irq.h>
+
+#include <asm/irq_cpu.h>
+
+static struct of_device_id of_irq_ids[] __initdata = {
+       { .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_irq_of_init },
+       {},
+};
+
+void __init arch_init_irq(void)
+{
+       of_irq_init(of_irq_ids);
+}
diff --git a/arch/mips/xilfpga/time.c b/arch/mips/xilfpga/time.c
new file mode 100644 (file)
index 0000000..cbb3fca
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Xilfpga clocksource/timer setup
+ *
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.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.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clocksource.h>
+#include <linux/of.h>
+
+#include <asm/time.h>
+
+void __init plat_time_init(void)
+{
+       struct device_node *np;
+       struct clk *clk;
+
+       of_clk_init(NULL);
+       clocksource_probe();
+
+       np = of_get_cpu_node(0, NULL);
+       if (!np) {
+               pr_err("Failed to get CPU node\n");
+               return;
+       }
+
+       clk = of_clk_get(np, 0);
+       if (IS_ERR(clk)) {
+               pr_err("Failed to get CPU clock: %ld\n", PTR_ERR(clk));
+               return;
+       }
+
+       mips_hpt_frequency = clk_get_rate(clk) / 2;
+       clk_put(clk);
+}
index 9c26c5a96ea2bc0ea9d2286f4995b2d629be9003..54b45b73195f912688ec4afe8e9fb4c9c3d5723c 100644 (file)
@@ -2019,7 +2019,7 @@ static bool can_split_piggybacked_subcores(struct core_info *cip)
                        return false;
                n_subcores += (cip->subcore_threads[sub] - 1) >> 1;
        }
-       if (n_subcores > 3 || large_sub < 0)
+       if (large_sub < 0 || !subcore_config_ok(n_subcores + 1, 2))
                return false;
 
        /*
index b1dab8d1d8850cdfcf92d4244e4c688d3d296341..3c6badcd53efced649af69ff9a4adf823b28d9a0 100644 (file)
@@ -1749,7 +1749,8 @@ kvmppc_hdsi:
        beq     3f
        clrrdi  r0, r4, 28
        PPC_SLBFEE_DOT(R5, R0)          /* if so, look up SLB */
-       bne     1f                      /* if no SLB entry found */
+       li      r0, BOOK3S_INTERRUPT_DATA_SEGMENT
+       bne     7f                      /* if no SLB entry found */
 4:     std     r4, VCPU_FAULT_DAR(r9)
        stw     r6, VCPU_FAULT_DSISR(r9)
 
@@ -1768,14 +1769,15 @@ kvmppc_hdsi:
        cmpdi   r3, -2                  /* MMIO emulation; need instr word */
        beq     2f
 
-       /* Synthesize a DSI for the guest */
+       /* Synthesize a DSI (or DSegI) for the guest */
        ld      r4, VCPU_FAULT_DAR(r9)
        mr      r6, r3
-1:     mtspr   SPRN_DAR, r4
+1:     li      r0, BOOK3S_INTERRUPT_DATA_STORAGE
        mtspr   SPRN_DSISR, r6
+7:     mtspr   SPRN_DAR, r4
        mtspr   SPRN_SRR0, r10
        mtspr   SPRN_SRR1, r11
-       li      r10, BOOK3S_INTERRUPT_DATA_STORAGE
+       mr      r10, r0
        bl      kvmppc_msr_interrupt
 fast_interrupt_c_return:
 6:     ld      r7, VCPU_CTR(r9)
@@ -1823,7 +1825,8 @@ kvmppc_hisi:
        beq     3f
        clrrdi  r0, r10, 28
        PPC_SLBFEE_DOT(R5, R0)          /* if so, look up SLB */
-       bne     1f                      /* if no SLB entry found */
+       li      r0, BOOK3S_INTERRUPT_INST_SEGMENT
+       bne     7f                      /* if no SLB entry found */
 4:
        /* Search the hash table. */
        mr      r3, r9                  /* vcpu pointer */
@@ -1840,11 +1843,12 @@ kvmppc_hisi:
        cmpdi   r3, -1                  /* handle in kernel mode */
        beq     guest_exit_cont
 
-       /* Synthesize an ISI for the guest */
+       /* Synthesize an ISI (or ISegI) for the guest */
        mr      r11, r3
-1:     mtspr   SPRN_SRR0, r10
+1:     li      r0, BOOK3S_INTERRUPT_INST_STORAGE
+7:     mtspr   SPRN_SRR0, r10
        mtspr   SPRN_SRR1, r11
-       li      r10, BOOK3S_INTERRUPT_INST_STORAGE
+       mr      r10, r0
        bl      kvmppc_msr_interrupt
        b       fast_interrupt_c_return
 
index 0c5d8ee657f06ecf8537f11ed93e4ecd6e04ee82..d1e7b0a0feeb72649ae71ab8413c7693d022e24c 100644 (file)
@@ -312,6 +312,7 @@ extern void css_schedule_reprobe(void);
 extern void reipl_ccw_dev(struct ccw_dev_id *id);
 
 struct cio_iplinfo {
+       u8 ssid;
        u16 devno;
        int is_qdio;
 };
index 3ad48f22de78c2d846254035c815a3c547d9a595..bab6739a1154e1fd9827ff8dfb5c152ef52f3930 100644 (file)
@@ -206,9 +206,16 @@ do {                                                               \
 } while (0)
 #endif /* CONFIG_COMPAT */
 
-extern unsigned long mmap_rnd_mask;
-
-#define STACK_RND_MASK (test_thread_flag(TIF_31BIT) ? 0x7ff : mmap_rnd_mask)
+/*
+ * Cache aliasing on the latest machines calls for a mapping granularity
+ * of 512KB. For 64-bit processes use a 512KB alignment and a randomization
+ * of up to 1GB. For 31-bit processes the virtual address space is limited,
+ * use no alignment and limit the randomization to 8MB.
+ */
+#define BRK_RND_MASK   (is_32bit_task() ? 0x7ffUL : 0x3ffffUL)
+#define MMAP_RND_MASK  (is_32bit_task() ? 0x7ffUL : 0x3ff80UL)
+#define MMAP_ALIGN_MASK        (is_32bit_task() ? 0 : 0x7fUL)
+#define STACK_RND_MASK MMAP_RND_MASK
 
 #define ARCH_DLINFO                                                        \
 do {                                                                       \
index 39ae6a3597478117e1c6328382e034a59b527c77..86634e71b69f4ec880c9c237d51b1626a69148b0 100644 (file)
@@ -64,7 +64,8 @@ struct ipl_block_fcp {
 
 struct ipl_block_ccw {
        u8  reserved1[84];
-       u8  reserved2[2];
+       u16 reserved2 : 13;
+       u8  ssid : 3;
        u16 devno;
        u8  vm_flags;
        u8  reserved3[3];
index 7a7abf1a5537242746b079bfb57dfe555a1e6b33..1aac41e83ea197121c5dd178c587323f9b875aa1 100644 (file)
@@ -195,5 +195,7 @@ void zpci_dma_exit_device(struct zpci_dev *);
 void dma_free_seg_table(unsigned long);
 unsigned long *dma_alloc_cpu_table(void);
 void dma_cleanup_tables(unsigned long *);
-void dma_update_cpu_trans(unsigned long *, void *, dma_addr_t, int);
+unsigned long *dma_walk_cpu_trans(unsigned long *rto, dma_addr_t dma_addr);
+void dma_update_cpu_trans(unsigned long *entry, void *page_addr, int flags);
+
 #endif
index 776f307960cc877a80edda1e41f5ed6f1d94a6c4..cc6cfe7889da5351057c1f036b5ca293a0f8bffa 100644 (file)
@@ -19,7 +19,7 @@
 #define TRACE_INCLUDE_PATH asm/trace
 #define TRACE_INCLUDE_FILE diag
 
-TRACE_EVENT(diagnose,
+TRACE_EVENT(s390_diagnose,
        TP_PROTO(unsigned short nr),
        TP_ARGS(nr),
        TP_STRUCT__entry(
@@ -32,9 +32,9 @@ TRACE_EVENT(diagnose,
 );
 
 #ifdef CONFIG_TRACEPOINTS
-void trace_diagnose_norecursion(int diag_nr);
+void trace_s390_diagnose_norecursion(int diag_nr);
 #else
-static inline void trace_diagnose_norecursion(int diag_nr) { }
+static inline void trace_s390_diagnose_norecursion(int diag_nr) { }
 #endif
 
 #endif /* _TRACE_S390_DIAG_H */
index a848adba1504a1c9b758d55ef3b44ee07bc74471..34ec202472c6cadb5b973b54c6c995bb6d2e897c 100644 (file)
 #define __NR_set_tid_address   252
 #define __NR_fadvise64         253
 #define __NR_timer_create      254
-#define __NR_timer_settime     (__NR_timer_create+1)
-#define __NR_timer_gettime     (__NR_timer_create+2)
-#define __NR_timer_getoverrun  (__NR_timer_create+3)
-#define __NR_timer_delete      (__NR_timer_create+4)
-#define __NR_clock_settime     (__NR_timer_create+5)
-#define __NR_clock_gettime     (__NR_timer_create+6)
-#define __NR_clock_getres      (__NR_timer_create+7)
-#define __NR_clock_nanosleep   (__NR_timer_create+8)
+#define __NR_timer_settime     255
+#define __NR_timer_gettime     256
+#define __NR_timer_getoverrun  257
+#define __NR_timer_delete      258
+#define __NR_clock_settime     259
+#define __NR_clock_gettime     260
+#define __NR_clock_getres      261
+#define __NR_clock_nanosleep   262
 /* Number 263 is reserved for vserver */
 #define __NR_statfs64          265
 #define __NR_fstatfs64         266
 #define __NR_recvfrom          371
 #define __NR_recvmsg           372
 #define __NR_shutdown          373
-#define NR_syscalls 374
+#define __NR_mlock2            374
+#define NR_syscalls 375
 
 /* 
  * There are some system calls that are not present on 64 bit, some
index 09f194052df35f712cff3fe8f44639df9de6c9e1..fac4eeddef91fe3acb21e0108069f3f3a70ef72a 100644 (file)
@@ -176,3 +176,4 @@ COMPAT_SYSCALL_WRAP4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr,
 COMPAT_SYSCALL_WRAP3(getsockname, int, fd, struct sockaddr __user *, usockaddr, int __user *, usockaddr_len);
 COMPAT_SYSCALL_WRAP3(getpeername, int, fd, struct sockaddr __user *, usockaddr, int __user *, usockaddr_len);
 COMPAT_SYSCALL_WRAP6(sendto, int, fd, void __user *, buff, size_t, len, unsigned int, flags, struct sockaddr __user *, addr, int, addr_len);
+COMPAT_SYSCALL_WRAP3(mlock2, unsigned long, start, size_t, len, int, flags);
index f98766ede4e156e83dc222194ed677150b891c64..48b37b8357e6838dd213f230eaaf274027193b74 100644 (file)
@@ -121,14 +121,14 @@ device_initcall(show_diag_stat_init);
 void diag_stat_inc(enum diag_stat_enum nr)
 {
        this_cpu_inc(diag_stat.counter[nr]);
-       trace_diagnose(diag_map[nr].code);
+       trace_s390_diagnose(diag_map[nr].code);
 }
 EXPORT_SYMBOL(diag_stat_inc);
 
 void diag_stat_inc_norecursion(enum diag_stat_enum nr)
 {
        this_cpu_inc(diag_stat.counter[nr]);
-       trace_diagnose_norecursion(diag_map[nr].code);
+       trace_s390_diagnose_norecursion(diag_map[nr].code);
 }
 EXPORT_SYMBOL(diag_stat_inc_norecursion);
 
index 1255c6c5353e2404f065545e557fe216e109b127..301ee9c70688b7ef35db09a62c9b8f3524ed5e68 100644 (file)
@@ -26,6 +26,7 @@
 #include <asm/asm-offsets.h>
 #include <asm/thread_info.h>
 #include <asm/page.h>
+#include <asm/ptrace.h>
 
 #define ARCH_OFFSET    4
 
@@ -59,19 +60,6 @@ __HEAD
        .long   0x020006e0,0x20000050
 
        .org    0x200
-#
-# subroutine to set architecture mode
-#
-.Lsetmode:
-       mvi     __LC_AR_MODE_ID,1       # set esame flag
-       slr     %r0,%r0                 # set cpuid to zero
-       lhi     %r1,2                   # mode 2 = esame (dump)
-       sigp    %r1,%r0,0x12            # switch to esame mode
-       bras    %r13,0f
-       .fill   16,4,0x0
-0:     lmh     %r0,%r15,0(%r13)        # clear high-order half of gprs
-       sam31                           # switch to 31 bit addressing mode
-       br      %r14
 
 #
 # subroutine to wait for end I/O
@@ -159,7 +147,14 @@ __HEAD
        .long   0x02200050,0x00000000
 
 iplstart:
-       bas     %r14,.Lsetmode          # Immediately switch to 64 bit mode
+       mvi     __LC_AR_MODE_ID,1       # set esame flag
+       slr     %r0,%r0                 # set cpuid to zero
+       lhi     %r1,2                   # mode 2 = esame (dump)
+       sigp    %r1,%r0,0x12            # switch to esame mode
+       bras    %r13,0f
+       .fill   16,4,0x0
+0:     lmh     %r0,%r15,0(%r13)        # clear high-order half of gprs
+       sam31                           # switch to 31 bit addressing mode
        lh      %r1,0xb8                # test if subchannel number
        bct     %r1,.Lnoload            #  is valid
        l       %r1,0xb8                # load ipl subchannel number
@@ -268,71 +263,6 @@ iplstart:
        .align  8
 .Lcpuid:.fill  8,1,0
 
-#
-# SALIPL loader support. Based on a patch by Rob van der Heij.
-# This entry point is called directly from the SALIPL loader and
-# doesn't need a builtin ipl record.
-#
-       .org    0x800
-ENTRY(start)
-       stm     %r0,%r15,0x07b0         # store registers
-       bas     %r14,.Lsetmode          # Immediately switch to 64 bit mode
-       basr    %r12,%r0
-.base:
-       l       %r11,.parm
-       l       %r8,.cmd                # pointer to command buffer
-
-       ltr     %r9,%r9                 # do we have SALIPL parameters?
-       bp      .sk8x8
-
-       mvc     0(64,%r8),0x00b0        # copy saved registers
-       xc      64(240-64,%r8),0(%r8)   # remainder of buffer
-       tr      0(64,%r8),.lowcase
-       b       .gotr
-.sk8x8:
-       mvc     0(240,%r8),0(%r9)       # copy iplparms into buffer
-.gotr:
-       slr     %r0,%r0
-       st      %r0,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r11)
-       st      %r0,INITRD_START+ARCH_OFFSET-PARMAREA(%r11)
-       j       startup                 # continue with startup
-.cmd:  .long   COMMAND_LINE            # address of command line buffer
-.parm: .long   PARMAREA
-.lowcase:
-       .byte 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07
-       .byte 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
-       .byte 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17
-       .byte 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f
-       .byte 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27
-       .byte 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f
-       .byte 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37
-       .byte 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f
-       .byte 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47
-       .byte 0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f
-       .byte 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57
-       .byte 0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f
-       .byte 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67
-       .byte 0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f
-       .byte 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77
-       .byte 0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f
-
-       .byte 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87
-       .byte 0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f
-       .byte 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97
-       .byte 0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f
-       .byte 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7
-       .byte 0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf
-       .byte 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7
-       .byte 0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf
-       .byte 0xc0,0x81,0x82,0x83,0x84,0x85,0x86,0x87   # .abcdefg
-       .byte 0x88,0x89,0xca,0xcb,0xcc,0xcd,0xce,0xcf   # hi
-       .byte 0xd0,0x91,0x92,0x93,0x94,0x95,0x96,0x97   # .jklmnop
-       .byte 0x98,0x99,0xda,0xdb,0xdc,0xdd,0xde,0xdf   # qr
-       .byte 0xe0,0xe1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7   # ..stuvwx
-       .byte 0xa8,0xa9,0xea,0xeb,0xec,0xed,0xee,0xef   # yz
-       .byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7
-       .byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
-
 #
 # startup-code at 0x10000, running in absolute addressing mode
 # this is called either by the ipl loader or directly by PSW restart
@@ -364,7 +294,7 @@ ENTRY(startup_kdump)
        bras    %r13,0f
        .fill   16,4,0x0
 0:     lmh     %r0,%r15,0(%r13)        # clear high-order half of gprs
-       sam31                           # switch to 31 bit addressing mode
+       sam64                           # switch to 64 bit addressing mode
        basr    %r13,0                  # get base
 .LPG0:
        xc      0x200(256),0x200        # partially clear lowcore
@@ -395,7 +325,7 @@ ENTRY(startup_kdump)
        jnz     1b
        j       4f
 2:     l       %r15,.Lstack-.LPG0(%r13)
-       ahi     %r15,-96
+       ahi     %r15,-STACK_FRAME_OVERHEAD
        la      %r2,.Lals_string-.LPG0(%r13)
        l       %r3,.Lsclp_print-.LPG0(%r13)
        basr    %r14,%r3
@@ -429,8 +359,7 @@ ENTRY(startup_kdump)
        .long 1, 0xc0000000
 #endif
 4:
-       /* Continue with 64bit startup code in head64.S */
-       sam64                           # switch to 64 bit mode
+       /* Continue with startup code in head64.S */
        jg      startup_continue
 
        .align  8
index f6d8acd7e13654c307a5d54e80bd6e084cf04a13..b1f0a90f933bbc95cc04c9e028d87865555909a9 100644 (file)
@@ -121,6 +121,7 @@ static char *dump_type_str(enum dump_type type)
  * Must be in data section since the bss section
  * is not cleared when these are accessed.
  */
+static u8 ipl_ssid __attribute__((__section__(".data"))) = 0;
 static u16 ipl_devno __attribute__((__section__(".data"))) = 0;
 u32 ipl_flags __attribute__((__section__(".data"))) = 0;
 
@@ -197,6 +198,33 @@ static ssize_t sys_##_prefix##_##_name##_show(struct kobject *kobj,        \
        return snprintf(page, PAGE_SIZE, _format, ##args);              \
 }
 
+#define IPL_ATTR_CCW_STORE_FN(_prefix, _name, _ipl_blk)                        \
+static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj,   \
+               struct kobj_attribute *attr,                            \
+               const char *buf, size_t len)                            \
+{                                                                      \
+       unsigned long long ssid, devno;                                 \
+                                                                       \
+       if (sscanf(buf, "0.%llx.%llx\n", &ssid, &devno) != 2)           \
+               return -EINVAL;                                         \
+                                                                       \
+       if (ssid > __MAX_SSID || devno > __MAX_SUBCHANNEL)              \
+               return -EINVAL;                                         \
+                                                                       \
+       _ipl_blk.ssid = ssid;                                           \
+       _ipl_blk.devno = devno;                                         \
+       return len;                                                     \
+}
+
+#define DEFINE_IPL_CCW_ATTR_RW(_prefix, _name, _ipl_blk)               \
+IPL_ATTR_SHOW_FN(_prefix, _name, "0.%x.%04x\n",                                \
+                _ipl_blk.ssid, _ipl_blk.devno);                        \
+IPL_ATTR_CCW_STORE_FN(_prefix, _name, _ipl_blk);                       \
+static struct kobj_attribute sys_##_prefix##_##_name##_attr =          \
+       __ATTR(_name, (S_IRUGO | S_IWUSR),                              \
+              sys_##_prefix##_##_name##_show,                          \
+              sys_##_prefix##_##_name##_store)                         \
+
 #define DEFINE_IPL_ATTR_RO(_prefix, _name, _format, _value)            \
 IPL_ATTR_SHOW_FN(_prefix, _name, _format, _value)                      \
 static struct kobj_attribute sys_##_prefix##_##_name##_attr =          \
@@ -395,7 +423,7 @@ static ssize_t sys_ipl_device_show(struct kobject *kobj,
 
        switch (ipl_info.type) {
        case IPL_TYPE_CCW:
-               return sprintf(page, "0.0.%04x\n", ipl_devno);
+               return sprintf(page, "0.%x.%04x\n", ipl_ssid, ipl_devno);
        case IPL_TYPE_FCP:
        case IPL_TYPE_FCP_DUMP:
                return sprintf(page, "0.0.%04x\n", ipl->ipl_info.fcp.devno);
@@ -687,21 +715,14 @@ static ssize_t reipl_fcp_scpdata_write(struct file *filp, struct kobject *kobj,
                                       struct bin_attribute *attr,
                                       char *buf, loff_t off, size_t count)
 {
+       size_t scpdata_len = count;
        size_t padding;
-       size_t scpdata_len;
-
-       if (off < 0)
-               return -EINVAL;
 
-       if (off >= DIAG308_SCPDATA_SIZE)
-               return -ENOSPC;
 
-       if (count > DIAG308_SCPDATA_SIZE - off)
-               count = DIAG308_SCPDATA_SIZE - off;
-
-       memcpy(reipl_block_fcp->ipl_info.fcp.scp_data, buf + off, count);
-       scpdata_len = off + count;
+       if (off)
+               return -EINVAL;
 
+       memcpy(reipl_block_fcp->ipl_info.fcp.scp_data, buf, count);
        if (scpdata_len % 8) {
                padding = 8 - (scpdata_len % 8);
                memset(reipl_block_fcp->ipl_info.fcp.scp_data + scpdata_len,
@@ -717,7 +738,7 @@ static ssize_t reipl_fcp_scpdata_write(struct file *filp, struct kobject *kobj,
 }
 static struct bin_attribute sys_reipl_fcp_scp_data_attr =
        __BIN_ATTR(scp_data, (S_IRUGO | S_IWUSR), reipl_fcp_scpdata_read,
-                  reipl_fcp_scpdata_write, PAGE_SIZE);
+                  reipl_fcp_scpdata_write, DIAG308_SCPDATA_SIZE);
 
 static struct bin_attribute *reipl_fcp_bin_attrs[] = {
        &sys_reipl_fcp_scp_data_attr,
@@ -814,9 +835,7 @@ static struct attribute_group reipl_fcp_attr_group = {
 };
 
 /* CCW reipl device attributes */
-
-DEFINE_IPL_ATTR_RW(reipl_ccw, device, "0.0.%04llx\n", "0.0.%llx\n",
-       reipl_block_ccw->ipl_info.ccw.devno);
+DEFINE_IPL_CCW_ATTR_RW(reipl_ccw, device, reipl_block_ccw->ipl_info.ccw);
 
 /* NSS wrapper */
 static ssize_t reipl_nss_loadparm_show(struct kobject *kobj,
@@ -1056,8 +1075,8 @@ static void __reipl_run(void *unused)
 
        switch (reipl_method) {
        case REIPL_METHOD_CCW_CIO:
+               devid.ssid  = reipl_block_ccw->ipl_info.ccw.ssid;
                devid.devno = reipl_block_ccw->ipl_info.ccw.devno;
-               devid.ssid  = 0;
                reipl_ccw_dev(&devid);
                break;
        case REIPL_METHOD_CCW_VM:
@@ -1192,6 +1211,7 @@ static int __init reipl_ccw_init(void)
 
        reipl_block_ccw_init(reipl_block_ccw);
        if (ipl_info.type == IPL_TYPE_CCW) {
+               reipl_block_ccw->ipl_info.ccw.ssid = ipl_ssid;
                reipl_block_ccw->ipl_info.ccw.devno = ipl_devno;
                reipl_block_ccw_fill_parms(reipl_block_ccw);
        }
@@ -1336,9 +1356,7 @@ static struct attribute_group dump_fcp_attr_group = {
 };
 
 /* CCW dump device attributes */
-
-DEFINE_IPL_ATTR_RW(dump_ccw, device, "0.0.%04llx\n", "0.0.%llx\n",
-                  dump_block_ccw->ipl_info.ccw.devno);
+DEFINE_IPL_CCW_ATTR_RW(dump_ccw, device, dump_block_ccw->ipl_info.ccw);
 
 static struct attribute *dump_ccw_attrs[] = {
        &sys_dump_ccw_device_attr.attr,
@@ -1418,8 +1436,8 @@ static void __dump_run(void *unused)
 
        switch (dump_method) {
        case DUMP_METHOD_CCW_CIO:
+               devid.ssid  = dump_block_ccw->ipl_info.ccw.ssid;
                devid.devno = dump_block_ccw->ipl_info.ccw.devno;
-               devid.ssid  = 0;
                reipl_ccw_dev(&devid);
                break;
        case DUMP_METHOD_CCW_VM:
@@ -1939,14 +1957,14 @@ void __init setup_ipl(void)
        ipl_info.type = get_ipl_type();
        switch (ipl_info.type) {
        case IPL_TYPE_CCW:
+               ipl_info.data.ccw.dev_id.ssid = ipl_ssid;
                ipl_info.data.ccw.dev_id.devno = ipl_devno;
-               ipl_info.data.ccw.dev_id.ssid = 0;
                break;
        case IPL_TYPE_FCP:
        case IPL_TYPE_FCP_DUMP:
+               ipl_info.data.fcp.dev_id.ssid = 0;
                ipl_info.data.fcp.dev_id.devno =
                        IPL_PARMBLOCK_START->ipl_info.fcp.devno;
-               ipl_info.data.fcp.dev_id.ssid = 0;
                ipl_info.data.fcp.wwpn = IPL_PARMBLOCK_START->ipl_info.fcp.wwpn;
                ipl_info.data.fcp.lun = IPL_PARMBLOCK_START->ipl_info.fcp.lun;
                break;
@@ -1978,6 +1996,7 @@ void __init ipl_save_parameters(void)
        if (cio_get_iplinfo(&iplinfo))
                return;
 
+       ipl_ssid = iplinfo.ssid;
        ipl_devno = iplinfo.devno;
        ipl_flags |= IPL_DEVNO_VALID;
        if (!iplinfo.is_qdio)
index 688a3aad9c79d02a49702f729c3b418065c982e3..114ee8b96f17d31d5dba657c704bc34a2e1b9a9e 100644 (file)
@@ -243,11 +243,7 @@ unsigned long arch_align_stack(unsigned long sp)
 
 static inline unsigned long brk_rnd(void)
 {
-       /* 8MB for 32bit, 1GB for 64bit */
-       if (is_32bit_task())
-               return (get_random_int() & 0x7ffUL) << PAGE_SHIFT;
-       else
-               return (get_random_int() & 0x3ffffUL) << PAGE_SHIFT;
+       return (get_random_int() & BRK_RND_MASK) << PAGE_SHIFT;
 }
 
 unsigned long arch_randomize_brk(struct mm_struct *mm)
index fa0bdff1d41305cb61fdc160d381a509ec4a53b7..9fe7781a45cdd7717e4a65af365f1a24d69812da 100644 (file)
@@ -21,7 +21,7 @@ static void _sclp_wait_int(void)
        __ctl_load(cr0_new, 0, 0);
 
        psw_ext_save = S390_lowcore.external_new_psw;
-       psw_mask = __extract_psw() & (PSW_MASK_EA | PSW_MASK_BA);
+       psw_mask = __extract_psw();
        S390_lowcore.external_new_psw.mask = psw_mask;
        psw_wait.mask = psw_mask | PSW_MASK_EXT | PSW_MASK_WAIT;
        S390_lowcore.ext_int_code = 0;
index ce0cbd6ba7ca9e5a8ca4b0cf05b37ea2a1e5dcc0..c837bcacf2188460a50754f3a75d1b485c25f671 100644 (file)
@@ -764,9 +764,6 @@ static int __init setup_hwcaps(void)
        get_cpu_id(&cpu_id);
        add_device_randomness(&cpu_id, sizeof(cpu_id));
        switch (cpu_id.machine) {
-       case 0x9672:
-               strcpy(elf_platform, "g5");
-               break;
        case 0x2064:
        case 0x2066:
        default:        /* Use "z900" as default for 64 bit kernels. */
index 8c56929c8d826e09ccd3620454b813101cb319e7..5378c3ea1b984918ed3719c8a9cf8d1c8c86574a 100644 (file)
@@ -382,3 +382,4 @@ SYSCALL(sys_sendmsg,compat_sys_sendmsg)                     /* 370 */
 SYSCALL(sys_recvfrom,compat_sys_recvfrom)
 SYSCALL(sys_recvmsg,compat_sys_recvmsg)
 SYSCALL(sys_shutdown,sys_shutdown)
+SYSCALL(sys_mlock2,compat_sys_mlock2)
index 73239bb576c4ee8aaa69b232cdea0cbbd7f91fd0..21a5df99552bce6e4f84c872acdda43e6c5732c3 100644 (file)
@@ -9,11 +9,11 @@
 #define CREATE_TRACE_POINTS
 #include <asm/trace/diag.h>
 
-EXPORT_TRACEPOINT_SYMBOL(diagnose);
+EXPORT_TRACEPOINT_SYMBOL(s390_diagnose);
 
 static DEFINE_PER_CPU(unsigned int, diagnose_trace_depth);
 
-void trace_diagnose_norecursion(int diag_nr)
+void trace_s390_diagnose_norecursion(int diag_nr)
 {
        unsigned long flags;
        unsigned int *depth;
@@ -22,7 +22,7 @@ void trace_diagnose_norecursion(int diag_nr)
        depth = this_cpu_ptr(&diagnose_trace_depth);
        if (*depth == 0) {
                (*depth)++;
-               trace_diagnose(diag_nr);
+               trace_s390_diagnose(diag_nr);
                (*depth)--;
        }
        local_irq_restore(flags);
index c3c07d3505ba17ebe953d4310508abeb6b63fba1..c722400c769784d8df6f13507693e117ad942497 100644 (file)
@@ -48,37 +48,13 @@ EXPORT_SYMBOL(zero_page_mask);
 
 static void __init setup_zero_pages(void)
 {
-       struct cpuid cpu_id;
        unsigned int order;
        struct page *page;
        int i;
 
-       get_cpu_id(&cpu_id);
-       switch (cpu_id.machine) {
-       case 0x9672:    /* g5 */
-       case 0x2064:    /* z900 */
-       case 0x2066:    /* z900 */
-       case 0x2084:    /* z990 */
-       case 0x2086:    /* z990 */
-       case 0x2094:    /* z9-109 */
-       case 0x2096:    /* z9-109 */
-               order = 0;
-               break;
-       case 0x2097:    /* z10 */
-       case 0x2098:    /* z10 */
-       case 0x2817:    /* z196 */
-       case 0x2818:    /* z196 */
-               order = 2;
-               break;
-       case 0x2827:    /* zEC12 */
-       case 0x2828:    /* zEC12 */
-               order = 5;
-               break;
-       case 0x2964:    /* z13 */
-       default:
-               order = 7;
-               break;
-       }
+       /* Latest machines require a mapping granularity of 512KB */
+       order = 7;
+
        /* Limit number of empty zero pages for small memory sizes */
        while (order > 2 && (totalram_pages >> 10) < (1UL << order))
                order--;
index 6e552af08c76a61027c023f7305133ee1b4efe02..ea01477b4aa67155f87b88e8c6a87f5374eda247 100644 (file)
@@ -31,9 +31,6 @@
 #include <linux/security.h>
 #include <asm/pgalloc.h>
 
-unsigned long mmap_rnd_mask;
-static unsigned long mmap_align_mask;
-
 static unsigned long stack_maxrandom_size(void)
 {
        if (!(current->flags & PF_RANDOMIZE))
@@ -62,10 +59,7 @@ static inline int mmap_is_legacy(void)
 
 unsigned long arch_mmap_rnd(void)
 {
-       if (is_32bit_task())
-               return (get_random_int() & 0x7ff) << PAGE_SHIFT;
-       else
-               return (get_random_int() & mmap_rnd_mask) << PAGE_SHIFT;
+       return (get_random_int() & MMAP_RND_MASK) << PAGE_SHIFT;
 }
 
 static unsigned long mmap_base_legacy(unsigned long rnd)
@@ -92,7 +86,6 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
        struct mm_struct *mm = current->mm;
        struct vm_area_struct *vma;
        struct vm_unmapped_area_info info;
-       int do_color_align;
 
        if (len > TASK_SIZE - mmap_min_addr)
                return -ENOMEM;
@@ -108,15 +101,14 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
                        return addr;
        }
 
-       do_color_align = 0;
-       if (filp || (flags & MAP_SHARED))
-               do_color_align = !is_32bit_task();
-
        info.flags = 0;
        info.length = len;
        info.low_limit = mm->mmap_base;
        info.high_limit = TASK_SIZE;
-       info.align_mask = do_color_align ? (mmap_align_mask << PAGE_SHIFT) : 0;
+       if (filp || (flags & MAP_SHARED))
+               info.align_mask = MMAP_ALIGN_MASK << PAGE_SHIFT;
+       else
+               info.align_mask = 0;
        info.align_offset = pgoff << PAGE_SHIFT;
        return vm_unmapped_area(&info);
 }
@@ -130,7 +122,6 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
        struct mm_struct *mm = current->mm;
        unsigned long addr = addr0;
        struct vm_unmapped_area_info info;
-       int do_color_align;
 
        /* requested length too big for entire address space */
        if (len > TASK_SIZE - mmap_min_addr)
@@ -148,15 +139,14 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
                        return addr;
        }
 
-       do_color_align = 0;
-       if (filp || (flags & MAP_SHARED))
-               do_color_align = !is_32bit_task();
-
        info.flags = VM_UNMAPPED_AREA_TOPDOWN;
        info.length = len;
        info.low_limit = max(PAGE_SIZE, mmap_min_addr);
        info.high_limit = mm->mmap_base;
-       info.align_mask = do_color_align ? (mmap_align_mask << PAGE_SHIFT) : 0;
+       if (filp || (flags & MAP_SHARED))
+               info.align_mask = MMAP_ALIGN_MASK << PAGE_SHIFT;
+       else
+               info.align_mask = 0;
        info.align_offset = pgoff << PAGE_SHIFT;
        addr = vm_unmapped_area(&info);
 
@@ -254,35 +244,3 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
                mm->get_unmapped_area = s390_get_unmapped_area_topdown;
        }
 }
-
-static int __init setup_mmap_rnd(void)
-{
-       struct cpuid cpu_id;
-
-       get_cpu_id(&cpu_id);
-       switch (cpu_id.machine) {
-       case 0x9672:
-       case 0x2064:
-       case 0x2066:
-       case 0x2084:
-       case 0x2086:
-       case 0x2094:
-       case 0x2096:
-       case 0x2097:
-       case 0x2098:
-       case 0x2817:
-       case 0x2818:
-       case 0x2827:
-       case 0x2828:
-               mmap_rnd_mask = 0x7ffUL;
-               mmap_align_mask = 0UL;
-               break;
-       case 0x2964:    /* z13 */
-       default:
-               mmap_rnd_mask = 0x3ff80UL;
-               mmap_align_mask = 0x7fUL;
-               break;
-       }
-       return 0;
-}
-early_initcall(setup_mmap_rnd);
index 37d10f74425a453202ae11e232d361404e9e68c2..d348f2c09a1eede659378cf4ae2686df008e4bd8 100644 (file)
@@ -33,7 +33,7 @@ unsigned long *dma_alloc_cpu_table(void)
                return NULL;
 
        for (entry = table; entry < table + ZPCI_TABLE_ENTRIES; entry++)
-               *entry = ZPCI_TABLE_INVALID | ZPCI_TABLE_PROTECTED;
+               *entry = ZPCI_TABLE_INVALID;
        return table;
 }
 
@@ -51,7 +51,7 @@ static unsigned long *dma_alloc_page_table(void)
                return NULL;
 
        for (entry = table; entry < table + ZPCI_PT_ENTRIES; entry++)
-               *entry = ZPCI_PTE_INVALID | ZPCI_TABLE_PROTECTED;
+               *entry = ZPCI_PTE_INVALID;
        return table;
 }
 
@@ -95,7 +95,7 @@ static unsigned long *dma_get_page_table_origin(unsigned long *entry)
        return pto;
 }
 
-static unsigned long *dma_walk_cpu_trans(unsigned long *rto, dma_addr_t dma_addr)
+unsigned long *dma_walk_cpu_trans(unsigned long *rto, dma_addr_t dma_addr)
 {
        unsigned long *sto, *pto;
        unsigned int rtx, sx, px;
@@ -114,20 +114,10 @@ static unsigned long *dma_walk_cpu_trans(unsigned long *rto, dma_addr_t dma_addr
        return &pto[px];
 }
 
-void dma_update_cpu_trans(unsigned long *dma_table, void *page_addr,
-                         dma_addr_t dma_addr, int flags)
+void dma_update_cpu_trans(unsigned long *entry, void *page_addr, int flags)
 {
-       unsigned long *entry;
-
-       entry = dma_walk_cpu_trans(dma_table, dma_addr);
-       if (!entry) {
-               WARN_ON_ONCE(1);
-               return;
-       }
-
        if (flags & ZPCI_PTE_INVALID) {
                invalidate_pt_entry(entry);
-               return;
        } else {
                set_pt_pfaa(entry, page_addr);
                validate_pt_entry(entry);
@@ -146,18 +136,25 @@ static int dma_update_trans(struct zpci_dev *zdev, unsigned long pa,
        u8 *page_addr = (u8 *) (pa & PAGE_MASK);
        dma_addr_t start_dma_addr = dma_addr;
        unsigned long irq_flags;
+       unsigned long *entry;
        int i, rc = 0;
 
        if (!nr_pages)
                return -EINVAL;
 
        spin_lock_irqsave(&zdev->dma_table_lock, irq_flags);
-       if (!zdev->dma_table)
+       if (!zdev->dma_table) {
+               rc = -EINVAL;
                goto no_refresh;
+       }
 
        for (i = 0; i < nr_pages; i++) {
-               dma_update_cpu_trans(zdev->dma_table, page_addr, dma_addr,
-                                    flags);
+               entry = dma_walk_cpu_trans(zdev->dma_table, dma_addr);
+               if (!entry) {
+                       rc = -ENOMEM;
+                       goto undo_cpu_trans;
+               }
+               dma_update_cpu_trans(entry, page_addr, flags);
                page_addr += PAGE_SIZE;
                dma_addr += PAGE_SIZE;
        }
@@ -176,6 +173,18 @@ static int dma_update_trans(struct zpci_dev *zdev, unsigned long pa,
 
        rc = zpci_refresh_trans((u64) zdev->fh << 32, start_dma_addr,
                                nr_pages * PAGE_SIZE);
+undo_cpu_trans:
+       if (rc && ((flags & ZPCI_PTE_VALID_MASK) == ZPCI_PTE_VALID)) {
+               flags = ZPCI_PTE_INVALID;
+               while (i-- > 0) {
+                       page_addr -= PAGE_SIZE;
+                       dma_addr -= PAGE_SIZE;
+                       entry = dma_walk_cpu_trans(zdev->dma_table, dma_addr);
+                       if (!entry)
+                               break;
+                       dma_update_cpu_trans(entry, page_addr, flags);
+               }
+       }
 
 no_refresh:
        spin_unlock_irqrestore(&zdev->dma_table_lock, irq_flags);
@@ -260,6 +269,16 @@ out:
        spin_unlock_irqrestore(&zdev->iommu_bitmap_lock, flags);
 }
 
+static inline void zpci_err_dma(unsigned long rc, unsigned long addr)
+{
+       struct {
+               unsigned long rc;
+               unsigned long addr;
+       } __packed data = {rc, addr};
+
+       zpci_err_hex(&data, sizeof(data));
+}
+
 static dma_addr_t s390_dma_map_pages(struct device *dev, struct page *page,
                                     unsigned long offset, size_t size,
                                     enum dma_data_direction direction,
@@ -270,33 +289,40 @@ static dma_addr_t s390_dma_map_pages(struct device *dev, struct page *page,
        unsigned long pa = page_to_phys(page) + offset;
        int flags = ZPCI_PTE_VALID;
        dma_addr_t dma_addr;
+       int ret;
 
        /* This rounds up number of pages based on size and offset */
        nr_pages = iommu_num_pages(pa, size, PAGE_SIZE);
        iommu_page_index = dma_alloc_iommu(zdev, nr_pages);
-       if (iommu_page_index == -1)
+       if (iommu_page_index == -1) {
+               ret = -ENOSPC;
                goto out_err;
+       }
 
        /* Use rounded up size */
        size = nr_pages * PAGE_SIZE;
 
        dma_addr = zdev->start_dma + iommu_page_index * PAGE_SIZE;
-       if (dma_addr + size > zdev->end_dma)
+       if (dma_addr + size > zdev->end_dma) {
+               ret = -ERANGE;
                goto out_free;
+       }
 
        if (direction == DMA_NONE || direction == DMA_TO_DEVICE)
                flags |= ZPCI_TABLE_PROTECTED;
 
-       if (!dma_update_trans(zdev, pa, dma_addr, size, flags)) {
-               atomic64_add(nr_pages, &zdev->mapped_pages);
-               return dma_addr + (offset & ~PAGE_MASK);
-       }
+       ret = dma_update_trans(zdev, pa, dma_addr, size, flags);
+       if (ret)
+               goto out_free;
+
+       atomic64_add(nr_pages, &zdev->mapped_pages);
+       return dma_addr + (offset & ~PAGE_MASK);
 
 out_free:
        dma_free_iommu(zdev, iommu_page_index, nr_pages);
 out_err:
        zpci_err("map error:\n");
-       zpci_err_hex(&pa, sizeof(pa));
+       zpci_err_dma(ret, pa);
        return DMA_ERROR_CODE;
 }
 
@@ -306,14 +332,16 @@ static void s390_dma_unmap_pages(struct device *dev, dma_addr_t dma_addr,
 {
        struct zpci_dev *zdev = to_zpci(to_pci_dev(dev));
        unsigned long iommu_page_index;
-       int npages;
+       int npages, ret;
 
        npages = iommu_num_pages(dma_addr, size, PAGE_SIZE);
        dma_addr = dma_addr & PAGE_MASK;
-       if (dma_update_trans(zdev, 0, dma_addr, npages * PAGE_SIZE,
-                            ZPCI_TABLE_PROTECTED | ZPCI_PTE_INVALID)) {
+       ret = dma_update_trans(zdev, 0, dma_addr, npages * PAGE_SIZE,
+                              ZPCI_PTE_INVALID);
+       if (ret) {
                zpci_err("unmap error:\n");
-               zpci_err_hex(&dma_addr, sizeof(dma_addr));
+               zpci_err_dma(ret, dma_addr);
+               return;
        }
 
        atomic64_add(npages, &zdev->unmapped_pages);
index 46ebfdccbc316d6e27f674d44d8e6c8d6de687e1..aab5f341dec0efce5a2426505c1feff97b87275d 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/reboot.h>
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
+#include <linux/pwm.h>
 #include <linux/pwm_backlight.h>
 #include <linux/gpio.h>
 #include <linux/gpio_keys.h>
@@ -49,11 +50,14 @@ static struct resource puv3_i2c_resources[] = {
        }
 };
 
+static struct pwm_lookup nb0916_pwm_lookup[] = {
+       PWM_LOOKUP("PKUnity-v3-PWM", 0, "pwm-backlight", NULL, 70 * 1024,
+                  PWM_POLARITY_NORMAL),
+};
+
 static struct platform_pwm_backlight_data nb0916_backlight_data = {
-       .pwm_id         = 0,
        .max_brightness = 100,
        .dft_brightness = 100,
-       .pwm_period_ns  = 70 * 1024,
        .enable_gpio    = -1,
 };
 
@@ -112,6 +116,8 @@ int __init mach_nb0916_init(void)
        platform_device_register_simple("PKUnity-v3-I2C", -1,
                        puv3_i2c_resources, ARRAY_SIZE(puv3_i2c_resources));
 
+       pwm_add_table(nb0916_pwm_lookup, ARRAY_SIZE(nb0916_pwm_lookup));
+
        platform_device_register_data(NULL, "pwm-backlight", -1,
                        &nb0916_backlight_data, sizeof(nb0916_backlight_data));
 
index ccffa53750a89283feae5c1ea8b10f7e99cf57ea..39bcefc20de73d2d8a5693586204609f1cf70279 100644 (file)
@@ -60,6 +60,7 @@ struct legacy_pic {
        void (*mask_all)(void);
        void (*restore_mask)(void);
        void (*init)(int auto_eoi);
+       int (*probe)(void);
        int (*irq_pending)(unsigned int irq);
        void (*make_irq)(unsigned int irq);
 };
index 9265196e877f34d662ea56a8d5993dcb4349ea57..30cfd64295a0075ab9c4727721c0fc8c8b607f46 100644 (file)
@@ -505,6 +505,7 @@ struct kvm_vcpu_arch {
        u32 virtual_tsc_mult;
        u32 virtual_tsc_khz;
        s64 ia32_tsc_adjust_msr;
+       u64 tsc_scaling_ratio;
 
        atomic_t nmi_queued;  /* unprocessed asynchronous NMIs */
        unsigned nmi_pending; /* NMI queued after currently running handler */
@@ -777,7 +778,7 @@ struct kvm_x86_ops {
        void (*vcpu_load)(struct kvm_vcpu *vcpu, int cpu);
        void (*vcpu_put)(struct kvm_vcpu *vcpu);
 
-       void (*update_db_bp_intercept)(struct kvm_vcpu *vcpu);
+       void (*update_bp_intercept)(struct kvm_vcpu *vcpu);
        int (*get_msr)(struct kvm_vcpu *vcpu, struct msr_data *msr);
        int (*set_msr)(struct kvm_vcpu *vcpu, struct msr_data *msr);
        u64 (*get_segment_base)(struct kvm_vcpu *vcpu, int seg);
@@ -844,7 +845,7 @@ struct kvm_x86_ops {
        int (*get_lpage_level)(void);
        bool (*rdtscp_supported)(void);
        bool (*invpcid_supported)(void);
-       void (*adjust_tsc_offset)(struct kvm_vcpu *vcpu, s64 adjustment, bool host);
+       void (*adjust_tsc_offset_guest)(struct kvm_vcpu *vcpu, s64 adjustment);
 
        void (*set_tdp_cr3)(struct kvm_vcpu *vcpu, unsigned long cr3);
 
@@ -852,11 +853,9 @@ struct kvm_x86_ops {
 
        bool (*has_wbinvd_exit)(void);
 
-       void (*set_tsc_khz)(struct kvm_vcpu *vcpu, u32 user_tsc_khz, bool scale);
        u64 (*read_tsc_offset)(struct kvm_vcpu *vcpu);
        void (*write_tsc_offset)(struct kvm_vcpu *vcpu, u64 offset);
 
-       u64 (*compute_tsc_offset)(struct kvm_vcpu *vcpu, u64 target_tsc);
        u64 (*read_l1_tsc)(struct kvm_vcpu *vcpu, u64 host_tsc);
 
        void (*get_exit_info)(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2);
@@ -923,17 +922,6 @@ struct kvm_arch_async_pf {
 
 extern struct kvm_x86_ops *kvm_x86_ops;
 
-static inline void adjust_tsc_offset_guest(struct kvm_vcpu *vcpu,
-                                          s64 adjustment)
-{
-       kvm_x86_ops->adjust_tsc_offset(vcpu, adjustment, false);
-}
-
-static inline void adjust_tsc_offset_host(struct kvm_vcpu *vcpu, s64 adjustment)
-{
-       kvm_x86_ops->adjust_tsc_offset(vcpu, adjustment, true);
-}
-
 int kvm_mmu_module_init(void);
 void kvm_mmu_module_exit(void);
 
@@ -986,10 +974,12 @@ u64 vcpu_tsc_khz(struct kvm_vcpu *vcpu);
 
 /* control of guest tsc rate supported? */
 extern bool kvm_has_tsc_control;
-/* minimum supported tsc_khz for guests */
-extern u32  kvm_min_guest_tsc_khz;
 /* maximum supported tsc_khz for guests */
 extern u32  kvm_max_guest_tsc_khz;
+/* number of bits of the fractional part of the TSC scaling ratio */
+extern u8   kvm_tsc_scaling_ratio_frac_bits;
+/* maximum allowed value of TSC scaling ratio */
+extern u64  kvm_max_tsc_scaling_ratio;
 
 enum emulation_result {
        EMULATE_DONE,         /* no further processing */
@@ -1235,6 +1225,9 @@ void kvm_arch_mmu_notifier_invalidate_page(struct kvm *kvm,
 void kvm_define_shared_msr(unsigned index, u32 msr);
 int kvm_set_shared_msr(unsigned index, u64 val, u64 mask);
 
+u64 kvm_scale_tsc(struct kvm_vcpu *vcpu, u64 tsc);
+u64 kvm_read_l1_tsc(struct kvm_vcpu *vcpu, u64 host_tsc);
+
 unsigned long kvm_get_linear_rip(struct kvm_vcpu *vcpu);
 bool kvm_is_linear_rip(struct kvm_vcpu *vcpu, unsigned long linear_rip);
 
index aa336ff3e03ec9c0680f7599bb642f807c64b81b..14c63c7e8337a3d2bdfc98a5b4c14d2892de5580 100644 (file)
@@ -73,6 +73,7 @@
 #define SECONDARY_EXEC_ENABLE_PML               0x00020000
 #define SECONDARY_EXEC_XSAVES                  0x00100000
 #define SECONDARY_EXEC_PCOMMIT                 0x00200000
+#define SECONDARY_EXEC_TSC_SCALING              0x02000000
 
 #define PIN_BASED_EXT_INTR_MASK                 0x00000001
 #define PIN_BASED_NMI_EXITING                   0x00000008
@@ -167,6 +168,8 @@ enum vmcs_field {
        VMWRITE_BITMAP                  = 0x00002028,
        XSS_EXIT_BITMAP                 = 0x0000202C,
        XSS_EXIT_BITMAP_HIGH            = 0x0000202D,
+       TSC_MULTIPLIER                  = 0x00002032,
+       TSC_MULTIPLIER_HIGH             = 0x00002033,
        GUEST_PHYSICAL_ADDRESS          = 0x00002400,
        GUEST_PHYSICAL_ADDRESS_HIGH     = 0x00002401,
        VMCS_LINK_POINTER               = 0x00002800,
index b5d7640abc5d6172838a99569d144f8acc96763a..8a4add8e463932445ba071903378927f76912cfa 100644 (file)
        { SVM_EXIT_EXCP_BASE + UD_VECTOR,       "UD excp" }, \
        { SVM_EXIT_EXCP_BASE + PF_VECTOR,       "PF excp" }, \
        { SVM_EXIT_EXCP_BASE + NM_VECTOR,       "NM excp" }, \
+       { SVM_EXIT_EXCP_BASE + AC_VECTOR,       "AC excp" }, \
        { SVM_EXIT_EXCP_BASE + MC_VECTOR,       "MC excp" }, \
        { SVM_EXIT_INTR,        "interrupt" }, \
        { SVM_EXIT_NMI,         "nmi" }, \
index 836d11b92811ce73446a6081f02a38231fdb9429..861bc59c8f2564eac7b87193e7cd250571e1fbf4 100644 (file)
@@ -361,7 +361,11 @@ int __init arch_probe_nr_irqs(void)
        if (nr < nr_irqs)
                nr_irqs = nr;
 
-       return nr_legacy_irqs();
+       /*
+        * We don't know if PIC is present at this point so we need to do
+        * probe() to get the right number of legacy IRQs.
+        */
+       return legacy_pic->probe();
 }
 
 #ifdef CONFIG_X86_IO_APIC
index 4a70fc6d400adbd1e342f249baec98592a92509d..a8816b3251620c941f543e595e949aa60c43467d 100644 (file)
@@ -352,6 +352,7 @@ static void amd_detect_cmp(struct cpuinfo_x86 *c)
 #ifdef CONFIG_SMP
        unsigned bits;
        int cpu = smp_processor_id();
+       unsigned int socket_id, core_complex_id;
 
        bits = c->x86_coreid_bits;
        /* Low order bits define the core id (index of core in socket) */
@@ -361,6 +362,18 @@ static void amd_detect_cmp(struct cpuinfo_x86 *c)
        /* use socket ID also for last level cache */
        per_cpu(cpu_llc_id, cpu) = c->phys_proc_id;
        amd_get_topology(c);
+
+       /*
+        * Fix percpu cpu_llc_id here as LLC topology is different
+        * for Fam17h systems.
+        */
+        if (c->x86 != 0x17 || !cpuid_edx(0x80000006))
+               return;
+
+       socket_id       = (c->apicid >> bits) - 1;
+       core_complex_id = (c->apicid & ((1 << bits) - 1)) >> 3;
+
+       per_cpu(cpu_llc_id, cpu) = (socket_id << 3) | core_complex_id;
 #endif
 }
 
index 98a13db5f4be5826a47c8572f3f7f65950658270..209ac1e7d1f03664010955dea71d953f6a396b5b 100644 (file)
@@ -97,6 +97,7 @@ static void early_init_intel(struct cpuinfo_x86 *c)
                switch (c->x86_model) {
                case 0x27:      /* Penwell */
                case 0x35:      /* Cloverview */
+               case 0x4a:      /* Merrifield */
                        set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC_S3);
                        break;
                default:
index 81431c0f0614cbd3c31b946918e842adb24e5c79..ed446bdcbf312daa9587a593fc1552cda4714dd3 100644 (file)
@@ -107,12 +107,6 @@ static ssize_t __rapl_##_var##_show(struct kobject *kobj,  \
 static struct kobj_attribute format_attr_##_var =              \
        __ATTR(_name, 0444, __rapl_##_var##_show, NULL)
 
-#define RAPL_EVENT_DESC(_name, _config)                                \
-{                                                              \
-       .attr   = __ATTR(_name, 0444, rapl_event_show, NULL),   \
-       .config = _config,                                      \
-}
-
 #define RAPL_CNTR_WIDTH 32 /* 32-bit rapl counters */
 
 #define RAPL_EVENT_ATTR_STR(_name, v, str)                             \
index 1d40ca8a73f27231e49c35704794d0cbe6ca94dc..ffdc0e8603902b12b0cd44fd175d806b046ccb4b 100644 (file)
@@ -65,6 +65,9 @@ startup_64:
         * tables and then reload them.
         */
 
+       /* Sanitize CPU configuration */
+       call verify_cpu
+
        /*
         * Compute the delta between the address I am compiled to run at and the
         * address I am actually running at.
@@ -174,6 +177,9 @@ ENTRY(secondary_startup_64)
         * after the boot processor executes this code.
         */
 
+       /* Sanitize CPU configuration */
+       call verify_cpu
+
        movq    $(init_level4_pgt - __START_KERNEL_map), %rax
 1:
 
@@ -288,6 +294,8 @@ ENTRY(secondary_startup_64)
        pushq   %rax            # target address in negative space
        lretq
 
+#include "verify_cpu.S"
+
 #ifdef CONFIG_HOTPLUG_CPU
 /*
  * Boot CPU0 entry point. It's called from play_dead(). Everything has been set
index 16cb827a5b27745d1f571d49a5b45443babb2c8c..be22f5a2192e358153610ebdf95a823da1ea8e5f 100644 (file)
@@ -295,16 +295,11 @@ static void unmask_8259A(void)
        raw_spin_unlock_irqrestore(&i8259A_lock, flags);
 }
 
-static void init_8259A(int auto_eoi)
+static int probe_8259A(void)
 {
        unsigned long flags;
        unsigned char probe_val = ~(1 << PIC_CASCADE_IR);
        unsigned char new_val;
-
-       i8259A_auto_eoi = auto_eoi;
-
-       raw_spin_lock_irqsave(&i8259A_lock, flags);
-
        /*
         * Check to see if we have a PIC.
         * Mask all except the cascade and read
@@ -312,16 +307,28 @@ static void init_8259A(int auto_eoi)
         * have a PIC, we will read 0xff as opposed to the
         * value we wrote.
         */
+       raw_spin_lock_irqsave(&i8259A_lock, flags);
+
        outb(0xff, PIC_SLAVE_IMR);      /* mask all of 8259A-2 */
        outb(probe_val, PIC_MASTER_IMR);
        new_val = inb(PIC_MASTER_IMR);
        if (new_val != probe_val) {
                printk(KERN_INFO "Using NULL legacy PIC\n");
                legacy_pic = &null_legacy_pic;
-               raw_spin_unlock_irqrestore(&i8259A_lock, flags);
-               return;
        }
 
+       raw_spin_unlock_irqrestore(&i8259A_lock, flags);
+       return nr_legacy_irqs();
+}
+
+static void init_8259A(int auto_eoi)
+{
+       unsigned long flags;
+
+       i8259A_auto_eoi = auto_eoi;
+
+       raw_spin_lock_irqsave(&i8259A_lock, flags);
+
        outb(0xff, PIC_MASTER_IMR);     /* mask all of 8259A-1 */
 
        /*
@@ -379,6 +386,10 @@ static int legacy_pic_irq_pending_noop(unsigned int irq)
 {
        return 0;
 }
+static int legacy_pic_probe(void)
+{
+       return 0;
+}
 
 struct legacy_pic null_legacy_pic = {
        .nr_legacy_irqs = 0,
@@ -388,6 +399,7 @@ struct legacy_pic null_legacy_pic = {
        .mask_all = legacy_pic_noop,
        .restore_mask = legacy_pic_noop,
        .init = legacy_pic_int_noop,
+       .probe = legacy_pic_probe,
        .irq_pending = legacy_pic_irq_pending_noop,
        .make_irq = legacy_pic_uint_noop,
 };
@@ -400,6 +412,7 @@ struct legacy_pic default_legacy_pic = {
        .mask_all = mask_8259A,
        .restore_mask = unmask_8259A,
        .init = init_8259A,
+       .probe = probe_8259A,
        .irq_pending = i8259A_irq_pending,
        .make_irq = make_8259A_irq,
 };
index a1e4da98c8f0db8c838766e9466c2608c124fe98..29db25f9a745ee11d23867cc974438817a6e5b15 100644 (file)
@@ -1188,7 +1188,7 @@ void __init setup_arch(char **cmdline_p)
         */
        clone_pgd_range(initial_page_table,
                        swapper_pg_dir     + KERNEL_PGD_BOUNDARY,
-                       KERNEL_PGD_PTRS);
+                       min(KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
 #endif
 
        tboot_probe();
index b9242bacbe59a2c02baee2e0d89fe8247b13106b..4cf401f581e7e720f858393476eb895a440d0ab2 100644 (file)
 #include <asm/msr-index.h>
 
 verify_cpu:
-       pushfl                          # Save caller passed flags
-       pushl   $0                      # Kill any dangerous flags
-       popfl
+       pushf                           # Save caller passed flags
+       push    $0                      # Kill any dangerous flags
+       popf
 
+#ifndef __x86_64__
        pushfl                          # standard way to check for cpuid
        popl    %eax
        movl    %eax,%ebx
@@ -48,6 +49,7 @@ verify_cpu:
        popl    %eax
        cmpl    %eax,%ebx
        jz      verify_cpu_no_longmode  # cpu has no cpuid
+#endif
 
        movl    $0x0,%eax               # See if cpuid 1 is implemented
        cpuid
@@ -130,10 +132,10 @@ verify_cpu_sse_test:
        jmp     verify_cpu_sse_test     # try again
 
 verify_cpu_no_longmode:
-       popfl                           # Restore caller passed flags
+       popf                            # Restore caller passed flags
        movl $1,%eax
        ret
 verify_cpu_sse_ok:
-       popfl                           # Restore caller passed flags
+       popf                            # Restore caller passed flags
        xorl %eax, %eax
        ret
index ecd4ea1d28a8ce01b5b693f5b7d8a953e50131a1..4d30b865be30641f4964a3279939020e9f1a057a 100644 (file)
@@ -1250,7 +1250,7 @@ void wait_lapic_expire(struct kvm_vcpu *vcpu)
 
        tsc_deadline = apic->lapic_timer.expired_tscdeadline;
        apic->lapic_timer.expired_tscdeadline = 0;
-       guest_tsc = kvm_x86_ops->read_l1_tsc(vcpu, rdtsc());
+       guest_tsc = kvm_read_l1_tsc(vcpu, rdtsc());
        trace_kvm_wait_lapic_expire(vcpu->vcpu_id, guest_tsc - tsc_deadline);
 
        /* __delay is delay_tsc whenever the hardware has TSC, thus always.  */
@@ -1318,7 +1318,7 @@ static void start_apic_timer(struct kvm_lapic *apic)
                local_irq_save(flags);
 
                now = apic->lapic_timer.timer.base->get_time();
-               guest_tsc = kvm_x86_ops->read_l1_tsc(vcpu, rdtsc());
+               guest_tsc = kvm_read_l1_tsc(vcpu, rdtsc());
                if (likely(tscdeadline > guest_tsc)) {
                        ns = (tscdeadline - guest_tsc) * 1000000ULL;
                        do_div(ns, this_tsc_khz);
index 7d85bcae3332f0eb04c0fb9314a6c401de271e18..e7c2c1428a691676a6a1fdadee044ab45124acc2 100644 (file)
@@ -3359,7 +3359,7 @@ exit:
        return reserved;
 }
 
-int handle_mmio_page_fault_common(struct kvm_vcpu *vcpu, u64 addr, bool direct)
+int handle_mmio_page_fault(struct kvm_vcpu *vcpu, u64 addr, bool direct)
 {
        u64 spte;
        bool reserved;
@@ -3368,7 +3368,7 @@ int handle_mmio_page_fault_common(struct kvm_vcpu *vcpu, u64 addr, bool direct)
                return RET_MMIO_PF_EMULATE;
 
        reserved = walk_shadow_page_get_mmio_spte(vcpu, addr, &spte);
-       if (unlikely(reserved))
+       if (WARN_ON(reserved))
                return RET_MMIO_PF_BUG;
 
        if (is_mmio_spte(spte)) {
@@ -3392,17 +3392,7 @@ int handle_mmio_page_fault_common(struct kvm_vcpu *vcpu, u64 addr, bool direct)
         */
        return RET_MMIO_PF_RETRY;
 }
-EXPORT_SYMBOL_GPL(handle_mmio_page_fault_common);
-
-static int handle_mmio_page_fault(struct kvm_vcpu *vcpu, u64 addr,
-                                 u32 error_code, bool direct)
-{
-       int ret;
-
-       ret = handle_mmio_page_fault_common(vcpu, addr, direct);
-       WARN_ON(ret == RET_MMIO_PF_BUG);
-       return ret;
-}
+EXPORT_SYMBOL_GPL(handle_mmio_page_fault);
 
 static int nonpaging_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
                                u32 error_code, bool prefault)
@@ -3413,7 +3403,7 @@ static int nonpaging_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
        pgprintk("%s: gva %lx error %x\n", __func__, gva, error_code);
 
        if (unlikely(error_code & PFERR_RSVD_MASK)) {
-               r = handle_mmio_page_fault(vcpu, gva, error_code, true);
+               r = handle_mmio_page_fault(vcpu, gva, true);
 
                if (likely(r != RET_MMIO_PF_INVALID))
                        return r;
@@ -3503,7 +3493,7 @@ static int tdp_page_fault(struct kvm_vcpu *vcpu, gva_t gpa, u32 error_code,
        MMU_WARN_ON(!VALID_PAGE(vcpu->arch.mmu.root_hpa));
 
        if (unlikely(error_code & PFERR_RSVD_MASK)) {
-               r = handle_mmio_page_fault(vcpu, gpa, error_code, true);
+               r = handle_mmio_page_fault(vcpu, gpa, true);
 
                if (likely(r != RET_MMIO_PF_INVALID))
                        return r;
index e4202e41d53541f06a468e0b72beac483e2e7b8f..55ffb7b0f95e9f82a97e8fd4ab7caf4f720fc335 100644 (file)
@@ -56,13 +56,13 @@ void
 reset_shadow_zero_bits_mask(struct kvm_vcpu *vcpu, struct kvm_mmu *context);
 
 /*
- * Return values of handle_mmio_page_fault_common:
+ * Return values of handle_mmio_page_fault:
  * RET_MMIO_PF_EMULATE: it is a real mmio page fault, emulate the instruction
  *                     directly.
  * RET_MMIO_PF_INVALID: invalid spte is detected then let the real page
  *                     fault path update the mmio spte.
  * RET_MMIO_PF_RETRY: let CPU fault again on the address.
- * RET_MMIO_PF_BUG: bug is detected.
+ * RET_MMIO_PF_BUG: a bug was detected (and a WARN was printed).
  */
 enum {
        RET_MMIO_PF_EMULATE = 1,
@@ -71,7 +71,7 @@ enum {
        RET_MMIO_PF_BUG = -1
 };
 
-int handle_mmio_page_fault_common(struct kvm_vcpu *vcpu, u64 addr, bool direct);
+int handle_mmio_page_fault(struct kvm_vcpu *vcpu, u64 addr, bool direct);
 void kvm_init_shadow_mmu(struct kvm_vcpu *vcpu);
 void kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, bool execonly);
 
index b41faa91a6f97ef4342b1c671160ddc5311b8502..3058a22a658d25db2bb8ecf4a37657bc1f873c1d 100644 (file)
@@ -705,8 +705,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, u32 error_code,
        pgprintk("%s: addr %lx err %x\n", __func__, addr, error_code);
 
        if (unlikely(error_code & PFERR_RSVD_MASK)) {
-               r = handle_mmio_page_fault(vcpu, addr, error_code,
-                                             mmu_is_nested(vcpu));
+               r = handle_mmio_page_fault(vcpu, addr, mmu_is_nested(vcpu));
                if (likely(r != RET_MMIO_PF_INVALID))
                        return r;
 
index f2c8e4917688a34a9dfb3994d776e8efab512fc2..83a1c643f9a50fd3fa0ffc041c40d9f4d25aa5b5 100644 (file)
@@ -158,8 +158,6 @@ struct vcpu_svm {
        unsigned long int3_rip;
        u32 apf_reason;
 
-       u64  tsc_ratio;
-
        /* cached guest cpuid flags for faster access */
        bool nrips_enabled      : 1;
 };
@@ -214,7 +212,6 @@ static int nested_svm_intercept(struct vcpu_svm *svm);
 static int nested_svm_vmexit(struct vcpu_svm *svm);
 static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
                                      bool has_error_code, u32 error_code);
-static u64 __scale_tsc(u64 ratio, u64 tsc);
 
 enum {
        VMCB_INTERCEPTS, /* Intercept vectors, TSC offset,
@@ -894,20 +891,9 @@ static __init int svm_hardware_setup(void)
                kvm_enable_efer_bits(EFER_FFXSR);
 
        if (boot_cpu_has(X86_FEATURE_TSCRATEMSR)) {
-               u64 max;
-
                kvm_has_tsc_control = true;
-
-               /*
-                * Make sure the user can only configure tsc_khz values that
-                * fit into a signed integer.
-                * A min value is not calculated needed because it will always
-                * be 1 on all machines and a value of 0 is used to disable
-                * tsc-scaling for the vcpu.
-                */
-               max = min(0x7fffffffULL, __scale_tsc(tsc_khz, TSC_RATIO_MAX));
-
-               kvm_max_guest_tsc_khz = max;
+               kvm_max_tsc_scaling_ratio = TSC_RATIO_MAX;
+               kvm_tsc_scaling_ratio_frac_bits = 32;
        }
 
        if (nested) {
@@ -971,68 +957,6 @@ static void init_sys_seg(struct vmcb_seg *seg, uint32_t type)
        seg->base = 0;
 }
 
-static u64 __scale_tsc(u64 ratio, u64 tsc)
-{
-       u64 mult, frac, _tsc;
-
-       mult  = ratio >> 32;
-       frac  = ratio & ((1ULL << 32) - 1);
-
-       _tsc  = tsc;
-       _tsc *= mult;
-       _tsc += (tsc >> 32) * frac;
-       _tsc += ((tsc & ((1ULL << 32) - 1)) * frac) >> 32;
-
-       return _tsc;
-}
-
-static u64 svm_scale_tsc(struct kvm_vcpu *vcpu, u64 tsc)
-{
-       struct vcpu_svm *svm = to_svm(vcpu);
-       u64 _tsc = tsc;
-
-       if (svm->tsc_ratio != TSC_RATIO_DEFAULT)
-               _tsc = __scale_tsc(svm->tsc_ratio, tsc);
-
-       return _tsc;
-}
-
-static void svm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz, bool scale)
-{
-       struct vcpu_svm *svm = to_svm(vcpu);
-       u64 ratio;
-       u64 khz;
-
-       /* Guest TSC same frequency as host TSC? */
-       if (!scale) {
-               svm->tsc_ratio = TSC_RATIO_DEFAULT;
-               return;
-       }
-
-       /* TSC scaling supported? */
-       if (!boot_cpu_has(X86_FEATURE_TSCRATEMSR)) {
-               if (user_tsc_khz > tsc_khz) {
-                       vcpu->arch.tsc_catchup = 1;
-                       vcpu->arch.tsc_always_catchup = 1;
-               } else
-                       WARN(1, "user requested TSC rate below hardware speed\n");
-               return;
-       }
-
-       khz = user_tsc_khz;
-
-       /* TSC scaling required  - calculate ratio */
-       ratio = khz << 32;
-       do_div(ratio, tsc_khz);
-
-       if (ratio == 0 || ratio & TSC_RATIO_RSVD) {
-               WARN_ONCE(1, "Invalid TSC ratio - virtual-tsc-khz=%u\n",
-                               user_tsc_khz);
-               return;
-       }
-       svm->tsc_ratio             = ratio;
-}
-
 static u64 svm_read_tsc_offset(struct kvm_vcpu *vcpu)
 {
        struct vcpu_svm *svm = to_svm(vcpu);
@@ -1059,16 +983,10 @@ static void svm_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
        mark_dirty(svm->vmcb, VMCB_INTERCEPTS);
 }
 
-static void svm_adjust_tsc_offset(struct kvm_vcpu *vcpu, s64 adjustment, bool host)
+static void svm_adjust_tsc_offset_guest(struct kvm_vcpu *vcpu, s64 adjustment)
 {
        struct vcpu_svm *svm = to_svm(vcpu);
 
-       if (host) {
-               if (svm->tsc_ratio != TSC_RATIO_DEFAULT)
-                       WARN_ON(adjustment < 0);
-               adjustment = svm_scale_tsc(vcpu, (u64)adjustment);
-       }
-
        svm->vmcb->control.tsc_offset += adjustment;
        if (is_guest_mode(vcpu))
                svm->nested.hsave->control.tsc_offset += adjustment;
@@ -1080,15 +998,6 @@ static void svm_adjust_tsc_offset(struct kvm_vcpu *vcpu, s64 adjustment, bool ho
        mark_dirty(svm->vmcb, VMCB_INTERCEPTS);
 }
 
-static u64 svm_compute_tsc_offset(struct kvm_vcpu *vcpu, u64 target_tsc)
-{
-       u64 tsc;
-
-       tsc = svm_scale_tsc(vcpu, rdtsc());
-
-       return target_tsc - tsc;
-}
-
 static void init_vmcb(struct vcpu_svm *svm)
 {
        struct vmcb_control_area *control = &svm->vmcb->control;
@@ -1110,6 +1019,8 @@ static void init_vmcb(struct vcpu_svm *svm)
        set_exception_intercept(svm, PF_VECTOR);
        set_exception_intercept(svm, UD_VECTOR);
        set_exception_intercept(svm, MC_VECTOR);
+       set_exception_intercept(svm, AC_VECTOR);
+       set_exception_intercept(svm, DB_VECTOR);
 
        set_intercept(svm, INTERCEPT_INTR);
        set_intercept(svm, INTERCEPT_NMI);
@@ -1235,8 +1146,6 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id)
                goto out;
        }
 
-       svm->tsc_ratio = TSC_RATIO_DEFAULT;
-
        err = kvm_vcpu_init(&svm->vcpu, kvm, id);
        if (err)
                goto free_svm;
@@ -1322,10 +1231,12 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
        for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++)
                rdmsrl(host_save_user_msrs[i], svm->host_user_msrs[i]);
 
-       if (static_cpu_has(X86_FEATURE_TSCRATEMSR) &&
-           svm->tsc_ratio != __this_cpu_read(current_tsc_ratio)) {
-               __this_cpu_write(current_tsc_ratio, svm->tsc_ratio);
-               wrmsrl(MSR_AMD64_TSC_RATIO, svm->tsc_ratio);
+       if (static_cpu_has(X86_FEATURE_TSCRATEMSR)) {
+               u64 tsc_ratio = vcpu->arch.tsc_scaling_ratio;
+               if (tsc_ratio != __this_cpu_read(current_tsc_ratio)) {
+                       __this_cpu_write(current_tsc_ratio, tsc_ratio);
+                       wrmsrl(MSR_AMD64_TSC_RATIO, tsc_ratio);
+               }
        }
 }
 
@@ -1644,20 +1555,13 @@ static void svm_set_segment(struct kvm_vcpu *vcpu,
        mark_dirty(svm->vmcb, VMCB_SEG);
 }
 
-static void update_db_bp_intercept(struct kvm_vcpu *vcpu)
+static void update_bp_intercept(struct kvm_vcpu *vcpu)
 {
        struct vcpu_svm *svm = to_svm(vcpu);
 
-       clr_exception_intercept(svm, DB_VECTOR);
        clr_exception_intercept(svm, BP_VECTOR);
 
-       if (svm->nmi_singlestep)
-               set_exception_intercept(svm, DB_VECTOR);
-
        if (vcpu->guest_debug & KVM_GUESTDBG_ENABLE) {
-               if (vcpu->guest_debug &
-                   (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))
-                       set_exception_intercept(svm, DB_VECTOR);
                if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
                        set_exception_intercept(svm, BP_VECTOR);
        } else
@@ -1763,7 +1667,6 @@ static int db_interception(struct vcpu_svm *svm)
                if (!(svm->vcpu.guest_debug & KVM_GUESTDBG_SINGLESTEP))
                        svm->vmcb->save.rflags &=
                                ~(X86_EFLAGS_TF | X86_EFLAGS_RF);
-               update_db_bp_intercept(&svm->vcpu);
        }
 
        if (svm->vcpu.guest_debug &
@@ -1798,6 +1701,12 @@ static int ud_interception(struct vcpu_svm *svm)
        return 1;
 }
 
+static int ac_interception(struct vcpu_svm *svm)
+{
+       kvm_queue_exception_e(&svm->vcpu, AC_VECTOR, 0);
+       return 1;
+}
+
 static void svm_fpu_activate(struct kvm_vcpu *vcpu)
 {
        struct vcpu_svm *svm = to_svm(vcpu);
@@ -3075,8 +2984,7 @@ static int cr8_write_interception(struct vcpu_svm *svm)
 static u64 svm_read_l1_tsc(struct kvm_vcpu *vcpu, u64 host_tsc)
 {
        struct vmcb *vmcb = get_host_vmcb(to_svm(vcpu));
-       return vmcb->control.tsc_offset +
-               svm_scale_tsc(vcpu, host_tsc);
+       return vmcb->control.tsc_offset + host_tsc;
 }
 
 static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
@@ -3086,7 +2994,7 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
        switch (msr_info->index) {
        case MSR_IA32_TSC: {
                msr_info->data = svm->vmcb->control.tsc_offset +
-                       svm_scale_tsc(vcpu, rdtsc());
+                       kvm_scale_tsc(vcpu, rdtsc());
 
                break;
        }
@@ -3362,6 +3270,7 @@ static int (*const svm_exit_handlers[])(struct vcpu_svm *svm) = {
        [SVM_EXIT_EXCP_BASE + PF_VECTOR]        = pf_interception,
        [SVM_EXIT_EXCP_BASE + NM_VECTOR]        = nm_interception,
        [SVM_EXIT_EXCP_BASE + MC_VECTOR]        = mc_interception,
+       [SVM_EXIT_EXCP_BASE + AC_VECTOR]        = ac_interception,
        [SVM_EXIT_INTR]                         = intr_interception,
        [SVM_EXIT_NMI]                          = nmi_interception,
        [SVM_EXIT_SMI]                          = nop_on_interception,
@@ -3745,7 +3654,6 @@ static void enable_nmi_window(struct kvm_vcpu *vcpu)
         */
        svm->nmi_singlestep = true;
        svm->vmcb->save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF);
-       update_db_bp_intercept(vcpu);
 }
 
 static int svm_set_tss_addr(struct kvm *kvm, unsigned int addr)
@@ -4371,7 +4279,7 @@ static struct kvm_x86_ops svm_x86_ops = {
        .vcpu_load = svm_vcpu_load,
        .vcpu_put = svm_vcpu_put,
 
-       .update_db_bp_intercept = update_db_bp_intercept,
+       .update_bp_intercept = update_bp_intercept,
        .get_msr = svm_get_msr,
        .set_msr = svm_set_msr,
        .get_segment_base = svm_get_segment_base,
@@ -4443,11 +4351,9 @@ static struct kvm_x86_ops svm_x86_ops = {
 
        .has_wbinvd_exit = svm_has_wbinvd_exit,
 
-       .set_tsc_khz = svm_set_tsc_khz,
        .read_tsc_offset = svm_read_tsc_offset,
        .write_tsc_offset = svm_write_tsc_offset,
-       .adjust_tsc_offset = svm_adjust_tsc_offset,
-       .compute_tsc_offset = svm_compute_tsc_offset,
+       .adjust_tsc_offset_guest = svm_adjust_tsc_offset_guest,
        .read_l1_tsc = svm_read_l1_tsc,
 
        .set_tdp_cr3 = set_tdp_cr3,
index 5eb56ed77c1fdea01652acf0da476761cf7a9aaa..87acc5221740a588d256f9f0ed4059d366165872 100644 (file)
@@ -107,6 +107,8 @@ static u64 __read_mostly host_xss;
 static bool __read_mostly enable_pml = 1;
 module_param_named(pml, enable_pml, bool, S_IRUGO);
 
+#define KVM_VMX_TSC_MULTIPLIER_MAX     0xffffffffffffffffULL
+
 #define KVM_GUEST_CR0_MASK (X86_CR0_NW | X86_CR0_CD)
 #define KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST (X86_CR0_WP | X86_CR0_NE)
 #define KVM_VM_CR0_ALWAYS_ON                                           \
@@ -1172,6 +1174,12 @@ static inline bool cpu_has_vmx_pml(void)
        return vmcs_config.cpu_based_2nd_exec_ctrl & SECONDARY_EXEC_ENABLE_PML;
 }
 
+static inline bool cpu_has_vmx_tsc_scaling(void)
+{
+       return vmcs_config.cpu_based_2nd_exec_ctrl &
+               SECONDARY_EXEC_TSC_SCALING;
+}
+
 static inline bool report_flexpriority(void)
 {
        return flexpriority_enabled;
@@ -1631,7 +1639,7 @@ static void update_exception_bitmap(struct kvm_vcpu *vcpu)
        u32 eb;
 
        eb = (1u << PF_VECTOR) | (1u << UD_VECTOR) | (1u << MC_VECTOR) |
-            (1u << NM_VECTOR) | (1u << DB_VECTOR);
+            (1u << NM_VECTOR) | (1u << DB_VECTOR) | (1u << AC_VECTOR);
        if ((vcpu->guest_debug &
             (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)) ==
            (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP))
@@ -2053,6 +2061,12 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 
                rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp);
                vmcs_writel(HOST_IA32_SYSENTER_ESP, sysenter_esp); /* 22.2.3 */
+
+               /* Setup TSC multiplier */
+               if (cpu_has_vmx_tsc_scaling())
+                       vmcs_write64(TSC_MULTIPLIER,
+                                    vcpu->arch.tsc_scaling_ratio);
+
                vmx->loaded_vmcs->cpu = cpu;
        }
 
@@ -2357,15 +2371,16 @@ static void setup_msrs(struct vcpu_vmx *vmx)
 
 /*
  * reads and returns guest's timestamp counter "register"
- * guest_tsc = host_tsc + tsc_offset    -- 21.3
+ * guest_tsc = (host_tsc * tsc multiplier) >> 48 + tsc_offset
+ * -- Intel TSC Scaling for Virtualization White Paper, sec 1.3
  */
-static u64 guest_read_tsc(void)
+static u64 guest_read_tsc(struct kvm_vcpu *vcpu)
 {
        u64 host_tsc, tsc_offset;
 
        host_tsc = rdtsc();
        tsc_offset = vmcs_read64(TSC_OFFSET);
-       return host_tsc + tsc_offset;
+       return kvm_scale_tsc(vcpu, host_tsc) + tsc_offset;
 }
 
 /*
@@ -2382,22 +2397,6 @@ static u64 vmx_read_l1_tsc(struct kvm_vcpu *vcpu, u64 host_tsc)
        return host_tsc + tsc_offset;
 }
 
-/*
- * Engage any workarounds for mis-matched TSC rates.  Currently limited to
- * software catchup for faster rates on slower CPUs.
- */
-static void vmx_set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz, bool scale)
-{
-       if (!scale)
-               return;
-
-       if (user_tsc_khz > tsc_khz) {
-               vcpu->arch.tsc_catchup = 1;
-               vcpu->arch.tsc_always_catchup = 1;
-       } else
-               WARN(1, "user requested TSC rate below hardware speed\n");
-}
-
 static u64 vmx_read_tsc_offset(struct kvm_vcpu *vcpu)
 {
        return vmcs_read64(TSC_OFFSET);
@@ -2429,7 +2428,7 @@ static void vmx_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
        }
 }
 
-static void vmx_adjust_tsc_offset(struct kvm_vcpu *vcpu, s64 adjustment, bool host)
+static void vmx_adjust_tsc_offset_guest(struct kvm_vcpu *vcpu, s64 adjustment)
 {
        u64 offset = vmcs_read64(TSC_OFFSET);
 
@@ -2442,11 +2441,6 @@ static void vmx_adjust_tsc_offset(struct kvm_vcpu *vcpu, s64 adjustment, bool ho
                                           offset + adjustment);
 }
 
-static u64 vmx_compute_tsc_offset(struct kvm_vcpu *vcpu, u64 target_tsc)
-{
-       return target_tsc - rdtsc();
-}
-
 static bool guest_cpuid_has_vmx(struct kvm_vcpu *vcpu)
 {
        struct kvm_cpuid_entry2 *best = kvm_find_cpuid_entry(vcpu, 1, 0);
@@ -2778,7 +2772,7 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
        case MSR_EFER:
                return kvm_get_msr_common(vcpu, msr_info);
        case MSR_IA32_TSC:
-               msr_info->data = guest_read_tsc();
+               msr_info->data = guest_read_tsc(vcpu);
                break;
        case MSR_IA32_SYSENTER_CS:
                msr_info->data = vmcs_read32(GUEST_SYSENTER_CS);
@@ -3154,7 +3148,8 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
                        SECONDARY_EXEC_SHADOW_VMCS |
                        SECONDARY_EXEC_XSAVES |
                        SECONDARY_EXEC_ENABLE_PML |
-                       SECONDARY_EXEC_PCOMMIT;
+                       SECONDARY_EXEC_PCOMMIT |
+                       SECONDARY_EXEC_TSC_SCALING;
                if (adjust_vmx_controls(min2, opt2,
                                        MSR_IA32_VMX_PROCBASED_CTLS2,
                                        &_cpu_based_2nd_exec_control) < 0)
@@ -5266,6 +5261,9 @@ static int handle_exception(struct kvm_vcpu *vcpu)
                return handle_rmode_exception(vcpu, ex_no, error_code);
 
        switch (ex_no) {
+       case AC_VECTOR:
+               kvm_queue_exception_e(vcpu, AC_VECTOR, error_code);
+               return 1;
        case DB_VECTOR:
                dr6 = vmcs_readl(EXIT_QUALIFICATION);
                if (!(vcpu->guest_debug &
@@ -5908,7 +5906,7 @@ static int handle_ept_misconfig(struct kvm_vcpu *vcpu)
                return 1;
        }
 
-       ret = handle_mmio_page_fault_common(vcpu, gpa, true);
+       ret = handle_mmio_page_fault(vcpu, gpa, true);
        if (likely(ret == RET_MMIO_PF_EMULATE))
                return x86_emulate_instruction(vcpu, gpa, 0, NULL, 0) ==
                                              EMULATE_DONE;
@@ -6199,6 +6197,12 @@ static __init int hardware_setup(void)
        if (!cpu_has_vmx_apicv())
                enable_apicv = 0;
 
+       if (cpu_has_vmx_tsc_scaling()) {
+               kvm_has_tsc_control = true;
+               kvm_max_tsc_scaling_ratio = KVM_VMX_TSC_MULTIPLIER_MAX;
+               kvm_tsc_scaling_ratio_frac_bits = 48;
+       }
+
        if (enable_apicv)
                kvm_x86_ops->update_cr8_intercept = NULL;
        else {
@@ -8008,6 +8012,9 @@ static void dump_vmcs(void)
               vmcs_read32(IDT_VECTORING_INFO_FIELD),
               vmcs_read32(IDT_VECTORING_ERROR_CODE));
        pr_err("TSC Offset = 0x%016lx\n", vmcs_readl(TSC_OFFSET));
+       if (secondary_exec_control & SECONDARY_EXEC_TSC_SCALING)
+               pr_err("TSC Multiplier = 0x%016lx\n",
+                      vmcs_readl(TSC_MULTIPLIER));
        if (cpu_based_exec_ctrl & CPU_BASED_TPR_SHADOW)
                pr_err("TPR Threshold = 0x%02x\n", vmcs_read32(TPR_THRESHOLD));
        if (pin_based_exec_ctrl & PIN_BASED_POSTED_INTR)
@@ -10752,7 +10759,7 @@ static struct kvm_x86_ops vmx_x86_ops = {
        .vcpu_load = vmx_vcpu_load,
        .vcpu_put = vmx_vcpu_put,
 
-       .update_db_bp_intercept = update_exception_bitmap,
+       .update_bp_intercept = update_exception_bitmap,
        .get_msr = vmx_get_msr,
        .set_msr = vmx_set_msr,
        .get_segment_base = vmx_get_segment_base,
@@ -10826,11 +10833,9 @@ static struct kvm_x86_ops vmx_x86_ops = {
 
        .has_wbinvd_exit = cpu_has_vmx_wbinvd_exit,
 
-       .set_tsc_khz = vmx_set_tsc_khz,
        .read_tsc_offset = vmx_read_tsc_offset,
        .write_tsc_offset = vmx_write_tsc_offset,
-       .adjust_tsc_offset = vmx_adjust_tsc_offset,
-       .compute_tsc_offset = vmx_compute_tsc_offset,
+       .adjust_tsc_offset_guest = vmx_adjust_tsc_offset_guest,
        .read_l1_tsc = vmx_read_l1_tsc,
 
        .set_tdp_cr3 = vmx_set_cr3,
index 4a6eff166fc61fa2053141f410260f2667f8a965..00462bd63129cfbde2c6b7e7bdf50eb073cc31b8 100644 (file)
@@ -93,10 +93,10 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu);
 static void process_nmi(struct kvm_vcpu *vcpu);
 static void __kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags);
 
-struct kvm_x86_ops *kvm_x86_ops;
+struct kvm_x86_ops *kvm_x86_ops __read_mostly;
 EXPORT_SYMBOL_GPL(kvm_x86_ops);
 
-static bool ignore_msrs = 0;
+static bool __read_mostly ignore_msrs = 0;
 module_param(ignore_msrs, bool, S_IRUGO | S_IWUSR);
 
 unsigned int min_timer_period_us = 500;
@@ -105,20 +105,25 @@ module_param(min_timer_period_us, uint, S_IRUGO | S_IWUSR);
 static bool __read_mostly kvmclock_periodic_sync = true;
 module_param(kvmclock_periodic_sync, bool, S_IRUGO);
 
-bool kvm_has_tsc_control;
+bool __read_mostly kvm_has_tsc_control;
 EXPORT_SYMBOL_GPL(kvm_has_tsc_control);
-u32  kvm_max_guest_tsc_khz;
+u32  __read_mostly kvm_max_guest_tsc_khz;
 EXPORT_SYMBOL_GPL(kvm_max_guest_tsc_khz);
+u8   __read_mostly kvm_tsc_scaling_ratio_frac_bits;
+EXPORT_SYMBOL_GPL(kvm_tsc_scaling_ratio_frac_bits);
+u64  __read_mostly kvm_max_tsc_scaling_ratio;
+EXPORT_SYMBOL_GPL(kvm_max_tsc_scaling_ratio);
+static u64 __read_mostly kvm_default_tsc_scaling_ratio;
 
 /* tsc tolerance in parts per million - default to 1/2 of the NTP threshold */
-static u32 tsc_tolerance_ppm = 250;
+static u32 __read_mostly tsc_tolerance_ppm = 250;
 module_param(tsc_tolerance_ppm, uint, S_IRUGO | S_IWUSR);
 
 /* lapic timer advance (tscdeadline mode only) in nanoseconds */
-unsigned int lapic_timer_advance_ns = 0;
+unsigned int __read_mostly lapic_timer_advance_ns = 0;
 module_param(lapic_timer_advance_ns, uint, S_IRUGO | S_IWUSR);
 
-static bool backwards_tsc_observed = false;
+static bool __read_mostly backwards_tsc_observed = false;
 
 #define KVM_NR_SHARED_MSRS 16
 
@@ -1249,14 +1254,53 @@ static u32 adjust_tsc_khz(u32 khz, s32 ppm)
        return v;
 }
 
-static void kvm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 this_tsc_khz)
+static int set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz, bool scale)
+{
+       u64 ratio;
+
+       /* Guest TSC same frequency as host TSC? */
+       if (!scale) {
+               vcpu->arch.tsc_scaling_ratio = kvm_default_tsc_scaling_ratio;
+               return 0;
+       }
+
+       /* TSC scaling supported? */
+       if (!kvm_has_tsc_control) {
+               if (user_tsc_khz > tsc_khz) {
+                       vcpu->arch.tsc_catchup = 1;
+                       vcpu->arch.tsc_always_catchup = 1;
+                       return 0;
+               } else {
+                       WARN(1, "user requested TSC rate below hardware speed\n");
+                       return -1;
+               }
+       }
+
+       /* TSC scaling required  - calculate ratio */
+       ratio = mul_u64_u32_div(1ULL << kvm_tsc_scaling_ratio_frac_bits,
+                               user_tsc_khz, tsc_khz);
+
+       if (ratio == 0 || ratio >= kvm_max_tsc_scaling_ratio) {
+               WARN_ONCE(1, "Invalid TSC scaling ratio - virtual-tsc-khz=%u\n",
+                         user_tsc_khz);
+               return -1;
+       }
+
+       vcpu->arch.tsc_scaling_ratio = ratio;
+       return 0;
+}
+
+static int kvm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 this_tsc_khz)
 {
        u32 thresh_lo, thresh_hi;
        int use_scaling = 0;
 
        /* tsc_khz can be zero if TSC calibration fails */
-       if (this_tsc_khz == 0)
-               return;
+       if (this_tsc_khz == 0) {
+               /* set tsc_scaling_ratio to a safe value */
+               vcpu->arch.tsc_scaling_ratio = kvm_default_tsc_scaling_ratio;
+               return -1;
+       }
 
        /* Compute a scale to convert nanoseconds in TSC cycles */
        kvm_get_time_scale(this_tsc_khz, NSEC_PER_SEC / 1000,
@@ -1276,7 +1320,7 @@ static void kvm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 this_tsc_khz)
                pr_debug("kvm: requested TSC rate %u falls outside tolerance [%u,%u]\n", this_tsc_khz, thresh_lo, thresh_hi);
                use_scaling = 1;
        }
-       kvm_x86_ops->set_tsc_khz(vcpu, this_tsc_khz, use_scaling);
+       return set_tsc_khz(vcpu, this_tsc_khz, use_scaling);
 }
 
 static u64 compute_guest_tsc(struct kvm_vcpu *vcpu, s64 kernel_ns)
@@ -1322,6 +1366,48 @@ static void update_ia32_tsc_adjust_msr(struct kvm_vcpu *vcpu, s64 offset)
        vcpu->arch.ia32_tsc_adjust_msr += offset - curr_offset;
 }
 
+/*
+ * Multiply tsc by a fixed point number represented by ratio.
+ *
+ * The most significant 64-N bits (mult) of ratio represent the
+ * integral part of the fixed point number; the remaining N bits
+ * (frac) represent the fractional part, ie. ratio represents a fixed
+ * point number (mult + frac * 2^(-N)).
+ *
+ * N equals to kvm_tsc_scaling_ratio_frac_bits.
+ */
+static inline u64 __scale_tsc(u64 ratio, u64 tsc)
+{
+       return mul_u64_u64_shr(tsc, ratio, kvm_tsc_scaling_ratio_frac_bits);
+}
+
+u64 kvm_scale_tsc(struct kvm_vcpu *vcpu, u64 tsc)
+{
+       u64 _tsc = tsc;
+       u64 ratio = vcpu->arch.tsc_scaling_ratio;
+
+       if (ratio != kvm_default_tsc_scaling_ratio)
+               _tsc = __scale_tsc(ratio, tsc);
+
+       return _tsc;
+}
+EXPORT_SYMBOL_GPL(kvm_scale_tsc);
+
+static u64 kvm_compute_tsc_offset(struct kvm_vcpu *vcpu, u64 target_tsc)
+{
+       u64 tsc;
+
+       tsc = kvm_scale_tsc(vcpu, rdtsc());
+
+       return target_tsc - tsc;
+}
+
+u64 kvm_read_l1_tsc(struct kvm_vcpu *vcpu, u64 host_tsc)
+{
+       return kvm_x86_ops->read_l1_tsc(vcpu, kvm_scale_tsc(vcpu, host_tsc));
+}
+EXPORT_SYMBOL_GPL(kvm_read_l1_tsc);
+
 void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr)
 {
        struct kvm *kvm = vcpu->kvm;
@@ -1333,7 +1419,7 @@ void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr)
        u64 data = msr->data;
 
        raw_spin_lock_irqsave(&kvm->arch.tsc_write_lock, flags);
-       offset = kvm_x86_ops->compute_tsc_offset(vcpu, data);
+       offset = kvm_compute_tsc_offset(vcpu, data);
        ns = get_kernel_ns();
        elapsed = ns - kvm->arch.last_tsc_nsec;
 
@@ -1390,7 +1476,7 @@ void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr)
                } else {
                        u64 delta = nsec_to_cycles(vcpu, elapsed);
                        data += delta;
-                       offset = kvm_x86_ops->compute_tsc_offset(vcpu, data);
+                       offset = kvm_compute_tsc_offset(vcpu, data);
                        pr_debug("kvm: adjusted tsc offset by %llu\n", delta);
                }
                matched = true;
@@ -1447,6 +1533,20 @@ void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr)
 
 EXPORT_SYMBOL_GPL(kvm_write_tsc);
 
+static inline void adjust_tsc_offset_guest(struct kvm_vcpu *vcpu,
+                                          s64 adjustment)
+{
+       kvm_x86_ops->adjust_tsc_offset_guest(vcpu, adjustment);
+}
+
+static inline void adjust_tsc_offset_host(struct kvm_vcpu *vcpu, s64 adjustment)
+{
+       if (vcpu->arch.tsc_scaling_ratio != kvm_default_tsc_scaling_ratio)
+               WARN_ON(adjustment < 0);
+       adjustment = kvm_scale_tsc(vcpu, (u64) adjustment);
+       kvm_x86_ops->adjust_tsc_offset_guest(vcpu, adjustment);
+}
+
 #ifdef CONFIG_X86_64
 
 static cycle_t read_tsc(void)
@@ -1608,7 +1708,7 @@ static void kvm_gen_update_masterclock(struct kvm *kvm)
 
 static int kvm_guest_time_update(struct kvm_vcpu *v)
 {
-       unsigned long flags, this_tsc_khz;
+       unsigned long flags, this_tsc_khz, tgt_tsc_khz;
        struct kvm_vcpu_arch *vcpu = &v->arch;
        struct kvm_arch *ka = &v->kvm->arch;
        s64 kernel_ns;
@@ -1645,7 +1745,7 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
                kernel_ns = get_kernel_ns();
        }
 
-       tsc_timestamp = kvm_x86_ops->read_l1_tsc(v, host_tsc);
+       tsc_timestamp = kvm_read_l1_tsc(v, host_tsc);
 
        /*
         * We may have to catch up the TSC to match elapsed wall clock
@@ -1671,7 +1771,9 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
                return 0;
 
        if (unlikely(vcpu->hw_tsc_khz != this_tsc_khz)) {
-               kvm_get_time_scale(NSEC_PER_SEC / 1000, this_tsc_khz,
+               tgt_tsc_khz = kvm_has_tsc_control ?
+                       vcpu->virtual_tsc_khz : this_tsc_khz;
+               kvm_get_time_scale(NSEC_PER_SEC / 1000, tgt_tsc_khz,
                                   &vcpu->hv_clock.tsc_shift,
                                   &vcpu->hv_clock.tsc_to_system_mul);
                vcpu->hw_tsc_khz = this_tsc_khz;
@@ -2617,7 +2719,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
                if (tsc_delta < 0)
                        mark_tsc_unstable("KVM discovered backwards TSC");
                if (check_tsc_unstable()) {
-                       u64 offset = kvm_x86_ops->compute_tsc_offset(vcpu,
+                       u64 offset = kvm_compute_tsc_offset(vcpu,
                                                vcpu->arch.last_guest_tsc);
                        kvm_x86_ops->write_tsc_offset(vcpu, offset);
                        vcpu->arch.tsc_catchup = 1;
@@ -3319,9 +3421,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
                if (user_tsc_khz == 0)
                        user_tsc_khz = tsc_khz;
 
-               kvm_set_tsc_khz(vcpu, user_tsc_khz);
+               if (!kvm_set_tsc_khz(vcpu, user_tsc_khz))
+                       r = 0;
 
-               r = 0;
                goto out;
        }
        case KVM_GET_TSC_KHZ: {
@@ -6452,8 +6554,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
        if (hw_breakpoint_active())
                hw_breakpoint_restore();
 
-       vcpu->arch.last_guest_tsc = kvm_x86_ops->read_l1_tsc(vcpu,
-                                                          rdtsc());
+       vcpu->arch.last_guest_tsc = kvm_read_l1_tsc(vcpu, rdtsc());
 
        vcpu->mode = OUTSIDE_GUEST_MODE;
        smp_wmb();
@@ -7015,7 +7116,7 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
         */
        kvm_set_rflags(vcpu, rflags);
 
-       kvm_x86_ops->update_db_bp_intercept(vcpu);
+       kvm_x86_ops->update_bp_intercept(vcpu);
 
        r = 0;
 
@@ -7364,6 +7465,20 @@ int kvm_arch_hardware_setup(void)
        if (r != 0)
                return r;
 
+       if (kvm_has_tsc_control) {
+               /*
+                * Make sure the user can only configure tsc_khz values that
+                * fit into a signed integer.
+                * A min value is not calculated needed because it will always
+                * be 1 on all machines.
+                */
+               u64 max = min(0x7fffffffULL,
+                             __scale_tsc(kvm_max_tsc_scaling_ratio, tsc_khz));
+               kvm_max_guest_tsc_khz = max;
+
+               kvm_default_tsc_scaling_ratio = 1ULL << kvm_tsc_scaling_ratio_frac_bits;
+       }
+
        kvm_init_msr_list();
        return 0;
 }
index 1bf417e9cc1309e3353f08fee9dad6915fb34c0c..a035c2aa780190c8c198e1bd8c2bec20a18d8ecb 100644 (file)
@@ -358,6 +358,21 @@ static void walk_pud_level(struct seq_file *m, struct pg_state *st, pgd_t addr,
 #define pgd_none(a)  pud_none(__pud(pgd_val(a)))
 #endif
 
+#ifdef CONFIG_X86_64
+static inline bool is_hypervisor_range(int idx)
+{
+       /*
+        * ffff800000000000 - ffff87ffffffffff is reserved for
+        * the hypervisor.
+        */
+       return paravirt_enabled() &&
+               (idx >= pgd_index(__PAGE_OFFSET) - 16) &&
+               (idx < pgd_index(__PAGE_OFFSET));
+}
+#else
+static inline bool is_hypervisor_range(int idx) { return false; }
+#endif
+
 static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd,
                                       bool checkwx)
 {
@@ -381,7 +396,7 @@ static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd,
 
        for (i = 0; i < PTRS_PER_PGD; i++) {
                st.current_address = normalize_addr(i * PGD_LEVEL_MULT);
-               if (!pgd_none(*start)) {
+               if (!pgd_none(*start) && !is_hypervisor_range(i)) {
                        if (pgd_large(*start) || !pgd_present(*start)) {
                                prot = pgd_flags(*start);
                                note_page(m, &st, __pgprot(prot), 1);
index 2bbf08cd29007a8da2db6e9cca053c79094ee504..5131993b23a1a2b35670adcbd4ab7d569a29a3d2 100644 (file)
@@ -1575,6 +1575,9 @@ bool bio_attempt_front_merge(struct request_queue *q, struct request *req,
  * @q: request_queue new bio is being queued at
  * @bio: new bio being queued
  * @request_count: out parameter for number of traversed plugged requests
+ * @same_queue_rq: pointer to &struct request that gets filled in when
+ * another request associated with @q is found on the plug list
+ * (optional, may be %NULL)
  *
  * Determine whether @bio being queued on @q can be merged with a request
  * on %current's plugged list.  Returns %true if merge was successful,
index 86bd5b25288e29c0415700db4993cd239183366e..3ae09de62f19ce2ca230a89ae6137a511fc9ae16 100644 (file)
@@ -358,7 +358,7 @@ static void blk_mq_ipi_complete_request(struct request *rq)
        put_cpu();
 }
 
-void __blk_mq_complete_request(struct request *rq)
+static void __blk_mq_complete_request(struct request *rq)
 {
        struct request_queue *q = rq->q;
 
index b44dce165761268c1f0a6bd64db78451f68d912f..713820b47b3182c85331f2638d44449cfdab3bbe 100644 (file)
@@ -25,7 +25,6 @@ struct blk_mq_ctx {
        struct kobject          kobj;
 } ____cacheline_aligned_in_smp;
 
-void __blk_mq_complete_request(struct request *rq);
 void blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx, bool async);
 void blk_mq_freeze_queue(struct request_queue *q);
 void blk_mq_free_queue(struct request_queue *q);
index 1396ad0787fc6b84ebdd9a9d552ce7eaccf1e698..b4c24fe3dcfb5ed575350406c9dd7ece3c006aef 100644 (file)
@@ -181,9 +181,14 @@ static int hash_accept(struct socket *sock, struct socket *newsock, int flags)
        struct sock *sk2;
        struct alg_sock *ask2;
        struct hash_ctx *ctx2;
+       bool more;
        int err;
 
-       err = crypto_ahash_export(req, state);
+       lock_sock(sk);
+       more = ctx->more;
+       err = more ? crypto_ahash_export(req, state) : 0;
+       release_sock(sk);
+
        if (err)
                return err;
 
@@ -194,7 +199,10 @@ static int hash_accept(struct socket *sock, struct socket *newsock, int flags)
        sk2 = newsock->sk;
        ask2 = alg_sk(sk2);
        ctx2 = ask2->private;
-       ctx2->more = 1;
+       ctx2->more = more;
+
+       if (!more)
+               return err;
 
        err = crypto_ahash_import(&ctx2->req, state);
        if (err) {
index 3000ea3b6687451df7b5459e01cbf4215f9e9c85..021d39c0ba75a8ce3c8c6cb4ea2c41cddd954ad7 100644 (file)
@@ -531,7 +531,11 @@ int x509_decode_time(time64_t *_t,  size_t hdrlen,
        if (*p != 'Z')
                goto unsupported_time;
 
-       mon_len = month_lengths[mon];
+       if (year < 1970 ||
+           mon < 1 || mon > 12)
+               goto invalid_time;
+
+       mon_len = month_lengths[mon - 1];
        if (mon == 2) {
                if (year % 4 == 0) {
                        mon_len = 29;
@@ -543,14 +547,12 @@ int x509_decode_time(time64_t *_t,  size_t hdrlen,
                }
        }
 
-       if (year < 1970 ||
-           mon < 1 || mon > 12 ||
-           day < 1 || day > mon_len ||
+       if (day < 1 || day > mon_len ||
            hour > 23 ||
            min > 59 ||
            sec > 59)
                goto invalid_time;
-       
+
        *_t = mktime64(year, mon, day, hour, min, sec);
        return 0;
 
index 06a67d5f28461a0ea5a29f7791f7865e45979082..296b7a14893aabba895c578e8671e36b34875a37 100644 (file)
@@ -103,7 +103,12 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev)
        pdevinfo.res = resources;
        pdevinfo.num_res = count;
        pdevinfo.fwnode = acpi_fwnode_handle(adev);
-       pdevinfo.dma_mask = acpi_check_dma(adev, NULL) ? DMA_BIT_MASK(32) : 0;
+
+       if (acpi_dma_supported(adev))
+               pdevinfo.dma_mask = DMA_BIT_MASK(32);
+       else
+               pdevinfo.dma_mask = 0;
+
        pdev = platform_device_register_full(&pdevinfo);
        if (IS_ERR(pdev))
                dev_err(&adev->dev, "platform device creation failed: %ld\n",
index 5778e8e4313a191629dbe00a459e0c2fb5e1ec58..3405f7a41e2576415d344eb0782323ba469ea0a4 100644 (file)
@@ -77,6 +77,12 @@ module_param(allow_duplicates, bool, 0644);
 static int disable_backlight_sysfs_if = -1;
 module_param(disable_backlight_sysfs_if, int, 0444);
 
+static bool device_id_scheme = false;
+module_param(device_id_scheme, bool, 0444);
+
+static bool only_lcd = false;
+module_param(only_lcd, bool, 0444);
+
 static int register_count;
 static DEFINE_MUTEX(register_count_mutex);
 static struct mutex video_list_lock;
@@ -394,6 +400,18 @@ static int video_disable_backlight_sysfs_if(
        return 0;
 }
 
+static int video_set_device_id_scheme(const struct dmi_system_id *d)
+{
+       device_id_scheme = true;
+       return 0;
+}
+
+static int video_enable_only_lcd(const struct dmi_system_id *d)
+{
+       only_lcd = true;
+       return 0;
+}
+
 static struct dmi_system_id video_dmi_table[] = {
        /*
         * Broken _BQC workaround http://bugzilla.kernel.org/show_bug.cgi?id=13121
@@ -455,6 +473,33 @@ static struct dmi_system_id video_dmi_table[] = {
                DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE R830"),
                },
        },
+       /*
+        * Some machine's _DOD IDs don't have bit 31(Device ID Scheme) set
+        * but the IDs actually follow the Device ID Scheme.
+        */
+       {
+        /* https://bugzilla.kernel.org/show_bug.cgi?id=104121 */
+        .callback = video_set_device_id_scheme,
+        .ident = "ESPRIMO Mobile M9410",
+        .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile M9410"),
+               },
+       },
+       /*
+        * Some machines have multiple video output devices, but only the one
+        * that is the type of LCD can do the backlight control so we should not
+        * register backlight interface for other video output devices.
+        */
+       {
+        /* https://bugzilla.kernel.org/show_bug.cgi?id=104121 */
+        .callback = video_enable_only_lcd,
+        .ident = "ESPRIMO Mobile M9410",
+        .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile M9410"),
+               },
+       },
        {}
 };
 
@@ -1003,7 +1048,7 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
 
        attribute = acpi_video_get_device_attr(video, device_id);
 
-       if (attribute && attribute->device_id_scheme) {
+       if (attribute && (attribute->device_id_scheme || device_id_scheme)) {
                switch (attribute->display_type) {
                case ACPI_VIDEO_DISPLAY_CRT:
                        data->flags.crt = 1;
@@ -1568,15 +1613,6 @@ static void acpi_video_dev_register_backlight(struct acpi_video_device *device)
        static int count;
        char *name;
 
-       /*
-        * Do not create backlight device for video output
-        * device that is not in the enumerated list.
-        */
-       if (!acpi_video_device_in_dod(device)) {
-               dev_dbg(&device->dev->dev, "not in _DOD list, ignore\n");
-               return;
-       }
-
        result = acpi_video_init_brightness(device);
        if (result)
                return;
@@ -1657,6 +1693,22 @@ static void acpi_video_run_bcl_for_osi(struct acpi_video_bus *video)
        mutex_unlock(&video->device_list_lock);
 }
 
+static bool acpi_video_should_register_backlight(struct acpi_video_device *dev)
+{
+       /*
+        * Do not create backlight device for video output
+        * device that is not in the enumerated list.
+        */
+       if (!acpi_video_device_in_dod(dev)) {
+               dev_dbg(&dev->dev->dev, "not in _DOD list, ignore\n");
+               return false;
+       }
+
+       if (only_lcd)
+               return dev->flags.lcd;
+       return true;
+}
+
 static int acpi_video_bus_register_backlight(struct acpi_video_bus *video)
 {
        struct acpi_video_device *dev;
@@ -1670,8 +1722,10 @@ static int acpi_video_bus_register_backlight(struct acpi_video_bus *video)
                return 0;
 
        mutex_lock(&video->device_list_lock);
-       list_for_each_entry(dev, &video->video_device_list, entry)
-               acpi_video_dev_register_backlight(dev);
+       list_for_each_entry(dev, &video->video_device_list, entry) {
+               if (acpi_video_should_register_backlight(dev))
+                       acpi_video_dev_register_backlight(dev);
+       }
        mutex_unlock(&video->device_list_lock);
 
        video->backlight_registered = true;
index 1470ae4f98c07ce6e358bd53bf17b0c0b209b1cb..5ea5dc219f563702e5bad7141832af2861e9144a 100644 (file)
@@ -168,7 +168,7 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
        struct list_head *physnode_list;
        unsigned int node_id;
        int retval = -EINVAL;
-       bool coherent;
+       enum dev_dma_attr attr;
 
        if (has_acpi_companion(dev)) {
                if (acpi_dev) {
@@ -225,8 +225,10 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
        if (!has_acpi_companion(dev))
                ACPI_COMPANION_SET(dev, acpi_dev);
 
-       if (acpi_check_dma(acpi_dev, &coherent))
-               arch_setup_dma_ops(dev, 0, 0, NULL, coherent);
+       attr = acpi_get_dma_attr(acpi_dev);
+       if (attr != DEV_DMA_NOT_SUPPORTED)
+               arch_setup_dma_ops(dev, 0, 0, NULL,
+                                  attr == DEV_DMA_COHERENT);
 
        acpi_physnode_link_name(physical_node_name, node_id);
        retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
index daf9fc8329e64c41817269d0b6c437e3ccb2d1e3..78d5f02a073bb1c9e84beaeaf2f38b6f54125333 100644 (file)
@@ -1308,6 +1308,48 @@ void acpi_free_pnp_ids(struct acpi_device_pnp *pnp)
        kfree(pnp->unique_id);
 }
 
+/**
+ * acpi_dma_supported - Check DMA support for the specified device.
+ * @adev: The pointer to acpi device
+ *
+ * Return false if DMA is not supported. Otherwise, return true
+ */
+bool acpi_dma_supported(struct acpi_device *adev)
+{
+       if (!adev)
+               return false;
+
+       if (adev->flags.cca_seen)
+               return true;
+
+       /*
+       * Per ACPI 6.0 sec 6.2.17, assume devices can do cache-coherent
+       * DMA on "Intel platforms".  Presumably that includes all x86 and
+       * ia64, and other arches will set CONFIG_ACPI_CCA_REQUIRED=y.
+       */
+       if (!IS_ENABLED(CONFIG_ACPI_CCA_REQUIRED))
+               return true;
+
+       return false;
+}
+
+/**
+ * acpi_get_dma_attr - Check the supported DMA attr for the specified device.
+ * @adev: The pointer to acpi device
+ *
+ * Return enum dev_dma_attr.
+ */
+enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
+{
+       if (!acpi_dma_supported(adev))
+               return DEV_DMA_NOT_SUPPORTED;
+
+       if (adev->flags.coherent_dma)
+               return DEV_DMA_COHERENT;
+       else
+               return DEV_DMA_NON_COHERENT;
+}
+
 static void acpi_init_coherency(struct acpi_device *adev)
 {
        unsigned long long cca = 0;
index 30d8518b25fbcfdb0ed11121c8725fb229ca17ba..82707f9824cae1a322411d486b486c48864be611 100644 (file)
@@ -315,7 +315,7 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
                        if (crt == -1) {
                                tz->trips.critical.flags.valid = 0;
                        } else if (crt > 0) {
-                               unsigned long crt_k = CELSIUS_TO_KELVIN(crt);
+                               unsigned long crt_k = CELSIUS_TO_DECI_KELVIN(crt);
                                /*
                                 * Allow override critical threshold
                                 */
@@ -351,7 +351,7 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
                if (psv == -1) {
                        status = AE_SUPPORT;
                } else if (psv > 0) {
-                       tmp = CELSIUS_TO_KELVIN(psv);
+                       tmp = CELSIUS_TO_DECI_KELVIN(psv);
                        status = AE_OK;
                } else {
                        status = acpi_evaluate_integer(tz->device->handle,
@@ -431,7 +431,7 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
                                        break;
                                if (i == 1)
                                        tz->trips.active[0].temperature =
-                                               CELSIUS_TO_KELVIN(act);
+                                               CELSIUS_TO_DECI_KELVIN(act);
                                else
                                        /*
                                         * Don't allow override higher than
@@ -439,9 +439,9 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
                                         */
                                        tz->trips.active[i - 1].temperature =
                                                (tz->trips.active[i - 2].temperature <
-                                               CELSIUS_TO_KELVIN(act) ?
+                                               CELSIUS_TO_DECI_KELVIN(act) ?
                                                tz->trips.active[i - 2].temperature :
-                                               CELSIUS_TO_KELVIN(act));
+                                               CELSIUS_TO_DECI_KELVIN(act));
                                break;
                        } else {
                                tz->trips.active[i].temperature = tmp;
@@ -1105,7 +1105,7 @@ static int acpi_thermal_add(struct acpi_device *device)
        INIT_WORK(&tz->thermal_check_work, acpi_thermal_check_fn);
 
        pr_info(PREFIX "%s [%s] (%ld C)\n", acpi_device_name(device),
-               acpi_device_bid(device), KELVIN_TO_CELSIUS(tz->temperature));
+               acpi_device_bid(device), DECI_KELVIN_TO_CELSIUS(tz->temperature));
        goto end;
 
 free_memory:
index 0d3a384b508a9c4782b7fe20ca1264dc3b11b0bf..daaf1c4e1e0f78657afb1f140b49e0cf3162d6df 100644 (file)
@@ -232,6 +232,15 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
                          "900X3C/900X3D/900X3E/900X4C/900X4D"),
                },
        },
+       {
+        /* https://bugzilla.redhat.com/show_bug.cgi?id=1272633 */
+        .callback = video_detect_force_video,
+        .ident = "Dell XPS14 L421X",
+        .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+               DMI_MATCH(DMI_PRODUCT_NAME, "XPS L421X"),
+               },
+       },
        {
         /* https://bugzilla.redhat.com/show_bug.cgi?id=1163574 */
         .callback = video_detect_force_video,
index 8b3a7861fa44c205490788d4538e5da300270ffb..7e959f90c0203f9b94124ab73867e4a72bd11188 100644 (file)
@@ -3696,9 +3696,6 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht)
                 */
                shost->max_host_blocked = 1;
 
-               if (scsi_init_shared_tag_map(shost, host->n_tags))
-                       goto err_add;
-
                rc = scsi_add_host_with_dma(ap->scsi_host,
                                                &ap->tdev, ap->host->dev);
                if (rc)
index 80e29887038830a7bac36fe79d8c53912b828d81..e03b1ad25a906334078490786dbd1406ac9ca76b 100644 (file)
@@ -321,8 +321,7 @@ static int genpd_poweroff(struct generic_pm_domain *genpd, bool is_async)
                if (stat > PM_QOS_FLAGS_NONE)
                        return -EBUSY;
 
-               if (pdd->dev->driver && (!pm_runtime_suspended(pdd->dev)
-                   || pdd->dev->power.irq_safe))
+               if (!pm_runtime_suspended(pdd->dev) || pdd->dev->power.irq_safe)
                        not_suspended++;
        }
 
@@ -1312,13 +1311,17 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd,
 int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
                           struct generic_pm_domain *subdomain)
 {
-       struct gpd_link *link;
+       struct gpd_link *link, *itr;
        int ret = 0;
 
        if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain)
            || genpd == subdomain)
                return -EINVAL;
 
+       link = kzalloc(sizeof(*link), GFP_KERNEL);
+       if (!link)
+               return -ENOMEM;
+
        mutex_lock(&genpd->lock);
        mutex_lock_nested(&subdomain->lock, SINGLE_DEPTH_NESTING);
 
@@ -1328,18 +1331,13 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
                goto out;
        }
 
-       list_for_each_entry(link, &genpd->master_links, master_node) {
-               if (link->slave == subdomain && link->master == genpd) {
+       list_for_each_entry(itr, &genpd->master_links, master_node) {
+               if (itr->slave == subdomain && itr->master == genpd) {
                        ret = -EINVAL;
                        goto out;
                }
        }
 
-       link = kzalloc(sizeof(*link), GFP_KERNEL);
-       if (!link) {
-               ret = -ENOMEM;
-               goto out;
-       }
        link->master = genpd;
        list_add_tail(&link->master_node, &genpd->master_links);
        link->slave = subdomain;
@@ -1350,7 +1348,8 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
  out:
        mutex_unlock(&subdomain->lock);
        mutex_unlock(&genpd->lock);
-
+       if (ret)
+               kfree(link);
        return ret;
 }
 EXPORT_SYMBOL_GPL(pm_genpd_add_subdomain);
index d5c1149ff123c335b58e1f8ee68ed97a66784fec..b8e76f75073b47a945b695506bb68176c586a161 100644 (file)
@@ -11,6 +11,8 @@
  * published by the Free Software Foundation.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/errno.h>
 #include <linux/err.h>
 #include <linux/slab.h>
@@ -27,7 +29,7 @@
  */
 static LIST_HEAD(dev_opp_list);
 /* Lock to allow exclusive modification to the device and opp lists */
-static DEFINE_MUTEX(dev_opp_list_lock);
+DEFINE_MUTEX(dev_opp_list_lock);
 
 #define opp_rcu_lockdep_assert()                                       \
 do {                                                                   \
@@ -79,14 +81,18 @@ static struct device_opp *_managed_opp(const struct device_node *np)
  * Return: pointer to 'struct device_opp' if found, otherwise -ENODEV or
  * -EINVAL based on type of error.
  *
- * Locking: This function must be called under rcu_read_lock(). device_opp
- * is a RCU protected pointer. This means that device_opp is valid as long
- * as we are under RCU lock.
+ * Locking: For readers, this function must be called under rcu_read_lock().
+ * device_opp is a RCU protected pointer, which means that device_opp is valid
+ * as long as we are under RCU lock.
+ *
+ * For Writers, this function must be called with dev_opp_list_lock held.
  */
 struct device_opp *_find_device_opp(struct device *dev)
 {
        struct device_opp *dev_opp;
 
+       opp_rcu_lockdep_assert();
+
        if (IS_ERR_OR_NULL(dev)) {
                pr_err("%s: Invalid parameters\n", __func__);
                return ERR_PTR(-EINVAL);
@@ -100,7 +106,7 @@ struct device_opp *_find_device_opp(struct device *dev)
 }
 
 /**
- * dev_pm_opp_get_voltage() - Gets the voltage corresponding to an available opp
+ * dev_pm_opp_get_voltage() - Gets the voltage corresponding to an opp
  * @opp:       opp for which voltage has to be returned for
  *
  * Return: voltage in micro volt corresponding to the opp, else
@@ -122,7 +128,7 @@ unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp)
        opp_rcu_lockdep_assert();
 
        tmp_opp = rcu_dereference(opp);
-       if (IS_ERR_OR_NULL(tmp_opp) || !tmp_opp->available)
+       if (IS_ERR_OR_NULL(tmp_opp))
                pr_err("%s: Invalid parameters\n", __func__);
        else
                v = tmp_opp->u_volt;
@@ -701,7 +707,7 @@ static int _opp_add(struct device *dev, struct dev_pm_opp *new_opp,
 }
 
 /**
- * _opp_add_dynamic() - Allocate a dynamic OPP.
+ * _opp_add_v1() - Allocate a OPP based on v1 bindings.
  * @dev:       device for which we do this operation
  * @freq:      Frequency in Hz for this OPP
  * @u_volt:    Voltage in uVolts for this OPP
@@ -727,8 +733,8 @@ static int _opp_add(struct device *dev, struct dev_pm_opp *new_opp,
  *             Duplicate OPPs (both freq and volt are same) and !opp->available
  * -ENOMEM     Memory allocation failure
  */
-static int _opp_add_dynamic(struct device *dev, unsigned long freq,
-                           long u_volt, bool dynamic)
+static int _opp_add_v1(struct device *dev, unsigned long freq, long u_volt,
+                      bool dynamic)
 {
        struct device_opp *dev_opp;
        struct dev_pm_opp *new_opp;
@@ -770,9 +776,10 @@ unlock:
 }
 
 /* TODO: Support multiple regulators */
-static int opp_get_microvolt(struct dev_pm_opp *opp, struct device *dev)
+static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev)
 {
        u32 microvolt[3] = {0};
+       u32 val;
        int count, ret;
 
        /* Missing property isn't a problem, but an invalid entry is */
@@ -805,6 +812,9 @@ static int opp_get_microvolt(struct dev_pm_opp *opp, struct device *dev)
        opp->u_volt_min = microvolt[1];
        opp->u_volt_max = microvolt[2];
 
+       if (!of_property_read_u32(opp->np, "opp-microamp", &val))
+               opp->u_amp = val;
+
        return 0;
 }
 
@@ -869,13 +879,10 @@ static int _opp_add_static_v2(struct device *dev, struct device_node *np)
        if (!of_property_read_u32(np, "clock-latency-ns", &val))
                new_opp->clock_latency_ns = val;
 
-       ret = opp_get_microvolt(new_opp, dev);
+       ret = opp_parse_supplies(new_opp, dev);
        if (ret)
                goto free_opp;
 
-       if (!of_property_read_u32(new_opp->np, "opp-microamp", &val))
-               new_opp->u_amp = val;
-
        ret = _opp_add(dev, new_opp, dev_opp);
        if (ret)
                goto free_opp;
@@ -939,7 +946,7 @@ unlock:
  */
 int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
 {
-       return _opp_add_dynamic(dev, freq, u_volt, true);
+       return _opp_add_v1(dev, freq, u_volt, true);
 }
 EXPORT_SYMBOL_GPL(dev_pm_opp_add);
 
@@ -1172,13 +1179,17 @@ static int _of_add_opp_table_v2(struct device *dev, struct device_node *opp_np)
        struct device_opp *dev_opp;
        int ret = 0, count = 0;
 
+       mutex_lock(&dev_opp_list_lock);
+
        dev_opp = _managed_opp(opp_np);
        if (dev_opp) {
                /* OPPs are already managed */
                if (!_add_list_dev(dev, dev_opp))
                        ret = -ENOMEM;
+               mutex_unlock(&dev_opp_list_lock);
                return ret;
        }
+       mutex_unlock(&dev_opp_list_lock);
 
        /* We have opp-list node now, iterate over it and add OPPs */
        for_each_available_child_of_node(opp_np, np) {
@@ -1196,15 +1207,20 @@ static int _of_add_opp_table_v2(struct device *dev, struct device_node *opp_np)
        if (WARN_ON(!count))
                return -ENOENT;
 
+       mutex_lock(&dev_opp_list_lock);
+
        dev_opp = _find_device_opp(dev);
        if (WARN_ON(IS_ERR(dev_opp))) {
                ret = PTR_ERR(dev_opp);
+               mutex_unlock(&dev_opp_list_lock);
                goto free_table;
        }
 
        dev_opp->np = opp_np;
        dev_opp->shared_opp = of_property_read_bool(opp_np, "opp-shared");
 
+       mutex_unlock(&dev_opp_list_lock);
+
        return 0;
 
 free_table:
@@ -1241,7 +1257,7 @@ static int _of_add_opp_table_v1(struct device *dev)
                unsigned long freq = be32_to_cpup(val++) * 1000;
                unsigned long volt = be32_to_cpup(val++);
 
-               if (_opp_add_dynamic(dev, freq, volt, false))
+               if (_opp_add_v1(dev, freq, volt, false))
                        dev_warn(dev, "%s: Failed to add OPP %ld\n",
                                 __func__, freq);
                nr -= 2;
index 7654c5606307f7e3d71903385964e3af9a71caea..7b445e88a0d559f091918be5e841f6a1380a33da 100644 (file)
@@ -10,6 +10,9 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/cpu.h>
 #include <linux/cpufreq.h>
 #include <linux/err.h>
@@ -124,12 +127,12 @@ int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, cpumask_var_t cpumask)
        struct device *dev;
        int cpu, ret = 0;
 
-       rcu_read_lock();
+       mutex_lock(&dev_opp_list_lock);
 
        dev_opp = _find_device_opp(cpu_dev);
        if (IS_ERR(dev_opp)) {
                ret = -EINVAL;
-               goto out_rcu_read_unlock;
+               goto unlock;
        }
 
        for_each_cpu(cpu, cpumask) {
@@ -150,10 +153,10 @@ int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, cpumask_var_t cpumask)
                        continue;
                }
        }
-out_rcu_read_unlock:
-       rcu_read_unlock();
+unlock:
+       mutex_unlock(&dev_opp_list_lock);
 
-       return 0;
+       return ret;
 }
 EXPORT_SYMBOL_GPL(dev_pm_opp_set_sharing_cpus);
 
index dcb38f78dae429dad1e6387c53fd984b967f64a4..7366b2aa8997897f89890cf99a4990d83e61a5a6 100644 (file)
@@ -21,6 +21,9 @@
 #include <linux/rculist.h>
 #include <linux/rcupdate.h>
 
+/* Lock to allow exclusive modification to the device and opp lists */
+extern struct mutex dev_opp_list_lock;
+
 /*
  * Internal data structure organization with the OPP layer library is as
  * follows:
index de40623bbd8a748fd81f3208810046d05861a75c..1325ff225cc4a5b37a7c0b3fe0b3d7946c37811e 100644 (file)
@@ -598,18 +598,34 @@ unsigned int device_get_child_node_count(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(device_get_child_node_count);
 
-bool device_dma_is_coherent(struct device *dev)
+bool device_dma_supported(struct device *dev)
 {
-       bool coherent = false;
-
+       /* For DT, this is always supported.
+        * For ACPI, this depends on CCA, which
+        * is determined by the acpi_dma_supported().
+        */
        if (IS_ENABLED(CONFIG_OF) && dev->of_node)
-               coherent = of_dma_is_coherent(dev->of_node);
-       else
-               acpi_check_dma(ACPI_COMPANION(dev), &coherent);
+               return true;
+
+       return acpi_dma_supported(ACPI_COMPANION(dev));
+}
+EXPORT_SYMBOL_GPL(device_dma_supported);
 
-       return coherent;
+enum dev_dma_attr device_get_dma_attr(struct device *dev)
+{
+       enum dev_dma_attr attr = DEV_DMA_NOT_SUPPORTED;
+
+       if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
+               if (of_dma_is_coherent(dev->of_node))
+                       attr = DEV_DMA_COHERENT;
+               else
+                       attr = DEV_DMA_NON_COHERENT;
+       } else
+               attr = acpi_get_dma_attr(ACPI_COMPANION(dev));
+
+       return attr;
 }
-EXPORT_SYMBOL_GPL(device_dma_is_coherent);
+EXPORT_SYMBOL_GPL(device_get_dma_attr);
 
 /**
  * device_get_phy_mode - Get phy mode for given device
index c9f9c30d646756296e0e4bdd212a33ba28a479b6..a5880f4ab40eb069bda60d6403b223d61ff1db80 100644 (file)
@@ -337,6 +337,9 @@ static blk_qc_t brd_make_request(struct request_queue *q, struct bio *bio)
                goto io_error;
 
        if (unlikely(bio->bi_rw & REQ_DISCARD)) {
+               if (sector & ((PAGE_SIZE >> SECTOR_SHIFT) - 1) ||
+                   bio->bi_iter.bi_size & PAGE_MASK)
+                       goto io_error;
                discard_from_brd(brd, sector, bio->bi_iter.bi_size);
                goto out;
        }
index 128e7df5b807222ba2d6f50148cb164919a308f7..235708c7c46eee709acb110acb95a28d85ebc946 100644 (file)
@@ -418,8 +418,6 @@ MODULE_PARM_DESC(single_major, "Use a single major number for all rbd devices (d
 
 static int rbd_img_request_submit(struct rbd_img_request *img_request);
 
-static void rbd_dev_device_release(struct device *dev);
-
 static ssize_t rbd_add(struct bus_type *bus, const char *buf,
                       size_t count);
 static ssize_t rbd_remove(struct bus_type *bus, const char *buf,
@@ -3991,14 +3989,12 @@ static const struct attribute_group *rbd_attr_groups[] = {
        NULL
 };
 
-static void rbd_sysfs_dev_release(struct device *dev)
-{
-}
+static void rbd_dev_release(struct device *dev);
 
 static struct device_type rbd_device_type = {
        .name           = "rbd",
        .groups         = rbd_attr_groups,
-       .release        = rbd_sysfs_dev_release,
+       .release        = rbd_dev_release,
 };
 
 static struct rbd_spec *rbd_spec_get(struct rbd_spec *spec)
@@ -4041,6 +4037,25 @@ static void rbd_spec_free(struct kref *kref)
        kfree(spec);
 }
 
+static void rbd_dev_release(struct device *dev)
+{
+       struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
+       bool need_put = !!rbd_dev->opts;
+
+       rbd_put_client(rbd_dev->rbd_client);
+       rbd_spec_put(rbd_dev->spec);
+       kfree(rbd_dev->opts);
+       kfree(rbd_dev);
+
+       /*
+        * This is racy, but way better than putting module outside of
+        * the release callback.  The race window is pretty small, so
+        * doing something similar to dm (dm-builtin.c) is overkill.
+        */
+       if (need_put)
+               module_put(THIS_MODULE);
+}
+
 static struct rbd_device *rbd_dev_create(struct rbd_client *rbdc,
                                         struct rbd_spec *spec,
                                         struct rbd_options *opts)
@@ -4057,6 +4072,11 @@ static struct rbd_device *rbd_dev_create(struct rbd_client *rbdc,
        INIT_LIST_HEAD(&rbd_dev->node);
        init_rwsem(&rbd_dev->header_rwsem);
 
+       rbd_dev->dev.bus = &rbd_bus_type;
+       rbd_dev->dev.type = &rbd_device_type;
+       rbd_dev->dev.parent = &rbd_root_dev;
+       device_initialize(&rbd_dev->dev);
+
        rbd_dev->rbd_client = rbdc;
        rbd_dev->spec = spec;
        rbd_dev->opts = opts;
@@ -4068,15 +4088,21 @@ static struct rbd_device *rbd_dev_create(struct rbd_client *rbdc,
        rbd_dev->layout.fl_object_size = cpu_to_le32(1 << RBD_MAX_OBJ_ORDER);
        rbd_dev->layout.fl_pg_pool = cpu_to_le32((u32) spec->pool_id);
 
+       /*
+        * If this is a mapping rbd_dev (as opposed to a parent one),
+        * pin our module.  We have a ref from do_rbd_add(), so use
+        * __module_get().
+        */
+       if (rbd_dev->opts)
+               __module_get(THIS_MODULE);
+
        return rbd_dev;
 }
 
 static void rbd_dev_destroy(struct rbd_device *rbd_dev)
 {
-       rbd_put_client(rbd_dev->rbd_client);
-       rbd_spec_put(rbd_dev->spec);
-       kfree(rbd_dev->opts);
-       kfree(rbd_dev);
+       if (rbd_dev)
+               put_device(&rbd_dev->dev);
 }
 
 /*
@@ -4702,27 +4728,6 @@ static int rbd_dev_header_info(struct rbd_device *rbd_dev)
        return rbd_dev_v2_header_info(rbd_dev);
 }
 
-static int rbd_bus_add_dev(struct rbd_device *rbd_dev)
-{
-       struct device *dev;
-       int ret;
-
-       dev = &rbd_dev->dev;
-       dev->bus = &rbd_bus_type;
-       dev->type = &rbd_device_type;
-       dev->parent = &rbd_root_dev;
-       dev->release = rbd_dev_device_release;
-       dev_set_name(dev, "%d", rbd_dev->dev_id);
-       ret = device_register(dev);
-
-       return ret;
-}
-
-static void rbd_bus_del_dev(struct rbd_device *rbd_dev)
-{
-       device_unregister(&rbd_dev->dev);
-}
-
 /*
  * Get a unique rbd identifier for the given new rbd_dev, and add
  * the rbd_dev to the global list.
@@ -5225,7 +5230,8 @@ static int rbd_dev_device_setup(struct rbd_device *rbd_dev)
        set_capacity(rbd_dev->disk, rbd_dev->mapping.size / SECTOR_SIZE);
        set_disk_ro(rbd_dev->disk, rbd_dev->mapping.read_only);
 
-       ret = rbd_bus_add_dev(rbd_dev);
+       dev_set_name(&rbd_dev->dev, "%d", rbd_dev->dev_id);
+       ret = device_add(&rbd_dev->dev);
        if (ret)
                goto err_out_mapping;
 
@@ -5248,8 +5254,6 @@ err_out_blkdev:
                unregister_blkdev(rbd_dev->major, rbd_dev->name);
 err_out_id:
        rbd_dev_id_put(rbd_dev);
-       rbd_dev_mapping_clear(rbd_dev);
-
        return ret;
 }
 
@@ -5397,7 +5401,7 @@ static ssize_t do_rbd_add(struct bus_type *bus,
        struct rbd_spec *spec = NULL;
        struct rbd_client *rbdc;
        bool read_only;
-       int rc = -ENOMEM;
+       int rc;
 
        if (!try_module_get(THIS_MODULE))
                return -ENODEV;
@@ -5405,7 +5409,7 @@ static ssize_t do_rbd_add(struct bus_type *bus,
        /* parse add command */
        rc = rbd_add_parse_args(buf, &ceph_opts, &rbd_opts, &spec);
        if (rc < 0)
-               goto err_out_module;
+               goto out;
 
        rbdc = rbd_get_client(ceph_opts);
        if (IS_ERR(rbdc)) {
@@ -5432,8 +5436,10 @@ static ssize_t do_rbd_add(struct bus_type *bus,
        }
 
        rbd_dev = rbd_dev_create(rbdc, spec, rbd_opts);
-       if (!rbd_dev)
+       if (!rbd_dev) {
+               rc = -ENOMEM;
                goto err_out_client;
+       }
        rbdc = NULL;            /* rbd_dev now owns this */
        spec = NULL;            /* rbd_dev now owns this */
        rbd_opts = NULL;        /* rbd_dev now owns this */
@@ -5458,10 +5464,13 @@ static ssize_t do_rbd_add(struct bus_type *bus,
                 */
                rbd_dev_header_unwatch_sync(rbd_dev);
                rbd_dev_image_release(rbd_dev);
-               goto err_out_module;
+               goto out;
        }
 
-       return count;
+       rc = count;
+out:
+       module_put(THIS_MODULE);
+       return rc;
 
 err_out_rbd_dev:
        rbd_dev_destroy(rbd_dev);
@@ -5470,12 +5479,7 @@ err_out_client:
 err_out_args:
        rbd_spec_put(spec);
        kfree(rbd_opts);
-err_out_module:
-       module_put(THIS_MODULE);
-
-       dout("Error adding device %s\n", buf);
-
-       return (ssize_t)rc;
+       goto out;
 }
 
 static ssize_t rbd_add(struct bus_type *bus,
@@ -5495,17 +5499,15 @@ static ssize_t rbd_add_single_major(struct bus_type *bus,
        return do_rbd_add(bus, buf, count);
 }
 
-static void rbd_dev_device_release(struct device *dev)
+static void rbd_dev_device_release(struct rbd_device *rbd_dev)
 {
-       struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
-
        rbd_free_disk(rbd_dev);
        clear_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags);
+       device_del(&rbd_dev->dev);
        rbd_dev_mapping_clear(rbd_dev);
        if (!single_major)
                unregister_blkdev(rbd_dev->major, rbd_dev->name);
        rbd_dev_id_put(rbd_dev);
-       rbd_dev_mapping_clear(rbd_dev);
 }
 
 static void rbd_dev_remove_parent(struct rbd_device *rbd_dev)
@@ -5590,9 +5592,8 @@ static ssize_t do_rbd_remove(struct bus_type *bus,
         * rbd_bus_del_dev() will race with rbd_watch_cb(), resulting
         * in a potential use after free of rbd_dev->disk or rbd_dev.
         */
-       rbd_bus_del_dev(rbd_dev);
+       rbd_dev_device_release(rbd_dev);
        rbd_dev_image_release(rbd_dev);
-       module_put(THIS_MODULE);
 
        return count;
 }
@@ -5663,10 +5664,8 @@ static int rbd_slab_init(void)
        if (rbd_segment_name_cache)
                return 0;
 out_err:
-       if (rbd_obj_request_cache) {
-               kmem_cache_destroy(rbd_obj_request_cache);
-               rbd_obj_request_cache = NULL;
-       }
+       kmem_cache_destroy(rbd_obj_request_cache);
+       rbd_obj_request_cache = NULL;
 
        kmem_cache_destroy(rbd_img_request_cache);
        rbd_img_request_cache = NULL;
index f26b0ae23bea77719c5f6e13e9cfcc33d5706405..45cc39aabeeeb8fde7967971516a4efad50d2caa 100644 (file)
@@ -226,21 +226,23 @@ int tpm_chip_register(struct tpm_chip *chip)
        if (rc)
                goto out_err;
 
-       if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) {
-               rc = __compat_only_sysfs_link_entry_to_kobj(&chip->pdev->kobj,
-                                                           &chip->dev.kobj,
-                                                           "ppi");
-               if (rc)
-                       goto out_err;
-       }
-
        /* Make the chip available. */
        spin_lock(&driver_lock);
-       list_add_rcu(&chip->list, &tpm_chip_list);
+       list_add_tail_rcu(&chip->list, &tpm_chip_list);
        spin_unlock(&driver_lock);
 
        chip->flags |= TPM_CHIP_FLAG_REGISTERED;
 
+       if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) {
+               rc = __compat_only_sysfs_link_entry_to_kobj(&chip->pdev->kobj,
+                                                           &chip->dev.kobj,
+                                                           "ppi");
+               if (rc && rc != -ENOENT) {
+                       tpm_chip_unregister(chip);
+                       return rc;
+               }
+       }
+
        return 0;
 out_err:
        tpm1_chip_unregister(chip);
index bd7039fafa8aa7c34326e7a2270cd09e42837d81..c12130485fc18e966c9e41736e57bd7fd0586082 100644 (file)
@@ -443,12 +443,13 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
                             TPM_DIGEST_SIZE);
 
        /* sensitive */
-       tpm_buf_append_u16(&buf, 4 + TPM_DIGEST_SIZE + payload->key_len);
+       tpm_buf_append_u16(&buf, 4 + TPM_DIGEST_SIZE + payload->key_len + 1);
 
        tpm_buf_append_u16(&buf, TPM_DIGEST_SIZE);
        tpm_buf_append(&buf, options->blobauth, TPM_DIGEST_SIZE);
-       tpm_buf_append_u16(&buf, payload->key_len);
+       tpm_buf_append_u16(&buf, payload->key_len + 1);
        tpm_buf_append(&buf, payload->key, payload->key_len);
+       tpm_buf_append_u8(&buf, payload->migratable);
 
        /* public */
        tpm_buf_append_u16(&buf, 14);
@@ -573,6 +574,8 @@ static int tpm2_unseal(struct tpm_chip *chip,
                       u32 blob_handle)
 {
        struct tpm_buf buf;
+       u16 data_len;
+       u8 *data;
        int rc;
 
        rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_UNSEAL);
@@ -591,11 +594,13 @@ static int tpm2_unseal(struct tpm_chip *chip,
                rc = -EPERM;
 
        if (!rc) {
-               payload->key_len = be16_to_cpup(
+               data_len = be16_to_cpup(
                        (__be16 *) &buf.data[TPM_HEADER_SIZE + 4]);
+               data = &buf.data[TPM_HEADER_SIZE + 6];
 
-               memcpy(payload->key, &buf.data[TPM_HEADER_SIZE + 6],
-                      payload->key_len);
+               memcpy(payload->key, data, data_len - 1);
+               payload->key_len = data_len - 1;
+               payload->migratable = data[data_len - 1];
        }
 
        tpm_buf_destroy(&buf);
index 1141456a4b1f1b974192e89574af9e165051922b..570f30c5c5f42ee5ee8076e17f45301de11ecf59 100644 (file)
@@ -53,17 +53,18 @@ int read_log(struct tpm_bios_log *log)
                goto cleanup_eio;
        }
 
-       of_node_put(np);
        log->bios_event_log = kmalloc(*sizep, GFP_KERNEL);
        if (!log->bios_event_log) {
                pr_err("%s: ERROR - Not enough memory for BIOS measurements\n",
                       __func__);
+               of_node_put(np);
                return -ENOMEM;
        }
 
        log->bios_event_log_end = log->bios_event_log + *sizep;
 
        memcpy(log->bios_event_log, __va(*basep), *sizep);
+       of_node_put(np);
 
        return 0;
 
index 696ef1d56b4f5830682bc1227b72686c2906eefb..65f7eecc45b01c489e2381b2311a95f2898527df 100644 (file)
@@ -645,6 +645,7 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
 {
        u32 vendor, intfcaps, intmask;
        int rc, i, irq_s, irq_e, probe;
+       int irq_r = -1;
        struct tpm_chip *chip;
        struct priv_data *priv;
 
@@ -751,6 +752,7 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
                irq_s =
                    ioread8(chip->vendor.iobase +
                            TPM_INT_VECTOR(chip->vendor.locality));
+               irq_r = irq_s;
                if (irq_s) {
                        irq_e = irq_s;
                } else {
@@ -805,6 +807,8 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
                        iowrite32(intmask,
                                  chip->vendor.iobase +
                                  TPM_INT_ENABLE(chip->vendor.locality));
+
+                       devm_free_irq(dev, i, chip);
                }
        }
        if (chip->vendor.irq) {
@@ -831,7 +835,9 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
                                  chip->vendor.iobase +
                                  TPM_INT_ENABLE(chip->vendor.locality));
                }
-       }
+       } else if (irq_r != -1)
+               iowrite8(irq_r, chip->vendor.iobase +
+                        TPM_INT_VECTOR(chip->vendor.locality));
 
        if (chip->flags & TPM_CHIP_FLAG_TPM2) {
                chip->vendor.timeout_a = msecs_to_jiffies(TPM2_TIMEOUT_A);
index 1dd5d14d5dbe0f4cc6092ba535ef950440d323be..d71d01157dbb0ee0fe468db4f6f3156675936ce9 100644 (file)
@@ -19,6 +19,7 @@ static void __init h8300_div_clk_setup(struct device_node *node)
        const char *parent_name;
        void __iomem *divcr = NULL;
        int width;
+       int offset;
 
        num_parents = of_clk_get_parent_count(node);
        if (num_parents < 1) {
@@ -31,11 +32,14 @@ static void __init h8300_div_clk_setup(struct device_node *node)
                pr_err("%s: failed to map divide register", clk_name);
                goto error;
        }
+       offset = (unsigned long)divcr & 3;
+       offset = (3 - offset) * 8;
+       divcr = (void *)((unsigned long)divcr & ~3);
 
        parent_name = of_clk_get_parent_name(node, 0);
        of_property_read_u32(node, "renesas,width", &width);
        clk = clk_register_divider(NULL, clk_name, parent_name,
-                                  CLK_SET_RATE_GATE, divcr, 0, width,
+                                  CLK_SET_RATE_GATE, divcr, offset, width,
                                   CLK_DIVIDER_POWER_OF_TWO, &clklock);
        if (!IS_ERR(clk)) {
                of_clk_add_provider(node, of_clk_src_simple_get, clk);
index 02a1945e5093f7c3c9efa83ee1af822ecc2b127d..89d3e4d7900c51f384f3b90200c1fecb2bab013f 100644 (file)
@@ -140,9 +140,10 @@ static cycle_t gic_hpt_read(struct clocksource *cs)
 }
 
 static struct clocksource gic_clocksource = {
-       .name   = "GIC",
-       .read   = gic_hpt_read,
-       .flags  = CLOCK_SOURCE_IS_CONTINUOUS,
+       .name           = "GIC",
+       .read           = gic_hpt_read,
+       .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
+       .archdata       = { .vdso_clock_mode = VDSO_CLOCK_GIC },
 };
 
 static void __init __gic_clocksource_init(void)
index f1e42f8ce0fcc75a5e67ae4e5365d098d83cfc32..c5d256caa664a63731e0cb7db6f5b00e31c750d8 100644 (file)
@@ -149,6 +149,19 @@ bL_cpufreq_set_rate(u32 cpu, u32 old_cluster, u32 new_cluster, u32 rate)
                        __func__, cpu, old_cluster, new_cluster, new_rate);
 
        ret = clk_set_rate(clk[new_cluster], new_rate * 1000);
+       if (!ret) {
+               /*
+                * FIXME: clk_set_rate hasn't returned an error here however it
+                * may be that clk_change_rate failed due to hardware or
+                * firmware issues and wasn't able to report that due to the
+                * current design of the clk core layer. To work around this
+                * problem we will read back the clock rate and check it is
+                * correct. This needs to be removed once clk core is fixed.
+                */
+               if (clk_get_rate(clk[new_cluster]) != new_rate * 1000)
+                       ret = -EIO;
+       }
+
        if (WARN_ON(ret)) {
                pr_err("clk_set_rate failed: %d, new cluster: %d\n", ret,
                                new_cluster);
@@ -189,15 +202,6 @@ bL_cpufreq_set_rate(u32 cpu, u32 old_cluster, u32 new_cluster, u32 rate)
                mutex_unlock(&cluster_lock[old_cluster]);
        }
 
-       /*
-        * FIXME: clk_set_rate has to handle the case where clk_change_rate
-        * can fail due to hardware or firmware issues. Until the clk core
-        * layer is fixed, we can check here. In most of the cases we will
-        * be reading only the cached value anyway. This needs to  be removed
-        * once clk core is fixed.
-        */
-       if (bL_cpufreq_get_rate(cpu) != new_rate)
-               return -EIO;
        return 0;
 }
 
index 93c219fab850f7e268d46d1ff83a38f958963b26..e8cb334094b0d5d89df7d8f482515f7901ac28f5 100644 (file)
@@ -166,8 +166,7 @@ static int __init cppc_cpufreq_init(void)
 
 out:
        for_each_possible_cpu(i)
-               if (all_cpu_data[i])
-                       kfree(all_cpu_data[i]);
+               kfree(all_cpu_data[i]);
 
        kfree(all_cpu_data);
        return -ENODEV;
index 11258c4c1b175be37827c201a8d7a422a5d3eda3..b260576ddb129c9bf485a12a954d0b1db30e08c5 100644 (file)
@@ -171,10 +171,6 @@ void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy,
 {
        int i;
 
-       mutex_lock(&cpufreq_governor_lock);
-       if (!policy->governor_enabled)
-               goto out_unlock;
-
        if (!all_cpus) {
                /*
                 * Use raw_smp_processor_id() to avoid preemptible warnings.
@@ -188,9 +184,6 @@ void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy,
                for_each_cpu(i, policy->cpus)
                        __gov_queue_work(i, dbs_data, delay);
        }
-
-out_unlock:
-       mutex_unlock(&cpufreq_governor_lock);
 }
 EXPORT_SYMBOL_GPL(gov_queue_work);
 
@@ -229,13 +222,24 @@ static void dbs_timer(struct work_struct *work)
        struct cpu_dbs_info *cdbs = container_of(work, struct cpu_dbs_info,
                                                 dwork.work);
        struct cpu_common_dbs_info *shared = cdbs->shared;
-       struct cpufreq_policy *policy = shared->policy;
-       struct dbs_data *dbs_data = policy->governor_data;
+       struct cpufreq_policy *policy;
+       struct dbs_data *dbs_data;
        unsigned int sampling_rate, delay;
        bool modify_all = true;
 
        mutex_lock(&shared->timer_mutex);
 
+       policy = shared->policy;
+
+       /*
+        * Governor might already be disabled and there is no point continuing
+        * with the work-handler.
+        */
+       if (!policy)
+               goto unlock;
+
+       dbs_data = policy->governor_data;
+
        if (dbs_data->cdata->governor == GOV_CONSERVATIVE) {
                struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;
 
@@ -252,6 +256,7 @@ static void dbs_timer(struct work_struct *work)
        delay = dbs_data->cdata->gov_dbs_timer(cdbs, dbs_data, modify_all);
        gov_queue_work(dbs_data, policy, delay, modify_all);
 
+unlock:
        mutex_unlock(&shared->timer_mutex);
 }
 
@@ -478,9 +483,17 @@ static int cpufreq_governor_stop(struct cpufreq_policy *policy,
        if (!shared || !shared->policy)
                return -EBUSY;
 
+       /*
+        * Work-handler must see this updated, as it should not proceed any
+        * further after governor is disabled. And so timer_mutex is taken while
+        * updating this value.
+        */
+       mutex_lock(&shared->timer_mutex);
+       shared->policy = NULL;
+       mutex_unlock(&shared->timer_mutex);
+
        gov_cancel_work(dbs_data, policy);
 
-       shared->policy = NULL;
        mutex_destroy(&shared->timer_mutex);
        return 0;
 }
index 93a3c635ea2741fa4296c013b564ec6a7c27b827..2e31d097def6b884262295e0d46d0faa6418bd81 100644 (file)
@@ -684,8 +684,6 @@ static void __init intel_pstate_sysfs_expose_params(void)
 
 static void intel_pstate_hwp_enable(struct cpudata *cpudata)
 {
-       pr_info("intel_pstate: HWP enabled\n");
-
        wrmsrl_on_cpu(cpudata->cpu, MSR_PM_ENABLE, 0x1);
 }
 
@@ -1557,8 +1555,10 @@ static int __init intel_pstate_init(void)
        if (!all_cpu_data)
                return -ENOMEM;
 
-       if (static_cpu_has_safe(X86_FEATURE_HWP) && !no_hwp)
+       if (static_cpu_has_safe(X86_FEATURE_HWP) && !no_hwp) {
+               pr_info("intel_pstate: HWP enabled\n");
                hwp_active++;
+       }
 
        if (!hwp_active && hwp_only)
                goto out;
@@ -1593,8 +1593,10 @@ static int __init intel_pstate_setup(char *str)
 
        if (!strcmp(str, "disable"))
                no_load = 1;
-       if (!strcmp(str, "no_hwp"))
+       if (!strcmp(str, "no_hwp")) {
+               pr_info("intel_pstate: HWP disabled\n");
                no_hwp = 1;
+       }
        if (!strcmp(str, "force"))
                force_load = 1;
        if (!strcmp(str, "hwp_only"))
index 9e231f52150c404ebd92e6d74ea6a24b5642576a..051a8a8224cd7ade8b846e62fc27d0733ba8f73b 100644 (file)
@@ -212,11 +212,11 @@ static void s5pv210_set_refresh(enum s5pv210_dmc_port ch, unsigned long freq)
        /* Find current DRAM frequency */
        tmp = s5pv210_dram_conf[ch].freq;
 
-       do_div(tmp, freq);
+       tmp /= freq;
 
        tmp1 = s5pv210_dram_conf[ch].refresh;
 
-       do_div(tmp1, tmp);
+       tmp1 /= tmp;
 
        __raw_writel(tmp1, reg);
 }
index 8b923b7e9389aabd96ee10350c0f0ea9f66556f6..01b50cb4c9822abb8455f0f465ed8587ef4d3ef5 100644 (file)
@@ -94,6 +94,7 @@ static int ccp_platform_probe(struct platform_device *pdev)
        struct ccp_device *ccp;
        struct ccp_platform *ccp_platform;
        struct device *dev = &pdev->dev;
+       enum dev_dma_attr attr;
        struct resource *ior;
        int ret;
 
@@ -118,18 +119,24 @@ static int ccp_platform_probe(struct platform_device *pdev)
        }
        ccp->io_regs = ccp->io_map;
 
-       ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48));
-       if (ret) {
-               dev_err(dev, "dma_set_mask_and_coherent failed (%d)\n", ret);
+       attr = device_get_dma_attr(dev);
+       if (attr == DEV_DMA_NOT_SUPPORTED) {
+               dev_err(dev, "DMA is not supported");
                goto e_err;
        }
 
-       ccp_platform->coherent = device_dma_is_coherent(ccp->dev);
+       ccp_platform->coherent = (attr == DEV_DMA_COHERENT);
        if (ccp_platform->coherent)
                ccp->axcache = CACHE_WB_NO_ALLOC;
        else
                ccp->axcache = CACHE_NONE;
 
+       ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48));
+       if (ret) {
+               dev_err(dev, "dma_set_mask_and_coherent failed (%d)\n", ret);
+               goto e_err;
+       }
+
        dev_set_drvdata(dev, ccp);
 
        ret = ccp_init(ccp);
index 03856ad280b9349d650a0d06723a9f9da31e7c75..473d36d91644c2a00010d89dfc280d08c7ed343e 100644 (file)
@@ -198,7 +198,7 @@ static int adf_copy_key_value_data(struct adf_accel_dev *accel_dev,
                        goto out_err;
                }
 
-               params_head = section_head->params;
+               params_head = section.params;
 
                while (params_head) {
                        if (copy_from_user(&key_val, (void __user *)params_head,
index f51d376d10ba64e9bc5c8e2ecb953582011f90e9..c2f5117fd8cb00c48f42784dcef9c97ebaa92080 100644 (file)
@@ -3675,6 +3675,11 @@ static int pci_probe(struct pci_dev *dev,
 
        reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, ~0);
        ohci->it_context_support = reg_read(ohci, OHCI1394_IsoXmitIntMaskSet);
+       /* JMicron JMB38x often shows 0 at first read, just ignore it */
+       if (!ohci->it_context_support) {
+               ohci_notice(ohci, "overriding IsoXmitIntMask\n");
+               ohci->it_context_support = 0xf;
+       }
        reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, ~0);
        ohci->it_context_mask = ohci->it_context_support;
        ohci->n_it = hweight32(ohci->it_context_mask);
index eba6337f5860cddf62efbe9fc6829db0c55343f6..2151ea551d3bd6526d850754b79ece388a9279df 100644 (file)
@@ -616,10 +616,18 @@ int drm_control(struct drm_device *dev, void *data,
 void drm_calc_timestamping_constants(struct drm_crtc *crtc,
                                     const struct drm_display_mode *mode)
 {
-       struct drm_vblank_crtc *vblank = &crtc->dev->vblank[drm_crtc_index(crtc)];
+       struct drm_device *dev = crtc->dev;
+       unsigned int pipe = drm_crtc_index(crtc);
+       struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
        int linedur_ns = 0, framedur_ns = 0;
        int dotclock = mode->crtc_clock;
 
+       if (!dev->num_crtcs)
+               return;
+
+       if (WARN_ON(pipe >= dev->num_crtcs))
+               return;
+
        /* Valid dotclock? */
        if (dotclock > 0) {
                int frame_size = mode->crtc_htotal * mode->crtc_vtotal;
index d26e0cc7dc4ba9fd699861cb6af1dbe882629c4d..f22e1e1ee64aae52a1e3efb657a78790bd6ba573 100644 (file)
@@ -19,7 +19,6 @@
 #include <drm/drmP.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_fb_helper.h>
-#include <drm/drm_of.h>
 #include <linux/dma-mapping.h>
 #include <linux/pm_runtime.h>
 #include <linux/module.h>
@@ -419,6 +418,29 @@ static int compare_of(struct device *dev, void *data)
        return dev->of_node == np;
 }
 
+static void rockchip_add_endpoints(struct device *dev,
+                                  struct component_match **match,
+                                  struct device_node *port)
+{
+       struct device_node *ep, *remote;
+
+       for_each_child_of_node(port, ep) {
+               remote = of_graph_get_remote_port_parent(ep);
+               if (!remote || !of_device_is_available(remote)) {
+                       of_node_put(remote);
+                       continue;
+               } else if (!of_device_is_available(remote->parent)) {
+                       dev_warn(dev, "parent device of %s is not available\n",
+                                remote->full_name);
+                       of_node_put(remote);
+                       continue;
+               }
+
+               component_match_add(dev, match, compare_of, remote);
+               of_node_put(remote);
+       }
+}
+
 static int rockchip_drm_bind(struct device *dev)
 {
        struct drm_device *drm;
@@ -461,14 +483,61 @@ static const struct component_master_ops rockchip_drm_ops = {
 
 static int rockchip_drm_platform_probe(struct platform_device *pdev)
 {
-       int ret = drm_of_component_probe(&pdev->dev, compare_of,
-                                        &rockchip_drm_ops);
+       struct device *dev = &pdev->dev;
+       struct component_match *match = NULL;
+       struct device_node *np = dev->of_node;
+       struct device_node *port;
+       int i;
 
-       /* keep compatibility with old code that was returning -ENODEV */
-       if (ret == -EINVAL)
+       if (!np)
                return -ENODEV;
+       /*
+        * Bind the crtc ports first, so that
+        * drm_of_find_possible_crtcs called from encoder .bind callbacks
+        * works as expected.
+        */
+       for (i = 0;; i++) {
+               port = of_parse_phandle(np, "ports", i);
+               if (!port)
+                       break;
+
+               if (!of_device_is_available(port->parent)) {
+                       of_node_put(port);
+                       continue;
+               }
 
-       return ret;
+               component_match_add(dev, &match, compare_of, port->parent);
+               of_node_put(port);
+       }
+
+       if (i == 0) {
+               dev_err(dev, "missing 'ports' property\n");
+               return -ENODEV;
+       }
+
+       if (!match) {
+               dev_err(dev, "No available vop found for display-subsystem.\n");
+               return -ENODEV;
+       }
+       /*
+        * For each bound crtc, bind the encoders attached to its
+        * remote endpoint.
+        */
+       for (i = 0;; i++) {
+               port = of_parse_phandle(np, "ports", i);
+               if (!port)
+                       break;
+
+               if (!of_device_is_available(port->parent)) {
+                       of_node_put(port);
+                       continue;
+               }
+
+               rockchip_add_endpoints(dev, &match, port);
+               of_node_put(port);
+       }
+
+       return component_master_add_with_match(dev, &rockchip_drm_ops, match);
 }
 
 static int rockchip_drm_platform_remove(struct platform_device *pdev)
index fbccc105819b707c2b3be9383dfd1898cee239af..10c1b1926e6f9665b083df291632924d91c12ef5 100644 (file)
@@ -6,12 +6,6 @@ config DRM_STI
        select DRM_GEM_CMA_HELPER
        select DRM_KMS_CMA_HELPER
        select DRM_PANEL
-       select FW_LOADER_USER_HELPER_FALLBACK
+       select FW_LOADER
        help
          Choose this option to enable DRM on STM stiH41x chipset
-
-config DRM_STI_FBDEV
-       bool "DRM frame buffer device for STMicroelectronics SoC stiH41x Serie"
-       depends on DRM_STI
-       help
-         Choose this option to enable FBDEV on top of DRM for STM stiH41x chipset
index e27490b492a5280a254b9a196d452f429abb9466..b8057620b3b35702f23476584c15efc0d2a7763e 100644 (file)
@@ -1,26 +1,23 @@
-sticompositor-y := \
+sti-drm-y := \
        sti_mixer.o \
        sti_gdp.o \
        sti_vid.o \
        sti_cursor.o \
        sti_compositor.o \
        sti_crtc.o \
-       sti_plane.o
-
-stihdmi-y := sti_hdmi.o \
+       sti_plane.o \
+       sti_crtc.o \
+       sti_plane.o \
+       sti_hdmi.o \
        sti_hdmi_tx3g0c55phy.o \
        sti_hdmi_tx3g4c28phy.o \
-
-stidvo-y := sti_dvo.o \
-       sti_awg_utils.o
-
-obj-$(CONFIG_DRM_STI) = \
+       sti_dvo.o \
+       sti_awg_utils.o \
        sti_vtg.o \
        sti_vtac.o \
-       stihdmi.o \
        sti_hda.o \
        sti_tvout.o \
-       sticompositor.o \
        sti_hqvdp.o \
-       stidvo.o \
        sti_drv.o
+
+obj-$(CONFIG_DRM_STI) = sti-drm.o
index 6029a2e3db1dc8feb5243e992abef98594d2a766..00d0698be9d33e7b4517c9e39c186607676a8399 100644 (file)
@@ -65,7 +65,6 @@ static int awg_generate_instr(enum opcode opcode,
 
                        mux = 0;
                        data_enable = 0;
-                       arg = (arg << 22) >> 22;
                        arg &= (0x3ff);
                        break;
                case REPEAT:
@@ -77,14 +76,12 @@ static int awg_generate_instr(enum opcode opcode,
 
                        mux = 0;
                        data_enable = 0;
-                       arg = (arg << 22) >> 22;
                        arg &= (0x3ff);
                        break;
                case JUMP:
                        mux = 0;
                        data_enable = 0;
                        arg |= 0x40; /* for jump instruction 7th bit is 1 */
-                       arg = (arg << 22) >> 22;
                        arg &= 0x3ff;
                        break;
                case STOP:
@@ -94,7 +91,6 @@ static int awg_generate_instr(enum opcode opcode,
                case RPTSET:
                case RPLSET:
                case HOLD:
-                       arg = (arg << 24) >> 24;
                        arg &= (0x0ff);
                        break;
                default:
index c652627b1bcadbe05a1a759677724f7be8819c0a..afed2171beb9a4ce4e2a6031eb139fe0247b1ae0 100644 (file)
@@ -263,7 +263,7 @@ static int sti_compositor_remove(struct platform_device *pdev)
        return 0;
 }
 
-static struct platform_driver sti_compositor_driver = {
+struct platform_driver sti_compositor_driver = {
        .driver = {
                .name = "sti-compositor",
                .of_match_table = compositor_of_match,
@@ -272,8 +272,6 @@ static struct platform_driver sti_compositor_driver = {
        .remove = sti_compositor_remove,
 };
 
-module_platform_driver(sti_compositor_driver);
-
 MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
 MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
 MODULE_LICENSE("GPL");
index 493c4a3006adb4b62e7074aff5f68f80dc7463c3..3ae09dcd4fd86c65fad95b13fc60aa596a1271e4 100644 (file)
@@ -226,7 +226,7 @@ static void sti_crtc_atomic_flush(struct drm_crtc *crtc,
        }
 }
 
-static struct drm_crtc_helper_funcs sti_crtc_helper_funcs = {
+static const struct drm_crtc_helper_funcs sti_crtc_helper_funcs = {
        .enable = sti_crtc_enable,
        .disable = sti_crtc_disabling,
        .mode_fixup = sti_crtc_mode_fixup,
@@ -254,15 +254,17 @@ static int sti_crtc_set_property(struct drm_crtc *crtc,
 int sti_crtc_vblank_cb(struct notifier_block *nb,
                       unsigned long event, void *data)
 {
-       struct drm_device *drm_dev;
        struct sti_compositor *compo =
                container_of(nb, struct sti_compositor, vtg_vblank_nb);
-       int *crtc = data;
+       struct drm_crtc *crtc = data;
+       struct sti_mixer *mixer;
        unsigned long flags;
        struct sti_private *priv;
+       unsigned int pipe;
 
-       drm_dev = compo->mixer[*crtc]->drm_crtc.dev;
-       priv = drm_dev->dev_private;
+       priv = crtc->dev->dev_private;
+       pipe = drm_crtc_index(crtc);
+       mixer = compo->mixer[pipe];
 
        if ((event != VTG_TOP_FIELD_EVENT) &&
            (event != VTG_BOTTOM_FIELD_EVENT)) {
@@ -270,30 +272,30 @@ int sti_crtc_vblank_cb(struct notifier_block *nb,
                return -EINVAL;
        }
 
-       drm_handle_vblank(drm_dev, *crtc);
+       drm_crtc_handle_vblank(crtc);
 
-       spin_lock_irqsave(&drm_dev->event_lock, flags);
-       if (compo->mixer[*crtc]->pending_event) {
-               drm_send_vblank_event(drm_dev, -1,
-                                     compo->mixer[*crtc]->pending_event);
-               drm_vblank_put(drm_dev, *crtc);
-               compo->mixer[*crtc]->pending_event = NULL;
+       spin_lock_irqsave(&crtc->dev->event_lock, flags);
+       if (mixer->pending_event) {
+               drm_crtc_send_vblank_event(crtc, mixer->pending_event);
+               drm_crtc_vblank_put(crtc);
+               mixer->pending_event = NULL;
        }
-       spin_unlock_irqrestore(&drm_dev->event_lock, flags);
+       spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
 
-       if (compo->mixer[*crtc]->status == STI_MIXER_DISABLING) {
+       if (mixer->status == STI_MIXER_DISABLING) {
                struct drm_plane *p;
 
                /* Disable mixer only if all overlay planes (GDP and VDP)
                 * are disabled */
-               list_for_each_entry(p, &drm_dev->mode_config.plane_list, head) {
+               list_for_each_entry(p, &crtc->dev->mode_config.plane_list,
+                                   head) {
                        struct sti_plane *plane = to_sti_plane(p);
 
                        if ((plane->desc & STI_PLANE_TYPE_MASK) <= STI_VDP)
                                if (plane->status != STI_PLANE_DISABLED)
                                        return 0;
                }
-               sti_crtc_disable(&compo->mixer[*crtc]->drm_crtc);
+               sti_crtc_disable(crtc);
        }
 
        return 0;
@@ -304,25 +306,26 @@ int sti_crtc_enable_vblank(struct drm_device *dev, unsigned int pipe)
        struct sti_private *dev_priv = dev->dev_private;
        struct sti_compositor *compo = dev_priv->compo;
        struct notifier_block *vtg_vblank_nb = &compo->vtg_vblank_nb;
+       struct drm_crtc *crtc = &compo->mixer[pipe]->drm_crtc;
 
        DRM_DEBUG_DRIVER("\n");
 
        if (sti_vtg_register_client(pipe == STI_MIXER_MAIN ?
                        compo->vtg_main : compo->vtg_aux,
-                       vtg_vblank_nb, pipe)) {
+                       vtg_vblank_nb, crtc)) {
                DRM_ERROR("Cannot register VTG notifier\n");
                return -EINVAL;
        }
 
        return 0;
 }
-EXPORT_SYMBOL(sti_crtc_enable_vblank);
 
 void sti_crtc_disable_vblank(struct drm_device *drm_dev, unsigned int pipe)
 {
        struct sti_private *priv = drm_dev->dev_private;
        struct sti_compositor *compo = priv->compo;
        struct notifier_block *vtg_vblank_nb = &compo->vtg_vblank_nb;
+       struct drm_crtc *crtc = &compo->mixer[pipe]->drm_crtc;
 
        DRM_DEBUG_DRIVER("\n");
 
@@ -332,13 +335,12 @@ void sti_crtc_disable_vblank(struct drm_device *drm_dev, unsigned int pipe)
 
        /* free the resources of the pending requests */
        if (compo->mixer[pipe]->pending_event) {
-               drm_vblank_put(drm_dev, pipe);
+               drm_crtc_vblank_put(crtc);
                compo->mixer[pipe]->pending_event = NULL;
        }
 }
-EXPORT_SYMBOL(sti_crtc_disable_vblank);
 
-static struct drm_crtc_funcs sti_crtc_funcs = {
+static const struct drm_crtc_funcs sti_crtc_funcs = {
        .set_config = drm_atomic_helper_set_config,
        .page_flip = drm_atomic_helper_page_flip,
        .destroy = sti_crtc_destroy,
@@ -357,7 +359,6 @@ bool sti_crtc_is_main(struct drm_crtc *crtc)
 
        return false;
 }
-EXPORT_SYMBOL(sti_crtc_is_main);
 
 int sti_crtc_init(struct drm_device *drm_dev, struct sti_mixer *mixer,
                  struct drm_plane *primary, struct drm_plane *cursor)
index f8469967a0bfbb43dcf5faee539ac9b5d5b5f328..1469987949d88f8b43cfdd97990e925156a149ec 100644 (file)
@@ -107,7 +107,7 @@ static int sti_atomic_commit(struct drm_device *drm,
        return 0;
 }
 
-static struct drm_mode_config_funcs sti_mode_config_funcs = {
+static const struct drm_mode_config_funcs sti_mode_config_funcs = {
        .fb_create = drm_fb_cma_create,
        .atomic_check = drm_atomic_helper_check,
        .atomic_commit = sti_atomic_commit,
@@ -123,8 +123,8 @@ static void sti_mode_config_init(struct drm_device *dev)
         * this value would be used to check framebuffer size limitation
         * at drm_mode_addfb().
         */
-       dev->mode_config.max_width = STI_MAX_FB_HEIGHT;
-       dev->mode_config.max_height = STI_MAX_FB_WIDTH;
+       dev->mode_config.max_width = STI_MAX_FB_WIDTH;
+       dev->mode_config.max_height = STI_MAX_FB_HEIGHT;
 
        dev->mode_config.funcs = &sti_mode_config_funcs;
 }
@@ -160,11 +160,10 @@ static int sti_load(struct drm_device *dev, unsigned long flags)
 
        drm_mode_config_reset(dev);
 
-#ifdef CONFIG_DRM_STI_FBDEV
        drm_fbdev_cma_init(dev, 32,
                           dev->mode_config.num_crtc,
                           dev->mode_config.num_connector);
-#endif
+
        return 0;
 }
 
@@ -287,7 +286,29 @@ static struct platform_driver sti_platform_driver = {
        },
 };
 
-module_platform_driver(sti_platform_driver);
+static struct platform_driver * const drivers[] = {
+       &sti_tvout_driver,
+       &sti_vtac_driver,
+       &sti_hqvdp_driver,
+       &sti_hdmi_driver,
+       &sti_hda_driver,
+       &sti_dvo_driver,
+       &sti_vtg_driver,
+       &sti_compositor_driver,
+       &sti_platform_driver,
+};
+
+static int sti_drm_init(void)
+{
+       return platform_register_drivers(drivers, ARRAY_SIZE(drivers));
+}
+module_init(sti_drm_init);
+
+static void sti_drm_exit(void)
+{
+       platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
+}
+module_exit(sti_drm_exit);
 
 MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
 MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
index 9372f69e1859ff96986b0cea5c795f3d3325c047..30ddc20841c343a6b1c904864107e6b4a4d732a0 100644 (file)
@@ -32,4 +32,13 @@ struct sti_private {
        } commit;
 };
 
+extern struct platform_driver sti_tvout_driver;
+extern struct platform_driver sti_vtac_driver;
+extern struct platform_driver sti_hqvdp_driver;
+extern struct platform_driver sti_hdmi_driver;
+extern struct platform_driver sti_hda_driver;
+extern struct platform_driver sti_dvo_driver;
+extern struct platform_driver sti_vtg_driver;
+extern struct platform_driver sti_compositor_driver;
+
 #endif
index d141d645bd13acd47c99b9c6b1de839e442fc280..45cbe2bf7dd60da4dbe6b513e21f8a890509c894 100644 (file)
@@ -329,7 +329,8 @@ struct drm_encoder *sti_dvo_best_encoder(struct drm_connector *connector)
        return dvo_connector->encoder;
 }
 
-static struct drm_connector_helper_funcs sti_dvo_connector_helper_funcs = {
+static const
+struct drm_connector_helper_funcs sti_dvo_connector_helper_funcs = {
        .get_modes = sti_dvo_connector_get_modes,
        .mode_valid = sti_dvo_connector_mode_valid,
        .best_encoder = sti_dvo_best_encoder,
@@ -364,7 +365,7 @@ static void sti_dvo_connector_destroy(struct drm_connector *connector)
        kfree(dvo_connector);
 }
 
-static struct drm_connector_funcs sti_dvo_connector_funcs = {
+static const struct drm_connector_funcs sti_dvo_connector_funcs = {
        .dpms = drm_atomic_helper_connector_dpms,
        .fill_modes = drm_helper_probe_single_connector_modes,
        .detect = sti_dvo_connector_detect,
@@ -557,8 +558,6 @@ struct platform_driver sti_dvo_driver = {
        .remove = sti_dvo_remove,
 };
 
-module_platform_driver(sti_dvo_driver);
-
 MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
 MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
 MODULE_LICENSE("GPL");
index 9365670427ad26ef7224b085557c678769c63c6c..c85dc7d6b0053d2f45a673e43bbda6b99032bcf7 100644 (file)
@@ -492,7 +492,7 @@ static void sti_gdp_atomic_update(struct drm_plane *drm_plane,
                /* Register gdp callback */
                if (sti_vtg_register_client(mixer->id == STI_MIXER_MAIN ?
                                compo->vtg_main : compo->vtg_aux,
-                               &gdp->vtg_field_nb, mixer->id)) {
+                               &gdp->vtg_field_nb, crtc)) {
                        DRM_ERROR("Cannot register VTG notifier\n");
                        return;
                }
index 598cd78b0b163cd2e86f92a68e5386325a3a357f..d735daccd4589b03528dd61eb350f9ded3b1da2d 100644 (file)
@@ -589,7 +589,8 @@ struct drm_encoder *sti_hda_best_encoder(struct drm_connector *connector)
        return hda_connector->encoder;
 }
 
-static struct drm_connector_helper_funcs sti_hda_connector_helper_funcs = {
+static const
+struct drm_connector_helper_funcs sti_hda_connector_helper_funcs = {
        .get_modes = sti_hda_connector_get_modes,
        .mode_valid = sti_hda_connector_mode_valid,
        .best_encoder = sti_hda_best_encoder,
@@ -611,7 +612,7 @@ static void sti_hda_connector_destroy(struct drm_connector *connector)
        kfree(hda_connector);
 }
 
-static struct drm_connector_funcs sti_hda_connector_funcs = {
+static const struct drm_connector_funcs sti_hda_connector_funcs = {
        .dpms = drm_atomic_helper_connector_dpms,
        .fill_modes = drm_helper_probe_single_connector_modes,
        .detect = sti_hda_connector_detect,
@@ -784,8 +785,6 @@ struct platform_driver sti_hda_driver = {
        .remove = sti_hda_remove,
 };
 
-module_platform_driver(sti_hda_driver);
-
 MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
 MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
 MODULE_LICENSE("GPL");
index 09e29e43423e21e6326b54e159ed81ffc4114b86..cd501563c0cc58f83b9992e7e83e09e048dfd32a 100644 (file)
@@ -628,7 +628,8 @@ struct drm_encoder *sti_hdmi_best_encoder(struct drm_connector *connector)
        return hdmi_connector->encoder;
 }
 
-static struct drm_connector_helper_funcs sti_hdmi_connector_helper_funcs = {
+static const
+struct drm_connector_helper_funcs sti_hdmi_connector_helper_funcs = {
        .get_modes = sti_hdmi_connector_get_modes,
        .mode_valid = sti_hdmi_connector_mode_valid,
        .best_encoder = sti_hdmi_best_encoder,
@@ -663,7 +664,7 @@ static void sti_hdmi_connector_destroy(struct drm_connector *connector)
        kfree(hdmi_connector);
 }
 
-static struct drm_connector_funcs sti_hdmi_connector_funcs = {
+static const struct drm_connector_funcs sti_hdmi_connector_funcs = {
        .dpms = drm_atomic_helper_connector_dpms,
        .fill_modes = drm_helper_probe_single_connector_modes,
        .detect = sti_hdmi_connector_detect,
@@ -700,18 +701,17 @@ static int sti_hdmi_bind(struct device *dev, struct device *master, void *data)
 
        encoder = sti_hdmi_find_encoder(drm_dev);
        if (!encoder)
-               goto err_adapt;
+               return -EINVAL;
 
        connector = devm_kzalloc(dev, sizeof(*connector), GFP_KERNEL);
        if (!connector)
-               goto err_adapt;
-
+               return -EINVAL;
 
        connector->hdmi = hdmi;
 
        bridge = devm_kzalloc(dev, sizeof(*bridge), GFP_KERNEL);
        if (!bridge)
-               goto err_adapt;
+               return -EINVAL;
 
        bridge->driver_private = hdmi;
        bridge->funcs = &sti_hdmi_bridge_funcs;
@@ -748,8 +748,7 @@ err_sysfs:
        drm_connector_unregister(drm_connector);
 err_connector:
        drm_connector_cleanup(drm_connector);
-err_adapt:
-       put_device(&hdmi->ddc_adapt->dev);
+
        return -EINVAL;
 }
 
@@ -794,13 +793,10 @@ static int sti_hdmi_probe(struct platform_device *pdev)
 
        ddc = of_parse_phandle(pdev->dev.of_node, "ddc", 0);
        if (ddc) {
-               hdmi->ddc_adapt = of_find_i2c_adapter_by_node(ddc);
-               if (!hdmi->ddc_adapt) {
-                       of_node_put(ddc);
-                       return -EPROBE_DEFER;
-               }
-
+               hdmi->ddc_adapt = of_get_i2c_adapter_by_node(ddc);
                of_node_put(ddc);
+               if (!hdmi->ddc_adapt)
+                       return -EPROBE_DEFER;
        }
 
        hdmi->dev = pdev->dev;
@@ -809,24 +805,29 @@ static int sti_hdmi_probe(struct platform_device *pdev)
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi-reg");
        if (!res) {
                DRM_ERROR("Invalid hdmi resource\n");
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto release_adapter;
        }
        hdmi->regs = devm_ioremap_nocache(dev, res->start, resource_size(res));
-       if (!hdmi->regs)
-               return -ENOMEM;
+       if (!hdmi->regs) {
+               ret = -ENOMEM;
+               goto release_adapter;
+       }
 
        if (of_device_is_compatible(np, "st,stih416-hdmi")) {
                res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
                                                   "syscfg");
                if (!res) {
                        DRM_ERROR("Invalid syscfg resource\n");
-                       return -ENOMEM;
+                       ret = -ENOMEM;
+                       goto release_adapter;
                }
                hdmi->syscfg = devm_ioremap_nocache(dev, res->start,
                                                    resource_size(res));
-               if (!hdmi->syscfg)
-                       return -ENOMEM;
-
+               if (!hdmi->syscfg) {
+                       ret = -ENOMEM;
+                       goto release_adapter;
+               }
        }
 
        hdmi->phy_ops = (struct hdmi_phy_ops *)
@@ -836,25 +837,29 @@ static int sti_hdmi_probe(struct platform_device *pdev)
        hdmi->clk_pix = devm_clk_get(dev, "pix");
        if (IS_ERR(hdmi->clk_pix)) {
                DRM_ERROR("Cannot get hdmi_pix clock\n");
-               return PTR_ERR(hdmi->clk_pix);
+               ret = PTR_ERR(hdmi->clk_pix);
+               goto release_adapter;
        }
 
        hdmi->clk_tmds = devm_clk_get(dev, "tmds");
        if (IS_ERR(hdmi->clk_tmds)) {
                DRM_ERROR("Cannot get hdmi_tmds clock\n");
-               return PTR_ERR(hdmi->clk_tmds);
+               ret = PTR_ERR(hdmi->clk_tmds);
+               goto release_adapter;
        }
 
        hdmi->clk_phy = devm_clk_get(dev, "phy");
        if (IS_ERR(hdmi->clk_phy)) {
                DRM_ERROR("Cannot get hdmi_phy clock\n");
-               return PTR_ERR(hdmi->clk_phy);
+               ret = PTR_ERR(hdmi->clk_phy);
+               goto release_adapter;
        }
 
        hdmi->clk_audio = devm_clk_get(dev, "audio");
        if (IS_ERR(hdmi->clk_audio)) {
                DRM_ERROR("Cannot get hdmi_audio clock\n");
-               return PTR_ERR(hdmi->clk_audio);
+               ret = PTR_ERR(hdmi->clk_audio);
+               goto release_adapter;
        }
 
        hdmi->hpd = readl(hdmi->regs + HDMI_STA) & HDMI_STA_HOT_PLUG;
@@ -867,7 +872,7 @@ static int sti_hdmi_probe(struct platform_device *pdev)
                        hdmi_irq_thread, IRQF_ONESHOT, dev_name(dev), hdmi);
        if (ret) {
                DRM_ERROR("Failed to register HDMI interrupt\n");
-               return ret;
+               goto release_adapter;
        }
 
        hdmi->reset = devm_reset_control_get(dev, "hdmi");
@@ -878,16 +883,20 @@ static int sti_hdmi_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, hdmi);
 
        return component_add(&pdev->dev, &sti_hdmi_ops);
+
+ release_adapter:
+       i2c_put_adapter(hdmi->ddc_adapt);
+
+       return ret;
 }
 
 static int sti_hdmi_remove(struct platform_device *pdev)
 {
        struct sti_hdmi *hdmi = dev_get_drvdata(&pdev->dev);
 
-       if (hdmi->ddc_adapt)
-               put_device(&hdmi->ddc_adapt->dev);
-
+       i2c_put_adapter(hdmi->ddc_adapt);
        component_del(&pdev->dev, &sti_hdmi_ops);
+
        return 0;
 }
 
@@ -901,8 +910,6 @@ struct platform_driver sti_hdmi_driver = {
        .remove = sti_hdmi_remove,
 };
 
-module_platform_driver(sti_hdmi_driver);
-
 MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
 MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
 MODULE_LICENSE("GPL");
index 7c8f9b8bfae10a27339b6693b462406500639c6c..ea0690bc77d5f72587ede24e1d1936d6dbd00578 100644 (file)
@@ -628,6 +628,153 @@ static void sti_hqvdp_init(struct sti_hqvdp *hqvdp)
        memset(hqvdp->hqvdp_cmd, 0, size);
 }
 
+static void sti_hqvdp_init_plugs(struct sti_hqvdp *hqvdp)
+{
+       /* Configure Plugs (same for RD & WR) */
+       writel(PLUG_PAGE_SIZE_256, hqvdp->regs + HQVDP_RD_PLUG_PAGE_SIZE);
+       writel(PLUG_MIN_OPC_8, hqvdp->regs + HQVDP_RD_PLUG_MIN_OPC);
+       writel(PLUG_MAX_OPC_64, hqvdp->regs + HQVDP_RD_PLUG_MAX_OPC);
+       writel(PLUG_MAX_CHK_2X, hqvdp->regs + HQVDP_RD_PLUG_MAX_CHK);
+       writel(PLUG_MAX_MSG_1X, hqvdp->regs + HQVDP_RD_PLUG_MAX_MSG);
+       writel(PLUG_MIN_SPACE_1, hqvdp->regs + HQVDP_RD_PLUG_MIN_SPACE);
+       writel(PLUG_CONTROL_ENABLE, hqvdp->regs + HQVDP_RD_PLUG_CONTROL);
+
+       writel(PLUG_PAGE_SIZE_256, hqvdp->regs + HQVDP_WR_PLUG_PAGE_SIZE);
+       writel(PLUG_MIN_OPC_8, hqvdp->regs + HQVDP_WR_PLUG_MIN_OPC);
+       writel(PLUG_MAX_OPC_64, hqvdp->regs + HQVDP_WR_PLUG_MAX_OPC);
+       writel(PLUG_MAX_CHK_2X, hqvdp->regs + HQVDP_WR_PLUG_MAX_CHK);
+       writel(PLUG_MAX_MSG_1X, hqvdp->regs + HQVDP_WR_PLUG_MAX_MSG);
+       writel(PLUG_MIN_SPACE_1, hqvdp->regs + HQVDP_WR_PLUG_MIN_SPACE);
+       writel(PLUG_CONTROL_ENABLE, hqvdp->regs + HQVDP_WR_PLUG_CONTROL);
+}
+
+/**
+ * sti_hqvdp_start_xp70
+ * @hqvdp: hqvdp pointer
+ *
+ * Run the xP70 initialization sequence
+ */
+static void sti_hqvdp_start_xp70(struct sti_hqvdp *hqvdp)
+{
+       const struct firmware *firmware;
+       u32 *fw_rd_plug, *fw_wr_plug, *fw_pmem, *fw_dmem;
+       u8 *data;
+       int i;
+       struct fw_header {
+               int rd_size;
+               int wr_size;
+               int pmem_size;
+               int dmem_size;
+       } *header;
+
+       DRM_DEBUG_DRIVER("\n");
+
+       if (hqvdp->xp70_initialized) {
+               DRM_INFO("HQVDP XP70 already initialized\n");
+               return;
+       }
+
+       /* Request firmware */
+       if (request_firmware(&firmware, HQVDP_FMW_NAME, hqvdp->dev)) {
+               DRM_ERROR("Can't get HQVDP firmware\n");
+               return;
+       }
+
+       /* Check firmware parts */
+       if (!firmware) {
+               DRM_ERROR("Firmware not available\n");
+               return;
+       }
+
+       header = (struct fw_header *)firmware->data;
+       if (firmware->size < sizeof(*header)) {
+               DRM_ERROR("Invalid firmware size (%d)\n", firmware->size);
+               goto out;
+       }
+       if ((sizeof(*header) + header->rd_size + header->wr_size +
+               header->pmem_size + header->dmem_size) != firmware->size) {
+               DRM_ERROR("Invalid fmw structure (%d+%d+%d+%d+%d != %d)\n",
+                         sizeof(*header), header->rd_size, header->wr_size,
+                         header->pmem_size, header->dmem_size,
+                         firmware->size);
+               goto out;
+       }
+
+       data = (u8 *)firmware->data;
+       data += sizeof(*header);
+       fw_rd_plug = (void *)data;
+       data += header->rd_size;
+       fw_wr_plug = (void *)data;
+       data += header->wr_size;
+       fw_pmem = (void *)data;
+       data += header->pmem_size;
+       fw_dmem = (void *)data;
+
+       /* Enable clock */
+       if (clk_prepare_enable(hqvdp->clk))
+               DRM_ERROR("Failed to prepare/enable HQVDP clk\n");
+
+       /* Reset */
+       writel(SW_RESET_CTRL_FULL, hqvdp->regs + HQVDP_MBX_SW_RESET_CTRL);
+
+       for (i = 0; i < POLL_MAX_ATTEMPT; i++) {
+               if (readl(hqvdp->regs + HQVDP_MBX_STARTUP_CTRL1)
+                               & STARTUP_CTRL1_RST_DONE)
+                       break;
+               msleep(POLL_DELAY_MS);
+       }
+       if (i == POLL_MAX_ATTEMPT) {
+               DRM_ERROR("Could not reset\n");
+               goto out;
+       }
+
+       /* Init Read & Write plugs */
+       for (i = 0; i < header->rd_size / 4; i++)
+               writel(fw_rd_plug[i], hqvdp->regs + HQVDP_RD_PLUG + i * 4);
+       for (i = 0; i < header->wr_size / 4; i++)
+               writel(fw_wr_plug[i], hqvdp->regs + HQVDP_WR_PLUG + i * 4);
+
+       sti_hqvdp_init_plugs(hqvdp);
+
+       /* Authorize Idle Mode */
+       writel(STARTUP_CTRL1_AUTH_IDLE, hqvdp->regs + HQVDP_MBX_STARTUP_CTRL1);
+
+       /* Prevent VTG interruption during the boot */
+       writel(SOFT_VSYNC_SW_CTRL_IRQ, hqvdp->regs + HQVDP_MBX_SOFT_VSYNC);
+       writel(0, hqvdp->regs + HQVDP_MBX_NEXT_CMD);
+
+       /* Download PMEM & DMEM */
+       for (i = 0; i < header->pmem_size / 4; i++)
+               writel(fw_pmem[i], hqvdp->regs + HQVDP_PMEM + i * 4);
+       for (i = 0; i < header->dmem_size / 4; i++)
+               writel(fw_dmem[i], hqvdp->regs + HQVDP_DMEM + i * 4);
+
+       /* Enable fetch */
+       writel(STARTUP_CTRL2_FETCH_EN, hqvdp->regs + HQVDP_MBX_STARTUP_CTRL2);
+
+       /* Wait end of boot */
+       for (i = 0; i < POLL_MAX_ATTEMPT; i++) {
+               if (readl(hqvdp->regs + HQVDP_MBX_INFO_XP70)
+                               & INFO_XP70_FW_READY)
+                       break;
+               msleep(POLL_DELAY_MS);
+       }
+       if (i == POLL_MAX_ATTEMPT) {
+               DRM_ERROR("Could not boot\n");
+               goto out;
+       }
+
+       /* Launch Vsync */
+       writel(SOFT_VSYNC_HW, hqvdp->regs + HQVDP_MBX_SOFT_VSYNC);
+
+       DRM_INFO("HQVDP XP70 initialized\n");
+
+       hqvdp->xp70_initialized = true;
+
+out:
+       release_firmware(firmware);
+}
+
 static void sti_hqvdp_atomic_update(struct drm_plane *drm_plane,
                                    struct drm_plane_state *oldstate)
 {
@@ -754,6 +901,9 @@ static void sti_hqvdp_atomic_update(struct drm_plane *drm_plane,
        sti_hqvdp_update_hvsrc(HVSRC_VERT, scale_v, &cmd->hvsrc);
 
        if (first_prepare) {
+               /* Start HQVDP XP70 coprocessor */
+               sti_hqvdp_start_xp70(hqvdp);
+
                /* Prevent VTG shutdown */
                if (clk_prepare_enable(hqvdp->clk_pix_main)) {
                        DRM_ERROR("Failed to prepare/enable pix main clk\n");
@@ -763,7 +913,7 @@ static void sti_hqvdp_atomic_update(struct drm_plane *drm_plane,
                /* Register VTG Vsync callback to handle bottom fields */
                if (sti_vtg_register_client(hqvdp->vtg,
                                            &hqvdp->vtg_nb,
-                                           mixer->id)) {
+                                           crtc)) {
                        DRM_ERROR("Cannot register VTG notifier\n");
                        return;
                }
@@ -836,168 +986,16 @@ static struct drm_plane *sti_hqvdp_create(struct drm_device *drm_dev,
        return &hqvdp->plane.drm_plane;
 }
 
-static void sti_hqvdp_init_plugs(struct sti_hqvdp *hqvdp)
-{
-       /* Configure Plugs (same for RD & WR) */
-       writel(PLUG_PAGE_SIZE_256, hqvdp->regs + HQVDP_RD_PLUG_PAGE_SIZE);
-       writel(PLUG_MIN_OPC_8, hqvdp->regs + HQVDP_RD_PLUG_MIN_OPC);
-       writel(PLUG_MAX_OPC_64, hqvdp->regs + HQVDP_RD_PLUG_MAX_OPC);
-       writel(PLUG_MAX_CHK_2X, hqvdp->regs + HQVDP_RD_PLUG_MAX_CHK);
-       writel(PLUG_MAX_MSG_1X, hqvdp->regs + HQVDP_RD_PLUG_MAX_MSG);
-       writel(PLUG_MIN_SPACE_1, hqvdp->regs + HQVDP_RD_PLUG_MIN_SPACE);
-       writel(PLUG_CONTROL_ENABLE, hqvdp->regs + HQVDP_RD_PLUG_CONTROL);
-
-       writel(PLUG_PAGE_SIZE_256, hqvdp->regs + HQVDP_WR_PLUG_PAGE_SIZE);
-       writel(PLUG_MIN_OPC_8, hqvdp->regs + HQVDP_WR_PLUG_MIN_OPC);
-       writel(PLUG_MAX_OPC_64, hqvdp->regs + HQVDP_WR_PLUG_MAX_OPC);
-       writel(PLUG_MAX_CHK_2X, hqvdp->regs + HQVDP_WR_PLUG_MAX_CHK);
-       writel(PLUG_MAX_MSG_1X, hqvdp->regs + HQVDP_WR_PLUG_MAX_MSG);
-       writel(PLUG_MIN_SPACE_1, hqvdp->regs + HQVDP_WR_PLUG_MIN_SPACE);
-       writel(PLUG_CONTROL_ENABLE, hqvdp->regs + HQVDP_WR_PLUG_CONTROL);
-}
-
-/**
- * sti_hqvdp_start_xp70
- * @firmware: firmware found
- * @ctxt:     hqvdp structure
- *
- * Run the xP70 initialization sequence
- */
-static void sti_hqvdp_start_xp70(const struct firmware *firmware, void *ctxt)
-{
-       struct sti_hqvdp *hqvdp = ctxt;
-       u32 *fw_rd_plug, *fw_wr_plug, *fw_pmem, *fw_dmem;
-       u8 *data;
-       int i;
-       struct fw_header {
-               int rd_size;
-               int wr_size;
-               int pmem_size;
-               int dmem_size;
-       } *header;
-
-       DRM_DEBUG_DRIVER("\n");
-
-       if (hqvdp->xp70_initialized) {
-               DRM_INFO("HQVDP XP70 already initialized\n");
-               return;
-       }
-
-       /* Check firmware parts */
-       if (!firmware) {
-               DRM_ERROR("Firmware not available\n");
-               return;
-       }
-
-       header = (struct fw_header *) firmware->data;
-       if (firmware->size < sizeof(*header)) {
-               DRM_ERROR("Invalid firmware size (%d)\n", firmware->size);
-               goto out;
-       }
-       if ((sizeof(*header) + header->rd_size + header->wr_size +
-               header->pmem_size + header->dmem_size) != firmware->size) {
-               DRM_ERROR("Invalid fmw structure (%d+%d+%d+%d+%d != %d)\n",
-                          sizeof(*header), header->rd_size, header->wr_size,
-                          header->pmem_size, header->dmem_size,
-                          firmware->size);
-               goto out;
-       }
-
-       data = (u8 *) firmware->data;
-       data += sizeof(*header);
-       fw_rd_plug = (void *) data;
-       data += header->rd_size;
-       fw_wr_plug = (void *) data;
-       data += header->wr_size;
-       fw_pmem = (void *) data;
-       data += header->pmem_size;
-       fw_dmem = (void *) data;
-
-       /* Enable clock */
-       if (clk_prepare_enable(hqvdp->clk))
-               DRM_ERROR("Failed to prepare/enable HQVDP clk\n");
-
-       /* Reset */
-       writel(SW_RESET_CTRL_FULL, hqvdp->regs + HQVDP_MBX_SW_RESET_CTRL);
-
-       for (i = 0; i < POLL_MAX_ATTEMPT; i++) {
-               if (readl(hqvdp->regs + HQVDP_MBX_STARTUP_CTRL1)
-                               & STARTUP_CTRL1_RST_DONE)
-                       break;
-               msleep(POLL_DELAY_MS);
-       }
-       if (i == POLL_MAX_ATTEMPT) {
-               DRM_ERROR("Could not reset\n");
-               goto out;
-       }
-
-       /* Init Read & Write plugs */
-       for (i = 0; i < header->rd_size / 4; i++)
-               writel(fw_rd_plug[i], hqvdp->regs + HQVDP_RD_PLUG + i * 4);
-       for (i = 0; i < header->wr_size / 4; i++)
-               writel(fw_wr_plug[i], hqvdp->regs + HQVDP_WR_PLUG + i * 4);
-
-       sti_hqvdp_init_plugs(hqvdp);
-
-       /* Authorize Idle Mode */
-       writel(STARTUP_CTRL1_AUTH_IDLE, hqvdp->regs + HQVDP_MBX_STARTUP_CTRL1);
-
-       /* Prevent VTG interruption during the boot */
-       writel(SOFT_VSYNC_SW_CTRL_IRQ, hqvdp->regs + HQVDP_MBX_SOFT_VSYNC);
-       writel(0, hqvdp->regs + HQVDP_MBX_NEXT_CMD);
-
-       /* Download PMEM & DMEM */
-       for (i = 0; i < header->pmem_size / 4; i++)
-               writel(fw_pmem[i], hqvdp->regs + HQVDP_PMEM + i * 4);
-       for (i = 0; i < header->dmem_size / 4; i++)
-               writel(fw_dmem[i], hqvdp->regs + HQVDP_DMEM + i * 4);
-
-       /* Enable fetch */
-       writel(STARTUP_CTRL2_FETCH_EN, hqvdp->regs + HQVDP_MBX_STARTUP_CTRL2);
-
-       /* Wait end of boot */
-       for (i = 0; i < POLL_MAX_ATTEMPT; i++) {
-               if (readl(hqvdp->regs + HQVDP_MBX_INFO_XP70)
-                               & INFO_XP70_FW_READY)
-                       break;
-               msleep(POLL_DELAY_MS);
-       }
-       if (i == POLL_MAX_ATTEMPT) {
-               DRM_ERROR("Could not boot\n");
-               goto out;
-       }
-
-       /* Launch Vsync */
-       writel(SOFT_VSYNC_HW, hqvdp->regs + HQVDP_MBX_SOFT_VSYNC);
-
-       DRM_INFO("HQVDP XP70 initialized\n");
-
-       hqvdp->xp70_initialized = true;
-
-out:
-       release_firmware(firmware);
-}
-
 int sti_hqvdp_bind(struct device *dev, struct device *master, void *data)
 {
        struct sti_hqvdp *hqvdp = dev_get_drvdata(dev);
        struct drm_device *drm_dev = data;
        struct drm_plane *plane;
-       int err;
 
        DRM_DEBUG_DRIVER("\n");
 
        hqvdp->drm_dev = drm_dev;
 
-       /* Request for firmware */
-       err = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
-                               HQVDP_FMW_NAME, hqvdp->dev,
-                               GFP_KERNEL, hqvdp, sti_hqvdp_start_xp70);
-       if (err) {
-               DRM_ERROR("Can't get HQVDP firmware\n");
-               return err;
-       }
-
        /* Create HQVDP plane once xp70 is initialized */
        plane = sti_hqvdp_create(drm_dev, hqvdp->dev, STI_HQVDP_0);
        if (!plane)
@@ -1090,8 +1088,6 @@ struct platform_driver sti_hqvdp_driver = {
        .remove = sti_hqvdp_remove,
 };
 
-module_platform_driver(sti_hqvdp_driver);
-
 MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
 MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
 MODULE_LICENSE("GPL");
index 0182e936500427e8fd798251c6dccdd340b87495..49db835dce036a3a78fc9cb13e1fdd5173fc7d7a 100644 (file)
 #include "sti_mixer.h"
 #include "sti_vtg.h"
 
+/* Module parameter to set the background color of the mixer */
+static unsigned int bkg_color = 0x000000;
+MODULE_PARM_DESC(bkgcolor, "Value of the background color 0xRRGGBB");
+module_param_named(bkgcolor, bkg_color, int, 0644);
+
 /* Identity: G=Y , B=Cb , R=Cr */
 static const u32 mixerColorSpaceMatIdentity[] = {
        0x10000000, 0x00000000, 0x10000000, 0x00001000,
@@ -58,7 +63,6 @@ const char *sti_mixer_to_str(struct sti_mixer *mixer)
                return "<UNKNOWN MIXER>";
        }
 }
-EXPORT_SYMBOL(sti_mixer_to_str);
 
 static inline u32 sti_mixer_reg_read(struct sti_mixer *mixer, u32 reg_id)
 {
@@ -81,11 +85,9 @@ void sti_mixer_set_background_status(struct sti_mixer *mixer, bool enable)
 }
 
 static void sti_mixer_set_background_color(struct sti_mixer *mixer,
-                                          u8 red, u8 green, u8 blue)
+                                          unsigned int rgb)
 {
-       u32 val = (red << 16) | (green << 8) | blue;
-
-       sti_mixer_reg_write(mixer, GAM_MIXER_BKC, val);
+       sti_mixer_reg_write(mixer, GAM_MIXER_BKC, rgb);
 }
 
 static void sti_mixer_set_background_area(struct sti_mixer *mixer,
@@ -175,7 +177,7 @@ int sti_mixer_active_video_area(struct sti_mixer *mixer,
        sti_mixer_reg_write(mixer, GAM_MIXER_AVO, ydo << 16 | xdo);
        sti_mixer_reg_write(mixer, GAM_MIXER_AVS, yds << 16 | xds);
 
-       sti_mixer_set_background_color(mixer, 0xFF, 0, 0);
+       sti_mixer_set_background_color(mixer, bkg_color);
 
        sti_mixer_set_background_area(mixer, mode);
        sti_mixer_set_background_status(mixer, true);
index d5c5e91f2956038d2daa3b180051c635bfd6d0e4..2e5c751910c579b70f90836d9a7973bd2f086921 100644 (file)
@@ -42,7 +42,6 @@ const char *sti_plane_to_str(struct sti_plane *plane)
                return "<UNKNOWN PLANE>";
        }
 }
-EXPORT_SYMBOL(sti_plane_to_str);
 
 static void sti_plane_destroy(struct drm_plane *drm_plane)
 {
@@ -108,7 +107,6 @@ void sti_plane_init_property(struct sti_plane *plane,
                         plane->drm_plane.base.id,
                         sti_plane_to_str(plane), plane->zorder);
 }
-EXPORT_SYMBOL(sti_plane_init_property);
 
 struct drm_plane_funcs sti_plane_helpers_funcs = {
        .update_plane = drm_atomic_helper_update_plane,
@@ -119,4 +117,3 @@ struct drm_plane_funcs sti_plane_helpers_funcs = {
        .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
        .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
 };
-EXPORT_SYMBOL(sti_plane_helpers_funcs);
index c1aac8e66fb5024a626aa5a37bf99264beb0d870..c8a4c5dae2b6f2010365d4e63c43ec2b4d8c8659 100644 (file)
@@ -735,8 +735,6 @@ struct platform_driver sti_tvout_driver = {
        .remove = sti_tvout_remove,
 };
 
-module_platform_driver(sti_tvout_driver);
-
 MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
 MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
 MODULE_LICENSE("GPL");
index 97bcdac23ae1f0733d87b3cc6f3b071834d1bdba..b1eb0d77630dfce30ee13373371edfbb32c10dad 100644 (file)
@@ -216,8 +216,6 @@ struct platform_driver sti_vtac_driver = {
        .remove = sti_vtac_remove,
 };
 
-module_platform_driver(sti_vtac_driver);
-
 MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
 MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
 MODULE_LICENSE("GPL");
index aa809713770166537db8f124dff3a2934e7492c9..d56630c60039fead79ca37f1ed52b7614f9e8aee 100644 (file)
@@ -79,7 +79,7 @@ LIST_HEAD(vtg_lookup);
  * @irq: VTG irq
  * @type: VTG type (main or aux)
  * @notifier_list: notifier callback
- * @crtc_id: the crtc id for vblank event
+ * @crtc: the CRTC for vblank event
  * @slave: slave vtg
  * @link: List node to link the structure in lookup list
  */
@@ -90,7 +90,7 @@ struct sti_vtg {
        int irq;
        u32 irq_status;
        struct raw_notifier_head notifier_list;
-       int crtc_id;
+       struct drm_crtc *crtc;
        struct sti_vtg *slave;
        struct list_head link;
 };
@@ -110,7 +110,6 @@ struct sti_vtg *of_vtg_find(struct device_node *np)
        }
        return NULL;
 }
-EXPORT_SYMBOL(of_vtg_find);
 
 static void vtg_reset(struct sti_vtg *vtg)
 {
@@ -242,7 +241,6 @@ void sti_vtg_set_config(struct sti_vtg *vtg,
        else
                vtg_enable_irq(vtg);
 }
-EXPORT_SYMBOL(sti_vtg_set_config);
 
 /**
  * sti_vtg_get_line_number
@@ -265,7 +263,6 @@ u32 sti_vtg_get_line_number(struct drm_display_mode mode, int y)
 
        return start_line + y;
 }
-EXPORT_SYMBOL(sti_vtg_get_line_number);
 
 /**
  * sti_vtg_get_pixel_number
@@ -281,18 +278,16 @@ u32 sti_vtg_get_pixel_number(struct drm_display_mode mode, int x)
 {
        return mode.htotal - mode.hsync_start + x;
 }
-EXPORT_SYMBOL(sti_vtg_get_pixel_number);
 
-int sti_vtg_register_client(struct sti_vtg *vtg,
-               struct notifier_block *nb, int crtc_id)
+int sti_vtg_register_client(struct sti_vtg *vtg, struct notifier_block *nb,
+                           struct drm_crtc *crtc)
 {
        if (vtg->slave)
-               return sti_vtg_register_client(vtg->slave, nb, crtc_id);
+               return sti_vtg_register_client(vtg->slave, nb, crtc);
 
-       vtg->crtc_id = crtc_id;
+       vtg->crtc = crtc;
        return raw_notifier_chain_register(&vtg->notifier_list, nb);
 }
-EXPORT_SYMBOL(sti_vtg_register_client);
 
 int sti_vtg_unregister_client(struct sti_vtg *vtg, struct notifier_block *nb)
 {
@@ -301,7 +296,6 @@ int sti_vtg_unregister_client(struct sti_vtg *vtg, struct notifier_block *nb)
 
        return raw_notifier_chain_unregister(&vtg->notifier_list, nb);
 }
-EXPORT_SYMBOL(sti_vtg_unregister_client);
 
 static irqreturn_t vtg_irq_thread(int irq, void *arg)
 {
@@ -311,7 +305,7 @@ static irqreturn_t vtg_irq_thread(int irq, void *arg)
        event = (vtg->irq_status & VTG_IRQ_TOP) ?
                VTG_TOP_FIELD_EVENT : VTG_BOTTOM_FIELD_EVENT;
 
-       raw_notifier_call_chain(&vtg->notifier_list, event, &vtg->crtc_id);
+       raw_notifier_call_chain(&vtg->notifier_list, event, vtg->crtc);
 
        return IRQ_HANDLED;
 }
@@ -406,8 +400,6 @@ struct platform_driver sti_vtg_driver = {
        .remove = vtg_remove,
 };
 
-module_platform_driver(sti_vtg_driver);
-
 MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
 MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
 MODULE_LICENSE("GPL");
index e84d23f1f57ff71912eac3759f0691625eb64776..cd2439f89d05d6b183f36a529526b3fa33d46b86 100644 (file)
@@ -17,8 +17,8 @@ struct notifier_block;
 struct sti_vtg *of_vtg_find(struct device_node *np);
 void sti_vtg_set_config(struct sti_vtg *vtg,
                const struct drm_display_mode *mode);
-int sti_vtg_register_client(struct sti_vtg *vtg,
-               struct notifier_block *nb, int crtc_id);
+int sti_vtg_register_client(struct sti_vtg *vtg, struct notifier_block *nb,
+                           struct drm_crtc *crtc);
 int sti_vtg_unregister_client(struct sti_vtg *vtg,
                struct notifier_block *nb);
 
index 842b0043ad9477160194a7c7a94b03f7ab06d5a1..8f59f057cdf4a336cf29cd32803dff2b50143be2 100644 (file)
@@ -324,6 +324,7 @@ config SENSORS_APPLESMC
 config SENSORS_ARM_SCPI
        tristate "ARM SCPI Sensors"
        depends on ARM_SCPI_PROTOCOL
+       depends on THERMAL || !THERMAL_OF
        help
          This driver provides support for temperature, voltage, current
          and power sensors available on ARM Ltd's SCP based platforms. The
@@ -1471,6 +1472,7 @@ config SENSORS_INA209
 config SENSORS_INA2XX
        tristate "Texas Instruments INA219 and compatibles"
        depends on I2C
+       select REGMAP_I2C
        help
          If you say yes here you get support for INA219, INA220, INA226,
          INA230, and INA231 power monitor chips.
index 1f5e956941b1326c6f590b62354bffd40e29ea95..0af7fd311979d25d0684e585ec92f9a65169bdaa 100644 (file)
@@ -537,7 +537,7 @@ static int applesmc_init_index(struct applesmc_registers *s)
 static int applesmc_init_smcreg_try(void)
 {
        struct applesmc_registers *s = &smcreg;
-       bool left_light_sensor, right_light_sensor;
+       bool left_light_sensor = 0, right_light_sensor = 0;
        unsigned int count;
        u8 tmp[1];
        int ret;
index 2c1241bbf9affdbf616a357d3b95c7f7c9963669..7e20567bc36912ada47687716405733e1372bc8a 100644 (file)
@@ -117,7 +117,7 @@ static int scpi_hwmon_probe(struct platform_device *pdev)
        struct scpi_ops *scpi_ops;
        struct device *hwdev, *dev = &pdev->dev;
        struct scpi_sensors *scpi_sensors;
-       int ret;
+       int ret, idx;
 
        scpi_ops = get_scpi_ops();
        if (!scpi_ops)
@@ -146,8 +146,8 @@ static int scpi_hwmon_probe(struct platform_device *pdev)
 
        scpi_sensors->scpi_ops = scpi_ops;
 
-       for (i = 0; i < nr_sensors; i++) {
-               struct sensor_data *sensor = &scpi_sensors->data[i];
+       for (i = 0, idx = 0; i < nr_sensors; i++) {
+               struct sensor_data *sensor = &scpi_sensors->data[idx];
 
                ret = scpi_ops->sensor_get_info(i, &sensor->info);
                if (ret)
@@ -183,7 +183,7 @@ static int scpi_hwmon_probe(struct platform_device *pdev)
                        num_power++;
                        break;
                default:
-                       break;
+                       continue;
                }
 
                sensor->dev_attr_input.attr.mode = S_IRUGO;
@@ -194,11 +194,12 @@ static int scpi_hwmon_probe(struct platform_device *pdev)
                sensor->dev_attr_label.show = scpi_show_label;
                sensor->dev_attr_label.attr.name = sensor->label;
 
-               scpi_sensors->attrs[i << 1] = &sensor->dev_attr_input.attr;
-               scpi_sensors->attrs[(i << 1) + 1] = &sensor->dev_attr_label.attr;
+               scpi_sensors->attrs[idx << 1] = &sensor->dev_attr_input.attr;
+               scpi_sensors->attrs[(idx << 1) + 1] = &sensor->dev_attr_label.attr;
 
-               sysfs_attr_init(scpi_sensors->attrs[i << 1]);
-               sysfs_attr_init(scpi_sensors->attrs[(i << 1) + 1]);
+               sysfs_attr_init(scpi_sensors->attrs[idx << 1]);
+               sysfs_attr_init(scpi_sensors->attrs[(idx << 1) + 1]);
+               idx++;
        }
 
        scpi_sensors->group.attrs = scpi_sensors->attrs;
@@ -236,8 +237,8 @@ static int scpi_hwmon_probe(struct platform_device *pdev)
 
                zone->sensor_id = i;
                zone->scpi_sensors = scpi_sensors;
-               zone->tzd = thermal_zone_of_sensor_register(dev, i, zone,
-                                                           &scpi_sensor_ops);
+               zone->tzd = thermal_zone_of_sensor_register(dev,
+                               sensor->info.sensor_id, zone, &scpi_sensor_ops);
                /*
                 * The call to thermal_zone_of_sensor_register returns
                 * an error for sensors that are not associated with
index 6498a9dbb7bd184802c6f270548c417b24e38e2d..11ab6d01adf63d1490c8474801d358ada4f657a8 100644 (file)
@@ -76,9 +76,10 @@ to_stp_policy_node(struct config_item *item)
                NULL;
 }
 
-static ssize_t stp_policy_node_masters_show(struct stp_policy_node *policy_node,
-                                           char *page)
+static ssize_t
+stp_policy_node_masters_show(struct config_item *item, char *page)
 {
+       struct stp_policy_node *policy_node = to_stp_policy_node(item);
        ssize_t count;
 
        count = sprintf(page, "%u %u\n", policy_node->first_master,
@@ -88,9 +89,10 @@ static ssize_t stp_policy_node_masters_show(struct stp_policy_node *policy_node,
 }
 
 static ssize_t
-stp_policy_node_masters_store(struct stp_policy_node *policy_node,
-                             const char *page, size_t count)
+stp_policy_node_masters_store(struct config_item *item, const char *page,
+                             size_t count)
 {
+       struct stp_policy_node *policy_node = to_stp_policy_node(item);
        unsigned int first, last;
        struct stm_device *stm;
        char *p = (char *)page;
@@ -123,8 +125,9 @@ unlock:
 }
 
 static ssize_t
-stp_policy_node_channels_show(struct stp_policy_node *policy_node, char *page)
+stp_policy_node_channels_show(struct config_item *item, char *page)
 {
+       struct stp_policy_node *policy_node = to_stp_policy_node(item);
        ssize_t count;
 
        count = sprintf(page, "%u %u\n", policy_node->first_channel,
@@ -134,9 +137,10 @@ stp_policy_node_channels_show(struct stp_policy_node *policy_node, char *page)
 }
 
 static ssize_t
-stp_policy_node_channels_store(struct stp_policy_node *policy_node,
-                              const char *page, size_t count)
+stp_policy_node_channels_store(struct config_item *item, const char *page,
+                              size_t count)
 {
+       struct stp_policy_node *policy_node = to_stp_policy_node(item);
        unsigned int first, last;
        struct stm_device *stm;
        char *p = (char *)page;
@@ -171,71 +175,16 @@ static void stp_policy_node_release(struct config_item *item)
        kfree(to_stp_policy_node(item));
 }
 
-struct stp_policy_node_attribute {
-       struct configfs_attribute       attr;
-       ssize_t (*show)(struct stp_policy_node *, char *);
-       ssize_t (*store)(struct stp_policy_node *, const char *, size_t);
-};
-
-static ssize_t stp_policy_node_attr_show(struct config_item *item,
-                                        struct configfs_attribute *attr,
-                                        char *page)
-{
-       struct stp_policy_node *policy_node = to_stp_policy_node(item);
-       struct stp_policy_node_attribute *pn_attr =
-               container_of(attr, struct stp_policy_node_attribute, attr);
-       ssize_t count = 0;
-
-       if (pn_attr->show)
-               count = pn_attr->show(policy_node, page);
-
-       return count;
-}
-
-static ssize_t stp_policy_node_attr_store(struct config_item *item,
-                                         struct configfs_attribute *attr,
-                                         const char *page, size_t len)
-{
-       struct stp_policy_node *policy_node = to_stp_policy_node(item);
-       struct stp_policy_node_attribute *pn_attr =
-               container_of(attr, struct stp_policy_node_attribute, attr);
-       ssize_t count = -EINVAL;
-
-       if (pn_attr->store)
-               count = pn_attr->store(policy_node, page, len);
-
-       return count;
-}
-
 static struct configfs_item_operations stp_policy_node_item_ops = {
        .release                = stp_policy_node_release,
-       .show_attribute         = stp_policy_node_attr_show,
-       .store_attribute        = stp_policy_node_attr_store,
 };
 
-static struct stp_policy_node_attribute stp_policy_node_attr_range = {
-       .attr   = {
-               .ca_owner = THIS_MODULE,
-               .ca_name = "masters",
-               .ca_mode = S_IRUGO | S_IWUSR,
-       },
-       .show   = stp_policy_node_masters_show,
-       .store  = stp_policy_node_masters_store,
-};
-
-static struct stp_policy_node_attribute stp_policy_node_attr_channels = {
-       .attr   = {
-               .ca_owner = THIS_MODULE,
-               .ca_name = "channels",
-               .ca_mode = S_IRUGO | S_IWUSR,
-       },
-       .show   = stp_policy_node_channels_show,
-       .store  = stp_policy_node_channels_store,
-};
+CONFIGFS_ATTR(stp_policy_node_, masters);
+CONFIGFS_ATTR(stp_policy_node_, channels);
 
 static struct configfs_attribute *stp_policy_node_attrs[] = {
-       &stp_policy_node_attr_range.attr,
-       &stp_policy_node_attr_channels.attr,
+       &stp_policy_node_attr_masters,
+       &stp_policy_node_attr_channels,
        NULL,
 };
 
@@ -298,20 +247,8 @@ static struct config_item_type stp_policy_node_type = {
 /*
  * Root group: policies.
  */
-static struct configfs_attribute stp_policy_attr_device = {
-       .ca_owner = THIS_MODULE,
-       .ca_name = "device",
-       .ca_mode = S_IRUGO,
-};
-
-static struct configfs_attribute *stp_policy_attrs[] = {
-       &stp_policy_attr_device,
-       NULL,
-};
-
-static ssize_t stp_policy_attr_show(struct config_item *item,
-                                   struct configfs_attribute *attr,
-                                   char *page)
+static ssize_t stp_policy_device_show(struct config_item *item,
+                                     char *page)
 {
        struct stp_policy *policy = to_stp_policy(item);
        ssize_t count;
@@ -324,6 +261,13 @@ static ssize_t stp_policy_attr_show(struct config_item *item,
        return count;
 }
 
+CONFIGFS_ATTR_RO(stp_policy_, device);
+
+static struct configfs_attribute *stp_policy_attrs[] = {
+       &stp_policy_attr_device,
+       NULL,
+};
+
 void stp_policy_unbind(struct stp_policy *policy)
 {
        struct stm_device *stm = policy->stm;
@@ -350,7 +294,6 @@ static void stp_policy_release(struct config_item *item)
 
 static struct configfs_item_operations stp_policy_item_ops = {
        .release                = stp_policy_release,
-       .show_attribute         = stp_policy_attr_show,
 };
 
 static struct configfs_group_operations stp_policy_group_ops = {
index 32f79624dd28565d3846384f24049e435aef83e7..9909022dc6c3eebd4c52ef3e7dca5221dc8b6038 100644 (file)
@@ -2798,7 +2798,6 @@ static struct scsi_host_template srp_template = {
        .cmd_per_lun                    = SRP_DEFAULT_CMD_SQ_SIZE,
        .use_clustering                 = ENABLE_CLUSTERING,
        .shost_attrs                    = srp_host_attrs,
-       .use_blk_tags                   = 1,
        .track_queue_depth              = 1,
 };
 
@@ -3229,10 +3228,6 @@ static ssize_t srp_create_target(struct device *dev,
        if (ret)
                goto out;
 
-       ret = scsi_init_shared_tag_map(target_host, target_host->can_queue);
-       if (ret)
-               goto out;
-
        target->req_ring_size = target->queue_size - SRP_TSK_MGMT_SQ_SIZE;
 
        if (!srp_conn_unique(target->srp_host, target)) {
index 47c4022fda7680e3107710bb703e83fa61affc15..2e2fe818ca9f1acc42d74c8f4d0e0cfbaf810172 100644 (file)
@@ -43,9 +43,7 @@
 #include <linux/atomic.h>
 #include <scsi/scsi_proto.h>
 #include <scsi/scsi_tcq.h>
-#include <target/configfs_macros.h>
 #include <target/target_core_base.h>
-#include <target/target_core_fabric_configfs.h>
 #include <target/target_core_fabric.h>
 #include "ib_srpt.h"
 
@@ -3546,20 +3544,19 @@ static void srpt_cleanup_nodeacl(struct se_node_acl *se_nacl)
        spin_unlock_irq(&sport->port_acl_lock);
 }
 
-static ssize_t srpt_tpg_attrib_show_srp_max_rdma_size(
-       struct se_portal_group *se_tpg,
-       char *page)
+static ssize_t srpt_tpg_attrib_srp_max_rdma_size_show(struct config_item *item,
+               char *page)
 {
+       struct se_portal_group *se_tpg = attrib_to_tpg(item);
        struct srpt_port *sport = container_of(se_tpg, struct srpt_port, port_tpg_1);
 
        return sprintf(page, "%u\n", sport->port_attrib.srp_max_rdma_size);
 }
 
-static ssize_t srpt_tpg_attrib_store_srp_max_rdma_size(
-       struct se_portal_group *se_tpg,
-       const char *page,
-       size_t count)
+static ssize_t srpt_tpg_attrib_srp_max_rdma_size_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct se_portal_group *se_tpg = attrib_to_tpg(item);
        struct srpt_port *sport = container_of(se_tpg, struct srpt_port, port_tpg_1);
        unsigned long val;
        int ret;
@@ -3584,22 +3581,19 @@ static ssize_t srpt_tpg_attrib_store_srp_max_rdma_size(
        return count;
 }
 
-TF_TPG_ATTRIB_ATTR(srpt, srp_max_rdma_size, S_IRUGO | S_IWUSR);
-
-static ssize_t srpt_tpg_attrib_show_srp_max_rsp_size(
-       struct se_portal_group *se_tpg,
-       char *page)
+static ssize_t srpt_tpg_attrib_srp_max_rsp_size_show(struct config_item *item,
+               char *page)
 {
+       struct se_portal_group *se_tpg = attrib_to_tpg(item);
        struct srpt_port *sport = container_of(se_tpg, struct srpt_port, port_tpg_1);
 
        return sprintf(page, "%u\n", sport->port_attrib.srp_max_rsp_size);
 }
 
-static ssize_t srpt_tpg_attrib_store_srp_max_rsp_size(
-       struct se_portal_group *se_tpg,
-       const char *page,
-       size_t count)
+static ssize_t srpt_tpg_attrib_srp_max_rsp_size_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct se_portal_group *se_tpg = attrib_to_tpg(item);
        struct srpt_port *sport = container_of(se_tpg, struct srpt_port, port_tpg_1);
        unsigned long val;
        int ret;
@@ -3624,22 +3618,19 @@ static ssize_t srpt_tpg_attrib_store_srp_max_rsp_size(
        return count;
 }
 
-TF_TPG_ATTRIB_ATTR(srpt, srp_max_rsp_size, S_IRUGO | S_IWUSR);
-
-static ssize_t srpt_tpg_attrib_show_srp_sq_size(
-       struct se_portal_group *se_tpg,
-       char *page)
+static ssize_t srpt_tpg_attrib_srp_sq_size_show(struct config_item *item,
+               char *page)
 {
+       struct se_portal_group *se_tpg = attrib_to_tpg(item);
        struct srpt_port *sport = container_of(se_tpg, struct srpt_port, port_tpg_1);
 
        return sprintf(page, "%u\n", sport->port_attrib.srp_sq_size);
 }
 
-static ssize_t srpt_tpg_attrib_store_srp_sq_size(
-       struct se_portal_group *se_tpg,
-       const char *page,
-       size_t count)
+static ssize_t srpt_tpg_attrib_srp_sq_size_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct se_portal_group *se_tpg = attrib_to_tpg(item);
        struct srpt_port *sport = container_of(se_tpg, struct srpt_port, port_tpg_1);
        unsigned long val;
        int ret;
@@ -3664,29 +3655,29 @@ static ssize_t srpt_tpg_attrib_store_srp_sq_size(
        return count;
 }
 
-TF_TPG_ATTRIB_ATTR(srpt, srp_sq_size, S_IRUGO | S_IWUSR);
+CONFIGFS_ATTR(srpt_tpg_attrib_,  srp_max_rdma_size);
+CONFIGFS_ATTR(srpt_tpg_attrib_,  srp_max_rsp_size);
+CONFIGFS_ATTR(srpt_tpg_attrib_,  srp_sq_size);
 
 static struct configfs_attribute *srpt_tpg_attrib_attrs[] = {
-       &srpt_tpg_attrib_srp_max_rdma_size.attr,
-       &srpt_tpg_attrib_srp_max_rsp_size.attr,
-       &srpt_tpg_attrib_srp_sq_size.attr,
+       &srpt_tpg_attrib_attr_srp_max_rdma_size,
+       &srpt_tpg_attrib_attr_srp_max_rsp_size,
+       &srpt_tpg_attrib_attr_srp_sq_size,
        NULL,
 };
 
-static ssize_t srpt_tpg_show_enable(
-       struct se_portal_group *se_tpg,
-       char *page)
+static ssize_t srpt_tpg_enable_show(struct config_item *item, char *page)
 {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct srpt_port *sport = container_of(se_tpg, struct srpt_port, port_tpg_1);
 
        return snprintf(page, PAGE_SIZE, "%d\n", (sport->enabled) ? 1: 0);
 }
 
-static ssize_t srpt_tpg_store_enable(
-       struct se_portal_group *se_tpg,
-       const char *page,
-       size_t count)
+static ssize_t srpt_tpg_enable_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct srpt_port *sport = container_of(se_tpg, struct srpt_port, port_tpg_1);
        unsigned long tmp;
         int ret;
@@ -3709,10 +3700,10 @@ static ssize_t srpt_tpg_store_enable(
        return count;
 }
 
-TF_TPG_BASE_ATTR(srpt, enable, S_IRUGO | S_IWUSR);
+CONFIGFS_ATTR(srpt_tpg_, enable);
 
 static struct configfs_attribute *srpt_tpg_attrs[] = {
-       &srpt_tpg_enable.attr,
+       &srpt_tpg_attr_enable,
        NULL,
 };
 
@@ -3782,16 +3773,15 @@ static void srpt_drop_tport(struct se_wwn *wwn)
        pr_debug("drop_tport(%s\n", config_item_name(&sport->port_wwn.wwn_group.cg_item));
 }
 
-static ssize_t srpt_wwn_show_attr_version(struct target_fabric_configfs *tf,
-                                             char *buf)
+static ssize_t srpt_wwn_version_show(struct config_item *item, char *buf)
 {
        return scnprintf(buf, PAGE_SIZE, "%s\n", DRV_VERSION);
 }
 
-TF_WWN_ATTR_RO(srpt, version);
+CONFIGFS_ATTR_RO(srpt_wwn_, version);
 
 static struct configfs_attribute *srpt_wwn_attrs[] = {
-       &srpt_wwn_version.attr,
+       &srpt_wwn_attr_version,
        NULL,
 };
 
index 2955f1d0ca6c4c9137f786028ca36bff706beab2..537ebb0e193a2a6f47e919c172151f37aa14b4c4 100644 (file)
@@ -1520,6 +1520,13 @@ static const struct dmi_system_id elantech_dmi_force_crc_enabled[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E544"),
                },
        },
+       {
+               /* Fujitsu LIFEBOOK U745 does not work with crc_enabled == 0 */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U745"),
+               },
+       },
 #endif
        { }
 };
index 74bb17270255439c6354f983676fdac121410c01..92c31b8f8fb489c317013f1cf77f133993fcc321 100644 (file)
@@ -164,7 +164,7 @@ static int parkbd_getport(struct parport *pp)
        return 0;
 }
 
-static struct serio * __init parkbd_allocate_serio(void)
+static struct serio *parkbd_allocate_serio(void)
 {
        struct serio *serio;
 
index 80cc69897a4331105801ff3eca9339819727e3c8..ae33da7ab51ff7f5f84464366be1c4b9f8030527 100644 (file)
@@ -939,10 +939,27 @@ config TOUCHSCREEN_TSC_SERIO
          To compile this driver as a module, choose M here: the
          module will be called tsc40.
 
+config TOUCHSCREEN_TSC200X_CORE
+       tristate
+
+config TOUCHSCREEN_TSC2004
+       tristate "TSC2004 based touchscreens"
+       depends on I2C
+       select REGMAP_I2C
+       select TOUCHSCREEN_TSC200X_CORE
+       help
+         Say Y here if you have a TSC2004 based touchscreen.
+
+         If unsure, say N.
+
+         To compile this driver as a module, choose M here: the
+         module will be called tsc2004.
+
 config TOUCHSCREEN_TSC2005
        tristate "TSC2005 based touchscreens"
        depends on SPI_MASTER
        select REGMAP_SPI
+       select TOUCHSCREEN_TSC200X_CORE
        help
          Say Y here if you have a TSC2005 based touchscreen.
 
index 17435c7e97e3bcbf421ce1135e9c64bec05f2c6a..cbaa6abb08dae6c58ea1125b0fc0baa335dbc444 100644 (file)
@@ -69,6 +69,8 @@ obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213)  += touchit213.o
 obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT)   += touchright.o
 obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN)     += touchwin.o
 obj-$(CONFIG_TOUCHSCREEN_TSC_SERIO)    += tsc40.o
+obj-$(CONFIG_TOUCHSCREEN_TSC200X_CORE) += tsc200x-core.o
+obj-$(CONFIG_TOUCHSCREEN_TSC2004)      += tsc2004.o
 obj-$(CONFIG_TOUCHSCREEN_TSC2005)      += tsc2005.o
 obj-$(CONFIG_TOUCHSCREEN_TSC2007)      += tsc2007.o
 obj-$(CONFIG_TOUCHSCREEN_UCB1400)      += ucb1400_ts.o
diff --git a/drivers/input/touchscreen/tsc2004.c b/drivers/input/touchscreen/tsc2004.c
new file mode 100644 (file)
index 0000000..7295c19
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * TSC2004 touchscreen driver
+ *
+ * Copyright (C) 2015 QWERTY Embedded Design
+ * Copyright (C) 2015 EMAC Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the 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/input.h>
+#include <linux/of.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include "tsc200x-core.h"
+
+static int tsc2004_cmd(struct device *dev, u8 cmd)
+{
+       u8 tx = TSC200X_CMD | TSC200X_CMD_12BIT | cmd;
+       s32 data;
+       struct i2c_client *i2c = to_i2c_client(dev);
+
+       data = i2c_smbus_write_byte(i2c, tx);
+       if (data < 0) {
+               dev_err(dev, "%s: failed, command: %x i2c error: %d\n",
+                       __func__, cmd, data);
+               return data;
+       }
+
+       return 0;
+}
+
+static int tsc2004_probe(struct i2c_client *i2c,
+                        const struct i2c_device_id *id)
+
+{
+       return tsc200x_probe(&i2c->dev, i2c->irq, BUS_I2C,
+                            devm_regmap_init_i2c(i2c, &tsc200x_regmap_config),
+                            tsc2004_cmd);
+}
+
+static int tsc2004_remove(struct i2c_client *i2c)
+{
+       return tsc200x_remove(&i2c->dev);
+}
+
+static const struct i2c_device_id tsc2004_idtable[] = {
+       { "tsc2004", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, tsc2004_idtable);
+
+#ifdef CONFIG_OF
+static const struct of_device_id tsc2004_of_match[] = {
+       { .compatible = "ti,tsc2004" },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, tsc2004_of_match);
+#endif
+
+static struct i2c_driver tsc2004_driver = {
+       .driver = {
+               .name   = "tsc2004",
+               .of_match_table = of_match_ptr(tsc2004_of_match),
+               .pm     = &tsc200x_pm_ops,
+       },
+       .id_table       = tsc2004_idtable,
+       .probe          = tsc2004_probe,
+       .remove         = tsc2004_remove,
+};
+module_i2c_driver(tsc2004_driver);
+
+MODULE_AUTHOR("Michael Welling <mwelling@ieee.org>");
+MODULE_DESCRIPTION("TSC2004 Touchscreen Driver");
+MODULE_LICENSE("GPL");
index f41f23318484d1fb97a427b38e28f15c6e585f57..b9f593dfd2ef8368223e5d7d7d9ca06856afcc8d 100644 (file)
@@ -2,9 +2,10 @@
  * TSC2005 touchscreen driver
  *
  * Copyright (C) 2006-2010 Nokia Corporation
+ * Copyright (C) 2015 QWERTY Embedded Design
+ * Copyright (C) 2015 EMAC Inc.
  *
- * Author: Lauri Leukkunen <lauri.leukkunen@nokia.com>
- * based on TSC2301 driver by Klaus K. Pedersen <klaus.k.pedersen@nokia.com>
+ * Based on original tsc2005.c by Lauri Leukkunen <lauri.leukkunen@nokia.com>
  *
  * 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
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
  */
 
-#include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/input.h>
-#include <linux/input/touchscreen.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/of.h>
 #include <linux/spi/spi.h>
-#include <linux/spi/tsc2005.h>
-#include <linux/regulator/consumer.h>
 #include <linux/regmap.h>
-#include <linux/gpio/consumer.h>
-
-/*
- * The touchscreen interface operates as follows:
- *
- * 1) Pen is pressed against the touchscreen.
- * 2) TSC2005 performs AD conversion.
- * 3) After the conversion is done TSC2005 drives DAV line down.
- * 4) GPIO IRQ is received and tsc2005_irq_thread() is scheduled.
- * 5) tsc2005_irq_thread() queues up an spi transfer to fetch the x, y, z1, z2
- *    values.
- * 6) tsc2005_irq_thread() reports coordinates to input layer and sets up
- *    tsc2005_penup_timer() to be called after TSC2005_PENUP_TIME_MS (40ms).
- * 7) When the penup timer expires, there have not been touch or DAV interrupts
- *    during the last 40ms which means the pen has been lifted.
- *
- * ESD recovery via a hardware reset is done if the TSC2005 doesn't respond
- * after a configurable period (in ms) of activity. If esd_timeout is 0, the
- * watchdog is disabled.
- */
-
-/* control byte 1 */
-#define TSC2005_CMD                    0x80
-#define TSC2005_CMD_NORMAL             0x00
-#define TSC2005_CMD_STOP               0x01
-#define TSC2005_CMD_12BIT              0x04
-
-/* control byte 0 */
-#define TSC2005_REG_READ               0x01 /* R/W access */
-#define TSC2005_REG_PND0               0x02 /* Power Not Down Control */
-#define TSC2005_REG_X                  (0x0 << 3)
-#define TSC2005_REG_Y                  (0x1 << 3)
-#define TSC2005_REG_Z1                 (0x2 << 3)
-#define TSC2005_REG_Z2                 (0x3 << 3)
-#define TSC2005_REG_AUX                        (0x4 << 3)
-#define TSC2005_REG_TEMP1              (0x5 << 3)
-#define TSC2005_REG_TEMP2              (0x6 << 3)
-#define TSC2005_REG_STATUS             (0x7 << 3)
-#define TSC2005_REG_AUX_HIGH           (0x8 << 3)
-#define TSC2005_REG_AUX_LOW            (0x9 << 3)
-#define TSC2005_REG_TEMP_HIGH          (0xA << 3)
-#define TSC2005_REG_TEMP_LOW           (0xB << 3)
-#define TSC2005_REG_CFR0               (0xC << 3)
-#define TSC2005_REG_CFR1               (0xD << 3)
-#define TSC2005_REG_CFR2               (0xE << 3)
-#define TSC2005_REG_CONV_FUNC          (0xF << 3)
-
-/* configuration register 0 */
-#define TSC2005_CFR0_PRECHARGE_276US   0x0040
-#define TSC2005_CFR0_STABTIME_1MS      0x0300
-#define TSC2005_CFR0_CLOCK_1MHZ                0x1000
-#define TSC2005_CFR0_RESOLUTION12      0x2000
-#define TSC2005_CFR0_PENMODE           0x8000
-#define TSC2005_CFR0_INITVALUE         (TSC2005_CFR0_STABTIME_1MS    | \
-                                        TSC2005_CFR0_CLOCK_1MHZ      | \
-                                        TSC2005_CFR0_RESOLUTION12    | \
-                                        TSC2005_CFR0_PRECHARGE_276US | \
-                                        TSC2005_CFR0_PENMODE)
-
-/* bits common to both read and write of configuration register 0 */
-#define        TSC2005_CFR0_RW_MASK            0x3fff
-
-/* configuration register 1 */
-#define TSC2005_CFR1_BATCHDELAY_4MS    0x0003
-#define TSC2005_CFR1_INITVALUE         TSC2005_CFR1_BATCHDELAY_4MS
-
-/* configuration register 2 */
-#define TSC2005_CFR2_MAVE_Z            0x0004
-#define TSC2005_CFR2_MAVE_Y            0x0008
-#define TSC2005_CFR2_MAVE_X            0x0010
-#define TSC2005_CFR2_AVG_7             0x0800
-#define TSC2005_CFR2_MEDIUM_15         0x3000
-#define TSC2005_CFR2_INITVALUE         (TSC2005_CFR2_MAVE_X    | \
-                                        TSC2005_CFR2_MAVE_Y    | \
-                                        TSC2005_CFR2_MAVE_Z    | \
-                                        TSC2005_CFR2_MEDIUM_15 | \
-                                        TSC2005_CFR2_AVG_7)
-
-#define MAX_12BIT                      0xfff
-#define TSC2005_DEF_X_FUZZ             4
-#define TSC2005_DEF_Y_FUZZ             8
-#define TSC2005_DEF_P_FUZZ             2
-#define TSC2005_DEF_RESISTOR           280
-
-#define TSC2005_SPI_MAX_SPEED_HZ       10000000
-#define TSC2005_PENUP_TIME_MS          40
-
-static const struct regmap_range tsc2005_writable_ranges[] = {
-       regmap_reg_range(TSC2005_REG_AUX_HIGH, TSC2005_REG_CFR2),
-};
-
-static const struct regmap_access_table tsc2005_writable_table = {
-       .yes_ranges = tsc2005_writable_ranges,
-       .n_yes_ranges = ARRAY_SIZE(tsc2005_writable_ranges),
-};
-
-static struct regmap_config tsc2005_regmap_config = {
-       .reg_bits = 8,
-       .val_bits = 16,
-       .reg_stride = 0x08,
-       .max_register = 0x78,
-       .read_flag_mask = TSC2005_REG_READ,
-       .write_flag_mask = TSC2005_REG_PND0,
-       .wr_table = &tsc2005_writable_table,
-       .use_single_rw = true,
-};
-
-struct tsc2005_data {
-       u16 x;
-       u16 y;
-       u16 z1;
-       u16 z2;
-} __packed;
-#define TSC2005_DATA_REGS 4
-
-struct tsc2005 {
-       struct spi_device       *spi;
-       struct regmap           *regmap;
-
-       struct input_dev        *idev;
-       char                    phys[32];
-
-       struct mutex            mutex;
-
-       /* raw copy of previous x,y,z */
-       int                     in_x;
-       int                     in_y;
-       int                     in_z1;
-       int                     in_z2;
-
-       spinlock_t              lock;
-       struct timer_list       penup_timer;
+#include "tsc200x-core.h"
 
-       unsigned int            esd_timeout;
-       struct delayed_work     esd_work;
-       unsigned long           last_valid_interrupt;
-
-       unsigned int            x_plate_ohm;
-
-       bool                    opened;
-       bool                    suspended;
-
-       bool                    pen_down;
-
-       struct regulator        *vio;
-
-       struct gpio_desc        *reset_gpio;
-       void                    (*set_reset)(bool enable);
-};
-
-static int tsc2005_cmd(struct tsc2005 *ts, u8 cmd)
+static int tsc2005_cmd(struct device *dev, u8 cmd)
 {
-       u8 tx = TSC2005_CMD | TSC2005_CMD_12BIT | cmd;
+       u8 tx = TSC200X_CMD | TSC200X_CMD_12BIT | cmd;
        struct spi_transfer xfer = {
-               .tx_buf         = &tx,
-               .len            = 1,
-               .bits_per_word  = 8,
+               .tx_buf         = &tx,
+               .len            = 1,
+               .bits_per_word  = 8,
        };
        struct spi_message msg;
+       struct spi_device *spi = to_spi_device(dev);
        int error;
 
        spi_message_init(&msg);
        spi_message_add_tail(&xfer, &msg);
 
-       error = spi_sync(ts->spi, &msg);
+       error = spi_sync(spi, &msg);
        if (error) {
-               dev_err(&ts->spi->dev, "%s: failed, command: %x, error: %d\n",
+               dev_err(dev, "%s: failed, command: %x, spi error: %d\n",
                        __func__, cmd, error);
                return error;
        }
@@ -208,382 +49,10 @@ static int tsc2005_cmd(struct tsc2005 *ts, u8 cmd)
        return 0;
 }
 
-static void tsc2005_update_pen_state(struct tsc2005 *ts,
-                                    int x, int y, int pressure)
-{
-       if (pressure) {
-               input_report_abs(ts->idev, ABS_X, x);
-               input_report_abs(ts->idev, ABS_Y, y);
-               input_report_abs(ts->idev, ABS_PRESSURE, pressure);
-               if (!ts->pen_down) {
-                       input_report_key(ts->idev, BTN_TOUCH, !!pressure);
-                       ts->pen_down = true;
-               }
-       } else {
-               input_report_abs(ts->idev, ABS_PRESSURE, 0);
-               if (ts->pen_down) {
-                       input_report_key(ts->idev, BTN_TOUCH, 0);
-                       ts->pen_down = false;
-               }
-       }
-       input_sync(ts->idev);
-       dev_dbg(&ts->spi->dev, "point(%4d,%4d), pressure (%4d)\n", x, y,
-               pressure);
-}
-
-static irqreturn_t tsc2005_irq_thread(int irq, void *_ts)
-{
-       struct tsc2005 *ts = _ts;
-       unsigned long flags;
-       unsigned int pressure;
-       struct tsc2005_data tsdata;
-       int error;
-
-       /* read the coordinates */
-       error = regmap_bulk_read(ts->regmap, TSC2005_REG_X, &tsdata,
-                                TSC2005_DATA_REGS);
-       if (unlikely(error))
-               goto out;
-
-       /* validate position */
-       if (unlikely(tsdata.x > MAX_12BIT || tsdata.y > MAX_12BIT))
-               goto out;
-
-       /* Skip reading if the pressure components are out of range */
-       if (unlikely(tsdata.z1 == 0 || tsdata.z2 > MAX_12BIT))
-               goto out;
-       if (unlikely(tsdata.z1 >= tsdata.z2))
-               goto out;
-
-       /*
-       * Skip point if this is a pen down with the exact same values as
-       * the value before pen-up - that implies SPI fed us stale data
-       */
-       if (!ts->pen_down &&
-           ts->in_x == tsdata.x && ts->in_y == tsdata.y &&
-           ts->in_z1 == tsdata.z1 && ts->in_z2 == tsdata.z2) {
-               goto out;
-       }
-
-       /*
-        * At this point we are happy we have a valid and useful reading.
-        * Remember it for later comparisons. We may now begin downsampling.
-        */
-       ts->in_x = tsdata.x;
-       ts->in_y = tsdata.y;
-       ts->in_z1 = tsdata.z1;
-       ts->in_z2 = tsdata.z2;
-
-       /* Compute touch pressure resistance using equation #1 */
-       pressure = tsdata.x * (tsdata.z2 - tsdata.z1) / tsdata.z1;
-       pressure = pressure * ts->x_plate_ohm / 4096;
-       if (unlikely(pressure > MAX_12BIT))
-               goto out;
-
-       spin_lock_irqsave(&ts->lock, flags);
-
-       tsc2005_update_pen_state(ts, tsdata.x, tsdata.y, pressure);
-       mod_timer(&ts->penup_timer,
-                 jiffies + msecs_to_jiffies(TSC2005_PENUP_TIME_MS));
-
-       spin_unlock_irqrestore(&ts->lock, flags);
-
-       ts->last_valid_interrupt = jiffies;
-out:
-       return IRQ_HANDLED;
-}
-
-static void tsc2005_penup_timer(unsigned long data)
-{
-       struct tsc2005 *ts = (struct tsc2005 *)data;
-       unsigned long flags;
-
-       spin_lock_irqsave(&ts->lock, flags);
-       tsc2005_update_pen_state(ts, 0, 0, 0);
-       spin_unlock_irqrestore(&ts->lock, flags);
-}
-
-static void tsc2005_start_scan(struct tsc2005 *ts)
-{
-       regmap_write(ts->regmap, TSC2005_REG_CFR0, TSC2005_CFR0_INITVALUE);
-       regmap_write(ts->regmap, TSC2005_REG_CFR1, TSC2005_CFR1_INITVALUE);
-       regmap_write(ts->regmap, TSC2005_REG_CFR2, TSC2005_CFR2_INITVALUE);
-       tsc2005_cmd(ts, TSC2005_CMD_NORMAL);
-}
-
-static void tsc2005_stop_scan(struct tsc2005 *ts)
-{
-       tsc2005_cmd(ts, TSC2005_CMD_STOP);
-}
-
-static void tsc2005_set_reset(struct tsc2005 *ts, bool enable)
-{
-       if (ts->reset_gpio)
-               gpiod_set_value_cansleep(ts->reset_gpio, enable);
-       else if (ts->set_reset)
-               ts->set_reset(enable);
-}
-
-/* must be called with ts->mutex held */
-static void __tsc2005_disable(struct tsc2005 *ts)
-{
-       tsc2005_stop_scan(ts);
-
-       disable_irq(ts->spi->irq);
-       del_timer_sync(&ts->penup_timer);
-
-       cancel_delayed_work_sync(&ts->esd_work);
-
-       enable_irq(ts->spi->irq);
-}
-
-/* must be called with ts->mutex held */
-static void __tsc2005_enable(struct tsc2005 *ts)
-{
-       tsc2005_start_scan(ts);
-
-       if (ts->esd_timeout && (ts->set_reset || ts->reset_gpio)) {
-               ts->last_valid_interrupt = jiffies;
-               schedule_delayed_work(&ts->esd_work,
-                               round_jiffies_relative(
-                                       msecs_to_jiffies(ts->esd_timeout)));
-       }
-
-}
-
-static ssize_t tsc2005_selftest_show(struct device *dev,
-                                    struct device_attribute *attr,
-                                    char *buf)
-{
-       struct tsc2005 *ts = dev_get_drvdata(dev);
-       unsigned int temp_high;
-       unsigned int temp_high_orig;
-       unsigned int temp_high_test;
-       bool success = true;
-       int error;
-
-       mutex_lock(&ts->mutex);
-
-       /*
-        * Test TSC2005 communications via temp high register.
-        */
-       __tsc2005_disable(ts);
-
-       error = regmap_read(ts->regmap, TSC2005_REG_TEMP_HIGH, &temp_high_orig);
-       if (error) {
-               dev_warn(dev, "selftest failed: read error %d\n", error);
-               success = false;
-               goto out;
-       }
-
-       temp_high_test = (temp_high_orig - 1) & MAX_12BIT;
-
-       error = regmap_write(ts->regmap, TSC2005_REG_TEMP_HIGH, temp_high_test);
-       if (error) {
-               dev_warn(dev, "selftest failed: write error %d\n", error);
-               success = false;
-               goto out;
-       }
-
-       error = regmap_read(ts->regmap, TSC2005_REG_TEMP_HIGH, &temp_high);
-       if (error) {
-               dev_warn(dev, "selftest failed: read error %d after write\n",
-                        error);
-               success = false;
-               goto out;
-       }
-
-       if (temp_high != temp_high_test) {
-               dev_warn(dev, "selftest failed: %d != %d\n",
-                        temp_high, temp_high_test);
-               success = false;
-       }
-
-       /* hardware reset */
-       tsc2005_set_reset(ts, false);
-       usleep_range(100, 500); /* only 10us required */
-       tsc2005_set_reset(ts, true);
-
-       if (!success)
-               goto out;
-
-       /* test that the reset really happened */
-       error = regmap_read(ts->regmap, TSC2005_REG_TEMP_HIGH, &temp_high);
-       if (error) {
-               dev_warn(dev, "selftest failed: read error %d after reset\n",
-                        error);
-               success = false;
-               goto out;
-       }
-
-       if (temp_high != temp_high_orig) {
-               dev_warn(dev, "selftest failed after reset: %d != %d\n",
-                        temp_high, temp_high_orig);
-               success = false;
-       }
-
-out:
-       __tsc2005_enable(ts);
-       mutex_unlock(&ts->mutex);
-
-       return sprintf(buf, "%d\n", success);
-}
-
-static DEVICE_ATTR(selftest, S_IRUGO, tsc2005_selftest_show, NULL);
-
-static struct attribute *tsc2005_attrs[] = {
-       &dev_attr_selftest.attr,
-       NULL
-};
-
-static umode_t tsc2005_attr_is_visible(struct kobject *kobj,
-                                     struct attribute *attr, int n)
-{
-       struct device *dev = container_of(kobj, struct device, kobj);
-       struct tsc2005 *ts = dev_get_drvdata(dev);
-       umode_t mode = attr->mode;
-
-       if (attr == &dev_attr_selftest.attr) {
-               if (!ts->set_reset && !ts->reset_gpio)
-                       mode = 0;
-       }
-
-       return mode;
-}
-
-static const struct attribute_group tsc2005_attr_group = {
-       .is_visible     = tsc2005_attr_is_visible,
-       .attrs          = tsc2005_attrs,
-};
-
-static void tsc2005_esd_work(struct work_struct *work)
-{
-       struct tsc2005 *ts = container_of(work, struct tsc2005, esd_work.work);
-       int error;
-       unsigned int r;
-
-       if (!mutex_trylock(&ts->mutex)) {
-               /*
-                * If the mutex is taken, it means that disable or enable is in
-                * progress. In that case just reschedule the work. If the work
-                * is not needed, it will be canceled by disable.
-                */
-               goto reschedule;
-       }
-
-       if (time_is_after_jiffies(ts->last_valid_interrupt +
-                                 msecs_to_jiffies(ts->esd_timeout)))
-               goto out;
-
-       /* We should be able to read register without disabling interrupts. */
-       error = regmap_read(ts->regmap, TSC2005_REG_CFR0, &r);
-       if (!error &&
-           !((r ^ TSC2005_CFR0_INITVALUE) & TSC2005_CFR0_RW_MASK)) {
-               goto out;
-       }
-
-       /*
-        * If we could not read our known value from configuration register 0
-        * then we should reset the controller as if from power-up and start
-        * scanning again.
-        */
-       dev_info(&ts->spi->dev, "TSC2005 not responding - resetting\n");
-
-       disable_irq(ts->spi->irq);
-       del_timer_sync(&ts->penup_timer);
-
-       tsc2005_update_pen_state(ts, 0, 0, 0);
-
-       tsc2005_set_reset(ts, false);
-       usleep_range(100, 500); /* only 10us required */
-       tsc2005_set_reset(ts, true);
-
-       enable_irq(ts->spi->irq);
-       tsc2005_start_scan(ts);
-
-out:
-       mutex_unlock(&ts->mutex);
-reschedule:
-       /* re-arm the watchdog */
-       schedule_delayed_work(&ts->esd_work,
-                             round_jiffies_relative(
-                                       msecs_to_jiffies(ts->esd_timeout)));
-}
-
-static int tsc2005_open(struct input_dev *input)
-{
-       struct tsc2005 *ts = input_get_drvdata(input);
-
-       mutex_lock(&ts->mutex);
-
-       if (!ts->suspended)
-               __tsc2005_enable(ts);
-
-       ts->opened = true;
-
-       mutex_unlock(&ts->mutex);
-
-       return 0;
-}
-
-static void tsc2005_close(struct input_dev *input)
-{
-       struct tsc2005 *ts = input_get_drvdata(input);
-
-       mutex_lock(&ts->mutex);
-
-       if (!ts->suspended)
-               __tsc2005_disable(ts);
-
-       ts->opened = false;
-
-       mutex_unlock(&ts->mutex);
-}
-
 static int tsc2005_probe(struct spi_device *spi)
 {
-       const struct tsc2005_platform_data *pdata = dev_get_platdata(&spi->dev);
-       struct device_node *np = spi->dev.of_node;
-
-       struct tsc2005 *ts;
-       struct input_dev *input_dev;
-       unsigned int max_x = MAX_12BIT;
-       unsigned int max_y = MAX_12BIT;
-       unsigned int max_p = MAX_12BIT;
-       unsigned int fudge_x = TSC2005_DEF_X_FUZZ;
-       unsigned int fudge_y = TSC2005_DEF_Y_FUZZ;
-       unsigned int fudge_p = TSC2005_DEF_P_FUZZ;
-       unsigned int x_plate_ohm = TSC2005_DEF_RESISTOR;
-       unsigned int esd_timeout;
        int error;
 
-       if (!np && !pdata) {
-               dev_err(&spi->dev, "no platform data\n");
-               return -ENODEV;
-       }
-
-       if (spi->irq <= 0) {
-               dev_err(&spi->dev, "no irq\n");
-               return -ENODEV;
-       }
-
-       if (pdata) {
-               fudge_x = pdata->ts_x_fudge;
-               fudge_y = pdata->ts_y_fudge;
-               fudge_p = pdata->ts_pressure_fudge;
-               max_x   = pdata->ts_x_max;
-               max_y   = pdata->ts_y_max;
-               max_p   = pdata->ts_pressure_max;
-               x_plate_ohm = pdata->ts_x_plate_ohm;
-               esd_timeout = pdata->esd_timeout_ms;
-       } else {
-               x_plate_ohm = TSC2005_DEF_RESISTOR;
-               of_property_read_u32(np, "ti,x-plate-ohms", &x_plate_ohm);
-               esd_timeout = 0;
-               of_property_read_u32(np, "ti,esd-recovery-timeout-ms",
-                                                               &esd_timeout);
-       }
-
        spi->mode = SPI_MODE_0;
        spi->bits_per_word = 8;
        if (!spi->max_speed_hz)
@@ -593,174 +62,27 @@ static int tsc2005_probe(struct spi_device *spi)
        if (error)
                return error;
 
-       ts = devm_kzalloc(&spi->dev, sizeof(*ts), GFP_KERNEL);
-       if (!ts)
-               return -ENOMEM;
-
-       input_dev = devm_input_allocate_device(&spi->dev);
-       if (!input_dev)
-               return -ENOMEM;
-
-       ts->spi = spi;
-       ts->idev = input_dev;
-
-       ts->regmap = devm_regmap_init_spi(spi, &tsc2005_regmap_config);
-       if (IS_ERR(ts->regmap))
-               return PTR_ERR(ts->regmap);
-
-       ts->x_plate_ohm = x_plate_ohm;
-       ts->esd_timeout = esd_timeout;
-
-       ts->reset_gpio = devm_gpiod_get_optional(&spi->dev, "reset",
-                                                GPIOD_OUT_HIGH);
-       if (IS_ERR(ts->reset_gpio)) {
-               error = PTR_ERR(ts->reset_gpio);
-               dev_err(&spi->dev, "error acquiring reset gpio: %d\n", error);
-               return error;
-       }
-
-       ts->vio = devm_regulator_get_optional(&spi->dev, "vio");
-       if (IS_ERR(ts->vio)) {
-               error = PTR_ERR(ts->vio);
-               dev_err(&spi->dev, "vio regulator missing (%d)", error);
-               return error;
-       }
-
-       if (!ts->reset_gpio && pdata)
-               ts->set_reset = pdata->set_reset;
-
-       mutex_init(&ts->mutex);
-
-       spin_lock_init(&ts->lock);
-       setup_timer(&ts->penup_timer, tsc2005_penup_timer, (unsigned long)ts);
-
-       INIT_DELAYED_WORK(&ts->esd_work, tsc2005_esd_work);
-
-       snprintf(ts->phys, sizeof(ts->phys),
-                "%s/input-ts", dev_name(&spi->dev));
-
-       input_dev->name = "TSC2005 touchscreen";
-       input_dev->phys = ts->phys;
-       input_dev->id.bustype = BUS_SPI;
-       input_dev->dev.parent = &spi->dev;
-       input_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
-       input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
-
-       input_set_abs_params(input_dev, ABS_X, 0, max_x, fudge_x, 0);
-       input_set_abs_params(input_dev, ABS_Y, 0, max_y, fudge_y, 0);
-       input_set_abs_params(input_dev, ABS_PRESSURE, 0, max_p, fudge_p, 0);
-
-       if (np)
-               touchscreen_parse_properties(input_dev, false);
-
-       input_dev->open = tsc2005_open;
-       input_dev->close = tsc2005_close;
-
-       input_set_drvdata(input_dev, ts);
-
-       /* Ensure the touchscreen is off */
-       tsc2005_stop_scan(ts);
-
-       error = devm_request_threaded_irq(&spi->dev, spi->irq, NULL,
-                                         tsc2005_irq_thread,
-                                         IRQF_TRIGGER_RISING | IRQF_ONESHOT,
-                                         "tsc2005", ts);
-       if (error) {
-               dev_err(&spi->dev, "Failed to request irq, err: %d\n", error);
-               return error;
-       }
-
-       /* enable regulator for DT */
-       if (ts->vio) {
-               error = regulator_enable(ts->vio);
-               if (error)
-                       return error;
-       }
-
-       dev_set_drvdata(&spi->dev, ts);
-       error = sysfs_create_group(&spi->dev.kobj, &tsc2005_attr_group);
-       if (error) {
-               dev_err(&spi->dev,
-                       "Failed to create sysfs attributes, err: %d\n", error);
-               goto disable_regulator;
-       }
-
-       error = input_register_device(ts->idev);
-       if (error) {
-               dev_err(&spi->dev,
-                       "Failed to register input device, err: %d\n", error);
-               goto err_remove_sysfs;
-       }
-
-       irq_set_irq_wake(spi->irq, 1);
-       return 0;
-
-err_remove_sysfs:
-       sysfs_remove_group(&spi->dev.kobj, &tsc2005_attr_group);
-disable_regulator:
-       if (ts->vio)
-               regulator_disable(ts->vio);
-       return error;
+       return tsc200x_probe(&spi->dev, spi->irq, BUS_SPI,
+                            devm_regmap_init_spi(spi, &tsc200x_regmap_config),
+                            tsc2005_cmd);
 }
 
 static int tsc2005_remove(struct spi_device *spi)
 {
-       struct tsc2005 *ts = dev_get_drvdata(&spi->dev);
-
-       sysfs_remove_group(&spi->dev.kobj, &tsc2005_attr_group);
-
-       if (ts->vio)
-               regulator_disable(ts->vio);
-
-       return 0;
-}
-
-static int __maybe_unused tsc2005_suspend(struct device *dev)
-{
-       struct tsc2005 *ts = dev_get_drvdata(dev);
-
-       mutex_lock(&ts->mutex);
-
-       if (!ts->suspended && ts->opened)
-               __tsc2005_disable(ts);
-
-       ts->suspended = true;
-
-       mutex_unlock(&ts->mutex);
-
-       return 0;
-}
-
-static int __maybe_unused tsc2005_resume(struct device *dev)
-{
-       struct tsc2005 *ts = dev_get_drvdata(dev);
-
-       mutex_lock(&ts->mutex);
-
-       if (ts->suspended && ts->opened)
-               __tsc2005_enable(ts);
-
-       ts->suspended = false;
-
-       mutex_unlock(&ts->mutex);
-
-       return 0;
+       return tsc200x_remove(&spi->dev);
 }
 
-static SIMPLE_DEV_PM_OPS(tsc2005_pm_ops, tsc2005_suspend, tsc2005_resume);
-
 static struct spi_driver tsc2005_driver = {
        .driver = {
                .name   = "tsc2005",
-               .pm     = &tsc2005_pm_ops,
+               .pm     = &tsc200x_pm_ops,
        },
        .probe  = tsc2005_probe,
        .remove = tsc2005_remove,
 };
-
 module_spi_driver(tsc2005_driver);
 
-MODULE_AUTHOR("Lauri Leukkunen <lauri.leukkunen@nokia.com>");
+MODULE_AUTHOR("Michael Welling <mwelling@ieee.org>");
 MODULE_DESCRIPTION("TSC2005 Touchscreen Driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("spi:tsc2005");
diff --git a/drivers/input/touchscreen/tsc200x-core.c b/drivers/input/touchscreen/tsc200x-core.c
new file mode 100644 (file)
index 0000000..15240c1
--- /dev/null
@@ -0,0 +1,665 @@
+/*
+ * TSC2004/TSC2005 touchscreen driver core
+ *
+ * Copyright (C) 2006-2010 Nokia Corporation
+ * Copyright (C) 2015 QWERTY Embedded Design
+ * Copyright (C) 2015 EMAC Inc.
+ *
+ * Author: Lauri Leukkunen <lauri.leukkunen@nokia.com>
+ * based on TSC2301 driver by Klaus K. Pedersen <klaus.k.pedersen@nokia.com>
+ *
+ * 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/kernel.h>
+#include <linux/module.h>
+#include <linux/input.h>
+#include <linux/input/touchscreen.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/of.h>
+#include <linux/spi/tsc2005.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regmap.h>
+#include <linux/gpio/consumer.h>
+#include "tsc200x-core.h"
+
+/*
+ * The touchscreen interface operates as follows:
+ *
+ * 1) Pen is pressed against the touchscreen.
+ * 2) TSC200X performs AD conversion.
+ * 3) After the conversion is done TSC200X drives DAV line down.
+ * 4) GPIO IRQ is received and tsc200x_irq_thread() is scheduled.
+ * 5) tsc200x_irq_thread() queues up a transfer to fetch the x, y, z1, z2
+ *    values.
+ * 6) tsc200x_irq_thread() reports coordinates to input layer and sets up
+ *    tsc200x_penup_timer() to be called after TSC200X_PENUP_TIME_MS (40ms).
+ * 7) When the penup timer expires, there have not been touch or DAV interrupts
+ *    during the last 40ms which means the pen has been lifted.
+ *
+ * ESD recovery via a hardware reset is done if the TSC200X doesn't respond
+ * after a configurable period (in ms) of activity. If esd_timeout is 0, the
+ * watchdog is disabled.
+ */
+
+static const struct regmap_range tsc200x_writable_ranges[] = {
+       regmap_reg_range(TSC200X_REG_AUX_HIGH, TSC200X_REG_CFR2),
+};
+
+static const struct regmap_access_table tsc200x_writable_table = {
+       .yes_ranges = tsc200x_writable_ranges,
+       .n_yes_ranges = ARRAY_SIZE(tsc200x_writable_ranges),
+};
+
+const struct regmap_config tsc200x_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 16,
+       .reg_stride = 0x08,
+       .max_register = 0x78,
+       .read_flag_mask = TSC200X_REG_READ,
+       .write_flag_mask = TSC200X_REG_PND0,
+       .wr_table = &tsc200x_writable_table,
+       .use_single_rw = true,
+};
+EXPORT_SYMBOL_GPL(tsc200x_regmap_config);
+
+struct tsc200x_data {
+       u16 x;
+       u16 y;
+       u16 z1;
+       u16 z2;
+} __packed;
+#define TSC200X_DATA_REGS 4
+
+struct tsc200x {
+       struct device           *dev;
+       struct regmap           *regmap;
+       __u16                   bustype;
+
+       struct input_dev        *idev;
+       char                    phys[32];
+
+       struct mutex            mutex;
+
+       /* raw copy of previous x,y,z */
+       int                     in_x;
+       int                     in_y;
+       int                     in_z1;
+       int                     in_z2;
+
+       spinlock_t              lock;
+       struct timer_list       penup_timer;
+
+       unsigned int            esd_timeout;
+       struct delayed_work     esd_work;
+       unsigned long           last_valid_interrupt;
+
+       unsigned int            x_plate_ohm;
+
+       bool                    opened;
+       bool                    suspended;
+
+       bool                    pen_down;
+
+       struct regulator        *vio;
+
+       struct gpio_desc        *reset_gpio;
+       void                    (*set_reset)(bool enable);
+       int                     (*tsc200x_cmd)(struct device *dev, u8 cmd);
+       int                     irq;
+};
+
+static void tsc200x_update_pen_state(struct tsc200x *ts,
+                                    int x, int y, int pressure)
+{
+       if (pressure) {
+               input_report_abs(ts->idev, ABS_X, x);
+               input_report_abs(ts->idev, ABS_Y, y);
+               input_report_abs(ts->idev, ABS_PRESSURE, pressure);
+               if (!ts->pen_down) {
+                       input_report_key(ts->idev, BTN_TOUCH, !!pressure);
+                       ts->pen_down = true;
+               }
+       } else {
+               input_report_abs(ts->idev, ABS_PRESSURE, 0);
+               if (ts->pen_down) {
+                       input_report_key(ts->idev, BTN_TOUCH, 0);
+                       ts->pen_down = false;
+               }
+       }
+       input_sync(ts->idev);
+       dev_dbg(ts->dev, "point(%4d,%4d), pressure (%4d)\n", x, y,
+               pressure);
+}
+
+static irqreturn_t tsc200x_irq_thread(int irq, void *_ts)
+{
+       struct tsc200x *ts = _ts;
+       unsigned long flags;
+       unsigned int pressure;
+       struct tsc200x_data tsdata;
+       int error;
+
+       /* read the coordinates */
+       error = regmap_bulk_read(ts->regmap, TSC200X_REG_X, &tsdata,
+                                TSC200X_DATA_REGS);
+       if (unlikely(error))
+               goto out;
+
+       /* validate position */
+       if (unlikely(tsdata.x > MAX_12BIT || tsdata.y > MAX_12BIT))
+               goto out;
+
+       /* Skip reading if the pressure components are out of range */
+       if (unlikely(tsdata.z1 == 0 || tsdata.z2 > MAX_12BIT))
+               goto out;
+       if (unlikely(tsdata.z1 >= tsdata.z2))
+               goto out;
+
+       /*
+       * Skip point if this is a pen down with the exact same values as
+       * the value before pen-up - that implies SPI fed us stale data
+       */
+       if (!ts->pen_down &&
+           ts->in_x == tsdata.x && ts->in_y == tsdata.y &&
+           ts->in_z1 == tsdata.z1 && ts->in_z2 == tsdata.z2) {
+               goto out;
+       }
+
+       /*
+        * At this point we are happy we have a valid and useful reading.
+        * Remember it for later comparisons. We may now begin downsampling.
+        */
+       ts->in_x = tsdata.x;
+       ts->in_y = tsdata.y;
+       ts->in_z1 = tsdata.z1;
+       ts->in_z2 = tsdata.z2;
+
+       /* Compute touch pressure resistance using equation #1 */
+       pressure = tsdata.x * (tsdata.z2 - tsdata.z1) / tsdata.z1;
+       pressure = pressure * ts->x_plate_ohm / 4096;
+       if (unlikely(pressure > MAX_12BIT))
+               goto out;
+
+       spin_lock_irqsave(&ts->lock, flags);
+
+       tsc200x_update_pen_state(ts, tsdata.x, tsdata.y, pressure);
+       mod_timer(&ts->penup_timer,
+                 jiffies + msecs_to_jiffies(TSC200X_PENUP_TIME_MS));
+
+       spin_unlock_irqrestore(&ts->lock, flags);
+
+       ts->last_valid_interrupt = jiffies;
+out:
+       return IRQ_HANDLED;
+}
+
+static void tsc200x_penup_timer(unsigned long data)
+{
+       struct tsc200x *ts = (struct tsc200x *)data;
+       unsigned long flags;
+
+       spin_lock_irqsave(&ts->lock, flags);
+       tsc200x_update_pen_state(ts, 0, 0, 0);
+       spin_unlock_irqrestore(&ts->lock, flags);
+}
+
+static void tsc200x_start_scan(struct tsc200x *ts)
+{
+       regmap_write(ts->regmap, TSC200X_REG_CFR0, TSC200X_CFR0_INITVALUE);
+       regmap_write(ts->regmap, TSC200X_REG_CFR1, TSC200X_CFR1_INITVALUE);
+       regmap_write(ts->regmap, TSC200X_REG_CFR2, TSC200X_CFR2_INITVALUE);
+       ts->tsc200x_cmd(ts->dev, TSC200X_CMD_NORMAL);
+}
+
+static void tsc200x_stop_scan(struct tsc200x *ts)
+{
+       ts->tsc200x_cmd(ts->dev, TSC200X_CMD_STOP);
+}
+
+static void tsc200x_set_reset(struct tsc200x *ts, bool enable)
+{
+       if (ts->reset_gpio)
+               gpiod_set_value_cansleep(ts->reset_gpio, enable);
+       else if (ts->set_reset)
+               ts->set_reset(enable);
+}
+
+/* must be called with ts->mutex held */
+static void __tsc200x_disable(struct tsc200x *ts)
+{
+       tsc200x_stop_scan(ts);
+
+       disable_irq(ts->irq);
+       del_timer_sync(&ts->penup_timer);
+
+       cancel_delayed_work_sync(&ts->esd_work);
+
+       enable_irq(ts->irq);
+}
+
+/* must be called with ts->mutex held */
+static void __tsc200x_enable(struct tsc200x *ts)
+{
+       tsc200x_start_scan(ts);
+
+       if (ts->esd_timeout && (ts->set_reset || ts->reset_gpio)) {
+               ts->last_valid_interrupt = jiffies;
+               schedule_delayed_work(&ts->esd_work,
+                               round_jiffies_relative(
+                                       msecs_to_jiffies(ts->esd_timeout)));
+       }
+}
+
+static ssize_t tsc200x_selftest_show(struct device *dev,
+                                    struct device_attribute *attr,
+                                    char *buf)
+{
+       struct tsc200x *ts = dev_get_drvdata(dev);
+       unsigned int temp_high;
+       unsigned int temp_high_orig;
+       unsigned int temp_high_test;
+       bool success = true;
+       int error;
+
+       mutex_lock(&ts->mutex);
+
+       /*
+        * Test TSC200X communications via temp high register.
+        */
+       __tsc200x_disable(ts);
+
+       error = regmap_read(ts->regmap, TSC200X_REG_TEMP_HIGH, &temp_high_orig);
+       if (error) {
+               dev_warn(dev, "selftest failed: read error %d\n", error);
+               success = false;
+               goto out;
+       }
+
+       temp_high_test = (temp_high_orig - 1) & MAX_12BIT;
+
+       error = regmap_write(ts->regmap, TSC200X_REG_TEMP_HIGH, temp_high_test);
+       if (error) {
+               dev_warn(dev, "selftest failed: write error %d\n", error);
+               success = false;
+               goto out;
+       }
+
+       error = regmap_read(ts->regmap, TSC200X_REG_TEMP_HIGH, &temp_high);
+       if (error) {
+               dev_warn(dev, "selftest failed: read error %d after write\n",
+                        error);
+               success = false;
+               goto out;
+       }
+
+       if (temp_high != temp_high_test) {
+               dev_warn(dev, "selftest failed: %d != %d\n",
+                        temp_high, temp_high_test);
+               success = false;
+       }
+
+       /* hardware reset */
+       tsc200x_set_reset(ts, false);
+       usleep_range(100, 500); /* only 10us required */
+       tsc200x_set_reset(ts, true);
+
+       if (!success)
+               goto out;
+
+       /* test that the reset really happened */
+       error = regmap_read(ts->regmap, TSC200X_REG_TEMP_HIGH, &temp_high);
+       if (error) {
+               dev_warn(dev, "selftest failed: read error %d after reset\n",
+                        error);
+               success = false;
+               goto out;
+       }
+
+       if (temp_high != temp_high_orig) {
+               dev_warn(dev, "selftest failed after reset: %d != %d\n",
+                        temp_high, temp_high_orig);
+               success = false;
+       }
+
+out:
+       __tsc200x_enable(ts);
+       mutex_unlock(&ts->mutex);
+
+       return sprintf(buf, "%d\n", success);
+}
+
+static DEVICE_ATTR(selftest, S_IRUGO, tsc200x_selftest_show, NULL);
+
+static struct attribute *tsc200x_attrs[] = {
+       &dev_attr_selftest.attr,
+       NULL
+};
+
+static umode_t tsc200x_attr_is_visible(struct kobject *kobj,
+                                     struct attribute *attr, int n)
+{
+       struct device *dev = container_of(kobj, struct device, kobj);
+       struct tsc200x *ts = dev_get_drvdata(dev);
+       umode_t mode = attr->mode;
+
+       if (attr == &dev_attr_selftest.attr) {
+               if (!ts->set_reset && !ts->reset_gpio)
+                       mode = 0;
+       }
+
+       return mode;
+}
+
+static const struct attribute_group tsc200x_attr_group = {
+       .is_visible     = tsc200x_attr_is_visible,
+       .attrs          = tsc200x_attrs,
+};
+
+static void tsc200x_esd_work(struct work_struct *work)
+{
+       struct tsc200x *ts = container_of(work, struct tsc200x, esd_work.work);
+       int error;
+       unsigned int r;
+
+       if (!mutex_trylock(&ts->mutex)) {
+               /*
+                * If the mutex is taken, it means that disable or enable is in
+                * progress. In that case just reschedule the work. If the work
+                * is not needed, it will be canceled by disable.
+                */
+               goto reschedule;
+       }
+
+       if (time_is_after_jiffies(ts->last_valid_interrupt +
+                                 msecs_to_jiffies(ts->esd_timeout)))
+               goto out;
+
+       /* We should be able to read register without disabling interrupts. */
+       error = regmap_read(ts->regmap, TSC200X_REG_CFR0, &r);
+       if (!error &&
+           !((r ^ TSC200X_CFR0_INITVALUE) & TSC200X_CFR0_RW_MASK)) {
+               goto out;
+       }
+
+       /*
+        * If we could not read our known value from configuration register 0
+        * then we should reset the controller as if from power-up and start
+        * scanning again.
+        */
+       dev_info(ts->dev, "TSC200X not responding - resetting\n");
+
+       disable_irq(ts->irq);
+       del_timer_sync(&ts->penup_timer);
+
+       tsc200x_update_pen_state(ts, 0, 0, 0);
+
+       tsc200x_set_reset(ts, false);
+       usleep_range(100, 500); /* only 10us required */
+       tsc200x_set_reset(ts, true);
+
+       enable_irq(ts->irq);
+       tsc200x_start_scan(ts);
+
+out:
+       mutex_unlock(&ts->mutex);
+reschedule:
+       /* re-arm the watchdog */
+       schedule_delayed_work(&ts->esd_work,
+                             round_jiffies_relative(
+                                       msecs_to_jiffies(ts->esd_timeout)));
+}
+
+static int tsc200x_open(struct input_dev *input)
+{
+       struct tsc200x *ts = input_get_drvdata(input);
+
+       mutex_lock(&ts->mutex);
+
+       if (!ts->suspended)
+               __tsc200x_enable(ts);
+
+       ts->opened = true;
+
+       mutex_unlock(&ts->mutex);
+
+       return 0;
+}
+
+static void tsc200x_close(struct input_dev *input)
+{
+       struct tsc200x *ts = input_get_drvdata(input);
+
+       mutex_lock(&ts->mutex);
+
+       if (!ts->suspended)
+               __tsc200x_disable(ts);
+
+       ts->opened = false;
+
+       mutex_unlock(&ts->mutex);
+}
+
+int tsc200x_probe(struct device *dev, int irq, __u16 bustype,
+                 struct regmap *regmap,
+                 int (*tsc200x_cmd)(struct device *dev, u8 cmd))
+{
+       const struct tsc2005_platform_data *pdata = dev_get_platdata(dev);
+       struct device_node *np = dev->of_node;
+
+       struct tsc200x *ts;
+       struct input_dev *input_dev;
+       unsigned int max_x = MAX_12BIT;
+       unsigned int max_y = MAX_12BIT;
+       unsigned int max_p = MAX_12BIT;
+       unsigned int fudge_x = TSC200X_DEF_X_FUZZ;
+       unsigned int fudge_y = TSC200X_DEF_Y_FUZZ;
+       unsigned int fudge_p = TSC200X_DEF_P_FUZZ;
+       unsigned int x_plate_ohm = TSC200X_DEF_RESISTOR;
+       unsigned int esd_timeout;
+       int error;
+
+       if (!np && !pdata) {
+               dev_err(dev, "no platform data\n");
+               return -ENODEV;
+       }
+
+       if (irq <= 0) {
+               dev_err(dev, "no irq\n");
+               return -ENODEV;
+       }
+
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       if (!tsc200x_cmd) {
+               dev_err(dev, "no cmd function\n");
+               return -ENODEV;
+       }
+
+       if (pdata) {
+               fudge_x = pdata->ts_x_fudge;
+               fudge_y = pdata->ts_y_fudge;
+               fudge_p = pdata->ts_pressure_fudge;
+               max_x   = pdata->ts_x_max;
+               max_y   = pdata->ts_y_max;
+               max_p   = pdata->ts_pressure_max;
+               x_plate_ohm = pdata->ts_x_plate_ohm;
+               esd_timeout = pdata->esd_timeout_ms;
+       } else {
+               x_plate_ohm = TSC200X_DEF_RESISTOR;
+               of_property_read_u32(np, "ti,x-plate-ohms", &x_plate_ohm);
+               esd_timeout = 0;
+               of_property_read_u32(np, "ti,esd-recovery-timeout-ms",
+                                                               &esd_timeout);
+       }
+
+       ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
+       if (!ts)
+               return -ENOMEM;
+
+       input_dev = devm_input_allocate_device(dev);
+       if (!input_dev)
+               return -ENOMEM;
+
+       ts->irq = irq;
+       ts->dev = dev;
+       ts->idev = input_dev;
+       ts->regmap = regmap;
+       ts->tsc200x_cmd = tsc200x_cmd;
+       ts->x_plate_ohm = x_plate_ohm;
+       ts->esd_timeout = esd_timeout;
+
+       ts->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
+       if (IS_ERR(ts->reset_gpio)) {
+               error = PTR_ERR(ts->reset_gpio);
+               dev_err(dev, "error acquiring reset gpio: %d\n", error);
+               return error;
+       }
+
+       ts->vio = devm_regulator_get_optional(dev, "vio");
+       if (IS_ERR(ts->vio)) {
+               error = PTR_ERR(ts->vio);
+               dev_err(dev, "vio regulator missing (%d)", error);
+               return error;
+       }
+
+       if (!ts->reset_gpio && pdata)
+               ts->set_reset = pdata->set_reset;
+
+       mutex_init(&ts->mutex);
+
+       spin_lock_init(&ts->lock);
+       setup_timer(&ts->penup_timer, tsc200x_penup_timer, (unsigned long)ts);
+
+       INIT_DELAYED_WORK(&ts->esd_work, tsc200x_esd_work);
+
+       snprintf(ts->phys, sizeof(ts->phys),
+                "%s/input-ts", dev_name(dev));
+
+       input_dev->name = "TSC200X touchscreen";
+       input_dev->phys = ts->phys;
+       input_dev->id.bustype = bustype;
+       input_dev->dev.parent = dev;
+       input_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
+       input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+
+       input_set_abs_params(input_dev, ABS_X, 0, max_x, fudge_x, 0);
+       input_set_abs_params(input_dev, ABS_Y, 0, max_y, fudge_y, 0);
+       input_set_abs_params(input_dev, ABS_PRESSURE, 0, max_p, fudge_p, 0);
+
+       if (np)
+               touchscreen_parse_properties(input_dev, false);
+
+       input_dev->open = tsc200x_open;
+       input_dev->close = tsc200x_close;
+
+       input_set_drvdata(input_dev, ts);
+
+       /* Ensure the touchscreen is off */
+       tsc200x_stop_scan(ts);
+
+       error = devm_request_threaded_irq(dev, irq, NULL,
+                                         tsc200x_irq_thread,
+                                         IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+                                         "tsc200x", ts);
+       if (error) {
+               dev_err(dev, "Failed to request irq, err: %d\n", error);
+               return error;
+       }
+
+       /* enable regulator for DT */
+       if (ts->vio) {
+               error = regulator_enable(ts->vio);
+               if (error)
+                       return error;
+       }
+
+       dev_set_drvdata(dev, ts);
+       error = sysfs_create_group(&dev->kobj, &tsc200x_attr_group);
+       if (error) {
+               dev_err(dev,
+                       "Failed to create sysfs attributes, err: %d\n", error);
+               goto disable_regulator;
+       }
+
+       error = input_register_device(ts->idev);
+       if (error) {
+               dev_err(dev,
+                       "Failed to register input device, err: %d\n", error);
+               goto err_remove_sysfs;
+       }
+
+       irq_set_irq_wake(irq, 1);
+       return 0;
+
+err_remove_sysfs:
+       sysfs_remove_group(&dev->kobj, &tsc200x_attr_group);
+disable_regulator:
+       if (ts->vio)
+               regulator_disable(ts->vio);
+       return error;
+}
+EXPORT_SYMBOL_GPL(tsc200x_probe);
+
+int tsc200x_remove(struct device *dev)
+{
+       struct tsc200x *ts = dev_get_drvdata(dev);
+
+       sysfs_remove_group(&dev->kobj, &tsc200x_attr_group);
+
+       if (ts->vio)
+               regulator_disable(ts->vio);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(tsc200x_remove);
+
+static int __maybe_unused tsc200x_suspend(struct device *dev)
+{
+       struct tsc200x *ts = dev_get_drvdata(dev);
+
+       mutex_lock(&ts->mutex);
+
+       if (!ts->suspended && ts->opened)
+               __tsc200x_disable(ts);
+
+       ts->suspended = true;
+
+       mutex_unlock(&ts->mutex);
+
+       return 0;
+}
+
+static int __maybe_unused tsc200x_resume(struct device *dev)
+{
+       struct tsc200x *ts = dev_get_drvdata(dev);
+
+       mutex_lock(&ts->mutex);
+
+       if (ts->suspended && ts->opened)
+               __tsc200x_enable(ts);
+
+       ts->suspended = false;
+
+       mutex_unlock(&ts->mutex);
+
+       return 0;
+}
+
+SIMPLE_DEV_PM_OPS(tsc200x_pm_ops, tsc200x_suspend, tsc200x_resume);
+EXPORT_SYMBOL_GPL(tsc200x_pm_ops);
+
+MODULE_AUTHOR("Lauri Leukkunen <lauri.leukkunen@nokia.com>");
+MODULE_DESCRIPTION("TSC200x Touchscreen Driver Core");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/tsc200x-core.h b/drivers/input/touchscreen/tsc200x-core.h
new file mode 100644 (file)
index 0000000..7a482d1
--- /dev/null
@@ -0,0 +1,78 @@
+#ifndef _TSC200X_CORE_H
+#define _TSC200X_CORE_H
+
+/* control byte 1 */
+#define TSC200X_CMD                    0x80
+#define TSC200X_CMD_NORMAL             0x00
+#define TSC200X_CMD_STOP               0x01
+#define TSC200X_CMD_12BIT              0x04
+
+/* control byte 0 */
+#define TSC200X_REG_READ               0x01 /* R/W access */
+#define TSC200X_REG_PND0               0x02 /* Power Not Down Control */
+#define TSC200X_REG_X                  (0x0 << 3)
+#define TSC200X_REG_Y                  (0x1 << 3)
+#define TSC200X_REG_Z1                 (0x2 << 3)
+#define TSC200X_REG_Z2                 (0x3 << 3)
+#define TSC200X_REG_AUX                        (0x4 << 3)
+#define TSC200X_REG_TEMP1              (0x5 << 3)
+#define TSC200X_REG_TEMP2              (0x6 << 3)
+#define TSC200X_REG_STATUS             (0x7 << 3)
+#define TSC200X_REG_AUX_HIGH           (0x8 << 3)
+#define TSC200X_REG_AUX_LOW            (0x9 << 3)
+#define TSC200X_REG_TEMP_HIGH          (0xA << 3)
+#define TSC200X_REG_TEMP_LOW           (0xB << 3)
+#define TSC200X_REG_CFR0               (0xC << 3)
+#define TSC200X_REG_CFR1               (0xD << 3)
+#define TSC200X_REG_CFR2               (0xE << 3)
+#define TSC200X_REG_CONV_FUNC          (0xF << 3)
+
+/* configuration register 0 */
+#define TSC200X_CFR0_PRECHARGE_276US   0x0040
+#define TSC200X_CFR0_STABTIME_1MS      0x0300
+#define TSC200X_CFR0_CLOCK_1MHZ                0x1000
+#define TSC200X_CFR0_RESOLUTION12      0x2000
+#define TSC200X_CFR0_PENMODE           0x8000
+#define TSC200X_CFR0_INITVALUE         (TSC200X_CFR0_STABTIME_1MS    | \
+                                        TSC200X_CFR0_CLOCK_1MHZ      | \
+                                        TSC200X_CFR0_RESOLUTION12    | \
+                                        TSC200X_CFR0_PRECHARGE_276US | \
+                                        TSC200X_CFR0_PENMODE)
+
+/* bits common to both read and write of configuration register 0 */
+#define        TSC200X_CFR0_RW_MASK            0x3fff
+
+/* configuration register 1 */
+#define TSC200X_CFR1_BATCHDELAY_4MS    0x0003
+#define TSC200X_CFR1_INITVALUE         TSC200X_CFR1_BATCHDELAY_4MS
+
+/* configuration register 2 */
+#define TSC200X_CFR2_MAVE_Z            0x0004
+#define TSC200X_CFR2_MAVE_Y            0x0008
+#define TSC200X_CFR2_MAVE_X            0x0010
+#define TSC200X_CFR2_AVG_7             0x0800
+#define TSC200X_CFR2_MEDIUM_15         0x3000
+#define TSC200X_CFR2_INITVALUE         (TSC200X_CFR2_MAVE_X    | \
+                                        TSC200X_CFR2_MAVE_Y    | \
+                                        TSC200X_CFR2_MAVE_Z    | \
+                                        TSC200X_CFR2_MEDIUM_15 | \
+                                        TSC200X_CFR2_AVG_7)
+
+#define MAX_12BIT                      0xfff
+#define TSC200X_DEF_X_FUZZ             4
+#define TSC200X_DEF_Y_FUZZ             8
+#define TSC200X_DEF_P_FUZZ             2
+#define TSC200X_DEF_RESISTOR           280
+
+#define TSC2005_SPI_MAX_SPEED_HZ       10000000
+#define TSC200X_PENUP_TIME_MS          40
+
+extern const struct regmap_config tsc200x_regmap_config;
+extern const struct dev_pm_ops tsc200x_pm_ops;
+
+int tsc200x_probe(struct device *dev, int irq, __u16 bustype,
+                 struct regmap *regmap,
+                 int (*tsc200x_cmd)(struct device *dev, u8 cmd));
+int tsc200x_remove(struct device *dev);
+
+#endif
index cbe198cb36991d3970f5a0ce4fc3596ee85eb5a7..471ee36b9c6eea6d72ad74302fadfb97c28f8a7f 100644 (file)
@@ -216,6 +216,7 @@ static int s390_iommu_update_trans(struct s390_domain *s390_domain,
        u8 *page_addr = (u8 *) (pa & PAGE_MASK);
        dma_addr_t start_dma_addr = dma_addr;
        unsigned long irq_flags, nr_pages, i;
+       unsigned long *entry;
        int rc = 0;
 
        if (dma_addr < s390_domain->domain.geometry.aperture_start ||
@@ -228,8 +229,12 @@ static int s390_iommu_update_trans(struct s390_domain *s390_domain,
 
        spin_lock_irqsave(&s390_domain->dma_table_lock, irq_flags);
        for (i = 0; i < nr_pages; i++) {
-               dma_update_cpu_trans(s390_domain->dma_table, page_addr,
-                                    dma_addr, flags);
+               entry = dma_walk_cpu_trans(s390_domain->dma_table, dma_addr);
+               if (!entry) {
+                       rc = -ENOMEM;
+                       goto undo_cpu_trans;
+               }
+               dma_update_cpu_trans(entry, page_addr, flags);
                page_addr += PAGE_SIZE;
                dma_addr += PAGE_SIZE;
        }
@@ -242,6 +247,20 @@ static int s390_iommu_update_trans(struct s390_domain *s390_domain,
                        break;
        }
        spin_unlock(&s390_domain->list_lock);
+
+undo_cpu_trans:
+       if (rc && ((flags & ZPCI_PTE_VALID_MASK) == ZPCI_PTE_VALID)) {
+               flags = ZPCI_PTE_INVALID;
+               while (i-- > 0) {
+                       page_addr -= PAGE_SIZE;
+                       dma_addr -= PAGE_SIZE;
+                       entry = dma_walk_cpu_trans(s390_domain->dma_table,
+                                                  dma_addr);
+                       if (!entry)
+                               break;
+                       dma_update_cpu_trans(entry, page_addr, flags);
+               }
+       }
        spin_unlock_irqrestore(&s390_domain->dma_table_lock, irq_flags);
 
        return rc;
index aeaa061f0dbfd3694d8a9f890822eba266e2e4e0..9e17ef27a183d6f62a6f2860ee416674a314465c 100644 (file)
@@ -29,6 +29,7 @@ struct gic_pcpu_mask {
        DECLARE_BITMAP(pcpu_mask, GIC_MAX_INTRS);
 };
 
+static unsigned long __gic_base_addr;
 static void __iomem *gic_base;
 static struct gic_pcpu_mask pcpu_masks[NR_CPUS];
 static DEFINE_SPINLOCK(gic_lock);
@@ -301,6 +302,17 @@ int gic_get_c0_fdc_int(void)
                                  GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_FDC));
 }
 
+int gic_get_usm_range(struct resource *gic_usm_res)
+{
+       if (!gic_present)
+               return -1;
+
+       gic_usm_res->start = __gic_base_addr + USM_VISIBLE_SECTION_OFS;
+       gic_usm_res->end = gic_usm_res->start + (USM_VISIBLE_SECTION_SIZE - 1);
+
+       return 0;
+}
+
 static void gic_handle_shared_int(bool chained)
 {
        unsigned int i, intr, virq, gic_reg_step = mips_cm_is64 ? 8 : 4;
@@ -798,6 +810,8 @@ static void __init __gic_init(unsigned long gic_base_addr,
 {
        unsigned int gicconfig;
 
+       __gic_base_addr = gic_base_addr;
+
        gic_base = ioremap_nocache(gic_base_addr, gic_addrspace_size);
 
        gicconfig = gic_read(GIC_REG(SHARED, GIC_SH_CONFIG));
index fc73937290812df292d9654ed43ec19f40497edf..02b5f69e1a423f2dd44eede58aaf010d55f3c9d9 100644 (file)
@@ -1038,6 +1038,10 @@ kbuf_alloc_2_sgl(int bytes, u32 sgdir, int sge_offset, int *frags,
        int              i, buflist_ent;
        int              sg_spill = MAX_FRAGS_SPILL1;
        int              dir;
+
+       if (bytes < 0)
+               return NULL;
+
        /* initialization */
        *frags = 0;
        *blp = NULL;
index 005a88b9f44029c42b2c700fa4e275482039c47f..7ebccfa8072a7ff8075ab2e71197713afc397dcf 100644 (file)
@@ -1994,7 +1994,6 @@ static struct scsi_host_template mptsas_driver_template = {
        .cmd_per_lun                    = 7,
        .use_clustering                 = ENABLE_CLUSTERING,
        .shost_attrs                    = mptscsih_host_attrs,
-       .use_blk_tags                   = 1,
 };
 
 static int mptsas_get_linkerrors(struct sas_phy *phy)
index b8374cdaf9c940ab202821bbaa76e6923f360c84..ee120dcbb3e6ba9b842859496d565129d66c1fd8 100644 (file)
@@ -220,11 +220,17 @@ static irqreturn_t spear_pcie_gadget_irq(int irq, void *dev_id)
 /*
  * configfs interfaces show/store functions
  */
-static ssize_t pcie_gadget_show_link(
-               struct spear_pcie_gadget_config *config,
-               char *buf)
+
+static struct pcie_gadget_target *to_target(struct config_item *item)
 {
-       struct pcie_app_reg __iomem *app_reg = config->va_app_base;
+       return item ?
+               container_of(to_configfs_subsystem(to_config_group(item)),
+                               struct pcie_gadget_target, subsys) : NULL;
+}
+
+static ssize_t pcie_gadget_link_show(struct config_item *item, char *buf)
+{
+       struct pcie_app_reg __iomem *app_reg = to_target(item)->va_app_base;
 
        if (readl(&app_reg->app_status_1) & ((u32)1 << XMLH_LINK_UP_ID))
                return sprintf(buf, "UP");
@@ -232,11 +238,10 @@ static ssize_t pcie_gadget_show_link(
                return sprintf(buf, "DOWN");
 }
 
-static ssize_t pcie_gadget_store_link(
-               struct spear_pcie_gadget_config *config,
+static ssize_t pcie_gadget_link_store(struct config_item *item,
                const char *buf, size_t count)
 {
-       struct pcie_app_reg __iomem *app_reg = config->va_app_base;
+       struct pcie_app_reg __iomem *app_reg = to_target(item)->va_app_base;
 
        if (sysfs_streq(buf, "UP"))
                writel(readl(&app_reg->app_ctrl_0) | (1 << APP_LTSSM_ENABLE_ID),
@@ -250,17 +255,15 @@ static ssize_t pcie_gadget_store_link(
        return count;
 }
 
-static ssize_t pcie_gadget_show_int_type(
-               struct spear_pcie_gadget_config *config,
-               char *buf)
+static ssize_t pcie_gadget_int_type_show(struct config_item *item, char *buf)
 {
-       return sprintf(buf, "%s", config->int_type);
+       return sprintf(buf, "%s", to_target(item)->int_type);
 }
 
-static ssize_t pcie_gadget_store_int_type(
-               struct spear_pcie_gadget_config *config,
+static ssize_t pcie_gadget_int_type_store(struct config_item *item,
                const char *buf, size_t count)
 {
+       struct spear_pcie_gadget_config *config = to_target(item)
        u32 cap, vec, flags;
        ulong vector;
 
@@ -288,11 +291,10 @@ static ssize_t pcie_gadget_store_int_type(
        return count;
 }
 
-static ssize_t pcie_gadget_show_no_of_msi(
-               struct spear_pcie_gadget_config *config,
-               char *buf)
+static ssize_t pcie_gadget_no_of_msi_show(struct config_item *item, char *buf)
 {
-       struct pcie_app_reg __iomem *app_reg = config->va_app_base;
+       struct spear_pcie_gadget_config *config = to_target(item)
+       struct pcie_app_reg __iomem *app_reg = to_target(item)->va_app_base;
        u32 cap, vec, flags;
        ulong vector;
 
@@ -313,13 +315,12 @@ static ssize_t pcie_gadget_show_no_of_msi(
        return sprintf(buf, "%lu", vector);
 }
 
-static ssize_t pcie_gadget_store_no_of_msi(
-               struct spear_pcie_gadget_config *config,
+static ssize_t pcie_gadget_no_of_msi_store(struct config_item *item,
                const char *buf, size_t count)
 {
        int ret;
 
-       ret = kstrtoul(buf, 0, &config->requested_msi);
+       ret = kstrtoul(buf, 0, &to_target(item)->requested_msi);
        if (ret)
                return ret;
 
@@ -329,11 +330,10 @@ static ssize_t pcie_gadget_store_no_of_msi(
        return count;
 }
 
-static ssize_t pcie_gadget_store_inta(
-               struct spear_pcie_gadget_config *config,
+static ssize_t pcie_gadget_inta_store(struct config_item *item,
                const char *buf, size_t count)
 {
-       struct pcie_app_reg __iomem *app_reg = config->va_app_base;
+       struct pcie_app_reg __iomem *app_reg = to_target(item)->va_app_base;
        ulong en;
        int ret;
 
@@ -351,10 +351,10 @@ static ssize_t pcie_gadget_store_inta(
        return count;
 }
 
-static ssize_t pcie_gadget_store_send_msi(
-               struct spear_pcie_gadget_config *config,
+static ssize_t pcie_gadget_send_msi_store(struct config_item *item,
                const char *buf, size_t count)
 {
+       struct spear_pcie_gadget_config *config = to_target(item)
        struct pcie_app_reg __iomem *app_reg = config->va_app_base;
        ulong vector;
        u32 ven_msi;
@@ -388,19 +388,16 @@ static ssize_t pcie_gadget_store_send_msi(
        return count;
 }
 
-static ssize_t pcie_gadget_show_vendor_id(
-               struct spear_pcie_gadget_config *config,
-               char *buf)
+static ssize_t pcie_gadget_vendor_id_show(struct config_item *item, char *buf)
 {
        u32 id;
 
-       spear_dbi_read_reg(config, PCI_VENDOR_ID, 2, &id);
+       spear_dbi_read_reg(to_target(item), PCI_VENDOR_ID, 2, &id);
 
        return sprintf(buf, "%x", id);
 }
 
-static ssize_t pcie_gadget_store_vendor_id(
-               struct spear_pcie_gadget_config *config,
+static ssize_t pcie_gadget_vendor_id_store(struct config_item *item,
                const char *buf, size_t count)
 {
        ulong id;
@@ -410,24 +407,21 @@ static ssize_t pcie_gadget_store_vendor_id(
        if (ret)
                return ret;
 
-       spear_dbi_write_reg(config, PCI_VENDOR_ID, 2, id);
+       spear_dbi_write_reg(to_target(item), PCI_VENDOR_ID, 2, id);
 
        return count;
 }
 
-static ssize_t pcie_gadget_show_device_id(
-               struct spear_pcie_gadget_config *config,
-               char *buf)
+static ssize_t pcie_gadget_device_id_show(struct config_item *item, char *buf)
 {
        u32 id;
 
-       spear_dbi_read_reg(config, PCI_DEVICE_ID, 2, &id);
+       spear_dbi_read_reg(to_target(item), PCI_DEVICE_ID, 2, &id);
 
        return sprintf(buf, "%x", id);
 }
 
-static ssize_t pcie_gadget_store_device_id(
-               struct spear_pcie_gadget_config *config,
+static ssize_t pcie_gadget_device_id_store(struct config_item *item,
                const char *buf, size_t count)
 {
        ulong id;
@@ -437,22 +431,20 @@ static ssize_t pcie_gadget_store_device_id(
        if (ret)
                return ret;
 
-       spear_dbi_write_reg(config, PCI_DEVICE_ID, 2, id);
+       spear_dbi_write_reg(to_target(item), PCI_DEVICE_ID, 2, id);
 
        return count;
 }
 
-static ssize_t pcie_gadget_show_bar0_size(
-               struct spear_pcie_gadget_config *config,
-               char *buf)
+static ssize_t pcie_gadget_bar0_size_show(struct config_item *item, char *buf)
 {
-       return sprintf(buf, "%lx", config->bar0_size);
+       return sprintf(buf, "%lx", to_target(item)->bar0_size);
 }
 
-static ssize_t pcie_gadget_store_bar0_size(
-               struct spear_pcie_gadget_config *config,
+static ssize_t pcie_gadget_bar0_size_store(struct config_item *item,
                const char *buf, size_t count)
 {
+       struct spear_pcie_gadget_config *config = to_target(item)
        ulong size;
        u32 pos, pos1;
        u32 no_of_bit = 0;
@@ -489,21 +481,20 @@ static ssize_t pcie_gadget_store_bar0_size(
        return count;
 }
 
-static ssize_t pcie_gadget_show_bar0_address(
-               struct spear_pcie_gadget_config *config,
+static ssize_t pcie_gadget_bar0_address_show(struct config_item *item,
                char *buf)
 {
-       struct pcie_app_reg __iomem *app_reg = config->va_app_base;
+       struct pcie_app_reg __iomem *app_reg = to_target(item)->va_app_base;
 
        u32 address = readl(&app_reg->pim0_mem_addr_start);
 
        return sprintf(buf, "%x", address);
 }
 
-static ssize_t pcie_gadget_store_bar0_address(
-               struct spear_pcie_gadget_config *config,
+static ssize_t pcie_gadget_bar0_address_store(struct config_item *item,
                const char *buf, size_t count)
 {
+       struct spear_pcie_gadget_config *config = to_target(item)
        struct pcie_app_reg __iomem *app_reg = config->va_app_base;
        ulong address;
        int ret;
@@ -524,15 +515,13 @@ static ssize_t pcie_gadget_store_bar0_address(
        return count;
 }
 
-static ssize_t pcie_gadget_show_bar0_rw_offset(
-               struct spear_pcie_gadget_config *config,
+static ssize_t pcie_gadget_bar0_rw_offset_show(struct config_item *item,
                char *buf)
 {
-       return sprintf(buf, "%lx", config->bar0_rw_offset);
+       return sprintf(buf, "%lx", to_target(item)->bar0_rw_offset);
 }
 
-static ssize_t pcie_gadget_store_bar0_rw_offset(
-               struct spear_pcie_gadget_config *config,
+static ssize_t pcie_gadget_bar0_rw_offset_store(struct config_item *item,
                const char *buf, size_t count)
 {
        ulong offset;
@@ -545,15 +534,14 @@ static ssize_t pcie_gadget_store_bar0_rw_offset(
        if (offset % 4)
                return -EINVAL;
 
-       config->bar0_rw_offset = offset;
+       to_target(item)->bar0_rw_offset = offset;
 
        return count;
 }
 
-static ssize_t pcie_gadget_show_bar0_data(
-               struct spear_pcie_gadget_config *config,
-               char *buf)
+static ssize_t pcie_gadget_bar0_data_show(struct config_item *item, char *buf)
 {
+       struct spear_pcie_gadget_config *config = to_target(item)
        ulong data;
 
        if (!config->va_bar0_address)
@@ -564,10 +552,10 @@ static ssize_t pcie_gadget_show_bar0_data(
        return sprintf(buf, "%lx", data);
 }
 
-static ssize_t pcie_gadget_store_bar0_data(
-               struct spear_pcie_gadget_config *config,
+static ssize_t pcie_gadget_bar0_data_store(struct config_item *item,
                const char *buf, size_t count)
 {
+       struct spear_pcie_gadget_config *config = to_target(item)
        ulong data;
        int ret;
 
@@ -583,97 +571,35 @@ static ssize_t pcie_gadget_store_bar0_data(
        return count;
 }
 
-/*
- * Attribute definitions.
- */
-
-#define PCIE_GADGET_TARGET_ATTR_RO(_name)                              \
-static struct pcie_gadget_target_attr pcie_gadget_target_##_name =     \
-       __CONFIGFS_ATTR(_name, S_IRUGO, pcie_gadget_show_##_name, NULL)
-
-#define PCIE_GADGET_TARGET_ATTR_WO(_name)                              \
-static struct pcie_gadget_target_attr pcie_gadget_target_##_name =     \
-       __CONFIGFS_ATTR(_name, S_IWUSR, NULL, pcie_gadget_store_##_name)
-
-#define PCIE_GADGET_TARGET_ATTR_RW(_name)                              \
-static struct pcie_gadget_target_attr pcie_gadget_target_##_name =     \
-       __CONFIGFS_ATTR(_name, S_IRUGO | S_IWUSR, pcie_gadget_show_##_name, \
-                       pcie_gadget_store_##_name)
-PCIE_GADGET_TARGET_ATTR_RW(link);
-PCIE_GADGET_TARGET_ATTR_RW(int_type);
-PCIE_GADGET_TARGET_ATTR_RW(no_of_msi);
-PCIE_GADGET_TARGET_ATTR_WO(inta);
-PCIE_GADGET_TARGET_ATTR_WO(send_msi);
-PCIE_GADGET_TARGET_ATTR_RW(vendor_id);
-PCIE_GADGET_TARGET_ATTR_RW(device_id);
-PCIE_GADGET_TARGET_ATTR_RW(bar0_size);
-PCIE_GADGET_TARGET_ATTR_RW(bar0_address);
-PCIE_GADGET_TARGET_ATTR_RW(bar0_rw_offset);
-PCIE_GADGET_TARGET_ATTR_RW(bar0_data);
+CONFIGFS_ATTR(pcie_gadget_, link);
+CONFIGFS_ATTR(pcie_gadget_, int_type);
+CONFIGFS_ATTR(pcie_gadget_, no_of_msi);
+CONFIGFS_ATTR_WO(pcie_gadget_, inta);
+CONFIGFS_ATTR_WO(pcie_gadget_, send_msi);
+CONFIGFS_ATTR(pcie_gadget_, vendor_id);
+CONFIGFS_ATTR(pcie_gadget_, device_id);
+CONFIGFS_ATTR(pcie_gadget_, bar0_size);
+CONFIGFS_ATTR(pcie_gadget_, bar0_address);
+CONFIGFS_ATTR(pcie_gadget_, bar0_rw_offset);
+CONFIGFS_ATTR(pcie_gadget_, bar0_data);
 
 static struct configfs_attribute *pcie_gadget_target_attrs[] = {
-       &pcie_gadget_target_link.attr,
-       &pcie_gadget_target_int_type.attr,
-       &pcie_gadget_target_no_of_msi.attr,
-       &pcie_gadget_target_inta.attr,
-       &pcie_gadget_target_send_msi.attr,
-       &pcie_gadget_target_vendor_id.attr,
-       &pcie_gadget_target_device_id.attr,
-       &pcie_gadget_target_bar0_size.attr,
-       &pcie_gadget_target_bar0_address.attr,
-       &pcie_gadget_target_bar0_rw_offset.attr,
-       &pcie_gadget_target_bar0_data.attr,
+       &pcie_gadget_attr_link,
+       &pcie_gadget_attr_int_type,
+       &pcie_gadget_attr_no_of_msi,
+       &pcie_gadget_attr_inta,
+       &pcie_gadget_attr_send_msi,
+       &pcie_gadget_attr_vendor_id,
+       &pcie_gadget_attr_device_id,
+       &pcie_gadget_attr_bar0_size,
+       &pcie_gadget_attr_bar0_address,
+       &pcie_gadget_attr_bar0_rw_offset,
+       &pcie_gadget_attr_bar0_data,
        NULL,
 };
 
-static struct pcie_gadget_target *to_target(struct config_item *item)
-{
-       return item ?
-               container_of(to_configfs_subsystem(to_config_group(item)),
-                               struct pcie_gadget_target, subsys) : NULL;
-}
-
-/*
- * Item operations and type for pcie_gadget_target.
- */
-
-static ssize_t pcie_gadget_target_attr_show(struct config_item *item,
-                                          struct configfs_attribute *attr,
-                                          char *buf)
-{
-       ssize_t ret = -EINVAL;
-       struct pcie_gadget_target *target = to_target(item);
-       struct pcie_gadget_target_attr *t_attr =
-               container_of(attr, struct pcie_gadget_target_attr, attr);
-
-       if (t_attr->show)
-               ret = t_attr->show(&target->config, buf);
-       return ret;
-}
-
-static ssize_t pcie_gadget_target_attr_store(struct config_item *item,
-                                       struct configfs_attribute *attr,
-                                       const char *buf,
-                                       size_t count)
-{
-       ssize_t ret = -EINVAL;
-       struct pcie_gadget_target *target = to_target(item);
-       struct pcie_gadget_target_attr *t_attr =
-               container_of(attr, struct pcie_gadget_target_attr, attr);
-
-       if (t_attr->store)
-               ret = t_attr->store(&target->config, buf, count);
-       return ret;
-}
-
-static struct configfs_item_operations pcie_gadget_target_item_ops = {
-       .show_attribute         = pcie_gadget_target_attr_show,
-       .store_attribute        = pcie_gadget_target_attr_store,
-};
-
 static struct config_item_type pcie_gadget_target_type = {
        .ct_attrs               = pcie_gadget_target_attrs,
-       .ct_item_ops            = &pcie_gadget_target_item_ops,
        .ct_owner               = THIS_MODULE,
 };
 
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 7dd893331785ebce1740280dfdee1acb13de0a52..618d952c2984c3756cee516fb4623f0cb6a80afd 100644 (file)
@@ -342,6 +342,7 @@ static int xgbe_probe(struct platform_device *pdev)
        struct resource *res;
        const char *phy_mode;
        unsigned int i, phy_memnum, phy_irqnum;
+       enum dev_dma_attr attr;
        int ret;
 
        DBGPR("--> xgbe_probe\n");
@@ -609,7 +610,12 @@ static int xgbe_probe(struct platform_device *pdev)
                goto err_io;
 
        /* Set the DMA coherency values */
-       pdata->coherent = device_dma_is_coherent(pdata->dev);
+       attr = device_get_dma_attr(dev);
+       if (attr == DEV_DMA_NOT_SUPPORTED) {
+               dev_err(dev, "DMA is not supported");
+               goto err_io;
+       }
+       pdata->coherent = (attr == DEV_DMA_COHERENT);
        if (pdata->coherent) {
                pdata->axdomain = XGBE_DMA_OS_AXDOMAIN;
                pdata->arcache = XGBE_DMA_OS_ARCACHE;
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 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 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 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 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 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 ae68afd50a156199b6f74b2d2e65420cddd02c73..f38696ceee74afcb1aa4eb731e70b3c307e40193 100644 (file)
@@ -345,13 +345,6 @@ VELOCITY_PARAM(flow_control, "Enable flow control ability");
 */
 VELOCITY_PARAM(speed_duplex, "Setting the speed and duplex mode");
 
-#define VAL_PKT_LEN_DEF     0
-/* ValPktLen[] is used for setting the checksum offload ability of NIC.
-   0: Receive frame with invalid layer 2 length (Default)
-   1: Drop frame with invalid layer 2 length
-*/
-VELOCITY_PARAM(ValPktLen, "Receiving or Drop invalid 802.3 frame");
-
 #define WOL_OPT_DEF     0
 #define WOL_OPT_MIN     0
 #define WOL_OPT_MAX     7
@@ -494,7 +487,6 @@ static void velocity_get_options(struct velocity_opt *opts, int index,
 
        velocity_set_int_opt(&opts->flow_cntl, flow_control[index], FLOW_CNTL_MIN, FLOW_CNTL_MAX, FLOW_CNTL_DEF, "flow_control", devname);
        velocity_set_bool_opt(&opts->flags, IP_byte_align[index], IP_ALIG_DEF, VELOCITY_FLAGS_IP_ALIGN, "IP_byte_align", devname);
-       velocity_set_bool_opt(&opts->flags, ValPktLen[index], VAL_PKT_LEN_DEF, VELOCITY_FLAGS_VAL_PKT_LEN, "ValPktLen", devname);
        velocity_set_int_opt((int *) &opts->spd_dpx, speed_duplex[index], MED_LNK_MIN, MED_LNK_MAX, MED_LNK_DEF, "Media link mode", devname);
        velocity_set_int_opt(&opts->wol_opts, wol_opts[index], WOL_OPT_MIN, WOL_OPT_MAX, WOL_OPT_DEF, "Wake On Lan options", devname);
        opts->numrx = (opts->numrx & ~3);
@@ -2055,8 +2047,9 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx)
        int pkt_len = le16_to_cpu(rd->rdesc0.len) & 0x3fff;
        struct sk_buff *skb;
 
-       if (rd->rdesc0.RSR & (RSR_STP | RSR_EDP)) {
-               VELOCITY_PRT(MSG_LEVEL_VERBOSE, KERN_ERR " %s : the received frame spans multiple RDs.\n", vptr->netdev->name);
+       if (unlikely(rd->rdesc0.RSR & (RSR_STP | RSR_EDP | RSR_RL))) {
+               if (rd->rdesc0.RSR & (RSR_STP | RSR_EDP))
+                       VELOCITY_PRT(MSG_LEVEL_VERBOSE, KERN_ERR " %s : the received frame spans multiple RDs.\n", vptr->netdev->name);
                stats->rx_length_errors++;
                return -EINVAL;
        }
@@ -2069,17 +2062,6 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx)
        dma_sync_single_for_cpu(vptr->dev, rd_info->skb_dma,
                                    vptr->rx.buf_sz, DMA_FROM_DEVICE);
 
-       /*
-        *      Drop frame not meeting IEEE 802.3
-        */
-
-       if (vptr->flags & VELOCITY_FLAGS_VAL_PKT_LEN) {
-               if (rd->rdesc0.RSR & RSR_RL) {
-                       stats->rx_length_errors++;
-                       return -EINVAL;
-               }
-       }
-
        velocity_rx_csum(rd, skb);
 
        if (velocity_rx_copy(&skb, pkt_len, vptr) < 0) {
index d50887e3df6de3b41767ccbb3fb04a67c9d459af..8c48bb2a94ea063aa9dd7c4dc662aa772f34930c 100644 (file)
@@ -254,7 +254,7 @@ acct:
        }
 }
 
-static int ipvlan_rcv_frame(struct ipvl_addr *addr, struct sk_buff *skb,
+static int ipvlan_rcv_frame(struct ipvl_addr *addr, struct sk_buff **pskb,
                            bool local)
 {
        struct ipvl_dev *ipvlan = addr->master;
@@ -262,6 +262,7 @@ static int ipvlan_rcv_frame(struct ipvl_addr *addr, struct sk_buff *skb,
        unsigned int len;
        rx_handler_result_t ret = RX_HANDLER_CONSUMED;
        bool success = false;
+       struct sk_buff *skb = *pskb;
 
        len = skb->len + ETH_HLEN;
        if (unlikely(!(dev->flags & IFF_UP))) {
@@ -273,6 +274,7 @@ static int ipvlan_rcv_frame(struct ipvl_addr *addr, struct sk_buff *skb,
        if (!skb)
                goto out;
 
+       *pskb = skb;
        skb->dev = dev;
        skb->pkt_type = PACKET_HOST;
 
@@ -486,7 +488,7 @@ static int ipvlan_xmit_mode_l3(struct sk_buff *skb, struct net_device *dev)
 
        addr = ipvlan_addr_lookup(ipvlan->port, lyr3h, addr_type, true);
        if (addr)
-               return ipvlan_rcv_frame(addr, skb, true);
+               return ipvlan_rcv_frame(addr, &skb, true);
 
 out:
        skb->dev = ipvlan->phy_dev;
@@ -506,7 +508,7 @@ static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev)
                if (lyr3h) {
                        addr = ipvlan_addr_lookup(ipvlan->port, lyr3h, addr_type, true);
                        if (addr)
-                               return ipvlan_rcv_frame(addr, skb, true);
+                               return ipvlan_rcv_frame(addr, &skb, true);
                }
                skb = skb_share_check(skb, GFP_ATOMIC);
                if (!skb)
@@ -589,7 +591,7 @@ static rx_handler_result_t ipvlan_handle_mode_l3(struct sk_buff **pskb,
 
        addr = ipvlan_addr_lookup(port, lyr3h, addr_type, true);
        if (addr)
-               ret = ipvlan_rcv_frame(addr, skb, false);
+               ret = ipvlan_rcv_frame(addr, pskb, false);
 
 out:
        return ret;
@@ -626,7 +628,7 @@ static rx_handler_result_t ipvlan_handle_mode_l2(struct sk_buff **pskb,
 
                addr = ipvlan_addr_lookup(port, lyr3h, addr_type, true);
                if (addr)
-                       ret = ipvlan_rcv_frame(addr, skb, false);
+                       ret = ipvlan_rcv_frame(addr, pskb, false);
        }
 
        return ret;
@@ -651,5 +653,5 @@ rx_handler_result_t ipvlan_handle_frame(struct sk_buff **pskb)
        WARN_ONCE(true, "ipvlan_handle_frame() called for mode = [%hx]\n",
                          port->mode);
        kfree_skb(skb);
-       return NET_RX_DROP;
+       return RX_HANDLER_CONSUMED;
 }
index 86f6c6292c2726c6991f305bc8794a5af2c648af..06c8bfeaccd6c11cf15a8f05d87ce23c0f1e4405 100644 (file)
@@ -415,6 +415,7 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
                skb = ip_check_defrag(dev_net(skb->dev), skb, IP_DEFRAG_MACVLAN);
                if (!skb)
                        return RX_HANDLER_CONSUMED;
+               *pskb = skb;
                eth = eth_hdr(skb);
                macvlan_forward_source(skb, port, eth->h_source);
                src = macvlan_hash_lookup(port, eth->h_source);
@@ -456,6 +457,7 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
                goto out;
        }
 
+       *pskb = skb;
        skb->dev = dev;
        skb->pkt_type = PACKET_HOST;
 
index 97f3acd447985851254d55b546bd625b113641de..06ee6395117f9df71a07d22326bc6c15c1e87f2e 100644 (file)
@@ -244,15 +244,6 @@ static void free_param_target(struct netconsole_target *nt)
  *                             <target>/...
  */
 
-struct netconsole_target_attr {
-       struct configfs_attribute       attr;
-       ssize_t                         (*show)(struct netconsole_target *nt,
-                                               char *buf);
-       ssize_t                         (*store)(struct netconsole_target *nt,
-                                                const char *buf,
-                                                size_t count);
-};
-
 static struct netconsole_target *to_target(struct config_item *item)
 {
        return item ?
@@ -264,58 +255,62 @@ static struct netconsole_target *to_target(struct config_item *item)
  * Attribute operations for netconsole_target.
  */
 
-static ssize_t show_enabled(struct netconsole_target *nt, char *buf)
+static ssize_t enabled_show(struct config_item *item, char *buf)
 {
-       return snprintf(buf, PAGE_SIZE, "%d\n", nt->enabled);
+       return snprintf(buf, PAGE_SIZE, "%d\n", to_target(item)->enabled);
 }
 
-static ssize_t show_extended(struct netconsole_target *nt, char *buf)
+static ssize_t extended_show(struct config_item *item, char *buf)
 {
-       return snprintf(buf, PAGE_SIZE, "%d\n", nt->extended);
+       return snprintf(buf, PAGE_SIZE, "%d\n", to_target(item)->extended);
 }
 
-static ssize_t show_dev_name(struct netconsole_target *nt, char *buf)
+static ssize_t dev_name_show(struct config_item *item, char *buf)
 {
-       return snprintf(buf, PAGE_SIZE, "%s\n", nt->np.dev_name);
+       return snprintf(buf, PAGE_SIZE, "%s\n", to_target(item)->np.dev_name);
 }
 
-static ssize_t show_local_port(struct netconsole_target *nt, char *buf)
+static ssize_t local_port_show(struct config_item *item, char *buf)
 {
-       return snprintf(buf, PAGE_SIZE, "%d\n", nt->np.local_port);
+       return snprintf(buf, PAGE_SIZE, "%d\n", to_target(item)->np.local_port);
 }
 
-static ssize_t show_remote_port(struct netconsole_target *nt, char *buf)
+static ssize_t remote_port_show(struct config_item *item, char *buf)
 {
-       return snprintf(buf, PAGE_SIZE, "%d\n", nt->np.remote_port);
+       return snprintf(buf, PAGE_SIZE, "%d\n", to_target(item)->np.remote_port);
 }
 
-static ssize_t show_local_ip(struct netconsole_target *nt, char *buf)
+static ssize_t local_ip_show(struct config_item *item, char *buf)
 {
+       struct netconsole_target *nt = to_target(item);
+
        if (nt->np.ipv6)
                return snprintf(buf, PAGE_SIZE, "%pI6c\n", &nt->np.local_ip.in6);
        else
                return snprintf(buf, PAGE_SIZE, "%pI4\n", &nt->np.local_ip);
 }
 
-static ssize_t show_remote_ip(struct netconsole_target *nt, char *buf)
+static ssize_t remote_ip_show(struct config_item *item, char *buf)
 {
+       struct netconsole_target *nt = to_target(item);
+
        if (nt->np.ipv6)
                return snprintf(buf, PAGE_SIZE, "%pI6c\n", &nt->np.remote_ip.in6);
        else
                return snprintf(buf, PAGE_SIZE, "%pI4\n", &nt->np.remote_ip);
 }
 
-static ssize_t show_local_mac(struct netconsole_target *nt, char *buf)
+static ssize_t local_mac_show(struct config_item *item, char *buf)
 {
-       struct net_device *dev = nt->np.dev;
+       struct net_device *dev = to_target(item)->np.dev;
        static const u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 
        return snprintf(buf, PAGE_SIZE, "%pM\n", dev ? dev->dev_addr : bcast);
 }
 
-static ssize_t show_remote_mac(struct netconsole_target *nt, char *buf)
+static ssize_t remote_mac_show(struct config_item *item, char *buf)
 {
-       return snprintf(buf, PAGE_SIZE, "%pM\n", nt->np.remote_mac);
+       return snprintf(buf, PAGE_SIZE, "%pM\n", to_target(item)->np.remote_mac);
 }
 
 /*
@@ -325,23 +320,26 @@ static ssize_t show_remote_mac(struct netconsole_target *nt, char *buf)
  * would enable him to dynamically add new netpoll targets for new
  * network interfaces as and when they come up).
  */
-static ssize_t store_enabled(struct netconsole_target *nt,
-                            const char *buf,
-                            size_t count)
+static ssize_t enabled_store(struct config_item *item,
+               const char *buf, size_t count)
 {
+       struct netconsole_target *nt = to_target(item);
        unsigned long flags;
        int enabled;
        int err;
 
+       mutex_lock(&dynamic_netconsole_mutex);
        err = kstrtoint(buf, 10, &enabled);
        if (err < 0)
-               return err;
+               goto out_unlock;
+
+       err = -EINVAL;
        if (enabled < 0 || enabled > 1)
-               return -EINVAL;
+               goto out_unlock;
        if ((bool)enabled == nt->enabled) {
                pr_info("network logging has already %s\n",
                        nt->enabled ? "started" : "stopped");
-               return -EINVAL;
+               goto out_unlock;
        }
 
        if (enabled) {  /* true */
@@ -358,7 +356,7 @@ static ssize_t store_enabled(struct netconsole_target *nt,
 
                err = netpoll_setup(&nt->np);
                if (err)
-                       return err;
+                       goto out_unlock;
 
                pr_info("netconsole: network logging started\n");
        } else {        /* false */
@@ -374,42 +372,56 @@ static ssize_t store_enabled(struct netconsole_target *nt,
 
        nt->enabled = enabled;
 
+       mutex_unlock(&dynamic_netconsole_mutex);
        return strnlen(buf, count);
+out_unlock:
+       mutex_unlock(&dynamic_netconsole_mutex);
+       return err;
 }
 
-static ssize_t store_extended(struct netconsole_target *nt,
-                             const char *buf,
-                             size_t count)
+static ssize_t extended_store(struct config_item *item, const char *buf,
+               size_t count)
 {
+       struct netconsole_target *nt = to_target(item);
        int extended;
        int err;
 
+       mutex_lock(&dynamic_netconsole_mutex);
        if (nt->enabled) {
                pr_err("target (%s) is enabled, disable to update parameters\n",
                       config_item_name(&nt->item));
-               return -EINVAL;
+               err = -EINVAL;
+               goto out_unlock;
        }
 
        err = kstrtoint(buf, 10, &extended);
        if (err < 0)
-               return err;
-       if (extended < 0 || extended > 1)
-               return -EINVAL;
+               goto out_unlock;
+       if (extended < 0 || extended > 1) {
+               err = -EINVAL;
+               goto out_unlock;
+       }
 
        nt->extended = extended;
 
+       mutex_unlock(&dynamic_netconsole_mutex);
        return strnlen(buf, count);
+out_unlock:
+       mutex_unlock(&dynamic_netconsole_mutex);
+       return err;
 }
 
-static ssize_t store_dev_name(struct netconsole_target *nt,
-                             const char *buf,
-                             size_t count)
+static ssize_t dev_name_store(struct config_item *item, const char *buf,
+               size_t count)
 {
+       struct netconsole_target *nt = to_target(item);
        size_t len;
 
+       mutex_lock(&dynamic_netconsole_mutex);
        if (nt->enabled) {
                pr_err("target (%s) is enabled, disable to update parameters\n",
                       config_item_name(&nt->item));
+               mutex_unlock(&dynamic_netconsole_mutex);
                return -EINVAL;
        }
 
@@ -420,53 +432,66 @@ static ssize_t store_dev_name(struct netconsole_target *nt,
        if (nt->np.dev_name[len - 1] == '\n')
                nt->np.dev_name[len - 1] = '\0';
 
+       mutex_unlock(&dynamic_netconsole_mutex);
        return strnlen(buf, count);
 }
 
-static ssize_t store_local_port(struct netconsole_target *nt,
-                               const char *buf,
-                               size_t count)
+static ssize_t local_port_store(struct config_item *item, const char *buf,
+               size_t count)
 {
-       int rv;
+       struct netconsole_target *nt = to_target(item);
+       int rv = -EINVAL;
 
+       mutex_lock(&dynamic_netconsole_mutex);
        if (nt->enabled) {
                pr_err("target (%s) is enabled, disable to update parameters\n",
                       config_item_name(&nt->item));
-               return -EINVAL;
+               goto out_unlock;
        }
 
        rv = kstrtou16(buf, 10, &nt->np.local_port);
        if (rv < 0)
-               return rv;
+               goto out_unlock;
+       mutex_unlock(&dynamic_netconsole_mutex);
        return strnlen(buf, count);
+out_unlock:
+       mutex_unlock(&dynamic_netconsole_mutex);
+       return rv;
 }
 
-static ssize_t store_remote_port(struct netconsole_target *nt,
-                                const char *buf,
-                                size_t count)
+static ssize_t remote_port_store(struct config_item *item,
+               const char *buf, size_t count)
 {
-       int rv;
+       struct netconsole_target *nt = to_target(item);
+       int rv = -EINVAL;
 
+       mutex_lock(&dynamic_netconsole_mutex);
        if (nt->enabled) {
                pr_err("target (%s) is enabled, disable to update parameters\n",
                       config_item_name(&nt->item));
-               return -EINVAL;
+               goto out_unlock;
        }
 
        rv = kstrtou16(buf, 10, &nt->np.remote_port);
        if (rv < 0)
-               return rv;
+               goto out_unlock;
+       mutex_unlock(&dynamic_netconsole_mutex);
        return strnlen(buf, count);
+out_unlock:
+       mutex_unlock(&dynamic_netconsole_mutex);
+       return rv;
 }
 
-static ssize_t store_local_ip(struct netconsole_target *nt,
-                             const char *buf,
-                             size_t count)
+static ssize_t local_ip_store(struct config_item *item, const char *buf,
+               size_t count)
 {
+       struct netconsole_target *nt = to_target(item);
+
+       mutex_lock(&dynamic_netconsole_mutex);
        if (nt->enabled) {
                pr_err("target (%s) is enabled, disable to update parameters\n",
                       config_item_name(&nt->item));
-               return -EINVAL;
+               goto out_unlock;
        }
 
        if (strnchr(buf, count, ':')) {
@@ -474,29 +499,35 @@ static ssize_t store_local_ip(struct netconsole_target *nt,
                if (in6_pton(buf, count, nt->np.local_ip.in6.s6_addr, -1, &end) > 0) {
                        if (*end && *end != '\n') {
                                pr_err("invalid IPv6 address at: <%c>\n", *end);
-                               return -EINVAL;
+                               goto out_unlock;
                        }
                        nt->np.ipv6 = true;
                } else
-                       return -EINVAL;
+                       goto out_unlock;
        } else {
                if (!nt->np.ipv6) {
                        nt->np.local_ip.ip = in_aton(buf);
                } else
-                       return -EINVAL;
+                       goto out_unlock;
        }
 
+       mutex_unlock(&dynamic_netconsole_mutex);
        return strnlen(buf, count);
+out_unlock:
+       mutex_unlock(&dynamic_netconsole_mutex);
+       return -EINVAL;
 }
 
-static ssize_t store_remote_ip(struct netconsole_target *nt,
-                              const char *buf,
-                              size_t count)
+static ssize_t remote_ip_store(struct config_item *item, const char *buf,
+              size_t count)
 {
+       struct netconsole_target *nt = to_target(item);
+
+       mutex_lock(&dynamic_netconsole_mutex);
        if (nt->enabled) {
                pr_err("target (%s) is enabled, disable to update parameters\n",
                       config_item_name(&nt->item));
-               return -EINVAL;
+               goto out_unlock;
        }
 
        if (strnchr(buf, count, ':')) {
@@ -504,74 +535,71 @@ static ssize_t store_remote_ip(struct netconsole_target *nt,
                if (in6_pton(buf, count, nt->np.remote_ip.in6.s6_addr, -1, &end) > 0) {
                        if (*end && *end != '\n') {
                                pr_err("invalid IPv6 address at: <%c>\n", *end);
-                               return -EINVAL;
+                               goto out_unlock;
                        }
                        nt->np.ipv6 = true;
                } else
-                       return -EINVAL;
+                       goto out_unlock;
        } else {
                if (!nt->np.ipv6) {
                        nt->np.remote_ip.ip = in_aton(buf);
                } else
-                       return -EINVAL;
+                       goto out_unlock;
        }
 
+       mutex_unlock(&dynamic_netconsole_mutex);
        return strnlen(buf, count);
+out_unlock:
+       mutex_unlock(&dynamic_netconsole_mutex);
+       return -EINVAL;
 }
 
-static ssize_t store_remote_mac(struct netconsole_target *nt,
-                               const char *buf,
-                               size_t count)
+static ssize_t remote_mac_store(struct config_item *item, const char *buf,
+               size_t count)
 {
+       struct netconsole_target *nt = to_target(item);
        u8 remote_mac[ETH_ALEN];
 
+       mutex_lock(&dynamic_netconsole_mutex);
        if (nt->enabled) {
                pr_err("target (%s) is enabled, disable to update parameters\n",
                       config_item_name(&nt->item));
-               return -EINVAL;
+               goto out_unlock;
        }
 
        if (!mac_pton(buf, remote_mac))
-               return -EINVAL;
+               goto out_unlock;
        if (buf[3 * ETH_ALEN - 1] && buf[3 * ETH_ALEN - 1] != '\n')
-               return -EINVAL;
+               goto out_unlock;
        memcpy(nt->np.remote_mac, remote_mac, ETH_ALEN);
 
+       mutex_unlock(&dynamic_netconsole_mutex);
        return strnlen(buf, count);
+out_unlock:
+       mutex_unlock(&dynamic_netconsole_mutex);
+       return -EINVAL;
 }
 
-/*
- * Attribute definitions for netconsole_target.
- */
-
-#define NETCONSOLE_TARGET_ATTR_RO(_name)                               \
-static struct netconsole_target_attr netconsole_target_##_name =       \
-       __CONFIGFS_ATTR(_name, S_IRUGO, show_##_name, NULL)
-
-#define NETCONSOLE_TARGET_ATTR_RW(_name)                               \
-static struct netconsole_target_attr netconsole_target_##_name =       \
-       __CONFIGFS_ATTR(_name, S_IRUGO | S_IWUSR, show_##_name, store_##_name)
-
-NETCONSOLE_TARGET_ATTR_RW(enabled);
-NETCONSOLE_TARGET_ATTR_RW(extended);
-NETCONSOLE_TARGET_ATTR_RW(dev_name);
-NETCONSOLE_TARGET_ATTR_RW(local_port);
-NETCONSOLE_TARGET_ATTR_RW(remote_port);
-NETCONSOLE_TARGET_ATTR_RW(local_ip);
-NETCONSOLE_TARGET_ATTR_RW(remote_ip);
-NETCONSOLE_TARGET_ATTR_RO(local_mac);
-NETCONSOLE_TARGET_ATTR_RW(remote_mac);
+CONFIGFS_ATTR(, enabled);
+CONFIGFS_ATTR(, extended);
+CONFIGFS_ATTR(, dev_name);
+CONFIGFS_ATTR(, local_port);
+CONFIGFS_ATTR(, remote_port);
+CONFIGFS_ATTR(, local_ip);
+CONFIGFS_ATTR(, remote_ip);
+CONFIGFS_ATTR_RO(, local_mac);
+CONFIGFS_ATTR(, remote_mac);
 
 static struct configfs_attribute *netconsole_target_attrs[] = {
-       &netconsole_target_enabled.attr,
-       &netconsole_target_extended.attr,
-       &netconsole_target_dev_name.attr,
-       &netconsole_target_local_port.attr,
-       &netconsole_target_remote_port.attr,
-       &netconsole_target_local_ip.attr,
-       &netconsole_target_remote_ip.attr,
-       &netconsole_target_local_mac.attr,
-       &netconsole_target_remote_mac.attr,
+       &attr_enabled,
+       &attr_extended,
+       &attr_dev_name,
+       &attr_local_port,
+       &attr_remote_port,
+       &attr_local_ip,
+       &attr_remote_ip,
+       &attr_local_mac,
+       &attr_remote_mac,
        NULL,
 };
 
@@ -584,43 +612,8 @@ static void netconsole_target_release(struct config_item *item)
        kfree(to_target(item));
 }
 
-static ssize_t netconsole_target_attr_show(struct config_item *item,
-                                          struct configfs_attribute *attr,
-                                          char *buf)
-{
-       ssize_t ret = -EINVAL;
-       struct netconsole_target *nt = to_target(item);
-       struct netconsole_target_attr *na =
-               container_of(attr, struct netconsole_target_attr, attr);
-
-       if (na->show)
-               ret = na->show(nt, buf);
-
-       return ret;
-}
-
-static ssize_t netconsole_target_attr_store(struct config_item *item,
-                                           struct configfs_attribute *attr,
-                                           const char *buf,
-                                           size_t count)
-{
-       ssize_t ret = -EINVAL;
-       struct netconsole_target *nt = to_target(item);
-       struct netconsole_target_attr *na =
-               container_of(attr, struct netconsole_target_attr, attr);
-
-       mutex_lock(&dynamic_netconsole_mutex);
-       if (na->store)
-               ret = na->store(nt, buf, count);
-       mutex_unlock(&dynamic_netconsole_mutex);
-
-       return ret;
-}
-
 static struct configfs_item_operations netconsole_target_item_ops = {
        .release                = netconsole_target_release,
-       .show_attribute         = netconsole_target_attr_show,
-       .store_attribute        = netconsole_target_attr_store,
 };
 
 static struct config_item_type netconsole_target_type = {
index 5de8d5827536b1c196b4dabe95f3815964dd0296..0240552b50f3228b16fb310afa52a0bdbe8fd4ef 100644 (file)
@@ -1153,6 +1153,21 @@ static struct phy_driver marvell_drivers[] = {
                .suspend = &genphy_suspend,
                .driver = { .owner = THIS_MODULE },
        },
+       {
+               .phy_id = MARVELL_PHY_ID_88E1540,
+               .phy_id_mask = MARVELL_PHY_ID_MASK,
+               .name = "Marvell 88E1540",
+               .features = PHY_GBIT_FEATURES,
+               .flags = PHY_HAS_INTERRUPT,
+               .config_aneg = &m88e1510_config_aneg,
+               .read_status = &marvell_read_status,
+               .ack_interrupt = &marvell_ack_interrupt,
+               .config_intr = &marvell_config_intr,
+               .did_interrupt = &m88e1121_did_interrupt,
+               .resume = &genphy_resume,
+               .suspend = &genphy_suspend,
+               .driver = { .owner = THIS_MODULE },
+       },
        {
                .phy_id = MARVELL_PHY_ID_88E3016,
                .phy_id_mask = MARVELL_PHY_ID_MASK,
@@ -1186,6 +1201,7 @@ static struct mdio_device_id __maybe_unused marvell_tbl[] = {
        { MARVELL_PHY_ID_88E1318S, MARVELL_PHY_ID_MASK },
        { MARVELL_PHY_ID_88E1116R, MARVELL_PHY_ID_MASK },
        { MARVELL_PHY_ID_88E1510, MARVELL_PHY_ID_MASK },
+       { MARVELL_PHY_ID_88E1540, MARVELL_PHY_ID_MASK },
        { MARVELL_PHY_ID_88E3016, MARVELL_PHY_ID_MASK },
        { }
 };
index adb48abafc872a71e801b5505d676f9db02c7466..48ce6ef400fe7fdda6ae78a9a22943b2307c1c8b 100644 (file)
@@ -863,6 +863,9 @@ void phy_state_machine(struct work_struct *work)
                        needs_aneg = true;
                break;
        case PHY_NOLINK:
+               if (phy_interrupt_is_valid(phydev))
+                       break;
+
                err = phy_read_status(phydev);
                if (err)
                        break;
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 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 8282db2ef99ea02077ef5609b85acfe0a8aae823..b0045a505dc88c9ef56dcc1094a198bd011d24a7 100644 (file)
@@ -3,6 +3,7 @@
  * Copyright (c) 2015, Intel Corporation.
  */
 #include <linux/platform_device.h>
+#include <linux/memory_hotplug.h>
 #include <linux/libnvdimm.h>
 #include <linux/module.h>
 
@@ -25,6 +26,18 @@ static int e820_pmem_remove(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_MEMORY_HOTPLUG
+static int e820_range_to_nid(resource_size_t addr)
+{
+       return memory_add_physaddr_to_nid(addr);
+}
+#else
+static int e820_range_to_nid(resource_size_t addr)
+{
+       return NUMA_NO_NODE;
+}
+#endif
+
 static int e820_pmem_probe(struct platform_device *pdev)
 {
        static struct nvdimm_bus_descriptor nd_desc;
@@ -48,7 +61,7 @@ static int e820_pmem_probe(struct platform_device *pdev)
                memset(&ndr_desc, 0, sizeof(ndr_desc));
                ndr_desc.res = p;
                ndr_desc.attr_groups = e820_pmem_region_attribute_groups;
-               ndr_desc.numa_node = NUMA_NO_NODE;
+               ndr_desc.numa_node = e820_range_to_nid(p->start);
                set_bit(ND_REGION_PAGEMAP, &ndr_desc.flags);
                if (!nvdimm_pmem_region_create(nvdimm_bus, &ndr_desc))
                        goto err;
index 012e0649f1ac48374de47a690a2d0ac1d1865cac..8ee79893d2f5f6f5165558baa22f236738b99c45 100644 (file)
@@ -105,22 +105,11 @@ static long pmem_direct_access(struct block_device *bdev, sector_t sector,
 {
        struct pmem_device *pmem = bdev->bd_disk->private_data;
        resource_size_t offset = sector * 512 + pmem->data_offset;
-       resource_size_t size;
-
-       if (pmem->data_offset) {
-               /*
-                * Limit the direct_access() size to what is covered by
-                * the memmap
-                */
-               size = (pmem->size - offset) & ~ND_PFN_MASK;
-       } else
-               size = pmem->size - offset;
-
-       /* FIXME convert DAX to comprehend that this mapping has a lifetime */
+
        *kaddr = pmem->virt_addr + offset;
        *pfn = (pmem->phys_addr + offset) >> PAGE_SHIFT;
 
-       return size;
+       return pmem->size - offset;
 }
 
 static const struct block_device_operations pmem_fops = {
index 3dfc28875cc31338be0c33ff040185d03302a3b7..8187df20469535023ae9966aecfb1542260b4270 100644 (file)
@@ -1725,7 +1725,7 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev)
 {
        int result;
        u32 aqa;
-       u64 cap = readq(&dev->bar->cap);
+       u64 cap = lo_hi_readq(&dev->bar->cap);
        struct nvme_queue *nvmeq;
        unsigned page_shift = PAGE_SHIFT;
        unsigned dev_page_min = NVME_CAP_MPSMIN(cap) + 12;
@@ -1774,8 +1774,8 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev)
        dev->ctrl_config |= NVME_CC_IOSQES | NVME_CC_IOCQES;
 
        writel(aqa, &dev->bar->aqa);
-       writeq(nvmeq->sq_dma_addr, &dev->bar->asq);
-       writeq(nvmeq->cq_dma_addr, &dev->bar->acq);
+       lo_hi_writeq(nvmeq->sq_dma_addr, &dev->bar->asq);
+       lo_hi_writeq(nvmeq->cq_dma_addr, &dev->bar->acq);
 
        result = nvme_enable_ctrl(dev, cap);
        if (result)
@@ -2606,7 +2606,7 @@ static int nvme_dev_add(struct nvme_dev *dev)
        struct pci_dev *pdev = to_pci_dev(dev->dev);
        int res;
        struct nvme_id_ctrl *ctrl;
-       int shift = NVME_CAP_MPSMIN(readq(&dev->bar->cap)) + 12;
+       int shift = NVME_CAP_MPSMIN(lo_hi_readq(&dev->bar->cap)) + 12;
 
        res = nvme_identify_ctrl(dev, &ctrl);
        if (res) {
@@ -2622,6 +2622,8 @@ static int nvme_dev_add(struct nvme_dev *dev)
        memcpy(dev->firmware_rev, ctrl->fr, sizeof(ctrl->fr));
        if (ctrl->mdts)
                dev->max_hw_sectors = 1 << (ctrl->mdts + shift - 9);
+       else
+               dev->max_hw_sectors = UINT_MAX;
        if ((pdev->vendor == PCI_VENDOR_ID_INTEL) &&
                        (pdev->device == 0x0953) && ctrl->vs[3]) {
                unsigned int max_hw_sectors;
@@ -2695,7 +2697,7 @@ static int nvme_dev_map(struct nvme_dev *dev)
                        goto unmap;
        }
 
-       cap = readq(&dev->bar->cap);
+       cap = lo_hi_readq(&dev->bar->cap);
        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;
@@ -2758,7 +2760,7 @@ static void nvme_wait_dq(struct nvme_delq_ctx *dq, struct nvme_dev *dev)
                         * queues than admin tags.
                         */
                        set_current_state(TASK_RUNNING);
-                       nvme_disable_ctrl(dev, readq(&dev->bar->cap));
+                       nvme_disable_ctrl(dev, lo_hi_readq(&dev->bar->cap));
                        nvme_clear_queue(dev->queues[0]);
                        flush_kthread_worker(dq->worker);
                        nvme_disable_queue(dev, 0);
@@ -3401,6 +3403,7 @@ static const struct pci_error_handlers nvme_err_handler = {
 
 static const struct pci_device_id nvme_id_table[] = {
        { PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_EXPRESS, 0xffffff) },
+       { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2001) },
        { 0, }
 };
 MODULE_DEVICE_TABLE(pci, nvme_id_table);
index ff27177f49edbdd3105b319c7deee29ed48da869..b1449f71601cb257f1057b77c217a943da92cab8 100644 (file)
@@ -143,26 +143,6 @@ void of_pci_check_probe_only(void)
 }
 EXPORT_SYMBOL_GPL(of_pci_check_probe_only);
 
-/**
- * of_pci_dma_configure - Setup DMA configuration
- * @dev: ptr to pci_dev struct of the PCI device
- *
- * Function to update PCI devices's DMA configuration using the same
- * info from the OF node of host bridge's parent (if any).
- */
-void of_pci_dma_configure(struct pci_dev *pci_dev)
-{
-       struct device *dev = &pci_dev->dev;
-       struct device *bridge = pci_get_host_bridge_device(pci_dev);
-
-       if (!bridge->parent)
-               return;
-
-       of_dma_configure(dev, bridge->parent->of_node);
-       pci_put_host_bridge_device(bridge);
-}
-EXPORT_SYMBOL_GPL(of_pci_dma_configure);
-
 #if defined(CONFIG_OF_ADDRESS)
 /**
  * of_pci_get_host_bridge_resources - Parse PCI host bridge resources from DT
index 62f467b8ccae940a931a2a08ce530a9a14f46a1f..be77e75c587db95c55a51e556f228f97810e051c 100644 (file)
@@ -124,6 +124,10 @@ static int __init __reserved_mem_alloc_size(unsigned long node,
                align = dt_mem_next_cell(dt_root_addr_cells, &prop);
        }
 
+       /* Need adjust the alignment to satisfy the CMA requirement */
+       if (IS_ENABLED(CONFIG_CMA) && of_flat_dt_is_compatible(node, "shared-dma-pool"))
+               align = max(align, (phys_addr_t)PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order));
+
        prop = of_get_flat_dt_prop(node, "alloc-ranges", &len);
        if (prop) {
 
@@ -226,10 +230,9 @@ static void __init __rmem_check_for_overlap(void)
 
                        this_end = this->base + this->size;
                        next_end = next->base + next->size;
-                       WARN(1,
-                            "Reserved memory: OVERLAP DETECTED!\n%s (%pa--%pa) overlaps with %s (%pa--%pa)\n",
-                            this->name, &this->base, &this_end,
-                            next->name, &next->base, &next_end);
+                       pr_err("Reserved memory: OVERLAP DETECTED!\n%s (%pa--%pa) overlaps with %s (%pa--%pa)\n",
+                              this->name, &this->base, &this_end,
+                              next->name, &next->base, &next_end);
                }
        }
 }
index f53b8e85f137902f6e8b0667ae9f0539c06537a1..e735c728e3b34aa441d1bc140e5473554af8385d 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/of_device.h>
 #include <linux/of_pci.h>
 #include <linux/pci_hotplug.h>
 #include <linux/slab.h>
@@ -13,6 +14,7 @@
 #include <linux/cpumask.h>
 #include <linux/pci-aspm.h>
 #include <linux/aer.h>
+#include <linux/acpi.h>
 #include <asm-generic/pci-bridge.h>
 #include "pci.h"
 
@@ -1672,6 +1674,34 @@ static void pci_set_msi_domain(struct pci_dev *dev)
        dev_set_msi_domain(&dev->dev, d);
 }
 
+/**
+ * pci_dma_configure - Setup DMA configuration
+ * @dev: ptr to pci_dev struct of the PCI device
+ *
+ * Function to update PCI devices's DMA configuration using the same
+ * info from the OF node or ACPI node of host bridge's parent (if any).
+ */
+static void pci_dma_configure(struct pci_dev *dev)
+{
+       struct device *bridge = pci_get_host_bridge_device(dev);
+
+       if (IS_ENABLED(CONFIG_OF) && dev->dev.of_node) {
+               if (bridge->parent)
+                       of_dma_configure(&dev->dev, bridge->parent->of_node);
+       } else if (has_acpi_companion(bridge)) {
+               struct acpi_device *adev = to_acpi_device_node(bridge->fwnode);
+               enum dev_dma_attr attr = acpi_get_dma_attr(adev);
+
+               if (attr == DEV_DMA_NOT_SUPPORTED)
+                       dev_warn(&dev->dev, "DMA not supported.\n");
+               else
+                       arch_setup_dma_ops(&dev->dev, 0, 0, NULL,
+                                          attr == DEV_DMA_COHERENT);
+       }
+
+       pci_put_host_bridge_device(bridge);
+}
+
 void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
 {
        int ret;
@@ -1685,7 +1715,7 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
        dev->dev.dma_mask = &dev->dma_mask;
        dev->dev.dma_parms = &dev->dma_parms;
        dev->dev.coherent_dma_mask = 0xffffffffull;
-       of_pci_dma_configure(dev);
+       pci_dma_configure(dev);
 
        pci_set_dma_max_seg_size(dev, 65536);
        pci_set_dma_seg_boundary(dev, 0xffffffff);
index 3271cd1abe7c0e6c5d2e813171aa5df494f9d977..d03df4a60d057854884eddaeb9f8b2b343bee2d5 100644 (file)
@@ -4,6 +4,7 @@
 
 menuconfig CHROME_PLATFORMS
        bool "Platform support for Chrome hardware"
+       depends on X86 || ARM || ARM64 || COMPILE_TEST
        ---help---
          Say Y here to get to see options for platform support for
          various Chromebooks and Chromeboxes. This option alone does
@@ -39,7 +40,7 @@ config CHROMEOS_PSTORE
 
 config CROS_EC_CHARDEV
         tristate "Chrome OS Embedded Controller userspace device interface"
-        depends on CROS_EC_PROTO
+        depends on MFD_CROS_EC
         ---help---
           This driver adds support to talk with the ChromeOS EC from userspace.
 
@@ -48,7 +49,7 @@ config CROS_EC_CHARDEV
 
 config CROS_EC_LPC
         tristate "ChromeOS Embedded Controller (LPC)"
-        depends on MFD_CROS_EC && CROS_EC_PROTO && (X86 || COMPILE_TEST)
+        depends on MFD_CROS_EC && (X86 || COMPILE_TEST)
         help
           If you say Y here, you get support for talking to the ChromeOS EC
           over an LPC bus. This uses a simple byte-level protocol with a
index 4a11b010f5d8859e37daad2c1c0d1b381cc5d3a4..bc498bda8211060b145406dea87b36f9e2b931ae 100644 (file)
@@ -1,7 +1,8 @@
 
 obj-$(CONFIG_CHROMEOS_LAPTOP)  += chromeos_laptop.o
 obj-$(CONFIG_CHROMEOS_PSTORE)  += chromeos_pstore.o
-cros_ec_devs-objs               := cros_ec_dev.o cros_ec_sysfs.o cros_ec_lightbar.o
+cros_ec_devs-objs              := cros_ec_dev.o cros_ec_sysfs.o \
+                                  cros_ec_lightbar.o cros_ec_vbc.o
 obj-$(CONFIG_CROS_EC_CHARDEV)   += cros_ec_devs.o
 obj-$(CONFIG_CROS_EC_LPC)       += cros_ec_lpc.o
 obj-$(CONFIG_CROS_EC_PROTO)    += cros_ec_proto.o
index 02072749fff3718ddc119aab5b24b4ecafbe53ff..2b441e9ae593518dd7ac0ade3168e8928436f042 100644 (file)
@@ -47,8 +47,8 @@ static const char *i2c_adapter_names[] = {
        "SMBus I801 adapter",
        "i915 gmbus vga",
        "i915 gmbus panel",
-       "i2c-designware-pci",
-       "i2c-designware-pci",
+       "Synopsys DesignWare I2C adapter",
+       "Synopsys DesignWare I2C adapter",
 };
 
 /* Keep this enum consistent with i2c_adapter_names */
index e8fcdc237029a97908194a52b668ad0c4aa6920c..d45cd254ed1c8f295292074100934130235fca64 100644 (file)
@@ -32,6 +32,7 @@ static int ec_major;
 static const struct attribute_group *cros_ec_groups[] = {
        &cros_ec_attr_group,
        &cros_ec_lightbar_attr_group,
+       &cros_ec_vbc_attr_group,
        NULL,
 };
 
@@ -287,6 +288,12 @@ static int ec_device_remove(struct platform_device *pdev)
        return 0;
 }
 
+static const struct platform_device_id cros_ec_id[] = {
+       { "cros-ec-ctl", 0 },
+       { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(platform, cros_ec_id);
+
 static struct platform_driver cros_ec_dev_driver = {
        .driver = {
                .name = "cros-ec-ctl",
index 144e09df9b846551edb9b2c9df6c7be8f717c697..ff7640575c751dfbc401486eee0f982c3527b1ff 100644 (file)
@@ -252,7 +252,7 @@ static ssize_t led_rgb_store(struct device *dev, struct device_attribute *attr,
 
                ret = sscanf(buf, "%i", &val[i++]);
                if (ret == 0)
-                       return -EINVAL;
+                       goto exit;
 
                if (i == 4) {
                        param = (struct ec_params_lightbar *)msg->data;
@@ -268,17 +268,15 @@ static ssize_t led_rgb_store(struct device *dev, struct device_attribute *attr,
                        if ((j++ % 4) == 0) {
                                ret = lb_throttle();
                                if (ret)
-                                       return ret;
+                                       goto exit;
                        }
 
                        ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
                        if (ret < 0)
                                goto exit;
 
-                       if (msg->result != EC_RES_SUCCESS) {
-                               ret = -EINVAL;
+                       if (msg->result != EC_RES_SUCCESS)
                                goto exit;
-                       }
 
                        i = 0;
                        ok = 1;
@@ -352,10 +350,6 @@ static ssize_t sequence_store(struct device *dev, struct device_attribute *attr,
        struct cros_ec_dev *ec = container_of(dev,
                                              struct cros_ec_dev, class_dev);
 
-       msg = alloc_lightbar_cmd_msg(ec);
-       if (!msg)
-               return -ENOMEM;
-
        for (len = 0; len < count; len++)
                if (!isalnum(buf[len]))
                        break;
@@ -370,21 +364,30 @@ static ssize_t sequence_store(struct device *dev, struct device_attribute *attr,
                        return ret;
        }
 
+       msg = alloc_lightbar_cmd_msg(ec);
+       if (!msg)
+               return -ENOMEM;
+
        param = (struct ec_params_lightbar *)msg->data;
        param->cmd = LIGHTBAR_CMD_SEQ;
        param->seq.num = num;
        ret = lb_throttle();
        if (ret)
-               return ret;
+               goto exit;
 
        ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
        if (ret < 0)
-               return ret;
+               goto exit;
 
-       if (msg->result != EC_RES_SUCCESS)
-               return -EINVAL;
+       if (msg->result != EC_RES_SUCCESS) {
+               ret = -EINVAL;
+               goto exit;
+       }
 
-       return count;
+       ret = count;
+exit:
+       kfree(msg);
+       return ret;
 }
 
 /* Module initialization */
index bdd77ce45f0512494fa775dba51fc8655be1a8c4..f9a245465fd099f64037711523f7b0903b9b226d 100644 (file)
@@ -166,19 +166,9 @@ static int cros_ec_cmd_xfer_lpc(struct cros_ec_device *ec,
 
        /* Check result */
        msg->result = inb(EC_LPC_ADDR_HOST_DATA);
-
-       switch (msg->result) {
-       case EC_RES_SUCCESS:
-               break;
-       case EC_RES_IN_PROGRESS:
-               ret = -EAGAIN;
-               dev_dbg(ec->dev, "command 0x%02x in progress\n",
-                       msg->command);
+       ret = cros_ec_check_result(ec, msg);
+       if (ret)
                goto done;
-       default:
-               dev_dbg(ec->dev, "command 0x%02x returned %d\n",
-                       msg->command, msg->result);
-       }
 
        /* Read back args */
        args.flags = inb(EC_LPC_ADDR_HOST_ARGS);
@@ -329,6 +319,13 @@ static struct dmi_system_id cros_ec_lpc_dmi_table[] __initdata = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "Link"),
                },
        },
+       {
+               /* x86-samus, the Chromebook Pixel 2. */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Samus"),
+               },
+       },
        {
                /* x86-peppy, the Acer C720 Chromebook. */
                .matches = {
diff --git a/drivers/platform/chrome/cros_ec_vbc.c b/drivers/platform/chrome/cros_ec_vbc.c
new file mode 100644 (file)
index 0000000..564a0d0
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * cros_ec_vbc - Expose the vboot context nvram to userspace
+ *
+ * Copyright (C) 2015 Collabora Ltd.
+ *
+ * based on vendor driver,
+ *
+ * Copyright (C) 2012 The Chromium OS Authors
+ *
+ * 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/of.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/cros_ec.h>
+#include <linux/mfd/cros_ec_commands.h>
+#include <linux/slab.h>
+
+static ssize_t vboot_context_read(struct file *filp, struct kobject *kobj,
+                                 struct bin_attribute *att, char *buf,
+                                 loff_t pos, size_t count)
+{
+       struct device *dev = container_of(kobj, struct device, kobj);
+       struct cros_ec_dev *ec = container_of(dev, struct cros_ec_dev,
+                                             class_dev);
+       struct cros_ec_device *ecdev = ec->ec_dev;
+       struct ec_params_vbnvcontext *params;
+       struct cros_ec_command *msg;
+       int err;
+       const size_t para_sz = sizeof(params->op);
+       const size_t resp_sz = sizeof(struct ec_response_vbnvcontext);
+       const size_t payload = max(para_sz, resp_sz);
+
+       msg = kmalloc(sizeof(*msg) + payload, GFP_KERNEL);
+       if (!msg)
+               return -ENOMEM;
+
+       /* NB: we only kmalloc()ated enough space for the op field */
+       params = (struct ec_params_vbnvcontext *)msg->data;
+       params->op = EC_VBNV_CONTEXT_OP_READ;
+
+       msg->version = EC_VER_VBNV_CONTEXT;
+       msg->command = EC_CMD_VBNV_CONTEXT;
+       msg->outsize = para_sz;
+       msg->insize = resp_sz;
+
+       err = cros_ec_cmd_xfer(ecdev, msg);
+       if (err < 0) {
+               dev_err(dev, "Error sending read request: %d\n", err);
+               kfree(msg);
+               return err;
+       }
+
+       memcpy(buf, msg->data, resp_sz);
+
+       kfree(msg);
+       return resp_sz;
+}
+
+static ssize_t vboot_context_write(struct file *filp, struct kobject *kobj,
+                                  struct bin_attribute *attr, char *buf,
+                                  loff_t pos, size_t count)
+{
+       struct device *dev = container_of(kobj, struct device, kobj);
+       struct cros_ec_dev *ec = container_of(dev, struct cros_ec_dev,
+                                             class_dev);
+       struct cros_ec_device *ecdev = ec->ec_dev;
+       struct ec_params_vbnvcontext *params;
+       struct cros_ec_command *msg;
+       int err;
+       const size_t para_sz = sizeof(*params);
+       const size_t data_sz = sizeof(params->block);
+
+       /* Only write full values */
+       if (count != data_sz)
+               return -EINVAL;
+
+       msg = kmalloc(sizeof(*msg) + para_sz, GFP_KERNEL);
+       if (!msg)
+               return -ENOMEM;
+
+       params = (struct ec_params_vbnvcontext *)msg->data;
+       params->op = EC_VBNV_CONTEXT_OP_WRITE;
+       memcpy(params->block, buf, data_sz);
+
+       msg->version = EC_VER_VBNV_CONTEXT;
+       msg->command = EC_CMD_VBNV_CONTEXT;
+       msg->outsize = para_sz;
+       msg->insize = 0;
+
+       err = cros_ec_cmd_xfer(ecdev, msg);
+       if (err < 0) {
+               dev_err(dev, "Error sending write request: %d\n", err);
+               kfree(msg);
+               return err;
+       }
+
+       kfree(msg);
+       return data_sz;
+}
+
+static umode_t cros_ec_vbc_is_visible(struct kobject *kobj,
+                                     struct bin_attribute *a, int n)
+{
+       struct device *dev = container_of(kobj, struct device, kobj);
+       struct cros_ec_dev *ec = container_of(dev, struct cros_ec_dev,
+                                             class_dev);
+       struct device_node *np = ec->ec_dev->dev->of_node;
+
+       if (IS_ENABLED(CONFIG_OF) && np) {
+               if (of_property_read_bool(np, "google,has-vbc-nvram"))
+                       return a->attr.mode;
+       }
+
+       return 0;
+}
+
+static BIN_ATTR_RW(vboot_context, 16);
+
+static struct bin_attribute *cros_ec_vbc_bin_attrs[] = {
+       &bin_attr_vboot_context,
+       NULL
+};
+
+struct attribute_group cros_ec_vbc_attr_group = {
+       .name = "vbc",
+       .bin_attrs = cros_ec_vbc_bin_attrs,
+       .is_bin_visible = cros_ec_vbc_is_visible,
+};
index 02bbc70c332dd8fb2d241974e5e41f140aa8a8c3..1089eaa02b00b07369b6de923c5b2217d432d26c 100644 (file)
@@ -345,6 +345,7 @@ config IDEAPAD_LAPTOP
        depends on SERIO_I8042
        depends on BACKLIGHT_CLASS_DEVICE
        depends on ACPI_VIDEO || ACPI_VIDEO = n
+       depends on ACPI_WMI || ACPI_WMI = n
        select INPUT_SPARSEKMAP
        help
          This is a driver for Lenovo IdeaPad netbooks contains drivers for
index 1f7d80ff8cb428b1a9e43867b43105b21b9871b6..f96f7b865267925086f464addccd7f1ef2314ac0 100644 (file)
@@ -1320,7 +1320,7 @@ static ssize_t asus_hwmon_temp1(struct device *dev,
        if (err < 0)
                return err;
 
-       value = KELVIN_TO_CELSIUS((value & 0xFFFF)) * 1000;
+       value = DECI_KELVIN_TO_CELSIUS((value & 0xFFFF)) * 1000;
 
        return sprintf(buf, "%d\n", value);
 }
@@ -1682,7 +1682,7 @@ static ssize_t store_sys_wmi(struct asus_wmi *asus, int devid,
        int rv, err, value;
 
        value = asus_wmi_get_devstate_simple(asus, devid);
-       if (value == -ENODEV)   /* Check device presence */
+       if (value < 0)
                return value;
 
        rv = parse_arg(buf, count, &value);
index fce49f3c6ed688f676aea9be4647cc63d3c56416..a313dfc0245f550ac5322fec17d890662d52e790 100644 (file)
 #define CFG_WIFI_BIT   (18)
 #define CFG_CAMERA_BIT (19)
 
+#if IS_ENABLED(CONFIG_ACPI_WMI)
+static const char ideapad_wmi_fnesc_event[] = "26CAB2E5-5CF1-46AE-AAC3-4A12B6BA50E6";
+#endif
+
 enum {
        VPCCMD_R_VPC1 = 0x10,
        VPCCMD_R_BL_MAX,
@@ -567,6 +571,8 @@ static const struct key_entry ideapad_keymap[] = {
        { KE_KEY, 65, { KEY_PROG4 } },
        { KE_KEY, 66, { KEY_TOUCHPAD_OFF } },
        { KE_KEY, 67, { KEY_TOUCHPAD_ON } },
+       { KE_KEY, 128, { KEY_ESC } },
+
        { KE_END, 0 },
 };
 
@@ -825,6 +831,19 @@ static void ideapad_acpi_notify(acpi_handle handle, u32 event, void *data)
        }
 }
 
+#if IS_ENABLED(CONFIG_ACPI_WMI)
+static void ideapad_wmi_notify(u32 value, void *context)
+{
+       switch (value) {
+       case 128:
+               ideapad_input_report(context, value);
+               break;
+       default:
+               pr_info("Unknown WMI event %u\n", value);
+       }
+}
+#endif
+
 /*
  * Some ideapads don't have a hardware rfkill switch, reading VPCCMD_R_RF
  * always results in 0 on these models, causing ideapad_laptop to wrongly
@@ -853,24 +872,31 @@ static const struct dmi_system_id no_hw_rfkill_list[] = {
                },
        },
        {
-               .ident = "Lenovo Yoga 3 14",
+               .ident = "Lenovo Yoga 2 11 / 13 / Pro",
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-                       DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Yoga 3 14"),
+                       DMI_MATCH(DMI_BOARD_NAME, "Yoga2"),
                },
        },
        {
-               .ident = "Lenovo Yoga 2 11 / 13 / Pro",
+               .ident = "Lenovo Yoga 3 1170 / 1470",
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-                       DMI_MATCH(DMI_BOARD_NAME, "Yoga2"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Yoga 3"),
                },
        },
        {
                .ident = "Lenovo Yoga 3 Pro 1370",
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-                       DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo YOGA 3 Pro-1370"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo YOGA 3"),
+               },
+       },
+       {
+               .ident = "Lenovo Yoga 900",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo YOGA 900"),
                },
        },
        {}
@@ -935,8 +961,18 @@ static int ideapad_acpi_add(struct platform_device *pdev)
                ACPI_DEVICE_NOTIFY, ideapad_acpi_notify, priv);
        if (ret)
                goto notification_failed;
+#if IS_ENABLED(CONFIG_ACPI_WMI)
+       ret = wmi_install_notify_handler(ideapad_wmi_fnesc_event, ideapad_wmi_notify, priv);
+       if (ret != AE_OK && ret != AE_NOT_EXIST)
+               goto notification_failed_wmi;
+#endif
 
        return 0;
+#if IS_ENABLED(CONFIG_ACPI_WMI)
+notification_failed_wmi:
+       acpi_remove_notify_handler(priv->adev->handle,
+               ACPI_DEVICE_NOTIFY, ideapad_acpi_notify);
+#endif
 notification_failed:
        ideapad_backlight_exit(priv);
 backlight_failed:
@@ -955,6 +991,9 @@ static int ideapad_acpi_remove(struct platform_device *pdev)
        struct ideapad_private *priv = dev_get_drvdata(&pdev->dev);
        int i;
 
+#if IS_ENABLED(CONFIG_ACPI_WMI)
+       wmi_remove_notify_handler(ideapad_wmi_fnesc_event);
+#endif
        acpi_remove_notify_handler(priv->adev->handle,
                ACPI_DEVICE_NOTIFY, ideapad_acpi_notify);
        ideapad_backlight_exit(priv);
index e8b46d2c468c963b37f338534b40aad814ac8792..0a919d81662cdd9fe19506323d78d1c05867e604 100644 (file)
@@ -315,7 +315,7 @@ static ssize_t aux0_show(struct device *dev,
 
        result = sensor_get_auxtrip(attr->handle, 0, &value);
 
-       return result ? result : sprintf(buf, "%lu", KELVIN_TO_CELSIUS(value));
+       return result ? result : sprintf(buf, "%lu", DECI_KELVIN_TO_CELSIUS(value));
 }
 
 static ssize_t aux1_show(struct device *dev,
@@ -327,7 +327,7 @@ static ssize_t aux1_show(struct device *dev,
 
        result = sensor_get_auxtrip(attr->handle, 1, &value);
 
-       return result ? result : sprintf(buf, "%lu", KELVIN_TO_CELSIUS(value));
+       return result ? result : sprintf(buf, "%lu", DECI_KELVIN_TO_CELSIUS(value));
 }
 
 static ssize_t aux0_store(struct device *dev,
@@ -345,7 +345,7 @@ static ssize_t aux0_store(struct device *dev,
        if (value < 0)
                return -EINVAL;
 
-       result = sensor_set_auxtrip(attr->handle, 0, CELSIUS_TO_KELVIN(value));
+       result = sensor_set_auxtrip(attr->handle, 0, CELSIUS_TO_DECI_KELVIN(value));
        return result ? result : count;
 }
 
@@ -364,7 +364,7 @@ static ssize_t aux1_store(struct device *dev,
        if (value < 0)
                return -EINVAL;
 
-       result = sensor_set_auxtrip(attr->handle, 1, CELSIUS_TO_KELVIN(value));
+       result = sensor_set_auxtrip(attr->handle, 1, CELSIUS_TO_DECI_KELVIN(value));
        return result ? result : count;
 }
 
index 131dd74641833e69e144f6a22d1d4021d09ee1c9..0bed4733c4f04925831a174b6b58e674ca2fe56c 100644 (file)
@@ -6459,8 +6459,7 @@ static void __init tpacpi_detect_brightness_capabilities(void)
                pr_info("detected a 8-level brightness capable ThinkPad\n");
                break;
        default:
-               pr_err("Unsupported brightness interface, "
-                      "please contact %s\n", TPACPI_MAIL);
+               pr_info("Unsupported brightness interface\n");
                tp_features.bright_unkfw = 1;
                bright_maxlvl = b - 1;
        }
index 062630ab742451c8d4d06b61262d0a4753bb4711..2f4641a0e88bc3da19e28c3a8e3f432c14f504a9 100644 (file)
@@ -92,6 +92,15 @@ config PWM_BCM2835
          To compile this driver as a module, choose M here: the module
          will be called pwm-bcm2835.
 
+config PWM_BERLIN
+       tristate "Marvell Berlin PWM support"
+       depends on ARCH_BERLIN
+       help
+         PWM framework driver for Marvell Berlin SoCs.
+
+         To compile this driver as a module, choose M here: the module
+         will be called pwm-berlin.
+
 config PWM_BFIN
        tristate "Blackfin PWM support"
        depends on BFIN_GPTIMERS
@@ -101,6 +110,16 @@ config PWM_BFIN
          To compile this driver as a module, choose M here: the module
          will be called pwm-bfin.
 
+config PWM_BRCMSTB
+       tristate "Broadcom STB PWM support"
+       depends on ARCH_BRCMSTB || BMIPS_GENERIC
+       help
+         Generic PWM framework driver for the Broadcom Set-top-Box
+         SoCs (BCM7xxx).
+
+         To compile this driver as a module, choose M Here: the module
+         will be called pwm-brcmstb.c.
+
 config PWM_CLPS711X
        tristate "CLPS711X PWM support"
        depends on ARCH_CLPS711X || COMPILE_TEST
@@ -230,6 +249,17 @@ config PWM_LPSS_PLATFORM
          To compile this driver as a module, choose M here: the module
          will be called pwm-lpss-platform.
 
+config PWM_MTK_DISP
+       tristate "MediaTek display PWM driver"
+       depends on ARCH_MEDIATEK || COMPILE_TEST
+       depends on HAS_IOMEM
+       help
+         Generic PWM framework driver for MediaTek disp-pwm device.
+         The PWM is used to control the backlight brightness for display.
+
+         To compile this driver as a module, choose M here: the module
+         will be called pwm-mtk-disp.
+
 config PWM_MXS
        tristate "Freescale MXS PWM support"
        depends on ARCH_MXS && OF
@@ -242,7 +272,7 @@ config PWM_MXS
 
 config PWM_PCA9685
        tristate "NXP PCA9685 PWM driver"
-       depends on OF && I2C
+       depends on I2C
        select REGMAP_I2C
        help
          Generic PWM framework driver for NXP PCA9685 LED controller.
@@ -268,6 +298,17 @@ config PWM_PXA
          To compile this driver as a module, choose M here: the module
          will be called pwm-pxa.
 
+config PWM_RCAR
+       tristate "Renesas R-Car PWM support"
+       depends on ARCH_RCAR_GEN1 || ARCH_RCAR_GEN2 || COMPILE_TEST
+       depends on HAS_IOMEM
+       help
+         This driver exposes the PWM Timer controller found in Renesas
+         R-Car chips through the PWM API.
+
+         To compile this driver as a module, choose M here: the module
+         will be called pwm-rcar.
+
 config PWM_RENESAS_TPU
        tristate "Renesas TPU PWM support"
        depends on ARCH_SHMOBILE || COMPILE_TEST
@@ -338,7 +379,7 @@ config PWM_TEGRA
 
 config  PWM_TIECAP
        tristate "ECAP PWM support"
-       depends on SOC_AM33XX || ARCH_DAVINCI_DA8XX
+       depends on ARCH_OMAP2PLUS || ARCH_DAVINCI_DA8XX
        help
          PWM driver support for the ECAP APWM controller found on AM33XX
          TI SOC
@@ -348,7 +389,7 @@ config  PWM_TIECAP
 
 config  PWM_TIEHRPWM
        tristate "EHRPWM PWM support"
-       depends on SOC_AM33XX || ARCH_DAVINCI_DA8XX
+       depends on ARCH_OMAP2PLUS || ARCH_DAVINCI_DA8XX
        help
          PWM driver support for the EHRPWM controller found on AM33XX
          TI SOC
@@ -358,7 +399,7 @@ config  PWM_TIEHRPWM
 
 config  PWM_TIPWMSS
        bool
-       default y if SOC_AM33XX && (PWM_TIECAP || PWM_TIEHRPWM)
+       default y if (ARCH_OMAP2PLUS) && (PWM_TIECAP || PWM_TIEHRPWM)
        help
          PWM Subsystem driver support for AM33xx SOC.
 
index a0e00c09ead3d05e6fb92c68f4744cfcf5177f17..69b8275f3c0805af259dbf4237943cf734c6065b 100644 (file)
@@ -6,7 +6,9 @@ obj-$(CONFIG_PWM_ATMEL_HLCDC_PWM)       += pwm-atmel-hlcdc.o
 obj-$(CONFIG_PWM_ATMEL_TCB)    += pwm-atmel-tcb.o
 obj-$(CONFIG_PWM_BCM_KONA)     += pwm-bcm-kona.o
 obj-$(CONFIG_PWM_BCM2835)      += pwm-bcm2835.o
+obj-$(CONFIG_PWM_BERLIN)       += pwm-berlin.o
 obj-$(CONFIG_PWM_BFIN)         += pwm-bfin.o
+obj-$(CONFIG_PWM_BRCMSTB)      += pwm-brcmstb.o
 obj-$(CONFIG_PWM_CLPS711X)     += pwm-clps711x.o
 obj-$(CONFIG_PWM_CRC)          += pwm-crc.o
 obj-$(CONFIG_PWM_EP93XX)       += pwm-ep93xx.o
@@ -20,10 +22,12 @@ obj-$(CONFIG_PWM_LPC32XX)   += pwm-lpc32xx.o
 obj-$(CONFIG_PWM_LPSS)         += pwm-lpss.o
 obj-$(CONFIG_PWM_LPSS_PCI)     += pwm-lpss-pci.o
 obj-$(CONFIG_PWM_LPSS_PLATFORM)        += pwm-lpss-platform.o
+obj-$(CONFIG_PWM_MTK_DISP)     += pwm-mtk-disp.o
 obj-$(CONFIG_PWM_MXS)          += pwm-mxs.o
 obj-$(CONFIG_PWM_PCA9685)      += pwm-pca9685.o
 obj-$(CONFIG_PWM_PUV3)         += pwm-puv3.o
 obj-$(CONFIG_PWM_PXA)          += pwm-pxa.o
+obj-$(CONFIG_PWM_RCAR)         += pwm-rcar.o
 obj-$(CONFIG_PWM_RENESAS_TPU)  += pwm-renesas-tpu.o
 obj-$(CONFIG_PWM_ROCKCHIP)     += pwm-rockchip.o
 obj-$(CONFIG_PWM_SAMSUNG)      += pwm-samsung.o
index 3f9df3ea33508da41334178038c121f6a3939f79..d24ca5f281b4bbd98e5ce86e8f454c270d86fe10 100644 (file)
@@ -269,6 +269,7 @@ int pwmchip_add_with_polarity(struct pwm_chip *chip,
                pwm->pwm = chip->base + i;
                pwm->hwpwm = i;
                pwm->polarity = polarity;
+               mutex_init(&pwm->lock);
 
                radix_tree_insert(&pwm_tree, pwm->pwm, pwm);
        }
@@ -473,16 +474,22 @@ int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity)
        if (!pwm->chip->ops->set_polarity)
                return -ENOSYS;
 
-       if (pwm_is_enabled(pwm))
-               return -EBUSY;
+       mutex_lock(&pwm->lock);
+
+       if (pwm_is_enabled(pwm)) {
+               err = -EBUSY;
+               goto unlock;
+       }
 
        err = pwm->chip->ops->set_polarity(pwm->chip, pwm, polarity);
        if (err)
-               return err;
+               goto unlock;
 
        pwm->polarity = polarity;
 
-       return 0;
+unlock:
+       mutex_unlock(&pwm->lock);
+       return err;
 }
 EXPORT_SYMBOL_GPL(pwm_set_polarity);
 
@@ -494,10 +501,22 @@ EXPORT_SYMBOL_GPL(pwm_set_polarity);
  */
 int pwm_enable(struct pwm_device *pwm)
 {
-       if (pwm && !test_and_set_bit(PWMF_ENABLED, &pwm->flags))
-               return pwm->chip->ops->enable(pwm->chip, pwm);
+       int err = 0;
 
-       return pwm ? 0 : -EINVAL;
+       if (!pwm)
+               return -EINVAL;
+
+       mutex_lock(&pwm->lock);
+
+       if (!test_and_set_bit(PWMF_ENABLED, &pwm->flags)) {
+               err = pwm->chip->ops->enable(pwm->chip, pwm);
+               if (err)
+                       clear_bit(PWMF_ENABLED, &pwm->flags);
+       }
+
+       mutex_unlock(&pwm->lock);
+
+       return err;
 }
 EXPORT_SYMBOL_GPL(pwm_enable);
 
@@ -719,8 +738,10 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id)
                }
        }
 
-       if (!chosen)
+       if (!chosen) {
+               pwm = ERR_PTR(-ENODEV);
                goto out;
+       }
 
        chip = pwmchip_find_by_name(chosen->provider);
        if (!chip)
index 5df1db40fc075add53c4084b55f94993800b0b9e..f994c7eaf41c6c3d67a0c688247561dadee49863 100644 (file)
@@ -226,6 +226,9 @@ static const struct of_device_id atmel_hlcdc_dt_ids[] = {
                .compatible = "atmel,at91sam9x5-hlcdc",
                .data = &atmel_hlcdc_pwm_at91sam9x5_errata,
        },
+       {
+               .compatible = "atmel,sama5d2-hlcdc",
+       },
        {
                .compatible = "atmel,sama5d3-hlcdc",
                .data = &atmel_hlcdc_pwm_sama5d3_errata,
@@ -236,6 +239,7 @@ static const struct of_device_id atmel_hlcdc_dt_ids[] = {
        },
        { /* sentinel */ },
 };
+MODULE_DEVICE_TABLE(of, atmel_hlcdc_dt_ids);
 
 static int atmel_hlcdc_pwm_probe(struct platform_device *pdev)
 {
diff --git a/drivers/pwm/pwm-berlin.c b/drivers/pwm/pwm-berlin.c
new file mode 100644 (file)
index 0000000..6510812
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ * Marvell Berlin PWM driver
+ *
+ * Copyright (C) 2015 Marvell Technology Group Ltd.
+ *
+ * Author: Antoine Tenart <antoine.tenart@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+
+#define BERLIN_PWM_EN                  0x0
+#define  BERLIN_PWM_ENABLE             BIT(0)
+#define BERLIN_PWM_CONTROL             0x4
+#define  BERLIN_PWM_PRESCALE_MASK      0x7
+#define  BERLIN_PWM_PRESCALE_MAX       4096
+#define  BERLIN_PWM_INVERT_POLARITY    BIT(3)
+#define BERLIN_PWM_DUTY                        0x8
+#define BERLIN_PWM_TCNT                        0xc
+#define  BERLIN_PWM_MAX_TCNT           65535
+
+struct berlin_pwm_chip {
+       struct pwm_chip chip;
+       struct clk *clk;
+       void __iomem *base;
+};
+
+static inline struct berlin_pwm_chip *to_berlin_pwm_chip(struct pwm_chip *chip)
+{
+       return container_of(chip, struct berlin_pwm_chip, chip);
+}
+
+static const u32 prescaler_table[] = {
+       1, 4, 8, 16, 64, 256, 1024, 4096
+};
+
+static inline u32 berlin_pwm_readl(struct berlin_pwm_chip *chip,
+                                  unsigned int channel, unsigned long offset)
+{
+       return readl_relaxed(chip->base + channel * 0x10 + offset);
+}
+
+static inline void berlin_pwm_writel(struct berlin_pwm_chip *chip,
+                                    unsigned int channel, u32 value,
+                                    unsigned long offset)
+{
+       writel_relaxed(value, chip->base + channel * 0x10 + offset);
+}
+
+static int berlin_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm_dev,
+                            int duty_ns, int period_ns)
+{
+       struct berlin_pwm_chip *pwm = to_berlin_pwm_chip(chip);
+       unsigned int prescale;
+       u32 value, duty, period;
+       u64 cycles, tmp;
+
+       cycles = clk_get_rate(pwm->clk);
+       cycles *= period_ns;
+       do_div(cycles, NSEC_PER_SEC);
+
+       for (prescale = 0; prescale < ARRAY_SIZE(prescaler_table); prescale++) {
+               tmp = cycles;
+               do_div(tmp, prescaler_table[prescale]);
+
+               if (tmp <= BERLIN_PWM_MAX_TCNT)
+                       break;
+       }
+
+       if (tmp > BERLIN_PWM_MAX_TCNT)
+               return -ERANGE;
+
+       period = tmp;
+       cycles = tmp * duty_ns;
+       do_div(cycles, period_ns);
+       duty = cycles;
+
+       value = berlin_pwm_readl(pwm, pwm_dev->hwpwm, BERLIN_PWM_CONTROL);
+       value &= ~BERLIN_PWM_PRESCALE_MASK;
+       value |= prescale;
+       berlin_pwm_writel(pwm, pwm_dev->hwpwm, value, BERLIN_PWM_CONTROL);
+
+       berlin_pwm_writel(pwm, pwm_dev->hwpwm, duty, BERLIN_PWM_DUTY);
+       berlin_pwm_writel(pwm, pwm_dev->hwpwm, period, BERLIN_PWM_TCNT);
+
+       return 0;
+}
+
+static int berlin_pwm_set_polarity(struct pwm_chip *chip,
+                                  struct pwm_device *pwm_dev,
+                                  enum pwm_polarity polarity)
+{
+       struct berlin_pwm_chip *pwm = to_berlin_pwm_chip(chip);
+       u32 value;
+
+       value = berlin_pwm_readl(pwm, pwm_dev->hwpwm, BERLIN_PWM_CONTROL);
+
+       if (polarity == PWM_POLARITY_NORMAL)
+               value &= ~BERLIN_PWM_INVERT_POLARITY;
+       else
+               value |= BERLIN_PWM_INVERT_POLARITY;
+
+       berlin_pwm_writel(pwm, pwm_dev->hwpwm, value, BERLIN_PWM_CONTROL);
+
+       return 0;
+}
+
+static int berlin_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm_dev)
+{
+       struct berlin_pwm_chip *pwm = to_berlin_pwm_chip(chip);
+       u32 value;
+
+       value = berlin_pwm_readl(pwm, pwm_dev->hwpwm, BERLIN_PWM_EN);
+       value |= BERLIN_PWM_ENABLE;
+       berlin_pwm_writel(pwm, pwm_dev->hwpwm, value, BERLIN_PWM_EN);
+
+       return 0;
+}
+
+static void berlin_pwm_disable(struct pwm_chip *chip,
+                              struct pwm_device *pwm_dev)
+{
+       struct berlin_pwm_chip *pwm = to_berlin_pwm_chip(chip);
+       u32 value;
+
+       value = berlin_pwm_readl(pwm, pwm_dev->hwpwm, BERLIN_PWM_EN);
+       value &= ~BERLIN_PWM_ENABLE;
+       berlin_pwm_writel(pwm, pwm_dev->hwpwm, value, BERLIN_PWM_EN);
+}
+
+static const struct pwm_ops berlin_pwm_ops = {
+       .config = berlin_pwm_config,
+       .set_polarity = berlin_pwm_set_polarity,
+       .enable = berlin_pwm_enable,
+       .disable = berlin_pwm_disable,
+       .owner = THIS_MODULE,
+};
+
+static const struct of_device_id berlin_pwm_match[] = {
+       { .compatible = "marvell,berlin-pwm" },
+       { },
+};
+MODULE_DEVICE_TABLE(of, berlin_pwm_match);
+
+static int berlin_pwm_probe(struct platform_device *pdev)
+{
+       struct berlin_pwm_chip *pwm;
+       struct resource *res;
+       int ret;
+
+       pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL);
+       if (!pwm)
+               return -ENOMEM;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       pwm->base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(pwm->base))
+               return PTR_ERR(pwm->base);
+
+       pwm->clk = devm_clk_get(&pdev->dev, NULL);
+       if (IS_ERR(pwm->clk))
+               return PTR_ERR(pwm->clk);
+
+       ret = clk_prepare_enable(pwm->clk);
+       if (ret)
+               return ret;
+
+       pwm->chip.dev = &pdev->dev;
+       pwm->chip.ops = &berlin_pwm_ops;
+       pwm->chip.base = -1;
+       pwm->chip.npwm = 4;
+       pwm->chip.can_sleep = true;
+       pwm->chip.of_xlate = of_pwm_xlate_with_flags;
+       pwm->chip.of_pwm_n_cells = 3;
+
+       ret = pwmchip_add(&pwm->chip);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret);
+               clk_disable_unprepare(pwm->clk);
+               return ret;
+       }
+
+       platform_set_drvdata(pdev, pwm);
+
+       return 0;
+}
+
+static int berlin_pwm_remove(struct platform_device *pdev)
+{
+       struct berlin_pwm_chip *pwm = platform_get_drvdata(pdev);
+       int ret;
+
+       ret = pwmchip_remove(&pwm->chip);
+       clk_disable_unprepare(pwm->clk);
+
+       return ret;
+}
+
+static struct platform_driver berlin_pwm_driver = {
+       .probe = berlin_pwm_probe,
+       .remove = berlin_pwm_remove,
+       .driver = {
+               .name = "berlin-pwm",
+               .of_match_table = berlin_pwm_match,
+       },
+};
+module_platform_driver(berlin_pwm_driver);
+
+MODULE_AUTHOR("Antoine Tenart <antoine.tenart@free-electrons.com>");
+MODULE_DESCRIPTION("Marvell Berlin PWM driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pwm/pwm-brcmstb.c b/drivers/pwm/pwm-brcmstb.c
new file mode 100644 (file)
index 0000000..423ce08
--- /dev/null
@@ -0,0 +1,343 @@
+/*
+ * Broadcom BCM7038 PWM driver
+ * Author: Florian Fainelli
+ *
+ * Copyright (C) 2015 Broadcom Corporation
+ *
+ * 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.
+ */
+
+#define pr_fmt(fmt)    KBUILD_MODNAME ": " fmt
+
+#include <linux/clk.h>
+#include <linux/export.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/spinlock.h>
+
+#define PWM_CTRL               0x00
+#define  CTRL_START            BIT(0)
+#define  CTRL_OEB              BIT(1)
+#define  CTRL_FORCE_HIGH       BIT(2)
+#define  CTRL_OPENDRAIN                BIT(3)
+#define  CTRL_CHAN_OFFS                4
+
+#define PWM_CTRL2              0x04
+#define  CTRL2_OUT_SELECT      BIT(0)
+
+#define PWM_CH_SIZE            0x8
+
+#define PWM_CWORD_MSB(ch)      (0x08 + ((ch) * PWM_CH_SIZE))
+#define PWM_CWORD_LSB(ch)      (0x0c + ((ch) * PWM_CH_SIZE))
+
+/* Number of bits for the CWORD value */
+#define CWORD_BIT_SIZE         16
+
+/*
+ * Maximum control word value allowed when variable-frequency PWM is used as a
+ * clock for the constant-frequency PMW.
+ */
+#define CONST_VAR_F_MAX                32768
+#define CONST_VAR_F_MIN                1
+
+#define PWM_ON(ch)             (0x18 + ((ch) * PWM_CH_SIZE))
+#define  PWM_ON_MIN            1
+#define PWM_PERIOD(ch)         (0x1c + ((ch) * PWM_CH_SIZE))
+#define  PWM_PERIOD_MIN                0
+
+#define PWM_ON_PERIOD_MAX      0xff
+
+struct brcmstb_pwm {
+       void __iomem *base;
+       spinlock_t lock;
+       struct clk *clk;
+       struct pwm_chip chip;
+};
+
+static inline u32 brcmstb_pwm_readl(struct brcmstb_pwm *p,
+                                   unsigned int offset)
+{
+       if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
+               return __raw_readl(p->base + offset);
+       else
+               return readl_relaxed(p->base + offset);
+}
+
+static inline void brcmstb_pwm_writel(struct brcmstb_pwm *p, u32 value,
+                                     unsigned int offset)
+{
+       if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
+               __raw_writel(value, p->base + offset);
+       else
+               writel_relaxed(value, p->base + offset);
+}
+
+static inline struct brcmstb_pwm *to_brcmstb_pwm(struct pwm_chip *chip)
+{
+       return container_of(chip, struct brcmstb_pwm, chip);
+}
+
+/*
+ * Fv is derived from the variable frequency output. The variable frequency
+ * output is configured using this formula:
+ *
+ * W = cword, if cword < 2 ^ 15 else 16-bit 2's complement of cword
+ *
+ * Fv = W x 2 ^ -16 x 27Mhz (reference clock)
+ *
+ * The period is: (period + 1) / Fv and "on" time is on / (period + 1)
+ *
+ * The PWM core framework specifies that the "duty_ns" parameter is in fact the
+ * "on" time, so this translates directly into our HW programming here.
+ */
+static int brcmstb_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+                             int duty_ns, int period_ns)
+{
+       struct brcmstb_pwm *p = to_brcmstb_pwm(chip);
+       unsigned long pc, dc, cword = CONST_VAR_F_MAX;
+       unsigned int channel = pwm->hwpwm;
+       u32 value;
+
+       /*
+        * If asking for a duty_ns equal to period_ns, we need to substract
+        * the period value by 1 to make it shorter than the "on" time and
+        * produce a flat 100% duty cycle signal, and max out the "on" time
+        */
+       if (duty_ns == period_ns) {
+               dc = PWM_ON_PERIOD_MAX;
+               pc = PWM_ON_PERIOD_MAX - 1;
+               goto done;
+       }
+
+       while (1) {
+               u64 rate, tmp;
+
+               /*
+                * Calculate the base rate from base frequency and current
+                * cword
+                */
+               rate = (u64)clk_get_rate(p->clk) * (u64)cword;
+               do_div(rate, 1 << CWORD_BIT_SIZE);
+
+               tmp = period_ns * rate;
+               do_div(tmp, NSEC_PER_SEC);
+               pc = tmp;
+
+               tmp = (duty_ns + 1) * rate;
+               do_div(tmp, NSEC_PER_SEC);
+               dc = tmp;
+
+               /*
+                * We can be called with separate duty and period updates,
+                * so do not reject dc == 0 right away
+                */
+               if (pc == PWM_PERIOD_MIN || (dc < PWM_ON_MIN && duty_ns))
+                       return -EINVAL;
+
+               /* We converged on a calculation */
+               if (pc <= PWM_ON_PERIOD_MAX && dc <= PWM_ON_PERIOD_MAX)
+                       break;
+
+               /*
+                * The cword needs to be a power of 2 for the variable
+                * frequency generator to output a 50% duty cycle variable
+                * frequency which is used as input clock to the fixed
+                * frequency generator.
+                */
+               cword >>= 1;
+
+               /*
+                * Desired periods are too large, we do not have a divider
+                * for them
+                */
+               if (cword < CONST_VAR_F_MIN)
+                       return -EINVAL;
+       }
+
+done:
+       /*
+        * Configure the defined "cword" value to have the variable frequency
+        * generator output a base frequency for the constant frequency
+        * generator to derive from.
+        */
+       spin_lock(&p->lock);
+       brcmstb_pwm_writel(p, cword >> 8, PWM_CWORD_MSB(channel));
+       brcmstb_pwm_writel(p, cword & 0xff, PWM_CWORD_LSB(channel));
+
+       /* Select constant frequency signal output */
+       value = brcmstb_pwm_readl(p, PWM_CTRL2);
+       value |= CTRL2_OUT_SELECT << (channel * CTRL_CHAN_OFFS);
+       brcmstb_pwm_writel(p, value, PWM_CTRL2);
+
+       /* Configure on and period value */
+       brcmstb_pwm_writel(p, pc, PWM_PERIOD(channel));
+       brcmstb_pwm_writel(p, dc, PWM_ON(channel));
+       spin_unlock(&p->lock);
+
+       return 0;
+}
+
+static inline void brcmstb_pwm_enable_set(struct brcmstb_pwm *p,
+                                         unsigned int channel, bool enable)
+{
+       unsigned int shift = channel * CTRL_CHAN_OFFS;
+       u32 value;
+
+       spin_lock(&p->lock);
+       value = brcmstb_pwm_readl(p, PWM_CTRL);
+
+       if (enable) {
+               value &= ~(CTRL_OEB << shift);
+               value |= (CTRL_START | CTRL_OPENDRAIN) << shift;
+       } else {
+               value &= ~((CTRL_START | CTRL_OPENDRAIN) << shift);
+               value |= CTRL_OEB << shift;
+       }
+
+       brcmstb_pwm_writel(p, value, PWM_CTRL);
+       spin_unlock(&p->lock);
+}
+
+static int brcmstb_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct brcmstb_pwm *p = to_brcmstb_pwm(chip);
+
+       brcmstb_pwm_enable_set(p, pwm->hwpwm, true);
+
+       return 0;
+}
+
+static void brcmstb_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct brcmstb_pwm *p = to_brcmstb_pwm(chip);
+
+       brcmstb_pwm_enable_set(p, pwm->hwpwm, false);
+}
+
+static const struct pwm_ops brcmstb_pwm_ops = {
+       .config = brcmstb_pwm_config,
+       .enable = brcmstb_pwm_enable,
+       .disable = brcmstb_pwm_disable,
+       .owner = THIS_MODULE,
+};
+
+static const struct of_device_id brcmstb_pwm_of_match[] = {
+       { .compatible = "brcm,bcm7038-pwm", },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, brcmstb_pwm_of_match);
+
+static int brcmstb_pwm_probe(struct platform_device *pdev)
+{
+       struct brcmstb_pwm *p;
+       struct resource *res;
+       int ret;
+
+       p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL);
+       if (!p)
+               return -ENOMEM;
+
+       spin_lock_init(&p->lock);
+
+       p->clk = devm_clk_get(&pdev->dev, NULL);
+       if (IS_ERR(p->clk)) {
+               dev_err(&pdev->dev, "failed to obtain clock\n");
+               return PTR_ERR(p->clk);
+       }
+
+       ret = clk_prepare_enable(p->clk);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "failed to enable clock: %d\n", ret);
+               return ret;
+       }
+
+       platform_set_drvdata(pdev, p);
+
+       p->chip.dev = &pdev->dev;
+       p->chip.ops = &brcmstb_pwm_ops;
+       p->chip.base = -1;
+       p->chip.npwm = 2;
+       p->chip.can_sleep = true;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       p->base = devm_ioremap_resource(&pdev->dev, res);
+       if (!p->base) {
+               ret = -ENOMEM;
+               goto out_clk;
+       }
+
+       ret = pwmchip_add(&p->chip);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret);
+               goto out_clk;
+       }
+
+       return 0;
+
+out_clk:
+       clk_disable_unprepare(p->clk);
+       return ret;
+}
+
+static int brcmstb_pwm_remove(struct platform_device *pdev)
+{
+       struct brcmstb_pwm *p = platform_get_drvdata(pdev);
+       int ret;
+
+       ret = pwmchip_remove(&p->chip);
+       clk_disable_unprepare(p->clk);
+
+       return ret;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int brcmstb_pwm_suspend(struct device *dev)
+{
+       struct brcmstb_pwm *p = dev_get_drvdata(dev);
+
+       clk_disable(p->clk);
+
+       return 0;
+}
+
+static int brcmstb_pwm_resume(struct device *dev)
+{
+       struct brcmstb_pwm *p = dev_get_drvdata(dev);
+
+       clk_enable(p->clk);
+
+       return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(brcmstb_pwm_pm_ops, brcmstb_pwm_suspend,
+                        brcmstb_pwm_resume);
+
+static struct platform_driver brcmstb_pwm_driver = {
+       .probe = brcmstb_pwm_probe,
+       .remove = brcmstb_pwm_remove,
+       .driver = {
+               .name = "pwm-brcmstb",
+               .of_match_table = brcmstb_pwm_of_match,
+               .pm = &brcmstb_pwm_pm_ops,
+       },
+};
+module_platform_driver(brcmstb_pwm_driver);
+
+MODULE_AUTHOR("Florian Fainelli <f.fainelli@gmail.com>");
+MODULE_DESCRIPTION("Broadcom STB PWM driver");
+MODULE_ALIAS("platform:pwm-brcmstb");
+MODULE_LICENSE("GPL");
index 45042c1b20463eeb1750c166731992d17a75caf6..7160e8ab38a4ea83f7cd01b21f58b6309b0859fc 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/pm_runtime.h>
 
 #include "pwm-lpss.h"
 
@@ -33,6 +34,10 @@ static int pwm_lpss_probe_pci(struct pci_dev *pdev,
                return PTR_ERR(lpwm);
 
        pci_set_drvdata(pdev, lpwm);
+
+       pm_runtime_put(&pdev->dev);
+       pm_runtime_allow(&pdev->dev);
+
        return 0;
 }
 
@@ -40,16 +45,41 @@ static void pwm_lpss_remove_pci(struct pci_dev *pdev)
 {
        struct pwm_lpss_chip *lpwm = pci_get_drvdata(pdev);
 
+       pm_runtime_forbid(&pdev->dev);
+       pm_runtime_get_sync(&pdev->dev);
+
        pwm_lpss_remove(lpwm);
 }
 
+#ifdef CONFIG_PM
+static int pwm_lpss_runtime_suspend_pci(struct device *dev)
+{
+       /*
+        * The PCI core will handle transition to D3 automatically. We only
+        * need to provide runtime PM hooks for that to happen.
+        */
+       return 0;
+}
+
+static int pwm_lpss_runtime_resume_pci(struct device *dev)
+{
+       return 0;
+}
+#endif
+
+static const struct dev_pm_ops pwm_lpss_pci_pm = {
+       SET_RUNTIME_PM_OPS(pwm_lpss_runtime_suspend_pci,
+                          pwm_lpss_runtime_resume_pci, NULL)
+};
+
 static const struct pci_device_id pwm_lpss_pci_ids[] = {
-       { PCI_VDEVICE(INTEL, 0x0ac8), (unsigned long)&pwm_lpss_bsw_info},
+       { PCI_VDEVICE(INTEL, 0x0ac8), (unsigned long)&pwm_lpss_bxt_info},
        { PCI_VDEVICE(INTEL, 0x0f08), (unsigned long)&pwm_lpss_byt_info},
        { PCI_VDEVICE(INTEL, 0x0f09), (unsigned long)&pwm_lpss_byt_info},
-       { PCI_VDEVICE(INTEL, 0x1ac8), (unsigned long)&pwm_lpss_bsw_info},
+       { PCI_VDEVICE(INTEL, 0x1ac8), (unsigned long)&pwm_lpss_bxt_info},
        { PCI_VDEVICE(INTEL, 0x2288), (unsigned long)&pwm_lpss_bsw_info},
        { PCI_VDEVICE(INTEL, 0x2289), (unsigned long)&pwm_lpss_bsw_info},
+       { PCI_VDEVICE(INTEL, 0x5ac8), (unsigned long)&pwm_lpss_bxt_info},
        { },
 };
 MODULE_DEVICE_TABLE(pci, pwm_lpss_pci_ids);
@@ -59,6 +89,9 @@ static struct pci_driver pwm_lpss_driver_pci = {
        .id_table = pwm_lpss_pci_ids,
        .probe = pwm_lpss_probe_pci,
        .remove = pwm_lpss_remove_pci,
+       .driver = {
+               .pm = &pwm_lpss_pci_pm,
+       },
 };
 module_pci_driver(pwm_lpss_driver_pci);
 
index 18a9c880a76d73f8651f6b80a313211bafb93da4..54433fc6d1a4e491e9e046b20558e093d7c5c4de 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 
 #include "pwm-lpss.h"
 
@@ -36,6 +37,10 @@ static int pwm_lpss_probe_platform(struct platform_device *pdev)
                return PTR_ERR(lpwm);
 
        platform_set_drvdata(pdev, lpwm);
+
+       pm_runtime_set_active(&pdev->dev);
+       pm_runtime_enable(&pdev->dev);
+
        return 0;
 }
 
@@ -43,12 +48,14 @@ static int pwm_lpss_remove_platform(struct platform_device *pdev)
 {
        struct pwm_lpss_chip *lpwm = platform_get_drvdata(pdev);
 
+       pm_runtime_disable(&pdev->dev);
        return pwm_lpss_remove(lpwm);
 }
 
 static const struct acpi_device_id pwm_lpss_acpi_match[] = {
        { "80860F09", (unsigned long)&pwm_lpss_byt_info },
        { "80862288", (unsigned long)&pwm_lpss_bsw_info },
+       { "80865AC8", (unsigned long)&pwm_lpss_bxt_info },
        { },
 };
 MODULE_DEVICE_TABLE(acpi, pwm_lpss_acpi_match);
index e9798253a16fcfb76117c219c1c7212e171f8fe5..25044104003b01a7e3879fe6b94e7e5e7d477681 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/pm_runtime.h>
 
 #include "pwm-lpss.h"
 
@@ -29,6 +30,9 @@
 #define PWM_LIMIT                      (0x8000 + PWM_DIVISION_CORRECTION)
 #define NSECS_PER_SEC                  1000000000UL
 
+/* Size of each PWM register space if multiple */
+#define PWM_SIZE                       0x400
+
 struct pwm_lpss_chip {
        struct pwm_chip chip;
        void __iomem *regs;
@@ -37,21 +41,44 @@ struct pwm_lpss_chip {
 
 /* BayTrail */
 const struct pwm_lpss_boardinfo pwm_lpss_byt_info = {
-       .clk_rate = 25000000
+       .clk_rate = 25000000,
+       .npwm = 1,
 };
 EXPORT_SYMBOL_GPL(pwm_lpss_byt_info);
 
 /* Braswell */
 const struct pwm_lpss_boardinfo pwm_lpss_bsw_info = {
-       .clk_rate = 19200000
+       .clk_rate = 19200000,
+       .npwm = 1,
 };
 EXPORT_SYMBOL_GPL(pwm_lpss_bsw_info);
 
+/* Broxton */
+const struct pwm_lpss_boardinfo pwm_lpss_bxt_info = {
+       .clk_rate = 19200000,
+       .npwm = 4,
+};
+EXPORT_SYMBOL_GPL(pwm_lpss_bxt_info);
+
 static inline struct pwm_lpss_chip *to_lpwm(struct pwm_chip *chip)
 {
        return container_of(chip, struct pwm_lpss_chip, chip);
 }
 
+static inline u32 pwm_lpss_read(const struct pwm_device *pwm)
+{
+       struct pwm_lpss_chip *lpwm = to_lpwm(pwm->chip);
+
+       return readl(lpwm->regs + pwm->hwpwm * PWM_SIZE + PWM);
+}
+
+static inline void pwm_lpss_write(const struct pwm_device *pwm, u32 value)
+{
+       struct pwm_lpss_chip *lpwm = to_lpwm(pwm->chip);
+
+       writel(value, lpwm->regs + pwm->hwpwm * PWM_SIZE + PWM);
+}
+
 static int pwm_lpss_config(struct pwm_chip *chip, struct pwm_device *pwm,
                           int duty_ns, int period_ns)
 {
@@ -79,38 +106,36 @@ static int pwm_lpss_config(struct pwm_chip *chip, struct pwm_device *pwm,
                duty_ns = 1;
        on_time_div = 255 - (255 * duty_ns / period_ns);
 
-       ctrl = readl(lpwm->regs + PWM);
+       pm_runtime_get_sync(chip->dev);
+
+       ctrl = pwm_lpss_read(pwm);
        ctrl &= ~(PWM_BASE_UNIT_MASK | PWM_ON_TIME_DIV_MASK);
        ctrl |= (u16) base_unit << PWM_BASE_UNIT_SHIFT;
        ctrl |= on_time_div;
        /* request PWM to update on next cycle */
        ctrl |= PWM_SW_UPDATE;
-       writel(ctrl, lpwm->regs + PWM);
+       pwm_lpss_write(pwm, ctrl);
+
+       pm_runtime_put(chip->dev);
 
        return 0;
 }
 
 static int pwm_lpss_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
-       struct pwm_lpss_chip *lpwm = to_lpwm(chip);
-       u32 ctrl;
-
-       ctrl = readl(lpwm->regs + PWM);
-       writel(ctrl | PWM_ENABLE, lpwm->regs + PWM);
-
+       pm_runtime_get_sync(chip->dev);
+       pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_ENABLE);
        return 0;
 }
 
 static void pwm_lpss_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
-       struct pwm_lpss_chip *lpwm = to_lpwm(chip);
-       u32 ctrl;
-
-       ctrl = readl(lpwm->regs + PWM);
-       writel(ctrl & ~PWM_ENABLE, lpwm->regs + PWM);
+       pwm_lpss_write(pwm, pwm_lpss_read(pwm) & ~PWM_ENABLE);
+       pm_runtime_put(chip->dev);
 }
 
 static const struct pwm_ops pwm_lpss_ops = {
+       .free = pwm_lpss_disable,
        .config = pwm_lpss_config,
        .enable = pwm_lpss_enable,
        .disable = pwm_lpss_disable,
@@ -135,7 +160,7 @@ struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, struct resource *r,
        lpwm->chip.dev = dev;
        lpwm->chip.ops = &pwm_lpss_ops;
        lpwm->chip.base = -1;
-       lpwm->chip.npwm = 1;
+       lpwm->chip.npwm = info->npwm;
 
        ret = pwmchip_add(&lpwm->chip);
        if (ret) {
@@ -149,11 +174,6 @@ EXPORT_SYMBOL_GPL(pwm_lpss_probe);
 
 int pwm_lpss_remove(struct pwm_lpss_chip *lpwm)
 {
-       u32 ctrl;
-
-       ctrl = readl(lpwm->regs + PWM);
-       writel(ctrl & ~PWM_ENABLE, lpwm->regs + PWM);
-
        return pwmchip_remove(&lpwm->chip);
 }
 EXPORT_SYMBOL_GPL(pwm_lpss_remove);
index aa041bb1b67d1c8b3330ab7709c3c1a20664f5ec..e8cf337ae1d1f7466bdd86d164261531cb32176c 100644 (file)
@@ -20,10 +20,12 @@ struct pwm_lpss_chip;
 
 struct pwm_lpss_boardinfo {
        unsigned long clk_rate;
+       unsigned int npwm;
 };
 
 extern const struct pwm_lpss_boardinfo pwm_lpss_byt_info;
 extern const struct pwm_lpss_boardinfo pwm_lpss_bsw_info;
+extern const struct pwm_lpss_boardinfo pwm_lpss_bxt_info;
 
 struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, struct resource *r,
                                     const struct pwm_lpss_boardinfo *info);
diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c
new file mode 100644 (file)
index 0000000..0ad3385
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ * MediaTek display pulse-width-modulation controller driver.
+ * Copyright (c) 2015 MediaTek Inc.
+ * Author: YH Huang <yh.huang@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/slab.h>
+
+#define DISP_PWM_EN            0x00
+#define PWM_ENABLE_MASK                BIT(0)
+
+#define DISP_PWM_COMMIT                0x08
+#define PWM_COMMIT_MASK                BIT(0)
+
+#define DISP_PWM_CON_0         0x10
+#define PWM_CLKDIV_SHIFT       16
+#define PWM_CLKDIV_MAX         0x3ff
+#define PWM_CLKDIV_MASK                (PWM_CLKDIV_MAX << PWM_CLKDIV_SHIFT)
+
+#define DISP_PWM_CON_1         0x14
+#define PWM_PERIOD_BIT_WIDTH   12
+#define PWM_PERIOD_MASK                ((1 << PWM_PERIOD_BIT_WIDTH) - 1)
+
+#define PWM_HIGH_WIDTH_SHIFT   16
+#define PWM_HIGH_WIDTH_MASK    (0x1fff << PWM_HIGH_WIDTH_SHIFT)
+
+struct mtk_disp_pwm {
+       struct pwm_chip chip;
+       struct clk *clk_main;
+       struct clk *clk_mm;
+       void __iomem *base;
+};
+
+static inline struct mtk_disp_pwm *to_mtk_disp_pwm(struct pwm_chip *chip)
+{
+       return container_of(chip, struct mtk_disp_pwm, chip);
+}
+
+static void mtk_disp_pwm_update_bits(struct mtk_disp_pwm *mdp, u32 offset,
+                                    u32 mask, u32 data)
+{
+       void __iomem *address = mdp->base + offset;
+       u32 value;
+
+       value = readl(address);
+       value &= ~mask;
+       value |= data;
+       writel(value, address);
+}
+
+static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+                              int duty_ns, int period_ns)
+{
+       struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip);
+       u32 clk_div, period, high_width, value;
+       u64 div, rate;
+       int err;
+
+       /*
+        * Find period, high_width and clk_div to suit duty_ns and period_ns.
+        * Calculate proper div value to keep period value in the bound.
+        *
+        * period_ns = 10^9 * (clk_div + 1) * (period + 1) / PWM_CLK_RATE
+        * duty_ns = 10^9 * (clk_div + 1) * high_width / PWM_CLK_RATE
+        *
+        * period = (PWM_CLK_RATE * period_ns) / (10^9 * (clk_div + 1)) - 1
+        * high_width = (PWM_CLK_RATE * duty_ns) / (10^9 * (clk_div + 1))
+        */
+       rate = clk_get_rate(mdp->clk_main);
+       clk_div = div_u64(rate * period_ns, NSEC_PER_SEC) >>
+                         PWM_PERIOD_BIT_WIDTH;
+       if (clk_div > PWM_CLKDIV_MAX)
+               return -EINVAL;
+
+       div = NSEC_PER_SEC * (clk_div + 1);
+       period = div64_u64(rate * period_ns, div);
+       if (period > 0)
+               period--;
+
+       high_width = div64_u64(rate * duty_ns, div);
+       value = period | (high_width << PWM_HIGH_WIDTH_SHIFT);
+
+       err = clk_enable(mdp->clk_main);
+       if (err < 0)
+               return err;
+
+       err = clk_enable(mdp->clk_mm);
+       if (err < 0) {
+               clk_disable(mdp->clk_main);
+               return err;
+       }
+
+       mtk_disp_pwm_update_bits(mdp, DISP_PWM_CON_0, PWM_CLKDIV_MASK,
+                                clk_div << PWM_CLKDIV_SHIFT);
+       mtk_disp_pwm_update_bits(mdp, DISP_PWM_CON_1,
+                                PWM_PERIOD_MASK | PWM_HIGH_WIDTH_MASK, value);
+       mtk_disp_pwm_update_bits(mdp, DISP_PWM_COMMIT, PWM_COMMIT_MASK, 1);
+       mtk_disp_pwm_update_bits(mdp, DISP_PWM_COMMIT, PWM_COMMIT_MASK, 0);
+
+       clk_disable(mdp->clk_mm);
+       clk_disable(mdp->clk_main);
+
+       return 0;
+}
+
+static int mtk_disp_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip);
+       int err;
+
+       err = clk_enable(mdp->clk_main);
+       if (err < 0)
+               return err;
+
+       err = clk_enable(mdp->clk_mm);
+       if (err < 0) {
+               clk_disable(mdp->clk_main);
+               return err;
+       }
+
+       mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, PWM_ENABLE_MASK, 1);
+
+       return 0;
+}
+
+static void mtk_disp_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip);
+
+       mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, PWM_ENABLE_MASK, 0);
+
+       clk_disable(mdp->clk_mm);
+       clk_disable(mdp->clk_main);
+}
+
+static const struct pwm_ops mtk_disp_pwm_ops = {
+       .config = mtk_disp_pwm_config,
+       .enable = mtk_disp_pwm_enable,
+       .disable = mtk_disp_pwm_disable,
+       .owner = THIS_MODULE,
+};
+
+static int mtk_disp_pwm_probe(struct platform_device *pdev)
+{
+       struct mtk_disp_pwm *mdp;
+       struct resource *r;
+       int ret;
+
+       mdp = devm_kzalloc(&pdev->dev, sizeof(*mdp), GFP_KERNEL);
+       if (!mdp)
+               return -ENOMEM;
+
+       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       mdp->base = devm_ioremap_resource(&pdev->dev, r);
+       if (IS_ERR(mdp->base))
+               return PTR_ERR(mdp->base);
+
+       mdp->clk_main = devm_clk_get(&pdev->dev, "main");
+       if (IS_ERR(mdp->clk_main))
+               return PTR_ERR(mdp->clk_main);
+
+       mdp->clk_mm = devm_clk_get(&pdev->dev, "mm");
+       if (IS_ERR(mdp->clk_mm))
+               return PTR_ERR(mdp->clk_mm);
+
+       ret = clk_prepare(mdp->clk_main);
+       if (ret < 0)
+               return ret;
+
+       ret = clk_prepare(mdp->clk_mm);
+       if (ret < 0)
+               goto disable_clk_main;
+
+       mdp->chip.dev = &pdev->dev;
+       mdp->chip.ops = &mtk_disp_pwm_ops;
+       mdp->chip.base = -1;
+       mdp->chip.npwm = 1;
+
+       ret = pwmchip_add(&mdp->chip);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
+               goto disable_clk_mm;
+       }
+
+       platform_set_drvdata(pdev, mdp);
+
+       return 0;
+
+disable_clk_mm:
+       clk_unprepare(mdp->clk_mm);
+disable_clk_main:
+       clk_unprepare(mdp->clk_main);
+       return ret;
+}
+
+static int mtk_disp_pwm_remove(struct platform_device *pdev)
+{
+       struct mtk_disp_pwm *mdp = platform_get_drvdata(pdev);
+       int ret;
+
+       ret = pwmchip_remove(&mdp->chip);
+       clk_unprepare(mdp->clk_mm);
+       clk_unprepare(mdp->clk_main);
+
+       return ret;
+}
+
+static const struct of_device_id mtk_disp_pwm_of_match[] = {
+       { .compatible = "mediatek,mt8173-disp-pwm" },
+       { .compatible = "mediatek,mt6595-disp-pwm" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, mtk_disp_pwm_of_match);
+
+static struct platform_driver mtk_disp_pwm_driver = {
+       .driver = {
+               .name = "mediatek-disp-pwm",
+               .of_match_table = mtk_disp_pwm_of_match,
+       },
+       .probe = mtk_disp_pwm_probe,
+       .remove = mtk_disp_pwm_remove,
+};
+module_platform_driver(mtk_disp_pwm_driver);
+
+MODULE_AUTHOR("YH Huang <yh.huang@mediatek.com>");
+MODULE_DESCRIPTION("MediaTek SoC display PWM driver");
+MODULE_LICENSE("GPL v2");
index 70448a6079b02ede68edf1b2242a5e7b049fb207..117fccf7934a73a3c4098d809ff72bb9bef8006a 100644 (file)
  * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/acpi.h>
 #include <linux/i2c.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/property.h>
 #include <linux/pwm.h>
 #include <linux/regmap.h>
 #include <linux/slab.h>
@@ -297,7 +299,6 @@ static const struct regmap_config pca9685_regmap_i2c_config = {
 static int pca9685_pwm_probe(struct i2c_client *client,
                                const struct i2c_device_id *id)
 {
-       struct device_node *np = client->dev.of_node;
        struct pca9685 *pca;
        int ret;
        int mode2;
@@ -320,12 +321,12 @@ static int pca9685_pwm_probe(struct i2c_client *client,
 
        regmap_read(pca->regmap, PCA9685_MODE2, &mode2);
 
-       if (of_property_read_bool(np, "invert"))
+       if (device_property_read_bool(&client->dev, "invert"))
                mode2 |= MODE2_INVRT;
        else
                mode2 &= ~MODE2_INVRT;
 
-       if (of_property_read_bool(np, "open-drain"))
+       if (device_property_read_bool(&client->dev, "open-drain"))
                mode2 &= ~MODE2_OUTDRV;
        else
                mode2 |= MODE2_OUTDRV;
@@ -363,16 +364,27 @@ static const struct i2c_device_id pca9685_id[] = {
 };
 MODULE_DEVICE_TABLE(i2c, pca9685_id);
 
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id pca9685_acpi_ids[] = {
+       { "INT3492", 0 },
+       { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(acpi, pca9685_acpi_ids);
+#endif
+
+#ifdef CONFIG_OF
 static const struct of_device_id pca9685_dt_ids[] = {
        { .compatible = "nxp,pca9685-pwm", },
        { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, pca9685_dt_ids);
+#endif
 
 static struct i2c_driver pca9685_i2c_driver = {
        .driver = {
                .name = "pca9685-pwm",
-               .of_match_table = pca9685_dt_ids,
+               .acpi_match_table = ACPI_PTR(pca9685_acpi_ids),
+               .of_match_table = of_match_ptr(pca9685_dt_ids),
        },
        .probe = pca9685_pwm_probe,
        .remove = pca9685_pwm_remove,
diff --git a/drivers/pwm/pwm-rcar.c b/drivers/pwm/pwm-rcar.c
new file mode 100644 (file)
index 0000000..6e99a63
--- /dev/null
@@ -0,0 +1,274 @@
+/*
+ * R-Car PWM Timer driver
+ *
+ * Copyright (C) 2015 Renesas Electronics Corporation
+ *
+ * This 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.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/pwm.h>
+#include <linux/slab.h>
+
+#define RCAR_PWM_MAX_DIVISION  24
+#define RCAR_PWM_MAX_CYCLE     1023
+
+#define RCAR_PWMCR             0x00
+#define  RCAR_PWMCR_CC0_MASK   0x000f0000
+#define  RCAR_PWMCR_CC0_SHIFT  16
+#define  RCAR_PWMCR_CCMD       BIT(15)
+#define  RCAR_PWMCR_SYNC       BIT(11)
+#define  RCAR_PWMCR_SS0                BIT(4)
+#define  RCAR_PWMCR_EN0                BIT(0)
+
+#define RCAR_PWMCNT            0x04
+#define  RCAR_PWMCNT_CYC0_MASK 0x03ff0000
+#define  RCAR_PWMCNT_CYC0_SHIFT        16
+#define  RCAR_PWMCNT_PH0_MASK  0x000003ff
+#define  RCAR_PWMCNT_PH0_SHIFT 0
+
+struct rcar_pwm_chip {
+       struct pwm_chip chip;
+       void __iomem *base;
+       struct clk *clk;
+};
+
+static inline struct rcar_pwm_chip *to_rcar_pwm_chip(struct pwm_chip *chip)
+{
+       return container_of(chip, struct rcar_pwm_chip, chip);
+}
+
+static void rcar_pwm_write(struct rcar_pwm_chip *rp, u32 data,
+                          unsigned int offset)
+{
+       writel(data, rp->base + offset);
+}
+
+static u32 rcar_pwm_read(struct rcar_pwm_chip *rp, unsigned int offset)
+{
+       return readl(rp->base + offset);
+}
+
+static void rcar_pwm_update(struct rcar_pwm_chip *rp, u32 mask, u32 data,
+                           unsigned int offset)
+{
+       u32 value;
+
+       value = rcar_pwm_read(rp, offset);
+       value &= ~mask;
+       value |= data & mask;
+       rcar_pwm_write(rp, value, offset);
+}
+
+static int rcar_pwm_get_clock_division(struct rcar_pwm_chip *rp, int period_ns)
+{
+       unsigned long clk_rate = clk_get_rate(rp->clk);
+       unsigned long long max; /* max cycle / nanoseconds */
+       unsigned int div;
+
+       if (clk_rate == 0)
+               return -EINVAL;
+
+       for (div = 0; div <= RCAR_PWM_MAX_DIVISION; div++) {
+               max = (unsigned long long)NSEC_PER_SEC * RCAR_PWM_MAX_CYCLE *
+                       (1 << div);
+               do_div(max, clk_rate);
+               if (period_ns < max)
+                       break;
+       }
+
+       return (div <= RCAR_PWM_MAX_DIVISION) ? div : -ERANGE;
+}
+
+static void rcar_pwm_set_clock_control(struct rcar_pwm_chip *rp,
+                                      unsigned int div)
+{
+       u32 value;
+
+       value = rcar_pwm_read(rp, RCAR_PWMCR);
+       value &= ~(RCAR_PWMCR_CCMD | RCAR_PWMCR_CC0_MASK);
+
+       if (div & 1)
+               value |= RCAR_PWMCR_CCMD;
+
+       div >>= 1;
+
+       value |= div << RCAR_PWMCR_CC0_SHIFT;
+       rcar_pwm_write(rp, value, RCAR_PWMCR);
+}
+
+static int rcar_pwm_set_counter(struct rcar_pwm_chip *rp, int div, int duty_ns,
+                               int period_ns)
+{
+       unsigned long long one_cycle, tmp;      /* 0.01 nanoseconds */
+       unsigned long clk_rate = clk_get_rate(rp->clk);
+       u32 cyc, ph;
+
+       one_cycle = (unsigned long long)NSEC_PER_SEC * 100ULL * (1 << div);
+       do_div(one_cycle, clk_rate);
+
+       tmp = period_ns * 100ULL;
+       do_div(tmp, one_cycle);
+       cyc = (tmp << RCAR_PWMCNT_CYC0_SHIFT) & RCAR_PWMCNT_CYC0_MASK;
+
+       tmp = duty_ns * 100ULL;
+       do_div(tmp, one_cycle);
+       ph = tmp & RCAR_PWMCNT_PH0_MASK;
+
+       /* Avoid prohibited setting */
+       if (cyc == 0 || ph == 0)
+               return -EINVAL;
+
+       rcar_pwm_write(rp, cyc | ph, RCAR_PWMCNT);
+
+       return 0;
+}
+
+static int rcar_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct rcar_pwm_chip *rp = to_rcar_pwm_chip(chip);
+
+       return clk_prepare_enable(rp->clk);
+}
+
+static void rcar_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct rcar_pwm_chip *rp = to_rcar_pwm_chip(chip);
+
+       clk_disable_unprepare(rp->clk);
+}
+
+static int rcar_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+                          int duty_ns, int period_ns)
+{
+       struct rcar_pwm_chip *rp = to_rcar_pwm_chip(chip);
+       int div, ret;
+
+       div = rcar_pwm_get_clock_division(rp, period_ns);
+       if (div < 0)
+               return div;
+
+       /* Let the core driver set pwm->period if disabled and duty_ns == 0 */
+       if (!test_bit(PWMF_ENABLED, &pwm->flags) && !duty_ns)
+               return 0;
+
+       rcar_pwm_update(rp, RCAR_PWMCR_SYNC, RCAR_PWMCR_SYNC, RCAR_PWMCR);
+
+       ret = rcar_pwm_set_counter(rp, div, duty_ns, period_ns);
+       if (!ret)
+               rcar_pwm_set_clock_control(rp, div);
+
+       /* The SYNC should be set to 0 even if rcar_pwm_set_counter failed */
+       rcar_pwm_update(rp, RCAR_PWMCR_SYNC, 0, RCAR_PWMCR);
+
+       return ret;
+}
+
+static int rcar_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct rcar_pwm_chip *rp = to_rcar_pwm_chip(chip);
+       u32 value;
+
+       /* Don't enable the PWM device if CYC0 or PH0 is 0 */
+       value = rcar_pwm_read(rp, RCAR_PWMCNT);
+       if ((value & RCAR_PWMCNT_CYC0_MASK) == 0 ||
+           (value & RCAR_PWMCNT_PH0_MASK) == 0)
+               return -EINVAL;
+
+       rcar_pwm_update(rp, RCAR_PWMCR_EN0, RCAR_PWMCR_EN0, RCAR_PWMCR);
+
+       return 0;
+}
+
+static void rcar_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct rcar_pwm_chip *rp = to_rcar_pwm_chip(chip);
+
+       rcar_pwm_update(rp, RCAR_PWMCR_EN0, 0, RCAR_PWMCR);
+}
+
+static const struct pwm_ops rcar_pwm_ops = {
+       .request = rcar_pwm_request,
+       .free = rcar_pwm_free,
+       .config = rcar_pwm_config,
+       .enable = rcar_pwm_enable,
+       .disable = rcar_pwm_disable,
+       .owner = THIS_MODULE,
+};
+
+static int rcar_pwm_probe(struct platform_device *pdev)
+{
+       struct rcar_pwm_chip *rcar_pwm;
+       struct resource *res;
+       int ret;
+
+       rcar_pwm = devm_kzalloc(&pdev->dev, sizeof(*rcar_pwm), GFP_KERNEL);
+       if (rcar_pwm == NULL)
+               return -ENOMEM;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       rcar_pwm->base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(rcar_pwm->base))
+               return PTR_ERR(rcar_pwm->base);
+
+       rcar_pwm->clk = devm_clk_get(&pdev->dev, NULL);
+       if (IS_ERR(rcar_pwm->clk)) {
+               dev_err(&pdev->dev, "cannot get clock\n");
+               return PTR_ERR(rcar_pwm->clk);
+       }
+
+       platform_set_drvdata(pdev, rcar_pwm);
+
+       rcar_pwm->chip.dev = &pdev->dev;
+       rcar_pwm->chip.ops = &rcar_pwm_ops;
+       rcar_pwm->chip.base = -1;
+       rcar_pwm->chip.npwm = 1;
+
+       ret = pwmchip_add(&rcar_pwm->chip);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "failed to register PWM chip: %d\n", ret);
+               return ret;
+       }
+
+       pm_runtime_enable(&pdev->dev);
+
+       return 0;
+}
+
+static int rcar_pwm_remove(struct platform_device *pdev)
+{
+       struct rcar_pwm_chip *rcar_pwm = platform_get_drvdata(pdev);
+
+       pm_runtime_disable(&pdev->dev);
+
+       return pwmchip_remove(&rcar_pwm->chip);
+}
+
+static const struct of_device_id rcar_pwm_of_table[] = {
+       { .compatible = "renesas,pwm-rcar", },
+       { },
+};
+MODULE_DEVICE_TABLE(of, rcar_pwm_of_table);
+
+static struct platform_driver rcar_pwm_driver = {
+       .probe = rcar_pwm_probe,
+       .remove = rcar_pwm_remove,
+       .driver = {
+               .name = "pwm-rcar",
+               .of_match_table = of_match_ptr(rcar_pwm_of_table),
+       }
+};
+module_platform_driver(rcar_pwm_driver);
+
+MODULE_AUTHOR("Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>");
+MODULE_DESCRIPTION("Renesas PWM Timer Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:pwm-rcar");
index cd9dde5630181d2bf353263b63b58614991b967f..67af9f62361fdc4b712c8adafbe4e331e32af9ae 100644 (file)
@@ -68,6 +68,7 @@ static const u32 prescaler_table[] = {
 struct sun4i_pwm_data {
        bool has_prescaler_bypass;
        bool has_rdy;
+       unsigned int npwm;
 };
 
 struct sun4i_pwm_chip {
@@ -114,7 +115,7 @@ static int sun4i_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
                 * is not an integer so round it half up instead of
                 * truncating to get less surprising values.
                 */
-               div = clk_rate * period_ns + NSEC_PER_SEC/2;
+               div = clk_rate * period_ns + NSEC_PER_SEC / 2;
                do_div(div, NSEC_PER_SEC);
                if (div - 1 > PWM_PRD_MASK)
                        prescaler = 0;
@@ -262,17 +263,37 @@ static const struct pwm_ops sun4i_pwm_ops = {
 static const struct sun4i_pwm_data sun4i_pwm_data_a10 = {
        .has_prescaler_bypass = false,
        .has_rdy = false,
+       .npwm = 2,
+};
+
+static const struct sun4i_pwm_data sun4i_pwm_data_a10s = {
+       .has_prescaler_bypass = true,
+       .has_rdy = true,
+       .npwm = 2,
+};
+
+static const struct sun4i_pwm_data sun4i_pwm_data_a13 = {
+       .has_prescaler_bypass = true,
+       .has_rdy = true,
+       .npwm = 1,
 };
 
 static const struct sun4i_pwm_data sun4i_pwm_data_a20 = {
        .has_prescaler_bypass = true,
        .has_rdy = true,
+       .npwm = 2,
 };
 
 static const struct of_device_id sun4i_pwm_dt_ids[] = {
        {
                .compatible = "allwinner,sun4i-a10-pwm",
                .data = &sun4i_pwm_data_a10,
+       }, {
+               .compatible = "allwinner,sun5i-a10s-pwm",
+               .data = &sun4i_pwm_data_a10s,
+       }, {
+               .compatible = "allwinner,sun5i-a13-pwm",
+               .data = &sun4i_pwm_data_a13,
        }, {
                .compatible = "allwinner,sun7i-a20-pwm",
                .data = &sun4i_pwm_data_a20,
@@ -305,14 +326,14 @@ static int sun4i_pwm_probe(struct platform_device *pdev)
        if (IS_ERR(pwm->clk))
                return PTR_ERR(pwm->clk);
 
+       pwm->data = match->data;
        pwm->chip.dev = &pdev->dev;
        pwm->chip.ops = &sun4i_pwm_ops;
        pwm->chip.base = -1;
-       pwm->chip.npwm = 2;
+       pwm->chip.npwm = pwm->data->npwm;
        pwm->chip.can_sleep = true;
        pwm->chip.of_xlate = of_pwm_xlate_with_flags;
        pwm->chip.of_pwm_n_cells = 3;
-       pwm->data = match->data;
 
        spin_lock_init(&pwm->ctrl_lock);
 
index c472772f00a7880611e23e62cfbd1731d04dfa27..9c90886f41234153d044d24f94a9ae1e82efbd83 100644 (file)
@@ -40,18 +40,18 @@ static struct pwm_device *child_to_pwm_device(struct device *child)
        return export->pwm;
 }
 
-static ssize_t pwm_period_show(struct device *child,
-                              struct device_attribute *attr,
-                              char *buf)
+static ssize_t period_show(struct device *child,
+                          struct device_attribute *attr,
+                          char *buf)
 {
        const struct pwm_device *pwm = child_to_pwm_device(child);
 
        return sprintf(buf, "%u\n", pwm_get_period(pwm));
 }
 
-static ssize_t pwm_period_store(struct device *child,
-                               struct device_attribute *attr,
-                               const char *buf, size_t size)
+static ssize_t period_store(struct device *child,
+                           struct device_attribute *attr,
+                           const char *buf, size_t size)
 {
        struct pwm_device *pwm = child_to_pwm_device(child);
        unsigned int val;
@@ -66,18 +66,18 @@ static ssize_t pwm_period_store(struct device *child,
        return ret ? : size;
 }
 
-static ssize_t pwm_duty_cycle_show(struct device *child,
-                                  struct device_attribute *attr,
-                                  char *buf)
+static ssize_t duty_cycle_show(struct device *child,
+                              struct device_attribute *attr,
+                              char *buf)
 {
        const struct pwm_device *pwm = child_to_pwm_device(child);
 
        return sprintf(buf, "%u\n", pwm_get_duty_cycle(pwm));
 }
 
-static ssize_t pwm_duty_cycle_store(struct device *child,
-                                   struct device_attribute *attr,
-                                   const char *buf, size_t size)
+static ssize_t duty_cycle_store(struct device *child,
+                               struct device_attribute *attr,
+                               const char *buf, size_t size)
 {
        struct pwm_device *pwm = child_to_pwm_device(child);
        unsigned int val;
@@ -92,19 +92,18 @@ static ssize_t pwm_duty_cycle_store(struct device *child,
        return ret ? : size;
 }
 
-static ssize_t pwm_enable_show(struct device *child,
-                              struct device_attribute *attr,
-                              char *buf)
+static ssize_t enable_show(struct device *child,
+                          struct device_attribute *attr,
+                          char *buf)
 {
        const struct pwm_device *pwm = child_to_pwm_device(child);
-       int enabled = pwm_is_enabled(pwm);
 
-       return sprintf(buf, "%d\n", enabled);
+       return sprintf(buf, "%d\n", pwm_is_enabled(pwm));
 }
 
-static ssize_t pwm_enable_store(struct device *child,
-                               struct device_attribute *attr,
-                               const char *buf, size_t size)
+static ssize_t enable_store(struct device *child,
+                           struct device_attribute *attr,
+                           const char *buf, size_t size)
 {
        struct pwm_device *pwm = child_to_pwm_device(child);
        int val, ret;
@@ -128,9 +127,9 @@ static ssize_t pwm_enable_store(struct device *child,
        return ret ? : size;
 }
 
-static ssize_t pwm_polarity_show(struct device *child,
-                                struct device_attribute *attr,
-                                char *buf)
+static ssize_t polarity_show(struct device *child,
+                            struct device_attribute *attr,
+                            char *buf)
 {
        const struct pwm_device *pwm = child_to_pwm_device(child);
        const char *polarity = "unknown";
@@ -148,9 +147,9 @@ static ssize_t pwm_polarity_show(struct device *child,
        return sprintf(buf, "%s\n", polarity);
 }
 
-static ssize_t pwm_polarity_store(struct device *child,
-                                 struct device_attribute *attr,
-                                 const char *buf, size_t size)
+static ssize_t polarity_store(struct device *child,
+                             struct device_attribute *attr,
+                             const char *buf, size_t size)
 {
        struct pwm_device *pwm = child_to_pwm_device(child);
        enum pwm_polarity polarity;
@@ -168,10 +167,10 @@ static ssize_t pwm_polarity_store(struct device *child,
        return ret ? : size;
 }
 
-static DEVICE_ATTR(period, 0644, pwm_period_show, pwm_period_store);
-static DEVICE_ATTR(duty_cycle, 0644, pwm_duty_cycle_show, pwm_duty_cycle_store);
-static DEVICE_ATTR(enable, 0644, pwm_enable_show, pwm_enable_store);
-static DEVICE_ATTR(polarity, 0644, pwm_polarity_show, pwm_polarity_store);
+static DEVICE_ATTR_RW(period);
+static DEVICE_ATTR_RW(duty_cycle);
+static DEVICE_ATTR_RW(enable);
+static DEVICE_ATTR_RW(polarity);
 
 static struct attribute *pwm_attrs[] = {
        &dev_attr_period.attr,
@@ -245,9 +244,9 @@ static int pwm_unexport_child(struct device *parent, struct pwm_device *pwm)
        return 0;
 }
 
-static ssize_t pwm_export_store(struct device *parent,
-                               struct device_attribute *attr,
-                               const char *buf, size_t len)
+static ssize_t export_store(struct device *parent,
+                           struct device_attribute *attr,
+                           const char *buf, size_t len)
 {
        struct pwm_chip *chip = dev_get_drvdata(parent);
        struct pwm_device *pwm;
@@ -271,11 +270,11 @@ static ssize_t pwm_export_store(struct device *parent,
 
        return ret ? : len;
 }
-static DEVICE_ATTR(export, 0200, NULL, pwm_export_store);
+static DEVICE_ATTR_WO(export);
 
-static ssize_t pwm_unexport_store(struct device *parent,
-                                 struct device_attribute *attr,
-                                 const char *buf, size_t len)
+static ssize_t unexport_store(struct device *parent,
+                             struct device_attribute *attr,
+                             const char *buf, size_t len)
 {
        struct pwm_chip *chip = dev_get_drvdata(parent);
        unsigned int hwpwm;
@@ -292,7 +291,7 @@ static ssize_t pwm_unexport_store(struct device *parent,
 
        return ret ? : len;
 }
-static DEVICE_ATTR(unexport, 0200, NULL, pwm_unexport_store);
+static DEVICE_ATTR_WO(unexport);
 
 static ssize_t npwm_show(struct device *parent, struct device_attribute *attr,
                         char *buf)
index 548a18916a31ec11f5abf0fae9c3626755422d46..a831d18596a5ef592f88ec5af031f639606c8c0b 100644 (file)
@@ -1080,28 +1080,10 @@ void __init chsc_init_cleanup(void)
        free_page((unsigned long)sei_page);
 }
 
-int chsc_enable_facility(int operation_code)
+int __chsc_enable_facility(struct chsc_sda_area *sda_area, int operation_code)
 {
-       unsigned long flags;
        int ret;
-       struct {
-               struct chsc_header request;
-               u8 reserved1:4;
-               u8 format:4;
-               u8 reserved2;
-               u16 operation_code;
-               u32 reserved3;
-               u32 reserved4;
-               u32 operation_data_area[252];
-               struct chsc_header response;
-               u32 reserved5:4;
-               u32 format2:4;
-               u32 reserved6:24;
-       } __attribute__ ((packed)) *sda_area;
 
-       spin_lock_irqsave(&chsc_page_lock, flags);
-       memset(chsc_page, 0, PAGE_SIZE);
-       sda_area = chsc_page;
        sda_area->request.length = 0x0400;
        sda_area->request.code = 0x0031;
        sda_area->operation_code = operation_code;
@@ -1119,10 +1101,25 @@ int chsc_enable_facility(int operation_code)
        default:
                ret = chsc_error_from_response(sda_area->response.code);
        }
+out:
+       return ret;
+}
+
+int chsc_enable_facility(int operation_code)
+{
+       struct chsc_sda_area *sda_area;
+       unsigned long flags;
+       int ret;
+
+       spin_lock_irqsave(&chsc_page_lock, flags);
+       memset(chsc_page, 0, PAGE_SIZE);
+       sda_area = chsc_page;
+
+       ret = __chsc_enable_facility(sda_area, operation_code);
        if (ret != 0)
                CIO_CRW_EVENT(2, "chsc: sda (oc=%x) failed (rc=%04x)\n",
                              operation_code, sda_area->response.code);
-out:
+
        spin_unlock_irqrestore(&chsc_page_lock, flags);
        return ret;
 }
index 76c9b50700b24975842713560b4d4fce2e9ddba6..0de134c3a2044be8956a31fa01c142d581e3a792 100644 (file)
@@ -115,6 +115,20 @@ struct chsc_scpd {
        u8 data[PAGE_SIZE - 20];
 } __attribute__ ((packed));
 
+struct chsc_sda_area {
+       struct chsc_header request;
+       u8 :4;
+       u8 format:4;
+       u8 :8;
+       u16 operation_code;
+       u32 :32;
+       u32 :32;
+       u32 operation_data_area[252];
+       struct chsc_header response;
+       u32 :4;
+       u32 format2:4;
+       u32 :24;
+} __packed __aligned(PAGE_SIZE);
 
 extern int chsc_get_ssd_info(struct subchannel_id schid,
                             struct chsc_ssd_info *ssd);
@@ -122,6 +136,7 @@ extern int chsc_determine_css_characteristics(void);
 extern int chsc_init(void);
 extern void chsc_init_cleanup(void);
 
+int __chsc_enable_facility(struct chsc_sda_area *sda_area, int operation_code);
 extern int chsc_enable_facility(int);
 struct channel_subsystem;
 extern int chsc_secm(struct channel_subsystem *, int);
index b5620e818d6b91307c329cfe67f2de5ac4847ca5..690b8547e828deb81d94a2646459d2babc79dc24 100644 (file)
@@ -925,18 +925,32 @@ void reipl_ccw_dev(struct ccw_dev_id *devid)
 
 int __init cio_get_iplinfo(struct cio_iplinfo *iplinfo)
 {
+       static struct chsc_sda_area sda_area __initdata;
        struct subchannel_id schid;
        struct schib schib;
 
        schid = *(struct subchannel_id *)&S390_lowcore.subchannel_id;
        if (!schid.one)
                return -ENODEV;
+
+       if (schid.ssid) {
+               /*
+                * Firmware should have already enabled MSS but whoever started
+                * the kernel might have initiated a channel subsystem reset.
+                * Ensure that MSS is enabled.
+                */
+               memset(&sda_area, 0, sizeof(sda_area));
+               if (__chsc_enable_facility(&sda_area, CHSC_SDA_OC_MSS))
+                       return -ENODEV;
+       }
        if (stsch_err(schid, &schib))
                return -ENODEV;
        if (schib.pmcw.st != SUBCHANNEL_TYPE_IO)
                return -ENODEV;
        if (!schib.pmcw.dnv)
                return -ENODEV;
+
+       iplinfo->ssid = schid.ssid;
        iplinfo->devno = schib.pmcw.dev;
        iplinfo->is_qdio = schib.pmcw.qf;
        return 0;
index 2ee3053bdc124319abf79a91f3ba07eb66835524..489e703dc82d85b49d33990bd3d5c2b687d9eb0f 100644 (file)
@@ -702,17 +702,12 @@ css_generate_pgid(struct channel_subsystem *css, u32 tod_high)
                css->global_pgid.pgid_high.ext_cssid.version = 0x80;
                css->global_pgid.pgid_high.ext_cssid.cssid = css->cssid;
        } else {
-#ifdef CONFIG_SMP
                css->global_pgid.pgid_high.cpu_addr = stap();
-#else
-               css->global_pgid.pgid_high.cpu_addr = 0;
-#endif
        }
        get_cpu_id(&cpu_id);
        css->global_pgid.cpu_id = cpu_id.ident;
        css->global_pgid.cpu_model = cpu_id.machine;
        css->global_pgid.tod_high = tod_high;
-
 }
 
 static void
index 57f710b3c8a42862357d65653494f72d89580b32..b8ab18676e69a39d2077fa3b5ff7c192ed3d3fe9 100644 (file)
@@ -3,6 +3,9 @@
 #
 
 ap-objs := ap_bus.o
-obj-$(CONFIG_ZCRYPT) += ap.o zcrypt_api.o zcrypt_pcixcc.o
-obj-$(CONFIG_ZCRYPT) += zcrypt_cex2a.o zcrypt_cex4.o
+# zcrypt_api depends on ap
+obj-$(CONFIG_ZCRYPT) += ap.o zcrypt_api.o
+# msgtype* depend on zcrypt_api
 obj-$(CONFIG_ZCRYPT) += zcrypt_msgtype6.o zcrypt_msgtype50.o
+# adapter drivers depend on ap, zcrypt_api and msgtype*
+obj-$(CONFIG_ZCRYPT) += zcrypt_pcixcc.o zcrypt_cex2a.o zcrypt_cex4.o
index 9cb3dfbcaddbc491f537fc431471a16a98f50b69..61f768518a34b0e963cd6b569610045a3f65188b 100644 (file)
@@ -74,6 +74,7 @@ static struct device *ap_root_device = NULL;
 static struct ap_config_info *ap_configuration;
 static DEFINE_SPINLOCK(ap_device_list_lock);
 static LIST_HEAD(ap_device_list);
+static bool initialised;
 
 /*
  * Workqueue timer for bus rescan.
@@ -1384,6 +1385,9 @@ int ap_driver_register(struct ap_driver *ap_drv, struct module *owner,
 {
        struct device_driver *drv = &ap_drv->driver;
 
+       if (!initialised)
+               return -ENODEV;
+
        drv->bus = &ap_bus_type;
        drv->probe = ap_device_probe;
        drv->remove = ap_device_remove;
@@ -1808,6 +1812,7 @@ int __init ap_module_init(void)
                goto out_pm;
 
        queue_work(system_long_wq, &ap_scan_work);
+       initialised = true;
 
        return 0;
 
@@ -1837,6 +1842,7 @@ void ap_module_exit(void)
 {
        int i;
 
+       initialised = false;
        ap_reset_domain();
        ap_poll_thread_stop();
        del_timer_sync(&ap_config_timer);
index a9603ebbc1f8fdd6ca03eb9b4702d356648157b4..9f8fa42c062c22f59681f2e18026214d39a2b7c0 100644 (file)
@@ -317,11 +317,9 @@ EXPORT_SYMBOL(zcrypt_device_unregister);
 
 void zcrypt_msgtype_register(struct zcrypt_ops *zops)
 {
-       if (zops->owner) {
-               spin_lock_bh(&zcrypt_ops_list_lock);
-               list_add_tail(&zops->list, &zcrypt_ops_list);
-               spin_unlock_bh(&zcrypt_ops_list_lock);
-       }
+       spin_lock_bh(&zcrypt_ops_list_lock);
+       list_add_tail(&zops->list, &zcrypt_ops_list);
+       spin_unlock_bh(&zcrypt_ops_list_lock);
 }
 EXPORT_SYMBOL(zcrypt_msgtype_register);
 
@@ -342,7 +340,7 @@ struct zcrypt_ops *__ops_lookup(unsigned char *name, int variant)
        spin_lock_bh(&zcrypt_ops_list_lock);
        list_for_each_entry(zops, &zcrypt_ops_list, list) {
                if ((zops->variant == variant) &&
-                   (!strncmp(zops->owner->name, name, MODULE_NAME_LEN))) {
+                   (!strncmp(zops->name, name, sizeof(zops->name)))) {
                        found = 1;
                        break;
                }
index 750876891931627641131a59dfd58df2c4e8f8ce..38618f05ad924c340d324500d9d3b887798c7cd8 100644 (file)
@@ -96,6 +96,7 @@ struct zcrypt_ops {
        struct list_head list;          /* zcrypt ops list. */
        struct module *owner;
        int variant;
+       char name[128];
 };
 
 struct zcrypt_device {
index 71ceee9137a88919d8c53ca7148afff0a7211e95..74edf2934e7c9fd652c33d1d14bb47b9e2bf44b8 100644 (file)
@@ -513,6 +513,7 @@ static struct zcrypt_ops zcrypt_msgtype50_ops = {
        .rsa_modexpo = zcrypt_cex2a_modexpo,
        .rsa_modexpo_crt = zcrypt_cex2a_modexpo_crt,
        .owner = THIS_MODULE,
+       .name = MSGTYPE50_NAME,
        .variant = MSGTYPE50_VARIANT_DEFAULT,
 };
 
index 74762214193b0326a8ee2cb6d21141f3c414123b..9a2dd472c1cc9870d37e98c5692c1c9c1e0ebac3 100644 (file)
@@ -1119,6 +1119,7 @@ static long zcrypt_msgtype6_rng(struct zcrypt_device *zdev,
  */
 static struct zcrypt_ops zcrypt_msgtype6_norng_ops = {
        .owner = THIS_MODULE,
+       .name = MSGTYPE06_NAME,
        .variant = MSGTYPE06_VARIANT_NORNG,
        .rsa_modexpo = zcrypt_msgtype6_modexpo,
        .rsa_modexpo_crt = zcrypt_msgtype6_modexpo_crt,
@@ -1127,6 +1128,7 @@ static struct zcrypt_ops zcrypt_msgtype6_norng_ops = {
 
 static struct zcrypt_ops zcrypt_msgtype6_ops = {
        .owner = THIS_MODULE,
+       .name = MSGTYPE06_NAME,
        .variant = MSGTYPE06_VARIANT_DEFAULT,
        .rsa_modexpo = zcrypt_msgtype6_modexpo,
        .rsa_modexpo_crt = zcrypt_msgtype6_modexpo_crt,
@@ -1136,6 +1138,7 @@ static struct zcrypt_ops zcrypt_msgtype6_ops = {
 
 static struct zcrypt_ops zcrypt_msgtype6_ep11_ops = {
        .owner = THIS_MODULE,
+       .name = MSGTYPE06_NAME,
        .variant = MSGTYPE06_VARIANT_EP11,
        .rsa_modexpo = NULL,
        .rsa_modexpo_crt = NULL,
index a209c341889830127fa6ca5e72bde71d141432e7..d4c285688ce98b8222dcc778ee646f6581e48df3 100644 (file)
@@ -325,7 +325,6 @@ NCR_700_detect(struct scsi_host_template *tpnt,
        tpnt->slave_destroy = NCR_700_slave_destroy;
        tpnt->slave_alloc = NCR_700_slave_alloc;
        tpnt->change_queue_depth = NCR_700_change_queue_depth;
-       tpnt->use_blk_tags = 1;
 
        if(tpnt->name == NULL)
                tpnt->name = "53c700";
@@ -1107,7 +1106,9 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
                        BUG();
                }
                if(hostdata->msgin[1] == A_SIMPLE_TAG_MSG) {
-                       struct scsi_cmnd *SCp = scsi_find_tag(SDp, hostdata->msgin[2]);
+                       struct scsi_cmnd *SCp;
+
+                       SCp = scsi_host_find_tag(SDp->host, hostdata->msgin[2]);
                        if(unlikely(SCp == NULL)) {
                                printk(KERN_ERR "scsi%d: (%d:%d) no saved request for tag %d\n", 
                                       host->host_no, reselection_id, lun, hostdata->msgin[2]);
@@ -1119,7 +1120,9 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
                                "reselection is tag %d, slot %p(%d)\n",
                                hostdata->msgin[2], slot, slot->tag);
                } else {
-                       struct scsi_cmnd *SCp = scsi_find_tag(SDp, SCSI_NO_TAG);
+                       struct scsi_cmnd *SCp;
+
+                       SCp = scsi_host_find_tag(SDp->host, SCSI_NO_TAG);
                        if(unlikely(SCp == NULL)) {
                                sdev_printk(KERN_ERR, SDp,
                                        "no saved request for untagged cmd\n");
@@ -1823,7 +1826,7 @@ NCR_700_queuecommand_lck(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *)
                       slot->tag, slot);
        } else {
                slot->tag = SCSI_NO_TAG;
-               /* must populate current_cmnd for scsi_find_tag to work */
+               /* must populate current_cmnd for scsi_host_find_tag to work */
                SCp->device->current_cmnd = SCp;
        }
        /* sanity check: some of the commands generated by the mid-layer
index 5c74e4c52fe4448af1df385c29c594e50d15f9b7..867b864f50479033bd5e206de8bec23cd4a0a81a 100644 (file)
@@ -2136,7 +2136,7 @@ static unsigned char FPT_SccbMgr_bad_isr(u32 p_port, unsigned char p_card,
  *
  *---------------------------------------------------------------------*/
 
-static void FPT_SccbMgrTableInitAll()
+static void FPT_SccbMgrTableInitAll(void)
 {
        unsigned char thisCard;
 
index d2f480b04a52ed4f882fe3ca9b0b79113ef804a4..5f692ae4074959e019a74eb0c81405cb2869195c 100644 (file)
@@ -534,7 +534,6 @@ config SCSI_ARCMSR
 
 source "drivers/scsi/esas2r/Kconfig"
 source "drivers/scsi/megaraid/Kconfig.megaraid"
-source "drivers/scsi/mpt2sas/Kconfig"
 source "drivers/scsi/mpt3sas/Kconfig"
 source "drivers/scsi/ufs/Kconfig"
 
index 1a8c9b53fafad5900ef775599a7f34abd34978eb..c14bca4a9675c1d1ce29d759354cd8a835bdf98d 100644 (file)
@@ -106,7 +106,6 @@ obj-$(CONFIG_CXLFLASH)              += cxlflash/
 obj-$(CONFIG_MEGARAID_LEGACY)  += megaraid.o
 obj-$(CONFIG_MEGARAID_NEWGEN)  += megaraid/
 obj-$(CONFIG_MEGARAID_SAS)     += megaraid/
-obj-$(CONFIG_SCSI_MPT2SAS)     += mpt2sas/
 obj-$(CONFIG_SCSI_MPT3SAS)     += mpt3sas/
 obj-$(CONFIG_SCSI_UFSHCD)      += ufs/
 obj-$(CONFIG_SCSI_ACARD)       += atp870u.o
index 9b3dd6ef6a0b75794480beedcbaa44965a81bd76..e4c243748a97f97d2fa16b1b2ee6622e83b3905e 100644 (file)
@@ -259,7 +259,7 @@ MODULE_PARM_DESC(commit, "Control whether a COMMIT_CONFIG is issued to the"
        " 0=off, 1=on");
 module_param_named(msi, aac_msi, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(msi, "IRQ handling."
-       " 0=PIC(default), 1=MSI, 2=MSI-X(unsupported, uses MSI)");
+       " 0=PIC(default), 1=MSI, 2=MSI-X)");
 module_param(startup_timeout, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(startup_timeout, "The duration of time in seconds to wait for"
        " adapter to have it's kernel up and\n"
@@ -570,7 +570,7 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd)
 
        status = aac_fib_send(ContainerCommand,
                  cmd_fibcontext,
-                 sizeof (struct aac_get_name),
+                 sizeof(struct aac_get_name_resp),
                  FsaNormal,
                  0, 1,
                  (fib_callback)get_container_name_callback,
@@ -1052,7 +1052,7 @@ static int aac_get_container_serial(struct scsi_cmnd * scsicmd)
 
        status = aac_fib_send(ContainerCommand,
                  cmd_fibcontext,
-                 sizeof (struct aac_get_serial),
+                 sizeof(struct aac_get_serial_resp),
                  FsaNormal,
                  0, 1,
                  (fib_callback) get_container_serial_callback,
@@ -2977,11 +2977,16 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
                return;
 
        BUG_ON(fibptr == NULL);
-
        dev = fibptr->dev;
 
-       srbreply = (struct aac_srb_reply *) fib_data(fibptr);
+       scsi_dma_unmap(scsicmd);
 
+       /* expose physical device if expose_physicald flag is on */
+       if (scsicmd->cmnd[0] == INQUIRY && !(scsicmd->cmnd[1] & 0x01)
+         && expose_physicals > 0)
+               aac_expose_phy_device(scsicmd);
+
+       srbreply = (struct aac_srb_reply *) fib_data(fibptr);
        scsicmd->sense_buffer[0] = '\0';  /* Initialize sense valid flag to false */
 
        if (fibptr->flags & FIB_CONTEXT_FLAG_FASTRESP) {
@@ -2994,147 +2999,157 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
                 */
                scsi_set_resid(scsicmd, scsi_bufflen(scsicmd)
                                   - le32_to_cpu(srbreply->data_xfer_length));
-       }
-
-       scsi_dma_unmap(scsicmd);
-
-       /* expose physical device if expose_physicald flag is on */
-       if (scsicmd->cmnd[0] == INQUIRY && !(scsicmd->cmnd[1] & 0x01)
-         && expose_physicals > 0)
-               aac_expose_phy_device(scsicmd);
+               /*
+                * First check the fib status
+                */
 
-       /*
-        * First check the fib status
-        */
+               if (le32_to_cpu(srbreply->status) != ST_OK) {
+                       int len;
 
-       if (le32_to_cpu(srbreply->status) != ST_OK){
-               int len;
-               printk(KERN_WARNING "aac_srb_callback: srb failed, status = %d\n", le32_to_cpu(srbreply->status));
-               len = min_t(u32, le32_to_cpu(srbreply->sense_data_size),
-                           SCSI_SENSE_BUFFERSIZE);
-               scsicmd->result = DID_ERROR << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
-               memcpy(scsicmd->sense_buffer, srbreply->sense_data, len);
-       }
+                       printk(KERN_WARNING "aac_srb_callback: srb failed, status = %d\n", le32_to_cpu(srbreply->status));
+                       len = min_t(u32, le32_to_cpu(srbreply->sense_data_size),
+                                   SCSI_SENSE_BUFFERSIZE);
+                       scsicmd->result = DID_ERROR << 16
+                                               | COMMAND_COMPLETE << 8
+                                               | SAM_STAT_CHECK_CONDITION;
+                       memcpy(scsicmd->sense_buffer,
+                                       srbreply->sense_data, len);
+               }
 
-       /*
-        * Next check the srb status
-        */
-       switch( (le32_to_cpu(srbreply->srb_status))&0x3f){
-       case SRB_STATUS_ERROR_RECOVERY:
-       case SRB_STATUS_PENDING:
-       case SRB_STATUS_SUCCESS:
-               scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
-               break;
-       case SRB_STATUS_DATA_OVERRUN:
-               switch(scsicmd->cmnd[0]){
-               case  READ_6:
-               case  WRITE_6:
-               case  READ_10:
-               case  WRITE_10:
-               case  READ_12:
-               case  WRITE_12:
-               case  READ_16:
-               case  WRITE_16:
-                       if (le32_to_cpu(srbreply->data_xfer_length) < scsicmd->underflow) {
-                               printk(KERN_WARNING"aacraid: SCSI CMD underflow\n");
-                       } else {
-                               printk(KERN_WARNING"aacraid: SCSI CMD Data Overrun\n");
+               /*
+                * Next check the srb status
+                */
+               switch ((le32_to_cpu(srbreply->srb_status))&0x3f) {
+               case SRB_STATUS_ERROR_RECOVERY:
+               case SRB_STATUS_PENDING:
+               case SRB_STATUS_SUCCESS:
+                       scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
+                       break;
+               case SRB_STATUS_DATA_OVERRUN:
+                       switch (scsicmd->cmnd[0]) {
+                       case  READ_6:
+                       case  WRITE_6:
+                       case  READ_10:
+                       case  WRITE_10:
+                       case  READ_12:
+                       case  WRITE_12:
+                       case  READ_16:
+                       case  WRITE_16:
+                               if (le32_to_cpu(srbreply->data_xfer_length)
+                                                       < scsicmd->underflow)
+                                       printk(KERN_WARNING"aacraid: SCSI CMD underflow\n");
+                               else
+                                       printk(KERN_WARNING"aacraid: SCSI CMD Data Overrun\n");
+                               scsicmd->result = DID_ERROR << 16
+                                                       | COMMAND_COMPLETE << 8;
+                               break;
+                       case INQUIRY: {
+                               scsicmd->result = DID_OK << 16
+                                                       | COMMAND_COMPLETE << 8;
+                               break;
+                       }
+                       default:
+                               scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
+                               break;
                        }
-                       scsicmd->result = DID_ERROR << 16 | COMMAND_COMPLETE << 8;
                        break;
-               case INQUIRY: {
-                       scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
+               case SRB_STATUS_ABORTED:
+                       scsicmd->result = DID_ABORT << 16 | ABORT << 8;
                        break;
-               }
-               default:
-                       scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
+               case SRB_STATUS_ABORT_FAILED:
+                       /*
+                        * Not sure about this one - but assuming the
+                        * hba was trying to abort for some reason
+                        */
+                       scsicmd->result = DID_ERROR << 16 | ABORT << 8;
+                       break;
+               case SRB_STATUS_PARITY_ERROR:
+                       scsicmd->result = DID_PARITY << 16
+                                               | MSG_PARITY_ERROR << 8;
+                       break;
+               case SRB_STATUS_NO_DEVICE:
+               case SRB_STATUS_INVALID_PATH_ID:
+               case SRB_STATUS_INVALID_TARGET_ID:
+               case SRB_STATUS_INVALID_LUN:
+               case SRB_STATUS_SELECTION_TIMEOUT:
+                       scsicmd->result = DID_NO_CONNECT << 16
+                                               | COMMAND_COMPLETE << 8;
                        break;
-               }
-               break;
-       case SRB_STATUS_ABORTED:
-               scsicmd->result = DID_ABORT << 16 | ABORT << 8;
-               break;
-       case SRB_STATUS_ABORT_FAILED:
-               // Not sure about this one - but assuming the hba was trying to abort for some reason
-               scsicmd->result = DID_ERROR << 16 | ABORT << 8;
-               break;
-       case SRB_STATUS_PARITY_ERROR:
-               scsicmd->result = DID_PARITY << 16 | MSG_PARITY_ERROR << 8;
-               break;
-       case SRB_STATUS_NO_DEVICE:
-       case SRB_STATUS_INVALID_PATH_ID:
-       case SRB_STATUS_INVALID_TARGET_ID:
-       case SRB_STATUS_INVALID_LUN:
-       case SRB_STATUS_SELECTION_TIMEOUT:
-               scsicmd->result = DID_NO_CONNECT << 16 | COMMAND_COMPLETE << 8;
-               break;
 
-       case SRB_STATUS_COMMAND_TIMEOUT:
-       case SRB_STATUS_TIMEOUT:
-               scsicmd->result = DID_TIME_OUT << 16 | COMMAND_COMPLETE << 8;
-               break;
+               case SRB_STATUS_COMMAND_TIMEOUT:
+               case SRB_STATUS_TIMEOUT:
+                       scsicmd->result = DID_TIME_OUT << 16
+                                               | COMMAND_COMPLETE << 8;
+                       break;
 
-       case SRB_STATUS_BUSY:
-               scsicmd->result = DID_BUS_BUSY << 16 | COMMAND_COMPLETE << 8;
-               break;
+               case SRB_STATUS_BUSY:
+                       scsicmd->result = DID_BUS_BUSY << 16
+                                               | COMMAND_COMPLETE << 8;
+                       break;
 
-       case SRB_STATUS_BUS_RESET:
-               scsicmd->result = DID_RESET << 16 | COMMAND_COMPLETE << 8;
-               break;
+               case SRB_STATUS_BUS_RESET:
+                       scsicmd->result = DID_RESET << 16
+                                               | COMMAND_COMPLETE << 8;
+                       break;
 
-       case SRB_STATUS_MESSAGE_REJECTED:
-               scsicmd->result = DID_ERROR << 16 | MESSAGE_REJECT << 8;
-               break;
-       case SRB_STATUS_REQUEST_FLUSHED:
-       case SRB_STATUS_ERROR:
-       case SRB_STATUS_INVALID_REQUEST:
-       case SRB_STATUS_REQUEST_SENSE_FAILED:
-       case SRB_STATUS_NO_HBA:
-       case SRB_STATUS_UNEXPECTED_BUS_FREE:
-       case SRB_STATUS_PHASE_SEQUENCE_FAILURE:
-       case SRB_STATUS_BAD_SRB_BLOCK_LENGTH:
-       case SRB_STATUS_DELAYED_RETRY:
-       case SRB_STATUS_BAD_FUNCTION:
-       case SRB_STATUS_NOT_STARTED:
-       case SRB_STATUS_NOT_IN_USE:
-       case SRB_STATUS_FORCE_ABORT:
-       case SRB_STATUS_DOMAIN_VALIDATION_FAIL:
-       default:
+               case SRB_STATUS_MESSAGE_REJECTED:
+                       scsicmd->result = DID_ERROR << 16
+                                               | MESSAGE_REJECT << 8;
+                       break;
+               case SRB_STATUS_REQUEST_FLUSHED:
+               case SRB_STATUS_ERROR:
+               case SRB_STATUS_INVALID_REQUEST:
+               case SRB_STATUS_REQUEST_SENSE_FAILED:
+               case SRB_STATUS_NO_HBA:
+               case SRB_STATUS_UNEXPECTED_BUS_FREE:
+               case SRB_STATUS_PHASE_SEQUENCE_FAILURE:
+               case SRB_STATUS_BAD_SRB_BLOCK_LENGTH:
+               case SRB_STATUS_DELAYED_RETRY:
+               case SRB_STATUS_BAD_FUNCTION:
+               case SRB_STATUS_NOT_STARTED:
+               case SRB_STATUS_NOT_IN_USE:
+               case SRB_STATUS_FORCE_ABORT:
+               case SRB_STATUS_DOMAIN_VALIDATION_FAIL:
+               default:
 #ifdef AAC_DETAILED_STATUS_INFO
-               printk("aacraid: SRB ERROR(%u) %s scsi cmd 0x%x - scsi status 0x%x\n",
-                       le32_to_cpu(srbreply->srb_status) & 0x3F,
-                       aac_get_status_string(
-                               le32_to_cpu(srbreply->srb_status) & 0x3F),
-                       scsicmd->cmnd[0],
-                       le32_to_cpu(srbreply->scsi_status));
+                       printk(KERN_INFO "aacraid: SRB ERROR(%u) %s scsi cmd 0x%x - scsi status 0x%x\n",
+                               le32_to_cpu(srbreply->srb_status) & 0x3F,
+                               aac_get_status_string(
+                                       le32_to_cpu(srbreply->srb_status) & 0x3F),
+                               scsicmd->cmnd[0],
+                               le32_to_cpu(srbreply->scsi_status));
 #endif
-               if ((scsicmd->cmnd[0] == ATA_12)
-                 || (scsicmd->cmnd[0] == ATA_16)) {
-                       if (scsicmd->cmnd[2] & (0x01 << 5)) {
-                               scsicmd->result = DID_OK << 16
-                                               | COMMAND_COMPLETE << 8;
+                       if ((scsicmd->cmnd[0] == ATA_12)
+                               || (scsicmd->cmnd[0] == ATA_16)) {
+                                       if (scsicmd->cmnd[2] & (0x01 << 5)) {
+                                               scsicmd->result = DID_OK << 16
+                                                       | COMMAND_COMPLETE << 8;
                                break;
+                               } else {
+                                       scsicmd->result = DID_ERROR << 16
+                                               | COMMAND_COMPLETE << 8;
+                                       break;
+                               }
                        } else {
                                scsicmd->result = DID_ERROR << 16
-                                               | COMMAND_COMPLETE << 8;
+                                       | COMMAND_COMPLETE << 8;
                                break;
                        }
-               } else {
-                       scsicmd->result = DID_ERROR << 16
-                                       | COMMAND_COMPLETE << 8;
-                       break;
                }
-       }
-       if (le32_to_cpu(srbreply->scsi_status) == SAM_STAT_CHECK_CONDITION) {
-               int len;
-               scsicmd->result |= SAM_STAT_CHECK_CONDITION;
-               len = min_t(u32, le32_to_cpu(srbreply->sense_data_size),
-                           SCSI_SENSE_BUFFERSIZE);
+               if (le32_to_cpu(srbreply->scsi_status)
+                               == SAM_STAT_CHECK_CONDITION) {
+                       int len;
+
+                       scsicmd->result |= SAM_STAT_CHECK_CONDITION;
+                       len = min_t(u32, le32_to_cpu(srbreply->sense_data_size),
+                                   SCSI_SENSE_BUFFERSIZE);
 #ifdef AAC_DETAILED_STATUS_INFO
-               printk(KERN_WARNING "aac_srb_callback: check condition, status = %d len=%d\n",
-                                       le32_to_cpu(srbreply->status), len);
+                       printk(KERN_WARNING "aac_srb_callback: check condition, status = %d len=%d\n",
+                                               le32_to_cpu(srbreply->status), len);
 #endif
-               memcpy(scsicmd->sense_buffer, srbreply->sense_data, len);
+                       memcpy(scsicmd->sense_buffer,
+                                       srbreply->sense_data, len);
+               }
        }
        /*
         * OR in the scsi status (already shifted up a bit)
index 40fe65c91b416d1d8781b163e18299db5d76a13f..074878b55a0b7d9f371fe5bc57b2714e01074fdb 100644 (file)
@@ -12,7 +12,7 @@
  *              D E F I N E S
  *----------------------------------------------------------------------------*/
 
-#define AAC_MAX_MSIX                 /* vectors */
+#define AAC_MAX_MSIX           32      /* vectors */
 #define AAC_PCI_MSI_ENABLE     0x8000
 
 enum {
@@ -62,7 +62,7 @@ enum {
 #define        PMC_GLOBAL_INT_BIT0             0x00000001
 
 #ifndef AAC_DRIVER_BUILD
-# define AAC_DRIVER_BUILD 40709
+# define AAC_DRIVER_BUILD 41010
 # define AAC_DRIVER_BRANCH "-ms"
 #endif
 #define MAXIMUM_NUM_CONTAINERS 32
@@ -547,6 +547,7 @@ struct adapter_ops
        int  (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4);
        int  (*adapter_check_health)(struct aac_dev *dev);
        int  (*adapter_restart)(struct aac_dev *dev, int bled);
+       void (*adapter_start)(struct aac_dev *dev);
        /* Transport operations */
        int  (*adapter_ioremap)(struct aac_dev * dev, u32 size);
        irq_handler_t adapter_intr;
@@ -843,6 +844,10 @@ struct src_registers {
                                                &((AEP)->regs.src.bar0->CSR))
 #define src_writel(AEP, CSR, value)    writel(value, \
                                                &((AEP)->regs.src.bar0->CSR))
+#if defined(writeq)
+#define        src_writeq(AEP, CSR, value)     writeq(value, \
+                                               &((AEP)->regs.src.bar0->CSR))
+#endif
 
 #define SRC_ODR_SHIFT          12
 #define SRC_IDR_SHIFT          9
@@ -1162,6 +1167,11 @@ struct aac_dev
        struct fsa_dev_info     *fsa_dev;
        struct task_struct      *thread;
        int                     cardtype;
+       /*
+        *This lock will protect the two 32-bit
+        *writes to the Inbound Queue
+        */
+       spinlock_t              iq_lock;
 
        /*
         *      The following is the device specific extension.
@@ -1247,6 +1257,9 @@ struct aac_dev
 #define aac_adapter_restart(dev,bled) \
        (dev)->a_ops.adapter_restart(dev,bled)
 
+#define aac_adapter_start(dev) \
+       ((dev)->a_ops.adapter_start(dev))
+
 #define aac_adapter_ioremap(dev, size) \
        (dev)->a_ops.adapter_ioremap(dev, size)
 
@@ -2097,6 +2110,8 @@ static inline unsigned int cap_to_cyls(sector_t capacity, unsigned divisor)
 #define AAC_OWNER_ERROR_HANDLER        0x103
 #define AAC_OWNER_FIRMWARE     0x106
 
+int aac_acquire_irq(struct aac_dev *dev);
+void aac_free_irq(struct aac_dev *dev);
 const char *aac_driverinfo(struct Scsi_Host *);
 struct fib *aac_fib_alloc(struct aac_dev *dev);
 int aac_fib_setup(struct aac_dev *dev);
@@ -2127,6 +2142,7 @@ int aac_sa_init(struct aac_dev *dev);
 int aac_src_init(struct aac_dev *dev);
 int aac_srcv_init(struct aac_dev *dev);
 int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw_fib, int wait, struct fib * fibptr, unsigned long *nonotify);
+void aac_define_int_mode(struct aac_dev *dev);
 unsigned int aac_response_normal(struct aac_queue * q);
 unsigned int aac_command_normal(struct aac_queue * q);
 unsigned int aac_intr_normal(struct aac_dev *dev, u32 Index,
index 45db84ad322f20de892a16e675acd3da6b8cbe84..0e954e37f0b5f3923980ee684e55ffef5b296510 100644 (file)
@@ -43,8 +43,6 @@
 
 #include "aacraid.h"
 
-static void aac_define_int_mode(struct aac_dev *dev);
-
 struct aac_common aac_config = {
        .irq_mod = 1
 };
@@ -338,6 +336,74 @@ static int aac_comm_init(struct aac_dev * dev)
        return 0;
 }
 
+void aac_define_int_mode(struct aac_dev *dev)
+{
+       int i, msi_count, min_msix;
+
+       msi_count = i = 0;
+       /* max. vectors from GET_COMM_PREFERRED_SETTINGS */
+       if (dev->max_msix == 0 ||
+           dev->pdev->device == PMC_DEVICE_S6 ||
+           dev->sync_mode) {
+               dev->max_msix = 1;
+               dev->vector_cap =
+                       dev->scsi_host_ptr->can_queue +
+                       AAC_NUM_MGT_FIB;
+               return;
+       }
+
+       /* Don't bother allocating more MSI-X vectors than cpus */
+       msi_count = min(dev->max_msix,
+               (unsigned int)num_online_cpus());
+
+       dev->max_msix = msi_count;
+
+       if (msi_count > AAC_MAX_MSIX)
+               msi_count = AAC_MAX_MSIX;
+
+       for (i = 0; i < msi_count; i++)
+               dev->msixentry[i].entry = i;
+
+       if (msi_count > 1 &&
+           pci_find_capability(dev->pdev, PCI_CAP_ID_MSIX)) {
+               min_msix = 2;
+               i = pci_enable_msix_range(dev->pdev,
+                                   dev->msixentry,
+                                   min_msix,
+                                   msi_count);
+               if (i > 0) {
+                       dev->msi_enabled = 1;
+                       msi_count = i;
+               } else {
+                       dev->msi_enabled = 0;
+                       printk(KERN_ERR "%s%d: MSIX not supported!! Will try MSI 0x%x.\n",
+                                       dev->name, dev->id, i);
+               }
+       }
+
+       if (!dev->msi_enabled) {
+               msi_count = 1;
+               i = pci_enable_msi(dev->pdev);
+
+               if (!i) {
+                       dev->msi_enabled = 1;
+                       dev->msi = 1;
+               } else {
+                       printk(KERN_ERR "%s%d: MSI not supported!! Will try INTx 0x%x.\n",
+                                       dev->name, dev->id, i);
+               }
+       }
+
+       if (!dev->msi_enabled)
+               dev->max_msix = msi_count = 1;
+       else {
+               if (dev->max_msix > msi_count)
+                       dev->max_msix = msi_count;
+       }
+       dev->vector_cap =
+               (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB) /
+               msi_count;
+}
 struct aac_dev *aac_init_adapter(struct aac_dev *dev)
 {
        u32 status[5];
@@ -350,6 +416,7 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
        dev->management_fib_count = 0;
        spin_lock_init(&dev->manage_lock);
        spin_lock_init(&dev->sync_lock);
+       spin_lock_init(&dev->iq_lock);
        dev->max_fib_size = sizeof(struct hw_fib);
        dev->sg_tablesize = host->sg_tablesize = (dev->max_fib_size
                - sizeof(struct aac_fibhdr)
@@ -508,79 +575,3 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
        return dev;
 }
 
-static void aac_define_int_mode(struct aac_dev *dev)
-{
-
-       int i, msi_count;
-
-       msi_count = i = 0;
-       /* max. vectors from GET_COMM_PREFERRED_SETTINGS */
-       if (dev->max_msix == 0 ||
-           dev->pdev->device == PMC_DEVICE_S6 ||
-           dev->sync_mode) {
-               dev->max_msix = 1;
-               dev->vector_cap =
-                       dev->scsi_host_ptr->can_queue +
-                       AAC_NUM_MGT_FIB;
-               return;
-       }
-
-       msi_count = min(dev->max_msix,
-               (unsigned int)num_online_cpus());
-
-       dev->max_msix = msi_count;
-
-       if (msi_count > AAC_MAX_MSIX)
-               msi_count = AAC_MAX_MSIX;
-
-       for (i = 0; i < msi_count; i++)
-               dev->msixentry[i].entry = i;
-
-       if (msi_count > 1 &&
-           pci_find_capability(dev->pdev, PCI_CAP_ID_MSIX)) {
-               i = pci_enable_msix(dev->pdev,
-                                   dev->msixentry,
-                                   msi_count);
-                /* Check how many MSIX vectors are allocated */
-               if (i >= 0) {
-                       dev->msi_enabled = 1;
-                       if (i) {
-                               msi_count = i;
-                               if (pci_enable_msix(dev->pdev,
-                                   dev->msixentry,
-                                   msi_count)) {
-                                       dev->msi_enabled = 0;
-                                       printk(KERN_ERR "%s%d: MSIX not supported!! Will try MSI 0x%x.\n",
-                                                       dev->name, dev->id, i);
-                               }
-                       }
-               } else {
-                       dev->msi_enabled = 0;
-                       printk(KERN_ERR "%s%d: MSIX not supported!! Will try MSI 0x%x.\n",
-                                       dev->name, dev->id, i);
-               }
-       }
-
-       if (!dev->msi_enabled) {
-               msi_count = 1;
-               i = pci_enable_msi(dev->pdev);
-
-               if (!i) {
-                       dev->msi_enabled = 1;
-                       dev->msi = 1;
-               } else {
-                       printk(KERN_ERR "%s%d: MSI not supported!! Will try INTx 0x%x.\n",
-                                       dev->name, dev->id, i);
-               }
-       }
-
-       if (!dev->msi_enabled)
-               dev->max_msix = msi_count = 1;
-       else {
-               if (dev->max_msix > msi_count)
-                       dev->max_msix = msi_count;
-       }
-       dev->vector_cap =
-               (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB) /
-               msi_count;
-}
index 4da574925284454cdba9cd6d6cc036bffc3dcdea..a1f90fe849c95201f410972b34413f45e484802e 100644 (file)
@@ -1270,13 +1270,12 @@ retry_next:
 static int _aac_reset_adapter(struct aac_dev *aac, int forced)
 {
        int index, quirks;
-       int retval, i;
+       int retval;
        struct Scsi_Host *host;
        struct scsi_device *dev;
        struct scsi_cmnd *command;
        struct scsi_cmnd *command_list;
        int jafo = 0;
-       int cpu;
 
        /*
         * Assumptions:
@@ -1339,35 +1338,7 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced)
        aac->comm_phys = 0;
        kfree(aac->queues);
        aac->queues = NULL;
-       cpu = cpumask_first(cpu_online_mask);
-       if (aac->pdev->device == PMC_DEVICE_S6 ||
-           aac->pdev->device == PMC_DEVICE_S7 ||
-           aac->pdev->device == PMC_DEVICE_S8 ||
-           aac->pdev->device == PMC_DEVICE_S9) {
-               if (aac->max_msix > 1) {
-                       for (i = 0; i < aac->max_msix; i++) {
-                               if (irq_set_affinity_hint(
-                                   aac->msixentry[i].vector,
-                                   NULL)) {
-                                       printk(KERN_ERR "%s%d: Failed to reset IRQ affinity for cpu %d\n",
-                                               aac->name,
-                                               aac->id,
-                                               cpu);
-                               }
-                               cpu = cpumask_next(cpu,
-                                               cpu_online_mask);
-                               free_irq(aac->msixentry[i].vector,
-                                        &(aac->aac_msix[i]));
-                       }
-                       pci_disable_msix(aac->pdev);
-               } else {
-                       free_irq(aac->pdev->irq, &(aac->aac_msix[0]));
-               }
-       } else {
-               free_irq(aac->pdev->irq, aac);
-       }
-       if (aac->msi)
-               pci_disable_msi(aac->pdev);
+       aac_free_irq(aac);
        kfree(aac->fsa_dev);
        aac->fsa_dev = NULL;
        quirks = aac_get_driver_ident(index)->quirks;
@@ -1978,3 +1949,83 @@ int aac_command_thread(void *data)
        dev->aif_thread = 0;
        return 0;
 }
+
+int aac_acquire_irq(struct aac_dev *dev)
+{
+       int i;
+       int j;
+       int ret = 0;
+       int cpu;
+
+       cpu = cpumask_first(cpu_online_mask);
+       if (!dev->sync_mode && dev->msi_enabled && dev->max_msix > 1) {
+               for (i = 0; i < dev->max_msix; i++) {
+                       dev->aac_msix[i].vector_no = i;
+                       dev->aac_msix[i].dev = dev;
+                       if (request_irq(dev->msixentry[i].vector,
+                                       dev->a_ops.adapter_intr,
+                                       0, "aacraid", &(dev->aac_msix[i]))) {
+                               printk(KERN_ERR "%s%d: Failed to register IRQ for vector %d.\n",
+                                               dev->name, dev->id, i);
+                               for (j = 0 ; j < i ; j++)
+                                       free_irq(dev->msixentry[j].vector,
+                                                &(dev->aac_msix[j]));
+                               pci_disable_msix(dev->pdev);
+                               ret = -1;
+                       }
+                       if (irq_set_affinity_hint(dev->msixentry[i].vector,
+                                                       get_cpu_mask(cpu))) {
+                               printk(KERN_ERR "%s%d: Failed to set IRQ affinity for cpu %d\n",
+                                           dev->name, dev->id, cpu);
+                       }
+                       cpu = cpumask_next(cpu, cpu_online_mask);
+               }
+       } else {
+               dev->aac_msix[0].vector_no = 0;
+               dev->aac_msix[0].dev = dev;
+
+               if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
+                       IRQF_SHARED, "aacraid",
+                       &(dev->aac_msix[0])) < 0) {
+                       if (dev->msi)
+                               pci_disable_msi(dev->pdev);
+                       printk(KERN_ERR "%s%d: Interrupt unavailable.\n",
+                                       dev->name, dev->id);
+                       ret = -1;
+               }
+       }
+       return ret;
+}
+
+void aac_free_irq(struct aac_dev *dev)
+{
+       int i;
+       int cpu;
+
+       cpu = cpumask_first(cpu_online_mask);
+       if (dev->pdev->device == PMC_DEVICE_S6 ||
+           dev->pdev->device == PMC_DEVICE_S7 ||
+           dev->pdev->device == PMC_DEVICE_S8 ||
+           dev->pdev->device == PMC_DEVICE_S9) {
+               if (dev->max_msix > 1) {
+                       for (i = 0; i < dev->max_msix; i++) {
+                               if (irq_set_affinity_hint(
+                                       dev->msixentry[i].vector, NULL)) {
+                                       printk(KERN_ERR "%s%d: Failed to reset IRQ affinity for cpu %d\n",
+                                           dev->name, dev->id, cpu);
+                               }
+                               cpu = cpumask_next(cpu, cpu_online_mask);
+                               free_irq(dev->msixentry[i].vector,
+                                               &(dev->aac_msix[i]));
+                       }
+               } else {
+                       free_irq(dev->pdev->irq, &(dev->aac_msix[0]));
+               }
+       } else {
+               free_irq(dev->pdev->irq, dev);
+       }
+       if (dev->msi)
+               pci_disable_msi(dev->pdev);
+       else if (dev->max_msix > 1)
+               pci_disable_msix(dev->pdev);
+}
index 9eec02733c8656e818efa8574652859e65ebad94..3b6e5c67e853d96aeafeee16859d19bfa3731a5b 100644 (file)
@@ -1317,6 +1317,154 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        return error;
 }
 
+#if (defined(CONFIG_PM))
+void aac_release_resources(struct aac_dev *aac)
+{
+       int i;
+
+       aac_adapter_disable_int(aac);
+       if (aac->pdev->device == PMC_DEVICE_S6 ||
+           aac->pdev->device == PMC_DEVICE_S7 ||
+           aac->pdev->device == PMC_DEVICE_S8 ||
+           aac->pdev->device == PMC_DEVICE_S9) {
+               if (aac->max_msix > 1) {
+                       for (i = 0; i < aac->max_msix; i++)
+                               free_irq(aac->msixentry[i].vector,
+                                       &(aac->aac_msix[i]));
+               } else {
+                       free_irq(aac->pdev->irq, &(aac->aac_msix[0]));
+               }
+       } else {
+               free_irq(aac->pdev->irq, aac);
+       }
+       if (aac->msi)
+               pci_disable_msi(aac->pdev);
+       else if (aac->max_msix > 1)
+               pci_disable_msix(aac->pdev);
+
+}
+
+static int aac_acquire_resources(struct aac_dev *dev)
+{
+       int i, j;
+       int instance = dev->id;
+       const char *name = dev->name;
+       unsigned long status;
+       /*
+        *      First clear out all interrupts.  Then enable the one's that we
+        *      can handle.
+        */
+       while (!((status = src_readl(dev, MUnit.OMR)) & KERNEL_UP_AND_RUNNING)
+               || status == 0xffffffff)
+                       msleep(20);
+
+       aac_adapter_disable_int(dev);
+       aac_adapter_enable_int(dev);
+
+
+       if ((dev->pdev->device == PMC_DEVICE_S7 ||
+            dev->pdev->device == PMC_DEVICE_S8 ||
+            dev->pdev->device == PMC_DEVICE_S9))
+               aac_define_int_mode(dev);
+
+       if (dev->msi_enabled)
+               aac_src_access_devreg(dev, AAC_ENABLE_MSIX);
+
+       if (!dev->sync_mode && dev->msi_enabled && dev->max_msix > 1) {
+               for (i = 0; i < dev->max_msix; i++) {
+                       dev->aac_msix[i].vector_no = i;
+                       dev->aac_msix[i].dev = dev;
+
+                       if (request_irq(dev->msixentry[i].vector,
+                                       dev->a_ops.adapter_intr,
+                                       0, "aacraid", &(dev->aac_msix[i]))) {
+                               printk(KERN_ERR "%s%d: Failed to register IRQ for vector %d.\n",
+                                               name, instance, i);
+                               for (j = 0 ; j < i ; j++)
+                                       free_irq(dev->msixentry[j].vector,
+                                                &(dev->aac_msix[j]));
+                               pci_disable_msix(dev->pdev);
+                               goto error_iounmap;
+                       }
+               }
+       } else {
+               dev->aac_msix[0].vector_no = 0;
+               dev->aac_msix[0].dev = dev;
+
+               if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
+                       IRQF_SHARED, "aacraid",
+                       &(dev->aac_msix[0])) < 0) {
+                       if (dev->msi)
+                               pci_disable_msi(dev->pdev);
+                       printk(KERN_ERR "%s%d: Interrupt unavailable.\n",
+                                       name, instance);
+                       goto error_iounmap;
+               }
+       }
+
+       aac_adapter_enable_int(dev);
+
+       if (!dev->sync_mode)
+               aac_adapter_start(dev);
+       return 0;
+
+error_iounmap:
+       return -1;
+
+}
+static int aac_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+
+       struct Scsi_Host *shost = pci_get_drvdata(pdev);
+       struct aac_dev *aac = (struct aac_dev *)shost->hostdata;
+
+       scsi_block_requests(shost);
+       aac_send_shutdown(aac);
+
+       aac_release_resources(aac);
+
+       pci_set_drvdata(pdev, shost);
+       pci_save_state(pdev);
+       pci_disable_device(pdev);
+       pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+       return 0;
+}
+
+static int aac_resume(struct pci_dev *pdev)
+{
+       struct Scsi_Host *shost = pci_get_drvdata(pdev);
+       struct aac_dev *aac = (struct aac_dev *)shost->hostdata;
+       int r;
+
+       pci_set_power_state(pdev, PCI_D0);
+       pci_enable_wake(pdev, PCI_D0, 0);
+       pci_restore_state(pdev);
+       r = pci_enable_device(pdev);
+
+       if (r)
+               goto fail_device;
+
+       pci_set_master(pdev);
+       if (aac_acquire_resources(aac))
+               goto fail_device;
+       /*
+       * reset this flag to unblock ioctl() as it was set at
+       * aac_send_shutdown() to block ioctls from upperlayer
+       */
+       aac->adapter_shutdown = 0;
+       scsi_unblock_requests(shost);
+
+       return 0;
+
+fail_device:
+       printk(KERN_INFO "%s%d: resume failed.\n", aac->name, aac->id);
+       scsi_host_put(shost);
+       pci_disable_device(pdev);
+       return -ENODEV;
+}
+#endif
+
 static void aac_shutdown(struct pci_dev *dev)
 {
        struct Scsi_Host *shost = pci_get_drvdata(dev);
@@ -1356,6 +1504,10 @@ static struct pci_driver aac_pci_driver = {
        .id_table       = aac_pci_tbl,
        .probe          = aac_probe_one,
        .remove         = aac_remove_one,
+#if (defined(CONFIG_PM))
+       .suspend        = aac_suspend,
+       .resume         = aac_resume,
+#endif
        .shutdown       = aac_shutdown,
 };
 
index 9570612b80ce1eedfea7ee46881030141efb9b2c..ac1638069335a66e87b4ccfb5da9d323c2ef6b50 100644 (file)
@@ -623,6 +623,7 @@ int _aac_rx_init(struct aac_dev *dev)
        dev->a_ops.adapter_sync_cmd = rx_sync_cmd;
        dev->a_ops.adapter_check_health = aac_rx_check_health;
        dev->a_ops.adapter_restart = aac_rx_restart_adapter;
+       dev->a_ops.adapter_start = aac_rx_start_adapter;
 
        /*
         *      First clear out all interrupts.  Then enable the one's that we
index e66477c98240e40f9c6aae11b59cb61da2aa41f3..869aea23c0411be51ff270bc8d140ed6fce254e1 100644 (file)
@@ -372,6 +372,7 @@ int aac_sa_init(struct aac_dev *dev)
        dev->a_ops.adapter_sync_cmd = sa_sync_cmd;
        dev->a_ops.adapter_check_health = aac_sa_check_health;
        dev->a_ops.adapter_restart = aac_sa_restart_adapter;
+       dev->a_ops.adapter_start = aac_sa_start_adapter;
        dev->a_ops.adapter_intr = aac_sa_intr;
        dev->a_ops.adapter_deliver = aac_rx_deliver_producer;
        dev->a_ops.adapter_ioremap = aac_sa_ioremap;
index e63cf9f22f36a40f2e4bf1320cbc695e5a40812e..2aa34ea8ceb1e903781331acd3283ba264eadd53 100644 (file)
@@ -447,6 +447,10 @@ static int aac_src_deliver_message(struct fib *fib)
        u32 fibsize;
        dma_addr_t address;
        struct aac_fib_xporthdr *pFibX;
+#if !defined(writeq)
+       unsigned long flags;
+#endif
+
        u16 hdr_size = le16_to_cpu(fib->hw_fib_va->header.Size);
 
        atomic_inc(&q->numpending);
@@ -511,10 +515,14 @@ static int aac_src_deliver_message(struct fib *fib)
                        return -EINVAL;
                address |= fibsize;
        }
-
+#if defined(writeq)
+       src_writeq(dev, MUnit.IQ_L, (u64)address);
+#else
+       spin_lock_irqsave(&fib->dev->iq_lock, flags);
        src_writel(dev, MUnit.IQ_H, upper_32_bits(address) & 0xffffffff);
        src_writel(dev, MUnit.IQ_L, address & 0xffffffff);
-
+       spin_unlock_irqrestore(&fib->dev->iq_lock, flags);
+#endif
        return 0;
 }
 
@@ -726,6 +734,7 @@ int aac_src_init(struct aac_dev *dev)
        dev->a_ops.adapter_sync_cmd = src_sync_cmd;
        dev->a_ops.adapter_check_health = aac_src_check_health;
        dev->a_ops.adapter_restart = aac_src_restart_adapter;
+       dev->a_ops.adapter_start = aac_src_start_adapter;
 
        /*
         *      First clear out all interrupts.  Then enable the one's that we
@@ -741,7 +750,7 @@ int aac_src_init(struct aac_dev *dev)
        if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE1)
                goto error_iounmap;
 
-       dev->msi = aac_msi && !pci_enable_msi(dev->pdev);
+       dev->msi = !pci_enable_msi(dev->pdev);
 
        dev->aac_msix[0].vector_no = 0;
        dev->aac_msix[0].dev = dev;
@@ -789,9 +798,7 @@ int aac_srcv_init(struct aac_dev *dev)
        unsigned long status;
        int restart = 0;
        int instance = dev->id;
-       int i, j;
        const char *name = dev->name;
-       int cpu;
 
        dev->a_ops.adapter_ioremap = aac_srcv_ioremap;
        dev->a_ops.adapter_comm = aac_src_select_comm;
@@ -892,6 +899,7 @@ int aac_srcv_init(struct aac_dev *dev)
        dev->a_ops.adapter_sync_cmd = src_sync_cmd;
        dev->a_ops.adapter_check_health = aac_src_check_health;
        dev->a_ops.adapter_restart = aac_src_restart_adapter;
+       dev->a_ops.adapter_start = aac_src_start_adapter;
 
        /*
         *      First clear out all interrupts.  Then enable the one's that we
@@ -908,48 +916,10 @@ int aac_srcv_init(struct aac_dev *dev)
                goto error_iounmap;
        if (dev->msi_enabled)
                aac_src_access_devreg(dev, AAC_ENABLE_MSIX);
-       if (!dev->sync_mode && dev->msi_enabled && dev->max_msix > 1) {
-               cpu = cpumask_first(cpu_online_mask);
-               for (i = 0; i < dev->max_msix; i++) {
-                       dev->aac_msix[i].vector_no = i;
-                       dev->aac_msix[i].dev = dev;
-
-                       if (request_irq(dev->msixentry[i].vector,
-                                       dev->a_ops.adapter_intr,
-                                       0,
-                                       "aacraid",
-                                       &(dev->aac_msix[i]))) {
-                               printk(KERN_ERR "%s%d: Failed to register IRQ for vector %d.\n",
-                                               name, instance, i);
-                               for (j = 0 ; j < i ; j++)
-                                       free_irq(dev->msixentry[j].vector,
-                                                &(dev->aac_msix[j]));
-                               pci_disable_msix(dev->pdev);
-                               goto error_iounmap;
-                       }
-                       if (irq_set_affinity_hint(
-                          dev->msixentry[i].vector,
-                          get_cpu_mask(cpu))) {
-                               printk(KERN_ERR "%s%d: Failed to set IRQ affinity for cpu %d\n",
-                                               name, instance, cpu);
-                       }
-                       cpu = cpumask_next(cpu, cpu_online_mask);
-               }
-       } else {
-               dev->aac_msix[0].vector_no = 0;
-               dev->aac_msix[0].dev = dev;
-
-               if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
-                               IRQF_SHARED,
-                               "aacraid",
-                               &(dev->aac_msix[0])) < 0) {
-                       if (dev->msi)
-                               pci_disable_msi(dev->pdev);
-                       printk(KERN_ERR "%s%d: Interrupt unavailable.\n",
-                                       name, instance);
-                       goto error_iounmap;
-               }
-       }
+
+       if (aac_acquire_irq(dev))
+               goto error_iounmap;
+
        dev->dbg_base = dev->base_start;
        dev->dbg_base_mapped = dev->base;
        dev->dbg_size = dev->base_size;
index 4305178e4e0147ba9a8f8e04a452e77947f2cddb..519f9a4b3dadf39c07be7e61f20fc2481cddbd02 100644 (file)
@@ -10819,7 +10819,6 @@ static struct scsi_host_template advansys_template = {
         * by enabling clustering, I/O throughput increases as well.
         */
        .use_clustering = ENABLE_CLUSTERING,
-       .use_blk_tags = 1,
 };
 
 static int advansys_wide_init_chip(struct Scsi_Host *shost)
@@ -11211,11 +11210,6 @@ static int advansys_board_found(struct Scsi_Host *shost, unsigned int iop,
                /* Set maximum number of queues the adapter can handle. */
                shost->can_queue = adv_dvc_varp->max_host_qng;
        }
-       ret = scsi_init_shared_tag_map(shost, shost->can_queue);
-       if (ret) {
-               shost_printk(KERN_ERR, shost, "init tag map failed\n");
-               goto err_free_dma;
-       }
 
        /*
         * Set the maximum number of scatter-gather elements the
index ce96a0be32820fa6b75460adf9e4b7f48587ab05..2588b8f84ba0ec37108f3bfedb033cee44c47985 100644 (file)
@@ -925,7 +925,6 @@ struct scsi_host_template aic79xx_driver_template = {
        .slave_configure        = ahd_linux_slave_configure,
        .target_alloc           = ahd_linux_target_alloc,
        .target_destroy         = ahd_linux_target_destroy,
-       .use_blk_tags           = 1,
 };
 
 /******************************** Bus DMA *************************************/
index a2f2c774cd6b75f5874d71b5970a739a6923abaa..b846a4683562ca8ddd472becdb70a9a3d56387bf 100644 (file)
@@ -812,7 +812,6 @@ struct scsi_host_template aic7xxx_driver_template = {
        .slave_configure        = ahc_linux_slave_configure,
        .target_alloc           = ahc_linux_target_alloc,
        .target_destroy         = ahc_linux_target_destroy,
-       .use_blk_tags           = 1,
 };
 
 /**************************** Tasklet Handler *********************************/
index f6c336b05d5bbf6e0354c3f18697fd3350f3d09e..662b2321d1b0f40e73bf401925e23b81d377462a 100644 (file)
@@ -73,7 +73,6 @@ static struct scsi_host_template aic94xx_sht = {
        .eh_bus_reset_handler   = sas_eh_bus_reset_handler,
        .target_destroy         = sas_target_destroy,
        .ioctl                  = sas_ioctl,
-       .use_blk_tags           = 1,
        .track_queue_depth      = 1,
 };
 
@@ -704,10 +703,10 @@ static int asd_unregister_sas_ha(struct asd_ha_struct *asd_ha)
 {
        int err;
 
+       scsi_remove_host(asd_ha->sas_ha.core.shost);
        err = sas_unregister_ha(&asd_ha->sas_ha);
 
        sas_remove_host(asd_ha->sas_ha.core.shost);
-       scsi_remove_host(asd_ha->sas_ha.core.shost);
        scsi_host_put(asd_ha->sas_ha.core.shost);
 
        kfree(asd_ha->sas_ha.sas_phy);
index 2e6abe7b73241b4bbbfa88a4bf97f7c672bcef61..fe0c5143f8e68a6cb3e9618c98258c9e4118e1ae 100644 (file)
@@ -1198,14 +1198,16 @@ free_io_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle)
  * alloc_wrb_handle - To allocate a wrb handle
  * @phba: The hba pointer
  * @cid: The cid to use for allocation
+ * @pwrb_context: ptr to ptr to wrb context
  *
  * This happens under session_lock until submission to chip
  */
-struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid)
+struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid,
+                                    struct hwi_wrb_context **pcontext)
 {
        struct hwi_wrb_context *pwrb_context;
        struct hwi_controller *phwi_ctrlr;
-       struct wrb_handle *pwrb_handle, *pwrb_handle_tmp;
+       struct wrb_handle *pwrb_handle;
        uint16_t cri_index = BE_GET_CRI_FROM_CID(cid);
 
        phwi_ctrlr = phba->phwi_ctrlr;
@@ -1219,9 +1221,9 @@ struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid)
                        pwrb_context->alloc_index = 0;
                else
                        pwrb_context->alloc_index++;
-               pwrb_handle_tmp = pwrb_context->pwrb_handle_base[
-                                               pwrb_context->alloc_index];
-               pwrb_handle->nxt_wrb_index = pwrb_handle_tmp->wrb_index;
+
+               /* Return the context address */
+               *pcontext = pwrb_context;
        } else
                pwrb_handle = NULL;
        return pwrb_handle;
@@ -3184,7 +3186,7 @@ be_sgl_create_contiguous(void *virtual_address,
 {
        WARN_ON(!virtual_address);
        WARN_ON(!physical_address);
-       WARN_ON(!length > 0);
+       WARN_ON(!length);
        WARN_ON(!sgl);
 
        sgl->va = virtual_address;
@@ -4678,6 +4680,7 @@ beiscsi_offload_connection(struct beiscsi_conn *beiscsi_conn,
                           struct beiscsi_offload_params *params)
 {
        struct wrb_handle *pwrb_handle;
+       struct hwi_wrb_context *pwrb_context = NULL;
        struct beiscsi_hba *phba = beiscsi_conn->phba;
        struct iscsi_task *task = beiscsi_conn->task;
        struct iscsi_session *session = task->conn->session;
@@ -4692,14 +4695,17 @@ beiscsi_offload_connection(struct beiscsi_conn *beiscsi_conn,
        beiscsi_cleanup_task(task);
        spin_unlock_bh(&session->back_lock);
 
-       pwrb_handle = alloc_wrb_handle(phba, beiscsi_conn->beiscsi_conn_cid);
+       pwrb_handle = alloc_wrb_handle(phba, beiscsi_conn->beiscsi_conn_cid,
+                                      &pwrb_context);
 
        /* Check for the adapter family */
        if (is_chip_be2_be3r(phba))
                beiscsi_offload_cxn_v0(params, pwrb_handle,
-                                      phba->init_mem);
+                                      phba->init_mem,
+                                      pwrb_context);
        else
-               beiscsi_offload_cxn_v2(params, pwrb_handle);
+               beiscsi_offload_cxn_v2(params, pwrb_handle,
+                                      pwrb_context);
 
        be_dws_le_to_cpu(pwrb_handle->pwrb,
                         sizeof(struct iscsi_target_context_update_wrb));
@@ -4769,7 +4775,8 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode)
                        goto free_hndls;
                }
                io_task->pwrb_handle = alloc_wrb_handle(phba,
-                                       beiscsi_conn->beiscsi_conn_cid);
+                                       beiscsi_conn->beiscsi_conn_cid,
+                                       &io_task->pwrb_context);
                if (!io_task->pwrb_handle) {
                        beiscsi_log(phba, KERN_ERR,
                                    BEISCSI_LOG_IO | BEISCSI_LOG_CONFIG,
@@ -4803,7 +4810,8 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode)
                                                        io_task->psgl_handle;
                                io_task->pwrb_handle =
                                        alloc_wrb_handle(phba,
-                                       beiscsi_conn->beiscsi_conn_cid);
+                                       beiscsi_conn->beiscsi_conn_cid,
+                                       &io_task->pwrb_context);
                                if (!io_task->pwrb_handle) {
                                        beiscsi_log(phba, KERN_ERR,
                                                    BEISCSI_LOG_IO |
@@ -4839,7 +4847,8 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode)
                        }
                        io_task->pwrb_handle =
                                        alloc_wrb_handle(phba,
-                                       beiscsi_conn->beiscsi_conn_cid);
+                                       beiscsi_conn->beiscsi_conn_cid,
+                                       &io_task->pwrb_context);
                        if (!io_task->pwrb_handle) {
                                beiscsi_log(phba, KERN_ERR,
                                            BEISCSI_LOG_IO | BEISCSI_LOG_CONFIG,
@@ -4925,7 +4934,12 @@ int beiscsi_iotask_v2(struct iscsi_task *task, struct scatterlist *sg,
 
        hwi_write_sgl_v2(pwrb, sg, num_sg, io_task);
        AMAP_SET_BITS(struct amap_iscsi_wrb_v2, ptr2nextwrb, pwrb,
-                     io_task->pwrb_handle->nxt_wrb_index);
+                     io_task->pwrb_handle->wrb_index);
+       if (io_task->pwrb_context->plast_wrb)
+               AMAP_SET_BITS(struct amap_iscsi_wrb_v2, ptr2nextwrb,
+                             io_task->pwrb_context->plast_wrb,
+                             io_task->pwrb_handle->wrb_index);
+       io_task->pwrb_context->plast_wrb = pwrb;
 
        be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_wrb));
 
@@ -4982,7 +4996,13 @@ static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg,
        hwi_write_sgl(pwrb, sg, num_sg, io_task);
 
        AMAP_SET_BITS(struct amap_iscsi_wrb, ptr2nextwrb, pwrb,
-                     io_task->pwrb_handle->nxt_wrb_index);
+                     io_task->pwrb_handle->wrb_index);
+       if (io_task->pwrb_context->plast_wrb)
+               AMAP_SET_BITS(struct amap_iscsi_wrb, ptr2nextwrb,
+                             io_task->pwrb_context->plast_wrb,
+                             io_task->pwrb_handle->wrb_index);
+       io_task->pwrb_context->plast_wrb = pwrb;
+
        be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_wrb));
 
        doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK;
@@ -5020,7 +5040,13 @@ static int beiscsi_mtask(struct iscsi_task *task)
                AMAP_SET_BITS(struct amap_iscsi_wrb, r2t_exp_dtl, pwrb,
                              task->data_count);
                AMAP_SET_BITS(struct amap_iscsi_wrb, ptr2nextwrb, pwrb,
-                             io_task->pwrb_handle->nxt_wrb_index);
+                             io_task->pwrb_handle->wrb_index);
+               if (io_task->pwrb_context->plast_wrb)
+                       AMAP_SET_BITS(struct amap_iscsi_wrb, ptr2nextwrb,
+                                     io_task->pwrb_context->plast_wrb,
+                                     io_task->pwrb_handle->wrb_index);
+               io_task->pwrb_context->plast_wrb = pwrb;
+
                pwrb_typeoffset = BE_WRB_TYPE_OFFSET;
        } else {
                AMAP_SET_BITS(struct amap_iscsi_wrb_v2, cmdsn_itt, pwrb,
@@ -5032,7 +5058,13 @@ static int beiscsi_mtask(struct iscsi_task *task)
                AMAP_SET_BITS(struct amap_iscsi_wrb_v2, r2t_exp_dtl, pwrb,
                              task->data_count);
                AMAP_SET_BITS(struct amap_iscsi_wrb_v2, ptr2nextwrb, pwrb,
-                             io_task->pwrb_handle->nxt_wrb_index);
+                             io_task->pwrb_handle->wrb_index);
+               if (io_task->pwrb_context->plast_wrb)
+                       AMAP_SET_BITS(struct amap_iscsi_wrb_v2, ptr2nextwrb,
+                                     io_task->pwrb_context->plast_wrb,
+                                     io_task->pwrb_handle->wrb_index);
+               io_task->pwrb_context->plast_wrb = pwrb;
+
                pwrb_typeoffset = SKH_WRB_TYPE_OFFSET;
        }
 
index 51366de5ef702661d5c94aadb87b444b743548cb..5c67c0732241b507e199ff756ad1c60e17c0b703 100644 (file)
@@ -36,7 +36,7 @@
 #include <scsi/scsi_transport_iscsi.h>
 
 #define DRV_NAME               "be2iscsi"
-#define BUILD_STR              "10.6.0.0"
+#define BUILD_STR              "10.6.0.1"
 #define BE_NAME                        "Emulex OneConnect" \
                                "Open-iSCSI Driver version" BUILD_STR
 #define DRV_DESC               BE_NAME " " "Driver"
@@ -502,6 +502,7 @@ struct beiscsi_io_task {
        struct sgl_handle *psgl_handle;
        struct beiscsi_conn *conn;
        struct scsi_cmnd *scsi_cmnd;
+       struct hwi_wrb_context *pwrb_context;
        unsigned int cmd_sn;
        unsigned int flags;
        unsigned short cid;
@@ -833,7 +834,8 @@ struct amap_iscsi_wrb_v2 {
 } __packed;
 
 
-struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid);
+struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid,
+                                    struct hwi_wrb_context **pcontext);
 void
 free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle);
 
@@ -1044,7 +1046,6 @@ enum hwh_type_enum {
 struct wrb_handle {
        enum hwh_type_enum type;
        unsigned short wrb_index;
-       unsigned short nxt_wrb_index;
 
        struct iscsi_task *pio_handle;
        struct iscsi_wrb *pwrb;
index 1b2bd044dad6dacc4ef81a4298ac80c7071493a3..aea3e6b9477dcc73df18b263365609a93abd3758 100644 (file)
@@ -1573,7 +1573,8 @@ beiscsi_phys_port_disp(struct device *dev, struct device_attribute *attr,
 
 void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
                             struct wrb_handle *pwrb_handle,
-                            struct be_mem_descriptor *mem_descr)
+                            struct be_mem_descriptor *mem_descr,
+                            struct hwi_wrb_context *pwrb_context)
 {
        struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
 
@@ -1617,7 +1618,14 @@ void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
                      max_burst_length) / 32]);
 
        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ptr2nextwrb,
-                     pwrb, pwrb_handle->nxt_wrb_index);
+                     pwrb, pwrb_handle->wrb_index);
+       if (pwrb_context->plast_wrb)
+               AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
+                             ptr2nextwrb,
+                             pwrb_context->plast_wrb,
+                             pwrb_handle->wrb_index);
+       pwrb_context->plast_wrb = pwrb;
+
        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
                      session_state, pwrb, 0);
        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, compltonack,
@@ -1637,7 +1645,8 @@ void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
 }
 
 void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
-                            struct wrb_handle *pwrb_handle)
+                            struct wrb_handle *pwrb_handle,
+                            struct hwi_wrb_context *pwrb_context)
 {
        struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
 
@@ -1652,7 +1661,14 @@ void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
                      BE_TGT_CTX_UPDT_CMD);
        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
                      ptr2nextwrb,
-                     pwrb, pwrb_handle->nxt_wrb_index);
+                     pwrb, pwrb_handle->wrb_index);
+       if (pwrb_context->plast_wrb)
+               AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
+                             ptr2nextwrb,
+                             pwrb_context->plast_wrb,
+                             pwrb_handle->wrb_index);
+       pwrb_context->plast_wrb = pwrb;
+
        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, wrb_idx,
                      pwrb, pwrb_handle->wrb_index);
        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
index afa326da75c6797d3a06126e2e5e8921f03f5da9..c1dbb690ee279f669fffb2ddab5919189923b8c8 100644 (file)
@@ -330,10 +330,13 @@ ssize_t beiscsi_phys_port_disp(struct device *dev,
 
 void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
                             struct wrb_handle *pwrb_handle,
-                            struct be_mem_descriptor *mem_descr);
+                            struct be_mem_descriptor *mem_descr,
+                            struct hwi_wrb_context *pwrb_context);
 
 void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
-                            struct wrb_handle *pwrb_handle);
+                            struct wrb_handle *pwrb_handle,
+                            struct hwi_wrb_context *pwrb_context);
+
 void beiscsi_ue_detect(struct beiscsi_hba *phba);
 int be_cmd_modify_eq_delay(struct beiscsi_hba *phba,
                         struct be_set_eqd *, int num);
index 8367c11d554b22a6fb5b7c5385b56bbc7f156f45..299c6f80d4605116c5039cb1a23b77a0b4324d05 100644 (file)
@@ -800,7 +800,6 @@ struct scsi_host_template bfad_im_scsi_host_template = {
        .shost_attrs = bfad_im_host_attrs,
        .max_sectors = BFAD_MAX_SECTORS,
        .vendor_id = BFA_PCI_VENDOR_ID_BROCADE,
-       .use_blk_tags = 1,
 };
 
 struct scsi_host_template bfad_im_vport_template = {
@@ -822,7 +821,6 @@ struct scsi_host_template bfad_im_vport_template = {
        .use_clustering = ENABLE_CLUSTERING,
        .shost_attrs = bfad_im_vport_attrs,
        .max_sectors = BFAD_MAX_SECTORS,
-       .use_blk_tags = 1,
 };
 
 bfa_status_t
index fe2106c91c08585049da46972d53f8089dc2469f..ac1c0b631acab02d5d78ed3ec5bd268a91b81785 100644 (file)
@@ -1,9 +1,9 @@
-/* 57xx_hsi_bnx2fc.h: QLogic NetXtreme II Linux FCoE offload driver.
+/* 57xx_hsi_bnx2fc.h: QLogic Linux FCoE offload driver.
  * Handles operations such as session offload/upload etc, and manages
  * session resources such as connection id and qp resources.
  *
- * Copyright (c) 2008 - 2013 Broadcom Corporation
- * Copyright (c) 2014, QLogic Corporation
+ * Copyright (c) 2008-2013 Broadcom Corporation
+ * Copyright (c) 2014-2015 QLogic Corporation
  *
  * 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
index 0978828826498693f794f661f0a6dc0f9cde6170..d401a096dfc7eb517642a29ae4aa5f3862fb40e5 100644 (file)
@@ -1,5 +1,5 @@
 config SCSI_BNX2X_FCOE
-       tristate "QLogic NetXtreme II FCoE support"
+       tristate "QLogic FCoE offload support"
        depends on PCI
        depends on (IPV6 || IPV6=n)
        depends on LIBFC
@@ -9,5 +9,4 @@ config SCSI_BNX2X_FCOE
        select NET_VENDOR_BROADCOM
        select CNIC
        ---help---
-       This driver supports FCoE offload for the QLogic NetXtreme II
-       devices.
+       This driver supports FCoE offload for the QLogic devices.
index 1346e052e03cc1311792b8a4c9bf3c85565748a6..499e369eabf0bb165a4300373be7868fd896bd85 100644 (file)
@@ -1,7 +1,7 @@
-/* bnx2fc.h: QLogic NetXtreme II Linux FCoE offload driver.
+/* bnx2fc.h: QLogic Linux FCoE offload driver.
  *
- * Copyright (c) 2008 - 2013 Broadcom Corporation
- * Copyright (c) 2014, QLogic Corporation
+ * Copyright (c) 2008-2013 Broadcom Corporation
+ * Copyright (c) 2014-2015 QLogic Corporation
  *
  * 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
@@ -65,7 +65,7 @@
 #include "bnx2fc_constants.h"
 
 #define BNX2FC_NAME            "bnx2fc"
-#define BNX2FC_VERSION         "2.4.2"
+#define BNX2FC_VERSION         "2.9.6"
 
 #define PFX                    "bnx2fc: "
 
@@ -303,7 +303,6 @@ struct bnx2fc_rport {
 #define BNX2FC_FLAG_OFLD_REQ_CMPL      0x5
 #define BNX2FC_FLAG_CTX_ALLOC_FAILURE  0x6
 #define BNX2FC_FLAG_UPLD_REQ_COMPL     0x7
-#define BNX2FC_FLAG_EXPL_LOGO          0x8
 #define BNX2FC_FLAG_DISABLE_FAILED     0x9
 #define BNX2FC_FLAG_ENABLED            0xa
 
index e147cc7ee36c5d454de7967f0eabbee7abaf7187..5b20efb661a57ee9d89cbdfaa6a67122e276dc52 100644 (file)
@@ -1,9 +1,9 @@
-/* bnx2fc_constants.h: QLogic NetXtreme II Linux FCoE offload driver.
+/* bnx2fc_constants.h: QLogic Linux FCoE offload driver.
  * Handles operations such as session offload/upload etc, and manages
  * session resources such as connection id and qp resources.
  *
- * Copyright (c) 2008 - 2013 Broadcom Corporation
- * Copyright (c) 2014, QLogic Corporation
+ * Copyright (c) 2008-2013 Broadcom Corporation
+ * Copyright (c) 2014-2015 QLogic Corporation
  *
  * 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
index d055df01faa5b3c18442e09a0806234459b0673e..c9e0bc7fad3b35af613b031b8aea76055a2fbadd 100644 (file)
@@ -1,9 +1,9 @@
-/* bnx2fc_debug.c: QLogic NetXtreme II Linux FCoE offload driver.
+/* bnx2fc_debug.c: QLogic Linux FCoE offload driver.
  * Handles operations such as session offload/upload etc, and manages
  * session resources such as connection id and qp resources.
  *
- * Copyright (c) 2008 - 2013 Broadcom Corporation
- * Copyright (c) 2014, QLogic Corporation
+ * Copyright (c) 2008-2013 Broadcom Corporation
+ * Copyright (c) 2014-2015 QLogic Corporation
  *
  * 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
index 2b9006774f377241565f36137dde0de616697376..34fda3e04d27024a8325191ec6fbf47c0e3a4a8f 100644 (file)
@@ -1,9 +1,9 @@
-/* bnx2fc_debug.h: QLogic NetXtreme II Linux FCoE offload driver.
+/* bnx2fc_debug.h: QLogic Linux FCoE offload driver.
  * Handles operations such as session offload/upload etc, and manages
  * session resources such as connection id and qp resources.
  *
- * Copyright (c) 2008 - 2013 Broadcom Corporation
- * Copyright (c) 2014, QLogic Corporation
+ * Copyright (c) 2008-2013 Broadcom Corporation
+ * Copyright (c) 2014-2015 QLogic Corporation
  *
  * 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
index ef355c13ccc47c9a9f05cde438408e4e56b3eb3d..5beea776b9f54c3fe920c1f561f19fce001c4a56 100644 (file)
@@ -1,10 +1,10 @@
 /*
- * bnx2fc_els.c: QLogic NetXtreme II Linux FCoE offload driver.
+ * bnx2fc_els.c: QLogic Linux FCoE offload driver.
  * This file contains helper routines that handle ELS requests
  * and responses.
  *
- * Copyright (c) 2008 - 2013 Broadcom Corporation
- * Copyright (c) 2014, QLogic Corporation
+ * Copyright (c) 2008-2013 Broadcom Corporation
+ * Copyright (c) 2014-2015 QLogic Corporation
  *
  * 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
@@ -689,8 +689,7 @@ static int bnx2fc_initiate_els(struct bnx2fc_rport *tgt, unsigned int op,
                rc = -EINVAL;
                goto els_err;
        }
-       if (!(test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags)) ||
-            (test_bit(BNX2FC_FLAG_EXPL_LOGO, &tgt->flags))) {
+       if (!(test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags))) {
                printk(KERN_ERR PFX "els 0x%x: tgt not ready\n", op);
                rc = -EINVAL;
                goto els_err;
@@ -707,6 +706,7 @@ static int bnx2fc_initiate_els(struct bnx2fc_rport *tgt, unsigned int op,
        els_req->cb_func = cb_func;
        cb_arg->io_req = els_req;
        els_req->cb_arg = cb_arg;
+       els_req->data_xfer_len = data_len;
 
        mp_req = (struct bnx2fc_mp_req *)&(els_req->mp_req);
        rc = bnx2fc_init_mp_req(els_req);
index b0bc5ffee903ad8b497886c0c445700496630110..67405c628864875bab6e56beb2a67846fa690ead 100644 (file)
@@ -1,10 +1,10 @@
-/* bnx2fc_fcoe.c: QLogic NetXtreme II Linux FCoE offload driver.
+/* bnx2fc_fcoe.c: QLogic Linux FCoE offload driver.
  * This file contains the code that interacts with libfc, libfcoe,
  * cnic modules to create FCoE instances, send/receive non-offloaded
  * FIP/FCoE packets, listen to link events etc.
  *
- * Copyright (c) 2008 - 2013 Broadcom Corporation
- * Copyright (c) 2014, QLogic Corporation
+ * Copyright (c) 2008-2013 Broadcom Corporation
+ * Copyright (c) 2014-2015 QLogic Corporation
  *
  * 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
@@ -23,16 +23,16 @@ DEFINE_PER_CPU(struct bnx2fc_percpu_s, bnx2fc_percpu);
 
 #define DRV_MODULE_NAME                "bnx2fc"
 #define DRV_MODULE_VERSION     BNX2FC_VERSION
-#define DRV_MODULE_RELDATE     "Dec 11, 2013"
+#define DRV_MODULE_RELDATE     "October 15, 2015"
 
 
 static char version[] =
-               "QLogic NetXtreme II FCoE Driver " DRV_MODULE_NAME \
+               "QLogic FCoE Driver " DRV_MODULE_NAME \
                " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
 
 
 MODULE_AUTHOR("Bhanu Prakash Gollapudi <bprakash@broadcom.com>");
-MODULE_DESCRIPTION("QLogic NetXtreme II BCM57710 FCoE Driver");
+MODULE_DESCRIPTION("QLogic FCoE Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_MODULE_VERSION);
 
@@ -2091,7 +2091,7 @@ static int __bnx2fc_enable(struct fcoe_ctlr *ctlr)
 {
        struct bnx2fc_interface *interface = fcoe_ctlr_priv(ctlr);
        struct bnx2fc_hba *hba;
-       struct cnic_fc_npiv_tbl npiv_tbl;
+       struct cnic_fc_npiv_tbl *npiv_tbl;
        struct fc_lport *lport;
 
        if (interface->enabled == false) {
@@ -2123,11 +2123,16 @@ static int __bnx2fc_enable(struct fcoe_ctlr *ctlr)
        if (!hba->cnic->get_fc_npiv_tbl)
                goto done;
 
-       memset(&npiv_tbl, 0, sizeof(npiv_tbl));
-       if (hba->cnic->get_fc_npiv_tbl(hba->cnic, &npiv_tbl))
+       npiv_tbl = kzalloc(sizeof(struct cnic_fc_npiv_tbl), GFP_KERNEL);
+       if (!npiv_tbl)
                goto done;
 
-       bnx2fc_npiv_create_vports(lport, &npiv_tbl);
+       if (hba->cnic->get_fc_npiv_tbl(hba->cnic, npiv_tbl))
+               goto done_free;
+
+       bnx2fc_npiv_create_vports(lport, npiv_tbl);
+done_free:
+       kfree(npiv_tbl);
 done:
        return 0;
 }
@@ -2862,7 +2867,6 @@ static struct scsi_host_template bnx2fc_shost_template = {
        .use_clustering         = ENABLE_CLUSTERING,
        .sg_tablesize           = BNX2FC_MAX_BDS_PER_CMD,
        .max_sectors            = 1024,
-       .use_blk_tags           = 1,
        .track_queue_depth      = 1,
 };
 
index c6688d72a846fa61d37324217d924d3f19848f48..28c671b609b2f44df627788ede37169180e4e8fb 100644 (file)
@@ -1,9 +1,9 @@
-/* bnx2fc_hwi.c: QLogic NetXtreme II Linux FCoE offload driver.
+/* bnx2fc_hwi.c: QLogic Linux FCoE offload driver.
  * This file contains the code that low level functions that interact
  * with 57712 FCoE firmware.
  *
- * Copyright (c) 2008 - 2013 Broadcom Corporation
- * Copyright (c) 2014, QLogic Corporation
+ * Copyright (c) 2008-2013 Broadcom Corporation
+ * Copyright (c) 2014-2015 QLogic Corporation
  *
  * 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
index 9ecca8504f60e64084e1e55487602011e7386e30..0002caf687dd027f959e76e3e64cac52b7ded11d 100644 (file)
@@ -1,8 +1,8 @@
-/* bnx2fc_io.c: QLogic NetXtreme II Linux FCoE offload driver.
+/* bnx2fc_io.c: QLogic Linux FCoE offload driver.
  * IO manager and SCSI IO processing.
  *
- * Copyright (c) 2008 - 2013 Broadcom Corporation
- * Copyright (c) 2014, QLogic Corporation
+ * Copyright (c) 2008-2013 Broadcom Corporation
+ * Copyright (c) 2014-2015 QLogic Corporation
  *
  * 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
@@ -40,11 +40,8 @@ static void bnx2fc_cmd_timeout(struct work_struct *work)
 {
        struct bnx2fc_cmd *io_req = container_of(work, struct bnx2fc_cmd,
                                                 timeout_work.work);
-       struct fc_lport *lport;
-       struct fc_rport_priv *rdata;
        u8 cmd_type = io_req->cmd_type;
        struct bnx2fc_rport *tgt = io_req->tgt;
-       int logo_issued;
        int rc;
 
        BNX2FC_IO_DBG(io_req, "cmd_timeout, cmd_type = %d,"
@@ -80,25 +77,14 @@ static void bnx2fc_cmd_timeout(struct work_struct *work)
                                        io_req->refcount.refcount.counter);
                        if (!(test_and_set_bit(BNX2FC_FLAG_ABTS_DONE,
                                               &io_req->req_flags))) {
-
-                               lport = io_req->port->lport;
-                               rdata = io_req->tgt->rdata;
-                               logo_issued = test_and_set_bit(
-                                               BNX2FC_FLAG_EXPL_LOGO,
-                                               &tgt->flags);
+                               /*
+                                * Cleanup and return original command to
+                                * mid-layer.
+                                */
+                               bnx2fc_initiate_cleanup(io_req);
                                kref_put(&io_req->refcount, bnx2fc_cmd_release);
                                spin_unlock_bh(&tgt->tgt_lock);
 
-                               /* Explicitly logo the target */
-                               if (!logo_issued) {
-                                       BNX2FC_IO_DBG(io_req, "Explicit "
-                                                  "logo - tgt flags = 0x%lx\n",
-                                                  tgt->flags);
-
-                                       mutex_lock(&lport->disc.disc_mutex);
-                                       lport->tt.rport_logoff(rdata);
-                                       mutex_unlock(&lport->disc.disc_mutex);
-                               }
                                return;
                        }
                } else {
@@ -116,28 +102,10 @@ static void bnx2fc_cmd_timeout(struct work_struct *work)
                                rc = bnx2fc_initiate_abts(io_req);
                                if (rc == SUCCESS)
                                        goto done;
-                               /*
-                                * Explicitly logo the target if
-                                * abts initiation fails
-                                */
-                               lport = io_req->port->lport;
-                               rdata = io_req->tgt->rdata;
-                               logo_issued = test_and_set_bit(
-                                               BNX2FC_FLAG_EXPL_LOGO,
-                                               &tgt->flags);
+
                                kref_put(&io_req->refcount, bnx2fc_cmd_release);
                                spin_unlock_bh(&tgt->tgt_lock);
 
-                               if (!logo_issued) {
-                                       BNX2FC_IO_DBG(io_req, "Explicit "
-                                                  "logo - tgt flags = 0x%lx\n",
-                                                  tgt->flags);
-
-
-                                       mutex_lock(&lport->disc.disc_mutex);
-                                       lport->tt.rport_logoff(rdata);
-                                       mutex_unlock(&lport->disc.disc_mutex);
-                               }
                                return;
                        } else {
                                BNX2FC_IO_DBG(io_req, "IO already in "
@@ -152,22 +120,9 @@ static void bnx2fc_cmd_timeout(struct work_struct *work)
 
                        if (!test_and_set_bit(BNX2FC_FLAG_ABTS_DONE,
                                              &io_req->req_flags)) {
-                               lport = io_req->port->lport;
-                               rdata = io_req->tgt->rdata;
-                               logo_issued = test_and_set_bit(
-                                               BNX2FC_FLAG_EXPL_LOGO,
-                                               &tgt->flags);
                                kref_put(&io_req->refcount, bnx2fc_cmd_release);
                                spin_unlock_bh(&tgt->tgt_lock);
 
-                               /* Explicitly logo the target */
-                               if (!logo_issued) {
-                                       BNX2FC_IO_DBG(io_req, "Explicitly logo"
-                                                  "(els)\n");
-                                       mutex_lock(&lport->disc.disc_mutex);
-                                       lport->tt.rport_logoff(rdata);
-                                       mutex_unlock(&lport->disc.disc_mutex);
-                               }
                                return;
                        }
                } else {
@@ -623,8 +578,12 @@ int bnx2fc_init_mp_req(struct bnx2fc_cmd *io_req)
        mp_req = (struct bnx2fc_mp_req *)&(io_req->mp_req);
        memset(mp_req, 0, sizeof(struct bnx2fc_mp_req));
 
-       mp_req->req_len = sizeof(struct fcp_cmnd);
-       io_req->data_xfer_len = mp_req->req_len;
+       if (io_req->cmd_type != BNX2FC_ELS) {
+               mp_req->req_len = sizeof(struct fcp_cmnd);
+               io_req->data_xfer_len = mp_req->req_len;
+       } else
+               mp_req->req_len = io_req->data_xfer_len;
+
        mp_req->req_buf = dma_alloc_coherent(&hba->pcidev->dev, CNIC_PAGE_SIZE,
                                             &mp_req->req_buf_dma,
                                             GFP_ATOMIC);
@@ -1108,18 +1067,11 @@ int bnx2fc_eh_device_reset(struct scsi_cmnd *sc_cmd)
        return bnx2fc_initiate_tmf(sc_cmd, FCP_TMF_LUN_RESET);
 }
 
-int bnx2fc_expl_logo(struct fc_lport *lport, struct bnx2fc_cmd *io_req)
+int bnx2fc_abts_cleanup(struct bnx2fc_cmd *io_req)
 {
        struct bnx2fc_rport *tgt = io_req->tgt;
-       struct fc_rport_priv *rdata = tgt->rdata;
-       int logo_issued;
        int rc = SUCCESS;
-       int wait_cnt = 0;
 
-       BNX2FC_IO_DBG(io_req, "Expl logo - tgt flags = 0x%lx\n",
-                     tgt->flags);
-       logo_issued = test_and_set_bit(BNX2FC_FLAG_EXPL_LOGO,
-                                      &tgt->flags);
        io_req->wait_for_comp = 1;
        bnx2fc_initiate_cleanup(io_req);
 
@@ -1132,21 +1084,8 @@ int bnx2fc_expl_logo(struct fc_lport *lport, struct bnx2fc_cmd *io_req)
         * release the reference taken in eh_abort to allow the
         * target to re-login after flushing IOs
         */
-        kref_put(&io_req->refcount, bnx2fc_cmd_release);
-
-       if (!logo_issued) {
-               clear_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags);
-               mutex_lock(&lport->disc.disc_mutex);
-               lport->tt.rport_logoff(rdata);
-               mutex_unlock(&lport->disc.disc_mutex);
-               do {
-                       msleep(BNX2FC_RELOGIN_WAIT_TIME);
-                       if (wait_cnt++ > BNX2FC_RELOGIN_WAIT_CNT) {
-                               rc = FAILED;
-                               break;
-                       }
-               } while (!test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags));
-       }
+       kref_put(&io_req->refcount, bnx2fc_cmd_release);
+
        spin_lock_bh(&tgt->tgt_lock);
        return rc;
 }
@@ -1248,7 +1187,7 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
                if (cancel_delayed_work(&io_req->timeout_work))
                        kref_put(&io_req->refcount,
                                 bnx2fc_cmd_release); /* drop timer hold */
-               rc = bnx2fc_expl_logo(lport, io_req);
+               rc = bnx2fc_abts_cleanup(io_req);
                /* This only occurs when an task abort was requested while ABTS
                   is in progress.  Setting the IO_CLEANUP flag will skip the
                   RRQ process in the case when the fw generated SCSI_CMD cmpl
@@ -1287,7 +1226,7 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
                /* Let the scsi-ml try to recover this command */
                printk(KERN_ERR PFX "abort failed, xid = 0x%x\n",
                       io_req->xid);
-               rc = bnx2fc_expl_logo(lport, io_req);
+               rc = bnx2fc_abts_cleanup(io_req);
                goto out;
        } else {
                /*
@@ -1755,7 +1694,10 @@ static void bnx2fc_parse_fcp_rsp(struct bnx2fc_cmd *io_req,
        int fcp_rsp_len = 0;
 
        io_req->fcp_status = FC_GOOD;
-       io_req->fcp_resid = fcp_rsp->fcp_resid;
+       io_req->fcp_resid = 0;
+       if (rsp_flags & (FCOE_FCP_RSP_FLAGS_FCP_RESID_OVER |
+           FCOE_FCP_RSP_FLAGS_FCP_RESID_UNDER))
+               io_req->fcp_resid = fcp_rsp->fcp_resid;
 
        io_req->scsi_comp_flags = rsp_flags;
        CMD_SCSI_STATUS(sc_cmd) = io_req->cdb_status =
index c66c708412a6a34a8d0cf3f281641b4a594707c1..08ec318afb99ccdaf032959b701313234039c484 100644 (file)
@@ -1,9 +1,9 @@
-/* bnx2fc_tgt.c: QLogic NetXtreme II Linux FCoE offload driver.
+/* bnx2fc_tgt.c: QLogic Linux FCoE offload driver.
  * Handles operations such as session offload/upload etc, and manages
  * session resources such as connection id and qp resources.
  *
- * Copyright (c) 2008 - 2013 Broadcom Corporation
- * Copyright (c) 2014, QLogic Corporation
+ * Copyright (c) 2008-2013 Broadcom Corporation
+ * Copyright (c) 2014-2015 QLogic Corporation
  *
  * 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
@@ -560,12 +560,6 @@ void bnx2fc_rport_event_handler(struct fc_lport *lport,
                    (hba->num_ofld_sess == 0)) {
                        wake_up_interruptible(&hba->shutdown_wait);
                }
-               if (test_bit(BNX2FC_FLAG_EXPL_LOGO, &tgt->flags)) {
-                       printk(KERN_ERR PFX "Relogin to the tgt\n");
-                       mutex_lock(&lport->disc.disc_mutex);
-                       lport->tt.rport_login(rdata);
-                       mutex_unlock(&lport->disc.disc_mutex);
-               }
                mutex_unlock(&hba->hba_mutex);
 
                break;
index 2c4562d82dc06281dc9e9e51cf1e8a9701c041c1..c2a6f9f294271c5db4f2ec2b885d87b5ec849a4d 100644 (file)
@@ -2283,7 +2283,6 @@ struct scsi_host_template csio_fcoe_shost_template = {
        .use_clustering         = ENABLE_CLUSTERING,
        .shost_attrs            = csio_fcoe_lport_attrs,
        .max_sectors            = CSIO_MAX_SECTOR_SIZE,
-       .use_blk_tags           = 1,
 };
 
 struct scsi_host_template csio_fcoe_shost_vport_template = {
@@ -2303,7 +2302,6 @@ struct scsi_host_template csio_fcoe_shost_vport_template = {
        .use_clustering         = ENABLE_CLUSTERING,
        .shost_attrs            = csio_fcoe_vport_attrs,
        .max_sectors            = CSIO_MAX_SECTOR_SIZE,
-       .use_blk_tags           = 1,
 };
 
 /*
index 31f8966b2e037823857bcae96866e414c5709044..33581ba4386e8014290c6ce7e2931a35d8dc07c0 100644 (file)
@@ -256,7 +256,6 @@ static struct scsi_host_template driver_template = {
        .proc_name                      = ESAS2R_DRVR_NAME,
        .change_queue_depth             = scsi_change_queue_depth,
        .max_sectors                    = 0xFFFF,
-       .use_blk_tags                   = 1,
 };
 
 int sgl_page_size = 512;
index 065b25df741b601f7e51345ce1e56d687a09ee0c..71cb05b1c3ebdd9d3d3631ee2da4a44a72b40731 100644 (file)
@@ -2694,7 +2694,6 @@ struct scsi_host_template scsi_esp_template = {
        .use_clustering         = ENABLE_CLUSTERING,
        .max_sectors            = 0xffff,
        .skip_settle_delay      = 1,
-       .use_blk_tags           = 1,
 };
 EXPORT_SYMBOL(scsi_esp_template);
 
index d3eb80c46bbe2224ac9cd82b2e3833f28e7ab297..f4424063b860177c6501f4b8796c384b4fed1884 100644 (file)
@@ -287,7 +287,6 @@ static struct scsi_host_template fcoe_shost_template = {
        .use_clustering = ENABLE_CLUSTERING,
        .sg_tablesize = SG_ALL,
        .max_sectors = 0xffff,
-       .use_blk_tags = 1,
        .track_queue_depth = 1,
 };
 
@@ -1873,7 +1872,6 @@ static int fcoe_percpu_receive_thread(void *arg)
 
        set_user_nice(current, MIN_NICE);
 
-retry:
        while (!kthread_should_stop()) {
 
                spin_lock_bh(&p->fcoe_rx_list.lock);
@@ -1883,7 +1881,7 @@ retry:
                        set_current_state(TASK_INTERRUPTIBLE);
                        spin_unlock_bh(&p->fcoe_rx_list.lock);
                        schedule();
-                       goto retry;
+                       continue;
                }
 
                spin_unlock_bh(&p->fcoe_rx_list.lock);
index 8a0d4d7b3254d715c32cfcc41bb0fc66dd221221..58ce9020d69c5882eebfa46f3ec685fb7b63fef6 100644 (file)
@@ -118,7 +118,6 @@ static struct scsi_host_template fnic_host_template = {
        .sg_tablesize = FNIC_MAX_SG_DESC_CNT,
        .max_sectors = 0xffff,
        .shost_attrs = fnic_attrs,
-       .use_blk_tags = 1,
        .track_queue_depth = 1,
 };
 
@@ -697,13 +696,6 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        }
        fnic->fnic_max_tag_id = host->can_queue;
 
-       err = scsi_init_shared_tag_map(host, fnic->fnic_max_tag_id);
-       if (err) {
-               shost_printk(KERN_ERR, fnic->lport->host,
-                         "Unable to alloc shared tag map\n");
-               goto err_out_dev_close;
-       }
-
        host->max_lun = fnic->config.luns_per_tgt;
        host->max_id = FNIC_MAX_FCP_TARGET;
        host->max_cmd_len = FCOE_MAX_CMD_LEN;
index 8bb173e01084efb40b80121cda098651375ed3ce..323982fd00c3ba985dfb59bf04b6eff04f86e9b7 100644 (file)
@@ -217,6 +217,13 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,
                error = scsi_mq_setup_tags(shost);
                if (error)
                        goto fail;
+       } else {
+               shost->bqt = blk_init_tags(shost->can_queue,
+                               shost->hostt->tag_alloc_policy);
+               if (!shost->bqt) {
+                       error = -ENOMEM;
+                       goto fail;
+               }
        }
 
        /*
index 40669f8dd0df12af584c581d71a151386d9155e2..6a8f95808ee0f92027796651a6254e6c9382ca5a 100644 (file)
@@ -41,6 +41,7 @@
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_tcq.h>
 #include <scsi/scsi_eh.h>
+#include <scsi/scsi_transport_sas.h>
 #include <scsi/scsi_dbg.h>
 #include <linux/cciss_ioctl.h>
 #include <linux/string.h>
 #include "hpsa_cmd.h"
 #include "hpsa.h"
 
-/* HPSA_DRIVER_VERSION must be 3 byte values (0-255) separated by '.' */
-#define HPSA_DRIVER_VERSION "3.4.10-0"
+/*
+ * HPSA_DRIVER_VERSION must be 3 byte values (0-255) separated by '.'
+ * with an optional trailing '-' followed by a byte value (0-255).
+ */
+#define HPSA_DRIVER_VERSION "3.4.14-0"
 #define DRIVER_NAME "HP HPSA Driver (v " HPSA_DRIVER_VERSION ")"
 #define HPSA "hpsa"
 
@@ -205,6 +209,16 @@ static struct board_type products[] = {
        {0xFFFF103C, "Unknown Smart Array", &SA5_access},
 };
 
+static struct scsi_transport_template *hpsa_sas_transport_template;
+static int hpsa_add_sas_host(struct ctlr_info *h);
+static void hpsa_delete_sas_host(struct ctlr_info *h);
+static int hpsa_add_sas_device(struct hpsa_sas_node *hpsa_sas_node,
+                       struct hpsa_scsi_dev_t *device);
+static void hpsa_remove_sas_device(struct hpsa_scsi_dev_t *device);
+static struct hpsa_scsi_dev_t
+       *hpsa_find_device_by_sas_rphy(struct ctlr_info *h,
+               struct sas_rphy *rphy);
+
 #define SCSI_CMD_BUSY ((struct scsi_cmnd *)&hpsa_cmd_busy)
 static const struct scsi_cmnd hpsa_cmd_busy;
 #define SCSI_CMD_IDLE ((struct scsi_cmnd *)&hpsa_cmd_idle)
@@ -230,6 +244,7 @@ static int fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h,
        int cmd_type);
 static void hpsa_free_cmd_pool(struct ctlr_info *h);
 #define VPD_PAGE (1 << 8)
+#define HPSA_SIMPLE_ERROR_BITS 0x03
 
 static int hpsa_scsi_queue_command(struct Scsi_Host *h, struct scsi_cmnd *cmd);
 static void hpsa_scan_start(struct Scsi_Host *);
@@ -243,7 +258,7 @@ static int hpsa_slave_alloc(struct scsi_device *sdev);
 static int hpsa_slave_configure(struct scsi_device *sdev);
 static void hpsa_slave_destroy(struct scsi_device *sdev);
 
-static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno);
+static void hpsa_update_scsi_devices(struct ctlr_info *h);
 static int check_for_unit_attention(struct ctlr_info *h,
        struct CommandList *c);
 static void check_ioctl_unit_attention(struct ctlr_info *h,
@@ -274,7 +289,10 @@ static int hpsa_scsi_ioaccel_queue_command(struct ctlr_info *h,
 static void hpsa_command_resubmit_worker(struct work_struct *work);
 static u32 lockup_detected(struct ctlr_info *h);
 static int detect_controller_lockup(struct ctlr_info *h);
-static int is_ext_target(struct ctlr_info *h, struct hpsa_scsi_dev_t *device);
+static void hpsa_disable_rld_caching(struct ctlr_info *h);
+static inline int hpsa_scsi_do_report_phys_luns(struct ctlr_info *h,
+       struct ReportExtendedLUNdata *buf, int bufsize);
+static int hpsa_luns_changed(struct ctlr_info *h);
 
 static inline struct ctlr_info *sdev_to_hba(struct scsi_device *sdev)
 {
@@ -606,7 +624,7 @@ static inline int is_logical_dev_addr_mode(unsigned char scsi3addr[])
 }
 
 static const char * const raid_label[] = { "0", "4", "1(+0)", "5", "5+1", "6",
-       "1(+0)ADM", "UNKNOWN"
+       "1(+0)ADM", "UNKNOWN", "PHYS DRV"
 };
 #define HPSA_RAID_0    0
 #define HPSA_RAID_4    1
@@ -615,7 +633,13 @@ static const char * const raid_label[] = { "0", "4", "1(+0)", "5", "5+1", "6",
 #define HPSA_RAID_51   4
 #define HPSA_RAID_6    5       /* also used for RAID 60 */
 #define HPSA_RAID_ADM  6       /* also used for RAID 1+0 ADM */
-#define RAID_UNKNOWN (ARRAY_SIZE(raid_label) - 1)
+#define RAID_UNKNOWN (ARRAY_SIZE(raid_label) - 2)
+#define PHYSICAL_DRIVE (ARRAY_SIZE(raid_label) - 1)
+
+static inline bool is_logical_device(struct hpsa_scsi_dev_t *device)
+{
+       return !device->physical_device;
+}
 
 static ssize_t raid_level_show(struct device *dev,
             struct device_attribute *attr, char *buf)
@@ -637,7 +661,7 @@ static ssize_t raid_level_show(struct device *dev,
        }
 
        /* Is this even a logical drive? */
-       if (!is_logical_dev_addr_mode(hdev->scsi3addr)) {
+       if (!is_logical_device(hdev)) {
                spin_unlock_irqrestore(&h->lock, flags);
                l = snprintf(buf, PAGE_SIZE, "N/A\n");
                return l;
@@ -726,7 +750,6 @@ static ssize_t host_show_hp_ssd_smart_path_enabled(struct device *dev,
 }
 
 #define MAX_PATHS 8
-#define PATH_STRING_LEN 50
 
 static ssize_t path_info_show(struct device *dev,
             struct device_attribute *attr, char *buf)
@@ -742,9 +765,7 @@ static ssize_t path_info_show(struct device *dev,
        u8 path_map_index = 0;
        char *active;
        unsigned char phys_connector[2];
-       unsigned char path[MAX_PATHS][PATH_STRING_LEN];
 
-       memset(path, 0, MAX_PATHS * PATH_STRING_LEN);
        sdev = to_scsi_device(dev);
        h = sdev_to_hba(sdev);
        spin_lock_irqsave(&h->devlock, flags);
@@ -764,18 +785,19 @@ static ssize_t path_info_show(struct device *dev,
                else
                        continue;
 
-               output_len = snprintf(path[i],
-                               PATH_STRING_LEN, "[%d:%d:%d:%d] %20.20s ",
+               output_len += scnprintf(buf + output_len,
+                               PAGE_SIZE - output_len,
+                               "[%d:%d:%d:%d] %20.20s ",
                                h->scsi_host->host_no,
                                hdev->bus, hdev->target, hdev->lun,
                                scsi_device_type(hdev->devtype));
 
-               if (is_ext_target(h, hdev) ||
-                       (hdev->devtype == TYPE_RAID) ||
-                       is_logical_dev_addr_mode(hdev->scsi3addr)) {
-                       output_len += snprintf(path[i] + output_len,
-                                               PATH_STRING_LEN, "%s\n",
-                                               active);
+               if (hdev->external ||
+                       hdev->devtype == TYPE_RAID ||
+                       is_logical_device(hdev)) {
+                       output_len += snprintf(buf + output_len,
+                                               PAGE_SIZE - output_len,
+                                               "%s\n", active);
                        continue;
                }
 
@@ -787,36 +809,33 @@ static ssize_t path_info_show(struct device *dev,
                if (phys_connector[1] < '0')
                        phys_connector[1] = '0';
                if (hdev->phys_connector[i] > 0)
-                       output_len += snprintf(path[i] + output_len,
-                               PATH_STRING_LEN,
+                       output_len += snprintf(buf + output_len,
+                               PAGE_SIZE - output_len,
                                "PORT: %.2s ",
                                phys_connector);
-               if (hdev->devtype == TYPE_DISK &&
-                       hdev->expose_state != HPSA_DO_NOT_EXPOSE) {
+               if (hdev->devtype == TYPE_DISK && hdev->expose_device) {
                        if (box == 0 || box == 0xFF) {
-                               output_len += snprintf(path[i] + output_len,
-                                       PATH_STRING_LEN,
+                               output_len += snprintf(buf + output_len,
+                                       PAGE_SIZE - output_len,
                                        "BAY: %hhu %s\n",
                                        bay, active);
                        } else {
-                               output_len += snprintf(path[i] + output_len,
-                                       PATH_STRING_LEN,
+                               output_len += snprintf(buf + output_len,
+                                       PAGE_SIZE - output_len,
                                        "BOX: %hhu BAY: %hhu %s\n",
                                        box, bay, active);
                        }
                } else if (box != 0 && box != 0xFF) {
-                       output_len += snprintf(path[i] + output_len,
-                               PATH_STRING_LEN, "BOX: %hhu %s\n",
+                       output_len += snprintf(buf + output_len,
+                               PAGE_SIZE - output_len, "BOX: %hhu %s\n",
                                box, active);
                } else
-                       output_len += snprintf(path[i] + output_len,
-                               PATH_STRING_LEN, "%s\n", active);
+                       output_len += snprintf(buf + output_len,
+                               PAGE_SIZE - output_len, "%s\n", active);
        }
 
        spin_unlock_irqrestore(&h->devlock, flags);
-       return snprintf(buf, output_len+1, "%s%s%s%s%s%s%s%s",
-               path[0], path[1], path[2], path[3],
-               path[4], path[5], path[6], path[7]);
+       return output_len;
 }
 
 static DEVICE_ATTR(raid_level, S_IRUGO, raid_level_show, NULL);
@@ -848,7 +867,6 @@ static struct device_attribute *hpsa_sdev_attrs[] = {
        &dev_attr_unique_id,
        &dev_attr_hp_ssd_smart_path_enabled,
        &dev_attr_path_info,
-       &dev_attr_lockup_detected,
        NULL,
 };
 
@@ -860,6 +878,7 @@ static struct device_attribute *hpsa_shost_attrs[] = {
        &dev_attr_resettable,
        &dev_attr_hp_ssd_smart_path_status,
        &dev_attr_raid_offload_debug,
+       &dev_attr_lockup_detected,
        NULL,
 };
 
@@ -1134,25 +1153,62 @@ static int hpsa_find_target_lun(struct ctlr_info *h,
        return !found;
 }
 
-static inline void hpsa_show_dev_msg(const char *level, struct ctlr_info *h,
+static void hpsa_show_dev_msg(const char *level, struct ctlr_info *h,
        struct hpsa_scsi_dev_t *dev, char *description)
 {
+#define LABEL_SIZE 25
+       char label[LABEL_SIZE];
+
+       if (h == NULL || h->pdev == NULL || h->scsi_host == NULL)
+               return;
+
+       switch (dev->devtype) {
+       case TYPE_RAID:
+               snprintf(label, LABEL_SIZE, "controller");
+               break;
+       case TYPE_ENCLOSURE:
+               snprintf(label, LABEL_SIZE, "enclosure");
+               break;
+       case TYPE_DISK:
+               if (dev->external)
+                       snprintf(label, LABEL_SIZE, "external");
+               else if (!is_logical_dev_addr_mode(dev->scsi3addr))
+                       snprintf(label, LABEL_SIZE, "%s",
+                               raid_label[PHYSICAL_DRIVE]);
+               else
+                       snprintf(label, LABEL_SIZE, "RAID-%s",
+                               dev->raid_level > RAID_UNKNOWN ? "?" :
+                               raid_label[dev->raid_level]);
+               break;
+       case TYPE_ROM:
+               snprintf(label, LABEL_SIZE, "rom");
+               break;
+       case TYPE_TAPE:
+               snprintf(label, LABEL_SIZE, "tape");
+               break;
+       case TYPE_MEDIUM_CHANGER:
+               snprintf(label, LABEL_SIZE, "changer");
+               break;
+       default:
+               snprintf(label, LABEL_SIZE, "UNKNOWN");
+               break;
+       }
+
        dev_printk(level, &h->pdev->dev,
-                       "scsi %d:%d:%d:%d: %s %s %.8s %.16s RAID-%s SSDSmartPathCap%c En%c Exp=%d\n",
+                       "scsi %d:%d:%d:%d: %s %s %.8s %.16s %s SSDSmartPathCap%c En%c Exp=%d\n",
                        h->scsi_host->host_no, dev->bus, dev->target, dev->lun,
                        description,
                        scsi_device_type(dev->devtype),
                        dev->vendor,
                        dev->model,
-                       dev->raid_level > RAID_UNKNOWN ?
-                               "RAID-?" : raid_label[dev->raid_level],
+                       label,
                        dev->offload_config ? '+' : '-',
                        dev->offload_enabled ? '+' : '-',
-                       dev->expose_state);
+                       dev->expose_device);
 }
 
 /* Add an entry into h->dev[] array. */
-static int hpsa_scsi_add_entry(struct ctlr_info *h, int hostno,
+static int hpsa_scsi_add_entry(struct ctlr_info *h,
                struct hpsa_scsi_dev_t *device,
                struct hpsa_scsi_dev_t *added[], int *nadded)
 {
@@ -1221,14 +1277,14 @@ lun_assigned:
        added[*nadded] = device;
        (*nadded)++;
        hpsa_show_dev_msg(KERN_INFO, h, device,
-               device->expose_state & HPSA_SCSI_ADD ? "added" : "masked");
+               device->expose_device ? "added" : "masked");
        device->offload_to_be_enabled = device->offload_enabled;
        device->offload_enabled = 0;
        return 0;
 }
 
 /* Update an entry in h->dev[] array. */
-static void hpsa_scsi_update_entry(struct ctlr_info *h, int hostno,
+static void hpsa_scsi_update_entry(struct ctlr_info *h,
        int entry, struct hpsa_scsi_dev_t *new_entry)
 {
        int offload_enabled;
@@ -1276,7 +1332,7 @@ static void hpsa_scsi_update_entry(struct ctlr_info *h, int hostno,
 }
 
 /* Replace an entry from h->dev[] array. */
-static void hpsa_scsi_replace_entry(struct ctlr_info *h, int hostno,
+static void hpsa_scsi_replace_entry(struct ctlr_info *h,
        int entry, struct hpsa_scsi_dev_t *new_entry,
        struct hpsa_scsi_dev_t *added[], int *nadded,
        struct hpsa_scsi_dev_t *removed[], int *nremoved)
@@ -1304,7 +1360,7 @@ static void hpsa_scsi_replace_entry(struct ctlr_info *h, int hostno,
 }
 
 /* Remove an entry from h->dev[] array. */
-static void hpsa_scsi_remove_entry(struct ctlr_info *h, int hostno, int entry,
+static void hpsa_scsi_remove_entry(struct ctlr_info *h, int entry,
        struct hpsa_scsi_dev_t *removed[], int *nremoved)
 {
        /* assumes h->devlock is held */
@@ -1415,6 +1471,9 @@ static int hpsa_scsi_find_entry(struct hpsa_scsi_dev_t *needle,
 #define DEVICE_CHANGED 1
 #define DEVICE_SAME 2
 #define DEVICE_UPDATED 3
+       if (needle == NULL)
+               return DEVICE_NOT_FOUND;
+
        for (i = 0; i < haystack_size; i++) {
                if (haystack[i] == NULL) /* previously removed. */
                        continue;
@@ -1577,9 +1636,11 @@ static void hpsa_figure_phys_disk_ptrs(struct ctlr_info *h,
                if (!logical_drive->offload_config)
                        continue;
                for (j = 0; j < ndevices; j++) {
+                       if (dev[j] == NULL)
+                               continue;
                        if (dev[j]->devtype != TYPE_DISK)
                                continue;
-                       if (is_logical_dev_addr_mode(dev[j]->scsi3addr))
+                       if (is_logical_device(dev[j]))
                                continue;
                        if (dev[j]->ioaccel_handle != dd[i].ioaccel_handle)
                                continue;
@@ -1620,9 +1681,11 @@ static void hpsa_update_log_drive_phys_drive_ptrs(struct ctlr_info *h,
        int i;
 
        for (i = 0; i < ndevices; i++) {
+               if (dev[i] == NULL)
+                       continue;
                if (dev[i]->devtype != TYPE_DISK)
                        continue;
-               if (!is_logical_dev_addr_mode(dev[i]->scsi3addr))
+               if (!is_logical_device(dev[i]))
                        continue;
 
                /*
@@ -1638,7 +1701,50 @@ static void hpsa_update_log_drive_phys_drive_ptrs(struct ctlr_info *h,
        }
 }
 
-static void adjust_hpsa_scsi_table(struct ctlr_info *h, int hostno,
+static int hpsa_add_device(struct ctlr_info *h, struct hpsa_scsi_dev_t *device)
+{
+       int rc = 0;
+
+       if (!h->scsi_host)
+               return 1;
+
+       if (is_logical_device(device)) /* RAID */
+               rc = scsi_add_device(h->scsi_host, device->bus,
+                                       device->target, device->lun);
+       else /* HBA */
+               rc = hpsa_add_sas_device(h->sas_host, device);
+
+       return rc;
+}
+
+static void hpsa_remove_device(struct ctlr_info *h,
+                       struct hpsa_scsi_dev_t *device)
+{
+       struct scsi_device *sdev = NULL;
+
+       if (!h->scsi_host)
+               return;
+
+       if (is_logical_device(device)) { /* RAID */
+               sdev = scsi_device_lookup(h->scsi_host, device->bus,
+                                               device->target, device->lun);
+               if (sdev) {
+                       scsi_remove_device(sdev);
+                       scsi_device_put(sdev);
+               } else {
+                       /*
+                        * We don't expect to get here.  Future commands
+                        * to this device will get a selection timeout as
+                        * if the device were gone.
+                        */
+                       hpsa_show_dev_msg(KERN_WARNING, h, device,
+                                       "didn't find device for removal.");
+               }
+       } else /* HBA */
+               hpsa_remove_sas_device(device);
+}
+
+static void adjust_hpsa_scsi_table(struct ctlr_info *h,
        struct hpsa_scsi_dev_t *sd[], int nsds)
 {
        /* sd contains scsi3 addresses and devtypes, and inquiry
@@ -1650,7 +1756,15 @@ static void adjust_hpsa_scsi_table(struct ctlr_info *h, int hostno,
        unsigned long flags;
        struct hpsa_scsi_dev_t **added, **removed;
        int nadded, nremoved;
-       struct Scsi_Host *sh = NULL;
+
+       /*
+        * A reset can cause a device status to change
+        * re-schedule the scan to see what happened.
+        */
+       if (h->reset_in_progress) {
+               h->drv_req_rescan = 1;
+               return;
+       }
 
        added = kzalloc(sizeof(*added) * HPSA_MAX_DEVICES, GFP_KERNEL);
        removed = kzalloc(sizeof(*removed) * HPSA_MAX_DEVICES, GFP_KERNEL);
@@ -1678,19 +1792,18 @@ static void adjust_hpsa_scsi_table(struct ctlr_info *h, int hostno,
                device_change = hpsa_scsi_find_entry(csd, sd, nsds, &entry);
                if (device_change == DEVICE_NOT_FOUND) {
                        changes++;
-                       hpsa_scsi_remove_entry(h, hostno, i,
-                               removed, &nremoved);
+                       hpsa_scsi_remove_entry(h, i, removed, &nremoved);
                        continue; /* remove ^^^, hence i not incremented */
                } else if (device_change == DEVICE_CHANGED) {
                        changes++;
-                       hpsa_scsi_replace_entry(h, hostno, i, sd[entry],
+                       hpsa_scsi_replace_entry(h, i, sd[entry],
                                added, &nadded, removed, &nremoved);
                        /* Set it to NULL to prevent it from being freed
                         * at the bottom of hpsa_update_scsi_devices()
                         */
                        sd[entry] = NULL;
                } else if (device_change == DEVICE_UPDATED) {
-                       hpsa_scsi_update_entry(h, hostno, i, sd[entry]);
+                       hpsa_scsi_update_entry(h, i, sd[entry]);
                }
                i++;
        }
@@ -1718,8 +1831,7 @@ static void adjust_hpsa_scsi_table(struct ctlr_info *h, int hostno,
                                        h->ndevices, &entry);
                if (device_change == DEVICE_NOT_FOUND) {
                        changes++;
-                       if (hpsa_scsi_add_entry(h, hostno, sd[i],
-                               added, &nadded) != 0)
+                       if (hpsa_scsi_add_entry(h, sd[i], added, &nadded) != 0)
                                break;
                        sd[i] = NULL; /* prevent from being freed later. */
                } else if (device_change == DEVICE_CHANGED) {
@@ -1735,8 +1847,11 @@ static void adjust_hpsa_scsi_table(struct ctlr_info *h, int hostno,
        /* Now that h->dev[]->phys_disk[] is coherent, we can enable
         * any logical drives that need it enabled.
         */
-       for (i = 0; i < h->ndevices; i++)
+       for (i = 0; i < h->ndevices; i++) {
+               if (h->dev[i] == NULL)
+                       continue;
                h->dev[i]->offload_enabled = h->dev[i]->offload_to_be_enabled;
+       }
 
        spin_unlock_irqrestore(&h->devlock, flags);
 
@@ -1755,47 +1870,37 @@ static void adjust_hpsa_scsi_table(struct ctlr_info *h, int hostno,
         * (or if there are no changes) scsi_scan_host will do it later the
         * first time through.
         */
-       if (hostno == -1 || !changes)
+       if (!changes)
                goto free_and_out;
 
-       sh = h->scsi_host;
        /* Notify scsi mid layer of any removed devices */
        for (i = 0; i < nremoved; i++) {
-               if (removed[i]->expose_state & HPSA_SCSI_ADD) {
-                       struct scsi_device *sdev =
-                               scsi_device_lookup(sh, removed[i]->bus,
-                                       removed[i]->target, removed[i]->lun);
-                       if (sdev != NULL) {
-                               scsi_remove_device(sdev);
-                               scsi_device_put(sdev);
-                       } else {
-                               /*
-                                * We don't expect to get here.
-                                * future cmds to this device will get selection
-                                * timeout as if the device was gone.
-                                */
-                               hpsa_show_dev_msg(KERN_WARNING, h, removed[i],
-                                       "didn't find device for removal.");
-                       }
-               }
+               if (removed[i] == NULL)
+                       continue;
+               if (removed[i]->expose_device)
+                       hpsa_remove_device(h, removed[i]);
                kfree(removed[i]);
                removed[i] = NULL;
        }
 
        /* Notify scsi mid layer of any added devices */
        for (i = 0; i < nadded; i++) {
-               if (!(added[i]->expose_state & HPSA_SCSI_ADD))
+               int rc = 0;
+
+               if (added[i] == NULL)
+                       continue;
+               if (!(added[i]->expose_device))
                        continue;
-               if (scsi_add_device(sh, added[i]->bus,
-                       added[i]->target, added[i]->lun) == 0)
+               rc = hpsa_add_device(h, added[i]);
+               if (!rc)
                        continue;
-               hpsa_show_dev_msg(KERN_WARNING, h, added[i],
-                                       "addition failed, device not added.");
+               dev_warn(&h->pdev->dev,
+                       "addition failed %d, device not added.", rc);
                /* now we have to remove it from h->dev,
                 * since it didn't get added to scsi mid layer
                 */
                fixup_botched_add(h, added[i]);
-               added[i] = NULL;
+               h->drv_req_rescan = 1;
        }
 
 free_and_out:
@@ -1829,11 +1934,24 @@ static int hpsa_slave_alloc(struct scsi_device *sdev)
 
        h = sdev_to_hba(sdev);
        spin_lock_irqsave(&h->devlock, flags);
-       sd = lookup_hpsa_scsi_dev(h, sdev_channel(sdev),
-               sdev_id(sdev), sdev->lun);
-       if (likely(sd)) {
+       if (sdev_channel(sdev) == HPSA_PHYSICAL_DEVICE_BUS) {
+               struct scsi_target *starget;
+               struct sas_rphy *rphy;
+
+               starget = scsi_target(sdev);
+               rphy = target_to_rphy(starget);
+               sd = hpsa_find_device_by_sas_rphy(h, rphy);
+               if (sd) {
+                       sd->target = sdev_id(sdev);
+                       sd->lun = sdev->lun;
+               }
+       } else
+               sd = lookup_hpsa_scsi_dev(h, sdev_channel(sdev),
+                                       sdev_id(sdev), sdev->lun);
+
+       if (sd && sd->expose_device) {
                atomic_set(&sd->ioaccel_cmds_out, 0);
-               sdev->hostdata = (sd->expose_state & HPSA_SCSI_ADD) ? sd : NULL;
+               sdev->hostdata = sd;
        } else
                sdev->hostdata = NULL;
        spin_unlock_irqrestore(&h->devlock, flags);
@@ -1847,7 +1965,7 @@ static int hpsa_slave_configure(struct scsi_device *sdev)
        int queue_depth;
 
        sd = sdev->hostdata;
-       sdev->no_uld_attach = !sd || !(sd->expose_state & HPSA_ULD_ATTACH);
+       sdev->no_uld_attach = !sd || !sd->expose_device;
 
        if (sd)
                queue_depth = sd->queue_depth != 0 ?
@@ -1955,7 +2073,7 @@ static int hpsa_map_ioaccel2_sg_chain_block(struct ctlr_info *h,
        u32 chain_size;
 
        chain_block = h->ioaccel2_cmd_sg_list[c->cmdindex];
-       chain_size = le32_to_cpu(cp->data_len);
+       chain_size = le32_to_cpu(cp->sg[0].length);
        temp64 = pci_map_single(h->pdev, chain_block, chain_size,
                                PCI_DMA_TODEVICE);
        if (dma_mapping_error(&h->pdev->dev, temp64)) {
@@ -1976,7 +2094,7 @@ static void hpsa_unmap_ioaccel2_sg_chain_block(struct ctlr_info *h,
 
        chain_sg = cp->sg;
        temp64 = le64_to_cpu(chain_sg->address);
-       chain_size = le32_to_cpu(cp->data_len);
+       chain_size = le32_to_cpu(cp->sg[0].length);
        pci_unmap_single(h->pdev, temp64, chain_size, PCI_DMA_TODEVICE);
 }
 
@@ -2210,7 +2328,7 @@ static void process_ioaccel2_completion(struct ctlr_info *h,
         * the normal I/O path so the controller can handle whatever's
         * wrong.
         */
-       if (is_logical_dev_addr_mode(dev->scsi3addr) &&
+       if (is_logical_device(dev) &&
                c2->error_data.serv_response ==
                        IOACCEL2_SERV_RESPONSE_FAILURE) {
                if (c2->error_data.status ==
@@ -2330,7 +2448,7 @@ static void complete_scsi_command(struct CommandList *cp)
                 * the normal I/O path so the controller can handle whatever's
                 * wrong.
                 */
-               if (is_logical_dev_addr_mode(dev->scsi3addr)) {
+               if (is_logical_device(dev)) {
                        if (ei->CommandStatus == CMD_IOACCEL_DISABLED)
                                dev->offload_enabled = 0;
                        return hpsa_retry_cmd(h, cp);
@@ -2709,9 +2827,8 @@ static int hpsa_send_reset(struct ctlr_info *h, unsigned char *scsi3addr,
 
 
        /* fill_cmd can't fail here, no data buffer to map. */
-       (void) fill_cmd(c, HPSA_DEVICE_RESET_MSG, h, NULL, 0, 0,
+       (void) fill_cmd(c, reset_type, h, NULL, 0, 0,
                        scsi3addr, TYPE_MSG);
-       c->Request.CDB[1] = reset_type; /* fill_cmd defaults to LUN reset */
        rc = hpsa_scsi_do_simple_cmd(h, c, reply_queue, NO_TIMEOUT);
        if (rc) {
                dev_warn(&h->pdev->dev, "Failed to send reset command\n");
@@ -2984,6 +3101,66 @@ out:
        return rc;
 }
 
+static int hpsa_bmic_sense_subsystem_information(struct ctlr_info *h,
+               unsigned char scsi3addr[], u16 bmic_device_index,
+               struct bmic_sense_subsystem_info *buf, size_t bufsize)
+{
+       int rc = IO_OK;
+       struct CommandList *c;
+       struct ErrorInfo *ei;
+
+       c = cmd_alloc(h);
+
+       rc = fill_cmd(c, BMIC_SENSE_SUBSYSTEM_INFORMATION, h, buf, bufsize,
+               0, RAID_CTLR_LUNID, TYPE_CMD);
+       if (rc)
+               goto out;
+
+       c->Request.CDB[2] = bmic_device_index & 0xff;
+       c->Request.CDB[9] = (bmic_device_index >> 8) & 0xff;
+
+       rc = hpsa_scsi_do_simple_cmd_with_retry(h, c,
+                               PCI_DMA_FROMDEVICE, NO_TIMEOUT);
+       if (rc)
+               goto out;
+       ei = c->err_info;
+       if (ei->CommandStatus != 0 && ei->CommandStatus != CMD_DATA_UNDERRUN) {
+               hpsa_scsi_interpret_error(h, c);
+               rc = -1;
+       }
+out:
+       cmd_free(h, c);
+       return rc;
+}
+
+static int hpsa_bmic_id_controller(struct ctlr_info *h,
+       struct bmic_identify_controller *buf, size_t bufsize)
+{
+       int rc = IO_OK;
+       struct CommandList *c;
+       struct ErrorInfo *ei;
+
+       c = cmd_alloc(h);
+
+       rc = fill_cmd(c, BMIC_IDENTIFY_CONTROLLER, h, buf, bufsize,
+               0, RAID_CTLR_LUNID, TYPE_CMD);
+       if (rc)
+               goto out;
+
+       rc = hpsa_scsi_do_simple_cmd_with_retry(h, c,
+               PCI_DMA_FROMDEVICE, NO_TIMEOUT);
+       if (rc)
+               goto out;
+       ei = c->err_info;
+       if (ei->CommandStatus != 0 && ei->CommandStatus != CMD_DATA_UNDERRUN) {
+               hpsa_scsi_interpret_error(h, c);
+               rc = -1;
+       }
+out:
+       cmd_free(h, c);
+       return rc;
+}
+
 static int hpsa_bmic_id_physical_device(struct ctlr_info *h,
                unsigned char scsi3addr[], u16 bmic_device_index,
                struct bmic_identify_physical_device *buf, size_t bufsize)
@@ -3010,9 +3187,71 @@ static int hpsa_bmic_id_physical_device(struct ctlr_info *h,
        }
 out:
        cmd_free(h, c);
+
        return rc;
 }
 
+static u64 hpsa_get_sas_address_from_report_physical(struct ctlr_info *h,
+                                               unsigned char *scsi3addr)
+{
+       struct ReportExtendedLUNdata *physdev;
+       u32 nphysicals;
+       u64 sa = 0;
+       int i;
+
+       physdev = kzalloc(sizeof(*physdev), GFP_KERNEL);
+       if (!physdev)
+               return 0;
+
+       if (hpsa_scsi_do_report_phys_luns(h, physdev, sizeof(*physdev))) {
+               dev_err(&h->pdev->dev, "report physical LUNs failed.\n");
+               kfree(physdev);
+               return 0;
+       }
+       nphysicals = get_unaligned_be32(physdev->LUNListLength) / 24;
+
+       for (i = 0; i < nphysicals; i++)
+               if (!memcmp(&physdev->LUN[i].lunid[0], scsi3addr, 8)) {
+                       sa = get_unaligned_be64(&physdev->LUN[i].wwid[0]);
+                       break;
+               }
+
+       kfree(physdev);
+
+       return sa;
+}
+
+static void hpsa_get_sas_address(struct ctlr_info *h, unsigned char *scsi3addr,
+                                       struct hpsa_scsi_dev_t *dev)
+{
+       int rc;
+       u64 sa = 0;
+
+       if (is_hba_lunid(scsi3addr)) {
+               struct bmic_sense_subsystem_info *ssi;
+
+               ssi = kzalloc(sizeof(*ssi), GFP_KERNEL);
+               if (ssi == NULL) {
+                       dev_warn(&h->pdev->dev,
+                               "%s: out of memory\n", __func__);
+                       return;
+               }
+
+               rc = hpsa_bmic_sense_subsystem_information(h,
+                                       scsi3addr, 0, ssi, sizeof(*ssi));
+               if (rc == 0) {
+                       sa = get_unaligned_be64(ssi->primary_world_wide_id);
+                       h->sas_address = sa;
+               }
+
+               kfree(ssi);
+       } else
+               sa = hpsa_get_sas_address_from_report_physical(h, scsi3addr);
+
+       dev->sas_address = sa;
+}
+
+/* Get a device id from inquiry page 0x83 */
 static int hpsa_vpd_page_supported(struct ctlr_info *h,
        unsigned char scsi3addr[], u8 page)
 {
@@ -3097,7 +3336,7 @@ out:
 
 /* Get the device id from inquiry page 0x83 */
 static int hpsa_get_device_id(struct ctlr_info *h, unsigned char *scsi3addr,
-       unsigned char *device_id, int buflen)
+       unsigned char *device_id, int index, int buflen)
 {
        int rc;
        unsigned char *buf;
@@ -3109,8 +3348,10 @@ static int hpsa_get_device_id(struct ctlr_info *h, unsigned char *scsi3addr,
                return -ENOMEM;
        rc = hpsa_scsi_do_inquiry(h, scsi3addr, VPD_PAGE | 0x83, buf, 64);
        if (rc == 0)
-               memcpy(device_id, &buf[8], buflen);
+               memcpy(device_id, &buf[index], buflen);
+
        kfree(buf);
+
        return rc != 0;
 }
 
@@ -3339,6 +3580,18 @@ static int hpsa_device_supports_aborts(struct ctlr_info *h,
        return rc;
 }
 
+static void sanitize_inquiry_string(unsigned char *s, int len)
+{
+       bool terminated = false;
+
+       for (; len > 0; (--len, ++s)) {
+               if (*s == 0)
+                       terminated = true;
+               if (terminated || *s < 0x20 || *s > 0x7e)
+                       *s = ' ';
+       }
+}
+
 static int hpsa_update_device_info(struct ctlr_info *h,
        unsigned char scsi3addr[], struct hpsa_scsi_dev_t *this_device,
        unsigned char *is_OBDR_device)
@@ -3351,10 +3604,13 @@ static int hpsa_update_device_info(struct ctlr_info *h,
 
        unsigned char *inq_buff;
        unsigned char *obdr_sig;
+       int rc = 0;
 
        inq_buff = kzalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL);
-       if (!inq_buff)
+       if (!inq_buff) {
+               rc = -ENOMEM;
                goto bail_out;
+       }
 
        /* Do an inquiry to the device to see what it is. */
        if (hpsa_scsi_do_inquiry(h, scsi3addr, 0, inq_buff,
@@ -3362,9 +3618,13 @@ static int hpsa_update_device_info(struct ctlr_info *h,
                /* Inquiry failed (msg printed already) */
                dev_err(&h->pdev->dev,
                        "hpsa_update_device_info: inquiry failed\n");
+               rc = -EIO;
                goto bail_out;
        }
 
+       sanitize_inquiry_string(&inq_buff[8], 8);
+       sanitize_inquiry_string(&inq_buff[16], 16);
+
        this_device->devtype = (inq_buff[0] & 0x1f);
        memcpy(this_device->scsi3addr, scsi3addr, 8);
        memcpy(this_device->vendor, &inq_buff[8],
@@ -3373,7 +3633,7 @@ static int hpsa_update_device_info(struct ctlr_info *h,
                sizeof(this_device->model));
        memset(this_device->device_id, 0,
                sizeof(this_device->device_id));
-       hpsa_get_device_id(h, scsi3addr, this_device->device_id,
+       hpsa_get_device_id(h, scsi3addr, this_device->device_id, 8,
                sizeof(this_device->device_id));
 
        if (this_device->devtype == TYPE_DISK &&
@@ -3411,7 +3671,7 @@ static int hpsa_update_device_info(struct ctlr_info *h,
 
 bail_out:
        kfree(inq_buff);
-       return 1;
+       return rc;
 }
 
 static void hpsa_update_device_supports_aborts(struct ctlr_info *h,
@@ -3439,115 +3699,39 @@ static void hpsa_update_device_supports_aborts(struct ctlr_info *h,
        }
 }
 
-static unsigned char *ext_target_model[] = {
-       "MSA2012",
-       "MSA2024",
-       "MSA2312",
-       "MSA2324",
-       "P2000 G3 SAS",
-       "MSA 2040 SAS",
-       NULL,
-};
-
-static int is_ext_target(struct ctlr_info *h, struct hpsa_scsi_dev_t *device)
-{
-       int i;
-
-       for (i = 0; ext_target_model[i]; i++)
-               if (strncmp(device->model, ext_target_model[i],
-                       strlen(ext_target_model[i])) == 0)
-                       return 1;
-       return 0;
-}
-
-/* Helper function to assign bus, target, lun mapping of devices.
- * Puts non-external target logical volumes on bus 0, external target logical
- * volumes on bus 1, physical devices on bus 2. and the hba on bus 3.
+/*
+ * Helper function to assign bus, target, lun mapping of devices.
  * Logical drive target and lun are assigned at this time, but
  * physical device lun and target assignment are deferred (assigned
  * in hpsa_find_target_lun, called by hpsa_scsi_add_entry.)
- */
+*/
 static void figure_bus_target_lun(struct ctlr_info *h,
        u8 *lunaddrbytes, struct hpsa_scsi_dev_t *device)
 {
-       u32 lunid = le32_to_cpu(*((__le32 *) lunaddrbytes));
+       u32 lunid = get_unaligned_le32(lunaddrbytes);
 
        if (!is_logical_dev_addr_mode(lunaddrbytes)) {
                /* physical device, target and lun filled in later */
                if (is_hba_lunid(lunaddrbytes))
-                       hpsa_set_bus_target_lun(device, 3, 0, lunid & 0x3fff);
+                       hpsa_set_bus_target_lun(device,
+                                       HPSA_HBA_BUS, 0, lunid & 0x3fff);
                else
                        /* defer target, lun assignment for physical devices */
-                       hpsa_set_bus_target_lun(device, 2, -1, -1);
+                       hpsa_set_bus_target_lun(device,
+                                       HPSA_PHYSICAL_DEVICE_BUS, -1, -1);
                return;
        }
        /* It's a logical device */
-       if (is_ext_target(h, device)) {
-               /* external target way, put logicals on bus 1
-                * and match target/lun numbers box
-                * reports, other smart array, bus 0, target 0, match lunid
-                */
+       if (device->external) {
                hpsa_set_bus_target_lun(device,
-                       1, (lunid >> 16) & 0x3fff, lunid & 0x00ff);
+                       HPSA_EXTERNAL_RAID_VOLUME_BUS, (lunid >> 16) & 0x3fff,
+                       lunid & 0x00ff);
                return;
        }
-       hpsa_set_bus_target_lun(device, 0, 0, lunid & 0x3fff);
+       hpsa_set_bus_target_lun(device, HPSA_RAID_VOLUME_BUS,
+                               0, lunid & 0x3fff);
 }
 
-/*
- * If there is no lun 0 on a target, linux won't find any devices.
- * For the external targets (arrays), we have to manually detect the enclosure
- * which is at lun zero, as CCISS_REPORT_PHYSICAL_LUNS doesn't report
- * it for some reason.  *tmpdevice is the target we're adding,
- * this_device is a pointer into the current element of currentsd[]
- * that we're building up in update_scsi_devices(), below.
- * lunzerobits is a bitmap that tracks which targets already have a
- * lun 0 assigned.
- * Returns 1 if an enclosure was added, 0 if not.
- */
-static int add_ext_target_dev(struct ctlr_info *h,
-       struct hpsa_scsi_dev_t *tmpdevice,
-       struct hpsa_scsi_dev_t *this_device, u8 *lunaddrbytes,
-       unsigned long lunzerobits[], int *n_ext_target_devs)
-{
-       unsigned char scsi3addr[8];
-
-       if (test_bit(tmpdevice->target, lunzerobits))
-               return 0; /* There is already a lun 0 on this target. */
-
-       if (!is_logical_dev_addr_mode(lunaddrbytes))
-               return 0; /* It's the logical targets that may lack lun 0. */
-
-       if (!is_ext_target(h, tmpdevice))
-               return 0; /* Only external target devices have this problem. */
-
-       if (tmpdevice->lun == 0) /* if lun is 0, then we have a lun 0. */
-               return 0;
-
-       memset(scsi3addr, 0, 8);
-       scsi3addr[3] = tmpdevice->target;
-       if (is_hba_lunid(scsi3addr))
-               return 0; /* Don't add the RAID controller here. */
-
-       if (is_scsi_rev_5(h))
-               return 0; /* p1210m doesn't need to do this. */
-
-       if (*n_ext_target_devs >= MAX_EXT_TARGETS) {
-               dev_warn(&h->pdev->dev, "Maximum number of external "
-                       "target devices exceeded.  Check your hardware "
-                       "configuration.");
-               return 0;
-       }
-
-       if (hpsa_update_device_info(h, scsi3addr, this_device, NULL))
-               return 0;
-       (*n_ext_target_devs)++;
-       hpsa_set_bus_target_lun(this_device,
-                               tmpdevice->bus, tmpdevice->target, 0);
-       hpsa_update_device_supports_aborts(h, this_device, scsi3addr);
-       set_bit(tmpdevice->target, lunzerobits);
-       return 1;
-}
 
 /*
  * Get address of physical disk used for an ioaccel2 mode command:
@@ -3577,6 +3761,27 @@ static int hpsa_get_pdisk_of_ioaccel2(struct ctlr_info *h,
        return 0;
 }
 
+static int  figure_external_status(struct ctlr_info *h, int raid_ctlr_position,
+       int i, int nphysicals, int nlocal_logicals)
+{
+       /* In report logicals, local logicals are listed first,
+       * then any externals.
+       */
+       int logicals_start = nphysicals + (raid_ctlr_position == 0);
+
+       if (i == raid_ctlr_position)
+               return 0;
+
+       if (i < logicals_start)
+               return 0;
+
+       /* i is in logicals range, but still within local logicals */
+       if ((i - nphysicals - (raid_ctlr_position == 0)) < nlocal_logicals)
+               return 0;
+
+       return 1; /* it's an external lun */
+}
+
 /*
  * Do CISS_REPORT_PHYS and CISS_REPORT_LOG.  Data is returned in physdev,
  * logdev.  The number of luns in physdev and logdev are returned in
@@ -3650,19 +3855,18 @@ static u8 *figure_lunaddrbytes(struct ctlr_info *h, int raid_ctlr_position,
 /* get physical drive ioaccel handle and queue depth */
 static void hpsa_get_ioaccel_drive_info(struct ctlr_info *h,
                struct hpsa_scsi_dev_t *dev,
-               u8 *lunaddrbytes,
+               struct ReportExtendedLUNdata *rlep, int rle_index,
                struct bmic_identify_physical_device *id_phys)
 {
        int rc;
-       struct ext_report_lun_entry *rle =
-               (struct ext_report_lun_entry *) lunaddrbytes;
+       struct ext_report_lun_entry *rle = &rlep->LUN[rle_index];
 
        dev->ioaccel_handle = rle->ioaccel_handle;
-       if (PHYS_IOACCEL(lunaddrbytes) && dev->ioaccel_handle)
+       if ((rle->device_flags & 0x08) && dev->ioaccel_handle)
                dev->hba_ioaccel_enabled = 1;
        memset(id_phys, 0, sizeof(*id_phys));
-       rc = hpsa_bmic_id_physical_device(h, lunaddrbytes,
-                       GET_BMIC_DRIVE_NUMBER(lunaddrbytes), id_phys,
+       rc = hpsa_bmic_id_physical_device(h, &rle->lunid[0],
+                       GET_BMIC_DRIVE_NUMBER(&rle->lunid[0]), id_phys,
                        sizeof(*id_phys));
        if (!rc)
                /* Reserve space for FW operations */
@@ -3673,16 +3877,15 @@ static void hpsa_get_ioaccel_drive_info(struct ctlr_info *h,
                                DRIVE_CMDS_RESERVED_FOR_FW;
        else
                dev->queue_depth = DRIVE_QUEUE_DEPTH; /* conservative */
-       atomic_set(&dev->ioaccel_cmds_out, 0);
-       atomic_set(&dev->reset_cmds_out, 0);
 }
 
 static void hpsa_get_path_info(struct hpsa_scsi_dev_t *this_device,
-       u8 *lunaddrbytes,
+       struct ReportExtendedLUNdata *rlep, int rle_index,
        struct bmic_identify_physical_device *id_phys)
 {
-       if (PHYS_IOACCEL(lunaddrbytes)
-               && this_device->ioaccel_handle)
+       struct ext_report_lun_entry *rle = &rlep->LUN[rle_index];
+
+       if ((rle->device_flags & 0x08) && this_device->ioaccel_handle)
                this_device->hba_ioaccel_enabled = 1;
 
        memcpy(&this_device->active_path_index,
@@ -3702,7 +3905,33 @@ static void hpsa_get_path_info(struct hpsa_scsi_dev_t *this_device,
                sizeof(this_device->bay));
 }
 
-static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
+/* get number of local logical disks. */
+static int hpsa_set_local_logical_count(struct ctlr_info *h,
+       struct bmic_identify_controller *id_ctlr,
+       u32 *nlocals)
+{
+       int rc;
+
+       if (!id_ctlr) {
+               dev_warn(&h->pdev->dev, "%s: id_ctlr buffer is NULL.\n",
+                       __func__);
+               return -ENOMEM;
+       }
+       memset(id_ctlr, 0, sizeof(*id_ctlr));
+       rc = hpsa_bmic_id_controller(h, id_ctlr, sizeof(*id_ctlr));
+       if (!rc)
+               if (id_ctlr->configured_logical_drive_count < 256)
+                       *nlocals = id_ctlr->configured_logical_drive_count;
+               else
+                       *nlocals = le16_to_cpu(
+                                       id_ctlr->extended_logical_unit_count);
+       else
+               *nlocals = -1;
+       return rc;
+}
+
+
+static void hpsa_update_scsi_devices(struct ctlr_info *h)
 {
        /* the idea here is we could get notified
         * that some devices have changed, so we do a report
@@ -3717,13 +3946,16 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
        struct ReportExtendedLUNdata *physdev_list = NULL;
        struct ReportLUNdata *logdev_list = NULL;
        struct bmic_identify_physical_device *id_phys = NULL;
+       struct bmic_identify_controller *id_ctlr = NULL;
        u32 nphysicals = 0;
        u32 nlogicals = 0;
+       u32 nlocal_logicals = 0;
        u32 ndev_allocated = 0;
        struct hpsa_scsi_dev_t **currentsd, *this_device, *tmpdevice;
        int ncurrent = 0;
        int i, n_ext_target_devs, ndevs_to_allocate;
        int raid_ctlr_position;
+       bool physical_device;
        DECLARE_BITMAP(lunzerobits, MAX_EXT_TARGETS);
 
        currentsd = kzalloc(sizeof(*currentsd) * HPSA_MAX_DEVICES, GFP_KERNEL);
@@ -3731,17 +3963,29 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
        logdev_list = kzalloc(sizeof(*logdev_list), GFP_KERNEL);
        tmpdevice = kzalloc(sizeof(*tmpdevice), GFP_KERNEL);
        id_phys = kzalloc(sizeof(*id_phys), GFP_KERNEL);
+       id_ctlr = kzalloc(sizeof(*id_ctlr), GFP_KERNEL);
 
        if (!currentsd || !physdev_list || !logdev_list ||
-               !tmpdevice || !id_phys) {
+               !tmpdevice || !id_phys || !id_ctlr) {
                dev_err(&h->pdev->dev, "out of memory\n");
                goto out;
        }
        memset(lunzerobits, 0, sizeof(lunzerobits));
 
+       h->drv_req_rescan = 0; /* cancel scheduled rescan - we're doing it. */
+
        if (hpsa_gather_lun_info(h, physdev_list, &nphysicals,
-                       logdev_list, &nlogicals))
+                       logdev_list, &nlogicals)) {
+               h->drv_req_rescan = 1;
                goto out;
+       }
+
+       /* Set number of local logicals (non PTRAID) */
+       if (hpsa_set_local_logical_count(h, id_ctlr, &nlocal_logicals)) {
+               dev_warn(&h->pdev->dev,
+                       "%s: Can't determine number of local logical devices.\n",
+                       __func__);
+       }
 
        /* We might see up to the maximum number of logical and physical disks
         * plus external target devices, and a device for the local RAID
@@ -3762,6 +4006,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
                if (!currentsd[i]) {
                        dev_warn(&h->pdev->dev, "out of memory at %s:%d\n",
                                __FILE__, __LINE__);
+                       h->drv_req_rescan = 1;
                        goto out;
                }
                ndev_allocated++;
@@ -3776,49 +4021,74 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
        n_ext_target_devs = 0;
        for (i = 0; i < nphysicals + nlogicals + 1; i++) {
                u8 *lunaddrbytes, is_OBDR = 0;
+               int rc = 0;
+               int phys_dev_index = i - (raid_ctlr_position == 0);
+
+               physical_device = i < nphysicals + (raid_ctlr_position == 0);
 
                /* Figure out where the LUN ID info is coming from */
                lunaddrbytes = figure_lunaddrbytes(h, raid_ctlr_position,
                        i, nphysicals, nlogicals, physdev_list, logdev_list);
 
                /* skip masked non-disk devices */
-               if (MASKED_DEVICE(lunaddrbytes))
-                       if (i < nphysicals + (raid_ctlr_position == 0) &&
-                               NON_DISK_PHYS_DEV(lunaddrbytes))
-                               continue;
+               if (MASKED_DEVICE(lunaddrbytes) && physical_device &&
+                       (physdev_list->LUN[phys_dev_index].device_flags & 0x01))
+                       continue;
 
                /* Get device type, vendor, model, device id */
-               if (hpsa_update_device_info(h, lunaddrbytes, tmpdevice,
-                                                       &is_OBDR))
-                       continue; /* skip it if we can't talk to it. */
+               rc = hpsa_update_device_info(h, lunaddrbytes, tmpdevice,
+                                                       &is_OBDR);
+               if (rc == -ENOMEM) {
+                       dev_warn(&h->pdev->dev,
+                               "Out of memory, rescan deferred.\n");
+                       h->drv_req_rescan = 1;
+                       goto out;
+               }
+               if (rc) {
+                       dev_warn(&h->pdev->dev,
+                               "Inquiry failed, skipping device.\n");
+                       continue;
+               }
+
+               /* Determine if this is a lun from an external target array */
+               tmpdevice->external =
+                       figure_external_status(h, raid_ctlr_position, i,
+                                               nphysicals, nlocal_logicals);
+
                figure_bus_target_lun(h, lunaddrbytes, tmpdevice);
                hpsa_update_device_supports_aborts(h, tmpdevice, lunaddrbytes);
                this_device = currentsd[ncurrent];
 
-               /*
-                * For external target devices, we have to insert a LUN 0 which
-                * doesn't show up in CCISS_REPORT_PHYSICAL data, but there
-                * is nonetheless an enclosure device there.  We have to
-                * present that otherwise linux won't find anything if
-                * there is no lun 0.
+               /* Turn on discovery_polling if there are ext target devices.
+                * Event-based change notification is unreliable for those.
                 */
-               if (add_ext_target_dev(h, tmpdevice, this_device,
-                               lunaddrbytes, lunzerobits,
-                               &n_ext_target_devs)) {
-                       ncurrent++;
-                       this_device = currentsd[ncurrent];
+               if (!h->discovery_polling) {
+                       if (tmpdevice->external) {
+                               h->discovery_polling = 1;
+                               dev_info(&h->pdev->dev,
+                                       "External target, activate discovery polling.\n");
+                       }
                }
 
+
                *this_device = *tmpdevice;
+               this_device->physical_device = physical_device;
 
-               /* do not expose masked devices */
-               if (MASKED_DEVICE(lunaddrbytes) &&
-                       i < nphysicals + (raid_ctlr_position == 0)) {
-                       this_device->expose_state = HPSA_DO_NOT_EXPOSE;
-               } else {
-                       this_device->expose_state =
-                                       HPSA_SG_ATTACH | HPSA_ULD_ATTACH;
-               }
+               /*
+                * Expose all devices except for physical devices that
+                * are masked.
+                */
+               if (MASKED_DEVICE(lunaddrbytes) && this_device->physical_device)
+                       this_device->expose_device = 0;
+               else
+                       this_device->expose_device = 1;
+
+
+               /*
+                * Get the SAS address for physical devices that are exposed.
+                */
+               if (this_device->physical_device && this_device->expose_device)
+                       hpsa_get_sas_address(h, lunaddrbytes, this_device);
 
                switch (this_device->devtype) {
                case TYPE_ROM:
@@ -3833,14 +4103,14 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
                                ncurrent++;
                        break;
                case TYPE_DISK:
-                       if (i < nphysicals + (raid_ctlr_position == 0)) {
+                       if (this_device->physical_device) {
                                /* The disk is in HBA mode. */
                                /* Never use RAID mapper in HBA mode. */
                                this_device->offload_enabled = 0;
                                hpsa_get_ioaccel_drive_info(h, this_device,
-                                       lunaddrbytes, id_phys);
-                               hpsa_get_path_info(this_device, lunaddrbytes,
-                                                       id_phys);
+                                       physdev_list, phys_dev_index, id_phys);
+                               hpsa_get_path_info(this_device,
+                                       physdev_list, phys_dev_index, id_phys);
                        }
                        ncurrent++;
                        break;
@@ -3865,7 +4135,19 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
                if (ncurrent >= HPSA_MAX_DEVICES)
                        break;
        }
-       adjust_hpsa_scsi_table(h, hostno, currentsd, ncurrent);
+
+       if (h->sas_host == NULL) {
+               int rc = 0;
+
+               rc = hpsa_add_sas_host(h);
+               if (rc) {
+                       dev_warn(&h->pdev->dev,
+                               "Could not add sas host %d\n", rc);
+                       goto out;
+               }
+       }
+
+       adjust_hpsa_scsi_table(h, currentsd, ncurrent);
 out:
        kfree(tmpdevice);
        for (i = 0; i < ndev_allocated; i++)
@@ -3873,6 +4155,7 @@ out:
        kfree(currentsd);
        kfree(physdev_list);
        kfree(logdev_list);
+       kfree(id_ctlr);
        kfree(id_phys);
 }
 
@@ -3978,19 +4261,14 @@ static int fixup_ioaccel_cdb(u8 *cdb, int *cdb_len)
        case READ_6:
        case READ_12:
                if (*cdb_len == 6) {
-                       block = (((u32) cdb[2]) << 8) | cdb[3];
+                       block = get_unaligned_be16(&cdb[2]);
                        block_cnt = cdb[4];
+                       if (block_cnt == 0)
+                               block_cnt = 256;
                } else {
                        BUG_ON(*cdb_len != 12);
-                       block = (((u32) cdb[2]) << 24) |
-                               (((u32) cdb[3]) << 16) |
-                               (((u32) cdb[4]) << 8) |
-                               cdb[5];
-                       block_cnt =
-                               (((u32) cdb[6]) << 24) |
-                               (((u32) cdb[7]) << 16) |
-                               (((u32) cdb[8]) << 8) |
-                               cdb[9];
+                       block = get_unaligned_be32(&cdb[2]);
+                       block_cnt = get_unaligned_be32(&cdb[6]);
                }
                if (block_cnt > 0xffff)
                        return IO_ACCEL_INELIGIBLE;
@@ -4272,6 +4550,7 @@ static int hpsa_scsi_ioaccel2_queue_command(struct ctlr_info *h,
        /* fill in sg elements */
        if (use_sg > h->ioaccel_maxsg) {
                cp->sg_count = 1;
+               cp->sg[0].length = cpu_to_le32(use_sg * sizeof(cp->sg[0]));
                if (hpsa_map_ioaccel2_sg_chain_block(h, cp, c)) {
                        atomic_dec(&phys_disk->ioaccel_cmds_out);
                        scsi_dma_unmap(cmd);
@@ -4376,9 +4655,7 @@ static int hpsa_scsi_ioaccel_raid_map(struct ctlr_info *h,
        case WRITE_6:
                is_write = 1;
        case READ_6:
-               first_block =
-                       (((u64) cmd->cmnd[2]) << 8) |
-                       cmd->cmnd[3];
+               first_block = get_unaligned_be16(&cmd->cmnd[2]);
                block_cnt = cmd->cmnd[4];
                if (block_cnt == 0)
                        block_cnt = 256;
@@ -4947,7 +5224,7 @@ static void hpsa_scan_start(struct Scsi_Host *sh)
        if (unlikely(lockup_detected(h)))
                return hpsa_scan_complete(h);
 
-       hpsa_update_scsi_devices(h, h->scsi_host->host_no);
+       hpsa_update_scsi_devices(h);
 
        hpsa_scan_complete(h);
 }
@@ -4983,7 +5260,6 @@ static int hpsa_scan_finished(struct Scsi_Host *sh,
 static int hpsa_scsi_host_alloc(struct ctlr_info *h)
 {
        struct Scsi_Host *sh;
-       int error;
 
        sh = scsi_host_alloc(&hpsa_driver_template, sizeof(h));
        if (sh == NULL) {
@@ -5001,17 +5277,11 @@ static int hpsa_scsi_host_alloc(struct ctlr_info *h)
        sh->can_queue = h->nr_cmds - HPSA_NRESERVED_CMDS;
        sh->cmd_per_lun = sh->can_queue;
        sh->sg_tablesize = h->maxsgentries;
+       sh->transportt = hpsa_sas_transport_template;
        sh->hostdata[0] = (unsigned long) h;
        sh->irq = h->intr[h->intr_mode];
        sh->unique_id = sh->irq;
-       error = scsi_init_shared_tag_map(sh, sh->can_queue);
-       if (error) {
-               dev_err(&h->pdev->dev,
-                       "%s: scsi_init_shared_tag_map failed for controller %d\n",
-                       __func__, h->ctlr);
-                       scsi_host_put(sh);
-                       return error;
-       }
+
        h->scsi_host = sh;
        return 0;
 }
@@ -5167,6 +5437,7 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
        int rc;
        struct ctlr_info *h;
        struct hpsa_scsi_dev_t *dev;
+       u8 reset_type;
        char msg[48];
 
        /* find the controller to which the command to be aborted was sent */
@@ -5205,14 +5476,25 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
        if (is_hba_lunid(dev->scsi3addr))
                return SUCCESS;
 
-       hpsa_show_dev_msg(KERN_WARNING, h, dev, "resetting");
+       if (is_logical_dev_addr_mode(dev->scsi3addr))
+               reset_type = HPSA_DEVICE_RESET_MSG;
+       else
+               reset_type = HPSA_PHYS_TARGET_RESET;
+
+       sprintf(msg, "resetting %s",
+               reset_type == HPSA_DEVICE_RESET_MSG ? "logical " : "physical ");
+       hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
+
+       h->reset_in_progress = 1;
 
        /* send a reset to the SCSI LUN which the command was sent to */
-       rc = hpsa_do_reset(h, dev, dev->scsi3addr, HPSA_RESET_TYPE_LUN,
+       rc = hpsa_do_reset(h, dev, dev->scsi3addr, reset_type,
                           DEFAULT_REPLY_QUEUE);
-       snprintf(msg, sizeof(msg), "reset %s",
-                rc == 0 ? "completed successfully" : "failed");
+       sprintf(msg, "reset %s %s",
+               reset_type == HPSA_DEVICE_RESET_MSG ? "logical " : "physical ",
+               rc == 0 ? "completed successfully" : "failed");
        hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
+       h->reset_in_progress = 0;
        return rc == 0 ? SUCCESS : FAILED;
 }
 
@@ -6270,6 +6552,24 @@ static int fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h,
                        c->Request.CDB[8] = (size >> 8) & 0xFF;
                        c->Request.CDB[9] = size & 0xFF;
                        break;
+               case BMIC_SENSE_DIAG_OPTIONS:
+                       c->Request.CDBLen = 16;
+                       c->Request.type_attr_dir =
+                               TYPE_ATTR_DIR(cmd_type, ATTR_SIMPLE, XFER_READ);
+                       c->Request.Timeout = 0;
+                       /* Spec says this should be BMIC_WRITE */
+                       c->Request.CDB[0] = BMIC_READ;
+                       c->Request.CDB[6] = BMIC_SENSE_DIAG_OPTIONS;
+                       break;
+               case BMIC_SET_DIAG_OPTIONS:
+                       c->Request.CDBLen = 16;
+                       c->Request.type_attr_dir =
+                                       TYPE_ATTR_DIR(cmd_type,
+                                               ATTR_SIMPLE, XFER_WRITE);
+                       c->Request.Timeout = 0;
+                       c->Request.CDB[0] = BMIC_WRITE;
+                       c->Request.CDB[6] = BMIC_SET_DIAG_OPTIONS;
+                       break;
                case HPSA_CACHE_FLUSH:
                        c->Request.CDBLen = 12;
                        c->Request.type_attr_dir =
@@ -6319,6 +6619,32 @@ static int fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h,
                        c->Request.CDB[7] = (size >> 16) & 0xFF;
                        c->Request.CDB[8] = (size >> 8) & 0XFF;
                        break;
+               case BMIC_SENSE_SUBSYSTEM_INFORMATION:
+                       c->Request.CDBLen = 10;
+                       c->Request.type_attr_dir =
+                               TYPE_ATTR_DIR(cmd_type, ATTR_SIMPLE, XFER_READ);
+                       c->Request.Timeout = 0;
+                       c->Request.CDB[0] = BMIC_READ;
+                       c->Request.CDB[6] = BMIC_SENSE_SUBSYSTEM_INFORMATION;
+                       c->Request.CDB[7] = (size >> 16) & 0xFF;
+                       c->Request.CDB[8] = (size >> 8) & 0XFF;
+                       break;
+               case BMIC_IDENTIFY_CONTROLLER:
+                       c->Request.CDBLen = 10;
+                       c->Request.type_attr_dir =
+                               TYPE_ATTR_DIR(cmd_type, ATTR_SIMPLE, XFER_READ);
+                       c->Request.Timeout = 0;
+                       c->Request.CDB[0] = BMIC_READ;
+                       c->Request.CDB[1] = 0;
+                       c->Request.CDB[2] = 0;
+                       c->Request.CDB[3] = 0;
+                       c->Request.CDB[4] = 0;
+                       c->Request.CDB[5] = 0;
+                       c->Request.CDB[6] = BMIC_IDENTIFY_CONTROLLER;
+                       c->Request.CDB[7] = (size >> 16) & 0xFF;
+                       c->Request.CDB[8] = (size >> 8) & 0XFF;
+                       c->Request.CDB[9] = 0;
+                       break;
                default:
                        dev_warn(&h->pdev->dev, "unknown command 0x%c\n", cmd);
                        BUG();
@@ -6327,6 +6653,20 @@ static int fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h,
        } else if (cmd_type == TYPE_MSG) {
                switch (cmd) {
 
+               case  HPSA_PHYS_TARGET_RESET:
+                       c->Request.CDBLen = 16;
+                       c->Request.type_attr_dir =
+                               TYPE_ATTR_DIR(cmd_type, ATTR_SIMPLE, XFER_NONE);
+                       c->Request.Timeout = 0; /* Don't time out */
+                       memset(&c->Request.CDB[0], 0, sizeof(c->Request.CDB));
+                       c->Request.CDB[0] = HPSA_RESET;
+                       c->Request.CDB[1] = HPSA_TARGET_RESET_TYPE;
+                       /* Physical target reset needs no control bytes 4-7*/
+                       c->Request.CDB[4] = 0x00;
+                       c->Request.CDB[5] = 0x00;
+                       c->Request.CDB[6] = 0x00;
+                       c->Request.CDB[7] = 0x00;
+                       break;
                case  HPSA_DEVICE_RESET_MSG:
                        c->Request.CDBLen = 16;
                        c->Request.type_attr_dir =
@@ -6440,16 +6780,6 @@ static inline void finish_cmd(struct CommandList *c)
                complete(c->waiting);
 }
 
-
-static inline u32 hpsa_tag_discard_error_bits(struct ctlr_info *h, u32 tag)
-{
-#define HPSA_PERF_ERROR_BITS ((1 << DIRECT_LOOKUP_SHIFT) - 1)
-#define HPSA_SIMPLE_ERROR_BITS 0x03
-       if (unlikely(!(h->transMethod & CFGTBL_Trans_Performant)))
-               return tag & ~HPSA_SIMPLE_ERROR_BITS;
-       return tag & ~HPSA_PERF_ERROR_BITS;
-}
-
 /* process completion of an indexed ("direct lookup") command */
 static inline void process_indexed_cmd(struct ctlr_info *h,
        u32 raw_tag)
@@ -7860,6 +8190,11 @@ static void hpsa_ack_ctlr_events(struct ctlr_info *h)
  */
 static int hpsa_ctlr_needs_rescan(struct ctlr_info *h)
 {
+       if (h->drv_req_rescan) {
+               h->drv_req_rescan = 0;
+               return 1;
+       }
+
        if (!(h->fw_support & MISC_FW_EVENT_NOTIFY))
                return 0;
 
@@ -7893,6 +8228,41 @@ static int hpsa_offline_devices_ready(struct ctlr_info *h)
        return 0;
 }
 
+static int hpsa_luns_changed(struct ctlr_info *h)
+{
+       int rc = 1; /* assume there are changes */
+       struct ReportLUNdata *logdev = NULL;
+
+       /* if we can't find out if lun data has changed,
+        * assume that it has.
+        */
+
+       if (!h->lastlogicals)
+               goto out;
+
+       logdev = kzalloc(sizeof(*logdev), GFP_KERNEL);
+       if (!logdev) {
+               dev_warn(&h->pdev->dev,
+                       "Out of memory, can't track lun changes.\n");
+               goto out;
+       }
+       if (hpsa_scsi_do_report_luns(h, 1, logdev, sizeof(*logdev), 0)) {
+               dev_warn(&h->pdev->dev,
+                       "report luns failed, can't track lun changes.\n");
+               goto out;
+       }
+       if (memcmp(logdev, h->lastlogicals, sizeof(*logdev))) {
+               dev_info(&h->pdev->dev,
+                       "Lun changes detected.\n");
+               memcpy(h->lastlogicals, logdev, sizeof(*logdev));
+               goto out;
+       } else
+               rc = 0; /* no changes detected. */
+out:
+       kfree(logdev);
+       return rc;
+}
+
 static void hpsa_rescan_ctlr_worker(struct work_struct *work)
 {
        unsigned long flags;
@@ -7908,6 +8278,19 @@ static void hpsa_rescan_ctlr_worker(struct work_struct *work)
                hpsa_ack_ctlr_events(h);
                hpsa_scan_start(h->scsi_host);
                scsi_host_put(h->scsi_host);
+       } else if (h->discovery_polling) {
+               hpsa_disable_rld_caching(h);
+               if (hpsa_luns_changed(h)) {
+                       struct Scsi_Host *sh = NULL;
+
+                       dev_info(&h->pdev->dev,
+                               "driver discovery polling rescan.\n");
+                       sh = scsi_host_get(h->scsi_host);
+                       if (sh != NULL) {
+                               hpsa_scan_start(sh);
+                               scsi_host_put(sh);
+                       }
+               }
        }
        spin_lock_irqsave(&h->lock, flags);
        if (!h->remove_in_progress)
@@ -8148,6 +8531,8 @@ reinit_after_soft_reset:
 
        /* Enable Accelerated IO path at driver layer */
        h->acciopath_status = 1;
+       /* Disable discovery polling.*/
+       h->discovery_polling = 0;
 
 
        /* Turn the interrupts on so we can service requests */
@@ -8155,6 +8540,11 @@ reinit_after_soft_reset:
 
        hpsa_hba_inquiry(h);
 
+       h->lastlogicals = kzalloc(sizeof(*(h->lastlogicals)), GFP_KERNEL);
+       if (!h->lastlogicals)
+               dev_info(&h->pdev->dev,
+                       "Can't track change to report lun data\n");
+
        /* Monitor the controller for firmware lockups */
        h->heartbeat_sample_interval = HEARTBEAT_SAMPLE_INTERVAL;
        INIT_DELAYED_WORK(&h->monitor_ctlr_work, hpsa_monitor_ctlr_worker);
@@ -8227,6 +8617,71 @@ out:
        kfree(flush_buf);
 }
 
+/* Make controller gather fresh report lun data each time we
+ * send down a report luns request
+ */
+static void hpsa_disable_rld_caching(struct ctlr_info *h)
+{
+       u32 *options;
+       struct CommandList *c;
+       int rc;
+
+       /* Don't bother trying to set diag options if locked up */
+       if (unlikely(h->lockup_detected))
+               return;
+
+       options = kzalloc(sizeof(*options), GFP_KERNEL);
+       if (!options) {
+               dev_err(&h->pdev->dev,
+                       "Error: failed to disable rld caching, during alloc.\n");
+               return;
+       }
+
+       c = cmd_alloc(h);
+
+       /* first, get the current diag options settings */
+       if (fill_cmd(c, BMIC_SENSE_DIAG_OPTIONS, h, options, 4, 0,
+               RAID_CTLR_LUNID, TYPE_CMD))
+               goto errout;
+
+       rc = hpsa_scsi_do_simple_cmd_with_retry(h, c,
+               PCI_DMA_FROMDEVICE, NO_TIMEOUT);
+       if ((rc != 0) || (c->err_info->CommandStatus != 0))
+               goto errout;
+
+       /* Now, set the bit for disabling the RLD caching */
+       *options |= HPSA_DIAG_OPTS_DISABLE_RLD_CACHING;
+
+       if (fill_cmd(c, BMIC_SET_DIAG_OPTIONS, h, options, 4, 0,
+               RAID_CTLR_LUNID, TYPE_CMD))
+               goto errout;
+
+       rc = hpsa_scsi_do_simple_cmd_with_retry(h, c,
+               PCI_DMA_TODEVICE, NO_TIMEOUT);
+       if ((rc != 0)  || (c->err_info->CommandStatus != 0))
+               goto errout;
+
+       /* Now verify that it got set: */
+       if (fill_cmd(c, BMIC_SENSE_DIAG_OPTIONS, h, options, 4, 0,
+               RAID_CTLR_LUNID, TYPE_CMD))
+               goto errout;
+
+       rc = hpsa_scsi_do_simple_cmd_with_retry(h, c,
+               PCI_DMA_FROMDEVICE, NO_TIMEOUT);
+       if ((rc != 0)  || (c->err_info->CommandStatus != 0))
+               goto errout;
+
+       if (*options && HPSA_DIAG_OPTS_DISABLE_RLD_CACHING)
+               goto out;
+
+errout:
+       dev_err(&h->pdev->dev,
+                       "Error: failed to disable report lun data caching.\n");
+out:
+       cmd_free(h, c);
+       kfree(options);
+}
+
 static void hpsa_shutdown(struct pci_dev *pdev)
 {
        struct ctlr_info *h;
@@ -8292,6 +8747,7 @@ static void hpsa_remove_one(struct pci_dev *pdev)
        hpsa_free_performant_mode(h);                   /* init_one 7 */
        hpsa_free_sg_chain_blocks(h);                   /* init_one 6 */
        hpsa_free_cmd_pool(h);                          /* init_one 5 */
+       kfree(h->lastlogicals);
 
        /* hpsa_free_irqs already called via hpsa_shutdown init_one 4 */
 
@@ -8304,6 +8760,9 @@ static void hpsa_remove_one(struct pci_dev *pdev)
        free_percpu(h->lockup_detected);                /* init_one 2 */
        h->lockup_detected = NULL;                      /* init_one 2 */
        /* (void) pci_disable_pcie_error_reporting(pdev); */    /* init_one 1 */
+
+       hpsa_delete_sas_host(h);
+
        kfree(h);                                       /* init_one 1 */
 }
 
@@ -8766,18 +9225,369 @@ static void hpsa_drain_accel_commands(struct ctlr_info *h)
        } while (1);
 }
 
+static struct hpsa_sas_phy *hpsa_alloc_sas_phy(
+                               struct hpsa_sas_port *hpsa_sas_port)
+{
+       struct hpsa_sas_phy *hpsa_sas_phy;
+       struct sas_phy *phy;
+
+       hpsa_sas_phy = kzalloc(sizeof(*hpsa_sas_phy), GFP_KERNEL);
+       if (!hpsa_sas_phy)
+               return NULL;
+
+       phy = sas_phy_alloc(hpsa_sas_port->parent_node->parent_dev,
+               hpsa_sas_port->next_phy_index);
+       if (!phy) {
+               kfree(hpsa_sas_phy);
+               return NULL;
+       }
+
+       hpsa_sas_port->next_phy_index++;
+       hpsa_sas_phy->phy = phy;
+       hpsa_sas_phy->parent_port = hpsa_sas_port;
+
+       return hpsa_sas_phy;
+}
+
+static void hpsa_free_sas_phy(struct hpsa_sas_phy *hpsa_sas_phy)
+{
+       struct sas_phy *phy = hpsa_sas_phy->phy;
+
+       sas_port_delete_phy(hpsa_sas_phy->parent_port->port, phy);
+       sas_phy_free(phy);
+       if (hpsa_sas_phy->added_to_port)
+               list_del(&hpsa_sas_phy->phy_list_entry);
+       kfree(hpsa_sas_phy);
+}
+
+static int hpsa_sas_port_add_phy(struct hpsa_sas_phy *hpsa_sas_phy)
+{
+       int rc;
+       struct hpsa_sas_port *hpsa_sas_port;
+       struct sas_phy *phy;
+       struct sas_identify *identify;
+
+       hpsa_sas_port = hpsa_sas_phy->parent_port;
+       phy = hpsa_sas_phy->phy;
+
+       identify = &phy->identify;
+       memset(identify, 0, sizeof(*identify));
+       identify->sas_address = hpsa_sas_port->sas_address;
+       identify->device_type = SAS_END_DEVICE;
+       identify->initiator_port_protocols = SAS_PROTOCOL_STP;
+       identify->target_port_protocols = SAS_PROTOCOL_STP;
+       phy->minimum_linkrate_hw = SAS_LINK_RATE_UNKNOWN;
+       phy->maximum_linkrate_hw = SAS_LINK_RATE_UNKNOWN;
+       phy->minimum_linkrate = SAS_LINK_RATE_UNKNOWN;
+       phy->maximum_linkrate = SAS_LINK_RATE_UNKNOWN;
+       phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
+
+       rc = sas_phy_add(hpsa_sas_phy->phy);
+       if (rc)
+               return rc;
+
+       sas_port_add_phy(hpsa_sas_port->port, hpsa_sas_phy->phy);
+       list_add_tail(&hpsa_sas_phy->phy_list_entry,
+                       &hpsa_sas_port->phy_list_head);
+       hpsa_sas_phy->added_to_port = true;
+
+       return 0;
+}
+
+static int
+       hpsa_sas_port_add_rphy(struct hpsa_sas_port *hpsa_sas_port,
+                               struct sas_rphy *rphy)
+{
+       struct sas_identify *identify;
+
+       identify = &rphy->identify;
+       identify->sas_address = hpsa_sas_port->sas_address;
+       identify->initiator_port_protocols = SAS_PROTOCOL_STP;
+       identify->target_port_protocols = SAS_PROTOCOL_STP;
+
+       return sas_rphy_add(rphy);
+}
+
+static struct hpsa_sas_port
+       *hpsa_alloc_sas_port(struct hpsa_sas_node *hpsa_sas_node,
+                               u64 sas_address)
+{
+       int rc;
+       struct hpsa_sas_port *hpsa_sas_port;
+       struct sas_port *port;
+
+       hpsa_sas_port = kzalloc(sizeof(*hpsa_sas_port), GFP_KERNEL);
+       if (!hpsa_sas_port)
+               return NULL;
+
+       INIT_LIST_HEAD(&hpsa_sas_port->phy_list_head);
+       hpsa_sas_port->parent_node = hpsa_sas_node;
+
+       port = sas_port_alloc_num(hpsa_sas_node->parent_dev);
+       if (!port)
+               goto free_hpsa_port;
+
+       rc = sas_port_add(port);
+       if (rc)
+               goto free_sas_port;
+
+       hpsa_sas_port->port = port;
+       hpsa_sas_port->sas_address = sas_address;
+       list_add_tail(&hpsa_sas_port->port_list_entry,
+                       &hpsa_sas_node->port_list_head);
+
+       return hpsa_sas_port;
+
+free_sas_port:
+       sas_port_free(port);
+free_hpsa_port:
+       kfree(hpsa_sas_port);
+
+       return NULL;
+}
+
+static void hpsa_free_sas_port(struct hpsa_sas_port *hpsa_sas_port)
+{
+       struct hpsa_sas_phy *hpsa_sas_phy;
+       struct hpsa_sas_phy *next;
+
+       list_for_each_entry_safe(hpsa_sas_phy, next,
+                       &hpsa_sas_port->phy_list_head, phy_list_entry)
+               hpsa_free_sas_phy(hpsa_sas_phy);
+
+       sas_port_delete(hpsa_sas_port->port);
+       list_del(&hpsa_sas_port->port_list_entry);
+       kfree(hpsa_sas_port);
+}
+
+static struct hpsa_sas_node *hpsa_alloc_sas_node(struct device *parent_dev)
+{
+       struct hpsa_sas_node *hpsa_sas_node;
+
+       hpsa_sas_node = kzalloc(sizeof(*hpsa_sas_node), GFP_KERNEL);
+       if (hpsa_sas_node) {
+               hpsa_sas_node->parent_dev = parent_dev;
+               INIT_LIST_HEAD(&hpsa_sas_node->port_list_head);
+       }
+
+       return hpsa_sas_node;
+}
+
+static void hpsa_free_sas_node(struct hpsa_sas_node *hpsa_sas_node)
+{
+       struct hpsa_sas_port *hpsa_sas_port;
+       struct hpsa_sas_port *next;
+
+       if (!hpsa_sas_node)
+               return;
+
+       list_for_each_entry_safe(hpsa_sas_port, next,
+                       &hpsa_sas_node->port_list_head, port_list_entry)
+               hpsa_free_sas_port(hpsa_sas_port);
+
+       kfree(hpsa_sas_node);
+}
+
+static struct hpsa_scsi_dev_t
+       *hpsa_find_device_by_sas_rphy(struct ctlr_info *h,
+                                       struct sas_rphy *rphy)
+{
+       int i;
+       struct hpsa_scsi_dev_t *device;
+
+       for (i = 0; i < h->ndevices; i++) {
+               device = h->dev[i];
+               if (!device->sas_port)
+                       continue;
+               if (device->sas_port->rphy == rphy)
+                       return device;
+       }
+
+       return NULL;
+}
+
+static int hpsa_add_sas_host(struct ctlr_info *h)
+{
+       int rc;
+       struct device *parent_dev;
+       struct hpsa_sas_node *hpsa_sas_node;
+       struct hpsa_sas_port *hpsa_sas_port;
+       struct hpsa_sas_phy *hpsa_sas_phy;
+
+       parent_dev = &h->scsi_host->shost_gendev;
+
+       hpsa_sas_node = hpsa_alloc_sas_node(parent_dev);
+       if (!hpsa_sas_node)
+               return -ENOMEM;
+
+       hpsa_sas_port = hpsa_alloc_sas_port(hpsa_sas_node, h->sas_address);
+       if (!hpsa_sas_port) {
+               rc = -ENODEV;
+               goto free_sas_node;
+       }
+
+       hpsa_sas_phy = hpsa_alloc_sas_phy(hpsa_sas_port);
+       if (!hpsa_sas_phy) {
+               rc = -ENODEV;
+               goto free_sas_port;
+       }
+
+       rc = hpsa_sas_port_add_phy(hpsa_sas_phy);
+       if (rc)
+               goto free_sas_phy;
+
+       h->sas_host = hpsa_sas_node;
+
+       return 0;
+
+free_sas_phy:
+       hpsa_free_sas_phy(hpsa_sas_phy);
+free_sas_port:
+       hpsa_free_sas_port(hpsa_sas_port);
+free_sas_node:
+       hpsa_free_sas_node(hpsa_sas_node);
+
+       return rc;
+}
+
+static void hpsa_delete_sas_host(struct ctlr_info *h)
+{
+       hpsa_free_sas_node(h->sas_host);
+}
+
+static int hpsa_add_sas_device(struct hpsa_sas_node *hpsa_sas_node,
+                               struct hpsa_scsi_dev_t *device)
+{
+       int rc;
+       struct hpsa_sas_port *hpsa_sas_port;
+       struct sas_rphy *rphy;
+
+       hpsa_sas_port = hpsa_alloc_sas_port(hpsa_sas_node, device->sas_address);
+       if (!hpsa_sas_port)
+               return -ENOMEM;
+
+       rphy = sas_end_device_alloc(hpsa_sas_port->port);
+       if (!rphy) {
+               rc = -ENODEV;
+               goto free_sas_port;
+       }
+
+       hpsa_sas_port->rphy = rphy;
+       device->sas_port = hpsa_sas_port;
+
+       rc = hpsa_sas_port_add_rphy(hpsa_sas_port, rphy);
+       if (rc)
+               goto free_sas_port;
+
+       return 0;
+
+free_sas_port:
+       hpsa_free_sas_port(hpsa_sas_port);
+       device->sas_port = NULL;
+
+       return rc;
+}
+
+static void hpsa_remove_sas_device(struct hpsa_scsi_dev_t *device)
+{
+       if (device->sas_port) {
+               hpsa_free_sas_port(device->sas_port);
+               device->sas_port = NULL;
+       }
+}
+
+static int
+hpsa_sas_get_linkerrors(struct sas_phy *phy)
+{
+       return 0;
+}
+
+static int
+hpsa_sas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
+{
+       return 0;
+}
+
+static int
+hpsa_sas_get_bay_identifier(struct sas_rphy *rphy)
+{
+       return -ENXIO;
+}
+
+static int
+hpsa_sas_phy_reset(struct sas_phy *phy, int hard_reset)
+{
+       return 0;
+}
+
+static int
+hpsa_sas_phy_enable(struct sas_phy *phy, int enable)
+{
+       return 0;
+}
+
+static int
+hpsa_sas_phy_setup(struct sas_phy *phy)
+{
+       return 0;
+}
+
+static void
+hpsa_sas_phy_release(struct sas_phy *phy)
+{
+}
+
+static int
+hpsa_sas_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates)
+{
+       return -EINVAL;
+}
+
+/* SMP = Serial Management Protocol */
+static int
+hpsa_sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
+struct request *req)
+{
+       return -EINVAL;
+}
+
+static struct sas_function_template hpsa_sas_transport_functions = {
+       .get_linkerrors = hpsa_sas_get_linkerrors,
+       .get_enclosure_identifier = hpsa_sas_get_enclosure_identifier,
+       .get_bay_identifier = hpsa_sas_get_bay_identifier,
+       .phy_reset = hpsa_sas_phy_reset,
+       .phy_enable = hpsa_sas_phy_enable,
+       .phy_setup = hpsa_sas_phy_setup,
+       .phy_release = hpsa_sas_phy_release,
+       .set_phy_speed = hpsa_sas_phy_speed,
+       .smp_handler = hpsa_sas_smp_handler,
+};
+
 /*
  *  This is it.  Register the PCI driver information for the cards we control
  *  the OS will call our registered routines when it finds one of our cards.
  */
 static int __init hpsa_init(void)
 {
-       return pci_register_driver(&hpsa_pci_driver);
+       int rc;
+
+       hpsa_sas_transport_template =
+               sas_attach_transport(&hpsa_sas_transport_functions);
+       if (!hpsa_sas_transport_template)
+               return -ENODEV;
+
+       rc = pci_register_driver(&hpsa_pci_driver);
+
+       if (rc)
+               sas_release_transport(hpsa_sas_transport_template);
+
+       return rc;
 }
 
 static void __exit hpsa_cleanup(void)
 {
        pci_unregister_driver(&hpsa_pci_driver);
+       sas_release_transport(hpsa_sas_transport_template);
 }
 
 static void __attribute__((unused)) verify_offsets(void)
index 27debb363529ec88cbac6f364a3538b64d32b7a7..ae5beda1bdb517849652a68a900c241057ab3ce2 100644 (file)
@@ -33,12 +33,38 @@ struct access_method {
        unsigned long (*command_completed)(struct ctlr_info *h, u8 q);
 };
 
+/* for SAS hosts and SAS expanders */
+struct hpsa_sas_node {
+       struct device *parent_dev;
+       struct list_head port_list_head;
+};
+
+struct hpsa_sas_port {
+       struct list_head port_list_entry;
+       u64 sas_address;
+       struct sas_port *port;
+       int next_phy_index;
+       struct list_head phy_list_head;
+       struct hpsa_sas_node *parent_node;
+       struct sas_rphy *rphy;
+};
+
+struct hpsa_sas_phy {
+       struct list_head phy_list_entry;
+       struct sas_phy *phy;
+       struct hpsa_sas_port *parent_port;
+       bool added_to_port;
+};
+
 struct hpsa_scsi_dev_t {
-       int devtype;
+       unsigned int devtype;
        int bus, target, lun;           /* as presented to the OS */
        unsigned char scsi3addr[8];     /* as presented to the HW */
+       u8 physical_device : 1;
+       u8 expose_device;
 #define RAID_CTLR_LUNID "\0\0\0\0\0\0\0\0"
        unsigned char device_id[16];    /* from inquiry pg. 0x83 */
+       u64 sas_address;
        unsigned char vendor[8];        /* bytes 8-15 of inquiry data */
        unsigned char model[16];        /* bytes 16-31 of inquiry data */
        unsigned char raid_level;       /* from inquiry page 0xC1 */
@@ -75,11 +101,8 @@ struct hpsa_scsi_dev_t {
        struct hpsa_scsi_dev_t *phys_disk[RAID_MAP_MAX_ENTRIES];
        int nphysical_disks;
        int supports_aborts;
-#define HPSA_DO_NOT_EXPOSE     0x0
-#define HPSA_SG_ATTACH         0x1
-#define HPSA_ULD_ATTACH                0x2
-#define HPSA_SCSI_ADD          (HPSA_SG_ATTACH | HPSA_ULD_ATTACH)
-       u8 expose_state;
+       struct hpsa_sas_port *sas_port;
+       int external;   /* 1-from external array 0-not <0-unknown */
 };
 
 struct reply_queue_buffer {
@@ -136,6 +159,7 @@ struct ctlr_info {
        char    *product_name;
        struct pci_dev *pdev;
        u32     board_id;
+       u64     sas_address;
        void __iomem *vaddr;
        unsigned long paddr;
        int     nr_cmds; /* Number of commands allowed on this controller */
@@ -262,7 +286,10 @@ struct ctlr_info {
        spinlock_t offline_device_lock;
        struct list_head offline_device_list;
        int     acciopath_status;
+       int     drv_req_rescan;
        int     raid_offload_debug;
+       int     discovery_polling;
+       struct  ReportLUNdata *lastlogicals;
        int     needs_abort_tags_swizzled;
        struct workqueue_struct *resubmit_wq;
        struct workqueue_struct *rescan_ctlr_wq;
@@ -270,6 +297,8 @@ struct ctlr_info {
        wait_queue_head_t abort_cmd_wait_queue;
        wait_queue_head_t event_sync_wait_queue;
        struct mutex reset_mutex;
+       u8 reset_in_progress;
+       struct hpsa_sas_node *sas_host;
 };
 
 struct offline_device_entry {
@@ -283,6 +312,7 @@ struct offline_device_entry {
 #define HPSA_RESET_TYPE_BUS 0x01
 #define HPSA_RESET_TYPE_TARGET 0x03
 #define HPSA_RESET_TYPE_LUN 0x04
+#define HPSA_PHYS_TARGET_RESET 0x99 /* not defined by cciss spec */
 #define HPSA_MSG_SEND_RETRY_LIMIT 10
 #define HPSA_MSG_SEND_RETRY_INTERVAL_MSECS (10000)
 
@@ -367,6 +397,11 @@ struct offline_device_entry {
 #define IOACCEL2_INBOUND_POSTQ_64_LOW  0xd0
 #define IOACCEL2_INBOUND_POSTQ_64_HI   0xd4
 
+#define HPSA_PHYSICAL_DEVICE_BUS       0
+#define HPSA_RAID_VOLUME_BUS           1
+#define HPSA_EXTERNAL_RAID_VOLUME_BUS  2
+#define HPSA_HBA_BUS                   3
+
 /*
        Send the command to the hardware
 */
index 47c756ba8dce414ce7302e3198359eda8223c327..d92ef0d352b55fa6d8d1fb0f9ef6e7c50b5ec3db 100644 (file)
@@ -260,8 +260,6 @@ struct ext_report_lun_entry {
        u8 wwid[8];
        u8 device_type;
        u8 device_flags;
-#define NON_DISK_PHYS_DEV(x) ((x)[17] & 0x01)
-#define PHYS_IOACCEL(x) ((x)[17] & 0x08)
        u8 lun_count; /* multi-lun device, how many luns */
        u8 redundant_paths;
        u32 ioaccel_handle; /* ioaccel1 only uses lower 16 bits */
@@ -288,6 +286,11 @@ struct SenseSubsystem_info {
 #define BMIC_FLASH_FIRMWARE 0xF7
 #define BMIC_SENSE_CONTROLLER_PARAMETERS 0x64
 #define BMIC_IDENTIFY_PHYSICAL_DEVICE 0x15
+#define BMIC_IDENTIFY_CONTROLLER 0x11
+#define BMIC_SET_DIAG_OPTIONS 0xF4
+#define BMIC_SENSE_DIAG_OPTIONS 0xF5
+#define HPSA_DIAG_OPTS_DISABLE_RLD_CACHING 0x40000000
+#define BMIC_SENSE_SUBSYSTEM_INFORMATION 0x66
 
 /* Command List Structure */
 union SCSI3Addr {
@@ -684,6 +687,16 @@ struct hpsa_pci_info {
        u32             board_id;
 };
 
+struct bmic_identify_controller {
+       u8      configured_logical_drive_count; /* offset 0 */
+       u8      pad1[153];
+       __le16  extended_logical_unit_count;    /* offset 154 */
+       u8      pad2[136];
+       u8      controller_mode;        /* offset 292 */
+       u8      pad3[32];
+};
+
+
 struct bmic_identify_physical_device {
        u8    scsi_bus;          /* SCSI Bus number on controller */
        u8    scsi_id;           /* SCSI ID on this bus */
@@ -816,5 +829,18 @@ struct bmic_identify_physical_device {
        u8     padding[112];
 };
 
+struct bmic_sense_subsystem_info {
+       u8      primary_slot_number;
+       u8      reserved[3];
+       u8      chasis_serial_number[32];
+       u8      primary_world_wide_id[8];
+       u8      primary_array_serial_number[32]; /* NULL terminated */
+       u8      primary_cache_serial_number[32]; /* NULL terminated */
+       u8      reserved_2[8];
+       u8      secondary_array_serial_number[32];
+       u8      secondary_cache_serial_number[32];
+       u8      pad[332];
+};
+
 #pragma pack()
 #endif /* HPSA_CMD_H */
index 057d27721d5b24d23e24c3040b64507507556400..6aa317c303e2dced686c76cc1102e563b4f058b1 100644 (file)
@@ -3095,7 +3095,6 @@ static struct scsi_host_template driver_template = {
        .max_sectors = IBMVFC_MAX_SECTORS,
        .use_clustering = ENABLE_CLUSTERING,
        .shost_attrs = ibmvfc_attrs,
-       .use_blk_tags = 1,
        .track_queue_depth = 1,
 };
 
index 6a41c36b16b0d5dfe5edc663988388dbf71e24cd..adfef9db6f1e2c279002315abc3d936adc622027 100644 (file)
@@ -106,9 +106,9 @@ MODULE_LICENSE("GPL");
 MODULE_VERSION(IBMVSCSI_VERSION);
 
 module_param_named(max_id, max_id, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(max_id, "Largest ID value for each channel");
+MODULE_PARM_DESC(max_id, "Largest ID value for each channel [Default=64]");
 module_param_named(max_channel, max_channel, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(max_channel, "Largest channel value");
+MODULE_PARM_DESC(max_channel, "Largest channel value [Default=3]");
 module_param_named(init_timeout, init_timeout, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(init_timeout, "Initialization timeout in seconds");
 module_param_named(max_requests, max_requests, int, S_IRUGO);
@@ -2289,11 +2289,15 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
                goto init_pool_failed;
        }
 
-       host->max_lun = 8;
+       host->max_lun = IBMVSCSI_MAX_LUN;
        host->max_id = max_id;
        host->max_channel = max_channel;
        host->max_cmd_len = 16;
 
+       dev_info(dev,
+                "Maximum ID: %d Maximum LUN: %llu Maximum Channel: %d\n",
+                host->max_id, host->max_lun, host->max_channel);
+
        if (scsi_add_host(hostdata->host, hostdata->dev))
                goto add_host_failed;
 
index 7d64867c5dd1784cb4a3e265bed621346e334d16..1067367395cd4fa216f160cf6578195c42e7cbd0 100644 (file)
@@ -48,6 +48,7 @@ struct Scsi_Host;
 #define IBMVSCSI_CMDS_PER_LUN_DEFAULT 16
 #define IBMVSCSI_MAX_SECTORS_DEFAULT 256 /* 32 * 8 = default max I/O 32 pages */
 #define IBMVSCSI_MAX_CMDS_PER_LUN 64
+#define IBMVSCSI_MAX_LUN 32
 
 /* ------------------------------------------------------------
  * Data Structures
index b62836ddbbee55c1fc7d6c65f4926a281fff387b..536cd5a8042245f4ad46929a256098e047d745dd 100644 (file)
@@ -6363,15 +6363,19 @@ static int ipr_queuecommand(struct Scsi_Host *shost,
        ipr_cmd->scsi_cmd = scsi_cmd;
        ipr_cmd->done = ipr_scsi_eh_done;
 
-       if (ipr_is_gscsi(res) || ipr_is_vset_device(res)) {
+       if (ipr_is_gscsi(res)) {
                if (scsi_cmd->underflow == 0)
                        ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK;
 
-               ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_LINK_DESC;
-               if (ipr_is_gscsi(res) && res->reset_occurred) {
+               if (res->reset_occurred) {
                        res->reset_occurred = 0;
                        ioarcb->cmd_pkt.flags_lo |= IPR_FLAGS_LO_DELAY_AFTER_RST;
                }
+       }
+
+       if (ipr_is_gscsi(res) || ipr_is_vset_device(res)) {
+               ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_LINK_DESC;
+
                ioarcb->cmd_pkt.flags_lo |= IPR_FLAGS_LO_ALIGNED_BFR;
                if (scsi_cmd->flags & SCMD_TAGGED)
                        ioarcb->cmd_pkt.flags_lo |= IPR_FLAGS_LO_SIMPLE_TASK;
@@ -6502,7 +6506,6 @@ static struct scsi_host_template driver_template = {
        .shost_attrs = ipr_ioa_attrs,
        .sdev_attrs = ipr_dev_attrs,
        .proc_name = IPR_NAME,
-       .use_blk_tags = 1,
 };
 
 /**
@@ -7671,6 +7674,63 @@ static int ipr_ioafp_query_ioa_cfg(struct ipr_cmnd *ipr_cmd)
        return IPR_RC_JOB_RETURN;
 }
 
+static int ipr_ioa_service_action_failed(struct ipr_cmnd *ipr_cmd)
+{
+       u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc);
+
+       if (ioasc == IPR_IOASC_IR_INVALID_REQ_TYPE_OR_PKT)
+               return IPR_RC_JOB_CONTINUE;
+
+       return ipr_reset_cmd_failed(ipr_cmd);
+}
+
+static void ipr_build_ioa_service_action(struct ipr_cmnd *ipr_cmd,
+                                        __be32 res_handle, u8 sa_code)
+{
+       struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
+
+       ioarcb->res_handle = res_handle;
+       ioarcb->cmd_pkt.cdb[0] = IPR_IOA_SERVICE_ACTION;
+       ioarcb->cmd_pkt.cdb[1] = sa_code;
+       ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
+}
+
+/**
+ * ipr_ioafp_set_caching_parameters - Issue Set Cache parameters service
+ * action
+ *
+ * Return value:
+ *     none
+ **/
+static int ipr_ioafp_set_caching_parameters(struct ipr_cmnd *ipr_cmd)
+{
+       struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
+       struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
+       struct ipr_inquiry_pageC4 *pageC4 = &ioa_cfg->vpd_cbs->pageC4_data;
+
+       ENTER;
+
+       ipr_cmd->job_step = ipr_ioafp_query_ioa_cfg;
+
+       if (pageC4->cache_cap[0] & IPR_CAP_SYNC_CACHE) {
+               ipr_build_ioa_service_action(ipr_cmd,
+                                            cpu_to_be32(IPR_IOA_RES_HANDLE),
+                                            IPR_IOA_SA_CHANGE_CACHE_PARAMS);
+
+               ioarcb->cmd_pkt.cdb[2] = 0x40;
+
+               ipr_cmd->job_step_failed = ipr_ioa_service_action_failed;
+               ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout,
+                          IPR_SET_SUP_DEVICE_TIMEOUT);
+
+               LEAVE;
+               return IPR_RC_JOB_RETURN;
+       }
+
+       LEAVE;
+       return IPR_RC_JOB_CONTINUE;
+}
+
 /**
  * ipr_ioafp_inquiry - Send an Inquiry to the adapter.
  * @ipr_cmd:   ipr command struct
@@ -7721,6 +7781,39 @@ static int ipr_inquiry_page_supported(struct ipr_inquiry_page0 *page0, u8 page)
        return 0;
 }
 
+/**
+ * ipr_ioafp_pageC4_inquiry - Send a Page 0xC4 Inquiry to the adapter.
+ * @ipr_cmd:   ipr command struct
+ *
+ * This function sends a Page 0xC4 inquiry to the adapter
+ * to retrieve software VPD information.
+ *
+ * Return value:
+ *     IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN
+ **/
+static int ipr_ioafp_pageC4_inquiry(struct ipr_cmnd *ipr_cmd)
+{
+       struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
+       struct ipr_inquiry_page0 *page0 = &ioa_cfg->vpd_cbs->page0_data;
+       struct ipr_inquiry_pageC4 *pageC4 = &ioa_cfg->vpd_cbs->pageC4_data;
+
+       ENTER;
+       ipr_cmd->job_step = ipr_ioafp_set_caching_parameters;
+       memset(pageC4, 0, sizeof(*pageC4));
+
+       if (ipr_inquiry_page_supported(page0, 0xC4)) {
+               ipr_ioafp_inquiry(ipr_cmd, 1, 0xC4,
+                                 (ioa_cfg->vpd_cbs_dma
+                                  + offsetof(struct ipr_misc_cbs,
+                                             pageC4_data)),
+                                 sizeof(struct ipr_inquiry_pageC4));
+               return IPR_RC_JOB_RETURN;
+       }
+
+       LEAVE;
+       return IPR_RC_JOB_CONTINUE;
+}
+
 /**
  * ipr_ioafp_cap_inquiry - Send a Page 0xD0 Inquiry to the adapter.
  * @ipr_cmd:   ipr command struct
@@ -7738,7 +7831,7 @@ static int ipr_ioafp_cap_inquiry(struct ipr_cmnd *ipr_cmd)
        struct ipr_inquiry_cap *cap = &ioa_cfg->vpd_cbs->cap;
 
        ENTER;
-       ipr_cmd->job_step = ipr_ioafp_query_ioa_cfg;
+       ipr_cmd->job_step = ipr_ioafp_pageC4_inquiry;
        memset(cap, 0, sizeof(*cap));
 
        if (ipr_inquiry_page_supported(page0, 0xD0)) {
@@ -8277,6 +8370,42 @@ static int ipr_reset_get_unit_check_job(struct ipr_cmnd *ipr_cmd)
        return IPR_RC_JOB_RETURN;
 }
 
+static int ipr_dump_mailbox_wait(struct ipr_cmnd *ipr_cmd)
+{
+       struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
+
+       ENTER;
+
+       if (ioa_cfg->sdt_state != GET_DUMP)
+               return IPR_RC_JOB_RETURN;
+
+       if (!ioa_cfg->sis64 || !ipr_cmd->u.time_left ||
+           (readl(ioa_cfg->regs.sense_interrupt_reg) &
+            IPR_PCII_MAILBOX_STABLE)) {
+
+               if (!ipr_cmd->u.time_left)
+                       dev_err(&ioa_cfg->pdev->dev,
+                               "Timed out waiting for Mailbox register.\n");
+
+               ioa_cfg->sdt_state = READ_DUMP;
+               ioa_cfg->dump_timeout = 0;
+               if (ioa_cfg->sis64)
+                       ipr_reset_start_timer(ipr_cmd, IPR_SIS64_DUMP_TIMEOUT);
+               else
+                       ipr_reset_start_timer(ipr_cmd, IPR_SIS32_DUMP_TIMEOUT);
+               ipr_cmd->job_step = ipr_reset_wait_for_dump;
+               schedule_work(&ioa_cfg->work_q);
+
+       } else {
+               ipr_cmd->u.time_left -= IPR_CHECK_FOR_RESET_TIMEOUT;
+               ipr_reset_start_timer(ipr_cmd,
+                                     IPR_CHECK_FOR_RESET_TIMEOUT);
+       }
+
+       LEAVE;
+       return IPR_RC_JOB_RETURN;
+}
+
 /**
  * ipr_reset_restore_cfg_space - Restore PCI config space.
  * @ipr_cmd:   ipr command struct
@@ -8326,20 +8455,11 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd)
 
        if (ioa_cfg->in_ioa_bringdown) {
                ipr_cmd->job_step = ipr_ioa_bringdown_done;
+       } else if (ioa_cfg->sdt_state == GET_DUMP) {
+               ipr_cmd->job_step = ipr_dump_mailbox_wait;
+               ipr_cmd->u.time_left = IPR_WAIT_FOR_MAILBOX;
        } else {
                ipr_cmd->job_step = ipr_reset_enable_ioa;
-
-               if (GET_DUMP == ioa_cfg->sdt_state) {
-                       ioa_cfg->sdt_state = READ_DUMP;
-                       ioa_cfg->dump_timeout = 0;
-                       if (ioa_cfg->sis64)
-                               ipr_reset_start_timer(ipr_cmd, IPR_SIS64_DUMP_TIMEOUT);
-                       else
-                               ipr_reset_start_timer(ipr_cmd, IPR_SIS32_DUMP_TIMEOUT);
-                       ipr_cmd->job_step = ipr_reset_wait_for_dump;
-                       schedule_work(&ioa_cfg->work_q);
-                       return IPR_RC_JOB_RETURN;
-               }
        }
 
        LEAVE;
index e4fb17a58649e22c110ae92490e0368a5e595505..a34c7a5a995e4bcbf61b1d859fb784b60a9cdbee 100644 (file)
@@ -39,8 +39,8 @@
 /*
  * Literals
  */
-#define IPR_DRIVER_VERSION "2.6.2"
-#define IPR_DRIVER_DATE "(June 11, 2015)"
+#define IPR_DRIVER_VERSION "2.6.3"
+#define IPR_DRIVER_DATE "(October 17, 2015)"
 
 /*
  * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding
 #define IPR_SET_ALL_SUPPORTED_DEVICES                  0x80
 #define IPR_IOA_SHUTDOWN                               0xF7
 #define        IPR_WR_BUF_DOWNLOAD_AND_SAVE                    0x05
+#define IPR_IOA_SERVICE_ACTION                         0xD2
+
+/* IOA Service Actions */
+#define IPR_IOA_SA_CHANGE_CACHE_PARAMS                 0x14
 
 /*
  * Timeouts
 #define IPR_IPL_INIT_STAGE_TIME_MASK                   0x0000ffff
 #define IPR_PCII_IPL_STAGE_CHANGE                      (0x80000000 >> 0)
 
+#define IPR_PCII_MAILBOX_STABLE                                (0x80000000 >> 4)
+#define IPR_WAIT_FOR_MAILBOX                           (2 * HZ)
+
 #define IPR_PCII_IOA_TRANS_TO_OPER                     (0x80000000 >> 0)
 #define IPR_PCII_IOARCB_XFER_FAILED                    (0x80000000 >> 3)
 #define IPR_PCII_IOA_UNIT_CHECKED                      (0x80000000 >> 4)
@@ -846,6 +853,16 @@ struct ipr_inquiry_page0 {
        u8 page[IPR_INQUIRY_PAGE0_ENTRIES];
 }__attribute__((packed));
 
+struct ipr_inquiry_pageC4 {
+       u8 peri_qual_dev_type;
+       u8 page_code;
+       u8 reserved1;
+       u8 len;
+       u8 cache_cap[4];
+#define IPR_CAP_SYNC_CACHE             0x08
+       u8 reserved2[20];
+} __packed;
+
 struct ipr_hostrcb_device_data_entry {
        struct ipr_vpd vpd;
        struct ipr_res_addr dev_res_addr;
@@ -1319,6 +1336,7 @@ struct ipr_misc_cbs {
        struct ipr_inquiry_page0 page0_data;
        struct ipr_inquiry_page3 page3_data;
        struct ipr_inquiry_cap cap;
+       struct ipr_inquiry_pageC4 pageC4_data;
        struct ipr_mode_pages mode_pages;
        struct ipr_supported_device supp_dev;
 };
index 0dfcabe3ca7c2c7862b3712a391f2cd4ba19015a..77128d680e3bc615732767ea428292c93ffb32fa 100644 (file)
@@ -170,7 +170,6 @@ static struct scsi_host_template isci_sht = {
        .target_destroy                 = sas_target_destroy,
        .ioctl                          = sas_ioctl,
        .shost_attrs                    = isci_host_attrs,
-       .use_blk_tags                   = 1,
        .track_queue_depth              = 1,
 };
 
@@ -272,11 +271,11 @@ static void isci_unregister(struct isci_host *isci_host)
        if (!isci_host)
                return;
 
+       shost = to_shost(isci_host);
+       scsi_remove_host(shost);
        sas_unregister_ha(&isci_host->sas_ha);
 
-       shost = to_shost(isci_host);
        sas_remove_host(shost);
-       scsi_remove_host(shost);
        scsi_host_put(shost);
 }
 
index 9fbf78ed821b3ceeb36a941e5fddd3142d0300cf..c168321b560e2d2046eec8299b3574abc90a90df 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/export.h>
 
 /**
- * fc_vport_create() - Create a new NPIV vport instance
+ * libfc_vport_create() - Create a new NPIV vport instance
  * @vport: fc_vport structure from scsi_transport_fc
  * @privsize: driver private data size to allocate along with the Scsi_Host
  */
index 3feeb447b7409e560eed9bbac571a41352cf6406..b6fa257ea3e0ba802e65f57d46c45944318bef7b 100644 (file)
@@ -5173,7 +5173,6 @@ lpfc_els_rcv_lcb(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
                rjt_err = LSRJT_CMD_UNSUPPORTED;
                goto rjt;
        }
-       lcb_context = kmalloc(sizeof(struct lpfc_lcb_context), GFP_KERNEL);
 
        if (phba->hba_flag & HBA_FCOE_MODE) {
                rjt_err = LSRJT_CMD_UNSUPPORTED;
@@ -5204,6 +5203,12 @@ lpfc_els_rcv_lcb(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
                goto rjt;
        }
 
+       lcb_context = kmalloc(sizeof(*lcb_context), GFP_KERNEL);
+       if (!lcb_context) {
+               rjt_err = LSRJT_UNABLE_TPC;
+               goto rjt;
+       }
+
        state = (beacon->lcb_sub_command == LPFC_LCB_ON) ? 1 : 0;
        lcb_context->sub_command = beacon->lcb_sub_command;
        lcb_context->type = beacon->lcb_type;
@@ -5214,6 +5219,7 @@ lpfc_els_rcv_lcb(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
        if (lpfc_sli4_set_beacon(vport, lcb_context, state)) {
                lpfc_printf_vlog(ndlp->vport, KERN_ERR,
                                 LOG_ELS, "0193 failed to send mail box");
+               kfree(lcb_context);
                lpfc_nlp_put(ndlp);
                rjt_err = LSRJT_UNABLE_TPC;
                goto rjt;
index 051b3b3bd625dea5891266a725ca514f8a98239b..4679ed4444a737e906342473031397b2137443ff 100644 (file)
@@ -5914,7 +5914,6 @@ struct scsi_host_template lpfc_template_s3 = {
        .max_sectors            = 0xFFFF,
        .vendor_id              = LPFC_NL_VENDOR_ID,
        .change_queue_depth     = scsi_change_queue_depth,
-       .use_blk_tags           = 1,
        .track_queue_depth      = 1,
 };
 
@@ -5940,7 +5939,6 @@ struct scsi_host_template lpfc_template = {
        .max_sectors            = 0xFFFF,
        .vendor_id              = LPFC_NL_VENDOR_ID,
        .change_queue_depth     = scsi_change_queue_depth,
-       .use_blk_tags           = 1,
        .track_queue_depth      = 1,
 };
 
@@ -5964,6 +5962,5 @@ struct scsi_host_template lpfc_vport_template = {
        .shost_attrs            = lpfc_vport_attrs,
        .max_sectors            = 0xFFFF,
        .change_queue_depth     = scsi_change_queue_depth,
-       .use_blk_tags           = 1,
        .track_queue_depth      = 1,
 };
index 20c37541963f4acd04ed6836647469f3d46cdabe..c0f7c8ce54aa08b668694b4b70e19076ec72dbff 100644 (file)
@@ -35,8 +35,8 @@
 /*
  * MegaRAID SAS Driver meta data
  */
-#define MEGASAS_VERSION                                "06.807.10.00-rc1"
-#define MEGASAS_RELDATE                                "March 6, 2015"
+#define MEGASAS_VERSION                                "06.808.16.00-rc1"
+#define MEGASAS_RELDATE                                "Oct. 8, 2015"
 
 /*
  * Device IDs
 #define PCI_DEVICE_ID_LSI_PLASMA               0x002f
 #define PCI_DEVICE_ID_LSI_INVADER              0x005d
 #define PCI_DEVICE_ID_LSI_FURY                 0x005f
+#define PCI_DEVICE_ID_LSI_INTRUDER             0x00ce
+#define PCI_DEVICE_ID_LSI_INTRUDER_24          0x00cf
+#define PCI_DEVICE_ID_LSI_CUTLASS_52           0x0052
+#define PCI_DEVICE_ID_LSI_CUTLASS_53           0x0053
 
 /*
  * Intel HBA SSDIDs
 #define MEGARAID_INTEL_RS3MC044_SSDID          0x9381
 #define MEGARAID_INTEL_RS3WC080_SSDID          0x9341
 #define MEGARAID_INTEL_RS3WC040_SSDID          0x9343
+#define MEGARAID_INTEL_RMS3BC160_SSDID         0x352B
+
+/*
+ * Intruder HBA SSDIDs
+ */
+#define MEGARAID_INTRUDER_SSDID1               0x9371
+#define MEGARAID_INTRUDER_SSDID2               0x9390
+#define MEGARAID_INTRUDER_SSDID3               0x9370
 
 /*
  * Intel HBA branding
@@ -78,6 +90,8 @@
        "Intel(R) RAID Controller RS3WC080"
 #define MEGARAID_INTEL_RS3WC040_BRANDING       \
        "Intel(R) RAID Controller RS3WC040"
+#define MEGARAID_INTEL_RMS3BC160_BRANDING      \
+       "Intel(R) Integrated RAID Module RMS3BC160"
 
 /*
  * =====================================
@@ -273,6 +287,16 @@ enum MFI_STAT {
        MFI_STAT_INVALID_STATUS = 0xFF
 };
 
+enum mfi_evt_class {
+       MFI_EVT_CLASS_DEBUG =           -2,
+       MFI_EVT_CLASS_PROGRESS =        -1,
+       MFI_EVT_CLASS_INFO =            0,
+       MFI_EVT_CLASS_WARNING =         1,
+       MFI_EVT_CLASS_CRITICAL =        2,
+       MFI_EVT_CLASS_FATAL =           3,
+       MFI_EVT_CLASS_DEAD =            4
+};
+
 /*
  * Crash dump related defines
  */
@@ -364,6 +388,8 @@ enum MR_EVT_ARGS {
        MR_EVT_ARGS_GENERIC,
 };
 
+
+#define SGE_BUFFER_SIZE        4096
 /*
  * define constants for device list query options
  */
@@ -394,6 +420,7 @@ enum MR_LD_QUERY_TYPE {
 #define MR_EVT_FOREIGN_CFG_IMPORTED                     0x00db
 #define MR_EVT_LD_OFFLINE                               0x00fc
 #define MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED             0x0152
+#define MR_EVT_CTRL_PROP_CHANGED                       0x012f
 
 enum MR_PD_STATE {
        MR_PD_STATE_UNCONFIGURED_GOOD   = 0x00,
@@ -973,7 +1000,12 @@ struct megasas_ctrl_info {
 
        struct {
 #if defined(__BIG_ENDIAN_BITFIELD)
-               u32     reserved:12;
+               u32     reserved:7;
+               u32     useSeqNumJbodFP:1;
+               u32     supportExtendedSSCSize:1;
+               u32     supportDiskCacheSettingForSysPDs:1;
+               u32     supportCPLDUpdate:1;
+               u32     supportTTYLogCompression:1;
                u32     discardCacheDuringLDDelete:1;
                u32     supportSecurityonJBOD:1;
                u32     supportCacheBypassModes:1;
@@ -1013,7 +1045,12 @@ struct megasas_ctrl_info {
                u32     supportCacheBypassModes:1;
                u32     supportSecurityonJBOD:1;
                u32     discardCacheDuringLDDelete:1;
-               u32     reserved:12;
+               u32     supportTTYLogCompression:1;
+               u32     supportCPLDUpdate:1;
+               u32     supportDiskCacheSettingForSysPDs:1;
+               u32     supportExtendedSSCSize:1;
+               u32     useSeqNumJbodFP:1;
+               u32     reserved:7;
 #endif
        } adapterOperations3;
 
@@ -1229,7 +1266,9 @@ union megasas_sgl_frame {
 typedef union _MFI_CAPABILITIES {
        struct {
 #if   defined(__BIG_ENDIAN_BITFIELD)
-               u32     reserved:25;
+               u32     reserved:23;
+               u32     support_ext_io_size:1;
+               u32     support_ext_queue_depth:1;
                u32     security_protocol_cmds_fw:1;
                u32     support_core_affinity:1;
                u32     support_ndrive_r1_lb:1;
@@ -1245,7 +1284,9 @@ typedef union _MFI_CAPABILITIES {
                u32     support_ndrive_r1_lb:1;
                u32     support_core_affinity:1;
                u32     security_protocol_cmds_fw:1;
-               u32     reserved:25;
+               u32     support_ext_queue_depth:1;
+               u32     support_ext_io_size:1;
+               u32     reserved:23;
 #endif
        } mfi_capabilities;
        __le32          reg;
@@ -1690,6 +1731,7 @@ struct megasas_instance {
        u32 crash_dump_drv_support;
        u32 crash_dump_app_support;
        u32 secure_jbod_support;
+       bool use_seqnum_jbod_fp;   /* Added for PD sequence */
        spinlock_t crashdump_lock;
 
        struct megasas_register_set __iomem *reg_set;
@@ -1748,6 +1790,7 @@ struct megasas_instance {
        u8 UnevenSpanSupport;
 
        u8 supportmax256vd;
+       u8 allow_fw_scan;
        u16 fw_supported_vd_count;
        u16 fw_supported_pd_count;
 
@@ -1769,7 +1812,9 @@ struct megasas_instance {
        struct msix_entry msixentry[MEGASAS_MAX_MSIX_QUEUES];
        struct megasas_irq_context irq_context[MEGASAS_MAX_MSIX_QUEUES];
        u64 map_id;
+       u64 pd_seq_map_id;
        struct megasas_cmd *map_update_cmd;
+       struct megasas_cmd *jbod_seq_cmd;
        unsigned long bar;
        long reset_flags;
        struct mutex reset_mutex;
@@ -1780,6 +1825,7 @@ struct megasas_instance {
        char mpio;
        u16 throttlequeuedepth;
        u8 mask_interrupts;
+       u16 max_chain_frame_sz;
        u8 is_imr;
        bool dev_handle;
 };
@@ -1985,6 +2031,9 @@ __le16 get_updated_dev_handle(struct megasas_instance *instance,
 void mr_update_load_balance_params(struct MR_DRV_RAID_MAP_ALL *map,
        struct LD_LOAD_BALANCE_INFO *lbInfo);
 int megasas_get_ctrl_info(struct megasas_instance *instance);
+/* PD sequence */
+int
+megasas_sync_pd_seq_num(struct megasas_instance *instance, bool pend);
 int megasas_set_crash_dump_params(struct megasas_instance *instance,
        u8 crash_buf_state);
 void megasas_free_host_crash_buffer(struct megasas_instance *instance);
@@ -2000,5 +2049,6 @@ void __megasas_return_cmd(struct megasas_instance *instance,
 void megasas_return_mfi_mpt_pthr(struct megasas_instance *instance,
        struct megasas_cmd *cmd_mfi, struct megasas_cmd_fusion *cmd_fusion);
 int megasas_cmd_type(struct scsi_cmnd *cmd);
+void megasas_setup_jbod_map(struct megasas_instance *instance);
 
 #endif                         /*LSI_MEGARAID_SAS_H */
index eaa81e552fd26f715122da4ee5e38427bb4ddb72..97a1c1c33b05dd2ba7e2dfe4feb3469dce3b6199 100644 (file)
@@ -135,6 +135,12 @@ static struct pci_device_id megasas_pci_table[] = {
        /* Invader */
        {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FURY)},
        /* Fury */
+       {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_INTRUDER)},
+       /* Intruder */
+       {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_INTRUDER_24)},
+       /* Intruder 24 port*/
+       {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_CUTLASS_52)},
+       {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_CUTLASS_53)},
        {}
 };
 
@@ -260,6 +266,66 @@ megasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
 
 }
 
+static const char *
+format_timestamp(uint32_t timestamp)
+{
+       static char buffer[32];
+
+       if ((timestamp & 0xff000000) == 0xff000000)
+               snprintf(buffer, sizeof(buffer), "boot + %us", timestamp &
+               0x00ffffff);
+       else
+               snprintf(buffer, sizeof(buffer), "%us", timestamp);
+       return buffer;
+}
+
+static const char *
+format_class(int8_t class)
+{
+       static char buffer[6];
+
+       switch (class) {
+       case MFI_EVT_CLASS_DEBUG:
+               return "debug";
+       case MFI_EVT_CLASS_PROGRESS:
+               return "progress";
+       case MFI_EVT_CLASS_INFO:
+               return "info";
+       case MFI_EVT_CLASS_WARNING:
+               return "WARN";
+       case MFI_EVT_CLASS_CRITICAL:
+               return "CRIT";
+       case MFI_EVT_CLASS_FATAL:
+               return "FATAL";
+       case MFI_EVT_CLASS_DEAD:
+               return "DEAD";
+       default:
+               snprintf(buffer, sizeof(buffer), "%d", class);
+               return buffer;
+       }
+}
+
+/**
+  * megasas_decode_evt: Decode FW AEN event and print critical event
+  * for information.
+  * @instance:                 Adapter soft state
+  */
+static void
+megasas_decode_evt(struct megasas_instance *instance)
+{
+       struct megasas_evt_detail *evt_detail = instance->evt_detail;
+       union megasas_evt_class_locale class_locale;
+       class_locale.word = le32_to_cpu(evt_detail->cl.word);
+
+       if (class_locale.members.class >= MFI_EVT_CLASS_CRITICAL)
+               dev_info(&instance->pdev->dev, "%d (%s/0x%04x/%s) - %s\n",
+                       le32_to_cpu(evt_detail->seq_num),
+                       format_timestamp(le32_to_cpu(evt_detail->time_stamp)),
+                       (class_locale.members.locale),
+                       format_class(class_locale.members.class),
+                       evt_detail->description);
+}
+
 /**
 *      The following functions are defined for xscale
 *      (deviceid : 1064R, PERC5) controllers
@@ -1659,8 +1725,56 @@ static struct megasas_instance *megasas_lookup_instance(u16 host_no)
        return NULL;
 }
 
+/*
+* megasas_set_dma_alignment - Set DMA alignment for PI enabled VD
+*
+* @sdev: OS provided scsi device
+*
+* Returns void
+*/
+static void megasas_set_dma_alignment(struct scsi_device *sdev)
+{
+       u32 device_id, ld;
+       struct megasas_instance *instance;
+       struct fusion_context *fusion;
+       struct MR_LD_RAID *raid;
+       struct MR_DRV_RAID_MAP_ALL *local_map_ptr;
+
+       instance = megasas_lookup_instance(sdev->host->host_no);
+       fusion = instance->ctrl_context;
+
+       if (!fusion)
+               return;
+
+       if (sdev->channel >= MEGASAS_MAX_PD_CHANNELS) {
+               device_id = ((sdev->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL)
+                                       + sdev->id;
+               local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)];
+               ld = MR_TargetIdToLdGet(device_id, local_map_ptr);
+               raid = MR_LdRaidGet(ld, local_map_ptr);
+
+               if (raid->capability.ldPiMode == MR_PROT_INFO_TYPE_CONTROLLER)
+                       blk_queue_update_dma_alignment(sdev->request_queue, 0x7);
+       }
+}
+
 static int megasas_slave_configure(struct scsi_device *sdev)
 {
+       u16 pd_index = 0;
+       struct megasas_instance *instance;
+
+       instance = megasas_lookup_instance(sdev->host->host_no);
+       if (instance->allow_fw_scan) {
+               if (sdev->channel < MEGASAS_MAX_PD_CHANNELS &&
+                       sdev->type == TYPE_DISK) {
+                       pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
+                               sdev->id;
+                       if (instance->pd_list[pd_index].driveState !=
+                               MR_PD_STATE_SYSTEM)
+                               return -ENXIO;
+               }
+       }
+       megasas_set_dma_alignment(sdev);
        /*
         * The RAID firmware may require extended timeouts.
         */
@@ -1683,8 +1797,8 @@ static int megasas_slave_alloc(struct scsi_device *sdev)
                pd_index =
                        (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
                        sdev->id;
-               if (instance->pd_list[pd_index].driveState ==
-                                       MR_PD_STATE_SYSTEM) {
+               if ((instance->allow_fw_scan || instance->pd_list[pd_index].driveState ==
+                       MR_PD_STATE_SYSTEM)) {
                        return 0;
                }
                return -ENXIO;
@@ -1736,10 +1850,7 @@ void megaraid_sas_kill_hba(struct megasas_instance *instance)
        msleep(1000);
        if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
                (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
-               (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
-               (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) ||
-               (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
-               (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
+               (instance->ctrl_context)) {
                writel(MFI_STOP_ADP, &instance->reg_set->doorbell);
                /* Flush */
                readl(&instance->reg_set->doorbell);
@@ -2506,10 +2617,7 @@ static int megasas_reset_bus_host(struct scsi_cmnd *scmd)
        /*
         * First wait for all commands to complete
         */
-       if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
-           (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) ||
-           (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
-           (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
+       if (instance->ctrl_context)
                ret = megasas_reset_fusion(scmd->device->host, 1);
        else
                ret = megasas_generic_reset(scmd);
@@ -2837,7 +2945,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
        struct megasas_header *hdr = &cmd->frame->hdr;
        unsigned long flags;
        struct fusion_context *fusion = instance->ctrl_context;
-       u32 opcode;
+       u32 opcode, status;
 
        /* flag for the retry reset */
        cmd->retry_for_fw_reset = 0;
@@ -2945,6 +3053,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
                        && (cmd->frame->dcmd.mbox.b[1] == 1)) {
                        fusion->fast_path_io = 0;
                        spin_lock_irqsave(instance->host->host_lock, flags);
+                       instance->map_update_cmd = NULL;
                        if (cmd->frame->hdr.cmd_status != 0) {
                                if (cmd->frame->hdr.cmd_status !=
                                    MFI_STAT_NOT_FOUND)
@@ -2982,6 +3091,27 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
                        spin_unlock_irqrestore(&poll_aen_lock, flags);
                }
 
+               /* FW has an updated PD sequence */
+               if ((opcode == MR_DCMD_SYSTEM_PD_MAP_GET_INFO) &&
+                       (cmd->frame->dcmd.mbox.b[0] == 1)) {
+
+                       spin_lock_irqsave(instance->host->host_lock, flags);
+                       status = cmd->frame->hdr.cmd_status;
+                       instance->jbod_seq_cmd = NULL;
+                       megasas_return_cmd(instance, cmd);
+
+                       if (status == MFI_STAT_OK) {
+                               instance->pd_seq_map_id++;
+                               /* Re-register a pd sync seq num cmd */
+                               if (megasas_sync_pd_seq_num(instance, true))
+                                       instance->use_seqnum_jbod_fp = false;
+                       } else
+                               instance->use_seqnum_jbod_fp = false;
+
+                       spin_unlock_irqrestore(instance->host->host_lock, flags);
+                       break;
+               }
+
                /*
                 * See if got an event notification
                 */
@@ -3348,22 +3478,14 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
                                PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
                                (instance->pdev->device ==
                                 PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
-                               (instance->pdev->device ==
-                               PCI_DEVICE_ID_LSI_FUSION) ||
-                               (instance->pdev->device ==
-                               PCI_DEVICE_ID_LSI_PLASMA) ||
-                               (instance->pdev->device ==
-                               PCI_DEVICE_ID_LSI_INVADER) ||
-                               (instance->pdev->device ==
-                               PCI_DEVICE_ID_LSI_FURY)) {
+                               (instance->ctrl_context))
                                writel(
                                  MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
                                  &instance->reg_set->doorbell);
-                       } else {
+                       else
                                writel(
                                    MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
                                        &instance->reg_set->inbound_doorbell);
-                       }
 
                        max_wait = MEGASAS_RESET_WAIT_TIME;
                        cur_state = MFI_STATE_WAIT_HANDSHAKE;
@@ -3374,17 +3496,10 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
                             PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
                                (instance->pdev->device ==
                                 PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
-                           (instance->pdev->device ==
-                            PCI_DEVICE_ID_LSI_FUSION) ||
-                           (instance->pdev->device ==
-                            PCI_DEVICE_ID_LSI_PLASMA) ||
-                           (instance->pdev->device ==
-                            PCI_DEVICE_ID_LSI_INVADER) ||
-                           (instance->pdev->device ==
-                            PCI_DEVICE_ID_LSI_FURY)) {
+                               (instance->ctrl_context))
                                writel(MFI_INIT_HOTPLUG,
                                       &instance->reg_set->doorbell);
-                       else
+                       else
                                writel(MFI_INIT_HOTPLUG,
                                        &instance->reg_set->inbound_doorbell);
 
@@ -3401,24 +3516,11 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
                                PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
                                (instance->pdev->device ==
                                PCI_DEVICE_ID_LSI_SAS0071SKINNY)  ||
-                               (instance->pdev->device
-                                       == PCI_DEVICE_ID_LSI_FUSION) ||
-                               (instance->pdev->device
-                                       == PCI_DEVICE_ID_LSI_PLASMA) ||
-                               (instance->pdev->device
-                                       == PCI_DEVICE_ID_LSI_INVADER) ||
-                               (instance->pdev->device
-                                       == PCI_DEVICE_ID_LSI_FURY)) {
+                               (instance->ctrl_context)) {
                                writel(MFI_RESET_FLAGS,
                                        &instance->reg_set->doorbell);
-                               if ((instance->pdev->device ==
-                                       PCI_DEVICE_ID_LSI_FUSION) ||
-                                       (instance->pdev->device ==
-                                       PCI_DEVICE_ID_LSI_PLASMA) ||
-                                       (instance->pdev->device ==
-                                       PCI_DEVICE_ID_LSI_INVADER) ||
-                                       (instance->pdev->device ==
-                                       PCI_DEVICE_ID_LSI_FURY)) {
+
+                               if (instance->ctrl_context) {
                                        for (i = 0; i < (10 * 1000); i += 20) {
                                                if (readl(
                                                            &instance->
@@ -3639,11 +3741,7 @@ static int megasas_create_frame_pool(struct megasas_instance *instance)
                memset(cmd->frame, 0, total_sz);
                cmd->frame->io.context = cpu_to_le32(cmd->index);
                cmd->frame->io.pad_0 = 0;
-               if ((instance->pdev->device != PCI_DEVICE_ID_LSI_FUSION) &&
-                   (instance->pdev->device != PCI_DEVICE_ID_LSI_PLASMA) &&
-                   (instance->pdev->device != PCI_DEVICE_ID_LSI_INVADER) &&
-                       (instance->pdev->device != PCI_DEVICE_ID_LSI_FURY) &&
-                   (reset_devices))
+               if (!instance->ctrl_context && reset_devices)
                        cmd->frame->hdr.cmd = MFI_CMD_INVALID;
        }
 
@@ -4136,11 +4234,21 @@ megasas_get_ctrl_info(struct megasas_instance *instance)
                le32_to_cpus((u32 *)&ctrl_info->adapterOperations2);
                le32_to_cpus((u32 *)&ctrl_info->adapterOperations3);
                megasas_update_ext_vd_details(instance);
+               instance->use_seqnum_jbod_fp =
+                       ctrl_info->adapterOperations3.useSeqNumJbodFP;
                instance->is_imr = (ctrl_info->memory_size ? 0 : 1);
                dev_info(&instance->pdev->dev,
                                "controller type\t: %s(%dMB)\n",
                                instance->is_imr ? "iMR" : "MR",
                                le16_to_cpu(ctrl_info->memory_size));
+               instance->disableOnlineCtrlReset =
+                       ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset;
+               dev_info(&instance->pdev->dev, "Online Controller Reset(OCR)\t: %s\n",
+                       instance->disableOnlineCtrlReset ? "Disabled" : "Enabled");
+               instance->secure_jbod_support =
+                       ctrl_info->adapterOperations3.supportSecurityonJBOD;
+               dev_info(&instance->pdev->dev, "Secure JBOD support\t: %s\n",
+                       instance->secure_jbod_support ? "Yes" : "No");
        }
 
        pci_free_consistent(instance->pdev, sizeof(struct megasas_ctrl_info),
@@ -4480,6 +4588,62 @@ megasas_destroy_irqs(struct megasas_instance *instance) {
                free_irq(instance->pdev->irq, &instance->irq_context[0]);
 }
 
+/**
+ * megasas_setup_jbod_map -    setup jbod map for FP seq_number.
+ * @instance:                          Adapter soft state
+ * @is_probe:                          Driver probe check
+ *
+ * Return 0 on success.
+ */
+void
+megasas_setup_jbod_map(struct megasas_instance *instance)
+{
+       int i;
+       struct fusion_context *fusion = instance->ctrl_context;
+       u32 pd_seq_map_sz;
+
+       pd_seq_map_sz = sizeof(struct MR_PD_CFG_SEQ_NUM_SYNC) +
+               (sizeof(struct MR_PD_CFG_SEQ) * (MAX_PHYSICAL_DEVICES - 1));
+
+       if (reset_devices || !fusion ||
+               !instance->ctrl_info->adapterOperations3.useSeqNumJbodFP) {
+               dev_info(&instance->pdev->dev,
+                       "Jbod map is not supported %s %d\n",
+                       __func__, __LINE__);
+               instance->use_seqnum_jbod_fp = false;
+               return;
+       }
+
+       if (fusion->pd_seq_sync[0])
+               goto skip_alloc;
+
+       for (i = 0; i < JBOD_MAPS_COUNT; i++) {
+               fusion->pd_seq_sync[i] = dma_alloc_coherent
+                       (&instance->pdev->dev, pd_seq_map_sz,
+                       &fusion->pd_seq_phys[i], GFP_KERNEL);
+               if (!fusion->pd_seq_sync[i]) {
+                       dev_err(&instance->pdev->dev,
+                               "Failed to allocate memory from %s %d\n",
+                               __func__, __LINE__);
+                       if (i == 1) {
+                               dma_free_coherent(&instance->pdev->dev,
+                                       pd_seq_map_sz, fusion->pd_seq_sync[0],
+                                       fusion->pd_seq_phys[0]);
+                               fusion->pd_seq_sync[0] = NULL;
+                       }
+                       instance->use_seqnum_jbod_fp = false;
+                       return;
+               }
+       }
+
+skip_alloc:
+       if (!megasas_sync_pd_seq_num(instance, false) &&
+               !megasas_sync_pd_seq_num(instance, true))
+               instance->use_seqnum_jbod_fp = true;
+       else
+               instance->use_seqnum_jbod_fp = false;
+}
+
 /**
  * megasas_init_fw -   Initializes the FW
  * @instance:          Adapter soft state
@@ -4498,6 +4662,9 @@ static int megasas_init_fw(struct megasas_instance *instance)
        unsigned long bar_list;
        int i, loop, fw_msix_count = 0;
        struct IOV_111 *iovPtr;
+       struct fusion_context *fusion;
+
+       fusion = instance->ctrl_context;
 
        /* Find first memory bar */
        bar_list = pci_select_bars(instance->pdev, IORESOURCE_MEM);
@@ -4523,6 +4690,10 @@ static int megasas_init_fw(struct megasas_instance *instance)
        case PCI_DEVICE_ID_LSI_PLASMA:
        case PCI_DEVICE_ID_LSI_INVADER:
        case PCI_DEVICE_ID_LSI_FURY:
+       case PCI_DEVICE_ID_LSI_INTRUDER:
+       case PCI_DEVICE_ID_LSI_INTRUDER_24:
+       case PCI_DEVICE_ID_LSI_CUTLASS_52:
+       case PCI_DEVICE_ID_LSI_CUTLASS_53:
                instance->instancet = &megasas_instance_template_fusion;
                break;
        case PCI_DEVICE_ID_LSI_SAS1078R:
@@ -4541,6 +4712,7 @@ static int megasas_init_fw(struct megasas_instance *instance)
        case PCI_DEVICE_ID_DELL_PERC5:
        default:
                instance->instancet = &megasas_instance_template_xscale;
+               instance->allow_fw_scan = 1;
                break;
        }
 
@@ -4575,37 +4747,32 @@ static int megasas_init_fw(struct megasas_instance *instance)
                scratch_pad_2 = readl
                        (&instance->reg_set->outbound_scratch_pad_2);
                /* Check max MSI-X vectors */
-               if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
-                   (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA)) {
-                       instance->msix_vectors = (scratch_pad_2
-                               & MR_MAX_REPLY_QUEUES_OFFSET) + 1;
-                       fw_msix_count = instance->msix_vectors;
-                       if (msix_vectors)
-                               instance->msix_vectors =
-                                       min(msix_vectors,
-                                           instance->msix_vectors);
-               } else if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER)
-                       || (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
-                       /* Invader/Fury supports more than 8 MSI-X */
-                       instance->msix_vectors = ((scratch_pad_2
-                               & MR_MAX_REPLY_QUEUES_EXT_OFFSET)
-                               >> MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT) + 1;
-                       fw_msix_count = instance->msix_vectors;
-                       /* Save 1-15 reply post index address to local memory
-                        * Index 0 is already saved from reg offset
-                        * MPI2_REPLY_POST_HOST_INDEX_OFFSET
-                        */
-                       for (loop = 1; loop < MR_MAX_MSIX_REG_ARRAY; loop++) {
-                               instance->reply_post_host_index_addr[loop] =
-                                       (u32 __iomem *)
-                                       ((u8 __iomem *)instance->reg_set +
-                                       MPI2_SUP_REPLY_POST_HOST_INDEX_OFFSET
-                                       + (loop * 0x10));
+               if (fusion) {
+                       if (fusion->adapter_type == THUNDERBOLT_SERIES) { /* Thunderbolt Series*/
+                               instance->msix_vectors = (scratch_pad_2
+                                       & MR_MAX_REPLY_QUEUES_OFFSET) + 1;
+                               fw_msix_count = instance->msix_vectors;
+                       } else { /* Invader series supports more than 8 MSI-x vectors*/
+                               instance->msix_vectors = ((scratch_pad_2
+                                       & MR_MAX_REPLY_QUEUES_EXT_OFFSET)
+                                       >> MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT) + 1;
+                               fw_msix_count = instance->msix_vectors;
+                               /* Save 1-15 reply post index address to local memory
+                                * Index 0 is already saved from reg offset
+                                * MPI2_REPLY_POST_HOST_INDEX_OFFSET
+                                */
+                               for (loop = 1; loop < MR_MAX_MSIX_REG_ARRAY; loop++) {
+                                       instance->reply_post_host_index_addr[loop] =
+                                               (u32 __iomem *)
+                                               ((u8 __iomem *)instance->reg_set +
+                                               MPI2_SUP_REPLY_POST_HOST_INDEX_OFFSET
+                                               + (loop * 0x10));
+                               }
                        }
                        if (msix_vectors)
                                instance->msix_vectors = min(msix_vectors,
                                        instance->msix_vectors);
-               } else
+               } else /* MFI adapters */
                        instance->msix_vectors = 1;
                /* Don't bother allocating more MSI-X vectors than cpus */
                instance->msix_vectors = min(instance->msix_vectors,
@@ -4626,6 +4793,9 @@ static int megasas_init_fw(struct megasas_instance *instance)
                "current msix/online cpus\t: (%d/%d)\n",
                instance->msix_vectors, (unsigned int)num_online_cpus());
 
+       tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
+               (unsigned long)instance);
+
        if (instance->msix_vectors ?
                megasas_setup_irqs_msix(instance, 1) :
                megasas_setup_irqs_ioapic(instance))
@@ -4646,13 +4816,13 @@ static int megasas_init_fw(struct megasas_instance *instance)
        if (instance->instancet->init_adapter(instance))
                goto fail_init_adapter;
 
-       tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
-               (unsigned long)instance);
 
        instance->instancet->enable_intr(instance);
 
        dev_err(&instance->pdev->dev, "INIT adapter done\n");
 
+       megasas_setup_jbod_map(instance);
+
        /** for passthrough
         * the following function will get the PD LIST.
         */
@@ -4686,8 +4856,6 @@ static int megasas_init_fw(struct megasas_instance *instance)
 
        tmp_sectors = min_t(u32, max_sectors_1, max_sectors_2);
 
-       instance->disableOnlineCtrlReset =
-       ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset;
        instance->mpio = ctrl_info->adapterOperations2.mpio;
        instance->UnevenSpanSupport =
                ctrl_info->adapterOperations2.supportUnevenSpans;
@@ -4700,18 +4868,22 @@ static int megasas_init_fw(struct megasas_instance *instance)
 
        }
        if (ctrl_info->host_interface.SRIOV) {
-               if (!ctrl_info->adapterOperations2.activePassive)
-                       instance->PlasmaFW111 = 1;
-
-               if (!instance->PlasmaFW111)
-                       instance->requestorId =
-                               ctrl_info->iov.requestorId;
-               else {
-                       iovPtr = (struct IOV_111 *)((unsigned char *)ctrl_info + IOV_111_OFFSET);
-                       instance->requestorId = iovPtr->requestorId;
+               instance->requestorId = ctrl_info->iov.requestorId;
+               if (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) {
+                       if (!ctrl_info->adapterOperations2.activePassive)
+                           instance->PlasmaFW111 = 1;
+
+                       dev_info(&instance->pdev->dev, "SR-IOV: firmware type: %s\n",
+                           instance->PlasmaFW111 ? "1.11" : "new");
+
+                       if (instance->PlasmaFW111) {
+                           iovPtr = (struct IOV_111 *)
+                               ((unsigned char *)ctrl_info + IOV_111_OFFSET);
+                           instance->requestorId = iovPtr->requestorId;
+                       }
                }
-               dev_warn(&instance->pdev->dev, "I am VF "
-                      "requestorId %d\n", instance->requestorId);
+               dev_info(&instance->pdev->dev, "SRIOV: VF requestorId %d\n",
+                       instance->requestorId);
        }
 
        instance->crash_dump_fw_support =
@@ -4732,8 +4904,6 @@ static int megasas_init_fw(struct megasas_instance *instance)
                instance->crash_dump_buf = NULL;
        }
 
-       instance->secure_jbod_support =
-               ctrl_info->adapterOperations3.supportSecurityonJBOD;
 
        dev_info(&instance->pdev->dev,
                "pci id\t\t: (0x%04x)/(0x%04x)/(0x%04x)/(0x%04x)\n",
@@ -4743,16 +4913,14 @@ static int megasas_init_fw(struct megasas_instance *instance)
                le16_to_cpu(ctrl_info->pci.sub_device_id));
        dev_info(&instance->pdev->dev, "unevenspan support      : %s\n",
                instance->UnevenSpanSupport ? "yes" : "no");
-       dev_info(&instance->pdev->dev, "disable ocr             : %s\n",
-               instance->disableOnlineCtrlReset ? "yes" : "no");
        dev_info(&instance->pdev->dev, "firmware crash dump     : %s\n",
                instance->crash_dump_drv_support ? "yes" : "no");
-       dev_info(&instance->pdev->dev, "secure jbod             : %s\n",
-               instance->secure_jbod_support ? "yes" : "no");
+       dev_info(&instance->pdev->dev, "jbod sync map           : %s\n",
+               instance->use_seqnum_jbod_fp ? "yes" : "no");
 
 
        instance->max_sectors_per_req = instance->max_num_sge *
-                                               PAGE_SIZE / 512;
+                                               SGE_BUFFER_SIZE / 512;
        if (tmp_sectors && (instance->max_sectors_per_req > tmp_sectors))
                instance->max_sectors_per_req = tmp_sectors;
 
@@ -5049,7 +5217,6 @@ static int megasas_start_aen(struct megasas_instance *instance)
 static int megasas_io_attach(struct megasas_instance *instance)
 {
        struct Scsi_Host *host = instance->host;
-       u32 error;
 
        /*
         * Export parameters required by SCSI mid-layer
@@ -5092,20 +5259,10 @@ static int megasas_io_attach(struct megasas_instance *instance)
        host->max_cmd_len = 16;
 
        /* Fusion only supports host reset */
-       if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
-           (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) ||
-           (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
-           (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
+       if (instance->ctrl_context) {
                host->hostt->eh_device_reset_handler = NULL;
                host->hostt->eh_bus_reset_handler = NULL;
        }
-       error = scsi_init_shared_tag_map(host, host->can_queue);
-       if (error) {
-               dev_err(&instance->pdev->dev,
-                       "Failed to shared tag from %s %d\n",
-                       __func__, __LINE__);
-               return -ENODEV;
-       }
 
        /*
         * Notify the mid-layer about the new controller
@@ -5218,6 +5375,10 @@ static int megasas_probe_one(struct pci_dev *pdev,
        case PCI_DEVICE_ID_LSI_PLASMA:
        case PCI_DEVICE_ID_LSI_INVADER:
        case PCI_DEVICE_ID_LSI_FURY:
+       case PCI_DEVICE_ID_LSI_INTRUDER:
+       case PCI_DEVICE_ID_LSI_INTRUDER_24:
+       case PCI_DEVICE_ID_LSI_CUTLASS_52:
+       case PCI_DEVICE_ID_LSI_CUTLASS_53:
        {
                instance->ctrl_context_pages =
                        get_order(sizeof(struct fusion_context));
@@ -5231,6 +5392,11 @@ static int megasas_probe_one(struct pci_dev *pdev,
                fusion = instance->ctrl_context;
                memset(fusion, 0,
                        ((1 << PAGE_SHIFT) << instance->ctrl_context_pages));
+               if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
+                       (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA))
+                       fusion->adapter_type = THUNDERBOLT_SERIES;
+               else
+                       fusion->adapter_type = INVADER_SERIES;
        }
        break;
        default: /* For all other supported controllers */
@@ -5333,10 +5499,7 @@ static int megasas_probe_one(struct pci_dev *pdev,
        instance->disableOnlineCtrlReset = 1;
        instance->UnevenSpanSupport = 0;
 
-       if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
-           (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) ||
-           (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
-           (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
+       if (instance->ctrl_context) {
                INIT_WORK(&instance->work_init, megasas_fusion_ocr_wq);
                INIT_WORK(&instance->crash_init, megasas_fusion_crash_dump_wq);
        } else
@@ -5416,10 +5579,7 @@ fail_io_attach:
        instance->instancet->disable_intr(instance);
        megasas_destroy_irqs(instance);
 
-       if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
-           (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) ||
-           (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
-           (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
+       if (instance->ctrl_context)
                megasas_release_fusion(instance);
        else
                megasas_release_mfi(instance);
@@ -5506,10 +5666,14 @@ static void megasas_shutdown_controller(struct megasas_instance *instance,
 
        if (instance->aen_cmd)
                megasas_issue_blocked_abort_cmd(instance,
-                       instance->aen_cmd, 30);
+                       instance->aen_cmd, MEGASAS_BLOCKED_CMD_TIMEOUT);
        if (instance->map_update_cmd)
                megasas_issue_blocked_abort_cmd(instance,
-                       instance->map_update_cmd, 30);
+                       instance->map_update_cmd, MEGASAS_BLOCKED_CMD_TIMEOUT);
+       if (instance->jbod_seq_cmd)
+               megasas_issue_blocked_abort_cmd(instance,
+                       instance->jbod_seq_cmd, MEGASAS_BLOCKED_CMD_TIMEOUT);
+
        dcmd = &cmd->frame->dcmd;
 
        memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
@@ -5628,12 +5792,7 @@ megasas_resume(struct pci_dev *pdev)
                                  instance->msix_vectors))
                goto fail_reenable_msix;
 
-       switch (instance->pdev->device) {
-       case PCI_DEVICE_ID_LSI_FUSION:
-       case PCI_DEVICE_ID_LSI_PLASMA:
-       case PCI_DEVICE_ID_LSI_INVADER:
-       case PCI_DEVICE_ID_LSI_FURY:
-       {
+       if (instance->ctrl_context) {
                megasas_reset_reply_desc(instance);
                if (megasas_ioc_init_fusion(instance)) {
                        megasas_free_cmds(instance);
@@ -5642,14 +5801,11 @@ megasas_resume(struct pci_dev *pdev)
                }
                if (!megasas_get_map_info(instance))
                        megasas_sync_map_info(instance);
-       }
-       break;
-       default:
+       } else {
                *instance->producer = 0;
                *instance->consumer = 0;
                if (megasas_issue_init_mfi(instance))
                        goto fail_init_mfi;
-               break;
        }
 
        tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
@@ -5674,6 +5830,7 @@ megasas_resume(struct pci_dev *pdev)
        }
 
        instance->instancet->enable_intr(instance);
+       megasas_setup_jbod_map(instance);
        instance->unload = 0;
 
        /*
@@ -5721,6 +5878,7 @@ static void megasas_detach_one(struct pci_dev *pdev)
        struct Scsi_Host *host;
        struct megasas_instance *instance;
        struct fusion_context *fusion;
+       u32 pd_seq_map_sz;
 
        instance = pci_get_drvdata(pdev);
        instance->unload = 1;
@@ -5769,12 +5927,11 @@ static void megasas_detach_one(struct pci_dev *pdev)
        if (instance->msix_vectors)
                pci_disable_msix(instance->pdev);
 
-       switch (instance->pdev->device) {
-       case PCI_DEVICE_ID_LSI_FUSION:
-       case PCI_DEVICE_ID_LSI_PLASMA:
-       case PCI_DEVICE_ID_LSI_INVADER:
-       case PCI_DEVICE_ID_LSI_FURY:
+       if (instance->ctrl_context) {
                megasas_release_fusion(instance);
+                       pd_seq_map_sz = sizeof(struct MR_PD_CFG_SEQ_NUM_SYNC) +
+                               (sizeof(struct MR_PD_CFG_SEQ) *
+                                       (MAX_PHYSICAL_DEVICES - 1));
                for (i = 0; i < 2 ; i++) {
                        if (fusion->ld_map[i])
                                dma_free_coherent(&instance->pdev->dev,
@@ -5784,11 +5941,15 @@ static void megasas_detach_one(struct pci_dev *pdev)
                        if (fusion->ld_drv_map[i])
                                free_pages((ulong)fusion->ld_drv_map[i],
                                        fusion->drv_map_pages);
+                               if (fusion->pd_seq_sync)
+                                       dma_free_coherent(&instance->pdev->dev,
+                                               pd_seq_map_sz,
+                                               fusion->pd_seq_sync[i],
+                                               fusion->pd_seq_phys[i]);
                }
                free_pages((ulong)instance->ctrl_context,
                        instance->ctrl_context_pages);
-               break;
-       default:
+       } else {
                megasas_release_mfi(instance);
                pci_free_consistent(pdev, sizeof(u32),
                                    instance->producer,
@@ -5796,7 +5957,6 @@ static void megasas_detach_one(struct pci_dev *pdev)
                pci_free_consistent(pdev, sizeof(u32),
                                    instance->consumer,
                                    instance->consumer_h);
-               break;
        }
 
        kfree(instance->ctrl_info);
@@ -6316,6 +6476,9 @@ static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg)
        int i;
        int error = 0;
        compat_uptr_t ptr;
+       unsigned long local_raw_ptr;
+       u32 local_sense_off;
+       u32 local_sense_len;
 
        if (clear_user(ioc, sizeof(*ioc)))
                return -EFAULT;
@@ -6333,9 +6496,15 @@ static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg)
         * sense_len is not null, so prepare the 64bit value under
         * the same condition.
         */
-       if (ioc->sense_len) {
+       if (get_user(local_raw_ptr, ioc->frame.raw) ||
+               get_user(local_sense_off, &ioc->sense_off) ||
+               get_user(local_sense_len, &ioc->sense_len))
+               return -EFAULT;
+
+
+       if (local_sense_len) {
                void __user **sense_ioc_ptr =
-                       (void __user **)(ioc->frame.raw + ioc->sense_off);
+                       (void __user **)((u8*)local_raw_ptr + local_sense_off);
                compat_uptr_t *sense_cioc_ptr =
                        (compat_uptr_t *)(cioc->frame.raw + cioc->sense_off);
                if (get_user(ptr, sense_cioc_ptr) ||
@@ -6504,6 +6673,7 @@ megasas_aen_polling(struct work_struct *work)
        instance->ev = NULL;
        host = instance->host;
        if (instance->evt_detail) {
+               megasas_decode_evt(instance);
 
                switch (le32_to_cpu(instance->evt_detail->code)) {
                case MR_EVT_PD_INSERTED:
@@ -6564,8 +6734,7 @@ megasas_aen_polling(struct work_struct *work)
                case MR_EVT_CFG_CLEARED:
                case MR_EVT_LD_DELETED:
                        if (!instance->requestorId ||
-                           (instance->requestorId &&
-                            megasas_get_ld_vf_affiliation(instance, 0))) {
+                           megasas_get_ld_vf_affiliation(instance, 0)) {
                                if (megasas_ld_list_query(instance,
                                                          MR_LD_QUERY_TYPE_EXPOSED_TO_HOST))
                                        megasas_get_ld_list(instance);
@@ -6596,8 +6765,7 @@ megasas_aen_polling(struct work_struct *work)
                        break;
                case MR_EVT_LD_CREATED:
                        if (!instance->requestorId ||
-                           (instance->requestorId &&
-                            megasas_get_ld_vf_affiliation(instance, 0))) {
+                           megasas_get_ld_vf_affiliation(instance, 0)) {
                                if (megasas_ld_list_query(instance,
                                                          MR_LD_QUERY_TYPE_EXPOSED_TO_HOST))
                                        megasas_get_ld_list(instance);
@@ -6627,6 +6795,9 @@ megasas_aen_polling(struct work_struct *work)
                case MR_EVT_LD_STATE_CHANGE:
                        doscan = 1;
                        break;
+               case MR_EVT_CTRL_PROP_CHANGED:
+                       megasas_get_ctrl_info(instance);
+                       break;
                default:
                        doscan = 0;
                        break;
@@ -6663,8 +6834,7 @@ megasas_aen_polling(struct work_struct *work)
                }
 
                if (!instance->requestorId ||
-                   (instance->requestorId &&
-                    megasas_get_ld_vf_affiliation(instance, 0))) {
+                   megasas_get_ld_vf_affiliation(instance, 0)) {
                        if (megasas_ld_list_query(instance,
                                                  MR_LD_QUERY_TYPE_EXPOSED_TO_HOST))
                                megasas_get_ld_list(instance);
index be57b18675a4b1b96243e067a71cd2db2a80c1c5..741509b3561776a874189ad1613984df86129ffe 100644 (file)
@@ -741,14 +741,12 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld,
        u8      physArm, span;
        u64     row;
        u8      retval = TRUE;
-       u8      do_invader = 0;
        u64     *pdBlock = &io_info->pdBlock;
        __le16  *pDevHandle = &io_info->devHandle;
        u32     logArm, rowMod, armQ, arm;
+       struct fusion_context *fusion;
 
-       if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER ||
-               instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
-               do_invader = 1;
+       fusion = instance->ctrl_context;
 
        /*Get row and span from io_info for Uneven Span IO.*/
        row         = io_info->start_row;
@@ -779,7 +777,8 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld,
        else {
                *pDevHandle = cpu_to_le16(MR_PD_INVALID);
                if ((raid->level >= 5) &&
-                       (!do_invader  || (do_invader &&
+                       ((fusion->adapter_type == THUNDERBOLT_SERIES)  ||
+                       ((fusion->adapter_type == INVADER_SERIES) &&
                        (raid->regTypeReqOnRead != REGION_TYPE_UNUSED))))
                        pRAID_Context->regLockFlags = REGION_TYPE_EXCLUSIVE;
                else if (raid->level == 1) {
@@ -823,13 +822,12 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow,
        u8          physArm, span;
        u64         row;
        u8          retval = TRUE;
-       u8          do_invader = 0;
        u64         *pdBlock = &io_info->pdBlock;
        __le16      *pDevHandle = &io_info->devHandle;
+       struct fusion_context *fusion;
+
+       fusion = instance->ctrl_context;
 
-       if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER ||
-               instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
-               do_invader = 1;
 
        row =  mega_div64_32(stripRow, raid->rowDataSize);
 
@@ -875,7 +873,8 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow,
                /* set dev handle as invalid. */
                *pDevHandle = cpu_to_le16(MR_PD_INVALID);
                if ((raid->level >= 5) &&
-                       (!do_invader  || (do_invader &&
+                       ((fusion->adapter_type == THUNDERBOLT_SERIES)  ||
+                       ((fusion->adapter_type == INVADER_SERIES) &&
                        (raid->regTypeReqOnRead != REGION_TYPE_UNUSED))))
                        pRAID_Context->regLockFlags = REGION_TYPE_EXCLUSIVE;
                else if (raid->level == 1) {
@@ -909,6 +908,7 @@ MR_BuildRaidContext(struct megasas_instance *instance,
                    struct RAID_CONTEXT *pRAID_Context,
                    struct MR_DRV_RAID_MAP_ALL *map, u8 **raidLUN)
 {
+       struct fusion_context *fusion;
        struct MR_LD_RAID  *raid;
        u32         ld, stripSize, stripe_mask;
        u64         endLba, endStrip, endRow, start_row, start_strip;
@@ -929,6 +929,7 @@ MR_BuildRaidContext(struct megasas_instance *instance,
        isRead = io_info->isRead;
        io_info->IoforUnevenSpan = 0;
        io_info->start_span     = SPAN_INVALID;
+       fusion = instance->ctrl_context;
 
        ld = MR_TargetIdToLdGet(ldTgtId, map);
        raid = MR_LdRaidGet(ld, map);
@@ -1092,8 +1093,7 @@ MR_BuildRaidContext(struct megasas_instance *instance,
                cpu_to_le16(raid->fpIoTimeoutForLd ?
                            raid->fpIoTimeoutForLd :
                            map->raidMap.fpPdIoTimeoutSec);
-       if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
-               (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
+       if (fusion->adapter_type == INVADER_SERIES)
                pRAID_Context->regLockFlags = (isRead) ?
                        raid->regTypeReqOnRead : raid->regTypeReqOnWrite;
        else
@@ -1198,10 +1198,6 @@ void mr_update_span_set(struct MR_DRV_RAID_MAP_ALL *map,
                                                span_row_width +=
                                                        MR_LdSpanPtrGet
                                                        (ld, count, map)->spanRowDataSize;
-                                               printk(KERN_INFO "megasas:"
-                                                       "span %x rowDataSize %x\n",
-                                                       count, MR_LdSpanPtrGet
-                                                       (ld, count, map)->spanRowDataSize);
                                        }
                                }
 
index f0837cc3b163949628cdeab58ed6073eb7015566..8d630a552b078721c5c5eea640995046a9907565 100644 (file)
@@ -316,26 +316,23 @@ static int megasas_create_frame_pool_fusion(struct megasas_instance *instance)
        u32 max_cmd;
        struct fusion_context *fusion;
        struct megasas_cmd_fusion *cmd;
-       u32 total_sz_chain_frame;
 
        fusion = instance->ctrl_context;
        max_cmd = instance->max_fw_cmds;
 
-       total_sz_chain_frame = MEGASAS_MAX_SZ_CHAIN_FRAME;
 
        /*
         * Use DMA pool facility provided by PCI layer
         */
 
-       fusion->sg_dma_pool = pci_pool_create("megasas sg pool fusion",
-                                             instance->pdev,
-                                             total_sz_chain_frame, 4,
-                                             0);
+       fusion->sg_dma_pool = pci_pool_create("sg_pool_fusion", instance->pdev,
+                                               instance->max_chain_frame_sz,
+                                               4, 0);
        if (!fusion->sg_dma_pool) {
                dev_printk(KERN_DEBUG, &instance->pdev->dev, "failed to setup request pool fusion\n");
                return -ENOMEM;
        }
-       fusion->sense_dma_pool = pci_pool_create("megasas sense pool fusion",
+       fusion->sense_dma_pool = pci_pool_create("sense pool fusion",
                                                 instance->pdev,
                                                 SCSI_SENSE_BUFFERSIZE, 64, 0);
 
@@ -605,6 +602,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
        int i;
        struct megasas_header *frame_hdr;
        const char *sys_info;
+       MFI_CAPABILITIES *drv_ops;
 
        fusion = instance->ctrl_context;
 
@@ -652,20 +650,21 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
        init_frame->cmd = MFI_CMD_INIT;
        init_frame->cmd_status = 0xFF;
 
+       drv_ops = (MFI_CAPABILITIES *) &(init_frame->driver_operations);
+
        /* driver support Extended MSIX */
-       if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
-               (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
-               init_frame->driver_operations.
-                       mfi_capabilities.support_additional_msix = 1;
+       if (fusion->adapter_type == INVADER_SERIES)
+               drv_ops->mfi_capabilities.support_additional_msix = 1;
        /* driver supports HA / Remote LUN over Fast Path interface */
-       init_frame->driver_operations.mfi_capabilities.support_fp_remote_lun
-               = 1;
-       init_frame->driver_operations.mfi_capabilities.support_max_255lds
-               = 1;
-       init_frame->driver_operations.mfi_capabilities.support_ndrive_r1_lb
-               = 1;
-       init_frame->driver_operations.mfi_capabilities.security_protocol_cmds_fw
-               = 1;
+       drv_ops->mfi_capabilities.support_fp_remote_lun = 1;
+
+       drv_ops->mfi_capabilities.support_max_255lds = 1;
+       drv_ops->mfi_capabilities.support_ndrive_r1_lb = 1;
+       drv_ops->mfi_capabilities.security_protocol_cmds_fw = 1;
+
+       if (instance->max_chain_frame_sz > MEGASAS_CHAIN_FRAME_SZ_MIN)
+               drv_ops->mfi_capabilities.support_ext_io_size = 1;
+
        /* Convert capability to LE32 */
        cpu_to_le32s((u32 *)&init_frame->driver_operations.mfi_capabilities);
 
@@ -726,6 +725,83 @@ fail_get_cmd:
        return ret;
 }
 
+/**
+ * megasas_sync_pd_seq_num -   JBOD SEQ MAP
+ * @instance:          Adapter soft state
+ * @pend:              set to 1, if it is pended jbod map.
+ *
+ * Issue Jbod map to the firmware. If it is pended command,
+ * issue command and return. If it is first instance of jbod map
+ * issue and receive command.
+ */
+int
+megasas_sync_pd_seq_num(struct megasas_instance *instance, bool pend) {
+       int ret = 0;
+       u32 pd_seq_map_sz;
+       struct megasas_cmd *cmd;
+       struct megasas_dcmd_frame *dcmd;
+       struct fusion_context *fusion = instance->ctrl_context;
+       struct MR_PD_CFG_SEQ_NUM_SYNC *pd_sync;
+       dma_addr_t pd_seq_h;
+
+       pd_sync = (void *)fusion->pd_seq_sync[(instance->pd_seq_map_id & 1)];
+       pd_seq_h = fusion->pd_seq_phys[(instance->pd_seq_map_id & 1)];
+       pd_seq_map_sz = sizeof(struct MR_PD_CFG_SEQ_NUM_SYNC) +
+                       (sizeof(struct MR_PD_CFG_SEQ) *
+                       (MAX_PHYSICAL_DEVICES - 1));
+
+       cmd = megasas_get_cmd(instance);
+       if (!cmd) {
+               dev_err(&instance->pdev->dev,
+                       "Could not get mfi cmd. Fail from %s %d\n",
+                       __func__, __LINE__);
+               return -ENOMEM;
+       }
+
+       dcmd = &cmd->frame->dcmd;
+
+       memset(pd_sync, 0, pd_seq_map_sz);
+       memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
+       dcmd->cmd = MFI_CMD_DCMD;
+       dcmd->cmd_status = 0xFF;
+       dcmd->sge_count = 1;
+       dcmd->timeout = 0;
+       dcmd->pad_0 = 0;
+       dcmd->data_xfer_len = cpu_to_le32(pd_seq_map_sz);
+       dcmd->opcode = cpu_to_le32(MR_DCMD_SYSTEM_PD_MAP_GET_INFO);
+       dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(pd_seq_h);
+       dcmd->sgl.sge32[0].length = cpu_to_le32(pd_seq_map_sz);
+
+       if (pend) {
+               dcmd->mbox.b[0] = MEGASAS_DCMD_MBOX_PEND_FLAG;
+               dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_WRITE);
+               instance->jbod_seq_cmd = cmd;
+               instance->instancet->issue_dcmd(instance, cmd);
+               return 0;
+       }
+
+       dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
+
+       /* Below code is only for non pended DCMD */
+       if (instance->ctrl_context && !instance->mask_interrupts)
+               ret = megasas_issue_blocked_cmd(instance, cmd, 60);
+       else
+               ret = megasas_issue_polled(instance, cmd);
+
+       if (le32_to_cpu(pd_sync->count) > MAX_PHYSICAL_DEVICES) {
+               dev_warn(&instance->pdev->dev,
+                       "driver supports max %d JBOD, but FW reports %d\n",
+                       MAX_PHYSICAL_DEVICES, le32_to_cpu(pd_sync->count));
+               ret = -EINVAL;
+       }
+
+       if (!ret)
+               instance->pd_seq_map_id++;
+
+       megasas_return_cmd(instance, cmd);
+       return ret;
+}
+
 /*
  * megasas_get_ld_map_info -   Returns FW's ld_map structure
  * @instance:                          Adapter soft state
@@ -961,6 +1037,18 @@ megasas_display_intel_branding(struct megasas_instance *instance)
                        break;
                }
                break;
+       case PCI_DEVICE_ID_LSI_CUTLASS_52:
+       case PCI_DEVICE_ID_LSI_CUTLASS_53:
+               switch (instance->pdev->subsystem_device) {
+               case MEGARAID_INTEL_RMS3BC160_SSDID:
+                       dev_info(&instance->pdev->dev, "scsi host %d: %s\n",
+                               instance->host->host_no,
+                               MEGARAID_INTEL_RMS3BC160_BRANDING);
+                       break;
+               default:
+                       break;
+               }
+               break;
        default:
                break;
        }
@@ -977,7 +1065,7 @@ megasas_init_adapter_fusion(struct megasas_instance *instance)
 {
        struct megasas_register_set __iomem *reg_set;
        struct fusion_context *fusion;
-       u32 max_cmd;
+       u32 max_cmd, scratch_pad_2;
        int i = 0, count;
 
        fusion = instance->ctrl_context;
@@ -1016,15 +1104,40 @@ megasas_init_adapter_fusion(struct megasas_instance *instance)
                (MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE *
                 (max_cmd + 1)); /* Extra 1 for SMID 0 */
 
+       scratch_pad_2 = readl(&instance->reg_set->outbound_scratch_pad_2);
+       /* If scratch_pad_2 & MEGASAS_MAX_CHAIN_SIZE_UNITS_MASK is set,
+        * Firmware support extended IO chain frame which is 4 times more than
+        * legacy Firmware.
+        * Legacy Firmware - Frame size is (8 * 128) = 1K
+        * 1M IO Firmware  - Frame size is (8 * 128 * 4)  = 4K
+        */
+       if (scratch_pad_2 & MEGASAS_MAX_CHAIN_SIZE_UNITS_MASK)
+               instance->max_chain_frame_sz =
+                       ((scratch_pad_2 & MEGASAS_MAX_CHAIN_SIZE_MASK) >>
+                       MEGASAS_MAX_CHAIN_SHIFT) * MEGASAS_1MB_IO;
+       else
+               instance->max_chain_frame_sz =
+                       ((scratch_pad_2 & MEGASAS_MAX_CHAIN_SIZE_MASK) >>
+                       MEGASAS_MAX_CHAIN_SHIFT) * MEGASAS_256K_IO;
+
+       if (instance->max_chain_frame_sz < MEGASAS_CHAIN_FRAME_SZ_MIN) {
+               dev_warn(&instance->pdev->dev, "frame size %d invalid, fall back to legacy max frame size %d\n",
+                       instance->max_chain_frame_sz,
+                       MEGASAS_CHAIN_FRAME_SZ_MIN);
+               instance->max_chain_frame_sz = MEGASAS_CHAIN_FRAME_SZ_MIN;
+       }
+
        fusion->max_sge_in_main_msg =
-         (MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE -
-          offsetof(struct MPI2_RAID_SCSI_IO_REQUEST, SGL))/16;
+               (MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE
+                       - offsetof(struct MPI2_RAID_SCSI_IO_REQUEST, SGL))/16;
 
        fusion->max_sge_in_chain =
-               MEGASAS_MAX_SZ_CHAIN_FRAME / sizeof(union MPI2_SGE_IO_UNION);
+               instance->max_chain_frame_sz
+                       / sizeof(union MPI2_SGE_IO_UNION);
 
-       instance->max_num_sge = rounddown_pow_of_two(
-               fusion->max_sge_in_main_msg + fusion->max_sge_in_chain - 2);
+       instance->max_num_sge =
+               rounddown_pow_of_two(fusion->max_sge_in_main_msg
+                       + fusion->max_sge_in_chain - 2);
 
        /* Used for pass thru MFI frame (DCMD) */
        fusion->chain_offset_mfi_pthru =
@@ -1186,8 +1299,7 @@ megasas_make_sgl_fusion(struct megasas_instance *instance,
 
        fusion = instance->ctrl_context;
 
-       if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
-               (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
+       if (fusion->adapter_type == INVADER_SERIES) {
                struct MPI25_IEEE_SGE_CHAIN64 *sgl_ptr_end = sgl_ptr;
                sgl_ptr_end += fusion->max_sge_in_main_msg - 1;
                sgl_ptr_end->Flags = 0;
@@ -1204,11 +1316,9 @@ megasas_make_sgl_fusion(struct megasas_instance *instance,
                sgl_ptr->Length = cpu_to_le32(sg_dma_len(os_sgl));
                sgl_ptr->Address = cpu_to_le64(sg_dma_address(os_sgl));
                sgl_ptr->Flags = 0;
-               if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
-                       (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
+               if (fusion->adapter_type == INVADER_SERIES)
                        if (i == sge_count - 1)
                                sgl_ptr->Flags = IEEE_SGE_FLAGS_END_OF_LIST;
-               }
                sgl_ptr++;
 
                sg_processed = i + 1;
@@ -1217,10 +1327,7 @@ megasas_make_sgl_fusion(struct megasas_instance *instance,
                    (sge_count > fusion->max_sge_in_main_msg)) {
 
                        struct MPI25_IEEE_SGE_CHAIN64 *sg_chain;
-                       if ((instance->pdev->device ==
-                               PCI_DEVICE_ID_LSI_INVADER) ||
-                               (instance->pdev->device ==
-                               PCI_DEVICE_ID_LSI_FURY)) {
+                       if (fusion->adapter_type == INVADER_SERIES) {
                                if ((le16_to_cpu(cmd->io_request->IoFlags) &
                                        MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH) !=
                                        MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH)
@@ -1236,10 +1343,7 @@ megasas_make_sgl_fusion(struct megasas_instance *instance,
                        sg_chain = sgl_ptr;
                        /* Prepare chain element */
                        sg_chain->NextChainOffset = 0;
-                       if ((instance->pdev->device ==
-                               PCI_DEVICE_ID_LSI_INVADER) ||
-                               (instance->pdev->device ==
-                               PCI_DEVICE_ID_LSI_FURY))
+                       if (fusion->adapter_type == INVADER_SERIES)
                                sg_chain->Flags = IEEE_SGE_FLAGS_CHAIN_ELEMENT;
                        else
                                sg_chain->Flags =
@@ -1250,7 +1354,7 @@ megasas_make_sgl_fusion(struct megasas_instance *instance,
 
                        sgl_ptr =
                          (struct MPI25_IEEE_SGE_CHAIN64 *)cmd->sg_frame;
-                       memset(sgl_ptr, 0, MEGASAS_MAX_SZ_CHAIN_FRAME);
+                       memset(sgl_ptr, 0, instance->max_chain_frame_sz);
                }
        }
 
@@ -1556,8 +1660,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
                cmd->request_desc->SCSIIO.RequestFlags =
                        (MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY
                         << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
-               if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
-                       (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
+               if (fusion->adapter_type == INVADER_SERIES) {
                        if (io_request->RaidContext.regLockFlags ==
                            REGION_TYPE_UNUSED)
                                cmd->request_desc->SCSIIO.RequestFlags =
@@ -1582,7 +1685,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
                        scp->SCp.Status &= ~MEGASAS_LOAD_BALANCE_FLAG;
 
                if ((raidLUN[0] == 1) &&
-                       (local_map_ptr->raidMap.devHndlInfo[io_info.pd_after_lb].validHandles > 2)) {
+                       (local_map_ptr->raidMap.devHndlInfo[io_info.pd_after_lb].validHandles > 1)) {
                        instance->dev_handle = !(instance->dev_handle);
                        io_info.devHandle =
                                local_map_ptr->raidMap.devHndlInfo[io_info.pd_after_lb].devHandle[instance->dev_handle];
@@ -1598,8 +1701,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
                cmd->request_desc->SCSIIO.RequestFlags =
                        (MEGASAS_REQ_DESCRIPT_FLAGS_LD_IO
                         << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
-               if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
-                       (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
+               if (fusion->adapter_type == INVADER_SERIES) {
                        if (io_request->RaidContext.regLockFlags ==
                            REGION_TYPE_UNUSED)
                                cmd->request_desc->SCSIIO.RequestFlags =
@@ -1722,7 +1824,9 @@ megasas_build_syspd_fusion(struct megasas_instance *instance,
        u16 timeout_limit;
        struct MR_DRV_RAID_MAP_ALL *local_map_ptr;
        struct RAID_CONTEXT     *pRAID_Context;
+       struct MR_PD_CFG_SEQ_NUM_SYNC *pd_sync;
        struct fusion_context *fusion = instance->ctrl_context;
+       pd_sync = (void *)fusion->pd_seq_sync[(instance->pd_seq_map_id - 1) & 1];
 
        device_id = MEGASAS_DEV_INDEX(scmd);
        pd_index = MEGASAS_PD_INDEX(scmd);
@@ -1731,16 +1835,38 @@ megasas_build_syspd_fusion(struct megasas_instance *instance,
        io_request = cmd->io_request;
        /* get RAID_Context pointer */
        pRAID_Context = &io_request->RaidContext;
+       pRAID_Context->regLockFlags = 0;
+       pRAID_Context->regLockRowLBA = 0;
+       pRAID_Context->regLockLength = 0;
        io_request->DataLength = cpu_to_le32(scsi_bufflen(scmd));
        io_request->LUN[1] = scmd->device->lun;
        pRAID_Context->RAIDFlags = MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD
                << MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT;
 
-       pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id);
-       pRAID_Context->configSeqNum = 0;
-       local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)];
-       io_request->DevHandle =
-               local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl;
+       /* If FW supports PD sequence number */
+       if (instance->use_seqnum_jbod_fp &&
+               instance->pd_list[pd_index].driveType == TYPE_DISK) {
+               /* TgtId must be incremented by 255 as jbod seq number is index
+                * below raid map
+                */
+               pRAID_Context->VirtualDiskTgtId =
+                       cpu_to_le16(device_id + (MAX_PHYSICAL_DEVICES - 1));
+               pRAID_Context->configSeqNum = pd_sync->seq[pd_index].seqNum;
+               io_request->DevHandle = pd_sync->seq[pd_index].devHandle;
+               pRAID_Context->regLockFlags |=
+                       (MR_RL_FLAGS_SEQ_NUM_ENABLE|MR_RL_FLAGS_GRANT_DESTINATION_CUDA);
+       } else if (fusion->fast_path_io) {
+               pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id);
+               pRAID_Context->configSeqNum = 0;
+               local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)];
+               io_request->DevHandle =
+                       local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl;
+       } else {
+               /* Want to send all IO via FW path */
+               pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id);
+               pRAID_Context->configSeqNum = 0;
+               io_request->DevHandle = cpu_to_le16(0xFFFF);
+       }
 
        cmd->request_desc->SCSIIO.DevHandle = io_request->DevHandle;
        cmd->request_desc->SCSIIO.MSIxIndex =
@@ -1755,22 +1881,16 @@ megasas_build_syspd_fusion(struct megasas_instance *instance,
                        (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO <<
                                MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
                pRAID_Context->timeoutValue = cpu_to_le16(os_timeout_value);
+               pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id);
        } else {
                /* system pd Fast Path */
                io_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
-               pRAID_Context->regLockFlags = 0;
-               pRAID_Context->regLockRowLBA = 0;
-               pRAID_Context->regLockLength = 0;
                timeout_limit = (scmd->device->type == TYPE_DISK) ?
                                255 : 0xFFFF;
                pRAID_Context->timeoutValue =
                        cpu_to_le16((os_timeout_value > timeout_limit) ?
                        timeout_limit : os_timeout_value);
-               if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
-                       (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
-                       cmd->request_desc->SCSIIO.RequestFlags |=
-                               (MEGASAS_REQ_DESCRIPT_FLAGS_NO_LOCK <<
-                               MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
+               if (fusion->adapter_type == INVADER_SERIES) {
                        pRAID_Context->Type = MPI2_TYPE_CUDA;
                        pRAID_Context->nseg = 0x1;
                        io_request->IoFlags |=
@@ -1796,7 +1916,7 @@ megasas_build_io_fusion(struct megasas_instance *instance,
                        struct scsi_cmnd *scp,
                        struct megasas_cmd_fusion *cmd)
 {
-       u32 sge_count;
+       u16 sge_count;
        u8  cmd_type;
        struct MPI2_RAID_SCSI_IO_REQUEST *io_request = cmd->io_request;
 
@@ -1854,7 +1974,11 @@ megasas_build_io_fusion(struct megasas_instance *instance,
                return 1;
        }
 
+       /* numSGE store lower 8 bit of sge_count.
+        * numSGEExt store higher 8 bit of sge_count
+        */
        io_request->RaidContext.numSGE = sge_count;
+       io_request->RaidContext.numSGEExt = (u8)(sge_count >> 8);
 
        io_request->SGLFlags = cpu_to_le16(MPI2_SGE_FLAGS_64_BIT_ADDRESSING);
 
@@ -2084,10 +2208,7 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)
                 * pending to be completed
                 */
                if (threshold_reply_count >= THRESHOLD_REPLY_COUNT) {
-                       if ((instance->pdev->device ==
-                               PCI_DEVICE_ID_LSI_INVADER) ||
-                               (instance->pdev->device ==
-                               PCI_DEVICE_ID_LSI_FURY))
+                       if (fusion->adapter_type == INVADER_SERIES)
                                writel(((MSIxIndex & 0x7) << 24) |
                                        fusion->last_reply_idx[MSIxIndex],
                                        instance->reply_post_host_index_addr[MSIxIndex/8]);
@@ -2103,8 +2224,7 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)
                return IRQ_NONE;
 
        wmb();
-       if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
-               (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
+       if (fusion->adapter_type == INVADER_SERIES)
                writel(((MSIxIndex & 0x7) << 24) |
                        fusion->last_reply_idx[MSIxIndex],
                        instance->reply_post_host_index_addr[MSIxIndex/8]);
@@ -2227,8 +2347,7 @@ build_mpt_mfi_pass_thru(struct megasas_instance *instance,
 
        io_req = cmd->io_request;
 
-       if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
-               (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
+       if (fusion->adapter_type == INVADER_SERIES) {
                struct MPI25_IEEE_SGE_CHAIN64 *sgl_ptr_end =
                        (struct MPI25_IEEE_SGE_CHAIN64 *)&io_req->SGL;
                sgl_ptr_end += fusion->max_sge_in_main_msg - 1;
@@ -2248,7 +2367,7 @@ build_mpt_mfi_pass_thru(struct megasas_instance *instance,
        mpi25_ieee_chain->Flags = IEEE_SGE_FLAGS_CHAIN_ELEMENT |
                MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR;
 
-       mpi25_ieee_chain->Length = cpu_to_le32(MEGASAS_MAX_SZ_CHAIN_FRAME);
+       mpi25_ieee_chain->Length = cpu_to_le32(instance->max_chain_frame_sz);
 
        return 0;
 }
@@ -2384,6 +2503,70 @@ static int
 megasas_adp_reset_fusion(struct megasas_instance *instance,
                         struct megasas_register_set __iomem *regs)
 {
+       u32 host_diag, abs_state, retry;
+
+       /* Now try to reset the chip */
+       writel(MPI2_WRSEQ_FLUSH_KEY_VALUE, &instance->reg_set->fusion_seq_offset);
+       writel(MPI2_WRSEQ_1ST_KEY_VALUE, &instance->reg_set->fusion_seq_offset);
+       writel(MPI2_WRSEQ_2ND_KEY_VALUE, &instance->reg_set->fusion_seq_offset);
+       writel(MPI2_WRSEQ_3RD_KEY_VALUE, &instance->reg_set->fusion_seq_offset);
+       writel(MPI2_WRSEQ_4TH_KEY_VALUE, &instance->reg_set->fusion_seq_offset);
+       writel(MPI2_WRSEQ_5TH_KEY_VALUE, &instance->reg_set->fusion_seq_offset);
+       writel(MPI2_WRSEQ_6TH_KEY_VALUE, &instance->reg_set->fusion_seq_offset);
+
+       /* Check that the diag write enable (DRWE) bit is on */
+       host_diag = readl(&instance->reg_set->fusion_host_diag);
+       retry = 0;
+       while (!(host_diag & HOST_DIAG_WRITE_ENABLE)) {
+               msleep(100);
+               host_diag = readl(&instance->reg_set->fusion_host_diag);
+               if (retry++ == 100) {
+                       dev_warn(&instance->pdev->dev,
+                               "Host diag unlock failed from %s %d\n",
+                               __func__, __LINE__);
+                       break;
+               }
+       }
+       if (!(host_diag & HOST_DIAG_WRITE_ENABLE))
+               return -1;
+
+       /* Send chip reset command */
+       writel(host_diag | HOST_DIAG_RESET_ADAPTER,
+               &instance->reg_set->fusion_host_diag);
+       msleep(3000);
+
+       /* Make sure reset adapter bit is cleared */
+       host_diag = readl(&instance->reg_set->fusion_host_diag);
+       retry = 0;
+       while (host_diag & HOST_DIAG_RESET_ADAPTER) {
+               msleep(100);
+               host_diag = readl(&instance->reg_set->fusion_host_diag);
+               if (retry++ == 1000) {
+                       dev_warn(&instance->pdev->dev,
+                               "Diag reset adapter never cleared %s %d\n",
+                               __func__, __LINE__);
+                       break;
+               }
+       }
+       if (host_diag & HOST_DIAG_RESET_ADAPTER)
+               return -1;
+
+       abs_state = instance->instancet->read_fw_status_reg(instance->reg_set)
+                       & MFI_STATE_MASK;
+       retry = 0;
+
+       while ((abs_state <= MFI_STATE_FW_INIT) && (retry++ < 1000)) {
+               msleep(100);
+               abs_state = instance->instancet->
+                       read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK;
+       }
+       if (abs_state <= MFI_STATE_FW_INIT) {
+               dev_warn(&instance->pdev->dev,
+                       "fw state < MFI_STATE_FW_INIT, state = 0x%x %s %d\n",
+                       abs_state, __func__, __LINE__);
+               return -1;
+       }
+
        return 0;
 }
 
@@ -2512,8 +2695,10 @@ void megasas_refire_mgmt_cmd(struct megasas_instance *instance)
                        continue;
                req_desc = megasas_get_request_descriptor
                                        (instance, smid - 1);
-               if (req_desc && (cmd_mfi->frame->dcmd.opcode !=
-                               cpu_to_le32(MR_DCMD_LD_MAP_GET_INFO)))
+               if (req_desc && ((cmd_mfi->frame->dcmd.opcode !=
+                               cpu_to_le32(MR_DCMD_LD_MAP_GET_INFO)) &&
+                                (cmd_mfi->frame->dcmd.opcode !=
+                               cpu_to_le32(MR_DCMD_SYSTEM_PD_MAP_GET_INFO))))
                        megasas_fire_cmd_fusion(instance, req_desc);
                else
                        megasas_return_cmd(instance, cmd_mfi);
@@ -2547,11 +2732,11 @@ out:
 /* Core fusion reset function */
 int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout)
 {
-       int retval = SUCCESS, i, retry = 0, convert = 0;
+       int retval = SUCCESS, i, convert = 0;
        struct megasas_instance *instance;
        struct megasas_cmd_fusion *cmd_fusion;
        struct fusion_context *fusion;
-       u32 host_diag, abs_state, status_reg, reset_adapter;
+       u32 abs_state, status_reg, reset_adapter;
        u32 io_timeout_in_crash_mode = 0;
        struct scsi_cmnd *scmd_local = NULL;
 
@@ -2705,82 +2890,11 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout)
 
                /* Now try to reset the chip */
                for (i = 0; i < MEGASAS_FUSION_MAX_RESET_TRIES; i++) {
-                       writel(MPI2_WRSEQ_FLUSH_KEY_VALUE,
-                              &instance->reg_set->fusion_seq_offset);
-                       writel(MPI2_WRSEQ_1ST_KEY_VALUE,
-                              &instance->reg_set->fusion_seq_offset);
-                       writel(MPI2_WRSEQ_2ND_KEY_VALUE,
-                              &instance->reg_set->fusion_seq_offset);
-                       writel(MPI2_WRSEQ_3RD_KEY_VALUE,
-                              &instance->reg_set->fusion_seq_offset);
-                       writel(MPI2_WRSEQ_4TH_KEY_VALUE,
-                              &instance->reg_set->fusion_seq_offset);
-                       writel(MPI2_WRSEQ_5TH_KEY_VALUE,
-                              &instance->reg_set->fusion_seq_offset);
-                       writel(MPI2_WRSEQ_6TH_KEY_VALUE,
-                              &instance->reg_set->fusion_seq_offset);
-
-                       /* Check that the diag write enable (DRWE) bit is on */
-                       host_diag = readl(&instance->reg_set->fusion_host_diag);
-                       retry = 0;
-                       while (!(host_diag & HOST_DIAG_WRITE_ENABLE)) {
-                               msleep(100);
-                               host_diag =
-                               readl(&instance->reg_set->fusion_host_diag);
-                               if (retry++ == 100) {
-                                       dev_warn(&instance->pdev->dev,
-                                              "Host diag unlock failed! "
-                                              "for scsi%d\n",
-                                               instance->host->host_no);
-                                       break;
-                               }
-                       }
-                       if (!(host_diag & HOST_DIAG_WRITE_ENABLE))
-                               continue;
 
-                       /* Send chip reset command */
-                       writel(host_diag | HOST_DIAG_RESET_ADAPTER,
-                              &instance->reg_set->fusion_host_diag);
-                       msleep(3000);
-
-                       /* Make sure reset adapter bit is cleared */
-                       host_diag = readl(&instance->reg_set->fusion_host_diag);
-                       retry = 0;
-                       while (host_diag & HOST_DIAG_RESET_ADAPTER) {
-                               msleep(100);
-                               host_diag =
-                               readl(&instance->reg_set->fusion_host_diag);
-                               if (retry++ == 1000) {
-                                       dev_warn(&instance->pdev->dev,
-                                              "Diag reset adapter never "
-                                              "cleared for scsi%d!\n",
-                                               instance->host->host_no);
-                                       break;
-                               }
-                       }
-                       if (host_diag & HOST_DIAG_RESET_ADAPTER)
+                       if (instance->instancet->adp_reset
+                               (instance, instance->reg_set))
                                continue;
 
-                       abs_state =
-                               instance->instancet->read_fw_status_reg(
-                                       instance->reg_set) & MFI_STATE_MASK;
-                       retry = 0;
-
-                       while ((abs_state <= MFI_STATE_FW_INIT) &&
-                              (retry++ < 1000)) {
-                               msleep(100);
-                               abs_state =
-                               instance->instancet->read_fw_status_reg(
-                                       instance->reg_set) & MFI_STATE_MASK;
-                       }
-                       if (abs_state <= MFI_STATE_FW_INIT) {
-                               dev_warn(&instance->pdev->dev, "firmware "
-                                      "state < MFI_STATE_FW_INIT, state = "
-                                      "0x%x for scsi%d\n", abs_state,
-                                       instance->host->host_no);
-                               continue;
-                       }
-
                        /* Wait for FW to become ready */
                        if (megasas_transition_to_ready(instance, 1)) {
                                dev_warn(&instance->pdev->dev, "Failed to "
@@ -2816,6 +2930,8 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout)
                        if (!megasas_get_map_info(instance))
                                megasas_sync_map_info(instance);
 
+                       megasas_setup_jbod_map(instance);
+
                        clear_bit(MEGASAS_FUSION_IN_RESET,
                                  &instance->reset_flags);
                        instance->instancet->enable_intr(instance);
index ced6dc0cf8e8ab7bf6e00ec1710ee24a5e802a4e..473005c99b4406d241cfb92ffbfea0ded5a124df 100644 (file)
 #define _MEGARAID_SAS_FUSION_H_
 
 /* Fusion defines */
-#define MEGASAS_MAX_SZ_CHAIN_FRAME 1024
+#define MEGASAS_CHAIN_FRAME_SZ_MIN 1024
 #define MFI_FUSION_ENABLE_INTERRUPT_MASK (0x00000009)
+#define MEGASAS_MAX_CHAIN_SHIFT                        5
+#define MEGASAS_MAX_CHAIN_SIZE_UNITS_MASK      0x400000
+#define MEGASAS_MAX_CHAIN_SIZE_MASK            0x3E0
+#define MEGASAS_256K_IO                                128
+#define MEGASAS_1MB_IO                         (MEGASAS_256K_IO * 4)
 #define MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE 256
 #define MEGASAS_MPI2_FUNCTION_PASSTHRU_IO_REQUEST   0xF0
 #define MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST         0xF1
@@ -89,6 +94,12 @@ enum MR_RAID_FLAGS_IO_SUB_TYPE {
 #define MEGASAS_FP_CMD_LEN     16
 #define MEGASAS_FUSION_IN_RESET 0
 #define THRESHOLD_REPLY_COUNT 50
+#define JBOD_MAPS_COUNT        2
+
+enum MR_FUSION_ADAPTER_TYPE {
+       THUNDERBOLT_SERIES = 0,
+       INVADER_SERIES = 1,
+};
 
 /*
  * Raid Context structure which describes MegaRAID specific IO Parameters
@@ -117,7 +128,9 @@ struct RAID_CONTEXT {
        u8      numSGE;
        __le16  configSeqNum;
        u8      spanArm;
-       u8      resvd2[3];
+       u8      priority;
+       u8      numSGEExt;
+       u8      resvd2;
 };
 
 #define RAID_CTX_SPANARM_ARM_SHIFT     (0)
@@ -486,6 +499,7 @@ struct MPI2_IOC_INIT_REQUEST {
 #define MAX_PHYSICAL_DEVICES 256
 #define MAX_RAIDMAP_PHYSICAL_DEVICES (MAX_PHYSICAL_DEVICES)
 #define MR_DCMD_LD_MAP_GET_INFO             0x0300e101
+#define MR_DCMD_SYSTEM_PD_MAP_GET_INFO      0x0200e102
 #define MR_DCMD_CTRL_SHARED_HOST_MEM_ALLOC  0x010e8485   /* SR-IOV HB alloc*/
 #define MR_DCMD_LD_VF_MAP_GET_ALL_LDS_111   0x03200200
 #define MR_DCMD_LD_VF_MAP_GET_ALL_LDS       0x03150200
@@ -789,6 +803,21 @@ struct MR_FW_RAID_MAP_EXT {
        struct MR_LD_SPAN_MAP      ldSpanMap[MAX_LOGICAL_DRIVES_EXT];
 };
 
+/*
+ *  * define MR_PD_CFG_SEQ structure for system PDs
+ *   */
+struct MR_PD_CFG_SEQ {
+       __le16 seqNum;
+       __le16 devHandle;
+       u8  reserved[4];
+} __packed;
+
+struct MR_PD_CFG_SEQ_NUM_SYNC {
+       __le32 size;
+       __le32 count;
+       struct MR_PD_CFG_SEQ seq[1];
+} __packed;
+
 struct fusion_context {
        struct megasas_cmd_fusion **cmd_list;
        dma_addr_t req_frames_desc_phys;
@@ -828,9 +857,12 @@ struct fusion_context {
        u32 current_map_sz;
        u32 drv_map_sz;
        u32 drv_map_pages;
+       struct MR_PD_CFG_SEQ_NUM_SYNC   *pd_seq_sync[JBOD_MAPS_COUNT];
+       dma_addr_t pd_seq_phys[JBOD_MAPS_COUNT];
        u8 fast_path_io;
        struct LD_LOAD_BALANCE_INFO load_balance_info[MAX_LOGICAL_DRIVES_EXT];
        LD_SPAN_INFO log_to_span[MAX_LOGICAL_DRIVES_EXT];
+       u8 adapter_type;
 };
 
 union desc_value {
diff --git a/drivers/scsi/mpt2sas/Kconfig b/drivers/scsi/mpt2sas/Kconfig
deleted file mode 100644 (file)
index 657b45c..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-#
-# Kernel configuration file for the MPT2SAS
-#
-# This code is based on drivers/scsi/mpt2sas/Kconfig
-# Copyright (C) 2007-2014  LSI Corporation
-#  (mailto:DL-MPTFusionLinux@lsi.com)
-
-# 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.
-
-# NO WARRANTY
-# THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
-# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
-# LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
-# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
-# solely responsible for determining the appropriateness of using and
-# distributing the Program and assumes all risks associated with its
-# exercise of rights under this Agreement, including but not limited to
-# the risks and costs of program errors, damage to or loss of data,
-# programs or equipment, and unavailability or interruption of operations.
-
-# DISCLAIMER OF LIABILITY
-# NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
-# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
-# HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
-# USA.
-
-config SCSI_MPT2SAS
-       tristate "LSI MPT Fusion SAS 2.0 Device Driver"
-       depends on PCI && SCSI
-       select SCSI_SAS_ATTRS
-       select RAID_ATTRS
-       ---help---
-       This driver supports PCI-Express SAS 6Gb/s Host Adapters.
-
-config SCSI_MPT2SAS_MAX_SGE
-       int "LSI MPT Fusion Max number of SG Entries (16 - 128)"
-       depends on PCI && SCSI && SCSI_MPT2SAS
-       default "128"
-       range 16 128
-       ---help---
-       This option allows you to specify the maximum number of scatter-
-       gather entries per I/O. The driver default is 128, which matches
-       SAFE_PHYS_SEGMENTS.  However, it may decreased down to 16.
-       Decreasing this parameter will reduce memory requirements
-       on a per controller instance.
-
-config SCSI_MPT2SAS_LOGGING
-       bool "LSI MPT Fusion logging facility"
-       depends on PCI && SCSI && SCSI_MPT2SAS
-       ---help---
-       This turns on a logging facility.
diff --git a/drivers/scsi/mpt2sas/Makefile b/drivers/scsi/mpt2sas/Makefile
deleted file mode 100644 (file)
index 728f047..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-# mpt2sas makefile
-obj-$(CONFIG_SCSI_MPT2SAS) += mpt2sas.o
-mpt2sas-y +=  mpt2sas_base.o        \
-               mpt2sas_config.o    \
-               mpt2sas_scsih.o     \
-               mpt2sas_transport.o \
-               mpt2sas_ctl.o
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2.h b/drivers/scsi/mpt2sas/mpi/mpi2.h
deleted file mode 100644 (file)
index 7fc6f23..0000000
+++ /dev/null
@@ -1,1170 +0,0 @@
-/*
- *  Copyright (c) 2000-2014 LSI Corporation.
- *
- *
- *           Name:  mpi2.h
- *          Title:  MPI Message independent structures and definitions
- *                  including System Interface Register Set and
- *                  scatter/gather formats.
- *  Creation Date:  June 21, 2006
- *
- *  mpi2.h Version:  02.00.35
- *
- *  Version History
- *  ---------------
- *
- *  Date      Version   Description
- *  --------  --------  ------------------------------------------------------
- *  04-30-07  02.00.00  Corresponds to Fusion-MPT MPI Specification Rev A.
- *  06-04-07  02.00.01  Bumped MPI2_HEADER_VERSION_UNIT.
- *  06-26-07  02.00.02  Bumped MPI2_HEADER_VERSION_UNIT.
- *  08-31-07  02.00.03  Bumped MPI2_HEADER_VERSION_UNIT.
- *                      Moved ReplyPostHostIndex register to offset 0x6C of the
- *                      MPI2_SYSTEM_INTERFACE_REGS and modified the define for
- *                      MPI2_REPLY_POST_HOST_INDEX_OFFSET.
- *                      Added union of request descriptors.
- *                      Added union of reply descriptors.
- *  10-31-07  02.00.04  Bumped MPI2_HEADER_VERSION_UNIT.
- *                      Added define for MPI2_VERSION_02_00.
- *                      Fixed the size of the FunctionDependent5 field in the
- *                      MPI2_DEFAULT_REPLY structure.
- *  12-18-07  02.00.05  Bumped MPI2_HEADER_VERSION_UNIT.
- *                      Removed the MPI-defined Fault Codes and extended the
- *                      product specific codes up to 0xEFFF.
- *                      Added a sixth key value for the WriteSequence register
- *                      and changed the flush value to 0x0.
- *                      Added message function codes for Diagnostic Buffer Post
- *                      and Diagnsotic Release.
- *                      New IOCStatus define: MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED
- *                      Moved MPI2_VERSION_UNION from mpi2_ioc.h.
- *  02-29-08  02.00.06  Bumped MPI2_HEADER_VERSION_UNIT.
- *  03-03-08  02.00.07  Bumped MPI2_HEADER_VERSION_UNIT.
- *  05-21-08  02.00.08  Bumped MPI2_HEADER_VERSION_UNIT.
- *                      Added #defines for marking a reply descriptor as unused.
- *  06-27-08  02.00.09  Bumped MPI2_HEADER_VERSION_UNIT.
- *  10-02-08  02.00.10  Bumped MPI2_HEADER_VERSION_UNIT.
- *                      Moved LUN field defines from mpi2_init.h.
- *  01-19-09  02.00.11  Bumped MPI2_HEADER_VERSION_UNIT.
- *  05-06-09  02.00.12  Bumped MPI2_HEADER_VERSION_UNIT.
- *                      In all request and reply descriptors, replaced VF_ID
- *                      field with MSIxIndex field.
- *                      Removed DevHandle field from
- *                      MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR and made those
- *                      bytes reserved.
- *                      Added RAID Accelerator functionality.
- *  07-30-09  02.00.13  Bumped MPI2_HEADER_VERSION_UNIT.
- *  10-28-09  02.00.14  Bumped MPI2_HEADER_VERSION_UNIT.
- *                      Added MSI-x index mask and shift for Reply Post Host
- *                      Index register.
- *                      Added function code for Host Based Discovery Action.
- *  02-10-10  02.00.15  Bumped MPI2_HEADER_VERSION_UNIT.
- *                      Added define for MPI2_FUNCTION_PWR_MGMT_CONTROL.
- *                      Added defines for product-specific range of message
- *                      function codes, 0xF0 to 0xFF.
- *  05-12-10  02.00.16  Bumped MPI2_HEADER_VERSION_UNIT.
- *                      Added alternative defines for the SGE Direction bit.
- *  08-11-10  02.00.17  Bumped MPI2_HEADER_VERSION_UNIT.
- *  11-10-10  02.00.18  Bumped MPI2_HEADER_VERSION_UNIT.
- *                      Added MPI2_IEEE_SGE_FLAGS_SYSTEMPLBCPI_ADDR define.
- *  02-23-11  02.00.19  Bumped MPI2_HEADER_VERSION_UNIT.
- *                      Added MPI2_FUNCTION_SEND_HOST_MESSAGE.
- *  03-09-11  02.00.20  Bumped MPI2_HEADER_VERSION_UNIT.
- *  05-25-11  02.00.21  Bumped MPI2_HEADER_VERSION_UNIT.
- *  08-24-11  02.00.22  Bumped MPI2_HEADER_VERSION_UNIT.
- *  11-18-11  02.00.23  Bumped MPI2_HEADER_VERSION_UNIT.
- *  02-06-12  02.00.24  Bumped MPI2_HEADER_VERSION_UNIT.
- *  03-29-12  02.00.25  Bumped MPI2_HEADER_VERSION_UNIT.
- *                      Added Hard Reset delay timings.
- *  07-10-12  02.00.26  Bumped MPI2_HEADER_VERSION_UNIT.
- *  07-26-12  02.00.27  Bumped MPI2_HEADER_VERSION_UNIT.
- *  11-27-12  02.00.28  Bumped MPI2_HEADER_VERSION_UNIT.
- *  12-20-12  02.00.29  Bumped MPI2_HEADER_VERSION_UNIT.
- *                     Added MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET.
- *  04-09-13  02.00.30  Bumped MPI2_HEADER_VERSION_UNIT.
- *  04-17-13  02.00.31  Bumped MPI2_HEADER_VERSION_UNIT.
- *  08-19-13  02.00.32  Bumped MPI2_HEADER_VERSION_UNIT.
- *  12-05-13  02.00.33  Bumped MPI2_HEADER_VERSION_UNIT.
- *  01-08-14  02.00.34  Bumped MPI2_HEADER_VERSION_UNIT.
- *  06-13-14  02.00.35  Bumped MPI2_HEADER_VERSION_UNIT.
- *  --------------------------------------------------------------------------
- */
-
-#ifndef MPI2_H
-#define MPI2_H
-
-
-/*****************************************************************************
-*
-*        MPI Version Definitions
-*
-*****************************************************************************/
-
-#define MPI2_VERSION_MAJOR                  (0x02)
-#define MPI2_VERSION_MINOR                  (0x00)
-#define MPI2_VERSION_MAJOR_MASK             (0xFF00)
-#define MPI2_VERSION_MAJOR_SHIFT            (8)
-#define MPI2_VERSION_MINOR_MASK             (0x00FF)
-#define MPI2_VERSION_MINOR_SHIFT            (0)
-#define MPI2_VERSION ((MPI2_VERSION_MAJOR << MPI2_VERSION_MAJOR_SHIFT) |   \
-                                      MPI2_VERSION_MINOR)
-
-#define MPI2_VERSION_02_00                  (0x0200)
-
-/* versioning for this MPI header set */
-#define MPI2_HEADER_VERSION_UNIT            (0x23)
-#define MPI2_HEADER_VERSION_DEV             (0x00)
-#define MPI2_HEADER_VERSION_UNIT_MASK       (0xFF00)
-#define MPI2_HEADER_VERSION_UNIT_SHIFT      (8)
-#define MPI2_HEADER_VERSION_DEV_MASK        (0x00FF)
-#define MPI2_HEADER_VERSION_DEV_SHIFT       (0)
-#define MPI2_HEADER_VERSION ((MPI2_HEADER_VERSION_UNIT << 8) | MPI2_HEADER_VERSION_DEV)
-
-
-/*****************************************************************************
-*
-*        IOC State Definitions
-*
-*****************************************************************************/
-
-#define MPI2_IOC_STATE_RESET               (0x00000000)
-#define MPI2_IOC_STATE_READY               (0x10000000)
-#define MPI2_IOC_STATE_OPERATIONAL         (0x20000000)
-#define MPI2_IOC_STATE_FAULT               (0x40000000)
-
-#define MPI2_IOC_STATE_MASK                (0xF0000000)
-#define MPI2_IOC_STATE_SHIFT               (28)
-
-/* Fault state range for prodcut specific codes */
-#define MPI2_FAULT_PRODUCT_SPECIFIC_MIN                 (0x0000)
-#define MPI2_FAULT_PRODUCT_SPECIFIC_MAX                 (0xEFFF)
-
-
-/*****************************************************************************
-*
-*        System Interface Register Definitions
-*
-*****************************************************************************/
-
-typedef volatile struct _MPI2_SYSTEM_INTERFACE_REGS
-{
-    U32         Doorbell;                   /* 0x00 */
-    U32         WriteSequence;              /* 0x04 */
-    U32         HostDiagnostic;             /* 0x08 */
-    U32         Reserved1;                  /* 0x0C */
-    U32         DiagRWData;                 /* 0x10 */
-    U32         DiagRWAddressLow;           /* 0x14 */
-    U32         DiagRWAddressHigh;          /* 0x18 */
-    U32         Reserved2[5];               /* 0x1C */
-    U32         HostInterruptStatus;        /* 0x30 */
-    U32         HostInterruptMask;          /* 0x34 */
-    U32         DCRData;                    /* 0x38 */
-    U32         DCRAddress;                 /* 0x3C */
-    U32         Reserved3[2];               /* 0x40 */
-    U32         ReplyFreeHostIndex;         /* 0x48 */
-    U32         Reserved4[8];               /* 0x4C */
-    U32         ReplyPostHostIndex;         /* 0x6C */
-    U32         Reserved5;                  /* 0x70 */
-    U32         HCBSize;                    /* 0x74 */
-    U32         HCBAddressLow;              /* 0x78 */
-    U32         HCBAddressHigh;             /* 0x7C */
-    U32         Reserved6[16];              /* 0x80 */
-    U32         RequestDescriptorPostLow;   /* 0xC0 */
-    U32         RequestDescriptorPostHigh;  /* 0xC4 */
-    U32         Reserved7[14];              /* 0xC8 */
-} MPI2_SYSTEM_INTERFACE_REGS, MPI2_POINTER PTR_MPI2_SYSTEM_INTERFACE_REGS,
-  Mpi2SystemInterfaceRegs_t, MPI2_POINTER pMpi2SystemInterfaceRegs_t;
-
-/*
- * Defines for working with the Doorbell register.
- */
-#define MPI2_DOORBELL_OFFSET                    (0x00000000)
-
-/* IOC --> System values */
-#define MPI2_DOORBELL_USED                      (0x08000000)
-#define MPI2_DOORBELL_WHO_INIT_MASK             (0x07000000)
-#define MPI2_DOORBELL_WHO_INIT_SHIFT            (24)
-#define MPI2_DOORBELL_FAULT_CODE_MASK           (0x0000FFFF)
-#define MPI2_DOORBELL_DATA_MASK                 (0x0000FFFF)
-
-/* System --> IOC values */
-#define MPI2_DOORBELL_FUNCTION_MASK             (0xFF000000)
-#define MPI2_DOORBELL_FUNCTION_SHIFT            (24)
-#define MPI2_DOORBELL_ADD_DWORDS_MASK           (0x00FF0000)
-#define MPI2_DOORBELL_ADD_DWORDS_SHIFT          (16)
-
-
-/*
- * Defines for the WriteSequence register
- */
-#define MPI2_WRITE_SEQUENCE_OFFSET              (0x00000004)
-#define MPI2_WRSEQ_KEY_VALUE_MASK               (0x0000000F)
-#define MPI2_WRSEQ_FLUSH_KEY_VALUE              (0x0)
-#define MPI2_WRSEQ_1ST_KEY_VALUE                (0xF)
-#define MPI2_WRSEQ_2ND_KEY_VALUE                (0x4)
-#define MPI2_WRSEQ_3RD_KEY_VALUE                (0xB)
-#define MPI2_WRSEQ_4TH_KEY_VALUE                (0x2)
-#define MPI2_WRSEQ_5TH_KEY_VALUE                (0x7)
-#define MPI2_WRSEQ_6TH_KEY_VALUE                (0xD)
-
-/*
- * Defines for the HostDiagnostic register
- */
-#define MPI2_HOST_DIAGNOSTIC_OFFSET             (0x00000008)
-
-#define MPI2_DIAG_BOOT_DEVICE_SELECT_MASK       (0x00001800)
-#define MPI2_DIAG_BOOT_DEVICE_SELECT_DEFAULT    (0x00000000)
-#define MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW       (0x00000800)
-
-#define MPI2_DIAG_CLEAR_FLASH_BAD_SIG           (0x00000400)
-#define MPI2_DIAG_FORCE_HCB_ON_RESET            (0x00000200)
-#define MPI2_DIAG_HCB_MODE                      (0x00000100)
-#define MPI2_DIAG_DIAG_WRITE_ENABLE             (0x00000080)
-#define MPI2_DIAG_FLASH_BAD_SIG                 (0x00000040)
-#define MPI2_DIAG_RESET_HISTORY                 (0x00000020)
-#define MPI2_DIAG_DIAG_RW_ENABLE                (0x00000010)
-#define MPI2_DIAG_RESET_ADAPTER                 (0x00000004)
-#define MPI2_DIAG_HOLD_IOC_RESET                (0x00000002)
-
-/*
- * Offsets for DiagRWData and address
- */
-#define MPI2_DIAG_RW_DATA_OFFSET                (0x00000010)
-#define MPI2_DIAG_RW_ADDRESS_LOW_OFFSET         (0x00000014)
-#define MPI2_DIAG_RW_ADDRESS_HIGH_OFFSET        (0x00000018)
-
-/*
- * Defines for the HostInterruptStatus register
- */
-#define MPI2_HOST_INTERRUPT_STATUS_OFFSET       (0x00000030)
-#define MPI2_HIS_SYS2IOC_DB_STATUS              (0x80000000)
-#define MPI2_HIS_IOP_DOORBELL_STATUS            MPI2_HIS_SYS2IOC_DB_STATUS
-#define MPI2_HIS_RESET_IRQ_STATUS               (0x40000000)
-#define MPI2_HIS_REPLY_DESCRIPTOR_INTERRUPT     (0x00000008)
-#define MPI2_HIS_IOC2SYS_DB_STATUS              (0x00000001)
-#define MPI2_HIS_DOORBELL_INTERRUPT             MPI2_HIS_IOC2SYS_DB_STATUS
-
-/*
- * Defines for the HostInterruptMask register
- */
-#define MPI2_HOST_INTERRUPT_MASK_OFFSET         (0x00000034)
-#define MPI2_HIM_RESET_IRQ_MASK                 (0x40000000)
-#define MPI2_HIM_REPLY_INT_MASK                 (0x00000008)
-#define MPI2_HIM_RIM                            MPI2_HIM_REPLY_INT_MASK
-#define MPI2_HIM_IOC2SYS_DB_MASK                (0x00000001)
-#define MPI2_HIM_DIM                            MPI2_HIM_IOC2SYS_DB_MASK
-
-/*
- * Offsets for DCRData and address
- */
-#define MPI2_DCR_DATA_OFFSET                    (0x00000038)
-#define MPI2_DCR_ADDRESS_OFFSET                 (0x0000003C)
-
-/*
- * Offset for the Reply Free Queue
- */
-#define MPI2_REPLY_FREE_HOST_INDEX_OFFSET       (0x00000048)
-
-/*
- * Defines for the Reply Descriptor Post Queue
- */
-#define MPI2_REPLY_POST_HOST_INDEX_OFFSET       (0x0000006C)
-#define MPI2_REPLY_POST_HOST_INDEX_MASK         (0x00FFFFFF)
-#define MPI2_RPHI_MSIX_INDEX_MASK               (0xFF000000)
-#define MPI2_RPHI_MSIX_INDEX_SHIFT              (24)
-#define MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET  (0x0000030C) /* MPI v2.5 only */
-
-/*
- * Defines for the HCBSize and address
- */
-#define MPI2_HCB_SIZE_OFFSET                    (0x00000074)
-#define MPI2_HCB_SIZE_SIZE_MASK                 (0xFFFFF000)
-#define MPI2_HCB_SIZE_HCB_ENABLE                (0x00000001)
-
-#define MPI2_HCB_ADDRESS_LOW_OFFSET             (0x00000078)
-#define MPI2_HCB_ADDRESS_HIGH_OFFSET            (0x0000007C)
-
-/*
- * Offsets for the Request Queue
- */
-#define MPI2_REQUEST_DESCRIPTOR_POST_LOW_OFFSET     (0x000000C0)
-#define MPI2_REQUEST_DESCRIPTOR_POST_HIGH_OFFSET    (0x000000C4)
-
-
-/* Hard Reset delay timings */
-#define MPI2_HARD_RESET_PCIE_FIRST_READ_DELAY_MICRO_SEC     (50000)
-#define MPI2_HARD_RESET_PCIE_RESET_READ_WINDOW_MICRO_SEC    (255000)
-#define MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC    (256000)
-
-/*****************************************************************************
-*
-*        Message Descriptors
-*
-*****************************************************************************/
-
-/* Request Descriptors */
-
-/* Default Request Descriptor */
-typedef struct _MPI2_DEFAULT_REQUEST_DESCRIPTOR
-{
-    U8              RequestFlags;               /* 0x00 */
-    U8              MSIxIndex;                  /* 0x01 */
-    U16             SMID;                       /* 0x02 */
-    U16             LMID;                       /* 0x04 */
-    U16             DescriptorTypeDependent;    /* 0x06 */
-} MPI2_DEFAULT_REQUEST_DESCRIPTOR,
-  MPI2_POINTER PTR_MPI2_DEFAULT_REQUEST_DESCRIPTOR,
-  Mpi2DefaultRequestDescriptor_t, MPI2_POINTER pMpi2DefaultRequestDescriptor_t;
-
-/* defines for the RequestFlags field */
-#define MPI2_REQ_DESCRIPT_FLAGS_TYPE_MASK               (0x0E)
-#define MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO                 (0x00)
-#define MPI2_REQ_DESCRIPT_FLAGS_SCSI_TARGET             (0x02)
-#define MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY           (0x06)
-#define MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE            (0x08)
-#define MPI2_REQ_DESCRIPT_FLAGS_RAID_ACCELERATOR        (0x0A)
-
-#define MPI2_REQ_DESCRIPT_FLAGS_IOC_FIFO_MARKER (0x01)
-
-
-/* High Priority Request Descriptor */
-typedef struct _MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR
-{
-    U8              RequestFlags;               /* 0x00 */
-    U8              MSIxIndex;                  /* 0x01 */
-    U16             SMID;                       /* 0x02 */
-    U16             LMID;                       /* 0x04 */
-    U16             Reserved1;                  /* 0x06 */
-} MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR,
-  MPI2_POINTER PTR_MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR,
-  Mpi2HighPriorityRequestDescriptor_t,
-  MPI2_POINTER pMpi2HighPriorityRequestDescriptor_t;
-
-
-/* SCSI IO Request Descriptor */
-typedef struct _MPI2_SCSI_IO_REQUEST_DESCRIPTOR
-{
-    U8              RequestFlags;               /* 0x00 */
-    U8              MSIxIndex;                  /* 0x01 */
-    U16             SMID;                       /* 0x02 */
-    U16             LMID;                       /* 0x04 */
-    U16             DevHandle;                  /* 0x06 */
-} MPI2_SCSI_IO_REQUEST_DESCRIPTOR,
-  MPI2_POINTER PTR_MPI2_SCSI_IO_REQUEST_DESCRIPTOR,
-  Mpi2SCSIIORequestDescriptor_t, MPI2_POINTER pMpi2SCSIIORequestDescriptor_t;
-
-
-/* SCSI Target Request Descriptor */
-typedef struct _MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR
-{
-    U8              RequestFlags;               /* 0x00 */
-    U8              MSIxIndex;                  /* 0x01 */
-    U16             SMID;                       /* 0x02 */
-    U16             LMID;                       /* 0x04 */
-    U16             IoIndex;                    /* 0x06 */
-} MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR,
-  MPI2_POINTER PTR_MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR,
-  Mpi2SCSITargetRequestDescriptor_t,
-  MPI2_POINTER pMpi2SCSITargetRequestDescriptor_t;
-
-
-/* RAID Accelerator Request Descriptor */
-typedef struct _MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR {
-    U8              RequestFlags;               /* 0x00 */
-    U8              MSIxIndex;                  /* 0x01 */
-    U16             SMID;                       /* 0x02 */
-    U16             LMID;                       /* 0x04 */
-    U16             Reserved;                   /* 0x06 */
-} MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR,
-  MPI2_POINTER PTR_MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR,
-  Mpi2RAIDAcceleratorRequestDescriptor_t,
-  MPI2_POINTER pMpi2RAIDAcceleratorRequestDescriptor_t;
-
-
-/* union of Request Descriptors */
-typedef union _MPI2_REQUEST_DESCRIPTOR_UNION
-{
-    MPI2_DEFAULT_REQUEST_DESCRIPTOR             Default;
-    MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR       HighPriority;
-    MPI2_SCSI_IO_REQUEST_DESCRIPTOR             SCSIIO;
-    MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR         SCSITarget;
-    MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR          RAIDAccelerator;
-    U64                                         Words;
-} MPI2_REQUEST_DESCRIPTOR_UNION, MPI2_POINTER PTR_MPI2_REQUEST_DESCRIPTOR_UNION,
-  Mpi2RequestDescriptorUnion_t, MPI2_POINTER pMpi2RequestDescriptorUnion_t;
-
-
-/* Reply Descriptors */
-
-/* Default Reply Descriptor */
-typedef struct _MPI2_DEFAULT_REPLY_DESCRIPTOR
-{
-    U8              ReplyFlags;                 /* 0x00 */
-    U8              MSIxIndex;                  /* 0x01 */
-    U16             DescriptorTypeDependent1;   /* 0x02 */
-    U32             DescriptorTypeDependent2;   /* 0x04 */
-} MPI2_DEFAULT_REPLY_DESCRIPTOR, MPI2_POINTER PTR_MPI2_DEFAULT_REPLY_DESCRIPTOR,
-  Mpi2DefaultReplyDescriptor_t, MPI2_POINTER pMpi2DefaultReplyDescriptor_t;
-
-/* defines for the ReplyFlags field */
-#define MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK                   (0x0F)
-#define MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS             (0x00)
-#define MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY               (0x01)
-#define MPI2_RPY_DESCRIPT_FLAGS_TARGETASSIST_SUCCESS        (0x02)
-#define MPI2_RPY_DESCRIPT_FLAGS_TARGET_COMMAND_BUFFER       (0x03)
-#define MPI2_RPY_DESCRIPT_FLAGS_RAID_ACCELERATOR_SUCCESS    (0x05)
-#define MPI2_RPY_DESCRIPT_FLAGS_UNUSED                      (0x0F)
-
-/* values for marking a reply descriptor as unused */
-#define MPI2_RPY_DESCRIPT_UNUSED_WORD0_MARK             (0xFFFFFFFF)
-#define MPI2_RPY_DESCRIPT_UNUSED_WORD1_MARK             (0xFFFFFFFF)
-
-/* Address Reply Descriptor */
-typedef struct _MPI2_ADDRESS_REPLY_DESCRIPTOR
-{
-    U8              ReplyFlags;                 /* 0x00 */
-    U8              MSIxIndex;                  /* 0x01 */
-    U16             SMID;                       /* 0x02 */
-    U32             ReplyFrameAddress;          /* 0x04 */
-} MPI2_ADDRESS_REPLY_DESCRIPTOR, MPI2_POINTER PTR_MPI2_ADDRESS_REPLY_DESCRIPTOR,
-  Mpi2AddressReplyDescriptor_t, MPI2_POINTER pMpi2AddressReplyDescriptor_t;
-
-#define MPI2_ADDRESS_REPLY_SMID_INVALID                 (0x00)
-
-
-/* SCSI IO Success Reply Descriptor */
-typedef struct _MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR
-{
-    U8              ReplyFlags;                 /* 0x00 */
-    U8              MSIxIndex;                  /* 0x01 */
-    U16             SMID;                       /* 0x02 */
-    U16             TaskTag;                    /* 0x04 */
-    U16             Reserved1;                  /* 0x06 */
-} MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR,
-  MPI2_POINTER PTR_MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR,
-  Mpi2SCSIIOSuccessReplyDescriptor_t,
-  MPI2_POINTER pMpi2SCSIIOSuccessReplyDescriptor_t;
-
-
-/* TargetAssist Success Reply Descriptor */
-typedef struct _MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR
-{
-    U8              ReplyFlags;                 /* 0x00 */
-    U8              MSIxIndex;                  /* 0x01 */
-    U16             SMID;                       /* 0x02 */
-    U8              SequenceNumber;             /* 0x04 */
-    U8              Reserved1;                  /* 0x05 */
-    U16             IoIndex;                    /* 0x06 */
-} MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR,
-  MPI2_POINTER PTR_MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR,
-  Mpi2TargetAssistSuccessReplyDescriptor_t,
-  MPI2_POINTER pMpi2TargetAssistSuccessReplyDescriptor_t;
-
-
-/* Target Command Buffer Reply Descriptor */
-typedef struct _MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR
-{
-    U8              ReplyFlags;                 /* 0x00 */
-    U8              MSIxIndex;                  /* 0x01 */
-    U8              VP_ID;                      /* 0x02 */
-    U8              Flags;                      /* 0x03 */
-    U16             InitiatorDevHandle;         /* 0x04 */
-    U16             IoIndex;                    /* 0x06 */
-} MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR,
-  MPI2_POINTER PTR_MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR,
-  Mpi2TargetCommandBufferReplyDescriptor_t,
-  MPI2_POINTER pMpi2TargetCommandBufferReplyDescriptor_t;
-
-/* defines for Flags field */
-#define MPI2_RPY_DESCRIPT_TCB_FLAGS_PHYNUM_MASK     (0x3F)
-
-
-/* RAID Accelerator Success Reply Descriptor */
-typedef struct _MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR {
-    U8              ReplyFlags;                 /* 0x00 */
-    U8              MSIxIndex;                  /* 0x01 */
-    U16             SMID;                       /* 0x02 */
-    U32             Reserved;                   /* 0x04 */
-} MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR,
-  MPI2_POINTER PTR_MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR,
-  Mpi2RAIDAcceleratorSuccessReplyDescriptor_t,
-  MPI2_POINTER pMpi2RAIDAcceleratorSuccessReplyDescriptor_t;
-
-
-/* union of Reply Descriptors */
-typedef union _MPI2_REPLY_DESCRIPTORS_UNION
-{
-    MPI2_DEFAULT_REPLY_DESCRIPTOR                   Default;
-    MPI2_ADDRESS_REPLY_DESCRIPTOR                   AddressReply;
-    MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR           SCSIIOSuccess;
-    MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR      TargetAssistSuccess;
-    MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR     TargetCommandBuffer;
-    MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR  RAIDAcceleratorSuccess;
-    U64                                             Words;
-} MPI2_REPLY_DESCRIPTORS_UNION, MPI2_POINTER PTR_MPI2_REPLY_DESCRIPTORS_UNION,
-Mpi2ReplyDescriptorsUnion_t, MPI2_POINTER pMpi2ReplyDescriptorsUnion_t;
-
-
-
-/*****************************************************************************
-*
-*        Message Functions
-*
-*****************************************************************************/
-
-#define MPI2_FUNCTION_SCSI_IO_REQUEST               (0x00) /* SCSI IO */
-#define MPI2_FUNCTION_SCSI_TASK_MGMT                (0x01) /* SCSI Task Management */
-#define MPI2_FUNCTION_IOC_INIT                      (0x02) /* IOC Init */
-#define MPI2_FUNCTION_IOC_FACTS                     (0x03) /* IOC Facts */
-#define MPI2_FUNCTION_CONFIG                        (0x04) /* Configuration */
-#define MPI2_FUNCTION_PORT_FACTS                    (0x05) /* Port Facts */
-#define MPI2_FUNCTION_PORT_ENABLE                   (0x06) /* Port Enable */
-#define MPI2_FUNCTION_EVENT_NOTIFICATION            (0x07) /* Event Notification */
-#define MPI2_FUNCTION_EVENT_ACK                     (0x08) /* Event Acknowledge */
-#define MPI2_FUNCTION_FW_DOWNLOAD                   (0x09) /* FW Download */
-#define MPI2_FUNCTION_TARGET_ASSIST                 (0x0B) /* Target Assist */
-#define MPI2_FUNCTION_TARGET_STATUS_SEND            (0x0C) /* Target Status Send */
-#define MPI2_FUNCTION_TARGET_MODE_ABORT             (0x0D) /* Target Mode Abort */
-#define MPI2_FUNCTION_FW_UPLOAD                     (0x12) /* FW Upload */
-#define MPI2_FUNCTION_RAID_ACTION                   (0x15) /* RAID Action */
-#define MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH      (0x16) /* SCSI IO RAID Passthrough */
-#define MPI2_FUNCTION_TOOLBOX                       (0x17) /* Toolbox */
-#define MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR      (0x18) /* SCSI Enclosure Processor */
-#define MPI2_FUNCTION_SMP_PASSTHROUGH               (0x1A) /* SMP Passthrough */
-#define MPI2_FUNCTION_SAS_IO_UNIT_CONTROL           (0x1B) /* SAS IO Unit Control */
-#define MPI2_FUNCTION_SATA_PASSTHROUGH              (0x1C) /* SATA Passthrough */
-#define MPI2_FUNCTION_DIAG_BUFFER_POST              (0x1D) /* Diagnostic Buffer Post */
-#define MPI2_FUNCTION_DIAG_RELEASE                  (0x1E) /* Diagnostic Release */
-#define MPI2_FUNCTION_TARGET_CMD_BUF_BASE_POST      (0x24) /* Target Command Buffer Post Base */
-#define MPI2_FUNCTION_TARGET_CMD_BUF_LIST_POST      (0x25) /* Target Command Buffer Post List */
-#define MPI2_FUNCTION_RAID_ACCELERATOR              (0x2C) /* RAID Accelerator*/
-/* Host Based Discovery Action */
-#define MPI2_FUNCTION_HOST_BASED_DISCOVERY_ACTION   (0x2F)
-/* Power Management Control */
-#define MPI2_FUNCTION_PWR_MGMT_CONTROL              (0x30)
-/* Send Host Message */
-#define MPI2_FUNCTION_SEND_HOST_MESSAGE             (0x31)
-/* beginning of product-specific range */
-#define MPI2_FUNCTION_MIN_PRODUCT_SPECIFIC          (0xF0)
-/* end of product-specific range */
-#define MPI2_FUNCTION_MAX_PRODUCT_SPECIFIC          (0xFF)
-
-
-
-
-/* Doorbell functions */
-#define MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET        (0x40)
-#define MPI2_FUNCTION_HANDSHAKE                     (0x42)
-
-
-/*****************************************************************************
-*
-*        IOC Status Values
-*
-*****************************************************************************/
-
-/* mask for IOCStatus status value */
-#define MPI2_IOCSTATUS_MASK                     (0x7FFF)
-
-/****************************************************************************
-*  Common IOCStatus values for all replies
-****************************************************************************/
-
-#define MPI2_IOCSTATUS_SUCCESS                      (0x0000)
-#define MPI2_IOCSTATUS_INVALID_FUNCTION             (0x0001)
-#define MPI2_IOCSTATUS_BUSY                         (0x0002)
-#define MPI2_IOCSTATUS_INVALID_SGL                  (0x0003)
-#define MPI2_IOCSTATUS_INTERNAL_ERROR               (0x0004)
-#define MPI2_IOCSTATUS_INVALID_VPID                 (0x0005)
-#define MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES       (0x0006)
-#define MPI2_IOCSTATUS_INVALID_FIELD                (0x0007)
-#define MPI2_IOCSTATUS_INVALID_STATE                (0x0008)
-#define MPI2_IOCSTATUS_OP_STATE_NOT_SUPPORTED       (0x0009)
-
-/****************************************************************************
-*  Config IOCStatus values
-****************************************************************************/
-
-#define MPI2_IOCSTATUS_CONFIG_INVALID_ACTION        (0x0020)
-#define MPI2_IOCSTATUS_CONFIG_INVALID_TYPE          (0x0021)
-#define MPI2_IOCSTATUS_CONFIG_INVALID_PAGE          (0x0022)
-#define MPI2_IOCSTATUS_CONFIG_INVALID_DATA          (0x0023)
-#define MPI2_IOCSTATUS_CONFIG_NO_DEFAULTS           (0x0024)
-#define MPI2_IOCSTATUS_CONFIG_CANT_COMMIT           (0x0025)
-
-/****************************************************************************
-*  SCSI IO Reply
-****************************************************************************/
-
-#define MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR         (0x0040)
-#define MPI2_IOCSTATUS_SCSI_INVALID_DEVHANDLE       (0x0042)
-#define MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE        (0x0043)
-#define MPI2_IOCSTATUS_SCSI_DATA_OVERRUN            (0x0044)
-#define MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN           (0x0045)
-#define MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR           (0x0046)
-#define MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR          (0x0047)
-#define MPI2_IOCSTATUS_SCSI_TASK_TERMINATED         (0x0048)
-#define MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH       (0x0049)
-#define MPI2_IOCSTATUS_SCSI_TASK_MGMT_FAILED        (0x004A)
-#define MPI2_IOCSTATUS_SCSI_IOC_TERMINATED          (0x004B)
-#define MPI2_IOCSTATUS_SCSI_EXT_TERMINATED          (0x004C)
-
-/****************************************************************************
-*  For use by SCSI Initiator and SCSI Target end-to-end data protection
-****************************************************************************/
-
-#define MPI2_IOCSTATUS_EEDP_GUARD_ERROR             (0x004D)
-#define MPI2_IOCSTATUS_EEDP_REF_TAG_ERROR           (0x004E)
-#define MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR           (0x004F)
-
-/****************************************************************************
-*  SCSI Target values
-****************************************************************************/
-
-#define MPI2_IOCSTATUS_TARGET_INVALID_IO_INDEX      (0x0062)
-#define MPI2_IOCSTATUS_TARGET_ABORTED               (0x0063)
-#define MPI2_IOCSTATUS_TARGET_NO_CONN_RETRYABLE     (0x0064)
-#define MPI2_IOCSTATUS_TARGET_NO_CONNECTION         (0x0065)
-#define MPI2_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH   (0x006A)
-#define MPI2_IOCSTATUS_TARGET_DATA_OFFSET_ERROR     (0x006D)
-#define MPI2_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA   (0x006E)
-#define MPI2_IOCSTATUS_TARGET_IU_TOO_SHORT          (0x006F)
-#define MPI2_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT       (0x0070)
-#define MPI2_IOCSTATUS_TARGET_NAK_RECEIVED          (0x0071)
-
-/****************************************************************************
-*  Serial Attached SCSI values
-****************************************************************************/
-
-#define MPI2_IOCSTATUS_SAS_SMP_REQUEST_FAILED       (0x0090)
-#define MPI2_IOCSTATUS_SAS_SMP_DATA_OVERRUN         (0x0091)
-
-/****************************************************************************
-*  Diagnostic Buffer Post / Diagnostic Release values
-****************************************************************************/
-
-#define MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED          (0x00A0)
-
-/****************************************************************************
-*  RAID Accelerator values
-****************************************************************************/
-
-#define MPI2_IOCSTATUS_RAID_ACCEL_ERROR             (0x00B0)
-
-/****************************************************************************
-*  IOCStatus flag to indicate that log info is available
-****************************************************************************/
-
-#define MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE      (0x8000)
-
-/****************************************************************************
-*  IOCLogInfo Types
-****************************************************************************/
-
-#define MPI2_IOCLOGINFO_TYPE_MASK               (0xF0000000)
-#define MPI2_IOCLOGINFO_TYPE_SHIFT              (28)
-#define MPI2_IOCLOGINFO_TYPE_NONE               (0x0)
-#define MPI2_IOCLOGINFO_TYPE_SCSI               (0x1)
-#define MPI2_IOCLOGINFO_TYPE_FC                 (0x2)
-#define MPI2_IOCLOGINFO_TYPE_SAS                (0x3)
-#define MPI2_IOCLOGINFO_TYPE_ISCSI              (0x4)
-#define MPI2_IOCLOGINFO_LOG_DATA_MASK           (0x0FFFFFFF)
-
-
-/*****************************************************************************
-*
-*        Standard Message Structures
-*
-*****************************************************************************/
-
-/****************************************************************************
-* Request Message Header for all request messages
-****************************************************************************/
-
-typedef struct _MPI2_REQUEST_HEADER
-{
-    U16             FunctionDependent1;         /* 0x00 */
-    U8              ChainOffset;                /* 0x02 */
-    U8              Function;                   /* 0x03 */
-    U16             FunctionDependent2;         /* 0x04 */
-    U8              FunctionDependent3;         /* 0x06 */
-    U8              MsgFlags;                   /* 0x07 */
-    U8              VP_ID;                      /* 0x08 */
-    U8              VF_ID;                      /* 0x09 */
-    U16             Reserved1;                  /* 0x0A */
-} MPI2_REQUEST_HEADER, MPI2_POINTER PTR_MPI2_REQUEST_HEADER,
-  MPI2RequestHeader_t, MPI2_POINTER pMPI2RequestHeader_t;
-
-
-/****************************************************************************
-*  Default Reply
-****************************************************************************/
-
-typedef struct _MPI2_DEFAULT_REPLY
-{
-    U16             FunctionDependent1;         /* 0x00 */
-    U8              MsgLength;                  /* 0x02 */
-    U8              Function;                   /* 0x03 */
-    U16             FunctionDependent2;         /* 0x04 */
-    U8              FunctionDependent3;         /* 0x06 */
-    U8              MsgFlags;                   /* 0x07 */
-    U8              VP_ID;                      /* 0x08 */
-    U8              VF_ID;                      /* 0x09 */
-    U16             Reserved1;                  /* 0x0A */
-    U16             FunctionDependent5;         /* 0x0C */
-    U16             IOCStatus;                  /* 0x0E */
-    U32             IOCLogInfo;                 /* 0x10 */
-} MPI2_DEFAULT_REPLY, MPI2_POINTER PTR_MPI2_DEFAULT_REPLY,
-  MPI2DefaultReply_t, MPI2_POINTER pMPI2DefaultReply_t;
-
-
-/* common version structure/union used in messages and configuration pages */
-
-typedef struct _MPI2_VERSION_STRUCT
-{
-    U8                      Dev;                        /* 0x00 */
-    U8                      Unit;                       /* 0x01 */
-    U8                      Minor;                      /* 0x02 */
-    U8                      Major;                      /* 0x03 */
-} MPI2_VERSION_STRUCT;
-
-typedef union _MPI2_VERSION_UNION
-{
-    MPI2_VERSION_STRUCT     Struct;
-    U32                     Word;
-} MPI2_VERSION_UNION;
-
-
-/* LUN field defines, common to many structures */
-#define MPI2_LUN_FIRST_LEVEL_ADDRESSING             (0x0000FFFF)
-#define MPI2_LUN_SECOND_LEVEL_ADDRESSING            (0xFFFF0000)
-#define MPI2_LUN_THIRD_LEVEL_ADDRESSING             (0x0000FFFF)
-#define MPI2_LUN_FOURTH_LEVEL_ADDRESSING            (0xFFFF0000)
-#define MPI2_LUN_LEVEL_1_WORD                       (0xFF00)
-#define MPI2_LUN_LEVEL_1_DWORD                      (0x0000FF00)
-
-
-/*****************************************************************************
-*
-*        Fusion-MPT MPI Scatter Gather Elements
-*
-*****************************************************************************/
-
-/****************************************************************************
-*  MPI Simple Element structures
-****************************************************************************/
-
-typedef struct _MPI2_SGE_SIMPLE32
-{
-    U32                     FlagsLength;
-    U32                     Address;
-} MPI2_SGE_SIMPLE32, MPI2_POINTER PTR_MPI2_SGE_SIMPLE32,
-  Mpi2SGESimple32_t, MPI2_POINTER pMpi2SGESimple32_t;
-
-typedef struct _MPI2_SGE_SIMPLE64
-{
-    U32                     FlagsLength;
-    U64                     Address;
-} MPI2_SGE_SIMPLE64, MPI2_POINTER PTR_MPI2_SGE_SIMPLE64,
-  Mpi2SGESimple64_t, MPI2_POINTER pMpi2SGESimple64_t;
-
-typedef struct _MPI2_SGE_SIMPLE_UNION
-{
-    U32                     FlagsLength;
-    union
-    {
-        U32                 Address32;
-        U64                 Address64;
-    } u;
-} MPI2_SGE_SIMPLE_UNION, MPI2_POINTER PTR_MPI2_SGE_SIMPLE_UNION,
-  Mpi2SGESimpleUnion_t, MPI2_POINTER pMpi2SGESimpleUnion_t;
-
-
-/****************************************************************************
-*  MPI Chain Element structures
-****************************************************************************/
-
-typedef struct _MPI2_SGE_CHAIN32
-{
-    U16                     Length;
-    U8                      NextChainOffset;
-    U8                      Flags;
-    U32                     Address;
-} MPI2_SGE_CHAIN32, MPI2_POINTER PTR_MPI2_SGE_CHAIN32,
-  Mpi2SGEChain32_t, MPI2_POINTER pMpi2SGEChain32_t;
-
-typedef struct _MPI2_SGE_CHAIN64
-{
-    U16                     Length;
-    U8                      NextChainOffset;
-    U8                      Flags;
-    U64                     Address;
-} MPI2_SGE_CHAIN64, MPI2_POINTER PTR_MPI2_SGE_CHAIN64,
-  Mpi2SGEChain64_t, MPI2_POINTER pMpi2SGEChain64_t;
-
-typedef struct _MPI2_SGE_CHAIN_UNION
-{
-    U16                     Length;
-    U8                      NextChainOffset;
-    U8                      Flags;
-    union
-    {
-        U32                 Address32;
-        U64                 Address64;
-    } u;
-} MPI2_SGE_CHAIN_UNION, MPI2_POINTER PTR_MPI2_SGE_CHAIN_UNION,
-  Mpi2SGEChainUnion_t, MPI2_POINTER pMpi2SGEChainUnion_t;
-
-
-/****************************************************************************
-*  MPI Transaction Context Element structures
-****************************************************************************/
-
-typedef struct _MPI2_SGE_TRANSACTION32
-{
-    U8                      Reserved;
-    U8                      ContextSize;
-    U8                      DetailsLength;
-    U8                      Flags;
-    U32                     TransactionContext[1];
-    U32                     TransactionDetails[1];
-} MPI2_SGE_TRANSACTION32, MPI2_POINTER PTR_MPI2_SGE_TRANSACTION32,
-  Mpi2SGETransaction32_t, MPI2_POINTER pMpi2SGETransaction32_t;
-
-typedef struct _MPI2_SGE_TRANSACTION64
-{
-    U8                      Reserved;
-    U8                      ContextSize;
-    U8                      DetailsLength;
-    U8                      Flags;
-    U32                     TransactionContext[2];
-    U32                     TransactionDetails[1];
-} MPI2_SGE_TRANSACTION64, MPI2_POINTER PTR_MPI2_SGE_TRANSACTION64,
-  Mpi2SGETransaction64_t, MPI2_POINTER pMpi2SGETransaction64_t;
-
-typedef struct _MPI2_SGE_TRANSACTION96
-{
-    U8                      Reserved;
-    U8                      ContextSize;
-    U8                      DetailsLength;
-    U8                      Flags;
-    U32                     TransactionContext[3];
-    U32                     TransactionDetails[1];
-} MPI2_SGE_TRANSACTION96, MPI2_POINTER PTR_MPI2_SGE_TRANSACTION96,
-  Mpi2SGETransaction96_t, MPI2_POINTER pMpi2SGETransaction96_t;
-
-typedef struct _MPI2_SGE_TRANSACTION128
-{
-    U8                      Reserved;
-    U8                      ContextSize;
-    U8                      DetailsLength;
-    U8                      Flags;
-    U32                     TransactionContext[4];
-    U32                     TransactionDetails[1];
-} MPI2_SGE_TRANSACTION128, MPI2_POINTER PTR_MPI2_SGE_TRANSACTION128,
-  Mpi2SGETransaction_t128, MPI2_POINTER pMpi2SGETransaction_t128;
-
-typedef struct _MPI2_SGE_TRANSACTION_UNION
-{
-    U8                      Reserved;
-    U8                      ContextSize;
-    U8                      DetailsLength;
-    U8                      Flags;
-    union
-    {
-        U32                 TransactionContext32[1];
-        U32                 TransactionContext64[2];
-        U32                 TransactionContext96[3];
-        U32                 TransactionContext128[4];
-    } u;
-    U32                     TransactionDetails[1];
-} MPI2_SGE_TRANSACTION_UNION, MPI2_POINTER PTR_MPI2_SGE_TRANSACTION_UNION,
-  Mpi2SGETransactionUnion_t, MPI2_POINTER pMpi2SGETransactionUnion_t;
-
-
-/****************************************************************************
-*  MPI SGE union for IO SGL's
-****************************************************************************/
-
-typedef struct _MPI2_MPI_SGE_IO_UNION
-{
-    union
-    {
-        MPI2_SGE_SIMPLE_UNION   Simple;
-        MPI2_SGE_CHAIN_UNION    Chain;
-    } u;
-} MPI2_MPI_SGE_IO_UNION, MPI2_POINTER PTR_MPI2_MPI_SGE_IO_UNION,
-  Mpi2MpiSGEIOUnion_t, MPI2_POINTER pMpi2MpiSGEIOUnion_t;
-
-
-/****************************************************************************
-*  MPI SGE union for SGL's with Simple and Transaction elements
-****************************************************************************/
-
-typedef struct _MPI2_SGE_TRANS_SIMPLE_UNION
-{
-    union
-    {
-        MPI2_SGE_SIMPLE_UNION       Simple;
-        MPI2_SGE_TRANSACTION_UNION  Transaction;
-    } u;
-} MPI2_SGE_TRANS_SIMPLE_UNION, MPI2_POINTER PTR_MPI2_SGE_TRANS_SIMPLE_UNION,
-  Mpi2SGETransSimpleUnion_t, MPI2_POINTER pMpi2SGETransSimpleUnion_t;
-
-
-/****************************************************************************
-*  All MPI SGE types union
-****************************************************************************/
-
-typedef struct _MPI2_MPI_SGE_UNION
-{
-    union
-    {
-        MPI2_SGE_SIMPLE_UNION       Simple;
-        MPI2_SGE_CHAIN_UNION        Chain;
-        MPI2_SGE_TRANSACTION_UNION  Transaction;
-    } u;
-} MPI2_MPI_SGE_UNION, MPI2_POINTER PTR_MPI2_MPI_SGE_UNION,
-  Mpi2MpiSgeUnion_t, MPI2_POINTER pMpi2MpiSgeUnion_t;
-
-
-/****************************************************************************
-*  MPI SGE field definition and masks
-****************************************************************************/
-
-/* Flags field bit definitions */
-
-#define MPI2_SGE_FLAGS_LAST_ELEMENT             (0x80)
-#define MPI2_SGE_FLAGS_END_OF_BUFFER            (0x40)
-#define MPI2_SGE_FLAGS_ELEMENT_TYPE_MASK        (0x30)
-#define MPI2_SGE_FLAGS_LOCAL_ADDRESS            (0x08)
-#define MPI2_SGE_FLAGS_DIRECTION                (0x04)
-#define MPI2_SGE_FLAGS_ADDRESS_SIZE             (0x02)
-#define MPI2_SGE_FLAGS_END_OF_LIST              (0x01)
-
-#define MPI2_SGE_FLAGS_SHIFT                    (24)
-
-#define MPI2_SGE_LENGTH_MASK                    (0x00FFFFFF)
-#define MPI2_SGE_CHAIN_LENGTH_MASK              (0x0000FFFF)
-
-/* Element Type */
-
-#define MPI2_SGE_FLAGS_TRANSACTION_ELEMENT      (0x00)
-#define MPI2_SGE_FLAGS_SIMPLE_ELEMENT           (0x10)
-#define MPI2_SGE_FLAGS_CHAIN_ELEMENT            (0x30)
-#define MPI2_SGE_FLAGS_ELEMENT_MASK             (0x30)
-
-/* Address location */
-
-#define MPI2_SGE_FLAGS_SYSTEM_ADDRESS           (0x00)
-
-/* Direction */
-
-#define MPI2_SGE_FLAGS_IOC_TO_HOST              (0x00)
-#define MPI2_SGE_FLAGS_HOST_TO_IOC              (0x04)
-
-#define MPI2_SGE_FLAGS_DEST                     (MPI2_SGE_FLAGS_IOC_TO_HOST)
-#define MPI2_SGE_FLAGS_SOURCE                   (MPI2_SGE_FLAGS_HOST_TO_IOC)
-
-/* Address Size */
-
-#define MPI2_SGE_FLAGS_32_BIT_ADDRESSING        (0x00)
-#define MPI2_SGE_FLAGS_64_BIT_ADDRESSING        (0x02)
-
-/* Context Size */
-
-#define MPI2_SGE_FLAGS_32_BIT_CONTEXT           (0x00)
-#define MPI2_SGE_FLAGS_64_BIT_CONTEXT           (0x02)
-#define MPI2_SGE_FLAGS_96_BIT_CONTEXT           (0x04)
-#define MPI2_SGE_FLAGS_128_BIT_CONTEXT          (0x06)
-
-#define MPI2_SGE_CHAIN_OFFSET_MASK              (0x00FF0000)
-#define MPI2_SGE_CHAIN_OFFSET_SHIFT             (16)
-
-/****************************************************************************
-*  MPI SGE operation Macros
-****************************************************************************/
-
-/* SIMPLE FlagsLength manipulations... */
-#define MPI2_SGE_SET_FLAGS(f)          ((U32)(f) << MPI2_SGE_FLAGS_SHIFT)
-#define MPI2_SGE_GET_FLAGS(f)          (((f) & ~MPI2_SGE_LENGTH_MASK) >> MPI2_SGE_FLAGS_SHIFT)
-#define MPI2_SGE_LENGTH(f)             ((f) & MPI2_SGE_LENGTH_MASK)
-#define MPI2_SGE_CHAIN_LENGTH(f)       ((f) & MPI2_SGE_CHAIN_LENGTH_MASK)
-
-#define MPI2_SGE_SET_FLAGS_LENGTH(f,l) (MPI2_SGE_SET_FLAGS(f) | MPI2_SGE_LENGTH(l))
-
-#define MPI2_pSGE_GET_FLAGS(psg)            MPI2_SGE_GET_FLAGS((psg)->FlagsLength)
-#define MPI2_pSGE_GET_LENGTH(psg)           MPI2_SGE_LENGTH((psg)->FlagsLength)
-#define MPI2_pSGE_SET_FLAGS_LENGTH(psg,f,l) (psg)->FlagsLength = MPI2_SGE_SET_FLAGS_LENGTH(f,l)
-
-/* CAUTION - The following are READ-MODIFY-WRITE! */
-#define MPI2_pSGE_SET_FLAGS(psg,f)      (psg)->FlagsLength |= MPI2_SGE_SET_FLAGS(f)
-#define MPI2_pSGE_SET_LENGTH(psg,l)     (psg)->FlagsLength |= MPI2_SGE_LENGTH(l)
-
-#define MPI2_GET_CHAIN_OFFSET(x)    ((x & MPI2_SGE_CHAIN_OFFSET_MASK) >> MPI2_SGE_CHAIN_OFFSET_SHIFT)
-
-
-/*****************************************************************************
-*
-*        Fusion-MPT IEEE Scatter Gather Elements
-*
-*****************************************************************************/
-
-/****************************************************************************
-*  IEEE Simple Element structures
-****************************************************************************/
-
-typedef struct _MPI2_IEEE_SGE_SIMPLE32
-{
-    U32                     Address;
-    U32                     FlagsLength;
-} MPI2_IEEE_SGE_SIMPLE32, MPI2_POINTER PTR_MPI2_IEEE_SGE_SIMPLE32,
-  Mpi2IeeeSgeSimple32_t, MPI2_POINTER pMpi2IeeeSgeSimple32_t;
-
-typedef struct _MPI2_IEEE_SGE_SIMPLE64
-{
-    U64                     Address;
-    U32                     Length;
-    U16                     Reserved1;
-    U8                      Reserved2;
-    U8                      Flags;
-} MPI2_IEEE_SGE_SIMPLE64, MPI2_POINTER PTR_MPI2_IEEE_SGE_SIMPLE64,
-  Mpi2IeeeSgeSimple64_t, MPI2_POINTER pMpi2IeeeSgeSimple64_t;
-
-typedef union _MPI2_IEEE_SGE_SIMPLE_UNION
-{
-    MPI2_IEEE_SGE_SIMPLE32  Simple32;
-    MPI2_IEEE_SGE_SIMPLE64  Simple64;
-} MPI2_IEEE_SGE_SIMPLE_UNION, MPI2_POINTER PTR_MPI2_IEEE_SGE_SIMPLE_UNION,
-  Mpi2IeeeSgeSimpleUnion_t, MPI2_POINTER pMpi2IeeeSgeSimpleUnion_t;
-
-
-/****************************************************************************
-*  IEEE Chain Element structures
-****************************************************************************/
-
-typedef MPI2_IEEE_SGE_SIMPLE32  MPI2_IEEE_SGE_CHAIN32;
-
-typedef MPI2_IEEE_SGE_SIMPLE64  MPI2_IEEE_SGE_CHAIN64;
-
-typedef union _MPI2_IEEE_SGE_CHAIN_UNION
-{
-    MPI2_IEEE_SGE_CHAIN32   Chain32;
-    MPI2_IEEE_SGE_CHAIN64   Chain64;
-} MPI2_IEEE_SGE_CHAIN_UNION, MPI2_POINTER PTR_MPI2_IEEE_SGE_CHAIN_UNION,
-  Mpi2IeeeSgeChainUnion_t, MPI2_POINTER pMpi2IeeeSgeChainUnion_t;
-
-
-/****************************************************************************
-*  All IEEE SGE types union
-****************************************************************************/
-
-typedef struct _MPI2_IEEE_SGE_UNION
-{
-    union
-    {
-        MPI2_IEEE_SGE_SIMPLE_UNION  Simple;
-        MPI2_IEEE_SGE_CHAIN_UNION   Chain;
-    } u;
-} MPI2_IEEE_SGE_UNION, MPI2_POINTER PTR_MPI2_IEEE_SGE_UNION,
-  Mpi2IeeeSgeUnion_t, MPI2_POINTER pMpi2IeeeSgeUnion_t;
-
-
-/****************************************************************************
-*  IEEE SGE field definitions and masks
-****************************************************************************/
-
-/* Flags field bit definitions */
-
-#define MPI2_IEEE_SGE_FLAGS_ELEMENT_TYPE_MASK   (0x80)
-
-#define MPI2_IEEE32_SGE_FLAGS_SHIFT             (24)
-
-#define MPI2_IEEE32_SGE_LENGTH_MASK             (0x00FFFFFF)
-
-/* Element Type */
-
-#define MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT      (0x00)
-#define MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT       (0x80)
-
-/* Data Location Address Space */
-
-#define MPI2_IEEE_SGE_FLAGS_ADDR_MASK           (0x03)
-#define MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR         (0x00)
-                                               /* IEEE Simple Element only */
-#define MPI2_IEEE_SGE_FLAGS_IOCDDR_ADDR         (0x01)
-                                               /* IEEE Simple Element only */
-#define MPI2_IEEE_SGE_FLAGS_IOCPLB_ADDR         (0x02)
-#define MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR      (0x03)
-                                               /* IEEE Simple Element only */
-#define MPI2_IEEE_SGE_FLAGS_SYSTEMPLBPCI_ADDR   (0x03)
-                                               /* IEEE Chain Element only */
-#define MPI2_IEEE_SGE_FLAGS_SYSTEMPLBCPI_ADDR   \
-       (MPI2_IEEE_SGE_FLAGS_SYSTEMPLBPCI_ADDR) /* typo in name */
-
-/****************************************************************************
-*  IEEE SGE operation Macros
-****************************************************************************/
-
-/* SIMPLE FlagsLength manipulations... */
-#define MPI2_IEEE32_SGE_SET_FLAGS(f)     ((U32)(f) << MPI2_IEEE32_SGE_FLAGS_SHIFT)
-#define MPI2_IEEE32_SGE_GET_FLAGS(f)     (((f) & ~MPI2_IEEE32_SGE_LENGTH_MASK) >> MPI2_IEEE32_SGE_FLAGS_SHIFT)
-#define MPI2_IEEE32_SGE_LENGTH(f)        ((f) & MPI2_IEEE32_SGE_LENGTH_MASK)
-
-#define MPI2_IEEE32_SGE_SET_FLAGS_LENGTH(f, l)      (MPI2_IEEE32_SGE_SET_FLAGS(f) | MPI2_IEEE32_SGE_LENGTH(l))
-
-#define MPI2_IEEE32_pSGE_GET_FLAGS(psg)             MPI2_IEEE32_SGE_GET_FLAGS((psg)->FlagsLength)
-#define MPI2_IEEE32_pSGE_GET_LENGTH(psg)            MPI2_IEEE32_SGE_LENGTH((psg)->FlagsLength)
-#define MPI2_IEEE32_pSGE_SET_FLAGS_LENGTH(psg,f,l)  (psg)->FlagsLength = MPI2_IEEE32_SGE_SET_FLAGS_LENGTH(f,l)
-
-/* CAUTION - The following are READ-MODIFY-WRITE! */
-#define MPI2_IEEE32_pSGE_SET_FLAGS(psg,f)    (psg)->FlagsLength |= MPI2_IEEE32_SGE_SET_FLAGS(f)
-#define MPI2_IEEE32_pSGE_SET_LENGTH(psg,l)   (psg)->FlagsLength |= MPI2_IEEE32_SGE_LENGTH(l)
-
-
-
-
-/*****************************************************************************
-*
-*        Fusion-MPT MPI/IEEE Scatter Gather Unions
-*
-*****************************************************************************/
-
-typedef union _MPI2_SIMPLE_SGE_UNION
-{
-    MPI2_SGE_SIMPLE_UNION       MpiSimple;
-    MPI2_IEEE_SGE_SIMPLE_UNION  IeeeSimple;
-} MPI2_SIMPLE_SGE_UNION, MPI2_POINTER PTR_MPI2_SIMPLE_SGE_UNION,
-  Mpi2SimpleSgeUntion_t, MPI2_POINTER pMpi2SimpleSgeUntion_t;
-
-
-typedef union _MPI2_SGE_IO_UNION
-{
-    MPI2_SGE_SIMPLE_UNION       MpiSimple;
-    MPI2_SGE_CHAIN_UNION        MpiChain;
-    MPI2_IEEE_SGE_SIMPLE_UNION  IeeeSimple;
-    MPI2_IEEE_SGE_CHAIN_UNION   IeeeChain;
-} MPI2_SGE_IO_UNION, MPI2_POINTER PTR_MPI2_SGE_IO_UNION,
-  Mpi2SGEIOUnion_t, MPI2_POINTER pMpi2SGEIOUnion_t;
-
-
-/****************************************************************************
-*
-*  Values for SGLFlags field, used in many request messages with an SGL
-*
-****************************************************************************/
-
-/* values for MPI SGL Data Location Address Space subfield */
-#define MPI2_SGLFLAGS_ADDRESS_SPACE_MASK            (0x0C)
-#define MPI2_SGLFLAGS_SYSTEM_ADDRESS_SPACE          (0x00)
-#define MPI2_SGLFLAGS_IOCDDR_ADDRESS_SPACE          (0x04)
-#define MPI2_SGLFLAGS_IOCPLB_ADDRESS_SPACE          (0x08)
-#define MPI2_SGLFLAGS_IOCPLBNTA_ADDRESS_SPACE       (0x0C)
-/* values for SGL Type subfield */
-#define MPI2_SGLFLAGS_SGL_TYPE_MASK                 (0x03)
-#define MPI2_SGLFLAGS_SGL_TYPE_MPI                  (0x00)
-#define MPI2_SGLFLAGS_SGL_TYPE_IEEE32               (0x01)
-#define MPI2_SGLFLAGS_SGL_TYPE_IEEE64               (0x02)
-
-
-#endif
-
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h b/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h
deleted file mode 100644 (file)
index ee8d2d6..0000000
+++ /dev/null
@@ -1,3068 +0,0 @@
-/*
- *  Copyright (c) 2000-2014 LSI Corporation.
- *
- *
- *           Name:  mpi2_cnfg.h
- *          Title:  MPI Configuration messages and pages
- *  Creation Date:  November 10, 2006
- *
- *    mpi2_cnfg.h Version:  02.00.29
- *
- *  Version History
- *  ---------------
- *
- *  Date      Version   Description
- *  --------  --------  ------------------------------------------------------
- *  04-30-07  02.00.00  Corresponds to Fusion-MPT MPI Specification Rev A.
- *  06-04-07  02.00.01  Added defines for SAS IO Unit Page 2 PhyFlags.
- *                      Added Manufacturing Page 11.
- *                      Added MPI2_SAS_EXPANDER0_FLAGS_CONNECTOR_END_DEVICE
- *                      define.
- *  06-26-07  02.00.02  Adding generic structure for product-specific
- *                      Manufacturing pages: MPI2_CONFIG_PAGE_MANUFACTURING_PS.
- *                      Rework of BIOS Page 2 configuration page.
- *                      Fixed MPI2_BIOSPAGE2_BOOT_DEVICE to be a union of the
- *                      forms.
- *                      Added configuration pages IOC Page 8 and Driver
- *                      Persistent Mapping Page 0.
- *  08-31-07  02.00.03  Modified configuration pages dealing with Integrated
- *                      RAID (Manufacturing Page 4, RAID Volume Pages 0 and 1,
- *                      RAID Physical Disk Pages 0 and 1, RAID Configuration
- *                      Page 0).
- *                      Added new value for AccessStatus field of SAS Device
- *                      Page 0 (_SATA_NEEDS_INITIALIZATION).
- *  10-31-07  02.00.04  Added missing SEPDevHandle field to
- *                      MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0.
- *  12-18-07  02.00.05  Modified IO Unit Page 0 to use 32-bit version fields for
- *                      NVDATA.
- *                      Modified IOC Page 7 to use masks and added field for
- *                      SASBroadcastPrimitiveMasks.
- *                      Added MPI2_CONFIG_PAGE_BIOS_4.
- *                      Added MPI2_CONFIG_PAGE_LOG_0.
- *  02-29-08  02.00.06  Modified various names to make them 32-character unique.
- *                      Added SAS Device IDs.
- *                      Updated Integrated RAID configuration pages including
- *                      Manufacturing Page 4, IOC Page 6, and RAID Configuration
- *                      Page 0.
- *  05-21-08  02.00.07  Added define MPI2_MANPAGE4_MIX_SSD_SAS_SATA.
- *                      Added define MPI2_MANPAGE4_PHYSDISK_128MB_COERCION.
- *                      Fixed define MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING.
- *                      Added missing MaxNumRoutedSasAddresses field to
- *                      MPI2_CONFIG_PAGE_EXPANDER_0.
- *                      Added SAS Port Page 0.
- *                      Modified structure layout for
- *                      MPI2_CONFIG_PAGE_DRIVER_MAPPING_0.
- *  06-27-08  02.00.08  Changed MPI2_CONFIG_PAGE_RD_PDISK_1 to use
- *                      MPI2_RAID_PHYS_DISK1_PATH_MAX to size the array.
- *  10-02-08  02.00.09  Changed MPI2_RAID_PGAD_CONFIGNUM_MASK from 0x0000FFFF
- *                      to 0x000000FF.
- *                      Added two new values for the Physical Disk Coercion Size
- *                      bits in the Flags field of Manufacturing Page 4.
- *                      Added product-specific Manufacturing pages 16 to 31.
- *                      Modified Flags bits for controlling write cache on SATA
- *                      drives in IO Unit Page 1.
- *                      Added new bit to AdditionalControlFlags of SAS IO Unit
- *                      Page 1 to control Invalid Topology Correction.
- *                      Added additional defines for RAID Volume Page 0
- *                      VolumeStatusFlags field.
- *                      Modified meaning of RAID Volume Page 0 VolumeSettings
- *                      define for auto-configure of hot-swap drives.
- *                      Added SupportedPhysDisks field to RAID Volume Page 1 and
- *                      added related defines.
- *                      Added PhysDiskAttributes field (and related defines) to
- *                      RAID Physical Disk Page 0.
- *                      Added MPI2_SAS_PHYINFO_PHY_VACANT define.
- *                      Added three new DiscoveryStatus bits for SAS IO Unit
- *                      Page 0 and SAS Expander Page 0.
- *                      Removed multiplexing information from SAS IO Unit pages.
- *                      Added BootDeviceWaitTime field to SAS IO Unit Page 4.
- *                      Removed Zone Address Resolved bit from PhyInfo and from
- *                      Expander Page 0 Flags field.
- *                      Added two new AccessStatus values to SAS Device Page 0
- *                      for indicating routing problems. Added 3 reserved words
- *                      to this page.
- *  01-19-09  02.00.10  Fixed defines for GPIOVal field of IO Unit Page 3.
- *                      Inserted missing reserved field into structure for IOC
- *                      Page 6.
- *                      Added more pending task bits to RAID Volume Page 0
- *                      VolumeStatusFlags defines.
- *                      Added MPI2_PHYSDISK0_STATUS_FLAG_NOT_CERTIFIED define.
- *                      Added a new DiscoveryStatus bit for SAS IO Unit Page 0
- *                      and SAS Expander Page 0 to flag a downstream initiator
- *                      when in simplified routing mode.
- *                      Removed SATA Init Failure defines for DiscoveryStatus
- *                      fields of SAS IO Unit Page 0 and SAS Expander Page 0.
- *                      Added MPI2_SAS_DEVICE0_ASTATUS_DEVICE_BLOCKED define.
- *                      Added PortGroups, DmaGroup, and ControlGroup fields to
- *                      SAS Device Page 0.
- *  05-06-09  02.00.11  Added structures and defines for IO Unit Page 5 and IO
- *                      Unit Page 6.
- *                      Added expander reduced functionality data to SAS
- *                      Expander Page 0.
- *                      Added SAS PHY Page 2 and SAS PHY Page 3.
- *  07-30-09  02.00.12  Added IO Unit Page 7.
- *                      Added new device ids.
- *                      Added SAS IO Unit Page 5.
- *                      Added partial and slumber power management capable flags
- *                      to SAS Device Page 0 Flags field.
- *                      Added PhyInfo defines for power condition.
- *                      Added Ethernet configuration pages.
- *  10-28-09  02.00.13  Added MPI2_IOUNITPAGE1_ENABLE_HOST_BASED_DISCOVERY.
- *                      Added SAS PHY Page 4 structure and defines.
- *  02-10-10  02.00.14  Modified the comments for the configuration page
- *                      structures that contain an array of data. The host
- *                      should use the "count" field in the page data (e.g. the
- *                      NumPhys field) to determine the number of valid elements
- *                      in the array.
- *                      Added/modified some MPI2_MFGPAGE_DEVID_SAS defines.
- *                      Added PowerManagementCapabilities to IO Unit Page 7.
- *                      Added PortWidthModGroup field to
- *                      MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS.
- *                      Added MPI2_CONFIG_PAGE_SASIOUNIT_6 and related defines.
- *                      Added MPI2_CONFIG_PAGE_SASIOUNIT_7 and related defines.
- *                      Added MPI2_CONFIG_PAGE_SASIOUNIT_8 and related defines.
- *  05-12-10  02.00.15  Added MPI2_RAIDVOL0_STATUS_FLAG_VOL_NOT_CONSISTENT
- *                      define.
- *                      Added MPI2_PHYSDISK0_INCOMPATIBLE_MEDIA_TYPE define.
- *                      Added MPI2_SAS_NEG_LINK_RATE_UNSUPPORTED_PHY define.
- *  08-11-10  02.00.16  Removed IO Unit Page 1 device path (multi-pathing)
- *                      defines.
- *  11-10-10  02.00.17  Added ReceptacleID field (replacing Reserved1) to
- *                      MPI2_MANPAGE7_CONNECTOR_INFO and reworked defines for
- *                      the Pinout field.
- *                      Added BoardTemperature and BoardTemperatureUnits fields
- *                      to MPI2_CONFIG_PAGE_IO_UNIT_7.
- *                      Added MPI2_CONFIG_EXTPAGETYPE_EXT_MANUFACTURING define
- *                      and MPI2_CONFIG_PAGE_EXT_MAN_PS structure.
- *  02-23-11  02.00.18  Added ProxyVF_ID field to MPI2_CONFIG_REQUEST.
- *                      Added IO Unit Page 8, IO Unit Page 9,
- *                      and IO Unit Page 10.
- *                      Added SASNotifyPrimitiveMasks field to
- *                      MPI2_CONFIG_PAGE_IOC_7.
- *  03-09-11  02.00.19  Fixed IO Unit Page 10 (to match the spec).
- *  05-25-11  02.00.20  Cleaned up a few comments.
- *  08-24-11  02.00.21  Marked the IO Unit Page 7 PowerManagementCapabilities
- *                      for PCIe link as obsolete.
- *                      Added SpinupFlags field containing a Disable Spin-up
- *                      bit to the MPI2_SAS_IOUNIT4_SPINUP_GROUP fields of
- *                      SAS IO Unit Page 4.
- *  11-18-11  02.00.22  Added define MPI2_IOCPAGE6_CAP_FLAGS_4K_SECTORS_SUPPORT.
- *                      Added UEFIVersion field to BIOS Page 1 and defined new
- *                      BiosOptions bits.
- *  11-27-12  02.00.23  Added MPI2_MANPAGE7_FLAG_EVENTREPLAY_SLOT_ORDER.
- *                     Added MPI2_BIOSPAGE1_OPTIONS_MASK_OEM_ID.
- *  12-20-12  02.00.24  Marked MPI2_SASIOUNIT1_CONTROL_CLEAR_AFFILIATION as
- *                     obsolete for MPI v2.5 and later.
- *                     Added some defines for 12G SAS speeds.
- *  04-09-13  02.00.25  Added MPI2_IOUNITPAGE1_ATA_SECURITY_FREEZE_LOCK.
- *                     Fixed MPI2_IOUNITPAGE5_DMA_CAP_MASK_MAX_REQUESTS to
- *                     match the specification.
- *  12-05-13  02.00.27  Added MPI2_MANPAGE7_FLAG_BASE_ENCLOSURE_LEVEL for
- *                     MPI2_CONFIG_PAGE_MAN_7.
- *                     Added EnclosureLevel and ConnectorName fields to
- *                     MPI2_CONFIG_PAGE_SAS_DEV_0.
- *                     Added MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID for
- *                     MPI2_CONFIG_PAGE_SAS_DEV_0.
- *                     Added EnclosureLevel field to
- *                     MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0.
- *                     Added MPI2_SAS_ENCLS0_FLAGS_ENCL_LEVEL_VALID for
- *                     MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0.
- *  01-08-14  02.00.28  Added more defines for the BiosOptions field of
- *                     MPI2_CONFIG_PAGE_BIOS_1.
- *  06-13-14  02.00.29  Added SSUTimeout field to MPI2_CONFIG_PAGE_BIOS_1, and
- *                     more defines for the BiosOptions field.
- *  --------------------------------------------------------------------------
- */
-
-#ifndef MPI2_CNFG_H
-#define MPI2_CNFG_H
-
-/*****************************************************************************
-*   Configuration Page Header and defines
-*****************************************************************************/
-
-/* Config Page Header */
-typedef struct _MPI2_CONFIG_PAGE_HEADER
-{
-    U8                 PageVersion;                /* 0x00 */
-    U8                 PageLength;                 /* 0x01 */
-    U8                 PageNumber;                 /* 0x02 */
-    U8                 PageType;                   /* 0x03 */
-} MPI2_CONFIG_PAGE_HEADER, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_HEADER,
-  Mpi2ConfigPageHeader_t, MPI2_POINTER pMpi2ConfigPageHeader_t;
-
-typedef union _MPI2_CONFIG_PAGE_HEADER_UNION
-{
-   MPI2_CONFIG_PAGE_HEADER  Struct;
-   U8                       Bytes[4];
-   U16                      Word16[2];
-   U32                      Word32;
-} MPI2_CONFIG_PAGE_HEADER_UNION, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_HEADER_UNION,
-  Mpi2ConfigPageHeaderUnion, MPI2_POINTER pMpi2ConfigPageHeaderUnion;
-
-/* Extended Config Page Header */
-typedef struct _MPI2_CONFIG_EXTENDED_PAGE_HEADER
-{
-    U8                  PageVersion;                /* 0x00 */
-    U8                  Reserved1;                  /* 0x01 */
-    U8                  PageNumber;                 /* 0x02 */
-    U8                  PageType;                   /* 0x03 */
-    U16                 ExtPageLength;              /* 0x04 */
-    U8                  ExtPageType;                /* 0x06 */
-    U8                  Reserved2;                  /* 0x07 */
-} MPI2_CONFIG_EXTENDED_PAGE_HEADER,
-  MPI2_POINTER PTR_MPI2_CONFIG_EXTENDED_PAGE_HEADER,
-  Mpi2ConfigExtendedPageHeader_t, MPI2_POINTER pMpi2ConfigExtendedPageHeader_t;
-
-typedef union _MPI2_CONFIG_EXT_PAGE_HEADER_UNION
-{
-   MPI2_CONFIG_PAGE_HEADER          Struct;
-   MPI2_CONFIG_EXTENDED_PAGE_HEADER Ext;
-   U8                               Bytes[8];
-   U16                              Word16[4];
-   U32                              Word32[2];
-} MPI2_CONFIG_EXT_PAGE_HEADER_UNION, MPI2_POINTER PTR_MPI2_CONFIG_EXT_PAGE_HEADER_UNION,
-  Mpi2ConfigPageExtendedHeaderUnion, MPI2_POINTER pMpi2ConfigPageExtendedHeaderUnion;
-
-
-/* PageType field values */
-#define MPI2_CONFIG_PAGEATTR_READ_ONLY              (0x00)
-#define MPI2_CONFIG_PAGEATTR_CHANGEABLE             (0x10)
-#define MPI2_CONFIG_PAGEATTR_PERSISTENT             (0x20)
-#define MPI2_CONFIG_PAGEATTR_MASK                   (0xF0)
-
-#define MPI2_CONFIG_PAGETYPE_IO_UNIT                (0x00)
-#define MPI2_CONFIG_PAGETYPE_IOC                    (0x01)
-#define MPI2_CONFIG_PAGETYPE_BIOS                   (0x02)
-#define MPI2_CONFIG_PAGETYPE_RAID_VOLUME            (0x08)
-#define MPI2_CONFIG_PAGETYPE_MANUFACTURING          (0x09)
-#define MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK          (0x0A)
-#define MPI2_CONFIG_PAGETYPE_EXTENDED               (0x0F)
-#define MPI2_CONFIG_PAGETYPE_MASK                   (0x0F)
-
-#define MPI2_CONFIG_TYPENUM_MASK                    (0x0FFF)
-
-
-/* ExtPageType field values */
-#define MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT         (0x10)
-#define MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER        (0x11)
-#define MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE          (0x12)
-#define MPI2_CONFIG_EXTPAGETYPE_SAS_PHY             (0x13)
-#define MPI2_CONFIG_EXTPAGETYPE_LOG                 (0x14)
-#define MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE           (0x15)
-#define MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG         (0x16)
-#define MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING      (0x17)
-#define MPI2_CONFIG_EXTPAGETYPE_SAS_PORT            (0x18)
-#define MPI2_CONFIG_EXTPAGETYPE_ETHERNET            (0x19)
-#define MPI2_CONFIG_EXTPAGETYPE_EXT_MANUFACTURING   (0x1A)
-
-
-/*****************************************************************************
-*   PageAddress defines
-*****************************************************************************/
-
-/* RAID Volume PageAddress format */
-#define MPI2_RAID_VOLUME_PGAD_FORM_MASK             (0xF0000000)
-#define MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE  (0x00000000)
-#define MPI2_RAID_VOLUME_PGAD_FORM_HANDLE           (0x10000000)
-
-#define MPI2_RAID_VOLUME_PGAD_HANDLE_MASK           (0x0000FFFF)
-
-
-/* RAID Physical Disk PageAddress format */
-#define MPI2_PHYSDISK_PGAD_FORM_MASK                    (0xF0000000)
-#define MPI2_PHYSDISK_PGAD_FORM_GET_NEXT_PHYSDISKNUM    (0x00000000)
-#define MPI2_PHYSDISK_PGAD_FORM_PHYSDISKNUM             (0x10000000)
-#define MPI2_PHYSDISK_PGAD_FORM_DEVHANDLE               (0x20000000)
-
-#define MPI2_PHYSDISK_PGAD_PHYSDISKNUM_MASK             (0x000000FF)
-#define MPI2_PHYSDISK_PGAD_DEVHANDLE_MASK               (0x0000FFFF)
-
-
-/* SAS Expander PageAddress format */
-#define MPI2_SAS_EXPAND_PGAD_FORM_MASK              (0xF0000000)
-#define MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL     (0x00000000)
-#define MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM      (0x10000000)
-#define MPI2_SAS_EXPAND_PGAD_FORM_HNDL              (0x20000000)
-
-#define MPI2_SAS_EXPAND_PGAD_HANDLE_MASK            (0x0000FFFF)
-#define MPI2_SAS_EXPAND_PGAD_PHYNUM_MASK            (0x00FF0000)
-#define MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT           (16)
-
-
-/* SAS Device PageAddress format */
-#define MPI2_SAS_DEVICE_PGAD_FORM_MASK              (0xF0000000)
-#define MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE   (0x00000000)
-#define MPI2_SAS_DEVICE_PGAD_FORM_HANDLE            (0x20000000)
-
-#define MPI2_SAS_DEVICE_PGAD_HANDLE_MASK            (0x0000FFFF)
-
-
-/* SAS PHY PageAddress format */
-#define MPI2_SAS_PHY_PGAD_FORM_MASK                 (0xF0000000)
-#define MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER           (0x00000000)
-#define MPI2_SAS_PHY_PGAD_FORM_PHY_TBL_INDEX        (0x10000000)
-
-#define MPI2_SAS_PHY_PGAD_PHY_NUMBER_MASK           (0x000000FF)
-#define MPI2_SAS_PHY_PGAD_PHY_TBL_INDEX_MASK        (0x0000FFFF)
-
-
-/* SAS Port PageAddress format */
-#define MPI2_SASPORT_PGAD_FORM_MASK                 (0xF0000000)
-#define MPI2_SASPORT_PGAD_FORM_GET_NEXT_PORT        (0x00000000)
-#define MPI2_SASPORT_PGAD_FORM_PORT_NUM             (0x10000000)
-
-#define MPI2_SASPORT_PGAD_PORTNUMBER_MASK           (0x00000FFF)
-
-
-/* SAS Enclosure PageAddress format */
-#define MPI2_SAS_ENCLOS_PGAD_FORM_MASK              (0xF0000000)
-#define MPI2_SAS_ENCLOS_PGAD_FORM_GET_NEXT_HANDLE   (0x00000000)
-#define MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE            (0x10000000)
-
-#define MPI2_SAS_ENCLOS_PGAD_HANDLE_MASK            (0x0000FFFF)
-
-
-/* RAID Configuration PageAddress format */
-#define MPI2_RAID_PGAD_FORM_MASK                    (0xF0000000)
-#define MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM      (0x00000000)
-#define MPI2_RAID_PGAD_FORM_CONFIGNUM               (0x10000000)
-#define MPI2_RAID_PGAD_FORM_ACTIVE_CONFIG           (0x20000000)
-
-#define MPI2_RAID_PGAD_CONFIGNUM_MASK               (0x000000FF)
-
-
-/* Driver Persistent Mapping PageAddress format */
-#define MPI2_DPM_PGAD_FORM_MASK                     (0xF0000000)
-#define MPI2_DPM_PGAD_FORM_ENTRY_RANGE              (0x00000000)
-
-#define MPI2_DPM_PGAD_ENTRY_COUNT_MASK              (0x0FFF0000)
-#define MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT             (16)
-#define MPI2_DPM_PGAD_START_ENTRY_MASK              (0x0000FFFF)
-
-
-/* Ethernet PageAddress format */
-#define MPI2_ETHERNET_PGAD_FORM_MASK                (0xF0000000)
-#define MPI2_ETHERNET_PGAD_FORM_IF_NUM              (0x00000000)
-
-#define MPI2_ETHERNET_PGAD_IF_NUMBER_MASK           (0x000000FF)
-
-
-
-/****************************************************************************
-*   Configuration messages
-****************************************************************************/
-
-/* Configuration Request Message */
-typedef struct _MPI2_CONFIG_REQUEST
-{
-    U8                      Action;                     /* 0x00 */
-    U8                      SGLFlags;                   /* 0x01 */
-    U8                      ChainOffset;                /* 0x02 */
-    U8                      Function;                   /* 0x03 */
-    U16                     ExtPageLength;              /* 0x04 */
-    U8                      ExtPageType;                /* 0x06 */
-    U8                      MsgFlags;                   /* 0x07 */
-    U8                      VP_ID;                      /* 0x08 */
-    U8                      VF_ID;                      /* 0x09 */
-    U16                     Reserved1;                  /* 0x0A */
-       U8                      Reserved2;                  /* 0x0C */
-       U8                      ProxyVF_ID;                 /* 0x0D */
-       U16                     Reserved4;                  /* 0x0E */
-    U32                     Reserved3;                  /* 0x10 */
-    MPI2_CONFIG_PAGE_HEADER Header;                     /* 0x14 */
-    U32                     PageAddress;                /* 0x18 */
-    MPI2_SGE_IO_UNION       PageBufferSGE;              /* 0x1C */
-} MPI2_CONFIG_REQUEST, MPI2_POINTER PTR_MPI2_CONFIG_REQUEST,
-  Mpi2ConfigRequest_t, MPI2_POINTER pMpi2ConfigRequest_t;
-
-/* values for the Action field */
-#define MPI2_CONFIG_ACTION_PAGE_HEADER              (0x00)
-#define MPI2_CONFIG_ACTION_PAGE_READ_CURRENT        (0x01)
-#define MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT       (0x02)
-#define MPI2_CONFIG_ACTION_PAGE_DEFAULT             (0x03)
-#define MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM         (0x04)
-#define MPI2_CONFIG_ACTION_PAGE_READ_DEFAULT        (0x05)
-#define MPI2_CONFIG_ACTION_PAGE_READ_NVRAM          (0x06)
-#define MPI2_CONFIG_ACTION_PAGE_GET_CHANGEABLE      (0x07)
-
-/* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */
-
-
-/* Config Reply Message */
-typedef struct _MPI2_CONFIG_REPLY
-{
-    U8                      Action;                     /* 0x00 */
-    U8                      SGLFlags;                   /* 0x01 */
-    U8                      MsgLength;                  /* 0x02 */
-    U8                      Function;                   /* 0x03 */
-    U16                     ExtPageLength;              /* 0x04 */
-    U8                      ExtPageType;                /* 0x06 */
-    U8                      MsgFlags;                   /* 0x07 */
-    U8                      VP_ID;                      /* 0x08 */
-    U8                      VF_ID;                      /* 0x09 */
-    U16                     Reserved1;                  /* 0x0A */
-    U16                     Reserved2;                  /* 0x0C */
-    U16                     IOCStatus;                  /* 0x0E */
-    U32                     IOCLogInfo;                 /* 0x10 */
-    MPI2_CONFIG_PAGE_HEADER Header;                     /* 0x14 */
-} MPI2_CONFIG_REPLY, MPI2_POINTER PTR_MPI2_CONFIG_REPLY,
-  Mpi2ConfigReply_t, MPI2_POINTER pMpi2ConfigReply_t;
-
-
-
-/*****************************************************************************
-*
-*               C o n f i g u r a t i o n    P a g e s
-*
-*****************************************************************************/
-
-/****************************************************************************
-*   Manufacturing Config pages
-****************************************************************************/
-
-#define MPI2_MFGPAGE_VENDORID_LSI                   (0x1000)
-
-/* SAS */
-#define MPI2_MFGPAGE_DEVID_SAS2004                  (0x0070)
-#define MPI2_MFGPAGE_DEVID_SAS2008                  (0x0072)
-#define MPI2_MFGPAGE_DEVID_SAS2108_1                (0x0074)
-#define MPI2_MFGPAGE_DEVID_SAS2108_2                (0x0076)
-#define MPI2_MFGPAGE_DEVID_SAS2108_3                (0x0077)
-#define MPI2_MFGPAGE_DEVID_SAS2116_1                (0x0064)
-#define MPI2_MFGPAGE_DEVID_SAS2116_2                (0x0065)
-
-#define MPI2_MFGPAGE_DEVID_SSS6200                  (0x007E)
-
-#define MPI2_MFGPAGE_DEVID_SAS2208_1                (0x0080)
-#define MPI2_MFGPAGE_DEVID_SAS2208_2                (0x0081)
-#define MPI2_MFGPAGE_DEVID_SAS2208_3                (0x0082)
-#define MPI2_MFGPAGE_DEVID_SAS2208_4                (0x0083)
-#define MPI2_MFGPAGE_DEVID_SAS2208_5                (0x0084)
-#define MPI2_MFGPAGE_DEVID_SAS2208_6                (0x0085)
-#define MPI2_MFGPAGE_DEVID_SAS2308_1                (0x0086)
-#define MPI2_MFGPAGE_DEVID_SAS2308_2                (0x0087)
-#define MPI2_MFGPAGE_DEVID_SAS2308_3                (0x006E)
-
-
-
-
-/* Manufacturing Page 0 */
-
-typedef struct _MPI2_CONFIG_PAGE_MAN_0
-{
-    MPI2_CONFIG_PAGE_HEADER Header;                     /* 0x00 */
-    U8                      ChipName[16];               /* 0x04 */
-    U8                      ChipRevision[8];            /* 0x14 */
-    U8                      BoardName[16];              /* 0x1C */
-    U8                      BoardAssembly[16];          /* 0x2C */
-    U8                      BoardTracerNumber[16];      /* 0x3C */
-} MPI2_CONFIG_PAGE_MAN_0,
-  MPI2_POINTER PTR_MPI2_CONFIG_PAGE_MAN_0,
-  Mpi2ManufacturingPage0_t, MPI2_POINTER pMpi2ManufacturingPage0_t;
-
-#define MPI2_MANUFACTURING0_PAGEVERSION                (0x00)
-
-
-/* Manufacturing Page 1 */
-
-typedef struct _MPI2_CONFIG_PAGE_MAN_1
-{
-    MPI2_CONFIG_PAGE_HEADER Header;                     /* 0x00 */
-    U8                      VPD[256];                   /* 0x04 */
-} MPI2_CONFIG_PAGE_MAN_1,
-  MPI2_POINTER PTR_MPI2_CONFIG_PAGE_MAN_1,
-  Mpi2ManufacturingPage1_t, MPI2_POINTER pMpi2ManufacturingPage1_t;
-
-#define MPI2_MANUFACTURING1_PAGEVERSION                (0x00)
-
-
-typedef struct _MPI2_CHIP_REVISION_ID
-{
-    U16 DeviceID;                                       /* 0x00 */
-    U8  PCIRevisionID;                                  /* 0x02 */
-    U8  Reserved;                                       /* 0x03 */
-} MPI2_CHIP_REVISION_ID, MPI2_POINTER PTR_MPI2_CHIP_REVISION_ID,
-  Mpi2ChipRevisionId_t, MPI2_POINTER pMpi2ChipRevisionId_t;
-
-
-/* Manufacturing Page 2 */
-
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check Header.PageLength at runtime.
- */
-#ifndef MPI2_MAN_PAGE_2_HW_SETTINGS_WORDS
-#define MPI2_MAN_PAGE_2_HW_SETTINGS_WORDS   (1)
-#endif
-
-typedef struct _MPI2_CONFIG_PAGE_MAN_2
-{
-    MPI2_CONFIG_PAGE_HEADER Header;                     /* 0x00 */
-    MPI2_CHIP_REVISION_ID   ChipId;                     /* 0x04 */
-    U32                     HwSettings[MPI2_MAN_PAGE_2_HW_SETTINGS_WORDS];/* 0x08 */
-} MPI2_CONFIG_PAGE_MAN_2,
-  MPI2_POINTER PTR_MPI2_CONFIG_PAGE_MAN_2,
-  Mpi2ManufacturingPage2_t, MPI2_POINTER pMpi2ManufacturingPage2_t;
-
-#define MPI2_MANUFACTURING2_PAGEVERSION                 (0x00)
-
-
-/* Manufacturing Page 3 */
-
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check Header.PageLength at runtime.
- */
-#ifndef MPI2_MAN_PAGE_3_INFO_WORDS
-#define MPI2_MAN_PAGE_3_INFO_WORDS          (1)
-#endif
-
-typedef struct _MPI2_CONFIG_PAGE_MAN_3
-{
-    MPI2_CONFIG_PAGE_HEADER             Header;         /* 0x00 */
-    MPI2_CHIP_REVISION_ID               ChipId;         /* 0x04 */
-    U32                                 Info[MPI2_MAN_PAGE_3_INFO_WORDS];/* 0x08 */
-} MPI2_CONFIG_PAGE_MAN_3,
-  MPI2_POINTER PTR_MPI2_CONFIG_PAGE_MAN_3,
-  Mpi2ManufacturingPage3_t, MPI2_POINTER pMpi2ManufacturingPage3_t;
-
-#define MPI2_MANUFACTURING3_PAGEVERSION                 (0x00)
-
-
-/* Manufacturing Page 4 */
-
-typedef struct _MPI2_MANPAGE4_PWR_SAVE_SETTINGS
-{
-    U8                          PowerSaveFlags;                 /* 0x00 */
-    U8                          InternalOperationsSleepTime;    /* 0x01 */
-    U8                          InternalOperationsRunTime;      /* 0x02 */
-    U8                          HostIdleTime;                   /* 0x03 */
-} MPI2_MANPAGE4_PWR_SAVE_SETTINGS,
-  MPI2_POINTER PTR_MPI2_MANPAGE4_PWR_SAVE_SETTINGS,
-  Mpi2ManPage4PwrSaveSettings_t, MPI2_POINTER pMpi2ManPage4PwrSaveSettings_t;
-
-/* defines for the PowerSaveFlags field */
-#define MPI2_MANPAGE4_MASK_POWERSAVE_MODE               (0x03)
-#define MPI2_MANPAGE4_POWERSAVE_MODE_DISABLED           (0x00)
-#define MPI2_MANPAGE4_CUSTOM_POWERSAVE_MODE             (0x01)
-#define MPI2_MANPAGE4_FULL_POWERSAVE_MODE               (0x02)
-
-typedef struct _MPI2_CONFIG_PAGE_MAN_4
-{
-    MPI2_CONFIG_PAGE_HEADER             Header;                 /* 0x00 */
-    U32                                 Reserved1;              /* 0x04 */
-    U32                                 Flags;                  /* 0x08 */
-    U8                                  InquirySize;            /* 0x0C */
-    U8                                  Reserved2;              /* 0x0D */
-    U16                                 Reserved3;              /* 0x0E */
-    U8                                  InquiryData[56];        /* 0x10 */
-    U32                                 RAID0VolumeSettings;    /* 0x48 */
-    U32                                 RAID1EVolumeSettings;   /* 0x4C */
-    U32                                 RAID1VolumeSettings;    /* 0x50 */
-    U32                                 RAID10VolumeSettings;   /* 0x54 */
-    U32                                 Reserved4;              /* 0x58 */
-    U32                                 Reserved5;              /* 0x5C */
-    MPI2_MANPAGE4_PWR_SAVE_SETTINGS     PowerSaveSettings;      /* 0x60 */
-    U8                                  MaxOCEDisks;            /* 0x64 */
-    U8                                  ResyncRate;             /* 0x65 */
-    U16                                 DataScrubDuration;      /* 0x66 */
-    U8                                  MaxHotSpares;           /* 0x68 */
-    U8                                  MaxPhysDisksPerVol;     /* 0x69 */
-    U8                                  MaxPhysDisks;           /* 0x6A */
-    U8                                  MaxVolumes;             /* 0x6B */
-} MPI2_CONFIG_PAGE_MAN_4,
-  MPI2_POINTER PTR_MPI2_CONFIG_PAGE_MAN_4,
-  Mpi2ManufacturingPage4_t, MPI2_POINTER pMpi2ManufacturingPage4_t;
-
-#define MPI2_MANUFACTURING4_PAGEVERSION                 (0x0A)
-
-/* Manufacturing Page 4 Flags field */
-#define MPI2_MANPAGE4_METADATA_SIZE_MASK                (0x00030000)
-#define MPI2_MANPAGE4_METADATA_512MB                    (0x00000000)
-
-#define MPI2_MANPAGE4_MIX_SSD_SAS_SATA                  (0x00008000)
-#define MPI2_MANPAGE4_MIX_SSD_AND_NON_SSD               (0x00004000)
-#define MPI2_MANPAGE4_HIDE_PHYSDISK_NON_IR              (0x00002000)
-
-#define MPI2_MANPAGE4_MASK_PHYSDISK_COERCION            (0x00001C00)
-#define MPI2_MANPAGE4_PHYSDISK_COERCION_1GB             (0x00000000)
-#define MPI2_MANPAGE4_PHYSDISK_128MB_COERCION           (0x00000400)
-#define MPI2_MANPAGE4_PHYSDISK_ADAPTIVE_COERCION        (0x00000800)
-#define MPI2_MANPAGE4_PHYSDISK_ZERO_COERCION            (0x00000C00)
-
-#define MPI2_MANPAGE4_MASK_BAD_BLOCK_MARKING            (0x00000300)
-#define MPI2_MANPAGE4_DEFAULT_BAD_BLOCK_MARKING         (0x00000000)
-#define MPI2_MANPAGE4_TABLE_BAD_BLOCK_MARKING           (0x00000100)
-#define MPI2_MANPAGE4_WRITE_LONG_BAD_BLOCK_MARKING      (0x00000200)
-
-#define MPI2_MANPAGE4_FORCE_OFFLINE_FAILOVER            (0x00000080)
-#define MPI2_MANPAGE4_RAID10_DISABLE                    (0x00000040)
-#define MPI2_MANPAGE4_RAID1E_DISABLE                    (0x00000020)
-#define MPI2_MANPAGE4_RAID1_DISABLE                     (0x00000010)
-#define MPI2_MANPAGE4_RAID0_DISABLE                     (0x00000008)
-#define MPI2_MANPAGE4_IR_MODEPAGE8_DISABLE              (0x00000004)
-#define MPI2_MANPAGE4_IM_RESYNC_CACHE_ENABLE            (0x00000002)
-#define MPI2_MANPAGE4_IR_NO_MIX_SAS_SATA                (0x00000001)
-
-
-/* Manufacturing Page 5 */
-
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check the value returned for NumPhys at runtime.
- */
-#ifndef MPI2_MAN_PAGE_5_PHY_ENTRIES
-#define MPI2_MAN_PAGE_5_PHY_ENTRIES         (1)
-#endif
-
-typedef struct _MPI2_MANUFACTURING5_ENTRY
-{
-    U64                                 WWID;           /* 0x00 */
-    U64                                 DeviceName;     /* 0x08 */
-} MPI2_MANUFACTURING5_ENTRY, MPI2_POINTER PTR_MPI2_MANUFACTURING5_ENTRY,
-  Mpi2Manufacturing5Entry_t, MPI2_POINTER pMpi2Manufacturing5Entry_t;
-
-typedef struct _MPI2_CONFIG_PAGE_MAN_5
-{
-    MPI2_CONFIG_PAGE_HEADER             Header;         /* 0x00 */
-    U8                                  NumPhys;        /* 0x04 */
-    U8                                  Reserved1;      /* 0x05 */
-    U16                                 Reserved2;      /* 0x06 */
-    U32                                 Reserved3;      /* 0x08 */
-    U32                                 Reserved4;      /* 0x0C */
-    MPI2_MANUFACTURING5_ENTRY           Phy[MPI2_MAN_PAGE_5_PHY_ENTRIES];/* 0x08 */
-} MPI2_CONFIG_PAGE_MAN_5,
-  MPI2_POINTER PTR_MPI2_CONFIG_PAGE_MAN_5,
-  Mpi2ManufacturingPage5_t, MPI2_POINTER pMpi2ManufacturingPage5_t;
-
-#define MPI2_MANUFACTURING5_PAGEVERSION                 (0x03)
-
-
-/* Manufacturing Page 6 */
-
-typedef struct _MPI2_CONFIG_PAGE_MAN_6
-{
-    MPI2_CONFIG_PAGE_HEADER         Header;             /* 0x00 */
-    U32                             ProductSpecificInfo;/* 0x04 */
-} MPI2_CONFIG_PAGE_MAN_6,
-  MPI2_POINTER PTR_MPI2_CONFIG_PAGE_MAN_6,
-  Mpi2ManufacturingPage6_t, MPI2_POINTER pMpi2ManufacturingPage6_t;
-
-#define MPI2_MANUFACTURING6_PAGEVERSION                 (0x00)
-
-
-/* Manufacturing Page 7 */
-
-typedef struct _MPI2_MANPAGE7_CONNECTOR_INFO
-{
-    U32                         Pinout;                 /* 0x00 */
-    U8                          Connector[16];          /* 0x04 */
-    U8                          Location;               /* 0x14 */
-       U8                          ReceptacleID;           /* 0x15 */
-    U16                         Slot;                   /* 0x16 */
-    U32                         Reserved2;              /* 0x18 */
-} MPI2_MANPAGE7_CONNECTOR_INFO, MPI2_POINTER PTR_MPI2_MANPAGE7_CONNECTOR_INFO,
-  Mpi2ManPage7ConnectorInfo_t, MPI2_POINTER pMpi2ManPage7ConnectorInfo_t;
-
-/* defines for the Pinout field */
-#define MPI2_MANPAGE7_PINOUT_LANE_MASK                  (0x0000FF00)
-#define MPI2_MANPAGE7_PINOUT_LANE_SHIFT                 (8)
-
-#define MPI2_MANPAGE7_PINOUT_TYPE_MASK                  (0x000000FF)
-#define MPI2_MANPAGE7_PINOUT_TYPE_UNKNOWN               (0x00)
-#define MPI2_MANPAGE7_PINOUT_SATA_SINGLE                (0x01)
-#define MPI2_MANPAGE7_PINOUT_SFF_8482                   (0x02)
-#define MPI2_MANPAGE7_PINOUT_SFF_8486                   (0x03)
-#define MPI2_MANPAGE7_PINOUT_SFF_8484                   (0x04)
-#define MPI2_MANPAGE7_PINOUT_SFF_8087                   (0x05)
-#define MPI2_MANPAGE7_PINOUT_SFF_8643_4I                (0x06)
-#define MPI2_MANPAGE7_PINOUT_SFF_8643_8I                (0x07)
-#define MPI2_MANPAGE7_PINOUT_SFF_8470                   (0x08)
-#define MPI2_MANPAGE7_PINOUT_SFF_8088                   (0x09)
-#define MPI2_MANPAGE7_PINOUT_SFF_8644_4X                (0x0A)
-#define MPI2_MANPAGE7_PINOUT_SFF_8644_8X                (0x0B)
-#define MPI2_MANPAGE7_PINOUT_SFF_8644_16X               (0x0C)
-#define MPI2_MANPAGE7_PINOUT_SFF_8436                   (0x0D)
-
-/* defines for the Location field */
-#define MPI2_MANPAGE7_LOCATION_UNKNOWN                  (0x01)
-#define MPI2_MANPAGE7_LOCATION_INTERNAL                 (0x02)
-#define MPI2_MANPAGE7_LOCATION_EXTERNAL                 (0x04)
-#define MPI2_MANPAGE7_LOCATION_SWITCHABLE               (0x08)
-#define MPI2_MANPAGE7_LOCATION_AUTO                     (0x10)
-#define MPI2_MANPAGE7_LOCATION_NOT_PRESENT              (0x20)
-#define MPI2_MANPAGE7_LOCATION_NOT_CONNECTED            (0x80)
-
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check the value returned for NumPhys at runtime.
- */
-#ifndef MPI2_MANPAGE7_CONNECTOR_INFO_MAX
-#define MPI2_MANPAGE7_CONNECTOR_INFO_MAX  (1)
-#endif
-
-typedef struct _MPI2_CONFIG_PAGE_MAN_7
-{
-    MPI2_CONFIG_PAGE_HEADER         Header;             /* 0x00 */
-    U32                             Reserved1;          /* 0x04 */
-    U32                             Reserved2;          /* 0x08 */
-    U32                             Flags;              /* 0x0C */
-    U8                              EnclosureName[16];  /* 0x10 */
-    U8                              NumPhys;            /* 0x20 */
-    U8                              Reserved3;          /* 0x21 */
-    U16                             Reserved4;          /* 0x22 */
-    MPI2_MANPAGE7_CONNECTOR_INFO    ConnectorInfo[MPI2_MANPAGE7_CONNECTOR_INFO_MAX]; /* 0x24 */
-} MPI2_CONFIG_PAGE_MAN_7,
-  MPI2_POINTER PTR_MPI2_CONFIG_PAGE_MAN_7,
-  Mpi2ManufacturingPage7_t, MPI2_POINTER pMpi2ManufacturingPage7_t;
-
-#define MPI2_MANUFACTURING7_PAGEVERSION                 (0x01)
-
-/* defines for the Flags field */
-#define MPI2_MANPAGE7_FLAG_BASE_ENCLOSURE_LEVEL         (0x00000008)
-#define MPI2_MANPAGE7_FLAG_EVENTREPLAY_SLOT_ORDER       (0x00000002)
-#define MPI2_MANPAGE7_FLAG_USE_SLOT_INFO                (0x00000001)
-
-
-/*
- * Generic structure to use for product-specific manufacturing pages
- * (currently Manufacturing Page 8 through Manufacturing Page 31).
- */
-
-typedef struct _MPI2_CONFIG_PAGE_MAN_PS
-{
-    MPI2_CONFIG_PAGE_HEADER         Header;             /* 0x00 */
-    U32                             ProductSpecificInfo;/* 0x04 */
-} MPI2_CONFIG_PAGE_MAN_PS,
-  MPI2_POINTER PTR_MPI2_CONFIG_PAGE_MAN_PS,
-  Mpi2ManufacturingPagePS_t, MPI2_POINTER pMpi2ManufacturingPagePS_t;
-
-#define MPI2_MANUFACTURING8_PAGEVERSION                 (0x00)
-#define MPI2_MANUFACTURING9_PAGEVERSION                 (0x00)
-#define MPI2_MANUFACTURING10_PAGEVERSION                (0x00)
-#define MPI2_MANUFACTURING11_PAGEVERSION                (0x00)
-#define MPI2_MANUFACTURING12_PAGEVERSION                (0x00)
-#define MPI2_MANUFACTURING13_PAGEVERSION                (0x00)
-#define MPI2_MANUFACTURING14_PAGEVERSION                (0x00)
-#define MPI2_MANUFACTURING15_PAGEVERSION                (0x00)
-#define MPI2_MANUFACTURING16_PAGEVERSION                (0x00)
-#define MPI2_MANUFACTURING17_PAGEVERSION                (0x00)
-#define MPI2_MANUFACTURING18_PAGEVERSION                (0x00)
-#define MPI2_MANUFACTURING19_PAGEVERSION                (0x00)
-#define MPI2_MANUFACTURING20_PAGEVERSION                (0x00)
-#define MPI2_MANUFACTURING21_PAGEVERSION                (0x00)
-#define MPI2_MANUFACTURING22_PAGEVERSION                (0x00)
-#define MPI2_MANUFACTURING23_PAGEVERSION                (0x00)
-#define MPI2_MANUFACTURING24_PAGEVERSION                (0x00)
-#define MPI2_MANUFACTURING25_PAGEVERSION                (0x00)
-#define MPI2_MANUFACTURING26_PAGEVERSION                (0x00)
-#define MPI2_MANUFACTURING27_PAGEVERSION                (0x00)
-#define MPI2_MANUFACTURING28_PAGEVERSION                (0x00)
-#define MPI2_MANUFACTURING29_PAGEVERSION                (0x00)
-#define MPI2_MANUFACTURING30_PAGEVERSION                (0x00)
-#define MPI2_MANUFACTURING31_PAGEVERSION                (0x00)
-
-
-/****************************************************************************
-*   IO Unit Config Pages
-****************************************************************************/
-
-/* IO Unit Page 0 */
-
-typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_0
-{
-    MPI2_CONFIG_PAGE_HEADER Header;                     /* 0x00 */
-    U64                     UniqueValue;                /* 0x04 */
-    MPI2_VERSION_UNION      NvdataVersionDefault;       /* 0x08 */
-    MPI2_VERSION_UNION      NvdataVersionPersistent;    /* 0x0A */
-} MPI2_CONFIG_PAGE_IO_UNIT_0, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IO_UNIT_0,
-  Mpi2IOUnitPage0_t, MPI2_POINTER pMpi2IOUnitPage0_t;
-
-#define MPI2_IOUNITPAGE0_PAGEVERSION                    (0x02)
-
-
-/* IO Unit Page 1 */
-
-typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_1
-{
-    MPI2_CONFIG_PAGE_HEADER Header;                     /* 0x00 */
-    U32                     Flags;                      /* 0x04 */
-} MPI2_CONFIG_PAGE_IO_UNIT_1, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IO_UNIT_1,
-  Mpi2IOUnitPage1_t, MPI2_POINTER pMpi2IOUnitPage1_t;
-
-#define MPI2_IOUNITPAGE1_PAGEVERSION                    (0x04)
-
-/* IO Unit Page 1 Flags defines */
-#define MPI2_IOUNITPAGE1_ATA_SECURITY_FREEZE_LOCK       (0x00004000)
-#define MPI2_IOUNITPAGE1_ENABLE_HOST_BASED_DISCOVERY    (0x00000800)
-#define MPI2_IOUNITPAGE1_MASK_SATA_WRITE_CACHE          (0x00000600)
-#define MPI2_IOUNITPAGE1_SATA_WRITE_CACHE_SHIFT         (9)
-#define MPI2_IOUNITPAGE1_ENABLE_SATA_WRITE_CACHE        (0x00000000)
-#define MPI2_IOUNITPAGE1_DISABLE_SATA_WRITE_CACHE       (0x00000200)
-#define MPI2_IOUNITPAGE1_UNCHANGED_SATA_WRITE_CACHE     (0x00000400)
-#define MPI2_IOUNITPAGE1_NATIVE_COMMAND_Q_DISABLE       (0x00000100)
-#define MPI2_IOUNITPAGE1_DISABLE_IR                     (0x00000040)
-#define MPI2_IOUNITPAGE1_DISABLE_TASK_SET_FULL_HANDLING (0x00000020)
-#define MPI2_IOUNITPAGE1_IR_USE_STATIC_VOLUME_ID        (0x00000004)
-
-
-/* IO Unit Page 3 */
-
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check the value returned for GPIOCount at runtime.
- */
-#ifndef MPI2_IO_UNIT_PAGE_3_GPIO_VAL_MAX
-#define MPI2_IO_UNIT_PAGE_3_GPIO_VAL_MAX    (1)
-#endif
-
-typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_3
-{
-    MPI2_CONFIG_PAGE_HEADER Header;                                   /* 0x00 */
-    U8                      GPIOCount;                                /* 0x04 */
-    U8                      Reserved1;                                /* 0x05 */
-    U16                     Reserved2;                                /* 0x06 */
-    U16                     GPIOVal[MPI2_IO_UNIT_PAGE_3_GPIO_VAL_MAX];/* 0x08 */
-} MPI2_CONFIG_PAGE_IO_UNIT_3, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IO_UNIT_3,
-  Mpi2IOUnitPage3_t, MPI2_POINTER pMpi2IOUnitPage3_t;
-
-#define MPI2_IOUNITPAGE3_PAGEVERSION                    (0x01)
-
-/* defines for IO Unit Page 3 GPIOVal field */
-#define MPI2_IOUNITPAGE3_GPIO_FUNCTION_MASK             (0xFFFC)
-#define MPI2_IOUNITPAGE3_GPIO_FUNCTION_SHIFT            (2)
-#define MPI2_IOUNITPAGE3_GPIO_SETTING_OFF               (0x0000)
-#define MPI2_IOUNITPAGE3_GPIO_SETTING_ON                (0x0001)
-
-
-/* IO Unit Page 5 */
-
-/*
- * Upper layer code (drivers, utilities, etc.) should leave this define set to
- * one and check the value returned for NumDmaEngines at runtime.
- */
-#ifndef MPI2_IOUNITPAGE5_DMAENGINE_ENTRIES
-#define MPI2_IOUNITPAGE5_DMAENGINE_ENTRIES      (1)
-#endif
-
-typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_5 {
-    MPI2_CONFIG_PAGE_HEADER Header;                            /* 0x00 */
-    U64                     RaidAcceleratorBufferBaseAddress;  /* 0x04 */
-    U64                     RaidAcceleratorBufferSize;         /* 0x0C */
-    U64                     RaidAcceleratorControlBaseAddress; /* 0x14 */
-    U8                      RAControlSize;                     /* 0x1C */
-    U8                      NumDmaEngines;                     /* 0x1D */
-    U8                      RAMinControlSize;                  /* 0x1E */
-    U8                      RAMaxControlSize;                  /* 0x1F */
-    U32                     Reserved1;                         /* 0x20 */
-    U32                     Reserved2;                         /* 0x24 */
-    U32                     Reserved3;                         /* 0x28 */
-    U32                     DmaEngineCapabilities
-                               [MPI2_IOUNITPAGE5_DMAENGINE_ENTRIES]; /* 0x2C */
-} MPI2_CONFIG_PAGE_IO_UNIT_5, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IO_UNIT_5,
-  Mpi2IOUnitPage5_t, MPI2_POINTER pMpi2IOUnitPage5_t;
-
-#define MPI2_IOUNITPAGE5_PAGEVERSION                    (0x00)
-
-/* defines for IO Unit Page 5 DmaEngineCapabilities field */
-#define MPI2_IOUNITPAGE5_DMA_CAP_MASK_MAX_REQUESTS      (0xFFFF0000)
-#define MPI2_IOUNITPAGE5_DMA_CAP_SHIFT_MAX_REQUESTS     (16)
-
-#define MPI2_IOUNITPAGE5_DMA_CAP_EEDP                   (0x0008)
-#define MPI2_IOUNITPAGE5_DMA_CAP_PARITY_GENERATION      (0x0004)
-#define MPI2_IOUNITPAGE5_DMA_CAP_HASHING                (0x0002)
-#define MPI2_IOUNITPAGE5_DMA_CAP_ENCRYPTION             (0x0001)
-
-
-/* IO Unit Page 6 */
-
-typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_6 {
-    MPI2_CONFIG_PAGE_HEADER Header;                                 /* 0x00 */
-    U16                     Flags;                                  /* 0x04 */
-    U8                      RAHostControlSize;                      /* 0x06 */
-    U8                      Reserved0;                              /* 0x07 */
-    U64                     RaidAcceleratorHostControlBaseAddress;  /* 0x08 */
-    U32                     Reserved1;                              /* 0x10 */
-    U32                     Reserved2;                              /* 0x14 */
-    U32                     Reserved3;                              /* 0x18 */
-} MPI2_CONFIG_PAGE_IO_UNIT_6, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IO_UNIT_6,
-  Mpi2IOUnitPage6_t, MPI2_POINTER pMpi2IOUnitPage6_t;
-
-#define MPI2_IOUNITPAGE6_PAGEVERSION                    (0x00)
-
-/* defines for IO Unit Page 6 Flags field */
-#define MPI2_IOUNITPAGE6_FLAGS_ENABLE_RAID_ACCELERATOR  (0x0001)
-
-
-/* IO Unit Page 7 */
-
-typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_7 {
-    MPI2_CONFIG_PAGE_HEADER Header;                                 /* 0x00 */
-    U16                     Reserved1;                              /* 0x04 */
-    U8                      PCIeWidth;                              /* 0x06 */
-    U8                      PCIeSpeed;                              /* 0x07 */
-    U32                     ProcessorState;                         /* 0x08 */
-    U32                     PowerManagementCapabilities;            /* 0x0C */
-    U16                     IOCTemperature;                         /* 0x10 */
-    U8                      IOCTemperatureUnits;                    /* 0x12 */
-    U8                      IOCSpeed;                               /* 0x13 */
-       U16                     BoardTemperature;                   /* 0x14 */
-       U8                      BoardTemperatureUnits;              /* 0x16 */
-       U8                      Reserved3;                          /* 0x17 */
-       U32                     Reserved4;                          /* 0x18 */
-       U32                     Reserved5;                          /* 0x1C */
-       U32                     Reserved6;                          /* 0x20 */
-       U32                     Reserved7;                          /* 0x24 */
-} MPI2_CONFIG_PAGE_IO_UNIT_7, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IO_UNIT_7,
-  Mpi2IOUnitPage7_t, MPI2_POINTER pMpi2IOUnitPage7_t;
-
-#define MPI2_IOUNITPAGE7_PAGEVERSION                    (0x04)
-
-/* defines for IO Unit Page 7 PCIeWidth field */
-#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X1              (0x01)
-#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X2              (0x02)
-#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X4              (0x04)
-#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X8              (0x08)
-
-/* defines for IO Unit Page 7 PCIeSpeed field */
-#define MPI2_IOUNITPAGE7_PCIE_SPEED_2_5_GBPS        (0x00)
-#define MPI2_IOUNITPAGE7_PCIE_SPEED_5_0_GBPS        (0x01)
-#define MPI2_IOUNITPAGE7_PCIE_SPEED_8_0_GBPS        (0x02)
-
-/* defines for IO Unit Page 7 ProcessorState field */
-#define MPI2_IOUNITPAGE7_PSTATE_MASK_SECOND         (0x0000000F)
-#define MPI2_IOUNITPAGE7_PSTATE_SHIFT_SECOND        (0)
-
-#define MPI2_IOUNITPAGE7_PSTATE_NOT_PRESENT         (0x00)
-#define MPI2_IOUNITPAGE7_PSTATE_DISABLED            (0x01)
-#define MPI2_IOUNITPAGE7_PSTATE_ENABLED             (0x02)
-
-/* defines for IO Unit Page 7 PowerManagementCapabilities field */
-#define MPI2_IOUNITPAGE7_PMCAP_12_5_PCT_IOCSPEED    (0x00000400)
-#define MPI2_IOUNITPAGE7_PMCAP_25_0_PCT_IOCSPEED    (0x00000200)
-#define MPI2_IOUNITPAGE7_PMCAP_50_0_PCT_IOCSPEED    (0x00000100)
-#define MPI2_IOUNITPAGE7_PMCAP_PCIE_WIDTH_CHANGE    (0x00000008) /* obsolete */
-#define MPI2_IOUNITPAGE7_PMCAP_PCIE_SPEED_CHANGE    (0x00000004) /* obsolete */
-
-/* defines for IO Unit Page 7 IOCTemperatureUnits field */
-#define MPI2_IOUNITPAGE7_IOC_TEMP_NOT_PRESENT       (0x00)
-#define MPI2_IOUNITPAGE7_IOC_TEMP_FAHRENHEIT        (0x01)
-#define MPI2_IOUNITPAGE7_IOC_TEMP_CELSIUS           (0x02)
-
-/* defines for IO Unit Page 7 IOCSpeed field */
-#define MPI2_IOUNITPAGE7_IOC_SPEED_FULL             (0x01)
-#define MPI2_IOUNITPAGE7_IOC_SPEED_HALF             (0x02)
-#define MPI2_IOUNITPAGE7_IOC_SPEED_QUARTER          (0x04)
-#define MPI2_IOUNITPAGE7_IOC_SPEED_EIGHTH           (0x08)
-
-/* defines for IO Unit Page 7 BoardTemperatureUnits field */
-#define MPI2_IOUNITPAGE7_BOARD_TEMP_NOT_PRESENT     (0x00)
-#define MPI2_IOUNITPAGE7_BOARD_TEMP_FAHRENHEIT      (0x01)
-#define MPI2_IOUNITPAGE7_BOARD_TEMP_CELSIUS         (0x02)
-
-/* IO Unit Page 8 */
-
-#define MPI2_IOUNIT8_NUM_THRESHOLDS     (4)
-
-typedef struct _MPI2_IOUNIT8_SENSOR {
-       U16                     Flags;                /* 0x00 */
-       U16                     Reserved1;            /* 0x02 */
-       U16
-               Threshold[MPI2_IOUNIT8_NUM_THRESHOLDS]; /* 0x04 */
-       U32                     Reserved2;            /* 0x0C */
-       U32                     Reserved3;            /* 0x10 */
-       U32                     Reserved4;            /* 0x14 */
-} MPI2_IOUNIT8_SENSOR, MPI2_POINTER PTR_MPI2_IOUNIT8_SENSOR,
-Mpi2IOUnit8Sensor_t, MPI2_POINTER pMpi2IOUnit8Sensor_t;
-
-/* defines for IO Unit Page 8 Sensor Flags field */
-#define MPI2_IOUNIT8_SENSOR_FLAGS_T3_ENABLE         (0x0008)
-#define MPI2_IOUNIT8_SENSOR_FLAGS_T2_ENABLE         (0x0004)
-#define MPI2_IOUNIT8_SENSOR_FLAGS_T1_ENABLE         (0x0002)
-#define MPI2_IOUNIT8_SENSOR_FLAGS_T0_ENABLE         (0x0001)
-
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check the value returned for NumSensors at runtime.
- */
-#ifndef MPI2_IOUNITPAGE8_SENSOR_ENTRIES
-#define MPI2_IOUNITPAGE8_SENSOR_ENTRIES     (1)
-#endif
-
-typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_8 {
-       MPI2_CONFIG_PAGE_HEADER Header;               /* 0x00 */
-       U32                     Reserved1;            /* 0x04 */
-       U32                     Reserved2;            /* 0x08 */
-       U8                      NumSensors;           /* 0x0C */
-       U8                      PollingInterval;      /* 0x0D */
-       U16                     Reserved3;            /* 0x0E */
-       MPI2_IOUNIT8_SENSOR
-                       Sensor[MPI2_IOUNITPAGE8_SENSOR_ENTRIES];/* 0x10 */
-} MPI2_CONFIG_PAGE_IO_UNIT_8, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IO_UNIT_8,
-Mpi2IOUnitPage8_t, MPI2_POINTER pMpi2IOUnitPage8_t;
-
-#define MPI2_IOUNITPAGE8_PAGEVERSION                    (0x00)
-
-
-/* IO Unit Page 9 */
-
-typedef struct _MPI2_IOUNIT9_SENSOR {
-       U16                     CurrentTemperature;     /* 0x00 */
-       U16                     Reserved1;              /* 0x02 */
-       U8                      Flags;                  /* 0x04 */
-       U8                      Reserved2;              /* 0x05 */
-       U16                     Reserved3;              /* 0x06 */
-       U32                     Reserved4;              /* 0x08 */
-       U32                     Reserved5;              /* 0x0C */
-} MPI2_IOUNIT9_SENSOR, MPI2_POINTER PTR_MPI2_IOUNIT9_SENSOR,
-Mpi2IOUnit9Sensor_t, MPI2_POINTER pMpi2IOUnit9Sensor_t;
-
-/* defines for IO Unit Page 9 Sensor Flags field */
-#define MPI2_IOUNIT9_SENSOR_FLAGS_TEMP_VALID        (0x01)
-
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check the value returned for NumSensors at runtime.
- */
-#ifndef MPI2_IOUNITPAGE9_SENSOR_ENTRIES
-#define MPI2_IOUNITPAGE9_SENSOR_ENTRIES     (1)
-#endif
-
-typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_9 {
-       MPI2_CONFIG_PAGE_HEADER Header;                /* 0x00 */
-       U32                     Reserved1;             /* 0x04 */
-       U32                     Reserved2;             /* 0x08 */
-       U8                      NumSensors;            /* 0x0C */
-       U8                      Reserved4;             /* 0x0D */
-       U16                     Reserved3;             /* 0x0E */
-       MPI2_IOUNIT9_SENSOR
-                       Sensor[MPI2_IOUNITPAGE9_SENSOR_ENTRIES];/* 0x10 */
-} MPI2_CONFIG_PAGE_IO_UNIT_9, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IO_UNIT_9,
-Mpi2IOUnitPage9_t, MPI2_POINTER pMpi2IOUnitPage9_t;
-
-#define MPI2_IOUNITPAGE9_PAGEVERSION                    (0x00)
-
-
-/* IO Unit Page 10 */
-
-typedef struct _MPI2_IOUNIT10_FUNCTION {
-       U8                      CreditPercent;      /* 0x00 */
-       U8                      Reserved1;          /* 0x01 */
-       U16                     Reserved2;          /* 0x02 */
-} MPI2_IOUNIT10_FUNCTION, MPI2_POINTER PTR_MPI2_IOUNIT10_FUNCTION,
-Mpi2IOUnit10Function_t, MPI2_POINTER pMpi2IOUnit10Function_t;
-
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check the value returned for NumFunctions at runtime.
- */
-#ifndef MPI2_IOUNITPAGE10_FUNCTION_ENTRIES
-#define MPI2_IOUNITPAGE10_FUNCTION_ENTRIES      (1)
-#endif
-
-typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_10 {
-       MPI2_CONFIG_PAGE_HEADER Header;                    /* 0x00 */
-       U8                      NumFunctions;             /* 0x04 */
-       U8                      Reserved1;              /* 0x05 */
-       U16                     Reserved2;              /* 0x06 */
-       U32                     Reserved3;              /* 0x08 */
-       U32                     Reserved4;              /* 0x0C */
-       MPI2_IOUNIT10_FUNCTION
-               Function[MPI2_IOUNITPAGE10_FUNCTION_ENTRIES];/* 0x10 */
-} MPI2_CONFIG_PAGE_IO_UNIT_10, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IO_UNIT_10,
-Mpi2IOUnitPage10_t, MPI2_POINTER pMpi2IOUnitPage10_t;
-
-#define MPI2_IOUNITPAGE10_PAGEVERSION                   (0x01)
-
-
-
-/****************************************************************************
-*   IOC Config Pages
-****************************************************************************/
-
-/* IOC Page 0 */
-
-typedef struct _MPI2_CONFIG_PAGE_IOC_0
-{
-    MPI2_CONFIG_PAGE_HEADER Header;                     /* 0x00 */
-    U32                     Reserved1;                  /* 0x04 */
-    U32                     Reserved2;                  /* 0x08 */
-    U16                     VendorID;                   /* 0x0C */
-    U16                     DeviceID;                   /* 0x0E */
-    U8                      RevisionID;                 /* 0x10 */
-    U8                      Reserved3;                  /* 0x11 */
-    U16                     Reserved4;                  /* 0x12 */
-    U32                     ClassCode;                  /* 0x14 */
-    U16                     SubsystemVendorID;          /* 0x18 */
-    U16                     SubsystemID;                /* 0x1A */
-} MPI2_CONFIG_PAGE_IOC_0, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IOC_0,
-  Mpi2IOCPage0_t, MPI2_POINTER pMpi2IOCPage0_t;
-
-#define MPI2_IOCPAGE0_PAGEVERSION                       (0x02)
-
-
-/* IOC Page 1 */
-
-typedef struct _MPI2_CONFIG_PAGE_IOC_1
-{
-    MPI2_CONFIG_PAGE_HEADER Header;                     /* 0x00 */
-    U32                     Flags;                      /* 0x04 */
-    U32                     CoalescingTimeout;          /* 0x08 */
-    U8                      CoalescingDepth;            /* 0x0C */
-    U8                      PCISlotNum;                 /* 0x0D */
-    U8                      PCIBusNum;                  /* 0x0E */
-    U8                      PCIDomainSegment;           /* 0x0F */
-    U32                     Reserved1;                  /* 0x10 */
-    U32                     Reserved2;                  /* 0x14 */
-} MPI2_CONFIG_PAGE_IOC_1, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IOC_1,
-  Mpi2IOCPage1_t, MPI2_POINTER pMpi2IOCPage1_t;
-
-#define MPI2_IOCPAGE1_PAGEVERSION                       (0x05)
-
-/* defines for IOC Page 1 Flags field */
-#define MPI2_IOCPAGE1_REPLY_COALESCING                  (0x00000001)
-
-#define MPI2_IOCPAGE1_PCISLOTNUM_UNKNOWN                (0xFF)
-#define MPI2_IOCPAGE1_PCIBUSNUM_UNKNOWN                 (0xFF)
-#define MPI2_IOCPAGE1_PCIDOMAIN_UNKNOWN                 (0xFF)
-
-/* IOC Page 6 */
-
-typedef struct _MPI2_CONFIG_PAGE_IOC_6
-{
-    MPI2_CONFIG_PAGE_HEADER Header;                         /* 0x00 */
-    U32                     CapabilitiesFlags;              /* 0x04 */
-    U8                      MaxDrivesRAID0;                 /* 0x08 */
-    U8                      MaxDrivesRAID1;                 /* 0x09 */
-    U8                      MaxDrivesRAID1E;                /* 0x0A */
-    U8                      MaxDrivesRAID10;                /* 0x0B */
-    U8                      MinDrivesRAID0;                 /* 0x0C */
-    U8                      MinDrivesRAID1;                 /* 0x0D */
-    U8                      MinDrivesRAID1E;                /* 0x0E */
-    U8                      MinDrivesRAID10;                /* 0x0F */
-    U32                     Reserved1;                      /* 0x10 */
-    U8                      MaxGlobalHotSpares;             /* 0x14 */
-    U8                      MaxPhysDisks;                   /* 0x15 */
-    U8                      MaxVolumes;                     /* 0x16 */
-    U8                      MaxConfigs;                     /* 0x17 */
-    U8                      MaxOCEDisks;                    /* 0x18 */
-    U8                      Reserved2;                      /* 0x19 */
-    U16                     Reserved3;                      /* 0x1A */
-    U32                     SupportedStripeSizeMapRAID0;    /* 0x1C */
-    U32                     SupportedStripeSizeMapRAID1E;   /* 0x20 */
-    U32                     SupportedStripeSizeMapRAID10;   /* 0x24 */
-    U32                     Reserved4;                      /* 0x28 */
-    U32                     Reserved5;                      /* 0x2C */
-    U16                     DefaultMetadataSize;            /* 0x30 */
-    U16                     Reserved6;                      /* 0x32 */
-    U16                     MaxBadBlockTableEntries;        /* 0x34 */
-    U16                     Reserved7;                      /* 0x36 */
-    U32                     IRNvsramVersion;                /* 0x38 */
-} MPI2_CONFIG_PAGE_IOC_6, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IOC_6,
-  Mpi2IOCPage6_t, MPI2_POINTER pMpi2IOCPage6_t;
-
-#define MPI2_IOCPAGE6_PAGEVERSION                       (0x05)
-
-/* defines for IOC Page 6 CapabilitiesFlags */
-#define MPI2_IOCPAGE6_CAP_FLAGS_4K_SECTORS_SUPPORT      (0x00000020)
-#define MPI2_IOCPAGE6_CAP_FLAGS_RAID10_SUPPORT          (0x00000010)
-#define MPI2_IOCPAGE6_CAP_FLAGS_RAID1_SUPPORT           (0x00000008)
-#define MPI2_IOCPAGE6_CAP_FLAGS_RAID1E_SUPPORT          (0x00000004)
-#define MPI2_IOCPAGE6_CAP_FLAGS_RAID0_SUPPORT           (0x00000002)
-#define MPI2_IOCPAGE6_CAP_FLAGS_GLOBAL_HOT_SPARE        (0x00000001)
-
-
-/* IOC Page 7 */
-
-#define MPI2_IOCPAGE7_EVENTMASK_WORDS       (4)
-
-typedef struct _MPI2_CONFIG_PAGE_IOC_7
-{
-    MPI2_CONFIG_PAGE_HEADER Header;                     /* 0x00 */
-    U32                     Reserved1;                  /* 0x04 */
-    U32                     EventMasks[MPI2_IOCPAGE7_EVENTMASK_WORDS];/* 0x08 */
-    U16                     SASBroadcastPrimitiveMasks; /* 0x18 */
-       U16                     SASNotifyPrimitiveMasks;    /* 0x1A */
-    U32                     Reserved3;                  /* 0x1C */
-} MPI2_CONFIG_PAGE_IOC_7, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IOC_7,
-  Mpi2IOCPage7_t, MPI2_POINTER pMpi2IOCPage7_t;
-
-#define MPI2_IOCPAGE7_PAGEVERSION                       (0x02)
-
-
-/* IOC Page 8 */
-
-typedef struct _MPI2_CONFIG_PAGE_IOC_8
-{
-    MPI2_CONFIG_PAGE_HEADER Header;                     /* 0x00 */
-    U8                      NumDevsPerEnclosure;        /* 0x04 */
-    U8                      Reserved1;                  /* 0x05 */
-    U16                     Reserved2;                  /* 0x06 */
-    U16                     MaxPersistentEntries;       /* 0x08 */
-    U16                     MaxNumPhysicalMappedIDs;    /* 0x0A */
-    U16                     Flags;                      /* 0x0C */
-    U16                     Reserved3;                  /* 0x0E */
-    U16                     IRVolumeMappingFlags;       /* 0x10 */
-    U16                     Reserved4;                  /* 0x12 */
-    U32                     Reserved5;                  /* 0x14 */
-} MPI2_CONFIG_PAGE_IOC_8, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IOC_8,
-  Mpi2IOCPage8_t, MPI2_POINTER pMpi2IOCPage8_t;
-
-#define MPI2_IOCPAGE8_PAGEVERSION                       (0x00)
-
-/* defines for IOC Page 8 Flags field */
-#define MPI2_IOCPAGE8_FLAGS_DA_START_SLOT_1             (0x00000020)
-#define MPI2_IOCPAGE8_FLAGS_RESERVED_TARGETID_0         (0x00000010)
-
-#define MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE           (0x0000000E)
-#define MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING  (0x00000000)
-#define MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING      (0x00000002)
-
-#define MPI2_IOCPAGE8_FLAGS_DISABLE_PERSISTENT_MAPPING  (0x00000001)
-#define MPI2_IOCPAGE8_FLAGS_ENABLE_PERSISTENT_MAPPING   (0x00000000)
-
-/* defines for IOC Page 8 IRVolumeMappingFlags */
-#define MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE  (0x00000003)
-#define MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING        (0x00000000)
-#define MPI2_IOCPAGE8_IRFLAGS_HIGH_VOLUME_MAPPING       (0x00000001)
-
-
-/****************************************************************************
-*   BIOS Config Pages
-****************************************************************************/
-
-/* BIOS Page 1 */
-
-typedef struct _MPI2_CONFIG_PAGE_BIOS_1
-{
-       MPI2_CONFIG_PAGE_HEADER Header;                     /* 0x00 */
-       U32                     BiosOptions;                /* 0x04 */
-       U32                     IOCSettings;                /* 0x08 */
-       U8                      SSUTimeout;                 /* 0x0C */
-       U8                      Reserved1;                  /* 0x0D */
-       U16                     Reserved2;                  /* 0x0E */
-       U32                     DeviceSettings;             /* 0x10 */
-       U16                     NumberOfDevices;            /* 0x14 */
-       U16                     UEFIVersion;                /* 0x16 */
-       U16                     IOTimeoutBlockDevicesNonRM; /* 0x18 */
-       U16                     IOTimeoutSequential;        /* 0x1A */
-       U16                     IOTimeoutOther;             /* 0x1C */
-       U16                     IOTimeoutBlockDevicesRM;    /* 0x1E */
-} MPI2_CONFIG_PAGE_BIOS_1, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_BIOS_1,
-  Mpi2BiosPage1_t, MPI2_POINTER pMpi2BiosPage1_t;
-
-#define MPI2_BIOSPAGE1_PAGEVERSION                      (0x07)
-
-/* values for BIOS Page 1 BiosOptions field */
-#define MPI2_BIOSPAGE1_OPTIONS_PNS_MASK                        (0x00003800)
-#define MPI2_BIOSPAGE1_OPTIONS_PNS_PBDHL                       (0x00000000)
-#define MPI2_BIOSPAGE1_OPTIONS_PNS_ENCSLOSURE                  (0x00000800)
-#define MPI2_BIOSPAGE1_OPTIONS_PNS_LWWID                       (0x00001000)
-#define MPI2_BIOSPAGE1_OPTIONS_PNS_PSENS                       (0x00001800)
-#define MPI2_BIOSPAGE1_OPTIONS_PNS_ESPHY                       (0x00002000)
-
-#define MPI2_BIOSPAGE1_OPTIONS_X86_DISABLE_BIOS                 (0x00000400)
-
-#define MPI2_BIOSPAGE1_OPTIONS_MASK_REGISTRATION_UEFI_BSD       (0x00000300)
-#define MPI2_BIOSPAGE1_OPTIONS_USE_BIT0_REGISTRATION_UEFI_BSD   (0x00000000)
-#define MPI2_BIOSPAGE1_OPTIONS_FULL_REGISTRATION_UEFI_BSD       (0x00000100)
-#define MPI2_BIOSPAGE1_OPTIONS_ADAPTER_REGISTRATION_UEFI_BSD    (0x00000200)
-#define MPI2_BIOSPAGE1_OPTIONS_DISABLE_REGISTRATION_UEFI_BSD    (0x00000300)
-
-#define MPI2_BIOSPAGE1_OPTIONS_MASK_OEM_ID                  (0x000000F0)
-#define MPI2_BIOSPAGE1_OPTIONS_LSI_OEM_ID                   (0x00000000)
-
-#define MPI2_BIOSPAGE1_OPTIONS_MASK_UEFI_HII_REGISTRATION   (0x00000006)
-#define MPI2_BIOSPAGE1_OPTIONS_ENABLE_UEFI_HII              (0x00000000)
-#define MPI2_BIOSPAGE1_OPTIONS_DISABLE_UEFI_HII             (0x00000002)
-#define MPI2_BIOSPAGE1_OPTIONS_VERSION_CHECK_UEFI_HII       (0x00000004)
-
-#define MPI2_BIOSPAGE1_OPTIONS_DISABLE_BIOS                 (0x00000001)
-
-/* values for BIOS Page 1 IOCSettings field */
-#define MPI2_BIOSPAGE1_IOCSET_MASK_BOOT_PREFERENCE      (0x00030000)
-#define MPI2_BIOSPAGE1_IOCSET_ENCLOSURE_SLOT_BOOT       (0x00000000)
-#define MPI2_BIOSPAGE1_IOCSET_SAS_ADDRESS_BOOT          (0x00010000)
-
-#define MPI2_BIOSPAGE1_IOCSET_MASK_RM_SETTING           (0x000000C0)
-#define MPI2_BIOSPAGE1_IOCSET_NONE_RM_SETTING           (0x00000000)
-#define MPI2_BIOSPAGE1_IOCSET_BOOT_RM_SETTING           (0x00000040)
-#define MPI2_BIOSPAGE1_IOCSET_MEDIA_RM_SETTING          (0x00000080)
-
-#define MPI2_BIOSPAGE1_IOCSET_MASK_ADAPTER_SUPPORT      (0x00000030)
-#define MPI2_BIOSPAGE1_IOCSET_NO_SUPPORT                (0x00000000)
-#define MPI2_BIOSPAGE1_IOCSET_BIOS_SUPPORT              (0x00000010)
-#define MPI2_BIOSPAGE1_IOCSET_OS_SUPPORT                (0x00000020)
-#define MPI2_BIOSPAGE1_IOCSET_ALL_SUPPORT               (0x00000030)
-
-#define MPI2_BIOSPAGE1_IOCSET_ALTERNATE_CHS             (0x00000008)
-
-/* values for BIOS Page 1 DeviceSettings field */
-#define MPI2_BIOSPAGE1_DEVSET_DISABLE_SMART_POLLING     (0x00000010)
-#define MPI2_BIOSPAGE1_DEVSET_DISABLE_SEQ_LUN           (0x00000008)
-#define MPI2_BIOSPAGE1_DEVSET_DISABLE_RM_LUN            (0x00000004)
-#define MPI2_BIOSPAGE1_DEVSET_DISABLE_NON_RM_LUN        (0x00000002)
-#define MPI2_BIOSPAGE1_DEVSET_DISABLE_OTHER_LUN         (0x00000001)
-
-/* defines for BIOS Page 1 UEFIVersion field */
-#define MPI2_BIOSPAGE1_UEFI_VER_MAJOR_MASK              (0xFF00)
-#define MPI2_BIOSPAGE1_UEFI_VER_MAJOR_SHIFT             (8)
-#define MPI2_BIOSPAGE1_UEFI_VER_MINOR_MASK              (0x00FF)
-#define MPI2_BIOSPAGE1_UEFI_VER_MINOR_SHIFT             (0)
-
-
-
-/* BIOS Page 2 */
-
-typedef struct _MPI2_BOOT_DEVICE_ADAPTER_ORDER
-{
-    U32         Reserved1;                              /* 0x00 */
-    U32         Reserved2;                              /* 0x04 */
-    U32         Reserved3;                              /* 0x08 */
-    U32         Reserved4;                              /* 0x0C */
-    U32         Reserved5;                              /* 0x10 */
-    U32         Reserved6;                              /* 0x14 */
-} MPI2_BOOT_DEVICE_ADAPTER_ORDER,
-  MPI2_POINTER PTR_MPI2_BOOT_DEVICE_ADAPTER_ORDER,
-  Mpi2BootDeviceAdapterOrder_t, MPI2_POINTER pMpi2BootDeviceAdapterOrder_t;
-
-typedef struct _MPI2_BOOT_DEVICE_SAS_WWID
-{
-    U64         SASAddress;                             /* 0x00 */
-    U8          LUN[8];                                 /* 0x08 */
-    U32         Reserved1;                              /* 0x10 */
-    U32         Reserved2;                              /* 0x14 */
-} MPI2_BOOT_DEVICE_SAS_WWID, MPI2_POINTER PTR_MPI2_BOOT_DEVICE_SAS_WWID,
-  Mpi2BootDeviceSasWwid_t, MPI2_POINTER pMpi2BootDeviceSasWwid_t;
-
-typedef struct _MPI2_BOOT_DEVICE_ENCLOSURE_SLOT
-{
-    U64         EnclosureLogicalID;                     /* 0x00 */
-    U32         Reserved1;                              /* 0x08 */
-    U32         Reserved2;                              /* 0x0C */
-    U16         SlotNumber;                             /* 0x10 */
-    U16         Reserved3;                              /* 0x12 */
-    U32         Reserved4;                              /* 0x14 */
-} MPI2_BOOT_DEVICE_ENCLOSURE_SLOT,
-  MPI2_POINTER PTR_MPI2_BOOT_DEVICE_ENCLOSURE_SLOT,
-  Mpi2BootDeviceEnclosureSlot_t, MPI2_POINTER pMpi2BootDeviceEnclosureSlot_t;
-
-typedef struct _MPI2_BOOT_DEVICE_DEVICE_NAME
-{
-    U64         DeviceName;                             /* 0x00 */
-    U8          LUN[8];                                 /* 0x08 */
-    U32         Reserved1;                              /* 0x10 */
-    U32         Reserved2;                              /* 0x14 */
-} MPI2_BOOT_DEVICE_DEVICE_NAME, MPI2_POINTER PTR_MPI2_BOOT_DEVICE_DEVICE_NAME,
-  Mpi2BootDeviceDeviceName_t, MPI2_POINTER pMpi2BootDeviceDeviceName_t;
-
-typedef union _MPI2_MPI2_BIOSPAGE2_BOOT_DEVICE
-{
-    MPI2_BOOT_DEVICE_ADAPTER_ORDER  AdapterOrder;
-    MPI2_BOOT_DEVICE_SAS_WWID       SasWwid;
-    MPI2_BOOT_DEVICE_ENCLOSURE_SLOT EnclosureSlot;
-    MPI2_BOOT_DEVICE_DEVICE_NAME    DeviceName;
-} MPI2_BIOSPAGE2_BOOT_DEVICE, MPI2_POINTER PTR_MPI2_BIOSPAGE2_BOOT_DEVICE,
-  Mpi2BiosPage2BootDevice_t, MPI2_POINTER pMpi2BiosPage2BootDevice_t;
-
-typedef struct _MPI2_CONFIG_PAGE_BIOS_2
-{
-    MPI2_CONFIG_PAGE_HEADER     Header;                 /* 0x00 */
-    U32                         Reserved1;              /* 0x04 */
-    U32                         Reserved2;              /* 0x08 */
-    U32                         Reserved3;              /* 0x0C */
-    U32                         Reserved4;              /* 0x10 */
-    U32                         Reserved5;              /* 0x14 */
-    U32                         Reserved6;              /* 0x18 */
-    U8                          ReqBootDeviceForm;      /* 0x1C */
-    U8                          Reserved7;              /* 0x1D */
-    U16                         Reserved8;              /* 0x1E */
-    MPI2_BIOSPAGE2_BOOT_DEVICE  RequestedBootDevice;    /* 0x20 */
-    U8                          ReqAltBootDeviceForm;   /* 0x38 */
-    U8                          Reserved9;              /* 0x39 */
-    U16                         Reserved10;             /* 0x3A */
-    MPI2_BIOSPAGE2_BOOT_DEVICE  RequestedAltBootDevice; /* 0x3C */
-    U8                          CurrentBootDeviceForm;  /* 0x58 */
-    U8                          Reserved11;             /* 0x59 */
-    U16                         Reserved12;             /* 0x5A */
-    MPI2_BIOSPAGE2_BOOT_DEVICE  CurrentBootDevice;      /* 0x58 */
-} MPI2_CONFIG_PAGE_BIOS_2, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_BIOS_2,
-  Mpi2BiosPage2_t, MPI2_POINTER pMpi2BiosPage2_t;
-
-#define MPI2_BIOSPAGE2_PAGEVERSION                      (0x04)
-
-/* values for BIOS Page 2 BootDeviceForm fields */
-#define MPI2_BIOSPAGE2_FORM_MASK                        (0x0F)
-#define MPI2_BIOSPAGE2_FORM_NO_DEVICE_SPECIFIED         (0x00)
-#define MPI2_BIOSPAGE2_FORM_SAS_WWID                    (0x05)
-#define MPI2_BIOSPAGE2_FORM_ENCLOSURE_SLOT              (0x06)
-#define MPI2_BIOSPAGE2_FORM_DEVICE_NAME                 (0x07)
-
-
-/* BIOS Page 3 */
-
-typedef struct _MPI2_ADAPTER_INFO
-{
-    U8      PciBusNumber;                               /* 0x00 */
-    U8      PciDeviceAndFunctionNumber;                 /* 0x01 */
-    U16     AdapterFlags;                               /* 0x02 */
-} MPI2_ADAPTER_INFO, MPI2_POINTER PTR_MPI2_ADAPTER_INFO,
-  Mpi2AdapterInfo_t, MPI2_POINTER pMpi2AdapterInfo_t;
-
-#define MPI2_ADAPTER_INFO_FLAGS_EMBEDDED                (0x0001)
-#define MPI2_ADAPTER_INFO_FLAGS_INIT_STATUS             (0x0002)
-
-typedef struct _MPI2_CONFIG_PAGE_BIOS_3
-{
-    MPI2_CONFIG_PAGE_HEADER Header;                     /* 0x00 */
-    U32                     GlobalFlags;                /* 0x04 */
-    U32                     BiosVersion;                /* 0x08 */
-    MPI2_ADAPTER_INFO       AdapterOrder[4];            /* 0x0C */
-    U32                     Reserved1;                  /* 0x1C */
-} MPI2_CONFIG_PAGE_BIOS_3, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_BIOS_3,
-  Mpi2BiosPage3_t, MPI2_POINTER pMpi2BiosPage3_t;
-
-#define MPI2_BIOSPAGE3_PAGEVERSION                      (0x00)
-
-/* values for BIOS Page 3 GlobalFlags */
-#define MPI2_BIOSPAGE3_FLAGS_PAUSE_ON_ERROR             (0x00000002)
-#define MPI2_BIOSPAGE3_FLAGS_VERBOSE_ENABLE             (0x00000004)
-#define MPI2_BIOSPAGE3_FLAGS_HOOK_INT_40_DISABLE        (0x00000010)
-
-#define MPI2_BIOSPAGE3_FLAGS_DEV_LIST_DISPLAY_MASK      (0x000000E0)
-#define MPI2_BIOSPAGE3_FLAGS_INSTALLED_DEV_DISPLAY      (0x00000000)
-#define MPI2_BIOSPAGE3_FLAGS_ADAPTER_DISPLAY            (0x00000020)
-#define MPI2_BIOSPAGE3_FLAGS_ADAPTER_DEV_DISPLAY        (0x00000040)
-
-
-/* BIOS Page 4 */
-
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check the value returned for NumPhys at runtime.
- */
-#ifndef MPI2_BIOS_PAGE_4_PHY_ENTRIES
-#define MPI2_BIOS_PAGE_4_PHY_ENTRIES        (1)
-#endif
-
-typedef struct _MPI2_BIOS4_ENTRY
-{
-    U64                     ReassignmentWWID;       /* 0x00 */
-    U64                     ReassignmentDeviceName; /* 0x08 */
-} MPI2_BIOS4_ENTRY, MPI2_POINTER PTR_MPI2_BIOS4_ENTRY,
-  Mpi2MBios4Entry_t, MPI2_POINTER pMpi2Bios4Entry_t;
-
-typedef struct _MPI2_CONFIG_PAGE_BIOS_4
-{
-    MPI2_CONFIG_PAGE_HEADER Header;                             /* 0x00 */
-    U8                      NumPhys;                            /* 0x04 */
-    U8                      Reserved1;                          /* 0x05 */
-    U16                     Reserved2;                          /* 0x06 */
-    MPI2_BIOS4_ENTRY        Phy[MPI2_BIOS_PAGE_4_PHY_ENTRIES];  /* 0x08 */
-} MPI2_CONFIG_PAGE_BIOS_4, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_BIOS_4,
-  Mpi2BiosPage4_t, MPI2_POINTER pMpi2BiosPage4_t;
-
-#define MPI2_BIOSPAGE4_PAGEVERSION                      (0x01)
-
-
-/****************************************************************************
-*   RAID Volume Config Pages
-****************************************************************************/
-
-/* RAID Volume Page 0 */
-
-typedef struct _MPI2_RAIDVOL0_PHYS_DISK
-{
-    U8                      RAIDSetNum;                 /* 0x00 */
-    U8                      PhysDiskMap;                /* 0x01 */
-    U8                      PhysDiskNum;                /* 0x02 */
-    U8                      Reserved;                   /* 0x03 */
-} MPI2_RAIDVOL0_PHYS_DISK, MPI2_POINTER PTR_MPI2_RAIDVOL0_PHYS_DISK,
-  Mpi2RaidVol0PhysDisk_t, MPI2_POINTER pMpi2RaidVol0PhysDisk_t;
-
-/* defines for the PhysDiskMap field */
-#define MPI2_RAIDVOL0_PHYSDISK_PRIMARY                  (0x01)
-#define MPI2_RAIDVOL0_PHYSDISK_SECONDARY                (0x02)
-
-typedef struct _MPI2_RAIDVOL0_SETTINGS
-{
-    U16                     Settings;                   /* 0x00 */
-    U8                      HotSparePool;               /* 0x01 */
-    U8                      Reserved;                   /* 0x02 */
-} MPI2_RAIDVOL0_SETTINGS, MPI2_POINTER PTR_MPI2_RAIDVOL0_SETTINGS,
-  Mpi2RaidVol0Settings_t, MPI2_POINTER pMpi2RaidVol0Settings_t;
-
-/* RAID Volume Page 0 HotSparePool defines, also used in RAID Physical Disk */
-#define MPI2_RAID_HOT_SPARE_POOL_0                      (0x01)
-#define MPI2_RAID_HOT_SPARE_POOL_1                      (0x02)
-#define MPI2_RAID_HOT_SPARE_POOL_2                      (0x04)
-#define MPI2_RAID_HOT_SPARE_POOL_3                      (0x08)
-#define MPI2_RAID_HOT_SPARE_POOL_4                      (0x10)
-#define MPI2_RAID_HOT_SPARE_POOL_5                      (0x20)
-#define MPI2_RAID_HOT_SPARE_POOL_6                      (0x40)
-#define MPI2_RAID_HOT_SPARE_POOL_7                      (0x80)
-
-/* RAID Volume Page 0 VolumeSettings defines */
-#define MPI2_RAIDVOL0_SETTING_USE_PRODUCT_ID_SUFFIX     (0x0008)
-#define MPI2_RAIDVOL0_SETTING_AUTO_CONFIG_HSWAP_DISABLE (0x0004)
-
-#define MPI2_RAIDVOL0_SETTING_MASK_WRITE_CACHING        (0x0003)
-#define MPI2_RAIDVOL0_SETTING_UNCHANGED                 (0x0000)
-#define MPI2_RAIDVOL0_SETTING_DISABLE_WRITE_CACHING     (0x0001)
-#define MPI2_RAIDVOL0_SETTING_ENABLE_WRITE_CACHING      (0x0002)
-
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check the value returned for NumPhysDisks at runtime.
- */
-#ifndef MPI2_RAID_VOL_PAGE_0_PHYSDISK_MAX
-#define MPI2_RAID_VOL_PAGE_0_PHYSDISK_MAX       (1)
-#endif
-
-typedef struct _MPI2_CONFIG_PAGE_RAID_VOL_0
-{
-    MPI2_CONFIG_PAGE_HEADER Header;                     /* 0x00 */
-    U16                     DevHandle;                  /* 0x04 */
-    U8                      VolumeState;                /* 0x06 */
-    U8                      VolumeType;                 /* 0x07 */
-    U32                     VolumeStatusFlags;          /* 0x08 */
-    MPI2_RAIDVOL0_SETTINGS  VolumeSettings;             /* 0x0C */
-    U64                     MaxLBA;                     /* 0x10 */
-    U32                     StripeSize;                 /* 0x18 */
-    U16                     BlockSize;                  /* 0x1C */
-    U16                     Reserved1;                  /* 0x1E */
-    U8                      SupportedPhysDisks;         /* 0x20 */
-    U8                      ResyncRate;                 /* 0x21 */
-    U16                     DataScrubDuration;          /* 0x22 */
-    U8                      NumPhysDisks;               /* 0x24 */
-    U8                      Reserved2;                  /* 0x25 */
-    U8                      Reserved3;                  /* 0x26 */
-    U8                      InactiveStatus;             /* 0x27 */
-    MPI2_RAIDVOL0_PHYS_DISK PhysDisk[MPI2_RAID_VOL_PAGE_0_PHYSDISK_MAX]; /* 0x28 */
-} MPI2_CONFIG_PAGE_RAID_VOL_0, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_RAID_VOL_0,
-  Mpi2RaidVolPage0_t, MPI2_POINTER pMpi2RaidVolPage0_t;
-
-#define MPI2_RAIDVOLPAGE0_PAGEVERSION           (0x0A)
-
-/* values for RAID VolumeState */
-#define MPI2_RAID_VOL_STATE_MISSING                         (0x00)
-#define MPI2_RAID_VOL_STATE_FAILED                          (0x01)
-#define MPI2_RAID_VOL_STATE_INITIALIZING                    (0x02)
-#define MPI2_RAID_VOL_STATE_ONLINE                          (0x03)
-#define MPI2_RAID_VOL_STATE_DEGRADED                        (0x04)
-#define MPI2_RAID_VOL_STATE_OPTIMAL                         (0x05)
-
-/* values for RAID VolumeType */
-#define MPI2_RAID_VOL_TYPE_RAID0                            (0x00)
-#define MPI2_RAID_VOL_TYPE_RAID1E                           (0x01)
-#define MPI2_RAID_VOL_TYPE_RAID1                            (0x02)
-#define MPI2_RAID_VOL_TYPE_RAID10                           (0x05)
-#define MPI2_RAID_VOL_TYPE_UNKNOWN                          (0xFF)
-
-/* values for RAID Volume Page 0 VolumeStatusFlags field */
-#define MPI2_RAIDVOL0_STATUS_FLAG_PENDING_RESYNC            (0x02000000)
-#define MPI2_RAIDVOL0_STATUS_FLAG_BACKG_INIT_PENDING        (0x01000000)
-#define MPI2_RAIDVOL0_STATUS_FLAG_MDC_PENDING               (0x00800000)
-#define MPI2_RAIDVOL0_STATUS_FLAG_USER_CONSIST_PENDING      (0x00400000)
-#define MPI2_RAIDVOL0_STATUS_FLAG_MAKE_DATA_CONSISTENT      (0x00200000)
-#define MPI2_RAIDVOL0_STATUS_FLAG_DATA_SCRUB                (0x00100000)
-#define MPI2_RAIDVOL0_STATUS_FLAG_CONSISTENCY_CHECK         (0x00080000)
-#define MPI2_RAIDVOL0_STATUS_FLAG_CAPACITY_EXPANSION        (0x00040000)
-#define MPI2_RAIDVOL0_STATUS_FLAG_BACKGROUND_INIT           (0x00020000)
-#define MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS        (0x00010000)
-#define MPI2_RAIDVOL0_STATUS_FLAG_VOL_NOT_CONSISTENT        (0x00000080)
-#define MPI2_RAIDVOL0_STATUS_FLAG_OCE_ALLOWED               (0x00000040)
-#define MPI2_RAIDVOL0_STATUS_FLAG_BGI_COMPLETE              (0x00000020)
-#define MPI2_RAIDVOL0_STATUS_FLAG_1E_OFFSET_MIRROR          (0x00000000)
-#define MPI2_RAIDVOL0_STATUS_FLAG_1E_ADJACENT_MIRROR        (0x00000010)
-#define MPI2_RAIDVOL0_STATUS_FLAG_BAD_BLOCK_TABLE_FULL      (0x00000008)
-#define MPI2_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE           (0x00000004)
-#define MPI2_RAIDVOL0_STATUS_FLAG_QUIESCED                  (0x00000002)
-#define MPI2_RAIDVOL0_STATUS_FLAG_ENABLED                   (0x00000001)
-
-/* values for RAID Volume Page 0 SupportedPhysDisks field */
-#define MPI2_RAIDVOL0_SUPPORT_SOLID_STATE_DISKS             (0x08)
-#define MPI2_RAIDVOL0_SUPPORT_HARD_DISKS                    (0x04)
-#define MPI2_RAIDVOL0_SUPPORT_SAS_PROTOCOL                  (0x02)
-#define MPI2_RAIDVOL0_SUPPORT_SATA_PROTOCOL                 (0x01)
-
-/* values for RAID Volume Page 0 InactiveStatus field */
-#define MPI2_RAIDVOLPAGE0_UNKNOWN_INACTIVE                  (0x00)
-#define MPI2_RAIDVOLPAGE0_STALE_METADATA_INACTIVE           (0x01)
-#define MPI2_RAIDVOLPAGE0_FOREIGN_VOLUME_INACTIVE           (0x02)
-#define MPI2_RAIDVOLPAGE0_INSUFFICIENT_RESOURCE_INACTIVE    (0x03)
-#define MPI2_RAIDVOLPAGE0_CLONE_VOLUME_INACTIVE             (0x04)
-#define MPI2_RAIDVOLPAGE0_INSUFFICIENT_METADATA_INACTIVE    (0x05)
-#define MPI2_RAIDVOLPAGE0_PREVIOUSLY_DELETED                (0x06)
-
-
-/* RAID Volume Page 1 */
-
-typedef struct _MPI2_CONFIG_PAGE_RAID_VOL_1
-{
-    MPI2_CONFIG_PAGE_HEADER Header;                     /* 0x00 */
-    U16                     DevHandle;                  /* 0x04 */
-    U16                     Reserved0;                  /* 0x06 */
-    U8                      GUID[24];                   /* 0x08 */
-    U8                      Name[16];                   /* 0x20 */
-    U64                     WWID;                       /* 0x30 */
-    U32                     Reserved1;                  /* 0x38 */
-    U32                     Reserved2;                  /* 0x3C */
-} MPI2_CONFIG_PAGE_RAID_VOL_1, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_RAID_VOL_1,
-  Mpi2RaidVolPage1_t, MPI2_POINTER pMpi2RaidVolPage1_t;
-
-#define MPI2_RAIDVOLPAGE1_PAGEVERSION           (0x03)
-
-
-/****************************************************************************
-*   RAID Physical Disk Config Pages
-****************************************************************************/
-
-/* RAID Physical Disk Page 0 */
-
-typedef struct _MPI2_RAIDPHYSDISK0_SETTINGS
-{
-    U16                     Reserved1;                  /* 0x00 */
-    U8                      HotSparePool;               /* 0x02 */
-    U8                      Reserved2;                  /* 0x03 */
-} MPI2_RAIDPHYSDISK0_SETTINGS, MPI2_POINTER PTR_MPI2_RAIDPHYSDISK0_SETTINGS,
-  Mpi2RaidPhysDisk0Settings_t, MPI2_POINTER pMpi2RaidPhysDisk0Settings_t;
-
-/* use MPI2_RAID_HOT_SPARE_POOL_ defines for the HotSparePool field */
-
-typedef struct _MPI2_RAIDPHYSDISK0_INQUIRY_DATA
-{
-    U8                      VendorID[8];                /* 0x00 */
-    U8                      ProductID[16];              /* 0x08 */
-    U8                      ProductRevLevel[4];         /* 0x18 */
-    U8                      SerialNum[32];              /* 0x1C */
-} MPI2_RAIDPHYSDISK0_INQUIRY_DATA,
-  MPI2_POINTER PTR_MPI2_RAIDPHYSDISK0_INQUIRY_DATA,
-  Mpi2RaidPhysDisk0InquiryData_t, MPI2_POINTER pMpi2RaidPhysDisk0InquiryData_t;
-
-typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_0
-{
-    MPI2_CONFIG_PAGE_HEADER         Header;                     /* 0x00 */
-    U16                             DevHandle;                  /* 0x04 */
-    U8                              Reserved1;                  /* 0x06 */
-    U8                              PhysDiskNum;                /* 0x07 */
-    MPI2_RAIDPHYSDISK0_SETTINGS     PhysDiskSettings;           /* 0x08 */
-    U32                             Reserved2;                  /* 0x0C */
-    MPI2_RAIDPHYSDISK0_INQUIRY_DATA InquiryData;                /* 0x10 */
-    U32                             Reserved3;                  /* 0x4C */
-    U8                              PhysDiskState;              /* 0x50 */
-    U8                              OfflineReason;              /* 0x51 */
-    U8                              IncompatibleReason;         /* 0x52 */
-    U8                              PhysDiskAttributes;         /* 0x53 */
-    U32                             PhysDiskStatusFlags;        /* 0x54 */
-    U64                             DeviceMaxLBA;               /* 0x58 */
-    U64                             HostMaxLBA;                 /* 0x60 */
-    U64                             CoercedMaxLBA;              /* 0x68 */
-    U16                             BlockSize;                  /* 0x70 */
-    U16                             Reserved5;                  /* 0x72 */
-    U32                             Reserved6;                  /* 0x74 */
-} MPI2_CONFIG_PAGE_RD_PDISK_0,
-  MPI2_POINTER PTR_MPI2_CONFIG_PAGE_RD_PDISK_0,
-  Mpi2RaidPhysDiskPage0_t, MPI2_POINTER pMpi2RaidPhysDiskPage0_t;
-
-#define MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION          (0x05)
-
-/* PhysDiskState defines */
-#define MPI2_RAID_PD_STATE_NOT_CONFIGURED               (0x00)
-#define MPI2_RAID_PD_STATE_NOT_COMPATIBLE               (0x01)
-#define MPI2_RAID_PD_STATE_OFFLINE                      (0x02)
-#define MPI2_RAID_PD_STATE_ONLINE                       (0x03)
-#define MPI2_RAID_PD_STATE_HOT_SPARE                    (0x04)
-#define MPI2_RAID_PD_STATE_DEGRADED                     (0x05)
-#define MPI2_RAID_PD_STATE_REBUILDING                   (0x06)
-#define MPI2_RAID_PD_STATE_OPTIMAL                      (0x07)
-
-/* OfflineReason defines */
-#define MPI2_PHYSDISK0_ONLINE                           (0x00)
-#define MPI2_PHYSDISK0_OFFLINE_MISSING                  (0x01)
-#define MPI2_PHYSDISK0_OFFLINE_FAILED                   (0x03)
-#define MPI2_PHYSDISK0_OFFLINE_INITIALIZING             (0x04)
-#define MPI2_PHYSDISK0_OFFLINE_REQUESTED                (0x05)
-#define MPI2_PHYSDISK0_OFFLINE_FAILED_REQUESTED         (0x06)
-#define MPI2_PHYSDISK0_OFFLINE_OTHER                    (0xFF)
-
-/* IncompatibleReason defines */
-#define MPI2_PHYSDISK0_COMPATIBLE                       (0x00)
-#define MPI2_PHYSDISK0_INCOMPATIBLE_PROTOCOL            (0x01)
-#define MPI2_PHYSDISK0_INCOMPATIBLE_BLOCKSIZE           (0x02)
-#define MPI2_PHYSDISK0_INCOMPATIBLE_MAX_LBA             (0x03)
-#define MPI2_PHYSDISK0_INCOMPATIBLE_SATA_EXTENDED_CMD   (0x04)
-#define MPI2_PHYSDISK0_INCOMPATIBLE_REMOVEABLE_MEDIA    (0x05)
-#define MPI2_PHYSDISK0_INCOMPATIBLE_MEDIA_TYPE          (0x06)
-#define MPI2_PHYSDISK0_INCOMPATIBLE_UNKNOWN             (0xFF)
-
-/* PhysDiskAttributes defines */
-#define MPI2_PHYSDISK0_ATTRIB_MEDIA_MASK                (0x0C)
-#define MPI2_PHYSDISK0_ATTRIB_SOLID_STATE_DRIVE         (0x08)
-#define MPI2_PHYSDISK0_ATTRIB_HARD_DISK_DRIVE           (0x04)
-
-#define MPI2_PHYSDISK0_ATTRIB_PROTOCOL_MASK             (0x03)
-#define MPI2_PHYSDISK0_ATTRIB_SAS_PROTOCOL              (0x02)
-#define MPI2_PHYSDISK0_ATTRIB_SATA_PROTOCOL             (0x01)
-
-/* PhysDiskStatusFlags defines */
-#define MPI2_PHYSDISK0_STATUS_FLAG_NOT_CERTIFIED        (0x00000040)
-#define MPI2_PHYSDISK0_STATUS_FLAG_OCE_TARGET           (0x00000020)
-#define MPI2_PHYSDISK0_STATUS_FLAG_WRITE_CACHE_ENABLED  (0x00000010)
-#define MPI2_PHYSDISK0_STATUS_FLAG_OPTIMAL_PREVIOUS     (0x00000000)
-#define MPI2_PHYSDISK0_STATUS_FLAG_NOT_OPTIMAL_PREVIOUS (0x00000008)
-#define MPI2_PHYSDISK0_STATUS_FLAG_INACTIVE_VOLUME      (0x00000004)
-#define MPI2_PHYSDISK0_STATUS_FLAG_QUIESCED             (0x00000002)
-#define MPI2_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC          (0x00000001)
-
-
-/* RAID Physical Disk Page 1 */
-
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check the value returned for NumPhysDiskPaths at runtime.
- */
-#ifndef MPI2_RAID_PHYS_DISK1_PATH_MAX
-#define MPI2_RAID_PHYS_DISK1_PATH_MAX   (1)
-#endif
-
-typedef struct _MPI2_RAIDPHYSDISK1_PATH
-{
-    U16             DevHandle;          /* 0x00 */
-    U16             Reserved1;          /* 0x02 */
-    U64             WWID;               /* 0x04 */
-    U64             OwnerWWID;          /* 0x0C */
-    U8              OwnerIdentifier;    /* 0x14 */
-    U8              Reserved2;          /* 0x15 */
-    U16             Flags;              /* 0x16 */
-} MPI2_RAIDPHYSDISK1_PATH, MPI2_POINTER PTR_MPI2_RAIDPHYSDISK1_PATH,
-  Mpi2RaidPhysDisk1Path_t, MPI2_POINTER pMpi2RaidPhysDisk1Path_t;
-
-/* RAID Physical Disk Page 1 Physical Disk Path Flags field defines */
-#define MPI2_RAID_PHYSDISK1_FLAG_PRIMARY        (0x0004)
-#define MPI2_RAID_PHYSDISK1_FLAG_BROKEN         (0x0002)
-#define MPI2_RAID_PHYSDISK1_FLAG_INVALID        (0x0001)
-
-typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_1
-{
-    MPI2_CONFIG_PAGE_HEADER         Header;                     /* 0x00 */
-    U8                              NumPhysDiskPaths;           /* 0x04 */
-    U8                              PhysDiskNum;                /* 0x05 */
-    U16                             Reserved1;                  /* 0x06 */
-    U32                             Reserved2;                  /* 0x08 */
-    MPI2_RAIDPHYSDISK1_PATH         PhysicalDiskPath[MPI2_RAID_PHYS_DISK1_PATH_MAX];/* 0x0C */
-} MPI2_CONFIG_PAGE_RD_PDISK_1,
-  MPI2_POINTER PTR_MPI2_CONFIG_PAGE_RD_PDISK_1,
-  Mpi2RaidPhysDiskPage1_t, MPI2_POINTER pMpi2RaidPhysDiskPage1_t;
-
-#define MPI2_RAIDPHYSDISKPAGE1_PAGEVERSION          (0x02)
-
-
-/****************************************************************************
-*   values for fields used by several types of SAS Config Pages
-****************************************************************************/
-
-/* values for NegotiatedLinkRates fields */
-#define MPI2_SAS_NEG_LINK_RATE_MASK_LOGICAL             (0xF0)
-#define MPI2_SAS_NEG_LINK_RATE_SHIFT_LOGICAL            (4)
-#define MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL            (0x0F)
-/* link rates used for Negotiated Physical and Logical Link Rate */
-#define MPI2_SAS_NEG_LINK_RATE_UNKNOWN_LINK_RATE        (0x00)
-#define MPI2_SAS_NEG_LINK_RATE_PHY_DISABLED             (0x01)
-#define MPI2_SAS_NEG_LINK_RATE_NEGOTIATION_FAILED       (0x02)
-#define MPI2_SAS_NEG_LINK_RATE_SATA_OOB_COMPLETE        (0x03)
-#define MPI2_SAS_NEG_LINK_RATE_PORT_SELECTOR            (0x04)
-#define MPI2_SAS_NEG_LINK_RATE_SMP_RESET_IN_PROGRESS    (0x05)
-#define MPI2_SAS_NEG_LINK_RATE_UNSUPPORTED_PHY          (0x06)
-#define MPI2_SAS_NEG_LINK_RATE_1_5                      (0x08)
-#define MPI2_SAS_NEG_LINK_RATE_3_0                      (0x09)
-#define MPI2_SAS_NEG_LINK_RATE_6_0                      (0x0A)
-
-
-/* values for AttachedPhyInfo fields */
-#define MPI2_SAS_APHYINFO_INSIDE_ZPSDS_PERSISTENT       (0x00000040)
-#define MPI2_SAS_APHYINFO_REQUESTED_INSIDE_ZPSDS        (0x00000020)
-#define MPI2_SAS_APHYINFO_BREAK_REPLY_CAPABLE           (0x00000010)
-
-#define MPI2_SAS_APHYINFO_REASON_MASK                   (0x0000000F)
-#define MPI2_SAS_APHYINFO_REASON_UNKNOWN                (0x00000000)
-#define MPI2_SAS_APHYINFO_REASON_POWER_ON               (0x00000001)
-#define MPI2_SAS_APHYINFO_REASON_HARD_RESET             (0x00000002)
-#define MPI2_SAS_APHYINFO_REASON_SMP_PHY_CONTROL        (0x00000003)
-#define MPI2_SAS_APHYINFO_REASON_LOSS_OF_SYNC           (0x00000004)
-#define MPI2_SAS_APHYINFO_REASON_MULTIPLEXING_SEQ       (0x00000005)
-#define MPI2_SAS_APHYINFO_REASON_IT_NEXUS_LOSS_TIMER    (0x00000006)
-#define MPI2_SAS_APHYINFO_REASON_BREAK_TIMEOUT          (0x00000007)
-#define MPI2_SAS_APHYINFO_REASON_PHY_TEST_STOPPED       (0x00000008)
-
-
-/* values for PhyInfo fields */
-#define MPI2_SAS_PHYINFO_PHY_VACANT                     (0x80000000)
-
-#define MPI2_SAS_PHYINFO_PHY_POWER_CONDITION_MASK       (0x18000000)
-#define MPI2_SAS_PHYINFO_SHIFT_PHY_POWER_CONDITION      (27)
-#define MPI2_SAS_PHYINFO_PHY_POWER_ACTIVE               (0x00000000)
-#define MPI2_SAS_PHYINFO_PHY_POWER_PARTIAL              (0x08000000)
-#define MPI2_SAS_PHYINFO_PHY_POWER_SLUMBER              (0x10000000)
-
-#define MPI2_SAS_PHYINFO_CHANGED_REQ_INSIDE_ZPSDS       (0x04000000)
-#define MPI2_SAS_PHYINFO_INSIDE_ZPSDS_PERSISTENT        (0x02000000)
-#define MPI2_SAS_PHYINFO_REQ_INSIDE_ZPSDS               (0x01000000)
-#define MPI2_SAS_PHYINFO_ZONE_GROUP_PERSISTENT          (0x00400000)
-#define MPI2_SAS_PHYINFO_INSIDE_ZPSDS                   (0x00200000)
-#define MPI2_SAS_PHYINFO_ZONING_ENABLED                 (0x00100000)
-
-#define MPI2_SAS_PHYINFO_REASON_MASK                    (0x000F0000)
-#define MPI2_SAS_PHYINFO_REASON_UNKNOWN                 (0x00000000)
-#define MPI2_SAS_PHYINFO_REASON_POWER_ON                (0x00010000)
-#define MPI2_SAS_PHYINFO_REASON_HARD_RESET              (0x00020000)
-#define MPI2_SAS_PHYINFO_REASON_SMP_PHY_CONTROL         (0x00030000)
-#define MPI2_SAS_PHYINFO_REASON_LOSS_OF_SYNC            (0x00040000)
-#define MPI2_SAS_PHYINFO_REASON_MULTIPLEXING_SEQ        (0x00050000)
-#define MPI2_SAS_PHYINFO_REASON_IT_NEXUS_LOSS_TIMER     (0x00060000)
-#define MPI2_SAS_PHYINFO_REASON_BREAK_TIMEOUT           (0x00070000)
-#define MPI2_SAS_PHYINFO_REASON_PHY_TEST_STOPPED        (0x00080000)
-
-#define MPI2_SAS_PHYINFO_MULTIPLEXING_SUPPORTED         (0x00008000)
-#define MPI2_SAS_PHYINFO_SATA_PORT_ACTIVE               (0x00004000)
-#define MPI2_SAS_PHYINFO_SATA_PORT_SELECTOR_PRESENT     (0x00002000)
-#define MPI2_SAS_PHYINFO_VIRTUAL_PHY                    (0x00001000)
-
-#define MPI2_SAS_PHYINFO_MASK_PARTIAL_PATHWAY_TIME      (0x00000F00)
-#define MPI2_SAS_PHYINFO_SHIFT_PARTIAL_PATHWAY_TIME     (8)
-
-#define MPI2_SAS_PHYINFO_MASK_ROUTING_ATTRIBUTE         (0x000000F0)
-#define MPI2_SAS_PHYINFO_DIRECT_ROUTING                 (0x00000000)
-#define MPI2_SAS_PHYINFO_SUBTRACTIVE_ROUTING            (0x00000010)
-#define MPI2_SAS_PHYINFO_TABLE_ROUTING                  (0x00000020)
-
-
-/* values for SAS ProgrammedLinkRate fields */
-#define MPI2_SAS_PRATE_MAX_RATE_MASK                    (0xF0)
-#define MPI2_SAS_PRATE_MAX_RATE_NOT_PROGRAMMABLE        (0x00)
-#define MPI2_SAS_PRATE_MAX_RATE_1_5                     (0x80)
-#define MPI2_SAS_PRATE_MAX_RATE_3_0                     (0x90)
-#define MPI2_SAS_PRATE_MAX_RATE_6_0                     (0xA0)
-#define MPI25_SAS_PRATE_MAX_RATE_12_0                   (0xB0)
-#define MPI2_SAS_PRATE_MIN_RATE_MASK                    (0x0F)
-#define MPI2_SAS_PRATE_MIN_RATE_NOT_PROGRAMMABLE        (0x00)
-#define MPI2_SAS_PRATE_MIN_RATE_1_5                     (0x08)
-#define MPI2_SAS_PRATE_MIN_RATE_3_0                     (0x09)
-#define MPI2_SAS_PRATE_MIN_RATE_6_0                     (0x0A)
-
-
-/* values for SAS HwLinkRate fields */
-#define MPI2_SAS_HWRATE_MAX_RATE_MASK                   (0xF0)
-#define MPI2_SAS_HWRATE_MAX_RATE_1_5                    (0x80)
-#define MPI2_SAS_HWRATE_MAX_RATE_3_0                    (0x90)
-#define MPI2_SAS_HWRATE_MAX_RATE_6_0                    (0xA0)
-#define MPI25_SAS_HWRATE_MAX_RATE_12_0                  (0xB0)
-#define MPI2_SAS_HWRATE_MIN_RATE_MASK                   (0x0F)
-#define MPI2_SAS_HWRATE_MIN_RATE_1_5                    (0x08)
-#define MPI2_SAS_HWRATE_MIN_RATE_3_0                    (0x09)
-#define MPI2_SAS_HWRATE_MIN_RATE_6_0                    (0x0A)
-
-
-
-/****************************************************************************
-*   SAS IO Unit Config Pages
-****************************************************************************/
-
-/* SAS IO Unit Page 0 */
-
-typedef struct _MPI2_SAS_IO_UNIT0_PHY_DATA
-{
-    U8          Port;                   /* 0x00 */
-    U8          PortFlags;              /* 0x01 */
-    U8          PhyFlags;               /* 0x02 */
-    U8          NegotiatedLinkRate;     /* 0x03 */
-    U32         ControllerPhyDeviceInfo;/* 0x04 */
-    U16         AttachedDevHandle;      /* 0x08 */
-    U16         ControllerDevHandle;    /* 0x0A */
-    U32         DiscoveryStatus;        /* 0x0C */
-    U32         Reserved;               /* 0x10 */
-} MPI2_SAS_IO_UNIT0_PHY_DATA, MPI2_POINTER PTR_MPI2_SAS_IO_UNIT0_PHY_DATA,
-  Mpi2SasIOUnit0PhyData_t, MPI2_POINTER pMpi2SasIOUnit0PhyData_t;
-
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check the value returned for NumPhys at runtime.
- */
-#ifndef MPI2_SAS_IOUNIT0_PHY_MAX
-#define MPI2_SAS_IOUNIT0_PHY_MAX        (1)
-#endif
-
-typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_0
-{
-    MPI2_CONFIG_EXTENDED_PAGE_HEADER    Header;                             /* 0x00 */
-    U32                                 Reserved1;                          /* 0x08 */
-    U8                                  NumPhys;                            /* 0x0C */
-    U8                                  Reserved2;                          /* 0x0D */
-    U16                                 Reserved3;                          /* 0x0E */
-    MPI2_SAS_IO_UNIT0_PHY_DATA          PhyData[MPI2_SAS_IOUNIT0_PHY_MAX];  /* 0x10 */
-} MPI2_CONFIG_PAGE_SASIOUNIT_0,
-  MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SASIOUNIT_0,
-  Mpi2SasIOUnitPage0_t, MPI2_POINTER pMpi2SasIOUnitPage0_t;
-
-#define MPI2_SASIOUNITPAGE0_PAGEVERSION                     (0x05)
-
-/* values for SAS IO Unit Page 0 PortFlags */
-#define MPI2_SASIOUNIT0_PORTFLAGS_DISCOVERY_IN_PROGRESS     (0x08)
-#define MPI2_SASIOUNIT0_PORTFLAGS_AUTO_PORT_CONFIG          (0x01)
-
-/* values for SAS IO Unit Page 0 PhyFlags */
-#define MPI2_SASIOUNIT0_PHYFLAGS_ZONING_ENABLED             (0x10)
-#define MPI2_SASIOUNIT0_PHYFLAGS_PHY_DISABLED               (0x08)
-
-/* use MPI2_SAS_NEG_LINK_RATE_ defines for the NegotiatedLinkRate field */
-
-/* see mpi2_sas.h for values for SAS IO Unit Page 0 ControllerPhyDeviceInfo values */
-
-/* values for SAS IO Unit Page 0 DiscoveryStatus */
-#define MPI2_SASIOUNIT0_DS_MAX_ENCLOSURES_EXCEED            (0x80000000)
-#define MPI2_SASIOUNIT0_DS_MAX_EXPANDERS_EXCEED             (0x40000000)
-#define MPI2_SASIOUNIT0_DS_MAX_DEVICES_EXCEED               (0x20000000)
-#define MPI2_SASIOUNIT0_DS_MAX_TOPO_PHYS_EXCEED             (0x10000000)
-#define MPI2_SASIOUNIT0_DS_DOWNSTREAM_INITIATOR             (0x08000000)
-#define MPI2_SASIOUNIT0_DS_MULTI_SUBTRACTIVE_SUBTRACTIVE    (0x00008000)
-#define MPI2_SASIOUNIT0_DS_EXP_MULTI_SUBTRACTIVE            (0x00004000)
-#define MPI2_SASIOUNIT0_DS_MULTI_PORT_DOMAIN                (0x00002000)
-#define MPI2_SASIOUNIT0_DS_TABLE_TO_SUBTRACTIVE_LINK        (0x00001000)
-#define MPI2_SASIOUNIT0_DS_UNSUPPORTED_DEVICE               (0x00000800)
-#define MPI2_SASIOUNIT0_DS_TABLE_LINK                       (0x00000400)
-#define MPI2_SASIOUNIT0_DS_SUBTRACTIVE_LINK                 (0x00000200)
-#define MPI2_SASIOUNIT0_DS_SMP_CRC_ERROR                    (0x00000100)
-#define MPI2_SASIOUNIT0_DS_SMP_FUNCTION_FAILED              (0x00000080)
-#define MPI2_SASIOUNIT0_DS_INDEX_NOT_EXIST                  (0x00000040)
-#define MPI2_SASIOUNIT0_DS_OUT_ROUTE_ENTRIES                (0x00000020)
-#define MPI2_SASIOUNIT0_DS_SMP_TIMEOUT                      (0x00000010)
-#define MPI2_SASIOUNIT0_DS_MULTIPLE_PORTS                   (0x00000004)
-#define MPI2_SASIOUNIT0_DS_UNADDRESSABLE_DEVICE             (0x00000002)
-#define MPI2_SASIOUNIT0_DS_LOOP_DETECTED                    (0x00000001)
-
-
-/* SAS IO Unit Page 1 */
-
-typedef struct _MPI2_SAS_IO_UNIT1_PHY_DATA
-{
-    U8          Port;                       /* 0x00 */
-    U8          PortFlags;                  /* 0x01 */
-    U8          PhyFlags;                   /* 0x02 */
-    U8          MaxMinLinkRate;             /* 0x03 */
-    U32         ControllerPhyDeviceInfo;    /* 0x04 */
-    U16         MaxTargetPortConnectTime;   /* 0x08 */
-    U16         Reserved1;                  /* 0x0A */
-} MPI2_SAS_IO_UNIT1_PHY_DATA, MPI2_POINTER PTR_MPI2_SAS_IO_UNIT1_PHY_DATA,
-  Mpi2SasIOUnit1PhyData_t, MPI2_POINTER pMpi2SasIOUnit1PhyData_t;
-
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check the value returned for NumPhys at runtime.
- */
-#ifndef MPI2_SAS_IOUNIT1_PHY_MAX
-#define MPI2_SAS_IOUNIT1_PHY_MAX        (1)
-#endif
-
-typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_1
-{
-    MPI2_CONFIG_EXTENDED_PAGE_HEADER    Header;                             /* 0x00 */
-    U16                                 ControlFlags;                       /* 0x08 */
-    U16                                 SASNarrowMaxQueueDepth;             /* 0x0A */
-    U16                                 AdditionalControlFlags;             /* 0x0C */
-    U16                                 SASWideMaxQueueDepth;               /* 0x0E */
-    U8                                  NumPhys;                            /* 0x10 */
-    U8                                  SATAMaxQDepth;                      /* 0x11 */
-    U8                                  ReportDeviceMissingDelay;           /* 0x12 */
-    U8                                  IODeviceMissingDelay;               /* 0x13 */
-    MPI2_SAS_IO_UNIT1_PHY_DATA          PhyData[MPI2_SAS_IOUNIT1_PHY_MAX];  /* 0x14 */
-} MPI2_CONFIG_PAGE_SASIOUNIT_1,
-  MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SASIOUNIT_1,
-  Mpi2SasIOUnitPage1_t, MPI2_POINTER pMpi2SasIOUnitPage1_t;
-
-#define MPI2_SASIOUNITPAGE1_PAGEVERSION     (0x09)
-
-/* values for SAS IO Unit Page 1 ControlFlags */
-#define MPI2_SASIOUNIT1_CONTROL_DEVICE_SELF_TEST                    (0x8000)
-#define MPI2_SASIOUNIT1_CONTROL_SATA_3_0_MAX                        (0x4000)
-#define MPI2_SASIOUNIT1_CONTROL_SATA_1_5_MAX                        (0x2000)
-#define MPI2_SASIOUNIT1_CONTROL_SATA_SW_PRESERVE                    (0x1000)
-
-#define MPI2_SASIOUNIT1_CONTROL_MASK_DEV_SUPPORT                    (0x0600)
-#define MPI2_SASIOUNIT1_CONTROL_SHIFT_DEV_SUPPORT                   (9)
-#define MPI2_SASIOUNIT1_CONTROL_DEV_SUPPORT_BOTH                    (0x0)
-#define MPI2_SASIOUNIT1_CONTROL_DEV_SAS_SUPPORT                     (0x1)
-#define MPI2_SASIOUNIT1_CONTROL_DEV_SATA_SUPPORT                    (0x2)
-
-#define MPI2_SASIOUNIT1_CONTROL_SATA_48BIT_LBA_REQUIRED             (0x0080)
-#define MPI2_SASIOUNIT1_CONTROL_SATA_SMART_REQUIRED                 (0x0040)
-#define MPI2_SASIOUNIT1_CONTROL_SATA_NCQ_REQUIRED                   (0x0020)
-#define MPI2_SASIOUNIT1_CONTROL_SATA_FUA_REQUIRED                   (0x0010)
-#define MPI2_SASIOUNIT1_CONTROL_TABLE_SUBTRACTIVE_ILLEGAL           (0x0008)
-#define MPI2_SASIOUNIT1_CONTROL_SUBTRACTIVE_ILLEGAL                 (0x0004)
-#define MPI2_SASIOUNIT1_CONTROL_FIRST_LVL_DISC_ONLY                 (0x0002)
-#define MPI2_SASIOUNIT1_CONTROL_CLEAR_AFFILIATION                   (0x0001)
-
-/* values for SAS IO Unit Page 1 AdditionalControlFlags */
-#define MPI2_SASIOUNIT1_ACONTROL_MULTI_PORT_DOMAIN_ILLEGAL          (0x0080)
-#define MPI2_SASIOUNIT1_ACONTROL_SATA_ASYNCHROUNOUS_NOTIFICATION    (0x0040)
-#define MPI2_SASIOUNIT1_ACONTROL_INVALID_TOPOLOGY_CORRECTION        (0x0020)
-#define MPI2_SASIOUNIT1_ACONTROL_PORT_ENABLE_ONLY_SATA_LINK_RESET   (0x0010)
-#define MPI2_SASIOUNIT1_ACONTROL_OTHER_AFFILIATION_SATA_LINK_RESET  (0x0008)
-#define MPI2_SASIOUNIT1_ACONTROL_SELF_AFFILIATION_SATA_LINK_RESET   (0x0004)
-#define MPI2_SASIOUNIT1_ACONTROL_NO_AFFILIATION_SATA_LINK_RESET     (0x0002)
-#define MPI2_SASIOUNIT1_ACONTROL_ALLOW_TABLE_TO_TABLE               (0x0001)
-
-/* defines for SAS IO Unit Page 1 ReportDeviceMissingDelay */
-#define MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK                 (0x7F)
-#define MPI2_SASIOUNIT1_REPORT_MISSING_UNIT_16                      (0x80)
-
-/* values for SAS IO Unit Page 1 PortFlags */
-#define MPI2_SASIOUNIT1_PORT_FLAGS_AUTO_PORT_CONFIG                 (0x01)
-
-/* values for SAS IO Unit Page 1 PhyFlags */
-#define MPI2_SASIOUNIT1_PHYFLAGS_ZONING_ENABLE                      (0x10)
-#define MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE                        (0x08)
-
-/* values for SAS IO Unit Page 1 MaxMinLinkRate */
-#define MPI2_SASIOUNIT1_MAX_RATE_MASK                               (0xF0)
-#define MPI2_SASIOUNIT1_MAX_RATE_1_5                                (0x80)
-#define MPI2_SASIOUNIT1_MAX_RATE_3_0                                (0x90)
-#define MPI2_SASIOUNIT1_MAX_RATE_6_0                                (0xA0)
-#define MPI2_SASIOUNIT1_MIN_RATE_MASK                               (0x0F)
-#define MPI2_SASIOUNIT1_MIN_RATE_1_5                                (0x08)
-#define MPI2_SASIOUNIT1_MIN_RATE_3_0                                (0x09)
-#define MPI2_SASIOUNIT1_MIN_RATE_6_0                                (0x0A)
-
-/* see mpi2_sas.h for values for SAS IO Unit Page 1 ControllerPhyDeviceInfo values */
-
-
-/* SAS IO Unit Page 4 */
-
-typedef struct _MPI2_SAS_IOUNIT4_SPINUP_GROUP
-{
-    U8          MaxTargetSpinup;            /* 0x00 */
-    U8          SpinupDelay;                /* 0x01 */
-       U8          SpinupFlags;                /* 0x02 */
-       U8          Reserved1;                  /* 0x03 */
-} MPI2_SAS_IOUNIT4_SPINUP_GROUP, MPI2_POINTER PTR_MPI2_SAS_IOUNIT4_SPINUP_GROUP,
-  Mpi2SasIOUnit4SpinupGroup_t, MPI2_POINTER pMpi2SasIOUnit4SpinupGroup_t;
-
-/* defines for SAS IO Unit Page 4 SpinupFlags */
-#define MPI2_SASIOUNIT4_SPINUP_DISABLE_FLAG         (0x01)
-
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check the value returned for NumPhys at runtime.
- */
-#ifndef MPI2_SAS_IOUNIT4_PHY_MAX
-#define MPI2_SAS_IOUNIT4_PHY_MAX        (4)
-#endif
-
-typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_4
-{
-    MPI2_CONFIG_EXTENDED_PAGE_HEADER    Header;                         /* 0x00 */
-    MPI2_SAS_IOUNIT4_SPINUP_GROUP       SpinupGroupParameters[4];       /* 0x08 */
-    U32                                 Reserved1;                      /* 0x18 */
-    U32                                 Reserved2;                      /* 0x1C */
-    U32                                 Reserved3;                      /* 0x20 */
-    U8                                  BootDeviceWaitTime;             /* 0x24 */
-    U8                                  Reserved4;                      /* 0x25 */
-    U16                                 Reserved5;                      /* 0x26 */
-    U8                                  NumPhys;                        /* 0x28 */
-    U8                                  PEInitialSpinupDelay;           /* 0x29 */
-    U8                                  PEReplyDelay;                   /* 0x2A */
-    U8                                  Flags;                          /* 0x2B */
-    U8                                  PHY[MPI2_SAS_IOUNIT4_PHY_MAX];  /* 0x2C */
-} MPI2_CONFIG_PAGE_SASIOUNIT_4,
-  MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SASIOUNIT_4,
-  Mpi2SasIOUnitPage4_t, MPI2_POINTER pMpi2SasIOUnitPage4_t;
-
-#define MPI2_SASIOUNITPAGE4_PAGEVERSION     (0x02)
-
-/* defines for Flags field */
-#define MPI2_SASIOUNIT4_FLAGS_AUTO_PORTENABLE               (0x01)
-
-/* defines for PHY field */
-#define MPI2_SASIOUNIT4_PHY_SPINUP_GROUP_MASK               (0x03)
-
-
-/* SAS IO Unit Page 5 */
-
-typedef struct _MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS {
-    U8          ControlFlags;               /* 0x00 */
-    U8          PortWidthModGroup;          /* 0x01 */
-    U16         InactivityTimerExponent;    /* 0x02 */
-    U8          SATAPartialTimeout;         /* 0x04 */
-    U8          Reserved2;                  /* 0x05 */
-    U8          SATASlumberTimeout;         /* 0x06 */
-    U8          Reserved3;                  /* 0x07 */
-    U8          SASPartialTimeout;          /* 0x08 */
-    U8          Reserved4;                  /* 0x09 */
-    U8          SASSlumberTimeout;          /* 0x0A */
-    U8          Reserved5;                  /* 0x0B */
-} MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS,
-  MPI2_POINTER PTR_MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS,
-  Mpi2SasIOUnit5PhyPmSettings_t, MPI2_POINTER pMpi2SasIOUnit5PhyPmSettings_t;
-
-/* defines for ControlFlags field */
-#define MPI2_SASIOUNIT5_CONTROL_SAS_SLUMBER_ENABLE      (0x08)
-#define MPI2_SASIOUNIT5_CONTROL_SAS_PARTIAL_ENABLE      (0x04)
-#define MPI2_SASIOUNIT5_CONTROL_SATA_SLUMBER_ENABLE     (0x02)
-#define MPI2_SASIOUNIT5_CONTROL_SATA_PARTIAL_ENABLE     (0x01)
-
-/* defines for PortWidthModeGroup field */
-#define MPI2_SASIOUNIT5_PWMG_DISABLE                    (0xFF)
-
-/* defines for InactivityTimerExponent field */
-#define MPI2_SASIOUNIT5_ITE_MASK_SAS_SLUMBER            (0x7000)
-#define MPI2_SASIOUNIT5_ITE_SHIFT_SAS_SLUMBER           (12)
-#define MPI2_SASIOUNIT5_ITE_MASK_SAS_PARTIAL            (0x0700)
-#define MPI2_SASIOUNIT5_ITE_SHIFT_SAS_PARTIAL           (8)
-#define MPI2_SASIOUNIT5_ITE_MASK_SATA_SLUMBER           (0x0070)
-#define MPI2_SASIOUNIT5_ITE_SHIFT_SATA_SLUMBER          (4)
-#define MPI2_SASIOUNIT5_ITE_MASK_SATA_PARTIAL           (0x0007)
-#define MPI2_SASIOUNIT5_ITE_SHIFT_SATA_PARTIAL          (0)
-
-#define MPI2_SASIOUNIT5_ITE_TEN_SECONDS                 (7)
-#define MPI2_SASIOUNIT5_ITE_ONE_SECOND                  (6)
-#define MPI2_SASIOUNIT5_ITE_HUNDRED_MILLISECONDS        (5)
-#define MPI2_SASIOUNIT5_ITE_TEN_MILLISECONDS            (4)
-#define MPI2_SASIOUNIT5_ITE_ONE_MILLISECOND             (3)
-#define MPI2_SASIOUNIT5_ITE_HUNDRED_MICROSECONDS        (2)
-#define MPI2_SASIOUNIT5_ITE_TEN_MICROSECONDS            (1)
-#define MPI2_SASIOUNIT5_ITE_ONE_MICROSECOND             (0)
-
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check the value returned for NumPhys at runtime.
- */
-#ifndef MPI2_SAS_IOUNIT5_PHY_MAX
-#define MPI2_SAS_IOUNIT5_PHY_MAX        (1)
-#endif
-
-typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_5 {
-    MPI2_CONFIG_EXTENDED_PAGE_HEADER    Header;                /* 0x00 */
-    U8                                  NumPhys;       /* 0x08 */
-    U8                                  Reserved1;     /* 0x09 */
-    U16                                 Reserved2;     /* 0x0A */
-    U32                                 Reserved3;     /* 0x0C */
-    MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS   SASPhyPowerManagementSettings
-                                       [MPI2_SAS_IOUNIT5_PHY_MAX];  /* 0x10 */
-} MPI2_CONFIG_PAGE_SASIOUNIT_5,
-  MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SASIOUNIT_5,
-  Mpi2SasIOUnitPage5_t, MPI2_POINTER pMpi2SasIOUnitPage5_t;
-
-#define MPI2_SASIOUNITPAGE5_PAGEVERSION     (0x01)
-
-
-/* SAS IO Unit Page 6 */
-
-typedef struct _MPI2_SAS_IO_UNIT6_PORT_WIDTH_MOD_GROUP_STATUS {
-    U8          CurrentStatus;              /* 0x00 */
-    U8          CurrentModulation;          /* 0x01 */
-    U8          CurrentUtilization;         /* 0x02 */
-    U8          Reserved1;                  /* 0x03 */
-    U32         Reserved2;                  /* 0x04 */
-} MPI2_SAS_IO_UNIT6_PORT_WIDTH_MOD_GROUP_STATUS,
-  MPI2_POINTER PTR_MPI2_SAS_IO_UNIT6_PORT_WIDTH_MOD_GROUP_STATUS,
-  Mpi2SasIOUnit6PortWidthModGroupStatus_t,
-  MPI2_POINTER pMpi2SasIOUnit6PortWidthModGroupStatus_t;
-
-/* defines for CurrentStatus field */
-#define MPI2_SASIOUNIT6_STATUS_UNAVAILABLE                      (0x00)
-#define MPI2_SASIOUNIT6_STATUS_UNCONFIGURED                     (0x01)
-#define MPI2_SASIOUNIT6_STATUS_INVALID_CONFIG                   (0x02)
-#define MPI2_SASIOUNIT6_STATUS_LINK_DOWN                        (0x03)
-#define MPI2_SASIOUNIT6_STATUS_OBSERVATION_ONLY                 (0x04)
-#define MPI2_SASIOUNIT6_STATUS_INACTIVE                         (0x05)
-#define MPI2_SASIOUNIT6_STATUS_ACTIVE_IOUNIT                    (0x06)
-#define MPI2_SASIOUNIT6_STATUS_ACTIVE_HOST                      (0x07)
-
-/* defines for CurrentModulation field */
-#define MPI2_SASIOUNIT6_MODULATION_25_PERCENT                   (0x00)
-#define MPI2_SASIOUNIT6_MODULATION_50_PERCENT                   (0x01)
-#define MPI2_SASIOUNIT6_MODULATION_75_PERCENT                   (0x02)
-#define MPI2_SASIOUNIT6_MODULATION_100_PERCENT                  (0x03)
-
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check the value returned for NumGroups at runtime.
- */
-#ifndef MPI2_SAS_IOUNIT6_GROUP_MAX
-#define MPI2_SAS_IOUNIT6_GROUP_MAX      (1)
-#endif
-
-typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_6 {
-    MPI2_CONFIG_EXTENDED_PAGE_HEADER    Header;                     /* 0x00 */
-    U32                                 Reserved1;                  /* 0x08 */
-    U32                                 Reserved2;                  /* 0x0C */
-    U8                                  NumGroups;                  /* 0x10 */
-    U8                                  Reserved3;                  /* 0x11 */
-    U16                                 Reserved4;                  /* 0x12 */
-    MPI2_SAS_IO_UNIT6_PORT_WIDTH_MOD_GROUP_STATUS
-       PortWidthModulationGroupStatus[MPI2_SAS_IOUNIT6_GROUP_MAX]; /* 0x14 */
-} MPI2_CONFIG_PAGE_SASIOUNIT_6,
-  MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SASIOUNIT_6,
-  Mpi2SasIOUnitPage6_t, MPI2_POINTER pMpi2SasIOUnitPage6_t;
-
-#define MPI2_SASIOUNITPAGE6_PAGEVERSION     (0x00)
-
-
-/* SAS IO Unit Page 7 */
-
-typedef struct _MPI2_SAS_IO_UNIT7_PORT_WIDTH_MOD_GROUP_SETTINGS {
-    U8          Flags;                      /* 0x00 */
-    U8          Reserved1;                  /* 0x01 */
-    U16         Reserved2;                  /* 0x02 */
-    U8          Threshold75Pct;             /* 0x04 */
-    U8          Threshold50Pct;             /* 0x05 */
-    U8          Threshold25Pct;             /* 0x06 */
-    U8          Reserved3;                  /* 0x07 */
-} MPI2_SAS_IO_UNIT7_PORT_WIDTH_MOD_GROUP_SETTINGS,
-  MPI2_POINTER PTR_MPI2_SAS_IO_UNIT7_PORT_WIDTH_MOD_GROUP_SETTINGS,
-  Mpi2SasIOUnit7PortWidthModGroupSettings_t,
-  MPI2_POINTER pMpi2SasIOUnit7PortWidthModGroupSettings_t;
-
-/* defines for Flags field */
-#define MPI2_SASIOUNIT7_FLAGS_ENABLE_PORT_WIDTH_MODULATION  (0x01)
-
-
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check the value returned for NumGroups at runtime.
- */
-#ifndef MPI2_SAS_IOUNIT7_GROUP_MAX
-#define MPI2_SAS_IOUNIT7_GROUP_MAX      (1)
-#endif
-
-typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_7 {
-    MPI2_CONFIG_EXTENDED_PAGE_HEADER            Header;             /* 0x00 */
-    U8                                          SamplingInterval;   /* 0x08 */
-    U8                                          WindowLength;       /* 0x09 */
-    U16                                         Reserved1;          /* 0x0A */
-    U32                                         Reserved2;          /* 0x0C */
-    U32                                         Reserved3;          /* 0x10 */
-    U8                                          NumGroups;          /* 0x14 */
-    U8                                          Reserved4;          /* 0x15 */
-    U16                                         Reserved5;          /* 0x16 */
-    MPI2_SAS_IO_UNIT7_PORT_WIDTH_MOD_GROUP_SETTINGS
-       PortWidthModulationGroupSettings[MPI2_SAS_IOUNIT7_GROUP_MAX]; /* 0x18 */
-} MPI2_CONFIG_PAGE_SASIOUNIT_7,
-  MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SASIOUNIT_7,
-  Mpi2SasIOUnitPage7_t, MPI2_POINTER pMpi2SasIOUnitPage7_t;
-
-#define MPI2_SASIOUNITPAGE7_PAGEVERSION     (0x00)
-
-
-/* SAS IO Unit Page 8 */
-
-typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_8 {
-    MPI2_CONFIG_EXTENDED_PAGE_HEADER    Header;                        /* 0x00 */
-    U32                                 Reserved1;             /* 0x08 */
-    U32                                 PowerManagementCapabilities;/* 0x0C */
-    U32                                 Reserved2;             /* 0x10 */
-} MPI2_CONFIG_PAGE_SASIOUNIT_8,
-  MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SASIOUNIT_8,
-  Mpi2SasIOUnitPage8_t, MPI2_POINTER pMpi2SasIOUnitPage8_t;
-
-#define MPI2_SASIOUNITPAGE8_PAGEVERSION     (0x00)
-
-/* defines for PowerManagementCapabilities field */
-#define MPI2_SASIOUNIT8_PM_HOST_PORT_WIDTH_MOD          (0x00001000)
-#define MPI2_SASIOUNIT8_PM_HOST_SAS_SLUMBER_MODE        (0x00000800)
-#define MPI2_SASIOUNIT8_PM_HOST_SAS_PARTIAL_MODE        (0x00000400)
-#define MPI2_SASIOUNIT8_PM_HOST_SATA_SLUMBER_MODE       (0x00000200)
-#define MPI2_SASIOUNIT8_PM_HOST_SATA_PARTIAL_MODE       (0x00000100)
-#define MPI2_SASIOUNIT8_PM_IOUNIT_PORT_WIDTH_MOD        (0x00000010)
-#define MPI2_SASIOUNIT8_PM_IOUNIT_SAS_SLUMBER_MODE      (0x00000008)
-#define MPI2_SASIOUNIT8_PM_IOUNIT_SAS_PARTIAL_MODE      (0x00000004)
-#define MPI2_SASIOUNIT8_PM_IOUNIT_SATA_SLUMBER_MODE     (0x00000002)
-#define MPI2_SASIOUNIT8_PM_IOUNIT_SATA_PARTIAL_MODE     (0x00000001)
-
-
-
-/* SAS IO Unit Page 16 */
-
-typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT16 {
-       MPI2_CONFIG_EXTENDED_PAGE_HEADER  Header;                  /* 0x00 */
-       U64                         TimeStamp;                     /* 0x08 */
-       U32                         Reserved1;                     /* 0x10 */
-       U32                         Reserved2;                     /* 0x14 */
-       U32                         FastPathPendedRequests;        /* 0x18 */
-       U32                         FastPathUnPendedRequests;      /* 0x1C */
-       U32                         FastPathHostRequestStarts;     /* 0x20 */
-       U32                         FastPathFirmwareRequestStarts; /* 0x24 */
-       U32                         FastPathHostCompletions;       /* 0x28 */
-       U32                         FastPathFirmwareCompletions;   /* 0x2C */
-       U32                         NonFastPathRequestStarts;      /* 0x30 */
-       U32                         NonFastPathHostCompletions;    /* 0x30 */
-} MPI2_CONFIG_PAGE_SASIOUNIT16,
-MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SASIOUNIT16,
-Mpi2SasIOUnitPage16_t, MPI2_POINTER pMpi2SasIOUnitPage16_t;
-
-#define MPI2_SASIOUNITPAGE16_PAGEVERSION    (0x00)
-
-
-/****************************************************************************
-*   SAS Expander Config Pages
-****************************************************************************/
-
-/* SAS Expander Page 0 */
-
-typedef struct _MPI2_CONFIG_PAGE_EXPANDER_0
-{
-    MPI2_CONFIG_EXTENDED_PAGE_HEADER    Header;                     /* 0x00 */
-    U8                                  PhysicalPort;               /* 0x08 */
-    U8                                  ReportGenLength;            /* 0x09 */
-    U16                                 EnclosureHandle;            /* 0x0A */
-    U64                                 SASAddress;                 /* 0x0C */
-    U32                                 DiscoveryStatus;            /* 0x14 */
-    U16                                 DevHandle;                  /* 0x18 */
-    U16                                 ParentDevHandle;            /* 0x1A */
-    U16                                 ExpanderChangeCount;        /* 0x1C */
-    U16                                 ExpanderRouteIndexes;       /* 0x1E */
-    U8                                  NumPhys;                    /* 0x20 */
-    U8                                  SASLevel;                   /* 0x21 */
-    U16                                 Flags;                      /* 0x22 */
-    U16                                 STPBusInactivityTimeLimit;  /* 0x24 */
-    U16                                 STPMaxConnectTimeLimit;     /* 0x26 */
-    U16                                 STP_SMP_NexusLossTime;      /* 0x28 */
-    U16                                 MaxNumRoutedSasAddresses;   /* 0x2A */
-    U64                                 ActiveZoneManagerSASAddress;/* 0x2C */
-    U16                                 ZoneLockInactivityLimit;    /* 0x34 */
-    U16                                 Reserved1;                  /* 0x36 */
-    U8                                  TimeToReducedFunc;          /* 0x38 */
-    U8                                  InitialTimeToReducedFunc;   /* 0x39 */
-    U8                                  MaxReducedFuncTime;         /* 0x3A */
-    U8                                  Reserved2;                  /* 0x3B */
-} MPI2_CONFIG_PAGE_EXPANDER_0, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_EXPANDER_0,
-  Mpi2ExpanderPage0_t, MPI2_POINTER pMpi2ExpanderPage0_t;
-
-#define MPI2_SASEXPANDER0_PAGEVERSION       (0x06)
-
-/* values for SAS Expander Page 0 DiscoveryStatus field */
-#define MPI2_SAS_EXPANDER0_DS_MAX_ENCLOSURES_EXCEED         (0x80000000)
-#define MPI2_SAS_EXPANDER0_DS_MAX_EXPANDERS_EXCEED          (0x40000000)
-#define MPI2_SAS_EXPANDER0_DS_MAX_DEVICES_EXCEED            (0x20000000)
-#define MPI2_SAS_EXPANDER0_DS_MAX_TOPO_PHYS_EXCEED          (0x10000000)
-#define MPI2_SAS_EXPANDER0_DS_DOWNSTREAM_INITIATOR          (0x08000000)
-#define MPI2_SAS_EXPANDER0_DS_MULTI_SUBTRACTIVE_SUBTRACTIVE (0x00008000)
-#define MPI2_SAS_EXPANDER0_DS_EXP_MULTI_SUBTRACTIVE         (0x00004000)
-#define MPI2_SAS_EXPANDER0_DS_MULTI_PORT_DOMAIN             (0x00002000)
-#define MPI2_SAS_EXPANDER0_DS_TABLE_TO_SUBTRACTIVE_LINK     (0x00001000)
-#define MPI2_SAS_EXPANDER0_DS_UNSUPPORTED_DEVICE            (0x00000800)
-#define MPI2_SAS_EXPANDER0_DS_TABLE_LINK                    (0x00000400)
-#define MPI2_SAS_EXPANDER0_DS_SUBTRACTIVE_LINK              (0x00000200)
-#define MPI2_SAS_EXPANDER0_DS_SMP_CRC_ERROR                 (0x00000100)
-#define MPI2_SAS_EXPANDER0_DS_SMP_FUNCTION_FAILED           (0x00000080)
-#define MPI2_SAS_EXPANDER0_DS_INDEX_NOT_EXIST               (0x00000040)
-#define MPI2_SAS_EXPANDER0_DS_OUT_ROUTE_ENTRIES             (0x00000020)
-#define MPI2_SAS_EXPANDER0_DS_SMP_TIMEOUT                   (0x00000010)
-#define MPI2_SAS_EXPANDER0_DS_MULTIPLE_PORTS                (0x00000004)
-#define MPI2_SAS_EXPANDER0_DS_UNADDRESSABLE_DEVICE          (0x00000002)
-#define MPI2_SAS_EXPANDER0_DS_LOOP_DETECTED                 (0x00000001)
-
-/* values for SAS Expander Page 0 Flags field */
-#define MPI2_SAS_EXPANDER0_FLAGS_REDUCED_FUNCTIONALITY      (0x2000)
-#define MPI2_SAS_EXPANDER0_FLAGS_ZONE_LOCKED                (0x1000)
-#define MPI2_SAS_EXPANDER0_FLAGS_SUPPORTED_PHYSICAL_PRES    (0x0800)
-#define MPI2_SAS_EXPANDER0_FLAGS_ASSERTED_PHYSICAL_PRES     (0x0400)
-#define MPI2_SAS_EXPANDER0_FLAGS_ZONING_SUPPORT             (0x0200)
-#define MPI2_SAS_EXPANDER0_FLAGS_ENABLED_ZONING             (0x0100)
-#define MPI2_SAS_EXPANDER0_FLAGS_TABLE_TO_TABLE_SUPPORT     (0x0080)
-#define MPI2_SAS_EXPANDER0_FLAGS_CONNECTOR_END_DEVICE       (0x0010)
-#define MPI2_SAS_EXPANDER0_FLAGS_OTHERS_CONFIG              (0x0004)
-#define MPI2_SAS_EXPANDER0_FLAGS_CONFIG_IN_PROGRESS         (0x0002)
-#define MPI2_SAS_EXPANDER0_FLAGS_ROUTE_TABLE_CONFIG         (0x0001)
-
-
-/* SAS Expander Page 1 */
-
-typedef struct _MPI2_CONFIG_PAGE_EXPANDER_1
-{
-    MPI2_CONFIG_EXTENDED_PAGE_HEADER    Header;                     /* 0x00 */
-    U8                                  PhysicalPort;               /* 0x08 */
-    U8                                  Reserved1;                  /* 0x09 */
-    U16                                 Reserved2;                  /* 0x0A */
-    U8                                  NumPhys;                    /* 0x0C */
-    U8                                  Phy;                        /* 0x0D */
-    U16                                 NumTableEntriesProgrammed;  /* 0x0E */
-    U8                                  ProgrammedLinkRate;         /* 0x10 */
-    U8                                  HwLinkRate;                 /* 0x11 */
-    U16                                 AttachedDevHandle;          /* 0x12 */
-    U32                                 PhyInfo;                    /* 0x14 */
-    U32                                 AttachedDeviceInfo;         /* 0x18 */
-    U16                                 ExpanderDevHandle;          /* 0x1C */
-    U8                                  ChangeCount;                /* 0x1E */
-    U8                                  NegotiatedLinkRate;         /* 0x1F */
-    U8                                  PhyIdentifier;              /* 0x20 */
-    U8                                  AttachedPhyIdentifier;      /* 0x21 */
-    U8                                  Reserved3;                  /* 0x22 */
-    U8                                  DiscoveryInfo;              /* 0x23 */
-    U32                                 AttachedPhyInfo;            /* 0x24 */
-    U8                                  ZoneGroup;                  /* 0x28 */
-    U8                                  SelfConfigStatus;           /* 0x29 */
-    U16                                 Reserved4;                  /* 0x2A */
-} MPI2_CONFIG_PAGE_EXPANDER_1, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_EXPANDER_1,
-  Mpi2ExpanderPage1_t, MPI2_POINTER pMpi2ExpanderPage1_t;
-
-#define MPI2_SASEXPANDER1_PAGEVERSION       (0x02)
-
-/* use MPI2_SAS_PRATE_ defines for the ProgrammedLinkRate field */
-
-/* use MPI2_SAS_HWRATE_ defines for the HwLinkRate field */
-
-/* use MPI2_SAS_PHYINFO_ for the PhyInfo field */
-
-/* see mpi2_sas.h for the MPI2_SAS_DEVICE_INFO_ defines used for the AttachedDeviceInfo field */
-
-/* use MPI2_SAS_NEG_LINK_RATE_ defines for the NegotiatedLinkRate field */
-
-/* values for SAS Expander Page 1 DiscoveryInfo field */
-#define MPI2_SAS_EXPANDER1_DISCINFO_BAD_PHY_DISABLED    (0x04)
-#define MPI2_SAS_EXPANDER1_DISCINFO_LINK_STATUS_CHANGE  (0x02)
-#define MPI2_SAS_EXPANDER1_DISCINFO_NO_ROUTING_ENTRIES  (0x01)
-
-/* use MPI2_SAS_APHYINFO_ defines for AttachedPhyInfo field */
-
-/****************************************************************************
-*   SAS Device Config Pages
-****************************************************************************/
-
-/* SAS Device Page 0 */
-
-typedef struct _MPI2_CONFIG_PAGE_SAS_DEV_0
-{
-    MPI2_CONFIG_EXTENDED_PAGE_HEADER    Header;                 /* 0x00 */
-    U16                                 Slot;                   /* 0x08 */
-    U16                                 EnclosureHandle;        /* 0x0A */
-    U64                                 SASAddress;             /* 0x0C */
-    U16                                 ParentDevHandle;        /* 0x14 */
-    U8                                  PhyNum;                 /* 0x16 */
-    U8                                  AccessStatus;           /* 0x17 */
-    U16                                 DevHandle;              /* 0x18 */
-    U8                                  AttachedPhyIdentifier;  /* 0x1A */
-    U8                                  ZoneGroup;              /* 0x1B */
-    U32                                 DeviceInfo;             /* 0x1C */
-    U16                                 Flags;                  /* 0x20 */
-    U8                                  PhysicalPort;           /* 0x22 */
-    U8                                  MaxPortConnections;     /* 0x23 */
-    U64                                 DeviceName;             /* 0x24 */
-    U8                                  PortGroups;             /* 0x2C */
-    U8                                  DmaGroup;               /* 0x2D */
-    U8                                  ControlGroup;           /* 0x2E */
-       U8                               EnclosureLevel;         /* 0x2F */
-       U8                               ConnectorName[4];       /* 0x30 */
-    U32                                 Reserved3;              /* 0x34 */
-} MPI2_CONFIG_PAGE_SAS_DEV_0, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SAS_DEV_0,
-  Mpi2SasDevicePage0_t, MPI2_POINTER pMpi2SasDevicePage0_t;
-
-#define MPI2_SASDEVICE0_PAGEVERSION         (0x09)
-
-/* values for SAS Device Page 0 AccessStatus field */
-#define MPI2_SAS_DEVICE0_ASTATUS_NO_ERRORS                  (0x00)
-#define MPI2_SAS_DEVICE0_ASTATUS_SATA_INIT_FAILED           (0x01)
-#define MPI2_SAS_DEVICE0_ASTATUS_SATA_CAPABILITY_FAILED     (0x02)
-#define MPI2_SAS_DEVICE0_ASTATUS_SATA_AFFILIATION_CONFLICT  (0x03)
-#define MPI2_SAS_DEVICE0_ASTATUS_SATA_NEEDS_INITIALIZATION  (0x04)
-#define MPI2_SAS_DEVICE0_ASTATUS_ROUTE_NOT_ADDRESSABLE      (0x05)
-#define MPI2_SAS_DEVICE0_ASTATUS_SMP_ERROR_NOT_ADDRESSABLE  (0x06)
-#define MPI2_SAS_DEVICE0_ASTATUS_DEVICE_BLOCKED             (0x07)
-/* specific values for SATA Init failures */
-#define MPI2_SAS_DEVICE0_ASTATUS_SIF_UNKNOWN                (0x10)
-#define MPI2_SAS_DEVICE0_ASTATUS_SIF_AFFILIATION_CONFLICT   (0x11)
-#define MPI2_SAS_DEVICE0_ASTATUS_SIF_DIAG                   (0x12)
-#define MPI2_SAS_DEVICE0_ASTATUS_SIF_IDENTIFICATION         (0x13)
-#define MPI2_SAS_DEVICE0_ASTATUS_SIF_CHECK_POWER            (0x14)
-#define MPI2_SAS_DEVICE0_ASTATUS_SIF_PIO_SN                 (0x15)
-#define MPI2_SAS_DEVICE0_ASTATUS_SIF_MDMA_SN                (0x16)
-#define MPI2_SAS_DEVICE0_ASTATUS_SIF_UDMA_SN                (0x17)
-#define MPI2_SAS_DEVICE0_ASTATUS_SIF_ZONING_VIOLATION       (0x18)
-#define MPI2_SAS_DEVICE0_ASTATUS_SIF_NOT_ADDRESSABLE        (0x19)
-#define MPI2_SAS_DEVICE0_ASTATUS_SIF_MAX                    (0x1F)
-
-/* see mpi2_sas.h for values for SAS Device Page 0 DeviceInfo values */
-
-/* values for SAS Device Page 0 Flags field */
-#define MPI2_SAS_DEVICE0_FLAGS_UNAUTHORIZED_DEVICE          (0x8000)
-#define MPI2_SAS_DEVICE0_FLAGS_SLUMBER_PM_CAPABLE           (0x1000)
-#define MPI2_SAS_DEVICE0_FLAGS_PARTIAL_PM_CAPABLE           (0x0800)
-#define MPI2_SAS_DEVICE0_FLAGS_SATA_ASYNCHRONOUS_NOTIFY     (0x0400)
-#define MPI2_SAS_DEVICE0_FLAGS_SATA_SW_PRESERVE             (0x0200)
-#define MPI2_SAS_DEVICE0_FLAGS_UNSUPPORTED_DEVICE           (0x0100)
-#define MPI2_SAS_DEVICE0_FLAGS_SATA_48BIT_LBA_SUPPORTED     (0x0080)
-#define MPI2_SAS_DEVICE0_FLAGS_SATA_SMART_SUPPORTED         (0x0040)
-#define MPI2_SAS_DEVICE0_FLAGS_SATA_NCQ_SUPPORTED           (0x0020)
-#define MPI2_SAS_DEVICE0_FLAGS_SATA_FUA_SUPPORTED           (0x0010)
-#define MPI2_SAS_DEVICE0_FLAGS_PORT_SELECTOR_ATTACH         (0x0008)
-#define MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID             (0x0002)
-#define MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT               (0x0001)
-
-
-/* SAS Device Page 1 */
-
-typedef struct _MPI2_CONFIG_PAGE_SAS_DEV_1
-{
-    MPI2_CONFIG_EXTENDED_PAGE_HEADER    Header;                 /* 0x00 */
-    U32                                 Reserved1;              /* 0x08 */
-    U64                                 SASAddress;             /* 0x0C */
-    U32                                 Reserved2;              /* 0x14 */
-    U16                                 DevHandle;              /* 0x18 */
-    U16                                 Reserved3;              /* 0x1A */
-    U8                                  InitialRegDeviceFIS[20];/* 0x1C */
-} MPI2_CONFIG_PAGE_SAS_DEV_1, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SAS_DEV_1,
-  Mpi2SasDevicePage1_t, MPI2_POINTER pMpi2SasDevicePage1_t;
-
-#define MPI2_SASDEVICE1_PAGEVERSION         (0x01)
-
-
-/****************************************************************************
-*   SAS PHY Config Pages
-****************************************************************************/
-
-/* SAS PHY Page 0 */
-
-typedef struct _MPI2_CONFIG_PAGE_SAS_PHY_0
-{
-    MPI2_CONFIG_EXTENDED_PAGE_HEADER    Header;                 /* 0x00 */
-    U16                                 OwnerDevHandle;         /* 0x08 */
-    U16                                 Reserved1;              /* 0x0A */
-    U16                                 AttachedDevHandle;      /* 0x0C */
-    U8                                  AttachedPhyIdentifier;  /* 0x0E */
-    U8                                  Reserved2;              /* 0x0F */
-    U32                                 AttachedPhyInfo;        /* 0x10 */
-    U8                                  ProgrammedLinkRate;     /* 0x14 */
-    U8                                  HwLinkRate;             /* 0x15 */
-    U8                                  ChangeCount;            /* 0x16 */
-    U8                                  Flags;                  /* 0x17 */
-    U32                                 PhyInfo;                /* 0x18 */
-    U8                                  NegotiatedLinkRate;     /* 0x1C */
-    U8                                  Reserved3;              /* 0x1D */
-    U16                                 Reserved4;              /* 0x1E */
-} MPI2_CONFIG_PAGE_SAS_PHY_0, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SAS_PHY_0,
-  Mpi2SasPhyPage0_t, MPI2_POINTER pMpi2SasPhyPage0_t;
-
-#define MPI2_SASPHY0_PAGEVERSION            (0x03)
-
-/* use MPI2_SAS_APHYINFO_ defines for AttachedPhyInfo field */
-
-/* use MPI2_SAS_PRATE_ defines for the ProgrammedLinkRate field */
-
-/* use MPI2_SAS_HWRATE_ defines for the HwLinkRate field */
-
-/* values for SAS PHY Page 0 Flags field */
-#define MPI2_SAS_PHY0_FLAGS_SGPIO_DIRECT_ATTACH_ENC             (0x01)
-
-/* use MPI2_SAS_PHYINFO_ for the PhyInfo field */
-
-/* use MPI2_SAS_NEG_LINK_RATE_ defines for the NegotiatedLinkRate field */
-
-
-/* SAS PHY Page 1 */
-
-typedef struct _MPI2_CONFIG_PAGE_SAS_PHY_1
-{
-    MPI2_CONFIG_EXTENDED_PAGE_HEADER    Header;                     /* 0x00 */
-    U32                                 Reserved1;                  /* 0x08 */
-    U32                                 InvalidDwordCount;          /* 0x0C */
-    U32                                 RunningDisparityErrorCount; /* 0x10 */
-    U32                                 LossDwordSynchCount;        /* 0x14 */
-    U32                                 PhyResetProblemCount;       /* 0x18 */
-} MPI2_CONFIG_PAGE_SAS_PHY_1, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SAS_PHY_1,
-  Mpi2SasPhyPage1_t, MPI2_POINTER pMpi2SasPhyPage1_t;
-
-#define MPI2_SASPHY1_PAGEVERSION            (0x01)
-
-
-/* SAS PHY Page 2 */
-
-typedef struct _MPI2_SASPHY2_PHY_EVENT {
-    U8          PhyEventCode;       /* 0x00 */
-    U8          Reserved1;          /* 0x01 */
-    U16         Reserved2;          /* 0x02 */
-    U32         PhyEventInfo;       /* 0x04 */
-} MPI2_SASPHY2_PHY_EVENT, MPI2_POINTER PTR_MPI2_SASPHY2_PHY_EVENT,
-  Mpi2SasPhy2PhyEvent_t, MPI2_POINTER pMpi2SasPhy2PhyEvent_t;
-
-/* use MPI2_SASPHY3_EVENT_CODE_ for the PhyEventCode field */
-
-
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check the value returned for NumPhyEvents at runtime.
- */
-#ifndef MPI2_SASPHY2_PHY_EVENT_MAX
-#define MPI2_SASPHY2_PHY_EVENT_MAX      (1)
-#endif
-
-typedef struct _MPI2_CONFIG_PAGE_SAS_PHY_2 {
-    MPI2_CONFIG_EXTENDED_PAGE_HEADER    Header;                     /* 0x00 */
-    U32                                 Reserved1;                  /* 0x08 */
-    U8                                  NumPhyEvents;               /* 0x0C */
-    U8                                  Reserved2;                  /* 0x0D */
-    U16                                 Reserved3;                  /* 0x0E */
-    MPI2_SASPHY2_PHY_EVENT              PhyEvent[MPI2_SASPHY2_PHY_EVENT_MAX];
-                                                               /* 0x10 */
-} MPI2_CONFIG_PAGE_SAS_PHY_2, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SAS_PHY_2,
-  Mpi2SasPhyPage2_t, MPI2_POINTER pMpi2SasPhyPage2_t;
-
-#define MPI2_SASPHY2_PAGEVERSION            (0x00)
-
-
-/* SAS PHY Page 3 */
-
-typedef struct _MPI2_SASPHY3_PHY_EVENT_CONFIG {
-    U8          PhyEventCode;       /* 0x00 */
-    U8          Reserved1;          /* 0x01 */
-    U16         Reserved2;          /* 0x02 */
-    U8          CounterType;        /* 0x04 */
-    U8          ThresholdWindow;    /* 0x05 */
-    U8          TimeUnits;          /* 0x06 */
-    U8          Reserved3;          /* 0x07 */
-    U32         EventThreshold;     /* 0x08 */
-    U16         ThresholdFlags;     /* 0x0C */
-    U16         Reserved4;          /* 0x0E */
-} MPI2_SASPHY3_PHY_EVENT_CONFIG, MPI2_POINTER PTR_MPI2_SASPHY3_PHY_EVENT_CONFIG,
-  Mpi2SasPhy3PhyEventConfig_t, MPI2_POINTER pMpi2SasPhy3PhyEventConfig_t;
-
-/* values for PhyEventCode field */
-#define MPI2_SASPHY3_EVENT_CODE_NO_EVENT                    (0x00)
-#define MPI2_SASPHY3_EVENT_CODE_INVALID_DWORD               (0x01)
-#define MPI2_SASPHY3_EVENT_CODE_RUNNING_DISPARITY_ERROR     (0x02)
-#define MPI2_SASPHY3_EVENT_CODE_LOSS_DWORD_SYNC             (0x03)
-#define MPI2_SASPHY3_EVENT_CODE_PHY_RESET_PROBLEM           (0x04)
-#define MPI2_SASPHY3_EVENT_CODE_ELASTICITY_BUF_OVERFLOW     (0x05)
-#define MPI2_SASPHY3_EVENT_CODE_RX_ERROR                    (0x06)
-#define MPI2_SASPHY3_EVENT_CODE_RX_ADDR_FRAME_ERROR         (0x20)
-#define MPI2_SASPHY3_EVENT_CODE_TX_AC_OPEN_REJECT           (0x21)
-#define MPI2_SASPHY3_EVENT_CODE_RX_AC_OPEN_REJECT           (0x22)
-#define MPI2_SASPHY3_EVENT_CODE_TX_RC_OPEN_REJECT           (0x23)
-#define MPI2_SASPHY3_EVENT_CODE_RX_RC_OPEN_REJECT           (0x24)
-#define MPI2_SASPHY3_EVENT_CODE_RX_AIP_PARTIAL_WAITING_ON   (0x25)
-#define MPI2_SASPHY3_EVENT_CODE_RX_AIP_CONNECT_WAITING_ON   (0x26)
-#define MPI2_SASPHY3_EVENT_CODE_TX_BREAK                    (0x27)
-#define MPI2_SASPHY3_EVENT_CODE_RX_BREAK                    (0x28)
-#define MPI2_SASPHY3_EVENT_CODE_BREAK_TIMEOUT               (0x29)
-#define MPI2_SASPHY3_EVENT_CODE_CONNECTION                  (0x2A)
-#define MPI2_SASPHY3_EVENT_CODE_PEAKTX_PATHWAY_BLOCKED      (0x2B)
-#define MPI2_SASPHY3_EVENT_CODE_PEAKTX_ARB_WAIT_TIME        (0x2C)
-#define MPI2_SASPHY3_EVENT_CODE_PEAK_ARB_WAIT_TIME          (0x2D)
-#define MPI2_SASPHY3_EVENT_CODE_PEAK_CONNECT_TIME           (0x2E)
-#define MPI2_SASPHY3_EVENT_CODE_TX_SSP_FRAMES               (0x40)
-#define MPI2_SASPHY3_EVENT_CODE_RX_SSP_FRAMES               (0x41)
-#define MPI2_SASPHY3_EVENT_CODE_TX_SSP_ERROR_FRAMES         (0x42)
-#define MPI2_SASPHY3_EVENT_CODE_RX_SSP_ERROR_FRAMES         (0x43)
-#define MPI2_SASPHY3_EVENT_CODE_TX_CREDIT_BLOCKED           (0x44)
-#define MPI2_SASPHY3_EVENT_CODE_RX_CREDIT_BLOCKED           (0x45)
-#define MPI2_SASPHY3_EVENT_CODE_TX_SATA_FRAMES              (0x50)
-#define MPI2_SASPHY3_EVENT_CODE_RX_SATA_FRAMES              (0x51)
-#define MPI2_SASPHY3_EVENT_CODE_SATA_OVERFLOW               (0x52)
-#define MPI2_SASPHY3_EVENT_CODE_TX_SMP_FRAMES               (0x60)
-#define MPI2_SASPHY3_EVENT_CODE_RX_SMP_FRAMES               (0x61)
-#define MPI2_SASPHY3_EVENT_CODE_RX_SMP_ERROR_FRAMES         (0x63)
-#define MPI2_SASPHY3_EVENT_CODE_HOTPLUG_TIMEOUT             (0xD0)
-#define MPI2_SASPHY3_EVENT_CODE_MISALIGNED_MUX_PRIMITIVE    (0xD1)
-#define MPI2_SASPHY3_EVENT_CODE_RX_AIP                      (0xD2)
-
-/* values for the CounterType field */
-#define MPI2_SASPHY3_COUNTER_TYPE_WRAPPING                  (0x00)
-#define MPI2_SASPHY3_COUNTER_TYPE_SATURATING                (0x01)
-#define MPI2_SASPHY3_COUNTER_TYPE_PEAK_VALUE                (0x02)
-
-/* values for the TimeUnits field */
-#define MPI2_SASPHY3_TIME_UNITS_10_MICROSECONDS             (0x00)
-#define MPI2_SASPHY3_TIME_UNITS_100_MICROSECONDS            (0x01)
-#define MPI2_SASPHY3_TIME_UNITS_1_MILLISECOND               (0x02)
-#define MPI2_SASPHY3_TIME_UNITS_10_MILLISECONDS             (0x03)
-
-/* values for the ThresholdFlags field */
-#define MPI2_SASPHY3_TFLAGS_PHY_RESET                       (0x0002)
-#define MPI2_SASPHY3_TFLAGS_EVENT_NOTIFY                    (0x0001)
-
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check the value returned for NumPhyEvents at runtime.
- */
-#ifndef MPI2_SASPHY3_PHY_EVENT_MAX
-#define MPI2_SASPHY3_PHY_EVENT_MAX      (1)
-#endif
-
-typedef struct _MPI2_CONFIG_PAGE_SAS_PHY_3 {
-    MPI2_CONFIG_EXTENDED_PAGE_HEADER    Header;                     /* 0x00 */
-    U32                                 Reserved1;                  /* 0x08 */
-    U8                                  NumPhyEvents;               /* 0x0C */
-    U8                                  Reserved2;                  /* 0x0D */
-    U16                                 Reserved3;                  /* 0x0E */
-    MPI2_SASPHY3_PHY_EVENT_CONFIG       PhyEventConfig
-                                       [MPI2_SASPHY3_PHY_EVENT_MAX]; /* 0x10 */
-} MPI2_CONFIG_PAGE_SAS_PHY_3, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SAS_PHY_3,
-  Mpi2SasPhyPage3_t, MPI2_POINTER pMpi2SasPhyPage3_t;
-
-#define MPI2_SASPHY3_PAGEVERSION            (0x00)
-
-
-/* SAS PHY Page 4 */
-
-typedef struct _MPI2_CONFIG_PAGE_SAS_PHY_4 {
-    MPI2_CONFIG_EXTENDED_PAGE_HEADER    Header;                     /* 0x00 */
-    U16                                 Reserved1;                  /* 0x08 */
-    U8                                  Reserved2;                  /* 0x0A */
-    U8                                  Flags;                      /* 0x0B */
-    U8                                  InitialFrame[28];           /* 0x0C */
-} MPI2_CONFIG_PAGE_SAS_PHY_4, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SAS_PHY_4,
-  Mpi2SasPhyPage4_t, MPI2_POINTER pMpi2SasPhyPage4_t;
-
-#define MPI2_SASPHY4_PAGEVERSION            (0x00)
-
-/* values for the Flags field */
-#define MPI2_SASPHY4_FLAGS_FRAME_VALID        (0x02)
-#define MPI2_SASPHY4_FLAGS_SATA_FRAME         (0x01)
-
-
-
-
-/****************************************************************************
-*   SAS Port Config Pages
-****************************************************************************/
-
-/* SAS Port Page 0 */
-
-typedef struct _MPI2_CONFIG_PAGE_SAS_PORT_0
-{
-    MPI2_CONFIG_EXTENDED_PAGE_HEADER    Header;                     /* 0x00 */
-    U8                                  PortNumber;                 /* 0x08 */
-    U8                                  PhysicalPort;               /* 0x09 */
-    U8                                  PortWidth;                  /* 0x0A */
-    U8                                  PhysicalPortWidth;          /* 0x0B */
-    U8                                  ZoneGroup;                  /* 0x0C */
-    U8                                  Reserved1;                  /* 0x0D */
-    U16                                 Reserved2;                  /* 0x0E */
-    U64                                 SASAddress;                 /* 0x10 */
-    U32                                 DeviceInfo;                 /* 0x18 */
-    U32                                 Reserved3;                  /* 0x1C */
-    U32                                 Reserved4;                  /* 0x20 */
-} MPI2_CONFIG_PAGE_SAS_PORT_0, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SAS_PORT_0,
-  Mpi2SasPortPage0_t, MPI2_POINTER pMpi2SasPortPage0_t;
-
-#define MPI2_SASPORT0_PAGEVERSION           (0x00)
-
-/* see mpi2_sas.h for values for SAS Port Page 0 DeviceInfo values */
-
-
-/****************************************************************************
-*   SAS Enclosure Config Pages
-****************************************************************************/
-
-/* SAS Enclosure Page 0 */
-
-typedef struct _MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0
-{
-    MPI2_CONFIG_EXTENDED_PAGE_HEADER    Header;                     /* 0x00 */
-    U32                                 Reserved1;                  /* 0x08 */
-    U64                                 EnclosureLogicalID;         /* 0x0C */
-    U16                                 Flags;                      /* 0x14 */
-    U16                                 EnclosureHandle;            /* 0x16 */
-    U16                                 NumSlots;                   /* 0x18 */
-    U16                                 StartSlot;                  /* 0x1A */
-       U8                               Reserved2;                  /* 0x1C */
-       U8                               EnclosureLevel;             /* 0x1D */
-    U16                                 SEPDevHandle;               /* 0x1E */
-    U32                                 Reserved3;                  /* 0x20 */
-    U32                                 Reserved4;                  /* 0x24 */
-} MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0,
-  MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0,
-  Mpi2SasEnclosurePage0_t, MPI2_POINTER pMpi2SasEnclosurePage0_t;
-
-#define MPI2_SASENCLOSURE0_PAGEVERSION      (0x04)
-
-/* values for SAS Enclosure Page 0 Flags field */
-#define MPI2_SAS_ENCLS0_FLAGS_ENCL_LEVEL_VALID      (0x0010)
-#define MPI2_SAS_ENCLS0_FLAGS_MNG_MASK              (0x000F)
-#define MPI2_SAS_ENCLS0_FLAGS_MNG_UNKNOWN           (0x0000)
-#define MPI2_SAS_ENCLS0_FLAGS_MNG_IOC_SES           (0x0001)
-#define MPI2_SAS_ENCLS0_FLAGS_MNG_IOC_SGPIO         (0x0002)
-#define MPI2_SAS_ENCLS0_FLAGS_MNG_EXP_SGPIO         (0x0003)
-#define MPI2_SAS_ENCLS0_FLAGS_MNG_SES_ENCLOSURE     (0x0004)
-#define MPI2_SAS_ENCLS0_FLAGS_MNG_IOC_GPIO          (0x0005)
-
-
-/****************************************************************************
-*   Log Config Page
-****************************************************************************/
-
-/* Log Page 0 */
-
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check the value returned for NumLogEntries at runtime.
- */
-#ifndef MPI2_LOG_0_NUM_LOG_ENTRIES
-#define MPI2_LOG_0_NUM_LOG_ENTRIES          (1)
-#endif
-
-#define MPI2_LOG_0_LOG_DATA_LENGTH          (0x1C)
-
-typedef struct _MPI2_LOG_0_ENTRY
-{
-    U64         TimeStamp;                          /* 0x00 */
-    U32         Reserved1;                          /* 0x08 */
-    U16         LogSequence;                        /* 0x0C */
-    U16         LogEntryQualifier;                  /* 0x0E */
-    U8          VP_ID;                              /* 0x10 */
-    U8          VF_ID;                              /* 0x11 */
-    U16         Reserved2;                          /* 0x12 */
-    U8          LogData[MPI2_LOG_0_LOG_DATA_LENGTH];/* 0x14 */
-} MPI2_LOG_0_ENTRY, MPI2_POINTER PTR_MPI2_LOG_0_ENTRY,
-  Mpi2Log0Entry_t, MPI2_POINTER pMpi2Log0Entry_t;
-
-/* values for Log Page 0 LogEntry LogEntryQualifier field */
-#define MPI2_LOG_0_ENTRY_QUAL_ENTRY_UNUSED          (0x0000)
-#define MPI2_LOG_0_ENTRY_QUAL_POWER_ON_RESET        (0x0001)
-#define MPI2_LOG_0_ENTRY_QUAL_TIMESTAMP_UPDATE      (0x0002)
-#define MPI2_LOG_0_ENTRY_QUAL_MIN_IMPLEMENT_SPEC    (0x8000)
-#define MPI2_LOG_0_ENTRY_QUAL_MAX_IMPLEMENT_SPEC    (0xFFFF)
-
-typedef struct _MPI2_CONFIG_PAGE_LOG_0
-{
-    MPI2_CONFIG_EXTENDED_PAGE_HEADER    Header;                     /* 0x00 */
-    U32                                 Reserved1;                  /* 0x08 */
-    U32                                 Reserved2;                  /* 0x0C */
-    U16                                 NumLogEntries;              /* 0x10 */
-    U16                                 Reserved3;                  /* 0x12 */
-    MPI2_LOG_0_ENTRY                    LogEntry[MPI2_LOG_0_NUM_LOG_ENTRIES]; /* 0x14 */
-} MPI2_CONFIG_PAGE_LOG_0, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_LOG_0,
-  Mpi2LogPage0_t, MPI2_POINTER pMpi2LogPage0_t;
-
-#define MPI2_LOG_0_PAGEVERSION              (0x02)
-
-
-/****************************************************************************
-*   RAID Config Page
-****************************************************************************/
-
-/* RAID Page 0 */
-
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check the value returned for NumElements at runtime.
- */
-#ifndef MPI2_RAIDCONFIG0_MAX_ELEMENTS
-#define MPI2_RAIDCONFIG0_MAX_ELEMENTS       (1)
-#endif
-
-typedef struct _MPI2_RAIDCONFIG0_CONFIG_ELEMENT
-{
-    U16                     ElementFlags;               /* 0x00 */
-    U16                     VolDevHandle;               /* 0x02 */
-    U8                      HotSparePool;               /* 0x04 */
-    U8                      PhysDiskNum;                /* 0x05 */
-    U16                     PhysDiskDevHandle;          /* 0x06 */
-} MPI2_RAIDCONFIG0_CONFIG_ELEMENT,
-  MPI2_POINTER PTR_MPI2_RAIDCONFIG0_CONFIG_ELEMENT,
-  Mpi2RaidConfig0ConfigElement_t, MPI2_POINTER pMpi2RaidConfig0ConfigElement_t;
-
-/* values for the ElementFlags field */
-#define MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE       (0x000F)
-#define MPI2_RAIDCONFIG0_EFLAGS_VOLUME_ELEMENT          (0x0000)
-#define MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT   (0x0001)
-#define MPI2_RAIDCONFIG0_EFLAGS_HOT_SPARE_ELEMENT       (0x0002)
-#define MPI2_RAIDCONFIG0_EFLAGS_OCE_ELEMENT             (0x0003)
-
-
-typedef struct _MPI2_CONFIG_PAGE_RAID_CONFIGURATION_0
-{
-    MPI2_CONFIG_EXTENDED_PAGE_HEADER    Header;                     /* 0x00 */
-    U8                                  NumHotSpares;               /* 0x08 */
-    U8                                  NumPhysDisks;               /* 0x09 */
-    U8                                  NumVolumes;                 /* 0x0A */
-    U8                                  ConfigNum;                  /* 0x0B */
-    U32                                 Flags;                      /* 0x0C */
-    U8                                  ConfigGUID[24];             /* 0x10 */
-    U32                                 Reserved1;                  /* 0x28 */
-    U8                                  NumElements;                /* 0x2C */
-    U8                                  Reserved2;                  /* 0x2D */
-    U16                                 Reserved3;                  /* 0x2E */
-    MPI2_RAIDCONFIG0_CONFIG_ELEMENT     ConfigElement[MPI2_RAIDCONFIG0_MAX_ELEMENTS]; /* 0x30 */
-} MPI2_CONFIG_PAGE_RAID_CONFIGURATION_0,
-  MPI2_POINTER PTR_MPI2_CONFIG_PAGE_RAID_CONFIGURATION_0,
-  Mpi2RaidConfigurationPage0_t, MPI2_POINTER pMpi2RaidConfigurationPage0_t;
-
-#define MPI2_RAIDCONFIG0_PAGEVERSION            (0x00)
-
-/* values for RAID Configuration Page 0 Flags field */
-#define MPI2_RAIDCONFIG0_FLAG_FOREIGN_CONFIG        (0x00000001)
-
-
-/****************************************************************************
-*   Driver Persistent Mapping Config Pages
-****************************************************************************/
-
-/* Driver Persistent Mapping Page 0 */
-
-typedef struct _MPI2_CONFIG_PAGE_DRIVER_MAP0_ENTRY
-{
-    U64                                 PhysicalIdentifier;         /* 0x00 */
-    U16                                 MappingInformation;         /* 0x08 */
-    U16                                 DeviceIndex;                /* 0x0A */
-    U32                                 PhysicalBitsMapping;        /* 0x0C */
-    U32                                 Reserved1;                  /* 0x10 */
-} MPI2_CONFIG_PAGE_DRIVER_MAP0_ENTRY,
-  MPI2_POINTER PTR_MPI2_CONFIG_PAGE_DRIVER_MAP0_ENTRY,
-  Mpi2DriverMap0Entry_t, MPI2_POINTER pMpi2DriverMap0Entry_t;
-
-typedef struct _MPI2_CONFIG_PAGE_DRIVER_MAPPING_0
-{
-    MPI2_CONFIG_EXTENDED_PAGE_HEADER    Header;                     /* 0x00 */
-    MPI2_CONFIG_PAGE_DRIVER_MAP0_ENTRY  Entry;                      /* 0x08 */
-} MPI2_CONFIG_PAGE_DRIVER_MAPPING_0,
-  MPI2_POINTER PTR_MPI2_CONFIG_PAGE_DRIVER_MAPPING_0,
-  Mpi2DriverMappingPage0_t, MPI2_POINTER pMpi2DriverMappingPage0_t;
-
-#define MPI2_DRIVERMAPPING0_PAGEVERSION         (0x00)
-
-/* values for Driver Persistent Mapping Page 0 MappingInformation field */
-#define MPI2_DRVMAP0_MAPINFO_SLOT_MASK              (0x07F0)
-#define MPI2_DRVMAP0_MAPINFO_SLOT_SHIFT             (4)
-#define MPI2_DRVMAP0_MAPINFO_MISSING_MASK           (0x000F)
-
-
-/****************************************************************************
-*   Ethernet Config Pages
-****************************************************************************/
-
-/* Ethernet Page 0 */
-
-/* IP address (union of IPv4 and IPv6) */
-typedef union _MPI2_ETHERNET_IP_ADDR {
-    U32     IPv4Addr;
-    U32     IPv6Addr[4];
-} MPI2_ETHERNET_IP_ADDR, MPI2_POINTER PTR_MPI2_ETHERNET_IP_ADDR,
-  Mpi2EthernetIpAddr_t, MPI2_POINTER pMpi2EthernetIpAddr_t;
-
-#define MPI2_ETHERNET_HOST_NAME_LENGTH          (32)
-
-typedef struct _MPI2_CONFIG_PAGE_ETHERNET_0 {
-    MPI2_CONFIG_EXTENDED_PAGE_HEADER    Header;                 /* 0x00 */
-    U8                                  NumInterfaces;          /* 0x08 */
-    U8                                  Reserved0;              /* 0x09 */
-    U16                                 Reserved1;              /* 0x0A */
-    U32                                 Status;                 /* 0x0C */
-    U8                                  MediaState;             /* 0x10 */
-    U8                                  Reserved2;              /* 0x11 */
-    U16                                 Reserved3;              /* 0x12 */
-    U8                                  MacAddress[6];          /* 0x14 */
-    U8                                  Reserved4;              /* 0x1A */
-    U8                                  Reserved5;              /* 0x1B */
-    MPI2_ETHERNET_IP_ADDR               IpAddress;              /* 0x1C */
-    MPI2_ETHERNET_IP_ADDR               SubnetMask;             /* 0x2C */
-    MPI2_ETHERNET_IP_ADDR               GatewayIpAddress;       /* 0x3C */
-    MPI2_ETHERNET_IP_ADDR               DNS1IpAddress;          /* 0x4C */
-    MPI2_ETHERNET_IP_ADDR               DNS2IpAddress;          /* 0x5C */
-    MPI2_ETHERNET_IP_ADDR               DhcpIpAddress;          /* 0x6C */
-    U8                                  HostName
-                               [MPI2_ETHERNET_HOST_NAME_LENGTH];/* 0x7C */
-} MPI2_CONFIG_PAGE_ETHERNET_0, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_ETHERNET_0,
-  Mpi2EthernetPage0_t, MPI2_POINTER pMpi2EthernetPage0_t;
-
-#define MPI2_ETHERNETPAGE0_PAGEVERSION   (0x00)
-
-/* values for Ethernet Page 0 Status field */
-#define MPI2_ETHPG0_STATUS_IPV6_CAPABLE             (0x80000000)
-#define MPI2_ETHPG0_STATUS_IPV4_CAPABLE             (0x40000000)
-#define MPI2_ETHPG0_STATUS_CONSOLE_CONNECTED        (0x20000000)
-#define MPI2_ETHPG0_STATUS_DEFAULT_IF               (0x00000100)
-#define MPI2_ETHPG0_STATUS_FW_DWNLD_ENABLED         (0x00000080)
-#define MPI2_ETHPG0_STATUS_TELNET_ENABLED           (0x00000040)
-#define MPI2_ETHPG0_STATUS_SSH2_ENABLED             (0x00000020)
-#define MPI2_ETHPG0_STATUS_DHCP_CLIENT_ENABLED      (0x00000010)
-#define MPI2_ETHPG0_STATUS_IPV6_ENABLED             (0x00000008)
-#define MPI2_ETHPG0_STATUS_IPV4_ENABLED             (0x00000004)
-#define MPI2_ETHPG0_STATUS_IPV6_ADDRESSES           (0x00000002)
-#define MPI2_ETHPG0_STATUS_ETH_IF_ENABLED           (0x00000001)
-
-/* values for Ethernet Page 0 MediaState field */
-#define MPI2_ETHPG0_MS_DUPLEX_MASK                  (0x80)
-#define MPI2_ETHPG0_MS_HALF_DUPLEX                  (0x00)
-#define MPI2_ETHPG0_MS_FULL_DUPLEX                  (0x80)
-
-#define MPI2_ETHPG0_MS_CONNECT_SPEED_MASK           (0x07)
-#define MPI2_ETHPG0_MS_NOT_CONNECTED                (0x00)
-#define MPI2_ETHPG0_MS_10MBIT                       (0x01)
-#define MPI2_ETHPG0_MS_100MBIT                      (0x02)
-#define MPI2_ETHPG0_MS_1GBIT                        (0x03)
-
-
-/* Ethernet Page 1 */
-
-typedef struct _MPI2_CONFIG_PAGE_ETHERNET_1 {
-    MPI2_CONFIG_EXTENDED_PAGE_HEADER    Header;                 /* 0x00 */
-    U32                                 Reserved0;              /* 0x08 */
-    U32                                 Flags;                  /* 0x0C */
-    U8                                  MediaState;             /* 0x10 */
-    U8                                  Reserved1;              /* 0x11 */
-    U16                                 Reserved2;              /* 0x12 */
-    U8                                  MacAddress[6];          /* 0x14 */
-    U8                                  Reserved3;              /* 0x1A */
-    U8                                  Reserved4;              /* 0x1B */
-    MPI2_ETHERNET_IP_ADDR               StaticIpAddress;        /* 0x1C */
-    MPI2_ETHERNET_IP_ADDR               StaticSubnetMask;       /* 0x2C */
-    MPI2_ETHERNET_IP_ADDR               StaticGatewayIpAddress; /* 0x3C */
-    MPI2_ETHERNET_IP_ADDR               StaticDNS1IpAddress;    /* 0x4C */
-    MPI2_ETHERNET_IP_ADDR               StaticDNS2IpAddress;    /* 0x5C */
-    U32                                 Reserved5;              /* 0x6C */
-    U32                                 Reserved6;              /* 0x70 */
-    U32                                 Reserved7;              /* 0x74 */
-    U32                                 Reserved8;              /* 0x78 */
-    U8                                  HostName
-                               [MPI2_ETHERNET_HOST_NAME_LENGTH];/* 0x7C */
-} MPI2_CONFIG_PAGE_ETHERNET_1, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_ETHERNET_1,
-  Mpi2EthernetPage1_t, MPI2_POINTER pMpi2EthernetPage1_t;
-
-#define MPI2_ETHERNETPAGE1_PAGEVERSION   (0x00)
-
-/* values for Ethernet Page 1 Flags field */
-#define MPI2_ETHPG1_FLAG_SET_DEFAULT_IF             (0x00000100)
-#define MPI2_ETHPG1_FLAG_ENABLE_FW_DOWNLOAD         (0x00000080)
-#define MPI2_ETHPG1_FLAG_ENABLE_TELNET              (0x00000040)
-#define MPI2_ETHPG1_FLAG_ENABLE_SSH2                (0x00000020)
-#define MPI2_ETHPG1_FLAG_ENABLE_DHCP_CLIENT         (0x00000010)
-#define MPI2_ETHPG1_FLAG_ENABLE_IPV6                (0x00000008)
-#define MPI2_ETHPG1_FLAG_ENABLE_IPV4                (0x00000004)
-#define MPI2_ETHPG1_FLAG_USE_IPV6_ADDRESSES         (0x00000002)
-#define MPI2_ETHPG1_FLAG_ENABLE_ETH_IF              (0x00000001)
-
-/* values for Ethernet Page 1 MediaState field */
-#define MPI2_ETHPG1_MS_DUPLEX_MASK                  (0x80)
-#define MPI2_ETHPG1_MS_HALF_DUPLEX                  (0x00)
-#define MPI2_ETHPG1_MS_FULL_DUPLEX                  (0x80)
-
-#define MPI2_ETHPG1_MS_DATA_RATE_MASK               (0x07)
-#define MPI2_ETHPG1_MS_DATA_RATE_AUTO               (0x00)
-#define MPI2_ETHPG1_MS_DATA_RATE_10MBIT             (0x01)
-#define MPI2_ETHPG1_MS_DATA_RATE_100MBIT            (0x02)
-#define MPI2_ETHPG1_MS_DATA_RATE_1GBIT              (0x03)
-
-
-/****************************************************************************
-*   Extended Manufacturing Config Pages
-****************************************************************************/
-
-/*
- * Generic structure to use for product-specific extended manufacturing pages
- * (currently Extended Manufacturing Page 40 through Extended Manufacturing
- * Page 60).
- */
-
-typedef struct _MPI2_CONFIG_PAGE_EXT_MAN_PS {
-       MPI2_CONFIG_EXTENDED_PAGE_HEADER    Header;                 /* 0x00 */
-       U32                                 ProductSpecificInfo;    /* 0x08 */
-}      MPI2_CONFIG_PAGE_EXT_MAN_PS,
-       MPI2_POINTER PTR_MPI2_CONFIG_PAGE_EXT_MAN_PS,
-       Mpi2ExtManufacturingPagePS_t,
-       MPI2_POINTER pMpi2ExtManufacturingPagePS_t;
-
-/* PageVersion should be provided by product-specific code */
-
-#endif
-
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_init.h b/drivers/scsi/mpt2sas/mpi/mpi2_init.h
deleted file mode 100644 (file)
index eea1a16..0000000
+++ /dev/null
@@ -1,461 +0,0 @@
-/*
- *  Copyright (c) 2000-2014 LSI Corporation.
- *
- *
- *           Name:  mpi2_init.h
- *          Title:  MPI SCSI initiator mode messages and structures
- *  Creation Date:  June 23, 2006
- *
- *    mpi2_init.h Version:  02.00.15
- *
- *  Version History
- *  ---------------
- *
- *  Date      Version   Description
- *  --------  --------  ------------------------------------------------------
- *  04-30-07  02.00.00  Corresponds to Fusion-MPT MPI Specification Rev A.
- *  10-31-07  02.00.01  Fixed name for pMpi2SCSITaskManagementRequest_t.
- *  12-18-07  02.00.02  Modified Task Management Target Reset Method defines.
- *  02-29-08  02.00.03  Added Query Task Set and Query Unit Attention.
- *  03-03-08  02.00.04  Fixed name of struct _MPI2_SCSI_TASK_MANAGE_REPLY.
- *  05-21-08  02.00.05  Fixed typo in name of Mpi2SepRequest_t.
- *  10-02-08  02.00.06  Removed Untagged and No Disconnect values from SCSI IO
- *                      Control field Task Attribute flags.
- *                      Moved LUN field defines to mpi2.h because they are
- *                      common to many structures.
- *  05-06-09  02.00.07  Changed task management type of Query Unit Attention to
- *                      Query Asynchronous Event.
- *                      Defined two new bits in the SlotStatus field of the SCSI
- *                      Enclosure Processor Request and Reply.
- *  10-28-09  02.00.08  Added defines for decoding the ResponseInfo bytes for
- *                      both SCSI IO Error Reply and SCSI Task Management Reply.
- *                      Added ResponseInfo field to MPI2_SCSI_TASK_MANAGE_REPLY.
- *                      Added MPI2_SCSITASKMGMT_RSP_TM_OVERLAPPED_TAG define.
- *  02-10-10  02.00.09  Removed unused structure that had "#if 0" around it.
- *  05-12-10  02.00.10  Added optional vendor-unique region to SCSI IO Request.
- *  11-10-10  02.00.11  Added MPI2_SCSIIO_NUM_SGLOFFSETS define.
- *  02-06-12  02.00.13  Added alternate defines for Task Priority / Command
- *                      Priority to match SAM-4.
- *  07-10-12  02.00.14  Added MPI2_SCSIIO_CONTROL_SHIFT_DATADIRECTION.
- *  04-09-13  02.00.15  Added SCSIStatusQualifier field to MPI2_SCSI_IO_REPLY,
- *                     replacing the Reserved4 field.
- *  --------------------------------------------------------------------------
- */
-
-#ifndef MPI2_INIT_H
-#define MPI2_INIT_H
-
-/*****************************************************************************
-*
-*               SCSI Initiator Messages
-*
-*****************************************************************************/
-
-/****************************************************************************
-*  SCSI IO messages and associated structures
-****************************************************************************/
-
-typedef struct
-{
-    U8                      CDB[20];                    /* 0x00 */
-    U32                     PrimaryReferenceTag;        /* 0x14 */
-    U16                     PrimaryApplicationTag;      /* 0x18 */
-    U16                     PrimaryApplicationTagMask;  /* 0x1A */
-    U32                     TransferLength;             /* 0x1C */
-} MPI2_SCSI_IO_CDB_EEDP32, MPI2_POINTER PTR_MPI2_SCSI_IO_CDB_EEDP32,
-  Mpi2ScsiIoCdbEedp32_t, MPI2_POINTER pMpi2ScsiIoCdbEedp32_t;
-
-typedef union
-{
-    U8                      CDB32[32];
-    MPI2_SCSI_IO_CDB_EEDP32 EEDP32;
-    MPI2_SGE_SIMPLE_UNION   SGE;
-} MPI2_SCSI_IO_CDB_UNION, MPI2_POINTER PTR_MPI2_SCSI_IO_CDB_UNION,
-  Mpi2ScsiIoCdb_t, MPI2_POINTER pMpi2ScsiIoCdb_t;
-
-/* SCSI IO Request Message */
-typedef struct _MPI2_SCSI_IO_REQUEST
-{
-    U16                     DevHandle;                      /* 0x00 */
-    U8                      ChainOffset;                    /* 0x02 */
-    U8                      Function;                       /* 0x03 */
-    U16                     Reserved1;                      /* 0x04 */
-    U8                      Reserved2;                      /* 0x06 */
-    U8                      MsgFlags;                       /* 0x07 */
-    U8                      VP_ID;                          /* 0x08 */
-    U8                      VF_ID;                          /* 0x09 */
-    U16                     Reserved3;                      /* 0x0A */
-    U32                     SenseBufferLowAddress;          /* 0x0C */
-    U16                     SGLFlags;                       /* 0x10 */
-    U8                      SenseBufferLength;              /* 0x12 */
-    U8                      Reserved4;                      /* 0x13 */
-    U8                      SGLOffset0;                     /* 0x14 */
-    U8                      SGLOffset1;                     /* 0x15 */
-    U8                      SGLOffset2;                     /* 0x16 */
-    U8                      SGLOffset3;                     /* 0x17 */
-    U32                     SkipCount;                      /* 0x18 */
-    U32                     DataLength;                     /* 0x1C */
-    U32                     BidirectionalDataLength;        /* 0x20 */
-    U16                     IoFlags;                        /* 0x24 */
-    U16                     EEDPFlags;                      /* 0x26 */
-    U32                     EEDPBlockSize;                  /* 0x28 */
-    U32                     SecondaryReferenceTag;          /* 0x2C */
-    U16                     SecondaryApplicationTag;        /* 0x30 */
-    U16                     ApplicationTagTranslationMask;  /* 0x32 */
-    U8                      LUN[8];                         /* 0x34 */
-    U32                     Control;                        /* 0x3C */
-    MPI2_SCSI_IO_CDB_UNION  CDB;                            /* 0x40 */
-
-#ifdef MPI2_SCSI_IO_VENDOR_UNIQUE_REGION /* typically this is left undefined */
-       MPI2_SCSI_IO_VENDOR_UNIQUE VendorRegion;
-#endif
-
-    MPI2_SGE_IO_UNION       SGL;                            /* 0x60 */
-
-} MPI2_SCSI_IO_REQUEST, MPI2_POINTER PTR_MPI2_SCSI_IO_REQUEST,
-  Mpi2SCSIIORequest_t, MPI2_POINTER pMpi2SCSIIORequest_t;
-
-/* SCSI IO MsgFlags bits */
-
-/* MsgFlags for SenseBufferAddressSpace */
-#define MPI2_SCSIIO_MSGFLAGS_MASK_SENSE_ADDR        (0x0C)
-#define MPI2_SCSIIO_MSGFLAGS_SYSTEM_SENSE_ADDR      (0x00)
-#define MPI2_SCSIIO_MSGFLAGS_IOCDDR_SENSE_ADDR      (0x04)
-#define MPI2_SCSIIO_MSGFLAGS_IOCPLB_SENSE_ADDR      (0x08)
-#define MPI2_SCSIIO_MSGFLAGS_IOCPLBNTA_SENSE_ADDR   (0x0C)
-
-/* SCSI IO SGLFlags bits */
-
-/* base values for Data Location Address Space */
-#define MPI2_SCSIIO_SGLFLAGS_ADDR_MASK              (0x0C)
-#define MPI2_SCSIIO_SGLFLAGS_SYSTEM_ADDR            (0x00)
-#define MPI2_SCSIIO_SGLFLAGS_IOCDDR_ADDR            (0x04)
-#define MPI2_SCSIIO_SGLFLAGS_IOCPLB_ADDR            (0x08)
-#define MPI2_SCSIIO_SGLFLAGS_IOCPLBNTA_ADDR         (0x0C)
-
-/* base values for Type */
-#define MPI2_SCSIIO_SGLFLAGS_TYPE_MASK              (0x03)
-#define MPI2_SCSIIO_SGLFLAGS_TYPE_MPI               (0x00)
-#define MPI2_SCSIIO_SGLFLAGS_TYPE_IEEE32            (0x01)
-#define MPI2_SCSIIO_SGLFLAGS_TYPE_IEEE64            (0x02)
-
-/* shift values for each sub-field */
-#define MPI2_SCSIIO_SGLFLAGS_SGL3_SHIFT             (12)
-#define MPI2_SCSIIO_SGLFLAGS_SGL2_SHIFT             (8)
-#define MPI2_SCSIIO_SGLFLAGS_SGL1_SHIFT             (4)
-#define MPI2_SCSIIO_SGLFLAGS_SGL0_SHIFT             (0)
-
-/* number of SGLOffset fields */
-#define MPI2_SCSIIO_NUM_SGLOFFSETS                  (4)
-
-/* SCSI IO IoFlags bits */
-
-/* Large CDB Address Space */
-#define MPI2_SCSIIO_CDB_ADDR_MASK                   (0x6000)
-#define MPI2_SCSIIO_CDB_ADDR_SYSTEM                 (0x0000)
-#define MPI2_SCSIIO_CDB_ADDR_IOCDDR                 (0x2000)
-#define MPI2_SCSIIO_CDB_ADDR_IOCPLB                 (0x4000)
-#define MPI2_SCSIIO_CDB_ADDR_IOCPLBNTA              (0x6000)
-
-#define MPI2_SCSIIO_IOFLAGS_LARGE_CDB               (0x1000)
-#define MPI2_SCSIIO_IOFLAGS_BIDIRECTIONAL           (0x0800)
-#define MPI2_SCSIIO_IOFLAGS_MULTICAST               (0x0400)
-#define MPI2_SCSIIO_IOFLAGS_CMD_DETERMINES_DATA_DIR (0x0200)
-#define MPI2_SCSIIO_IOFLAGS_CDBLENGTH_MASK          (0x01FF)
-
-/* SCSI IO EEDPFlags bits */
-
-#define MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG        (0x8000)
-#define MPI2_SCSIIO_EEDPFLAGS_INC_SEC_REFTAG        (0x4000)
-#define MPI2_SCSIIO_EEDPFLAGS_INC_PRI_APPTAG        (0x2000)
-#define MPI2_SCSIIO_EEDPFLAGS_INC_SEC_APPTAG        (0x1000)
-
-#define MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG          (0x0400)
-#define MPI2_SCSIIO_EEDPFLAGS_CHECK_APPTAG          (0x0200)
-#define MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD           (0x0100)
-
-#define MPI2_SCSIIO_EEDPFLAGS_PASSTHRU_REFTAG       (0x0008)
-
-#define MPI2_SCSIIO_EEDPFLAGS_MASK_OP               (0x0007)
-#define MPI2_SCSIIO_EEDPFLAGS_NOOP_OP               (0x0000)
-#define MPI2_SCSIIO_EEDPFLAGS_CHECK_OP              (0x0001)
-#define MPI2_SCSIIO_EEDPFLAGS_STRIP_OP              (0x0002)
-#define MPI2_SCSIIO_EEDPFLAGS_CHECK_REMOVE_OP       (0x0003)
-#define MPI2_SCSIIO_EEDPFLAGS_INSERT_OP             (0x0004)
-#define MPI2_SCSIIO_EEDPFLAGS_REPLACE_OP            (0x0006)
-#define MPI2_SCSIIO_EEDPFLAGS_CHECK_REGEN_OP        (0x0007)
-
-/* SCSI IO LUN fields: use MPI2_LUN_ from mpi2.h */
-
-/* SCSI IO Control bits */
-#define MPI2_SCSIIO_CONTROL_ADDCDBLEN_MASK      (0xFC000000)
-#define MPI2_SCSIIO_CONTROL_ADDCDBLEN_SHIFT     (26)
-
-#define MPI2_SCSIIO_CONTROL_DATADIRECTION_MASK  (0x03000000)
-#define MPI2_SCSIIO_CONTROL_SHIFT_DATADIRECTION (24)
-#define MPI2_SCSIIO_CONTROL_NODATATRANSFER      (0x00000000)
-#define MPI2_SCSIIO_CONTROL_WRITE               (0x01000000)
-#define MPI2_SCSIIO_CONTROL_READ                (0x02000000)
-#define MPI2_SCSIIO_CONTROL_BIDIRECTIONAL       (0x03000000)
-
-#define MPI2_SCSIIO_CONTROL_TASKPRI_MASK        (0x00007800)
-#define MPI2_SCSIIO_CONTROL_TASKPRI_SHIFT       (11)
-/* alternate name for the previous field; called Command Priority in SAM-4 */
-#define MPI2_SCSIIO_CONTROL_CMDPRI_MASK         (0x00007800)
-#define MPI2_SCSIIO_CONTROL_CMDPRI_SHIFT        (11)
-
-#define MPI2_SCSIIO_CONTROL_TASKATTRIBUTE_MASK  (0x00000700)
-#define MPI2_SCSIIO_CONTROL_SIMPLEQ             (0x00000000)
-#define MPI2_SCSIIO_CONTROL_HEADOFQ             (0x00000100)
-#define MPI2_SCSIIO_CONTROL_ORDEREDQ            (0x00000200)
-#define MPI2_SCSIIO_CONTROL_ACAQ                (0x00000400)
-
-#define MPI2_SCSIIO_CONTROL_TLR_MASK            (0x000000C0)
-#define MPI2_SCSIIO_CONTROL_NO_TLR              (0x00000000)
-#define MPI2_SCSIIO_CONTROL_TLR_ON              (0x00000040)
-#define MPI2_SCSIIO_CONTROL_TLR_OFF             (0x00000080)
-
-
-/* SCSI IO Error Reply Message */
-typedef struct _MPI2_SCSI_IO_REPLY
-{
-    U16                     DevHandle;                      /* 0x00 */
-    U8                      MsgLength;                      /* 0x02 */
-    U8                      Function;                       /* 0x03 */
-    U16                     Reserved1;                      /* 0x04 */
-    U8                      Reserved2;                      /* 0x06 */
-    U8                      MsgFlags;                       /* 0x07 */
-    U8                      VP_ID;                          /* 0x08 */
-    U8                      VF_ID;                          /* 0x09 */
-    U16                     Reserved3;                      /* 0x0A */
-    U8                      SCSIStatus;                     /* 0x0C */
-    U8                      SCSIState;                      /* 0x0D */
-    U16                     IOCStatus;                      /* 0x0E */
-    U32                     IOCLogInfo;                     /* 0x10 */
-    U32                     TransferCount;                  /* 0x14 */
-    U32                     SenseCount;                     /* 0x18 */
-    U32                     ResponseInfo;                   /* 0x1C */
-    U16                     TaskTag;                        /* 0x20 */
-       U16                     SCSIStatusQualifier;         /* 0x22 */
-    U32                     BidirectionalTransferCount;     /* 0x24 */
-    U32                     Reserved5;                      /* 0x28 */
-    U32                     Reserved6;                      /* 0x2C */
-} MPI2_SCSI_IO_REPLY, MPI2_POINTER PTR_MPI2_SCSI_IO_REPLY,
-  Mpi2SCSIIOReply_t, MPI2_POINTER pMpi2SCSIIOReply_t;
-
-/* SCSI IO Reply SCSIStatus values (SAM-4 status codes) */
-
-#define MPI2_SCSI_STATUS_GOOD                   (0x00)
-#define MPI2_SCSI_STATUS_CHECK_CONDITION        (0x02)
-#define MPI2_SCSI_STATUS_CONDITION_MET          (0x04)
-#define MPI2_SCSI_STATUS_BUSY                   (0x08)
-#define MPI2_SCSI_STATUS_INTERMEDIATE           (0x10)
-#define MPI2_SCSI_STATUS_INTERMEDIATE_CONDMET   (0x14)
-#define MPI2_SCSI_STATUS_RESERVATION_CONFLICT   (0x18)
-#define MPI2_SCSI_STATUS_COMMAND_TERMINATED     (0x22) /* obsolete */
-#define MPI2_SCSI_STATUS_TASK_SET_FULL          (0x28)
-#define MPI2_SCSI_STATUS_ACA_ACTIVE             (0x30)
-#define MPI2_SCSI_STATUS_TASK_ABORTED           (0x40)
-
-/* SCSI IO Reply SCSIState flags */
-
-#define MPI2_SCSI_STATE_RESPONSE_INFO_VALID     (0x10)
-#define MPI2_SCSI_STATE_TERMINATED              (0x08)
-#define MPI2_SCSI_STATE_NO_SCSI_STATUS          (0x04)
-#define MPI2_SCSI_STATE_AUTOSENSE_FAILED        (0x02)
-#define MPI2_SCSI_STATE_AUTOSENSE_VALID         (0x01)
-
-/* masks and shifts for the ResponseInfo field */
-
-#define MPI2_SCSI_RI_MASK_REASONCODE            (0x000000FF)
-#define MPI2_SCSI_RI_SHIFT_REASONCODE           (0)
-
-#define MPI2_SCSI_TASKTAG_UNKNOWN               (0xFFFF)
-
-
-/****************************************************************************
-*  SCSI Task Management messages
-****************************************************************************/
-
-/* SCSI Task Management Request Message */
-typedef struct _MPI2_SCSI_TASK_MANAGE_REQUEST
-{
-    U16                     DevHandle;                      /* 0x00 */
-    U8                      ChainOffset;                    /* 0x02 */
-    U8                      Function;                       /* 0x03 */
-    U8                      Reserved1;                      /* 0x04 */
-    U8                      TaskType;                       /* 0x05 */
-    U8                      Reserved2;                      /* 0x06 */
-    U8                      MsgFlags;                       /* 0x07 */
-    U8                      VP_ID;                          /* 0x08 */
-    U8                      VF_ID;                          /* 0x09 */
-    U16                     Reserved3;                      /* 0x0A */
-    U8                      LUN[8];                         /* 0x0C */
-    U32                     Reserved4[7];                   /* 0x14 */
-    U16                     TaskMID;                        /* 0x30 */
-    U16                     Reserved5;                      /* 0x32 */
-} MPI2_SCSI_TASK_MANAGE_REQUEST,
-  MPI2_POINTER PTR_MPI2_SCSI_TASK_MANAGE_REQUEST,
-  Mpi2SCSITaskManagementRequest_t,
-  MPI2_POINTER pMpi2SCSITaskManagementRequest_t;
-
-/* TaskType values */
-
-#define MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK           (0x01)
-#define MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET        (0x02)
-#define MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET         (0x03)
-#define MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET   (0x05)
-#define MPI2_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET       (0x06)
-#define MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK           (0x07)
-#define MPI2_SCSITASKMGMT_TASKTYPE_CLR_ACA              (0x08)
-#define MPI2_SCSITASKMGMT_TASKTYPE_QRY_TASK_SET         (0x09)
-#define MPI2_SCSITASKMGMT_TASKTYPE_QRY_ASYNC_EVENT      (0x0A)
-
-/* obsolete TaskType name */
-#define MPI2_SCSITASKMGMT_TASKTYPE_QRY_UNIT_ATTENTION  \
-       (MPI2_SCSITASKMGMT_TASKTYPE_QRY_ASYNC_EVENT)
-
-/* MsgFlags bits */
-
-#define MPI2_SCSITASKMGMT_MSGFLAGS_MASK_TARGET_RESET    (0x18)
-#define MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET           (0x00)
-#define MPI2_SCSITASKMGMT_MSGFLAGS_NEXUS_RESET_SRST     (0x08)
-#define MPI2_SCSITASKMGMT_MSGFLAGS_SAS_HARD_LINK_RESET  (0x10)
-
-#define MPI2_SCSITASKMGMT_MSGFLAGS_DO_NOT_SEND_TASK_IU  (0x01)
-
-
-
-/* SCSI Task Management Reply Message */
-typedef struct _MPI2_SCSI_TASK_MANAGE_REPLY
-{
-    U16                     DevHandle;                      /* 0x00 */
-    U8                      MsgLength;                      /* 0x02 */
-    U8                      Function;                       /* 0x03 */
-    U8                      ResponseCode;                   /* 0x04 */
-    U8                      TaskType;                       /* 0x05 */
-    U8                      Reserved1;                      /* 0x06 */
-    U8                      MsgFlags;                       /* 0x07 */
-    U8                      VP_ID;                          /* 0x08 */
-    U8                      VF_ID;                          /* 0x09 */
-    U16                     Reserved2;                      /* 0x0A */
-    U16                     Reserved3;                      /* 0x0C */
-    U16                     IOCStatus;                      /* 0x0E */
-    U32                     IOCLogInfo;                     /* 0x10 */
-    U32                     TerminationCount;               /* 0x14 */
-    U32                     ResponseInfo;                   /* 0x18 */
-} MPI2_SCSI_TASK_MANAGE_REPLY,
-  MPI2_POINTER PTR_MPI2_SCSI_TASK_MANAGE_REPLY,
-  Mpi2SCSITaskManagementReply_t, MPI2_POINTER pMpi2SCSIManagementReply_t;
-
-/* ResponseCode values */
-
-#define MPI2_SCSITASKMGMT_RSP_TM_COMPLETE               (0x00)
-#define MPI2_SCSITASKMGMT_RSP_INVALID_FRAME             (0x02)
-#define MPI2_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED          (0x04)
-#define MPI2_SCSITASKMGMT_RSP_TM_FAILED                 (0x05)
-#define MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED              (0x08)
-#define MPI2_SCSITASKMGMT_RSP_TM_INVALID_LUN            (0x09)
-#define MPI2_SCSITASKMGMT_RSP_TM_OVERLAPPED_TAG         (0x0A)
-#define MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC          (0x80)
-
-/* masks and shifts for the ResponseInfo field */
-
-#define MPI2_SCSITASKMGMT_RI_MASK_REASONCODE            (0x000000FF)
-#define MPI2_SCSITASKMGMT_RI_SHIFT_REASONCODE           (0)
-#define MPI2_SCSITASKMGMT_RI_MASK_ARI2                  (0x0000FF00)
-#define MPI2_SCSITASKMGMT_RI_SHIFT_ARI2                 (8)
-#define MPI2_SCSITASKMGMT_RI_MASK_ARI1                  (0x00FF0000)
-#define MPI2_SCSITASKMGMT_RI_SHIFT_ARI1                 (16)
-#define MPI2_SCSITASKMGMT_RI_MASK_ARI0                  (0xFF000000)
-#define MPI2_SCSITASKMGMT_RI_SHIFT_ARI0                 (24)
-
-
-/****************************************************************************
-*  SCSI Enclosure Processor messages
-****************************************************************************/
-
-/* SCSI Enclosure Processor Request Message */
-typedef struct _MPI2_SEP_REQUEST
-{
-    U16                     DevHandle;          /* 0x00 */
-    U8                      ChainOffset;        /* 0x02 */
-    U8                      Function;           /* 0x03 */
-    U8                      Action;             /* 0x04 */
-    U8                      Flags;              /* 0x05 */
-    U8                      Reserved1;          /* 0x06 */
-    U8                      MsgFlags;           /* 0x07 */
-    U8                      VP_ID;              /* 0x08 */
-    U8                      VF_ID;              /* 0x09 */
-    U16                     Reserved2;          /* 0x0A */
-    U32                     SlotStatus;         /* 0x0C */
-    U32                     Reserved3;          /* 0x10 */
-    U32                     Reserved4;          /* 0x14 */
-    U32                     Reserved5;          /* 0x18 */
-    U16                     Slot;               /* 0x1C */
-    U16                     EnclosureHandle;    /* 0x1E */
-} MPI2_SEP_REQUEST, MPI2_POINTER PTR_MPI2_SEP_REQUEST,
-  Mpi2SepRequest_t, MPI2_POINTER pMpi2SepRequest_t;
-
-/* Action defines */
-#define MPI2_SEP_REQ_ACTION_WRITE_STATUS                (0x00)
-#define MPI2_SEP_REQ_ACTION_READ_STATUS                 (0x01)
-
-/* Flags defines */
-#define MPI2_SEP_REQ_FLAGS_DEVHANDLE_ADDRESS            (0x00)
-#define MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS       (0x01)
-
-/* SlotStatus defines */
-#define MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE          (0x00040000)
-#define MPI2_SEP_REQ_SLOTSTATUS_IDENTIFY_REQUEST        (0x00020000)
-#define MPI2_SEP_REQ_SLOTSTATUS_REBUILD_STOPPED         (0x00000200)
-#define MPI2_SEP_REQ_SLOTSTATUS_HOT_SPARE               (0x00000100)
-#define MPI2_SEP_REQ_SLOTSTATUS_UNCONFIGURED            (0x00000080)
-#define MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT         (0x00000040)
-#define MPI2_SEP_REQ_SLOTSTATUS_IN_CRITICAL_ARRAY       (0x00000010)
-#define MPI2_SEP_REQ_SLOTSTATUS_IN_FAILED_ARRAY         (0x00000008)
-#define MPI2_SEP_REQ_SLOTSTATUS_DEV_REBUILDING          (0x00000004)
-#define MPI2_SEP_REQ_SLOTSTATUS_DEV_FAULTY              (0x00000002)
-#define MPI2_SEP_REQ_SLOTSTATUS_NO_ERROR                (0x00000001)
-
-
-/* SCSI Enclosure Processor Reply Message */
-typedef struct _MPI2_SEP_REPLY
-{
-    U16                     DevHandle;          /* 0x00 */
-    U8                      MsgLength;          /* 0x02 */
-    U8                      Function;           /* 0x03 */
-    U8                      Action;             /* 0x04 */
-    U8                      Flags;              /* 0x05 */
-    U8                      Reserved1;          /* 0x06 */
-    U8                      MsgFlags;           /* 0x07 */
-    U8                      VP_ID;              /* 0x08 */
-    U8                      VF_ID;              /* 0x09 */
-    U16                     Reserved2;          /* 0x0A */
-    U16                     Reserved3;          /* 0x0C */
-    U16                     IOCStatus;          /* 0x0E */
-    U32                     IOCLogInfo;         /* 0x10 */
-    U32                     SlotStatus;         /* 0x14 */
-    U32                     Reserved4;          /* 0x18 */
-    U16                     Slot;               /* 0x1C */
-    U16                     EnclosureHandle;    /* 0x1E */
-} MPI2_SEP_REPLY, MPI2_POINTER PTR_MPI2_SEP_REPLY,
-  Mpi2SepReply_t, MPI2_POINTER pMpi2SepReply_t;
-
-/* SlotStatus defines */
-#define MPI2_SEP_REPLY_SLOTSTATUS_REMOVE_READY          (0x00040000)
-#define MPI2_SEP_REPLY_SLOTSTATUS_IDENTIFY_REQUEST      (0x00020000)
-#define MPI2_SEP_REPLY_SLOTSTATUS_REBUILD_STOPPED       (0x00000200)
-#define MPI2_SEP_REPLY_SLOTSTATUS_HOT_SPARE             (0x00000100)
-#define MPI2_SEP_REPLY_SLOTSTATUS_UNCONFIGURED          (0x00000080)
-#define MPI2_SEP_REPLY_SLOTSTATUS_PREDICTED_FAULT       (0x00000040)
-#define MPI2_SEP_REPLY_SLOTSTATUS_IN_CRITICAL_ARRAY     (0x00000010)
-#define MPI2_SEP_REPLY_SLOTSTATUS_IN_FAILED_ARRAY       (0x00000008)
-#define MPI2_SEP_REPLY_SLOTSTATUS_DEV_REBUILDING        (0x00000004)
-#define MPI2_SEP_REPLY_SLOTSTATUS_DEV_FAULTY            (0x00000002)
-#define MPI2_SEP_REPLY_SLOTSTATUS_NO_ERROR              (0x00000001)
-
-
-#endif
-
-
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h b/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
deleted file mode 100644 (file)
index b02de48..0000000
+++ /dev/null
@@ -1,1708 +0,0 @@
-/*
- *  Copyright (c) 2000-2014 LSI Corporation.
- *
- *
- *           Name:  mpi2_ioc.h
- *          Title:  MPI IOC, Port, Event, FW Download, and FW Upload messages
- *  Creation Date:  October 11, 2006
- *
- *  mpi2_ioc.h Version:  02.00.24
- *
- *  Version History
- *  ---------------
- *
- *  Date      Version   Description
- *  --------  --------  ------------------------------------------------------
- *  04-30-07  02.00.00  Corresponds to Fusion-MPT MPI Specification Rev A.
- *  06-04-07  02.00.01  In IOCFacts Reply structure, renamed MaxDevices to
- *                      MaxTargets.
- *                      Added TotalImageSize field to FWDownload Request.
- *                      Added reserved words to FWUpload Request.
- *  06-26-07  02.00.02  Added IR Configuration Change List Event.
- *  08-31-07  02.00.03  Removed SystemReplyQueueDepth field from the IOCInit
- *                      request and replaced it with
- *                      ReplyDescriptorPostQueueDepth and ReplyFreeQueueDepth.
- *                      Replaced the MinReplyQueueDepth field of the IOCFacts
- *                      reply with MaxReplyDescriptorPostQueueDepth.
- *                      Added MPI2_RDPQ_DEPTH_MIN define to specify the minimum
- *                      depth for the Reply Descriptor Post Queue.
- *                      Added SASAddress field to Initiator Device Table
- *                      Overflow Event data.
- *  10-31-07  02.00.04  Added ReasonCode MPI2_EVENT_SAS_INIT_RC_NOT_RESPONDING
- *                      for SAS Initiator Device Status Change Event data.
- *                      Modified Reason Code defines for SAS Topology Change
- *                      List Event data, including adding a bit for PHY Vacant
- *                      status, and adding a mask for the Reason Code.
- *                      Added define for
- *                      MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING.
- *                      Added define for MPI2_EXT_IMAGE_TYPE_MEGARAID.
- *  12-18-07  02.00.05  Added Boot Status defines for the IOCExceptions field of
- *                      the IOCFacts Reply.
- *                      Removed MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER define.
- *                      Moved MPI2_VERSION_UNION to mpi2.h.
- *                      Changed MPI2_EVENT_NOTIFICATION_REQUEST to use masks
- *                      instead of enables, and added SASBroadcastPrimitiveMasks
- *                      field.
- *                      Added Log Entry Added Event and related structure.
- *  02-29-08  02.00.06  Added define MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID.
- *                      Removed define MPI2_IOCFACTS_PROTOCOL_SMP_TARGET.
- *                      Added MaxVolumes and MaxPersistentEntries fields to
- *                      IOCFacts reply.
- *                      Added ProtocalFlags and IOCCapabilities fields to
- *                      MPI2_FW_IMAGE_HEADER.
- *                      Removed MPI2_PORTENABLE_FLAGS_ENABLE_SINGLE_PORT.
- *  03-03-08  02.00.07  Fixed MPI2_FW_IMAGE_HEADER by changing Reserved26 to
- *                      a U16 (from a U32).
- *                      Removed extra 's' from EventMasks name.
- *  06-27-08  02.00.08  Fixed an offset in a comment.
- *  10-02-08  02.00.09  Removed SystemReplyFrameSize from MPI2_IOC_INIT_REQUEST.
- *                      Removed CurReplyFrameSize from MPI2_IOC_FACTS_REPLY and
- *                      renamed MinReplyFrameSize to ReplyFrameSize.
- *                      Added MPI2_IOCFACTS_EXCEPT_IR_FOREIGN_CONFIG_MAX.
- *                      Added two new RAIDOperation values for Integrated RAID
- *                      Operations Status Event data.
- *                      Added four new IR Configuration Change List Event data
- *                      ReasonCode values.
- *                      Added two new ReasonCode defines for SAS Device Status
- *                      Change Event data.
- *                      Added three new DiscoveryStatus bits for the SAS
- *                      Discovery event data.
- *                      Added Multiplexing Status Change bit to the PhyStatus
- *                      field of the SAS Topology Change List event data.
- *                      Removed define for MPI2_INIT_IMAGE_BOOTFLAGS_XMEMCOPY.
- *                      BootFlags are now product-specific.
- *                      Added defines for the indivdual signature bytes
- *                      for MPI2_INIT_IMAGE_FOOTER.
- *  01-19-09  02.00.10  Added MPI2_IOCFACTS_CAPABILITY_EVENT_REPLAY define.
- *                      Added MPI2_EVENT_SAS_DISC_DS_DOWNSTREAM_INITIATOR
- *                      define.
- *                      Added MPI2_EVENT_SAS_DEV_STAT_RC_SATA_INIT_FAILURE
- *                      define.
- *                      Removed MPI2_EVENT_SAS_DISC_DS_SATA_INIT_FAILURE define.
- *  05-06-09  02.00.11  Added MPI2_IOCFACTS_CAPABILITY_RAID_ACCELERATOR define.
- *                      Added MPI2_IOCFACTS_CAPABILITY_MSI_X_INDEX define.
- *                      Added two new reason codes for SAS Device Status Change
- *                      Event.
- *                      Added new event: SAS PHY Counter.
- *  07-30-09  02.00.12  Added GPIO Interrupt event define and structure.
- *                      Added MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER define.
- *                      Added new product id family for 2208.
- *  10-28-09  02.00.13  Added HostMSIxVectors field to MPI2_IOC_INIT_REQUEST.
- *                      Added MaxMSIxVectors field to MPI2_IOC_FACTS_REPLY.
- *                      Added MinDevHandle field to MPI2_IOC_FACTS_REPLY.
- *                      Added MPI2_IOCFACTS_CAPABILITY_HOST_BASED_DISCOVERY.
- *                      Added MPI2_EVENT_HOST_BASED_DISCOVERY_PHY define.
- *                      Added MPI2_EVENT_SAS_TOPO_ES_NO_EXPANDER define.
- *                      Added Host Based Discovery Phy Event data.
- *                      Added defines for ProductID Product field
- *                      (MPI2_FW_HEADER_PID_).
- *                      Modified values for SAS ProductID Family
- *                      (MPI2_FW_HEADER_PID_FAMILY_).
- *  02-10-10  02.00.14  Added SAS Quiesce Event structure and defines.
- *                      Added PowerManagementControl Request structures and
- *                      defines.
- *  05-12-10  02.00.15  Marked Task Set Full Event as obsolete.
- *                      Added MPI2_EVENT_SAS_TOPO_LR_UNSUPPORTED_PHY define.
- *  11-10-10  02.00.16  Added MPI2_FW_DOWNLOAD_ITYPE_MIN_PRODUCT_SPECIFIC.
- *  02-23-11  02.00.17  Added SAS NOTIFY Primitive event, and added
- *                      SASNotifyPrimitiveMasks field to
- *                      MPI2_EVENT_NOTIFICATION_REQUEST.
- *                      Added Temperature Threshold Event.
- *                      Added Host Message Event.
- *                      Added Send Host Message request and reply.
- *  05-25-11  02.00.18  For Extended Image Header, added
- *                      MPI2_EXT_IMAGE_TYPE_MIN_PRODUCT_SPECIFIC and
- *                      MPI2_EXT_IMAGE_TYPE_MAX_PRODUCT_SPECIFIC defines.
- *                      Deprecated MPI2_EXT_IMAGE_TYPE_MAX define.
- *  08-24-11  02.00.19  Added PhysicalPort field to
- *                      MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE structure.
- *                      Marked MPI2_PM_CONTROL_FEATURE_PCIE_LINK as obsolete.
- *  03-29-12  02.00.21  Added a product specific range to event values.
- *  07-26-12  02.00.22  Added MPI2_IOCFACTS_EXCEPT_PARTIAL_MEMORY_FAILURE.
- *                      Added ElapsedSeconds field to
- *                      MPI2_EVENT_DATA_IR_OPERATION_STATUS.
- *  08-19-13  02.00.23  For IOCInit, added MPI2_IOCINIT_MSGFLAG_RDPQ_ARRAY_MODE
- *                      and MPI2_IOC_INIT_RDPQ_ARRAY_ENTRY.
- *                      Added MPI2_IOCFACTS_CAPABILITY_RDPQ_ARRAY_CAPABLE.
- *                      Added MPI2_FW_DOWNLOAD_ITYPE_PUBLIC_KEY.
- *                      Added Encrypted Hash Extended Image.
- *  12-05-13  02.00.24  Added MPI25_HASH_IMAGE_TYPE_BIOS.
- *  --------------------------------------------------------------------------
- */
-
-#ifndef MPI2_IOC_H
-#define MPI2_IOC_H
-
-/*****************************************************************************
-*
-*               IOC Messages
-*
-*****************************************************************************/
-
-/****************************************************************************
-*  IOCInit message
-****************************************************************************/
-
-/* IOCInit Request message */
-typedef struct _MPI2_IOC_INIT_REQUEST
-{
-    U8                      WhoInit;                        /* 0x00 */
-    U8                      Reserved1;                      /* 0x01 */
-    U8                      ChainOffset;                    /* 0x02 */
-    U8                      Function;                       /* 0x03 */
-    U16                     Reserved2;                      /* 0x04 */
-    U8                      Reserved3;                      /* 0x06 */
-    U8                      MsgFlags;                       /* 0x07 */
-    U8                      VP_ID;                          /* 0x08 */
-    U8                      VF_ID;                          /* 0x09 */
-    U16                     Reserved4;                      /* 0x0A */
-    U16                     MsgVersion;                     /* 0x0C */
-    U16                     HeaderVersion;                  /* 0x0E */
-    U32                     Reserved5;                      /* 0x10 */
-    U16                     Reserved6;                      /* 0x14 */
-    U8                      Reserved7;                      /* 0x16 */
-    U8                      HostMSIxVectors;                /* 0x17 */
-    U16                     Reserved8;                      /* 0x18 */
-    U16                     SystemRequestFrameSize;         /* 0x1A */
-    U16                     ReplyDescriptorPostQueueDepth;  /* 0x1C */
-    U16                     ReplyFreeQueueDepth;            /* 0x1E */
-    U32                     SenseBufferAddressHigh;         /* 0x20 */
-    U32                     SystemReplyAddressHigh;         /* 0x24 */
-    U64                     SystemRequestFrameBaseAddress;  /* 0x28 */
-    U64                     ReplyDescriptorPostQueueAddress;/* 0x30 */
-    U64                     ReplyFreeQueueAddress;          /* 0x38 */
-    U64                     TimeStamp;                      /* 0x40 */
-} MPI2_IOC_INIT_REQUEST, MPI2_POINTER PTR_MPI2_IOC_INIT_REQUEST,
-  Mpi2IOCInitRequest_t, MPI2_POINTER pMpi2IOCInitRequest_t;
-
-/* WhoInit values */
-#define MPI2_WHOINIT_NOT_INITIALIZED            (0x00)
-#define MPI2_WHOINIT_SYSTEM_BIOS                (0x01)
-#define MPI2_WHOINIT_ROM_BIOS                   (0x02)
-#define MPI2_WHOINIT_PCI_PEER                   (0x03)
-#define MPI2_WHOINIT_HOST_DRIVER                (0x04)
-#define MPI2_WHOINIT_MANUFACTURER               (0x05)
-
-/* MsgFlags */
-#define MPI2_IOCINIT_MSGFLAG_RDPQ_ARRAY_MODE    (0x01)
-
-/* MsgVersion */
-#define MPI2_IOCINIT_MSGVERSION_MAJOR_MASK      (0xFF00)
-#define MPI2_IOCINIT_MSGVERSION_MAJOR_SHIFT     (8)
-#define MPI2_IOCINIT_MSGVERSION_MINOR_MASK      (0x00FF)
-#define MPI2_IOCINIT_MSGVERSION_MINOR_SHIFT     (0)
-
-/* HeaderVersion */
-#define MPI2_IOCINIT_HDRVERSION_UNIT_MASK       (0xFF00)
-#define MPI2_IOCINIT_HDRVERSION_UNIT_SHIFT      (8)
-#define MPI2_IOCINIT_HDRVERSION_DEV_MASK        (0x00FF)
-#define MPI2_IOCINIT_HDRVERSION_DEV_SHIFT       (0)
-
-/* minimum depth for a Reply Descriptor Post Queue */
-#define MPI2_RDPQ_DEPTH_MIN                     (16)
-
-/* Reply Descriptor Post Queue Array Entry */
-typedef struct _MPI2_IOC_INIT_RDPQ_ARRAY_ENTRY {
-       U64                 RDPQBaseAddress;                    /* 0x00 */
-       U32                 Reserved1;                          /* 0x08 */
-       U32                 Reserved2;                          /* 0x0C */
-} MPI2_IOC_INIT_RDPQ_ARRAY_ENTRY,
-MPI2_POINTER PTR_MPI2_IOC_INIT_RDPQ_ARRAY_ENTRY,
-Mpi2IOCInitRDPQArrayEntry, MPI2_POINTER pMpi2IOCInitRDPQArrayEntry;
-
-/* IOCInit Reply message */
-typedef struct _MPI2_IOC_INIT_REPLY
-{
-    U8                      WhoInit;                        /* 0x00 */
-    U8                      Reserved1;                      /* 0x01 */
-    U8                      MsgLength;                      /* 0x02 */
-    U8                      Function;                       /* 0x03 */
-    U16                     Reserved2;                      /* 0x04 */
-    U8                      Reserved3;                      /* 0x06 */
-    U8                      MsgFlags;                       /* 0x07 */
-    U8                      VP_ID;                          /* 0x08 */
-    U8                      VF_ID;                          /* 0x09 */
-    U16                     Reserved4;                      /* 0x0A */
-    U16                     Reserved5;                      /* 0x0C */
-    U16                     IOCStatus;                      /* 0x0E */
-    U32                     IOCLogInfo;                     /* 0x10 */
-} MPI2_IOC_INIT_REPLY, MPI2_POINTER PTR_MPI2_IOC_INIT_REPLY,
-  Mpi2IOCInitReply_t, MPI2_POINTER pMpi2IOCInitReply_t;
-
-
-/****************************************************************************
-*  IOCFacts message
-****************************************************************************/
-
-/* IOCFacts Request message */
-typedef struct _MPI2_IOC_FACTS_REQUEST
-{
-    U16                     Reserved1;                      /* 0x00 */
-    U8                      ChainOffset;                    /* 0x02 */
-    U8                      Function;                       /* 0x03 */
-    U16                     Reserved2;                      /* 0x04 */
-    U8                      Reserved3;                      /* 0x06 */
-    U8                      MsgFlags;                       /* 0x07 */
-    U8                      VP_ID;                          /* 0x08 */
-    U8                      VF_ID;                          /* 0x09 */
-    U16                     Reserved4;                      /* 0x0A */
-} MPI2_IOC_FACTS_REQUEST, MPI2_POINTER PTR_MPI2_IOC_FACTS_REQUEST,
-  Mpi2IOCFactsRequest_t, MPI2_POINTER pMpi2IOCFactsRequest_t;
-
-
-/* IOCFacts Reply message */
-typedef struct _MPI2_IOC_FACTS_REPLY
-{
-    U16                     MsgVersion;                     /* 0x00 */
-    U8                      MsgLength;                      /* 0x02 */
-    U8                      Function;                       /* 0x03 */
-    U16                     HeaderVersion;                  /* 0x04 */
-    U8                      IOCNumber;                      /* 0x06 */
-    U8                      MsgFlags;                       /* 0x07 */
-    U8                      VP_ID;                          /* 0x08 */
-    U8                      VF_ID;                          /* 0x09 */
-    U16                     Reserved1;                      /* 0x0A */
-    U16                     IOCExceptions;                  /* 0x0C */
-    U16                     IOCStatus;                      /* 0x0E */
-    U32                     IOCLogInfo;                     /* 0x10 */
-    U8                      MaxChainDepth;                  /* 0x14 */
-    U8                      WhoInit;                        /* 0x15 */
-    U8                      NumberOfPorts;                  /* 0x16 */
-    U8                      MaxMSIxVectors;                 /* 0x17 */
-    U16                     RequestCredit;                  /* 0x18 */
-    U16                     ProductID;                      /* 0x1A */
-    U32                     IOCCapabilities;                /* 0x1C */
-    MPI2_VERSION_UNION      FWVersion;                      /* 0x20 */
-    U16                     IOCRequestFrameSize;            /* 0x24 */
-    U16                     Reserved3;                      /* 0x26 */
-    U16                     MaxInitiators;                  /* 0x28 */
-    U16                     MaxTargets;                     /* 0x2A */
-    U16                     MaxSasExpanders;                /* 0x2C */
-    U16                     MaxEnclosures;                  /* 0x2E */
-    U16                     ProtocolFlags;                  /* 0x30 */
-    U16                     HighPriorityCredit;             /* 0x32 */
-    U16                     MaxReplyDescriptorPostQueueDepth; /* 0x34 */
-    U8                      ReplyFrameSize;                 /* 0x36 */
-    U8                      MaxVolumes;                     /* 0x37 */
-    U16                     MaxDevHandle;                   /* 0x38 */
-    U16                     MaxPersistentEntries;           /* 0x3A */
-    U16                     MinDevHandle;                   /* 0x3C */
-    U16                     Reserved4;                      /* 0x3E */
-} MPI2_IOC_FACTS_REPLY, MPI2_POINTER PTR_MPI2_IOC_FACTS_REPLY,
-  Mpi2IOCFactsReply_t, MPI2_POINTER pMpi2IOCFactsReply_t;
-
-/* MsgVersion */
-#define MPI2_IOCFACTS_MSGVERSION_MAJOR_MASK             (0xFF00)
-#define MPI2_IOCFACTS_MSGVERSION_MAJOR_SHIFT            (8)
-#define MPI2_IOCFACTS_MSGVERSION_MINOR_MASK             (0x00FF)
-#define MPI2_IOCFACTS_MSGVERSION_MINOR_SHIFT            (0)
-
-/* HeaderVersion */
-#define MPI2_IOCFACTS_HDRVERSION_UNIT_MASK              (0xFF00)
-#define MPI2_IOCFACTS_HDRVERSION_UNIT_SHIFT             (8)
-#define MPI2_IOCFACTS_HDRVERSION_DEV_MASK               (0x00FF)
-#define MPI2_IOCFACTS_HDRVERSION_DEV_SHIFT              (0)
-
-/* IOCExceptions */
-#define MPI2_IOCFACTS_EXCEPT_PARTIAL_MEMORY_FAILURE     (0x0200)
-#define MPI2_IOCFACTS_EXCEPT_IR_FOREIGN_CONFIG_MAX      (0x0100)
-
-#define MPI2_IOCFACTS_EXCEPT_BOOTSTAT_MASK              (0x00E0)
-#define MPI2_IOCFACTS_EXCEPT_BOOTSTAT_GOOD              (0x0000)
-#define MPI2_IOCFACTS_EXCEPT_BOOTSTAT_BACKUP            (0x0020)
-#define MPI2_IOCFACTS_EXCEPT_BOOTSTAT_RESTORED          (0x0040)
-#define MPI2_IOCFACTS_EXCEPT_BOOTSTAT_CORRUPT_BACKUP    (0x0060)
-
-#define MPI2_IOCFACTS_EXCEPT_METADATA_UNSUPPORTED       (0x0010)
-#define MPI2_IOCFACTS_EXCEPT_MANUFACT_CHECKSUM_FAIL     (0x0008)
-#define MPI2_IOCFACTS_EXCEPT_FW_CHECKSUM_FAIL           (0x0004)
-#define MPI2_IOCFACTS_EXCEPT_RAID_CONFIG_INVALID        (0x0002)
-#define MPI2_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL       (0x0001)
-
-/* defines for WhoInit field are after the IOCInit Request */
-
-/* ProductID field uses MPI2_FW_HEADER_PID_ */
-
-/* IOCCapabilities */
-#define MPI2_IOCFACTS_CAPABILITY_RDPQ_ARRAY_CAPABLE     (0x00040000)
-#define MPI2_IOCFACTS_CAPABILITY_HOST_BASED_DISCOVERY   (0x00010000)
-#define MPI2_IOCFACTS_CAPABILITY_MSI_X_INDEX            (0x00008000)
-#define MPI2_IOCFACTS_CAPABILITY_RAID_ACCELERATOR       (0x00004000)
-#define MPI2_IOCFACTS_CAPABILITY_EVENT_REPLAY           (0x00002000)
-#define MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID        (0x00001000)
-#define MPI2_IOCFACTS_CAPABILITY_TLR                    (0x00000800)
-#define MPI2_IOCFACTS_CAPABILITY_MULTICAST              (0x00000100)
-#define MPI2_IOCFACTS_CAPABILITY_BIDIRECTIONAL_TARGET   (0x00000080)
-#define MPI2_IOCFACTS_CAPABILITY_EEDP                   (0x00000040)
-#define MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER        (0x00000020)
-#define MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER        (0x00000010)
-#define MPI2_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER      (0x00000008)
-#define MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING (0x00000004)
-
-/* ProtocolFlags */
-#define MPI2_IOCFACTS_PROTOCOL_SCSI_TARGET              (0x0001)
-#define MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR           (0x0002)
-
-
-/****************************************************************************
-*  PortFacts message
-****************************************************************************/
-
-/* PortFacts Request message */
-typedef struct _MPI2_PORT_FACTS_REQUEST
-{
-    U16                     Reserved1;                      /* 0x00 */
-    U8                      ChainOffset;                    /* 0x02 */
-    U8                      Function;                       /* 0x03 */
-    U16                     Reserved2;                      /* 0x04 */
-    U8                      PortNumber;                     /* 0x06 */
-    U8                      MsgFlags;                       /* 0x07 */
-    U8                      VP_ID;                          /* 0x08 */
-    U8                      VF_ID;                          /* 0x09 */
-    U16                     Reserved3;                      /* 0x0A */
-} MPI2_PORT_FACTS_REQUEST, MPI2_POINTER PTR_MPI2_PORT_FACTS_REQUEST,
-  Mpi2PortFactsRequest_t, MPI2_POINTER pMpi2PortFactsRequest_t;
-
-/* PortFacts Reply message */
-typedef struct _MPI2_PORT_FACTS_REPLY
-{
-    U16                     Reserved1;                      /* 0x00 */
-    U8                      MsgLength;                      /* 0x02 */
-    U8                      Function;                       /* 0x03 */
-    U16                     Reserved2;                      /* 0x04 */
-    U8                      PortNumber;                     /* 0x06 */
-    U8                      MsgFlags;                       /* 0x07 */
-    U8                      VP_ID;                          /* 0x08 */
-    U8                      VF_ID;                          /* 0x09 */
-    U16                     Reserved3;                      /* 0x0A */
-    U16                     Reserved4;                      /* 0x0C */
-    U16                     IOCStatus;                      /* 0x0E */
-    U32                     IOCLogInfo;                     /* 0x10 */
-    U8                      Reserved5;                      /* 0x14 */
-    U8                      PortType;                       /* 0x15 */
-    U16                     Reserved6;                      /* 0x16 */
-    U16                     MaxPostedCmdBuffers;            /* 0x18 */
-    U16                     Reserved7;                      /* 0x1A */
-} MPI2_PORT_FACTS_REPLY, MPI2_POINTER PTR_MPI2_PORT_FACTS_REPLY,
-  Mpi2PortFactsReply_t, MPI2_POINTER pMpi2PortFactsReply_t;
-
-/* PortType values */
-#define MPI2_PORTFACTS_PORTTYPE_INACTIVE            (0x00)
-#define MPI2_PORTFACTS_PORTTYPE_FC                  (0x10)
-#define MPI2_PORTFACTS_PORTTYPE_ISCSI               (0x20)
-#define MPI2_PORTFACTS_PORTTYPE_SAS_PHYSICAL        (0x30)
-#define MPI2_PORTFACTS_PORTTYPE_SAS_VIRTUAL         (0x31)
-
-
-/****************************************************************************
-*  PortEnable message
-****************************************************************************/
-
-/* PortEnable Request message */
-typedef struct _MPI2_PORT_ENABLE_REQUEST
-{
-    U16                     Reserved1;                      /* 0x00 */
-    U8                      ChainOffset;                    /* 0x02 */
-    U8                      Function;                       /* 0x03 */
-    U8                      Reserved2;                      /* 0x04 */
-    U8                      PortFlags;                      /* 0x05 */
-    U8                      Reserved3;                      /* 0x06 */
-    U8                      MsgFlags;                       /* 0x07 */
-    U8                      VP_ID;                          /* 0x08 */
-    U8                      VF_ID;                          /* 0x09 */
-    U16                     Reserved4;                      /* 0x0A */
-} MPI2_PORT_ENABLE_REQUEST, MPI2_POINTER PTR_MPI2_PORT_ENABLE_REQUEST,
-  Mpi2PortEnableRequest_t, MPI2_POINTER pMpi2PortEnableRequest_t;
-
-
-/* PortEnable Reply message */
-typedef struct _MPI2_PORT_ENABLE_REPLY
-{
-    U16                     Reserved1;                      /* 0x00 */
-    U8                      MsgLength;                      /* 0x02 */
-    U8                      Function;                       /* 0x03 */
-    U8                      Reserved2;                      /* 0x04 */
-    U8                      PortFlags;                      /* 0x05 */
-    U8                      Reserved3;                      /* 0x06 */
-    U8                      MsgFlags;                       /* 0x07 */
-    U8                      VP_ID;                          /* 0x08 */
-    U8                      VF_ID;                          /* 0x09 */
-    U16                     Reserved4;                      /* 0x0A */
-    U16                     Reserved5;                      /* 0x0C */
-    U16                     IOCStatus;                      /* 0x0E */
-    U32                     IOCLogInfo;                     /* 0x10 */
-} MPI2_PORT_ENABLE_REPLY, MPI2_POINTER PTR_MPI2_PORT_ENABLE_REPLY,
-  Mpi2PortEnableReply_t, MPI2_POINTER pMpi2PortEnableReply_t;
-
-
-/****************************************************************************
-*  EventNotification message
-****************************************************************************/
-
-/* EventNotification Request message */
-#define MPI2_EVENT_NOTIFY_EVENTMASK_WORDS           (4)
-
-typedef struct _MPI2_EVENT_NOTIFICATION_REQUEST
-{
-    U16                     Reserved1;                      /* 0x00 */
-    U8                      ChainOffset;                    /* 0x02 */
-    U8                      Function;                       /* 0x03 */
-    U16                     Reserved2;                      /* 0x04 */
-    U8                      Reserved3;                      /* 0x06 */
-    U8                      MsgFlags;                       /* 0x07 */
-    U8                      VP_ID;                          /* 0x08 */
-    U8                      VF_ID;                          /* 0x09 */
-    U16                     Reserved4;                      /* 0x0A */
-    U32                     Reserved5;                      /* 0x0C */
-    U32                     Reserved6;                      /* 0x10 */
-    U32                     EventMasks[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS];/* 0x14 */
-    U16                     SASBroadcastPrimitiveMasks;     /* 0x24 */
-        U16                     SASNotifyPrimitiveMasks;        /* 0x26 */
-    U32                     Reserved8;                      /* 0x28 */
-} MPI2_EVENT_NOTIFICATION_REQUEST,
-  MPI2_POINTER PTR_MPI2_EVENT_NOTIFICATION_REQUEST,
-  Mpi2EventNotificationRequest_t, MPI2_POINTER pMpi2EventNotificationRequest_t;
-
-
-/* EventNotification Reply message */
-typedef struct _MPI2_EVENT_NOTIFICATION_REPLY
-{
-    U16                     EventDataLength;                /* 0x00 */
-    U8                      MsgLength;                      /* 0x02 */
-    U8                      Function;                       /* 0x03 */
-    U16                     Reserved1;                      /* 0x04 */
-    U8                      AckRequired;                    /* 0x06 */
-    U8                      MsgFlags;                       /* 0x07 */
-    U8                      VP_ID;                          /* 0x08 */
-    U8                      VF_ID;                          /* 0x09 */
-    U16                     Reserved2;                      /* 0x0A */
-    U16                     Reserved3;                      /* 0x0C */
-    U16                     IOCStatus;                      /* 0x0E */
-    U32                     IOCLogInfo;                     /* 0x10 */
-    U16                     Event;                          /* 0x14 */
-    U16                     Reserved4;                      /* 0x16 */
-    U32                     EventContext;                   /* 0x18 */
-    U32                     EventData[1];                   /* 0x1C */
-} MPI2_EVENT_NOTIFICATION_REPLY, MPI2_POINTER PTR_MPI2_EVENT_NOTIFICATION_REPLY,
-  Mpi2EventNotificationReply_t, MPI2_POINTER pMpi2EventNotificationReply_t;
-
-/* AckRequired */
-#define MPI2_EVENT_NOTIFICATION_ACK_NOT_REQUIRED    (0x00)
-#define MPI2_EVENT_NOTIFICATION_ACK_REQUIRED        (0x01)
-
-/* Event */
-#define MPI2_EVENT_LOG_DATA                         (0x0001)
-#define MPI2_EVENT_STATE_CHANGE                     (0x0002)
-#define MPI2_EVENT_HARD_RESET_RECEIVED              (0x0005)
-#define MPI2_EVENT_EVENT_CHANGE                     (0x000A)
-#define MPI2_EVENT_TASK_SET_FULL                    (0x000E) /* obsolete */
-#define MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE         (0x000F)
-#define MPI2_EVENT_IR_OPERATION_STATUS              (0x0014)
-#define MPI2_EVENT_SAS_DISCOVERY                    (0x0016)
-#define MPI2_EVENT_SAS_BROADCAST_PRIMITIVE          (0x0017)
-#define MPI2_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE    (0x0018)
-#define MPI2_EVENT_SAS_INIT_TABLE_OVERFLOW          (0x0019)
-#define MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST         (0x001C)
-#define MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE    (0x001D)
-#define MPI2_EVENT_IR_VOLUME                        (0x001E)
-#define MPI2_EVENT_IR_PHYSICAL_DISK                 (0x001F)
-#define MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST     (0x0020)
-#define MPI2_EVENT_LOG_ENTRY_ADDED                  (0x0021)
-#define MPI2_EVENT_SAS_PHY_COUNTER                  (0x0022)
-#define MPI2_EVENT_GPIO_INTERRUPT                   (0x0023)
-#define MPI2_EVENT_HOST_BASED_DISCOVERY_PHY         (0x0024)
-#define MPI2_EVENT_SAS_QUIESCE                      (0x0025)
-#define MPI2_EVENT_SAS_NOTIFY_PRIMITIVE             (0x0026)
-#define MPI2_EVENT_TEMP_THRESHOLD                   (0x0027)
-#define MPI2_EVENT_HOST_MESSAGE                     (0x0028)
-#define MPI2_EVENT_MIN_PRODUCT_SPECIFIC             (0x006E)
-#define MPI2_EVENT_MAX_PRODUCT_SPECIFIC             (0x007F)
-
-/* Log Entry Added Event data */
-
-/* the following structure matches MPI2_LOG_0_ENTRY in mpi2_cnfg.h */
-#define MPI2_EVENT_DATA_LOG_DATA_LENGTH             (0x1C)
-
-typedef struct _MPI2_EVENT_DATA_LOG_ENTRY_ADDED
-{
-    U64         TimeStamp;                          /* 0x00 */
-    U32         Reserved1;                          /* 0x08 */
-    U16         LogSequence;                        /* 0x0C */
-    U16         LogEntryQualifier;                  /* 0x0E */
-    U8          VP_ID;                              /* 0x10 */
-    U8          VF_ID;                              /* 0x11 */
-    U16         Reserved2;                          /* 0x12 */
-    U8          LogData[MPI2_EVENT_DATA_LOG_DATA_LENGTH];/* 0x14 */
-} MPI2_EVENT_DATA_LOG_ENTRY_ADDED,
-  MPI2_POINTER PTR_MPI2_EVENT_DATA_LOG_ENTRY_ADDED,
-  Mpi2EventDataLogEntryAdded_t, MPI2_POINTER pMpi2EventDataLogEntryAdded_t;
-
-/* GPIO Interrupt Event data */
-
-typedef struct _MPI2_EVENT_DATA_GPIO_INTERRUPT {
-    U8          GPIONum;                            /* 0x00 */
-    U8          Reserved1;                          /* 0x01 */
-    U16         Reserved2;                          /* 0x02 */
-} MPI2_EVENT_DATA_GPIO_INTERRUPT,
-  MPI2_POINTER PTR_MPI2_EVENT_DATA_GPIO_INTERRUPT,
-  Mpi2EventDataGpioInterrupt_t, MPI2_POINTER pMpi2EventDataGpioInterrupt_t;
-
-/* Temperature Threshold Event data */
-
-typedef struct _MPI2_EVENT_DATA_TEMPERATURE {
-       U16         Status;                             /* 0x00 */
-       U8          SensorNum;                          /* 0x02 */
-       U8          Reserved1;                          /* 0x03 */
-       U16         CurrentTemperature;                 /* 0x04 */
-       U16         Reserved2;                          /* 0x06 */
-       U32         Reserved3;                          /* 0x08 */
-       U32         Reserved4;                          /* 0x0C */
-} MPI2_EVENT_DATA_TEMPERATURE,
-MPI2_POINTER PTR_MPI2_EVENT_DATA_TEMPERATURE,
-Mpi2EventDataTemperature_t, MPI2_POINTER pMpi2EventDataTemperature_t;
-
-/* Temperature Threshold Event data Status bits */
-#define MPI2_EVENT_TEMPERATURE3_EXCEEDED            (0x0008)
-#define MPI2_EVENT_TEMPERATURE2_EXCEEDED            (0x0004)
-#define MPI2_EVENT_TEMPERATURE1_EXCEEDED            (0x0002)
-#define MPI2_EVENT_TEMPERATURE0_EXCEEDED            (0x0001)
-
-
-/* Host Message Event data */
-
-typedef struct _MPI2_EVENT_DATA_HOST_MESSAGE {
-       U8          SourceVF_ID;                        /* 0x00 */
-       U8          Reserved1;                          /* 0x01 */
-       U16         Reserved2;                          /* 0x02 */
-       U32         Reserved3;                          /* 0x04 */
-       U32         HostData[1];                        /* 0x08 */
-} MPI2_EVENT_DATA_HOST_MESSAGE, MPI2_POINTER PTR_MPI2_EVENT_DATA_HOST_MESSAGE,
-Mpi2EventDataHostMessage_t, MPI2_POINTER pMpi2EventDataHostMessage_t;
-
-
-/* Hard Reset Received Event data */
-
-typedef struct _MPI2_EVENT_DATA_HARD_RESET_RECEIVED
-{
-    U8                      Reserved1;                      /* 0x00 */
-    U8                      Port;                           /* 0x01 */
-    U16                     Reserved2;                      /* 0x02 */
-} MPI2_EVENT_DATA_HARD_RESET_RECEIVED,
-  MPI2_POINTER PTR_MPI2_EVENT_DATA_HARD_RESET_RECEIVED,
-  Mpi2EventDataHardResetReceived_t,
-  MPI2_POINTER pMpi2EventDataHardResetReceived_t;
-
-/* Task Set Full Event data */
-/*   this event is obsolete */
-
-typedef struct _MPI2_EVENT_DATA_TASK_SET_FULL
-{
-    U16                     DevHandle;                      /* 0x00 */
-    U16                     CurrentDepth;                   /* 0x02 */
-} MPI2_EVENT_DATA_TASK_SET_FULL, MPI2_POINTER PTR_MPI2_EVENT_DATA_TASK_SET_FULL,
-  Mpi2EventDataTaskSetFull_t, MPI2_POINTER pMpi2EventDataTaskSetFull_t;
-
-
-/* SAS Device Status Change Event data */
-
-typedef struct _MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE
-{
-    U16                     TaskTag;                        /* 0x00 */
-    U8                      ReasonCode;                     /* 0x02 */
-       U8                      PhysicalPort;                   /* 0x03 */
-    U8                      ASC;                            /* 0x04 */
-    U8                      ASCQ;                           /* 0x05 */
-    U16                     DevHandle;                      /* 0x06 */
-    U32                     Reserved2;                      /* 0x08 */
-    U64                     SASAddress;                     /* 0x0C */
-    U8                      LUN[8];                         /* 0x14 */
-} MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE,
-  MPI2_POINTER PTR_MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE,
-  Mpi2EventDataSasDeviceStatusChange_t,
-  MPI2_POINTER pMpi2EventDataSasDeviceStatusChange_t;
-
-/* SAS Device Status Change Event data ReasonCode values */
-#define MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA                           (0x05)
-#define MPI2_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED                          (0x07)
-#define MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET                (0x08)
-#define MPI2_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL                  (0x09)
-#define MPI2_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL              (0x0A)
-#define MPI2_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL              (0x0B)
-#define MPI2_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL                  (0x0C)
-#define MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION                   (0x0D)
-#define MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET               (0x0E)
-#define MPI2_EVENT_SAS_DEV_STAT_RC_CMP_TASK_ABORT_INTERNAL              (0x0F)
-#define MPI2_EVENT_SAS_DEV_STAT_RC_SATA_INIT_FAILURE                    (0x10)
-#define MPI2_EVENT_SAS_DEV_STAT_RC_EXPANDER_REDUCED_FUNCTIONALITY       (0x11)
-#define MPI2_EVENT_SAS_DEV_STAT_RC_CMP_EXPANDER_REDUCED_FUNCTIONALITY   (0x12)
-
-
-/* Integrated RAID Operation Status Event data */
-
-typedef struct _MPI2_EVENT_DATA_IR_OPERATION_STATUS
-{
-    U16                     VolDevHandle;               /* 0x00 */
-    U16                     Reserved1;                  /* 0x02 */
-    U8                      RAIDOperation;              /* 0x04 */
-    U8                      PercentComplete;            /* 0x05 */
-    U16                     Reserved2;                  /* 0x06 */
-       U32                     ElapsedSeconds;             /* 0x08 */
-} MPI2_EVENT_DATA_IR_OPERATION_STATUS,
-  MPI2_POINTER PTR_MPI2_EVENT_DATA_IR_OPERATION_STATUS,
-  Mpi2EventDataIrOperationStatus_t,
-  MPI2_POINTER pMpi2EventDataIrOperationStatus_t;
-
-/* Integrated RAID Operation Status Event data RAIDOperation values */
-#define MPI2_EVENT_IR_RAIDOP_RESYNC                     (0x00)
-#define MPI2_EVENT_IR_RAIDOP_ONLINE_CAP_EXPANSION       (0x01)
-#define MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK          (0x02)
-#define MPI2_EVENT_IR_RAIDOP_BACKGROUND_INIT            (0x03)
-#define MPI2_EVENT_IR_RAIDOP_MAKE_DATA_CONSISTENT       (0x04)
-
-
-/* Integrated RAID Volume Event data */
-
-typedef struct _MPI2_EVENT_DATA_IR_VOLUME
-{
-    U16                     VolDevHandle;               /* 0x00 */
-    U8                      ReasonCode;                 /* 0x02 */
-    U8                      Reserved1;                  /* 0x03 */
-    U32                     NewValue;                   /* 0x04 */
-    U32                     PreviousValue;              /* 0x08 */
-} MPI2_EVENT_DATA_IR_VOLUME, MPI2_POINTER PTR_MPI2_EVENT_DATA_IR_VOLUME,
-  Mpi2EventDataIrVolume_t, MPI2_POINTER pMpi2EventDataIrVolume_t;
-
-/* Integrated RAID Volume Event data ReasonCode values */
-#define MPI2_EVENT_IR_VOLUME_RC_SETTINGS_CHANGED        (0x01)
-#define MPI2_EVENT_IR_VOLUME_RC_STATUS_FLAGS_CHANGED    (0x02)
-#define MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED           (0x03)
-
-
-/* Integrated RAID Physical Disk Event data */
-
-typedef struct _MPI2_EVENT_DATA_IR_PHYSICAL_DISK
-{
-    U16                     Reserved1;                  /* 0x00 */
-    U8                      ReasonCode;                 /* 0x02 */
-    U8                      PhysDiskNum;                /* 0x03 */
-    U16                     PhysDiskDevHandle;          /* 0x04 */
-    U16                     Reserved2;                  /* 0x06 */
-    U16                     Slot;                       /* 0x08 */
-    U16                     EnclosureHandle;            /* 0x0A */
-    U32                     NewValue;                   /* 0x0C */
-    U32                     PreviousValue;              /* 0x10 */
-} MPI2_EVENT_DATA_IR_PHYSICAL_DISK,
-  MPI2_POINTER PTR_MPI2_EVENT_DATA_IR_PHYSICAL_DISK,
-  Mpi2EventDataIrPhysicalDisk_t, MPI2_POINTER pMpi2EventDataIrPhysicalDisk_t;
-
-/* Integrated RAID Physical Disk Event data ReasonCode values */
-#define MPI2_EVENT_IR_PHYSDISK_RC_SETTINGS_CHANGED      (0x01)
-#define MPI2_EVENT_IR_PHYSDISK_RC_STATUS_FLAGS_CHANGED  (0x02)
-#define MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED         (0x03)
-
-
-/* Integrated RAID Configuration Change List Event data */
-
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check NumElements at runtime.
- */
-#ifndef MPI2_EVENT_IR_CONFIG_ELEMENT_COUNT
-#define MPI2_EVENT_IR_CONFIG_ELEMENT_COUNT          (1)
-#endif
-
-typedef struct _MPI2_EVENT_IR_CONFIG_ELEMENT
-{
-    U16                     ElementFlags;               /* 0x00 */
-    U16                     VolDevHandle;               /* 0x02 */
-    U8                      ReasonCode;                 /* 0x04 */
-    U8                      PhysDiskNum;                /* 0x05 */
-    U16                     PhysDiskDevHandle;          /* 0x06 */
-} MPI2_EVENT_IR_CONFIG_ELEMENT, MPI2_POINTER PTR_MPI2_EVENT_IR_CONFIG_ELEMENT,
-  Mpi2EventIrConfigElement_t, MPI2_POINTER pMpi2EventIrConfigElement_t;
-
-/* IR Configuration Change List Event data ElementFlags values */
-#define MPI2_EVENT_IR_CHANGE_EFLAGS_ELEMENT_TYPE_MASK   (0x000F)
-#define MPI2_EVENT_IR_CHANGE_EFLAGS_VOLUME_ELEMENT      (0x0000)
-#define MPI2_EVENT_IR_CHANGE_EFLAGS_VOLPHYSDISK_ELEMENT (0x0001)
-#define MPI2_EVENT_IR_CHANGE_EFLAGS_HOTSPARE_ELEMENT    (0x0002)
-
-/* IR Configuration Change List Event data ReasonCode values */
-#define MPI2_EVENT_IR_CHANGE_RC_ADDED                   (0x01)
-#define MPI2_EVENT_IR_CHANGE_RC_REMOVED                 (0x02)
-#define MPI2_EVENT_IR_CHANGE_RC_NO_CHANGE               (0x03)
-#define MPI2_EVENT_IR_CHANGE_RC_HIDE                    (0x04)
-#define MPI2_EVENT_IR_CHANGE_RC_UNHIDE                  (0x05)
-#define MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED          (0x06)
-#define MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED          (0x07)
-#define MPI2_EVENT_IR_CHANGE_RC_PD_CREATED              (0x08)
-#define MPI2_EVENT_IR_CHANGE_RC_PD_DELETED              (0x09)
-
-typedef struct _MPI2_EVENT_DATA_IR_CONFIG_CHANGE_LIST
-{
-    U8                              NumElements;        /* 0x00 */
-    U8                              Reserved1;          /* 0x01 */
-    U8                              Reserved2;          /* 0x02 */
-    U8                              ConfigNum;          /* 0x03 */
-    U32                             Flags;              /* 0x04 */
-    MPI2_EVENT_IR_CONFIG_ELEMENT    ConfigElement[MPI2_EVENT_IR_CONFIG_ELEMENT_COUNT];    /* 0x08 */
-} MPI2_EVENT_DATA_IR_CONFIG_CHANGE_LIST,
-  MPI2_POINTER PTR_MPI2_EVENT_DATA_IR_CONFIG_CHANGE_LIST,
-  Mpi2EventDataIrConfigChangeList_t,
-  MPI2_POINTER pMpi2EventDataIrConfigChangeList_t;
-
-/* IR Configuration Change List Event data Flags values */
-#define MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG   (0x00000001)
-
-
-/* SAS Discovery Event data */
-
-typedef struct _MPI2_EVENT_DATA_SAS_DISCOVERY
-{
-    U8                      Flags;                      /* 0x00 */
-    U8                      ReasonCode;                 /* 0x01 */
-    U8                      PhysicalPort;               /* 0x02 */
-    U8                      Reserved1;                  /* 0x03 */
-    U32                     DiscoveryStatus;            /* 0x04 */
-} MPI2_EVENT_DATA_SAS_DISCOVERY,
-  MPI2_POINTER PTR_MPI2_EVENT_DATA_SAS_DISCOVERY,
-  Mpi2EventDataSasDiscovery_t, MPI2_POINTER pMpi2EventDataSasDiscovery_t;
-
-/* SAS Discovery Event data Flags values */
-#define MPI2_EVENT_SAS_DISC_DEVICE_CHANGE                   (0x02)
-#define MPI2_EVENT_SAS_DISC_IN_PROGRESS                     (0x01)
-
-/* SAS Discovery Event data ReasonCode values */
-#define MPI2_EVENT_SAS_DISC_RC_STARTED                      (0x01)
-#define MPI2_EVENT_SAS_DISC_RC_COMPLETED                    (0x02)
-
-/* SAS Discovery Event data DiscoveryStatus values */
-#define MPI2_EVENT_SAS_DISC_DS_MAX_ENCLOSURES_EXCEED            (0x80000000)
-#define MPI2_EVENT_SAS_DISC_DS_MAX_EXPANDERS_EXCEED             (0x40000000)
-#define MPI2_EVENT_SAS_DISC_DS_MAX_DEVICES_EXCEED               (0x20000000)
-#define MPI2_EVENT_SAS_DISC_DS_MAX_TOPO_PHYS_EXCEED             (0x10000000)
-#define MPI2_EVENT_SAS_DISC_DS_DOWNSTREAM_INITIATOR             (0x08000000)
-#define MPI2_EVENT_SAS_DISC_DS_MULTI_SUBTRACTIVE_SUBTRACTIVE    (0x00008000)
-#define MPI2_EVENT_SAS_DISC_DS_EXP_MULTI_SUBTRACTIVE            (0x00004000)
-#define MPI2_EVENT_SAS_DISC_DS_MULTI_PORT_DOMAIN                (0x00002000)
-#define MPI2_EVENT_SAS_DISC_DS_TABLE_TO_SUBTRACTIVE_LINK        (0x00001000)
-#define MPI2_EVENT_SAS_DISC_DS_UNSUPPORTED_DEVICE               (0x00000800)
-#define MPI2_EVENT_SAS_DISC_DS_TABLE_LINK                       (0x00000400)
-#define MPI2_EVENT_SAS_DISC_DS_SUBTRACTIVE_LINK                 (0x00000200)
-#define MPI2_EVENT_SAS_DISC_DS_SMP_CRC_ERROR                    (0x00000100)
-#define MPI2_EVENT_SAS_DISC_DS_SMP_FUNCTION_FAILED              (0x00000080)
-#define MPI2_EVENT_SAS_DISC_DS_INDEX_NOT_EXIST                  (0x00000040)
-#define MPI2_EVENT_SAS_DISC_DS_OUT_ROUTE_ENTRIES                (0x00000020)
-#define MPI2_EVENT_SAS_DISC_DS_SMP_TIMEOUT                      (0x00000010)
-#define MPI2_EVENT_SAS_DISC_DS_MULTIPLE_PORTS                   (0x00000004)
-#define MPI2_EVENT_SAS_DISC_DS_UNADDRESSABLE_DEVICE             (0x00000002)
-#define MPI2_EVENT_SAS_DISC_DS_LOOP_DETECTED                    (0x00000001)
-
-
-/* SAS Broadcast Primitive Event data */
-
-typedef struct _MPI2_EVENT_DATA_SAS_BROADCAST_PRIMITIVE
-{
-    U8                      PhyNum;                     /* 0x00 */
-    U8                      Port;                       /* 0x01 */
-    U8                      PortWidth;                  /* 0x02 */
-    U8                      Primitive;                  /* 0x03 */
-} MPI2_EVENT_DATA_SAS_BROADCAST_PRIMITIVE,
-  MPI2_POINTER PTR_MPI2_EVENT_DATA_SAS_BROADCAST_PRIMITIVE,
-  Mpi2EventDataSasBroadcastPrimitive_t,
-  MPI2_POINTER pMpi2EventDataSasBroadcastPrimitive_t;
-
-/* defines for the Primitive field */
-#define MPI2_EVENT_PRIMITIVE_CHANGE                         (0x01)
-#define MPI2_EVENT_PRIMITIVE_SES                            (0x02)
-#define MPI2_EVENT_PRIMITIVE_EXPANDER                       (0x03)
-#define MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT             (0x04)
-#define MPI2_EVENT_PRIMITIVE_RESERVED3                      (0x05)
-#define MPI2_EVENT_PRIMITIVE_RESERVED4                      (0x06)
-#define MPI2_EVENT_PRIMITIVE_CHANGE0_RESERVED               (0x07)
-#define MPI2_EVENT_PRIMITIVE_CHANGE1_RESERVED               (0x08)
-
-/* SAS Notify Primitive Event data */
-
-typedef struct _MPI2_EVENT_DATA_SAS_NOTIFY_PRIMITIVE {
-       U8                      PhyNum;                     /* 0x00 */
-       U8                      Port;                       /* 0x01 */
-       U8                      Reserved1;                  /* 0x02 */
-       U8                      Primitive;                  /* 0x03 */
-} MPI2_EVENT_DATA_SAS_NOTIFY_PRIMITIVE,
-MPI2_POINTER PTR_MPI2_EVENT_DATA_SAS_NOTIFY_PRIMITIVE,
-Mpi2EventDataSasNotifyPrimitive_t,
-MPI2_POINTER pMpi2EventDataSasNotifyPrimitive_t;
-
-/* defines for the Primitive field */
-#define MPI2_EVENT_NOTIFY_ENABLE_SPINUP                     (0x01)
-#define MPI2_EVENT_NOTIFY_POWER_LOSS_EXPECTED               (0x02)
-#define MPI2_EVENT_NOTIFY_RESERVED1                         (0x03)
-#define MPI2_EVENT_NOTIFY_RESERVED2                         (0x04)
-
-
-/* SAS Initiator Device Status Change Event data */
-
-typedef struct _MPI2_EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE
-{
-    U8                      ReasonCode;                 /* 0x00 */
-    U8                      PhysicalPort;               /* 0x01 */
-    U16                     DevHandle;                  /* 0x02 */
-    U64                     SASAddress;                 /* 0x04 */
-} MPI2_EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE,
-  MPI2_POINTER PTR_MPI2_EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE,
-  Mpi2EventDataSasInitDevStatusChange_t,
-  MPI2_POINTER pMpi2EventDataSasInitDevStatusChange_t;
-
-/* SAS Initiator Device Status Change event ReasonCode values */
-#define MPI2_EVENT_SAS_INIT_RC_ADDED                (0x01)
-#define MPI2_EVENT_SAS_INIT_RC_NOT_RESPONDING       (0x02)
-
-
-/* SAS Initiator Device Table Overflow Event data */
-
-typedef struct _MPI2_EVENT_DATA_SAS_INIT_TABLE_OVERFLOW
-{
-    U16                     MaxInit;                    /* 0x00 */
-    U16                     CurrentInit;                /* 0x02 */
-    U64                     SASAddress;                 /* 0x04 */
-} MPI2_EVENT_DATA_SAS_INIT_TABLE_OVERFLOW,
-  MPI2_POINTER PTR_MPI2_EVENT_DATA_SAS_INIT_TABLE_OVERFLOW,
-  Mpi2EventDataSasInitTableOverflow_t,
-  MPI2_POINTER pMpi2EventDataSasInitTableOverflow_t;
-
-
-/* SAS Topology Change List Event data */
-
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check NumEntries at runtime.
- */
-#ifndef MPI2_EVENT_SAS_TOPO_PHY_COUNT
-#define MPI2_EVENT_SAS_TOPO_PHY_COUNT           (1)
-#endif
-
-typedef struct _MPI2_EVENT_SAS_TOPO_PHY_ENTRY
-{
-    U16                     AttachedDevHandle;          /* 0x00 */
-    U8                      LinkRate;                   /* 0x02 */
-    U8                      PhyStatus;                  /* 0x03 */
-} MPI2_EVENT_SAS_TOPO_PHY_ENTRY, MPI2_POINTER PTR_MPI2_EVENT_SAS_TOPO_PHY_ENTRY,
-  Mpi2EventSasTopoPhyEntry_t, MPI2_POINTER pMpi2EventSasTopoPhyEntry_t;
-
-typedef struct _MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST
-{
-    U16                             EnclosureHandle;            /* 0x00 */
-    U16                             ExpanderDevHandle;          /* 0x02 */
-    U8                              NumPhys;                    /* 0x04 */
-    U8                              Reserved1;                  /* 0x05 */
-    U16                             Reserved2;                  /* 0x06 */
-    U8                              NumEntries;                 /* 0x08 */
-    U8                              StartPhyNum;                /* 0x09 */
-    U8                              ExpStatus;                  /* 0x0A */
-    U8                              PhysicalPort;               /* 0x0B */
-    MPI2_EVENT_SAS_TOPO_PHY_ENTRY   PHY[MPI2_EVENT_SAS_TOPO_PHY_COUNT]; /* 0x0C*/
-} MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST,
-  MPI2_POINTER PTR_MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST,
-  Mpi2EventDataSasTopologyChangeList_t,
-  MPI2_POINTER pMpi2EventDataSasTopologyChangeList_t;
-
-/* values for the ExpStatus field */
-#define MPI2_EVENT_SAS_TOPO_ES_NO_EXPANDER                  (0x00)
-#define MPI2_EVENT_SAS_TOPO_ES_ADDED                        (0x01)
-#define MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING               (0x02)
-#define MPI2_EVENT_SAS_TOPO_ES_RESPONDING                   (0x03)
-#define MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING         (0x04)
-
-/* defines for the LinkRate field */
-#define MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK                 (0xF0)
-#define MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT                (4)
-#define MPI2_EVENT_SAS_TOPO_LR_PREV_MASK                    (0x0F)
-#define MPI2_EVENT_SAS_TOPO_LR_PREV_SHIFT                   (0)
-
-#define MPI2_EVENT_SAS_TOPO_LR_UNKNOWN_LINK_RATE            (0x00)
-#define MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED                 (0x01)
-#define MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED           (0x02)
-#define MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE            (0x03)
-#define MPI2_EVENT_SAS_TOPO_LR_PORT_SELECTOR                (0x04)
-#define MPI2_EVENT_SAS_TOPO_LR_SMP_RESET_IN_PROGRESS        (0x05)
-#define MPI2_EVENT_SAS_TOPO_LR_UNSUPPORTED_PHY              (0x06)
-#define MPI2_EVENT_SAS_TOPO_LR_RATE_1_5                     (0x08)
-#define MPI2_EVENT_SAS_TOPO_LR_RATE_3_0                     (0x09)
-#define MPI2_EVENT_SAS_TOPO_LR_RATE_6_0                     (0x0A)
-
-/* values for the PhyStatus field */
-#define MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT                (0x80)
-#define MPI2_EVENT_SAS_TOPO_PS_MULTIPLEX_CHANGE             (0x10)
-/* values for the PhyStatus ReasonCode sub-field */
-#define MPI2_EVENT_SAS_TOPO_RC_MASK                         (0x0F)
-#define MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED                   (0x01)
-#define MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING          (0x02)
-#define MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED                  (0x03)
-#define MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE                    (0x04)
-#define MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING         (0x05)
-
-
-/* SAS Enclosure Device Status Change Event data */
-
-typedef struct _MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE
-{
-    U16                     EnclosureHandle;            /* 0x00 */
-    U8                      ReasonCode;                 /* 0x02 */
-    U8                      PhysicalPort;               /* 0x03 */
-    U64                     EnclosureLogicalID;         /* 0x04 */
-    U16                     NumSlots;                   /* 0x0C */
-    U16                     StartSlot;                  /* 0x0E */
-    U32                     PhyBits;                    /* 0x10 */
-} MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE,
-  MPI2_POINTER PTR_MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE,
-  Mpi2EventDataSasEnclDevStatusChange_t,
-  MPI2_POINTER pMpi2EventDataSasEnclDevStatusChange_t;
-
-/* SAS Enclosure Device Status Change event ReasonCode values */
-#define MPI2_EVENT_SAS_ENCL_RC_ADDED                (0x01)
-#define MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING       (0x02)
-
-
-/* SAS PHY Counter Event data */
-
-typedef struct _MPI2_EVENT_DATA_SAS_PHY_COUNTER {
-    U64         TimeStamp;          /* 0x00 */
-    U32         Reserved1;          /* 0x08 */
-    U8          PhyEventCode;       /* 0x0C */
-    U8          PhyNum;             /* 0x0D */
-    U16         Reserved2;          /* 0x0E */
-    U32         PhyEventInfo;       /* 0x10 */
-    U8          CounterType;        /* 0x14 */
-    U8          ThresholdWindow;    /* 0x15 */
-    U8          TimeUnits;          /* 0x16 */
-    U8          Reserved3;          /* 0x17 */
-    U32         EventThreshold;     /* 0x18 */
-    U16         ThresholdFlags;     /* 0x1C */
-    U16         Reserved4;          /* 0x1E */
-} MPI2_EVENT_DATA_SAS_PHY_COUNTER,
-  MPI2_POINTER PTR_MPI2_EVENT_DATA_SAS_PHY_COUNTER,
-  Mpi2EventDataSasPhyCounter_t, MPI2_POINTER pMpi2EventDataSasPhyCounter_t;
-
-/* use MPI2_SASPHY3_EVENT_CODE_ values from mpi2_cnfg.h for the
- * PhyEventCode field
- * use MPI2_SASPHY3_COUNTER_TYPE_ values from mpi2_cnfg.h for the
- * CounterType field
- * use MPI2_SASPHY3_TIME_UNITS_ values from mpi2_cnfg.h for the
- * TimeUnits field
- * use MPI2_SASPHY3_TFLAGS_ values from mpi2_cnfg.h for the
- * ThresholdFlags field
- * */
-
-
-/* SAS Quiesce Event data */
-
-typedef struct _MPI2_EVENT_DATA_SAS_QUIESCE {
-    U8                      ReasonCode;                 /* 0x00 */
-    U8                      Reserved1;                  /* 0x01 */
-    U16                     Reserved2;                  /* 0x02 */
-    U32                     Reserved3;                  /* 0x04 */
-} MPI2_EVENT_DATA_SAS_QUIESCE,
-  MPI2_POINTER PTR_MPI2_EVENT_DATA_SAS_QUIESCE,
-  Mpi2EventDataSasQuiesce_t, MPI2_POINTER pMpi2EventDataSasQuiesce_t;
-
-/* SAS Quiesce Event data ReasonCode values */
-#define MPI2_EVENT_SAS_QUIESCE_RC_STARTED                   (0x01)
-#define MPI2_EVENT_SAS_QUIESCE_RC_COMPLETED                 (0x02)
-
-
-/* Host Based Discovery Phy Event data */
-
-typedef struct _MPI2_EVENT_HBD_PHY_SAS {
-    U8          Flags;                      /* 0x00 */
-    U8          NegotiatedLinkRate;         /* 0x01 */
-    U8          PhyNum;                     /* 0x02 */
-    U8          PhysicalPort;               /* 0x03 */
-    U32         Reserved1;                  /* 0x04 */
-    U8          InitialFrame[28];           /* 0x08 */
-} MPI2_EVENT_HBD_PHY_SAS, MPI2_POINTER PTR_MPI2_EVENT_HBD_PHY_SAS,
-  Mpi2EventHbdPhySas_t, MPI2_POINTER pMpi2EventHbdPhySas_t;
-
-/* values for the Flags field */
-#define MPI2_EVENT_HBD_SAS_FLAGS_FRAME_VALID        (0x02)
-#define MPI2_EVENT_HBD_SAS_FLAGS_SATA_FRAME         (0x01)
-
-/* use MPI2_SAS_NEG_LINK_RATE_ defines from mpi2_cnfg.h for
- * the NegotiatedLinkRate field */
-
-typedef union _MPI2_EVENT_HBD_DESCRIPTOR {
-    MPI2_EVENT_HBD_PHY_SAS      Sas;
-} MPI2_EVENT_HBD_DESCRIPTOR, MPI2_POINTER PTR_MPI2_EVENT_HBD_DESCRIPTOR,
-  Mpi2EventHbdDescriptor_t, MPI2_POINTER pMpi2EventHbdDescriptor_t;
-
-typedef struct _MPI2_EVENT_DATA_HBD_PHY {
-    U8                          DescriptorType;     /* 0x00 */
-    U8                          Reserved1;          /* 0x01 */
-    U16                         Reserved2;          /* 0x02 */
-    U32                         Reserved3;          /* 0x04 */
-    MPI2_EVENT_HBD_DESCRIPTOR   Descriptor;         /* 0x08 */
-} MPI2_EVENT_DATA_HBD_PHY, MPI2_POINTER PTR_MPI2_EVENT_DATA_HBD_PHY,
-  Mpi2EventDataHbdPhy_t, MPI2_POINTER pMpi2EventDataMpi2EventDataHbdPhy_t;
-
-/* values for the DescriptorType field */
-#define MPI2_EVENT_HBD_DT_SAS               (0x01)
-
-
-
-/****************************************************************************
-*  EventAck message
-****************************************************************************/
-
-/* EventAck Request message */
-typedef struct _MPI2_EVENT_ACK_REQUEST
-{
-    U16                     Reserved1;                      /* 0x00 */
-    U8                      ChainOffset;                    /* 0x02 */
-    U8                      Function;                       /* 0x03 */
-    U16                     Reserved2;                      /* 0x04 */
-    U8                      Reserved3;                      /* 0x06 */
-    U8                      MsgFlags;                       /* 0x07 */
-    U8                      VP_ID;                          /* 0x08 */
-    U8                      VF_ID;                          /* 0x09 */
-    U16                     Reserved4;                      /* 0x0A */
-    U16                     Event;                          /* 0x0C */
-    U16                     Reserved5;                      /* 0x0E */
-    U32                     EventContext;                   /* 0x10 */
-} MPI2_EVENT_ACK_REQUEST, MPI2_POINTER PTR_MPI2_EVENT_ACK_REQUEST,
-  Mpi2EventAckRequest_t, MPI2_POINTER pMpi2EventAckRequest_t;
-
-
-/* EventAck Reply message */
-typedef struct _MPI2_EVENT_ACK_REPLY
-{
-    U16                     Reserved1;                      /* 0x00 */
-    U8                      MsgLength;                      /* 0x02 */
-    U8                      Function;                       /* 0x03 */
-    U16                     Reserved2;                      /* 0x04 */
-    U8                      Reserved3;                      /* 0x06 */
-    U8                      MsgFlags;                       /* 0x07 */
-    U8                      VP_ID;                          /* 0x08 */
-    U8                      VF_ID;                          /* 0x09 */
-    U16                     Reserved4;                      /* 0x0A */
-    U16                     Reserved5;                      /* 0x0C */
-    U16                     IOCStatus;                      /* 0x0E */
-    U32                     IOCLogInfo;                     /* 0x10 */
-} MPI2_EVENT_ACK_REPLY, MPI2_POINTER PTR_MPI2_EVENT_ACK_REPLY,
-  Mpi2EventAckReply_t, MPI2_POINTER pMpi2EventAckReply_t;
-
-
-/****************************************************************************
-*  SendHostMessage message
-****************************************************************************/
-
-/* SendHostMessage Request message */
-typedef struct _MPI2_SEND_HOST_MESSAGE_REQUEST {
-       U16                     HostDataLength;                 /* 0x00 */
-       U8                      ChainOffset;                    /* 0x02 */
-       U8                      Function;                       /* 0x03 */
-       U16                     Reserved1;                      /* 0x04 */
-       U8                      Reserved2;                      /* 0x06 */
-       U8                      MsgFlags;                       /* 0x07 */
-       U8                      VP_ID;                          /* 0x08 */
-       U8                      VF_ID;                          /* 0x09 */
-       U16                     Reserved3;                      /* 0x0A */
-       U8                      Reserved4;                      /* 0x0C */
-       U8                      DestVF_ID;                      /* 0x0D */
-       U16                     Reserved5;                      /* 0x0E */
-       U32                     Reserved6;                      /* 0x10 */
-       U32                     Reserved7;                      /* 0x14 */
-       U32                     Reserved8;                      /* 0x18 */
-       U32                     Reserved9;                      /* 0x1C */
-       U32                     Reserved10;                     /* 0x20 */
-       U32                     HostData[1];                    /* 0x24 */
-} MPI2_SEND_HOST_MESSAGE_REQUEST,
-MPI2_POINTER PTR_MPI2_SEND_HOST_MESSAGE_REQUEST,
-Mpi2SendHostMessageRequest_t, MPI2_POINTER pMpi2SendHostMessageRequest_t;
-
-
-/* SendHostMessage Reply message */
-typedef struct _MPI2_SEND_HOST_MESSAGE_REPLY {
-       U16                     HostDataLength;                 /* 0x00 */
-       U8                      MsgLength;                      /* 0x02 */
-       U8                      Function;                       /* 0x03 */
-       U16                     Reserved1;                      /* 0x04 */
-       U8                      Reserved2;                      /* 0x06 */
-       U8                      MsgFlags;                       /* 0x07 */
-       U8                      VP_ID;                          /* 0x08 */
-       U8                      VF_ID;                          /* 0x09 */
-       U16                     Reserved3;                      /* 0x0A */
-       U16                     Reserved4;                      /* 0x0C */
-       U16                     IOCStatus;                      /* 0x0E */
-       U32                     IOCLogInfo;                     /* 0x10 */
-} MPI2_SEND_HOST_MESSAGE_REPLY, MPI2_POINTER PTR_MPI2_SEND_HOST_MESSAGE_REPLY,
-Mpi2SendHostMessageReply_t, MPI2_POINTER pMpi2SendHostMessageReply_t;
-
-
-/****************************************************************************
-*  FWDownload message
-****************************************************************************/
-
-/* FWDownload Request message */
-typedef struct _MPI2_FW_DOWNLOAD_REQUEST
-{
-    U8                      ImageType;                  /* 0x00 */
-    U8                      Reserved1;                  /* 0x01 */
-    U8                      ChainOffset;                /* 0x02 */
-    U8                      Function;                   /* 0x03 */
-    U16                     Reserved2;                  /* 0x04 */
-    U8                      Reserved3;                  /* 0x06 */
-    U8                      MsgFlags;                   /* 0x07 */
-    U8                      VP_ID;                      /* 0x08 */
-    U8                      VF_ID;                      /* 0x09 */
-    U16                     Reserved4;                  /* 0x0A */
-    U32                     TotalImageSize;             /* 0x0C */
-    U32                     Reserved5;                  /* 0x10 */
-    MPI2_MPI_SGE_UNION      SGL;                        /* 0x14 */
-} MPI2_FW_DOWNLOAD_REQUEST, MPI2_POINTER PTR_MPI2_FW_DOWNLOAD_REQUEST,
-  Mpi2FWDownloadRequest, MPI2_POINTER pMpi2FWDownloadRequest;
-
-#define MPI2_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT   (0x01)
-
-#define MPI2_FW_DOWNLOAD_ITYPE_FW                   (0x01)
-#define MPI2_FW_DOWNLOAD_ITYPE_BIOS                 (0x02)
-#define MPI2_FW_DOWNLOAD_ITYPE_MANUFACTURING        (0x06)
-#define MPI2_FW_DOWNLOAD_ITYPE_CONFIG_1             (0x07)
-#define MPI2_FW_DOWNLOAD_ITYPE_CONFIG_2             (0x08)
-#define MPI2_FW_DOWNLOAD_ITYPE_MEGARAID             (0x09)
-#define MPI2_FW_DOWNLOAD_ITYPE_COMPLETE             (0x0A)
-#define MPI2_FW_DOWNLOAD_ITYPE_COMMON_BOOT_BLOCK    (0x0B)
-#define MPI2_FW_DOWNLOAD_ITYPE_PUBLIC_KEY           (0x0C)
-#define MPI2_FW_DOWNLOAD_ITYPE_MIN_PRODUCT_SPECIFIC (0xF0)
-
-/* FWDownload TransactionContext Element */
-typedef struct _MPI2_FW_DOWNLOAD_TCSGE
-{
-    U8                      Reserved1;                  /* 0x00 */
-    U8                      ContextSize;                /* 0x01 */
-    U8                      DetailsLength;              /* 0x02 */
-    U8                      Flags;                      /* 0x03 */
-    U32                     Reserved2;                  /* 0x04 */
-    U32                     ImageOffset;                /* 0x08 */
-    U32                     ImageSize;                  /* 0x0C */
-} MPI2_FW_DOWNLOAD_TCSGE, MPI2_POINTER PTR_MPI2_FW_DOWNLOAD_TCSGE,
-  Mpi2FWDownloadTCSGE_t, MPI2_POINTER pMpi2FWDownloadTCSGE_t;
-
-/* FWDownload Reply message */
-typedef struct _MPI2_FW_DOWNLOAD_REPLY
-{
-    U8                      ImageType;                  /* 0x00 */
-    U8                      Reserved1;                  /* 0x01 */
-    U8                      MsgLength;                  /* 0x02 */
-    U8                      Function;                   /* 0x03 */
-    U16                     Reserved2;                  /* 0x04 */
-    U8                      Reserved3;                  /* 0x06 */
-    U8                      MsgFlags;                   /* 0x07 */
-    U8                      VP_ID;                      /* 0x08 */
-    U8                      VF_ID;                      /* 0x09 */
-    U16                     Reserved4;                  /* 0x0A */
-    U16                     Reserved5;                  /* 0x0C */
-    U16                     IOCStatus;                  /* 0x0E */
-    U32                     IOCLogInfo;                 /* 0x10 */
-} MPI2_FW_DOWNLOAD_REPLY, MPI2_POINTER PTR_MPI2_FW_DOWNLOAD_REPLY,
-  Mpi2FWDownloadReply_t, MPI2_POINTER pMpi2FWDownloadReply_t;
-
-
-/****************************************************************************
-*  FWUpload message
-****************************************************************************/
-
-/* FWUpload Request message */
-typedef struct _MPI2_FW_UPLOAD_REQUEST
-{
-    U8                      ImageType;                  /* 0x00 */
-    U8                      Reserved1;                  /* 0x01 */
-    U8                      ChainOffset;                /* 0x02 */
-    U8                      Function;                   /* 0x03 */
-    U16                     Reserved2;                  /* 0x04 */
-    U8                      Reserved3;                  /* 0x06 */
-    U8                      MsgFlags;                   /* 0x07 */
-    U8                      VP_ID;                      /* 0x08 */
-    U8                      VF_ID;                      /* 0x09 */
-    U16                     Reserved4;                  /* 0x0A */
-    U32                     Reserved5;                  /* 0x0C */
-    U32                     Reserved6;                  /* 0x10 */
-    MPI2_MPI_SGE_UNION      SGL;                        /* 0x14 */
-} MPI2_FW_UPLOAD_REQUEST, MPI2_POINTER PTR_MPI2_FW_UPLOAD_REQUEST,
-  Mpi2FWUploadRequest_t, MPI2_POINTER pMpi2FWUploadRequest_t;
-
-#define MPI2_FW_UPLOAD_ITYPE_FW_CURRENT         (0x00)
-#define MPI2_FW_UPLOAD_ITYPE_FW_FLASH           (0x01)
-#define MPI2_FW_UPLOAD_ITYPE_BIOS_FLASH         (0x02)
-#define MPI2_FW_UPLOAD_ITYPE_FW_BACKUP          (0x05)
-#define MPI2_FW_UPLOAD_ITYPE_MANUFACTURING      (0x06)
-#define MPI2_FW_UPLOAD_ITYPE_CONFIG_1           (0x07)
-#define MPI2_FW_UPLOAD_ITYPE_CONFIG_2           (0x08)
-#define MPI2_FW_UPLOAD_ITYPE_MEGARAID           (0x09)
-#define MPI2_FW_UPLOAD_ITYPE_COMPLETE           (0x0A)
-#define MPI2_FW_UPLOAD_ITYPE_COMMON_BOOT_BLOCK  (0x0B)
-
-typedef struct _MPI2_FW_UPLOAD_TCSGE
-{
-    U8                      Reserved1;                  /* 0x00 */
-    U8                      ContextSize;                /* 0x01 */
-    U8                      DetailsLength;              /* 0x02 */
-    U8                      Flags;                      /* 0x03 */
-    U32                     Reserved2;                  /* 0x04 */
-    U32                     ImageOffset;                /* 0x08 */
-    U32                     ImageSize;                  /* 0x0C */
-} MPI2_FW_UPLOAD_TCSGE, MPI2_POINTER PTR_MPI2_FW_UPLOAD_TCSGE,
-  Mpi2FWUploadTCSGE_t, MPI2_POINTER pMpi2FWUploadTCSGE_t;
-
-/* FWUpload Reply message */
-typedef struct _MPI2_FW_UPLOAD_REPLY
-{
-    U8                      ImageType;                  /* 0x00 */
-    U8                      Reserved1;                  /* 0x01 */
-    U8                      MsgLength;                  /* 0x02 */
-    U8                      Function;                   /* 0x03 */
-    U16                     Reserved2;                  /* 0x04 */
-    U8                      Reserved3;                  /* 0x06 */
-    U8                      MsgFlags;                   /* 0x07 */
-    U8                      VP_ID;                      /* 0x08 */
-    U8                      VF_ID;                      /* 0x09 */
-    U16                     Reserved4;                  /* 0x0A */
-    U16                     Reserved5;                  /* 0x0C */
-    U16                     IOCStatus;                  /* 0x0E */
-    U32                     IOCLogInfo;                 /* 0x10 */
-    U32                     ActualImageSize;            /* 0x14 */
-} MPI2_FW_UPLOAD_REPLY, MPI2_POINTER PTR_MPI2_FW_UPLOAD_REPLY,
-  Mpi2FWUploadReply_t, MPI2_POINTER pMPi2FWUploadReply_t;
-
-
-/* FW Image Header */
-typedef struct _MPI2_FW_IMAGE_HEADER
-{
-    U32                     Signature;                  /* 0x00 */
-    U32                     Signature0;                 /* 0x04 */
-    U32                     Signature1;                 /* 0x08 */
-    U32                     Signature2;                 /* 0x0C */
-    MPI2_VERSION_UNION      MPIVersion;                 /* 0x10 */
-    MPI2_VERSION_UNION      FWVersion;                  /* 0x14 */
-    MPI2_VERSION_UNION      NVDATAVersion;              /* 0x18 */
-    MPI2_VERSION_UNION      PackageVersion;             /* 0x1C */
-    U16                     VendorID;                   /* 0x20 */
-    U16                     ProductID;                  /* 0x22 */
-    U16                     ProtocolFlags;              /* 0x24 */
-    U16                     Reserved26;                 /* 0x26 */
-    U32                     IOCCapabilities;            /* 0x28 */
-    U32                     ImageSize;                  /* 0x2C */
-    U32                     NextImageHeaderOffset;      /* 0x30 */
-    U32                     Checksum;                   /* 0x34 */
-    U32                     Reserved38;                 /* 0x38 */
-    U32                     Reserved3C;                 /* 0x3C */
-    U32                     Reserved40;                 /* 0x40 */
-    U32                     Reserved44;                 /* 0x44 */
-    U32                     Reserved48;                 /* 0x48 */
-    U32                     Reserved4C;                 /* 0x4C */
-    U32                     Reserved50;                 /* 0x50 */
-    U32                     Reserved54;                 /* 0x54 */
-    U32                     Reserved58;                 /* 0x58 */
-    U32                     Reserved5C;                 /* 0x5C */
-    U32                     Reserved60;                 /* 0x60 */
-    U32                     FirmwareVersionNameWhat;    /* 0x64 */
-    U8                      FirmwareVersionName[32];    /* 0x68 */
-    U32                     VendorNameWhat;             /* 0x88 */
-    U8                      VendorName[32];             /* 0x8C */
-    U32                     PackageNameWhat;            /* 0x88 */
-    U8                      PackageName[32];            /* 0x8C */
-    U32                     ReservedD0;                 /* 0xD0 */
-    U32                     ReservedD4;                 /* 0xD4 */
-    U32                     ReservedD8;                 /* 0xD8 */
-    U32                     ReservedDC;                 /* 0xDC */
-    U32                     ReservedE0;                 /* 0xE0 */
-    U32                     ReservedE4;                 /* 0xE4 */
-    U32                     ReservedE8;                 /* 0xE8 */
-    U32                     ReservedEC;                 /* 0xEC */
-    U32                     ReservedF0;                 /* 0xF0 */
-    U32                     ReservedF4;                 /* 0xF4 */
-    U32                     ReservedF8;                 /* 0xF8 */
-    U32                     ReservedFC;                 /* 0xFC */
-} MPI2_FW_IMAGE_HEADER, MPI2_POINTER PTR_MPI2_FW_IMAGE_HEADER,
-  Mpi2FWImageHeader_t, MPI2_POINTER pMpi2FWImageHeader_t;
-
-/* Signature field */
-#define MPI2_FW_HEADER_SIGNATURE_OFFSET         (0x00)
-#define MPI2_FW_HEADER_SIGNATURE_MASK           (0xFF000000)
-#define MPI2_FW_HEADER_SIGNATURE                (0xEA000000)
-
-/* Signature0 field */
-#define MPI2_FW_HEADER_SIGNATURE0_OFFSET        (0x04)
-#define MPI2_FW_HEADER_SIGNATURE0               (0x5AFAA55A)
-
-/* Signature1 field */
-#define MPI2_FW_HEADER_SIGNATURE1_OFFSET        (0x08)
-#define MPI2_FW_HEADER_SIGNATURE1               (0xA55AFAA5)
-
-/* Signature2 field */
-#define MPI2_FW_HEADER_SIGNATURE2_OFFSET        (0x0C)
-#define MPI2_FW_HEADER_SIGNATURE2               (0x5AA55AFA)
-
-
-/* defines for using the ProductID field */
-#define MPI2_FW_HEADER_PID_TYPE_MASK            (0xF000)
-#define MPI2_FW_HEADER_PID_TYPE_SAS             (0x2000)
-
-#define MPI2_FW_HEADER_PID_PROD_MASK                    (0x0F00)
-#define MPI2_FW_HEADER_PID_PROD_A                       (0x0000)
-#define MPI2_FW_HEADER_PID_PROD_TARGET_INITIATOR_SCSI   (0x0200)
-#define MPI2_FW_HEADER_PID_PROD_IR_SCSI                 (0x0700)
-
-
-#define MPI2_FW_HEADER_PID_FAMILY_MASK          (0x00FF)
-/* SAS */
-#define MPI2_FW_HEADER_PID_FAMILY_2108_SAS      (0x0013)
-#define MPI2_FW_HEADER_PID_FAMILY_2208_SAS      (0x0014)
-
-/* use MPI2_IOCFACTS_PROTOCOL_ defines for ProtocolFlags field */
-
-/* use MPI2_IOCFACTS_CAPABILITY_ defines for IOCCapabilities field */
-
-
-#define MPI2_FW_HEADER_IMAGESIZE_OFFSET         (0x2C)
-#define MPI2_FW_HEADER_NEXTIMAGE_OFFSET         (0x30)
-#define MPI2_FW_HEADER_VERNMHWAT_OFFSET         (0x64)
-
-#define MPI2_FW_HEADER_WHAT_SIGNATURE           (0x29232840)
-
-#define MPI2_FW_HEADER_SIZE                     (0x100)
-
-
-/* Extended Image Header */
-typedef struct _MPI2_EXT_IMAGE_HEADER
-
-{
-    U8                      ImageType;                  /* 0x00 */
-    U8                      Reserved1;                  /* 0x01 */
-    U16                     Reserved2;                  /* 0x02 */
-    U32                     Checksum;                   /* 0x04 */
-    U32                     ImageSize;                  /* 0x08 */
-    U32                     NextImageHeaderOffset;      /* 0x0C */
-    U32                     PackageVersion;             /* 0x10 */
-    U32                     Reserved3;                  /* 0x14 */
-    U32                     Reserved4;                  /* 0x18 */
-    U32                     Reserved5;                  /* 0x1C */
-    U8                      IdentifyString[32];         /* 0x20 */
-} MPI2_EXT_IMAGE_HEADER, MPI2_POINTER PTR_MPI2_EXT_IMAGE_HEADER,
-  Mpi2ExtImageHeader_t, MPI2_POINTER pMpi2ExtImageHeader_t;
-
-/* useful offsets */
-#define MPI2_EXT_IMAGE_IMAGETYPE_OFFSET         (0x00)
-#define MPI2_EXT_IMAGE_IMAGESIZE_OFFSET         (0x08)
-#define MPI2_EXT_IMAGE_NEXTIMAGE_OFFSET         (0x0C)
-
-#define MPI2_EXT_IMAGE_HEADER_SIZE              (0x40)
-
-/* defines for the ImageType field */
-#define MPI2_EXT_IMAGE_TYPE_UNSPECIFIED             (0x00)
-#define MPI2_EXT_IMAGE_TYPE_FW                      (0x01)
-#define MPI2_EXT_IMAGE_TYPE_NVDATA                  (0x03)
-#define MPI2_EXT_IMAGE_TYPE_BOOTLOADER              (0x04)
-#define MPI2_EXT_IMAGE_TYPE_INITIALIZATION          (0x05)
-#define MPI2_EXT_IMAGE_TYPE_FLASH_LAYOUT            (0x06)
-#define MPI2_EXT_IMAGE_TYPE_SUPPORTED_DEVICES       (0x07)
-#define MPI2_EXT_IMAGE_TYPE_MEGARAID                (0x08)
-#define MPI2_EXT_IMAGE_TYPE_ENCRYPTED_HASH          (0x09)
-#define MPI2_EXT_IMAGE_TYPE_MIN_PRODUCT_SPECIFIC    (0x80)
-#define MPI2_EXT_IMAGE_TYPE_MAX_PRODUCT_SPECIFIC    (0xFF)
-#define MPI2_EXT_IMAGE_TYPE_MAX                   \
-       (MPI2_EXT_IMAGE_TYPE_MAX_PRODUCT_SPECIFIC)      /* deprecated */
-
-
-
-/* FLASH Layout Extended Image Data */
-
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check RegionsPerLayout at runtime.
- */
-#ifndef MPI2_FLASH_NUMBER_OF_REGIONS
-#define MPI2_FLASH_NUMBER_OF_REGIONS        (1)
-#endif
-
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check NumberOfLayouts at runtime.
- */
-#ifndef MPI2_FLASH_NUMBER_OF_LAYOUTS
-#define MPI2_FLASH_NUMBER_OF_LAYOUTS        (1)
-#endif
-
-typedef struct _MPI2_FLASH_REGION
-{
-    U8                      RegionType;                 /* 0x00 */
-    U8                      Reserved1;                  /* 0x01 */
-    U16                     Reserved2;                  /* 0x02 */
-    U32                     RegionOffset;               /* 0x04 */
-    U32                     RegionSize;                 /* 0x08 */
-    U32                     Reserved3;                  /* 0x0C */
-} MPI2_FLASH_REGION, MPI2_POINTER PTR_MPI2_FLASH_REGION,
-  Mpi2FlashRegion_t, MPI2_POINTER pMpi2FlashRegion_t;
-
-typedef struct _MPI2_FLASH_LAYOUT
-{
-    U32                     FlashSize;                  /* 0x00 */
-    U32                     Reserved1;                  /* 0x04 */
-    U32                     Reserved2;                  /* 0x08 */
-    U32                     Reserved3;                  /* 0x0C */
-    MPI2_FLASH_REGION       Region[MPI2_FLASH_NUMBER_OF_REGIONS];/* 0x10 */
-} MPI2_FLASH_LAYOUT, MPI2_POINTER PTR_MPI2_FLASH_LAYOUT,
-  Mpi2FlashLayout_t, MPI2_POINTER pMpi2FlashLayout_t;
-
-typedef struct _MPI2_FLASH_LAYOUT_DATA
-{
-    U8                      ImageRevision;              /* 0x00 */
-    U8                      Reserved1;                  /* 0x01 */
-    U8                      SizeOfRegion;               /* 0x02 */
-    U8                      Reserved2;                  /* 0x03 */
-    U16                     NumberOfLayouts;            /* 0x04 */
-    U16                     RegionsPerLayout;           /* 0x06 */
-    U16                     MinimumSectorAlignment;     /* 0x08 */
-    U16                     Reserved3;                  /* 0x0A */
-    U32                     Reserved4;                  /* 0x0C */
-    MPI2_FLASH_LAYOUT       Layout[MPI2_FLASH_NUMBER_OF_LAYOUTS];/* 0x10 */
-} MPI2_FLASH_LAYOUT_DATA, MPI2_POINTER PTR_MPI2_FLASH_LAYOUT_DATA,
-  Mpi2FlashLayoutData_t, MPI2_POINTER pMpi2FlashLayoutData_t;
-
-/* defines for the RegionType field */
-#define MPI2_FLASH_REGION_UNUSED                (0x00)
-#define MPI2_FLASH_REGION_FIRMWARE              (0x01)
-#define MPI2_FLASH_REGION_BIOS                  (0x02)
-#define MPI2_FLASH_REGION_NVDATA                (0x03)
-#define MPI2_FLASH_REGION_FIRMWARE_BACKUP       (0x05)
-#define MPI2_FLASH_REGION_MFG_INFORMATION       (0x06)
-#define MPI2_FLASH_REGION_CONFIG_1              (0x07)
-#define MPI2_FLASH_REGION_CONFIG_2              (0x08)
-#define MPI2_FLASH_REGION_MEGARAID              (0x09)
-#define MPI2_FLASH_REGION_INIT                  (0x0A)
-
-/* ImageRevision */
-#define MPI2_FLASH_LAYOUT_IMAGE_REVISION        (0x00)
-
-
-
-/* Supported Devices Extended Image Data */
-
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check NumberOfDevices at runtime.
- */
-#ifndef MPI2_SUPPORTED_DEVICES_IMAGE_NUM_DEVICES
-#define MPI2_SUPPORTED_DEVICES_IMAGE_NUM_DEVICES    (1)
-#endif
-
-typedef struct _MPI2_SUPPORTED_DEVICE
-{
-    U16                     DeviceID;                   /* 0x00 */
-    U16                     VendorID;                   /* 0x02 */
-    U16                     DeviceIDMask;               /* 0x04 */
-    U16                     Reserved1;                  /* 0x06 */
-    U8                      LowPCIRev;                  /* 0x08 */
-    U8                      HighPCIRev;                 /* 0x09 */
-    U16                     Reserved2;                  /* 0x0A */
-    U32                     Reserved3;                  /* 0x0C */
-} MPI2_SUPPORTED_DEVICE, MPI2_POINTER PTR_MPI2_SUPPORTED_DEVICE,
-  Mpi2SupportedDevice_t, MPI2_POINTER pMpi2SupportedDevice_t;
-
-typedef struct _MPI2_SUPPORTED_DEVICES_DATA
-{
-    U8                      ImageRevision;              /* 0x00 */
-    U8                      Reserved1;                  /* 0x01 */
-    U8                      NumberOfDevices;            /* 0x02 */
-    U8                      Reserved2;                  /* 0x03 */
-    U32                     Reserved3;                  /* 0x04 */
-    MPI2_SUPPORTED_DEVICE   SupportedDevice[MPI2_SUPPORTED_DEVICES_IMAGE_NUM_DEVICES]; /* 0x08 */
-} MPI2_SUPPORTED_DEVICES_DATA, MPI2_POINTER PTR_MPI2_SUPPORTED_DEVICES_DATA,
-  Mpi2SupportedDevicesData_t, MPI2_POINTER pMpi2SupportedDevicesData_t;
-
-/* ImageRevision */
-#define MPI2_SUPPORTED_DEVICES_IMAGE_REVISION   (0x00)
-
-
-/* Init Extended Image Data */
-
-typedef struct _MPI2_INIT_IMAGE_FOOTER
-
-{
-    U32                     BootFlags;                  /* 0x00 */
-    U32                     ImageSize;                  /* 0x04 */
-    U32                     Signature0;                 /* 0x08 */
-    U32                     Signature1;                 /* 0x0C */
-    U32                     Signature2;                 /* 0x10 */
-    U32                     ResetVector;                /* 0x14 */
-} MPI2_INIT_IMAGE_FOOTER, MPI2_POINTER PTR_MPI2_INIT_IMAGE_FOOTER,
-  Mpi2InitImageFooter_t, MPI2_POINTER pMpi2InitImageFooter_t;
-
-/* defines for the BootFlags field */
-#define MPI2_INIT_IMAGE_BOOTFLAGS_OFFSET        (0x00)
-
-/* defines for the ImageSize field */
-#define MPI2_INIT_IMAGE_IMAGESIZE_OFFSET        (0x04)
-
-/* defines for the Signature0 field */
-#define MPI2_INIT_IMAGE_SIGNATURE0_OFFSET       (0x08)
-#define MPI2_INIT_IMAGE_SIGNATURE0              (0x5AA55AEA)
-
-/* defines for the Signature1 field */
-#define MPI2_INIT_IMAGE_SIGNATURE1_OFFSET       (0x0C)
-#define MPI2_INIT_IMAGE_SIGNATURE1              (0xA55AEAA5)
-
-/* defines for the Signature2 field */
-#define MPI2_INIT_IMAGE_SIGNATURE2_OFFSET       (0x10)
-#define MPI2_INIT_IMAGE_SIGNATURE2              (0x5AEAA55A)
-
-/* Signature fields as individual bytes */
-#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_0        (0xEA)
-#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_1        (0x5A)
-#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_2        (0xA5)
-#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_3        (0x5A)
-
-#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_4        (0xA5)
-#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_5        (0xEA)
-#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_6        (0x5A)
-#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_7        (0xA5)
-
-#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_8        (0x5A)
-#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_9        (0xA5)
-#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_A        (0xEA)
-#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_B        (0x5A)
-
-/* defines for the ResetVector field */
-#define MPI2_INIT_IMAGE_RESETVECTOR_OFFSET      (0x14)
-
-
-/* Encrypted Hash Extended Image Data */
-
-typedef struct _MPI25_ENCRYPTED_HASH_ENTRY {
-       U8                  HashImageType;          /* 0x00 */
-       U8                  HashAlgorithm;          /* 0x01 */
-       U8                  EncryptionAlgorithm;    /* 0x02 */
-       U8                  Reserved1;              /* 0x03 */
-       U32                 Reserved2;              /* 0x04 */
-       U32                 EncryptedHash[1];       /* 0x08 */
-} MPI25_ENCRYPTED_HASH_ENTRY, MPI2_POINTER PTR_MPI25_ENCRYPTED_HASH_ENTRY,
-Mpi25EncryptedHashEntry_t, MPI2_POINTER pMpi25EncryptedHashEntry_t;
-
-/* values for HashImageType */
-#define MPI25_HASH_IMAGE_TYPE_UNUSED            (0x00)
-#define MPI25_HASH_IMAGE_TYPE_FIRMWARE          (0x01)
-#define MPI25_HASH_IMAGE_TYPE_BIOS              (0x02)
-
-/* values for HashAlgorithm */
-#define MPI25_HASH_ALGORITHM_UNUSED             (0x00)
-#define MPI25_HASH_ALGORITHM_SHA256             (0x01)
-
-/* values for EncryptionAlgorithm */
-#define MPI25_ENCRYPTION_ALG_UNUSED             (0x00)
-#define MPI25_ENCRYPTION_ALG_RSA256             (0x01)
-
-typedef struct _MPI25_ENCRYPTED_HASH_DATA {
-       U8                              ImageVersion;           /* 0x00 */
-       U8                              NumHash;                /* 0x01 */
-       U16                             Reserved1;              /* 0x02 */
-       U32                             Reserved2;              /* 0x04 */
-       MPI25_ENCRYPTED_HASH_ENTRY      EncryptedHashEntry[1];  /* 0x08 */
-} MPI25_ENCRYPTED_HASH_DATA, MPI2_POINTER PTR_MPI25_ENCRYPTED_HASH_DATA,
-Mpi25EncryptedHashData_t, MPI2_POINTER pMpi25EncryptedHashData_t;
-
-/****************************************************************************
-*  PowerManagementControl message
-****************************************************************************/
-
-/* PowerManagementControl Request message */
-typedef struct _MPI2_PWR_MGMT_CONTROL_REQUEST {
-    U8                      Feature;                    /* 0x00 */
-    U8                      Reserved1;                  /* 0x01 */
-    U8                      ChainOffset;                /* 0x02 */
-    U8                      Function;                   /* 0x03 */
-    U16                     Reserved2;                  /* 0x04 */
-    U8                      Reserved3;                  /* 0x06 */
-    U8                      MsgFlags;                   /* 0x07 */
-    U8                      VP_ID;                      /* 0x08 */
-    U8                      VF_ID;                      /* 0x09 */
-    U16                     Reserved4;                  /* 0x0A */
-    U8                      Parameter1;                 /* 0x0C */
-    U8                      Parameter2;                 /* 0x0D */
-    U8                      Parameter3;                 /* 0x0E */
-    U8                      Parameter4;                 /* 0x0F */
-    U32                     Reserved5;                  /* 0x10 */
-    U32                     Reserved6;                  /* 0x14 */
-} MPI2_PWR_MGMT_CONTROL_REQUEST, MPI2_POINTER PTR_MPI2_PWR_MGMT_CONTROL_REQUEST,
-  Mpi2PwrMgmtControlRequest_t, MPI2_POINTER pMpi2PwrMgmtControlRequest_t;
-
-/* defines for the Feature field */
-#define MPI2_PM_CONTROL_FEATURE_DA_PHY_POWER_COND       (0x01)
-#define MPI2_PM_CONTROL_FEATURE_PORT_WIDTH_MODULATION   (0x02)
-#define MPI2_PM_CONTROL_FEATURE_PCIE_LINK               (0x03) /* obsolete */
-#define MPI2_PM_CONTROL_FEATURE_IOC_SPEED               (0x04)
-#define MPI2_PM_CONTROL_FEATURE_MIN_PRODUCT_SPECIFIC    (0x80)
-#define MPI2_PM_CONTROL_FEATURE_MAX_PRODUCT_SPECIFIC    (0xFF)
-
-/* parameter usage for the MPI2_PM_CONTROL_FEATURE_DA_PHY_POWER_COND Feature */
-/* Parameter1 contains a PHY number */
-/* Parameter2 indicates power condition action using these defines */
-#define MPI2_PM_CONTROL_PARAM2_PARTIAL                  (0x01)
-#define MPI2_PM_CONTROL_PARAM2_SLUMBER                  (0x02)
-#define MPI2_PM_CONTROL_PARAM2_EXIT_PWR_MGMT            (0x03)
-/* Parameter3 and Parameter4 are reserved */
-
-/* parameter usage for the MPI2_PM_CONTROL_FEATURE_PORT_WIDTH_MODULATION
- *  Feature */
-/* Parameter1 contains SAS port width modulation group number */
-/* Parameter2 indicates IOC action using these defines */
-#define MPI2_PM_CONTROL_PARAM2_REQUEST_OWNERSHIP        (0x01)
-#define MPI2_PM_CONTROL_PARAM2_CHANGE_MODULATION        (0x02)
-#define MPI2_PM_CONTROL_PARAM2_RELINQUISH_OWNERSHIP     (0x03)
-/* Parameter3 indicates desired modulation level using these defines */
-#define MPI2_PM_CONTROL_PARAM3_25_PERCENT               (0x00)
-#define MPI2_PM_CONTROL_PARAM3_50_PERCENT               (0x01)
-#define MPI2_PM_CONTROL_PARAM3_75_PERCENT               (0x02)
-#define MPI2_PM_CONTROL_PARAM3_100_PERCENT              (0x03)
-/* Parameter4 is reserved */
-
-/* parameter usage for the MPI2_PM_CONTROL_FEATURE_PCIE_LINK Feature */
-/* Parameter1 indicates desired PCIe link speed using these defines */
-#define MPI2_PM_CONTROL_PARAM1_PCIE_2_5_GBPS            (0x00) /* obsolete */
-#define MPI2_PM_CONTROL_PARAM1_PCIE_5_0_GBPS            (0x01) /* obsolete */
-#define MPI2_PM_CONTROL_PARAM1_PCIE_8_0_GBPS            (0x02) /* obsolete */
-/* Parameter2 indicates desired PCIe link width using these defines */
-#define MPI2_PM_CONTROL_PARAM2_WIDTH_X1                 (0x01) /* obsolete */
-#define MPI2_PM_CONTROL_PARAM2_WIDTH_X2                 (0x02) /* obsolete */
-#define MPI2_PM_CONTROL_PARAM2_WIDTH_X4                 (0x04) /* obsolete */
-#define MPI2_PM_CONTROL_PARAM2_WIDTH_X8                 (0x08) /* obsolete */
-/* Parameter3 and Parameter4 are reserved */
-
-/* parameter usage for the MPI2_PM_CONTROL_FEATURE_IOC_SPEED Feature */
-/* Parameter1 indicates desired IOC hardware clock speed using these defines */
-#define MPI2_PM_CONTROL_PARAM1_FULL_IOC_SPEED           (0x01)
-#define MPI2_PM_CONTROL_PARAM1_HALF_IOC_SPEED           (0x02)
-#define MPI2_PM_CONTROL_PARAM1_QUARTER_IOC_SPEED        (0x04)
-#define MPI2_PM_CONTROL_PARAM1_EIGHTH_IOC_SPEED         (0x08)
-/* Parameter2, Parameter3, and Parameter4 are reserved */
-
-
-/* PowerManagementControl Reply message */
-typedef struct _MPI2_PWR_MGMT_CONTROL_REPLY {
-    U8                      Feature;                    /* 0x00 */
-    U8                      Reserved1;                  /* 0x01 */
-    U8                      MsgLength;                  /* 0x02 */
-    U8                      Function;                   /* 0x03 */
-    U16                     Reserved2;                  /* 0x04 */
-    U8                      Reserved3;                  /* 0x06 */
-    U8                      MsgFlags;                   /* 0x07 */
-    U8                      VP_ID;                      /* 0x08 */
-    U8                      VF_ID;                      /* 0x09 */
-    U16                     Reserved4;                  /* 0x0A */
-    U16                     Reserved5;                  /* 0x0C */
-    U16                     IOCStatus;                  /* 0x0E */
-    U32                     IOCLogInfo;                 /* 0x10 */
-} MPI2_PWR_MGMT_CONTROL_REPLY, MPI2_POINTER PTR_MPI2_PWR_MGMT_CONTROL_REPLY,
-  Mpi2PwrMgmtControlReply_t, MPI2_POINTER pMpi2PwrMgmtControlReply_t;
-
-
-#endif
-
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_raid.h b/drivers/scsi/mpt2sas/mpi/mpi2_raid.h
deleted file mode 100644 (file)
index 7efa58f..0000000
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
- *  Copyright (c) 2000-2014 LSI Corporation.
- *
- *
- *           Name:  mpi2_raid.h
- *          Title:  MPI Integrated RAID messages and structures
- *  Creation Date:  April 26, 2007
- *
- *    mpi2_raid.h Version:  02.00.10
- *
- *  Version History
- *  ---------------
- *
- *  Date      Version   Description
- *  --------  --------  ------------------------------------------------------
- *  04-30-07  02.00.00  Corresponds to Fusion-MPT MPI Specification Rev A.
- *  08-31-07  02.00.01  Modifications to RAID Action request and reply,
- *                      including the Actions and ActionData.
- *  02-29-08  02.00.02  Added MPI2_RAID_ACTION_ADATA_DISABL_FULL_REBUILD.
- *  05-21-08  02.00.03  Added MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS so that
- *                      the PhysDisk array in MPI2_RAID_VOLUME_CREATION_STRUCT
- *                      can be sized by the build environment.
- *  07-30-09  02.00.04  Added proper define for the Use Default Settings bit of
- *                      VolumeCreationFlags and marked the old one as obsolete.
- *  05-12-10  02.00.05  Added MPI2_RAID_VOL_FLAGS_OP_MDC define.
- *  08-24-10  02.00.06  Added MPI2_RAID_ACTION_COMPATIBILITY_CHECK along with
- *                      related structures and defines.
- *                      Added product-specific range to RAID Action values.
- *  02-06-12  02.00.08  Added MPI2_RAID_ACTION_PHYSDISK_HIDDEN.
- *  07-26-12  02.00.09  Added ElapsedSeconds field to MPI2_RAID_VOL_INDICATOR.
- *                      Added MPI2_RAID_VOL_FLAGS_ELAPSED_SECONDS_VALID define.
- *  04-17-13  02.00.10  Added MPI25_RAID_ACTION_ADATA_ALLOW_PI.
- *  --------------------------------------------------------------------------
- */
-
-#ifndef MPI2_RAID_H
-#define MPI2_RAID_H
-
-/*****************************************************************************
-*
-*               Integrated RAID Messages
-*
-*****************************************************************************/
-
-/****************************************************************************
-*  RAID Action messages
-****************************************************************************/
-
-/* ActionDataWord defines for use with MPI2_RAID_ACTION_CREATE_VOLUME action */
-#define MPI25_RAID_ACTION_ADATA_ALLOW_PI            (0x80000000)
-
-/* ActionDataWord defines for use with MPI2_RAID_ACTION_DELETE_VOLUME action */
-#define MPI2_RAID_ACTION_ADATA_KEEP_LBA0            (0x00000000)
-#define MPI2_RAID_ACTION_ADATA_ZERO_LBA0            (0x00000001)
-
-/* use MPI2_RAIDVOL0_SETTING_ defines from mpi2_cnfg.h for MPI2_RAID_ACTION_CHANGE_VOL_WRITE_CACHE action */
-
-/* ActionDataWord defines for use with MPI2_RAID_ACTION_DISABLE_ALL_VOLUMES action */
-#define MPI2_RAID_ACTION_ADATA_DISABL_FULL_REBUILD  (0x00000001)
-
-/* ActionDataWord for MPI2_RAID_ACTION_SET_RAID_FUNCTION_RATE Action */
-typedef struct _MPI2_RAID_ACTION_RATE_DATA
-{
-    U8              RateToChange;               /* 0x00 */
-    U8              RateOrMode;                 /* 0x01 */
-    U16             DataScrubDuration;          /* 0x02 */
-} MPI2_RAID_ACTION_RATE_DATA, MPI2_POINTER PTR_MPI2_RAID_ACTION_RATE_DATA,
-  Mpi2RaidActionRateData_t, MPI2_POINTER pMpi2RaidActionRateData_t;
-
-#define MPI2_RAID_ACTION_SET_RATE_RESYNC            (0x00)
-#define MPI2_RAID_ACTION_SET_RATE_DATA_SCRUB        (0x01)
-#define MPI2_RAID_ACTION_SET_RATE_POWERSAVE_MODE    (0x02)
-
-/* ActionDataWord for MPI2_RAID_ACTION_START_RAID_FUNCTION Action */
-typedef struct _MPI2_RAID_ACTION_START_RAID_FUNCTION
-{
-    U8              RAIDFunction;                       /* 0x00 */
-    U8              Flags;                              /* 0x01 */
-    U16             Reserved1;                          /* 0x02 */
-} MPI2_RAID_ACTION_START_RAID_FUNCTION,
-  MPI2_POINTER PTR_MPI2_RAID_ACTION_START_RAID_FUNCTION,
-  Mpi2RaidActionStartRaidFunction_t,
-  MPI2_POINTER pMpi2RaidActionStartRaidFunction_t;
-
-/* defines for the RAIDFunction field */
-#define MPI2_RAID_ACTION_START_BACKGROUND_INIT      (0x00)
-#define MPI2_RAID_ACTION_START_ONLINE_CAP_EXPANSION (0x01)
-#define MPI2_RAID_ACTION_START_CONSISTENCY_CHECK    (0x02)
-
-/* defines for the Flags field */
-#define MPI2_RAID_ACTION_START_NEW                  (0x00)
-#define MPI2_RAID_ACTION_START_RESUME               (0x01)
-
-/* ActionDataWord for MPI2_RAID_ACTION_STOP_RAID_FUNCTION Action */
-typedef struct _MPI2_RAID_ACTION_STOP_RAID_FUNCTION
-{
-    U8              RAIDFunction;                       /* 0x00 */
-    U8              Flags;                              /* 0x01 */
-    U16             Reserved1;                          /* 0x02 */
-} MPI2_RAID_ACTION_STOP_RAID_FUNCTION,
-  MPI2_POINTER PTR_MPI2_RAID_ACTION_STOP_RAID_FUNCTION,
-  Mpi2RaidActionStopRaidFunction_t,
-  MPI2_POINTER pMpi2RaidActionStopRaidFunction_t;
-
-/* defines for the RAIDFunction field */
-#define MPI2_RAID_ACTION_STOP_BACKGROUND_INIT       (0x00)
-#define MPI2_RAID_ACTION_STOP_ONLINE_CAP_EXPANSION  (0x01)
-#define MPI2_RAID_ACTION_STOP_CONSISTENCY_CHECK     (0x02)
-
-/* defines for the Flags field */
-#define MPI2_RAID_ACTION_STOP_ABORT                 (0x00)
-#define MPI2_RAID_ACTION_STOP_PAUSE                 (0x01)
-
-/* ActionDataWord for MPI2_RAID_ACTION_CREATE_HOT_SPARE Action */
-typedef struct _MPI2_RAID_ACTION_HOT_SPARE
-{
-    U8              HotSparePool;               /* 0x00 */
-    U8              Reserved1;                  /* 0x01 */
-    U16             DevHandle;                  /* 0x02 */
-} MPI2_RAID_ACTION_HOT_SPARE, MPI2_POINTER PTR_MPI2_RAID_ACTION_HOT_SPARE,
-  Mpi2RaidActionHotSpare_t, MPI2_POINTER pMpi2RaidActionHotSpare_t;
-
-/* ActionDataWord for MPI2_RAID_ACTION_DEVICE_FW_UPDATE_MODE Action */
-typedef struct _MPI2_RAID_ACTION_FW_UPDATE_MODE
-{
-    U8              Flags;                              /* 0x00 */
-    U8              DeviceFirmwareUpdateModeTimeout;    /* 0x01 */
-    U16             Reserved1;                          /* 0x02 */
-} MPI2_RAID_ACTION_FW_UPDATE_MODE,
-  MPI2_POINTER PTR_MPI2_RAID_ACTION_FW_UPDATE_MODE,
-  Mpi2RaidActionFwUpdateMode_t, MPI2_POINTER pMpi2RaidActionFwUpdateMode_t;
-
-/* ActionDataWord defines for use with MPI2_RAID_ACTION_DEVICE_FW_UPDATE_MODE action */
-#define MPI2_RAID_ACTION_ADATA_DISABLE_FW_UPDATE        (0x00)
-#define MPI2_RAID_ACTION_ADATA_ENABLE_FW_UPDATE         (0x01)
-
-typedef union _MPI2_RAID_ACTION_DATA
-{
-    U32                                     Word;
-    MPI2_RAID_ACTION_RATE_DATA              Rates;
-    MPI2_RAID_ACTION_START_RAID_FUNCTION    StartRaidFunction;
-    MPI2_RAID_ACTION_STOP_RAID_FUNCTION     StopRaidFunction;
-    MPI2_RAID_ACTION_HOT_SPARE              HotSpare;
-    MPI2_RAID_ACTION_FW_UPDATE_MODE         FwUpdateMode;
-} MPI2_RAID_ACTION_DATA, MPI2_POINTER PTR_MPI2_RAID_ACTION_DATA,
-  Mpi2RaidActionData_t, MPI2_POINTER pMpi2RaidActionData_t;
-
-
-/* RAID Action Request Message */
-typedef struct _MPI2_RAID_ACTION_REQUEST
-{
-    U8                      Action;                         /* 0x00 */
-    U8                      Reserved1;                      /* 0x01 */
-    U8                      ChainOffset;                    /* 0x02 */
-    U8                      Function;                       /* 0x03 */
-    U16                     VolDevHandle;                   /* 0x04 */
-    U8                      PhysDiskNum;                    /* 0x06 */
-    U8                      MsgFlags;                       /* 0x07 */
-    U8                      VP_ID;                          /* 0x08 */
-    U8                      VF_ID;                          /* 0x09 */
-    U16                     Reserved2;                      /* 0x0A */
-    U32                     Reserved3;                      /* 0x0C */
-    MPI2_RAID_ACTION_DATA   ActionDataWord;                 /* 0x10 */
-    MPI2_SGE_SIMPLE_UNION   ActionDataSGE;                  /* 0x14 */
-} MPI2_RAID_ACTION_REQUEST, MPI2_POINTER PTR_MPI2_RAID_ACTION_REQUEST,
-  Mpi2RaidActionRequest_t, MPI2_POINTER pMpi2RaidActionRequest_t;
-
-/* RAID Action request Action values */
-
-#define MPI2_RAID_ACTION_INDICATOR_STRUCT           (0x01)
-#define MPI2_RAID_ACTION_CREATE_VOLUME              (0x02)
-#define MPI2_RAID_ACTION_DELETE_VOLUME              (0x03)
-#define MPI2_RAID_ACTION_DISABLE_ALL_VOLUMES        (0x04)
-#define MPI2_RAID_ACTION_ENABLE_ALL_VOLUMES         (0x05)
-#define MPI2_RAID_ACTION_PHYSDISK_OFFLINE           (0x0A)
-#define MPI2_RAID_ACTION_PHYSDISK_ONLINE            (0x0B)
-#define MPI2_RAID_ACTION_FAIL_PHYSDISK              (0x0F)
-#define MPI2_RAID_ACTION_ACTIVATE_VOLUME            (0x11)
-#define MPI2_RAID_ACTION_DEVICE_FW_UPDATE_MODE      (0x15)
-#define MPI2_RAID_ACTION_CHANGE_VOL_WRITE_CACHE     (0x17)
-#define MPI2_RAID_ACTION_SET_VOLUME_NAME            (0x18)
-#define MPI2_RAID_ACTION_SET_RAID_FUNCTION_RATE     (0x19)
-#define MPI2_RAID_ACTION_ENABLE_FAILED_VOLUME       (0x1C)
-#define MPI2_RAID_ACTION_CREATE_HOT_SPARE           (0x1D)
-#define MPI2_RAID_ACTION_DELETE_HOT_SPARE           (0x1E)
-#define MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED  (0x20)
-#define MPI2_RAID_ACTION_START_RAID_FUNCTION        (0x21)
-#define MPI2_RAID_ACTION_STOP_RAID_FUNCTION         (0x22)
-#define MPI2_RAID_ACTION_COMPATIBILITY_CHECK        (0x23)
-#define MPI2_RAID_ACTION_PHYSDISK_HIDDEN            (0x24)
-#define MPI2_RAID_ACTION_MIN_PRODUCT_SPECIFIC       (0x80)
-#define MPI2_RAID_ACTION_MAX_PRODUCT_SPECIFIC       (0xFF)
-
-/* RAID Volume Creation Structure */
-
-/*
- * The following define can be customized for the targeted product.
- */
-#ifndef MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS
-#define MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS        (1)
-#endif
-
-typedef struct _MPI2_RAID_VOLUME_PHYSDISK
-{
-    U8                      RAIDSetNum;                     /* 0x00 */
-    U8                      PhysDiskMap;                    /* 0x01 */
-    U16                     PhysDiskDevHandle;              /* 0x02 */
-} MPI2_RAID_VOLUME_PHYSDISK, MPI2_POINTER PTR_MPI2_RAID_VOLUME_PHYSDISK,
-  Mpi2RaidVolumePhysDisk_t, MPI2_POINTER pMpi2RaidVolumePhysDisk_t;
-
-/* defines for the PhysDiskMap field */
-#define MPI2_RAIDACTION_PHYSDISK_PRIMARY            (0x01)
-#define MPI2_RAIDACTION_PHYSDISK_SECONDARY          (0x02)
-
-typedef struct _MPI2_RAID_VOLUME_CREATION_STRUCT
-{
-    U8                          NumPhysDisks;               /* 0x00 */
-    U8                          VolumeType;                 /* 0x01 */
-    U16                         Reserved1;                  /* 0x02 */
-    U32                         VolumeCreationFlags;        /* 0x04 */
-    U32                         VolumeSettings;             /* 0x08 */
-    U8                          Reserved2;                  /* 0x0C */
-    U8                          ResyncRate;                 /* 0x0D */
-    U16                         DataScrubDuration;          /* 0x0E */
-    U64                         VolumeMaxLBA;               /* 0x10 */
-    U32                         StripeSize;                 /* 0x18 */
-    U8                          Name[16];                   /* 0x1C */
-    MPI2_RAID_VOLUME_PHYSDISK   PhysDisk[MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS];/* 0x2C */
-} MPI2_RAID_VOLUME_CREATION_STRUCT,
-  MPI2_POINTER PTR_MPI2_RAID_VOLUME_CREATION_STRUCT,
-  Mpi2RaidVolumeCreationStruct_t, MPI2_POINTER pMpi2RaidVolumeCreationStruct_t;
-
-/* use MPI2_RAID_VOL_TYPE_ defines from mpi2_cnfg.h for VolumeType */
-
-/* defines for the VolumeCreationFlags field */
-#define MPI2_RAID_VOL_CREATION_DEFAULT_SETTINGS     (0x80000000)
-#define MPI2_RAID_VOL_CREATION_BACKGROUND_INIT      (0x00000004)
-#define MPI2_RAID_VOL_CREATION_LOW_LEVEL_INIT       (0x00000002)
-#define MPI2_RAID_VOL_CREATION_MIGRATE_DATA         (0x00000001)
-/* The following is an obsolete define.
- * It must be shifted left 24 bits in order to set the proper bit.
- */
-#define MPI2_RAID_VOL_CREATION_USE_DEFAULT_SETTINGS (0x80)
-
-
-/* RAID Online Capacity Expansion Structure */
-
-typedef struct _MPI2_RAID_ONLINE_CAPACITY_EXPANSION
-{
-    U32                     Flags;                          /* 0x00 */
-    U16                     DevHandle0;                     /* 0x04 */
-    U16                     Reserved1;                      /* 0x06 */
-    U16                     DevHandle1;                     /* 0x08 */
-    U16                     Reserved2;                      /* 0x0A */
-} MPI2_RAID_ONLINE_CAPACITY_EXPANSION,
-  MPI2_POINTER PTR_MPI2_RAID_ONLINE_CAPACITY_EXPANSION,
-  Mpi2RaidOnlineCapacityExpansion_t,
-  MPI2_POINTER pMpi2RaidOnlineCapacityExpansion_t;
-
-/* RAID Compatibility Input Structure */
-
-typedef struct _MPI2_RAID_COMPATIBILITY_INPUT_STRUCT {
-       U16                     SourceDevHandle;               /* 0x00 */
-       U16                     CandidateDevHandle;             /* 0x02 */
-       U32                     Flags;                          /* 0x04 */
-       U32                     Reserved1;                      /* 0x08 */
-       U32                     Reserved2;                      /* 0x0C */
-} MPI2_RAID_COMPATIBILITY_INPUT_STRUCT,
-MPI2_POINTER PTR_MPI2_RAID_COMPATIBILITY_INPUT_STRUCT,
-Mpi2RaidCompatibilityInputStruct_t,
-MPI2_POINTER pMpi2RaidCompatibilityInputStruct_t;
-
-/* defines for RAID Compatibility Structure Flags field */
-#define MPI2_RAID_COMPAT_SOURCE_IS_VOLUME_FLAG      (0x00000002)
-#define MPI2_RAID_COMPAT_REPORT_SOURCE_INFO_FLAG    (0x00000001)
-
-
-/* RAID Volume Indicator Structure */
-
-typedef struct _MPI2_RAID_VOL_INDICATOR
-{
-    U64                     TotalBlocks;                    /* 0x00 */
-    U64                     BlocksRemaining;                /* 0x08 */
-    U32                     Flags;                          /* 0x10 */
-       U32                     ElapsedSeconds;                 /* 0x14 */
-} MPI2_RAID_VOL_INDICATOR, MPI2_POINTER PTR_MPI2_RAID_VOL_INDICATOR,
-  Mpi2RaidVolIndicator_t, MPI2_POINTER pMpi2RaidVolIndicator_t;
-
-/* defines for RAID Volume Indicator Flags field */
-#define MPI2_RAID_VOL_FLAGS_ELAPSED_SECONDS_VALID   (0x80000000)
-
-#define MPI2_RAID_VOL_FLAGS_OP_MASK                 (0x0000000F)
-#define MPI2_RAID_VOL_FLAGS_OP_BACKGROUND_INIT      (0x00000000)
-#define MPI2_RAID_VOL_FLAGS_OP_ONLINE_CAP_EXPANSION (0x00000001)
-#define MPI2_RAID_VOL_FLAGS_OP_CONSISTENCY_CHECK    (0x00000002)
-#define MPI2_RAID_VOL_FLAGS_OP_RESYNC               (0x00000003)
-#define MPI2_RAID_VOL_FLAGS_OP_MDC                  (0x00000004)
-
-/* RAID Compatibility Result Structure */
-
-typedef struct _MPI2_RAID_COMPATIBILITY_RESULT_STRUCT {
-       U8                      State;                          /* 0x00 */
-       U8                      Reserved1;                      /* 0x01 */
-       U16                     Reserved2;                      /* 0x02 */
-       U32                     GenericAttributes;              /* 0x04 */
-       U32                     OEMSpecificAttributes;          /* 0x08 */
-       U32                     Reserved3;                      /* 0x0C */
-       U32                     Reserved4;                      /* 0x10 */
-} MPI2_RAID_COMPATIBILITY_RESULT_STRUCT,
-MPI2_POINTER PTR_MPI2_RAID_COMPATIBILITY_RESULT_STRUCT,
-Mpi2RaidCompatibilityResultStruct_t,
-MPI2_POINTER pMpi2RaidCompatibilityResultStruct_t;
-
-/* defines for RAID Compatibility Result Structure State field */
-#define MPI2_RAID_COMPAT_STATE_COMPATIBLE           (0x00)
-#define MPI2_RAID_COMPAT_STATE_NOT_COMPATIBLE       (0x01)
-
-/* defines for RAID Compatibility Result Structure GenericAttributes field */
-#define MPI2_RAID_COMPAT_GENATTRIB_4K_SECTOR            (0x00000010)
-
-#define MPI2_RAID_COMPAT_GENATTRIB_MEDIA_MASK           (0x0000000C)
-#define MPI2_RAID_COMPAT_GENATTRIB_SOLID_STATE_DRIVE    (0x00000008)
-#define MPI2_RAID_COMPAT_GENATTRIB_HARD_DISK_DRIVE      (0x00000004)
-
-#define MPI2_RAID_COMPAT_GENATTRIB_PROTOCOL_MASK        (0x00000003)
-#define MPI2_RAID_COMPAT_GENATTRIB_SAS_PROTOCOL         (0x00000002)
-#define MPI2_RAID_COMPAT_GENATTRIB_SATA_PROTOCOL        (0x00000001)
-
-/* RAID Action Reply ActionData union */
-typedef union _MPI2_RAID_ACTION_REPLY_DATA
-{
-       U32                                     Word[6];
-       MPI2_RAID_VOL_INDICATOR                 RaidVolumeIndicator;
-       U16                                     VolDevHandle;
-       U8                                      VolumeState;
-       U8                                      PhysDiskNum;
-       MPI2_RAID_COMPATIBILITY_RESULT_STRUCT   RaidCompatibilityResult;
-} MPI2_RAID_ACTION_REPLY_DATA, MPI2_POINTER PTR_MPI2_RAID_ACTION_REPLY_DATA,
-  Mpi2RaidActionReplyData_t, MPI2_POINTER pMpi2RaidActionReplyData_t;
-
-/* use MPI2_RAIDVOL0_SETTING_ defines from mpi2_cnfg.h for MPI2_RAID_ACTION_CHANGE_VOL_WRITE_CACHE action */
-
-
-/* RAID Action Reply Message */
-typedef struct _MPI2_RAID_ACTION_REPLY
-{
-    U8                          Action;                     /* 0x00 */
-    U8                          Reserved1;                  /* 0x01 */
-    U8                          MsgLength;                  /* 0x02 */
-    U8                          Function;                   /* 0x03 */
-    U16                         VolDevHandle;               /* 0x04 */
-    U8                          PhysDiskNum;                /* 0x06 */
-    U8                          MsgFlags;                   /* 0x07 */
-    U8                          VP_ID;                      /* 0x08 */
-    U8                          VF_ID;                      /* 0x09 */
-    U16                         Reserved2;                  /* 0x0A */
-    U16                         Reserved3;                  /* 0x0C */
-    U16                         IOCStatus;                  /* 0x0E */
-    U32                         IOCLogInfo;                 /* 0x10 */
-    MPI2_RAID_ACTION_REPLY_DATA ActionData;                 /* 0x14 */
-} MPI2_RAID_ACTION_REPLY, MPI2_POINTER PTR_MPI2_RAID_ACTION_REPLY,
-  Mpi2RaidActionReply_t, MPI2_POINTER pMpi2RaidActionReply_t;
-
-
-#endif
-
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_sas.h b/drivers/scsi/mpt2sas/mpi/mpi2_sas.h
deleted file mode 100644 (file)
index 45b6fa1..0000000
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- *  Copyright (c) 2000-2014 LSI Corporation.
- *
- *
- *           Name:  mpi2_sas.h
- *          Title:  MPI Serial Attached SCSI structures and definitions
- *  Creation Date:  February 9, 2007
- *
- *  mpi2_sas.h Version:  02.00.05
- *
- *  Version History
- *  ---------------
- *
- *  Date      Version   Description
- *  --------  --------  ------------------------------------------------------
- *  04-30-07  02.00.00  Corresponds to Fusion-MPT MPI Specification Rev A.
- *  06-26-07  02.00.01  Added Clear All Persistent Operation to SAS IO Unit
- *                      Control Request.
- *  10-02-08  02.00.02  Added Set IOC Parameter Operation to SAS IO Unit Control
- *                      Request.
- *  10-28-09  02.00.03  Changed the type of SGL in MPI2_SATA_PASSTHROUGH_REQUEST
- *                      to MPI2_SGE_IO_UNION since it supports chained SGLs.
- *  05-12-10  02.00.04  Modified some comments.
- *  08-11-10  02.00.05  Added NCQ operations to SAS IO Unit Control.
- *  --------------------------------------------------------------------------
- */
-
-#ifndef MPI2_SAS_H
-#define MPI2_SAS_H
-
-/*
- * Values for SASStatus.
- */
-#define MPI2_SASSTATUS_SUCCESS                          (0x00)
-#define MPI2_SASSTATUS_UNKNOWN_ERROR                    (0x01)
-#define MPI2_SASSTATUS_INVALID_FRAME                    (0x02)
-#define MPI2_SASSTATUS_UTC_BAD_DEST                     (0x03)
-#define MPI2_SASSTATUS_UTC_BREAK_RECEIVED               (0x04)
-#define MPI2_SASSTATUS_UTC_CONNECT_RATE_NOT_SUPPORTED   (0x05)
-#define MPI2_SASSTATUS_UTC_PORT_LAYER_REQUEST           (0x06)
-#define MPI2_SASSTATUS_UTC_PROTOCOL_NOT_SUPPORTED       (0x07)
-#define MPI2_SASSTATUS_UTC_STP_RESOURCES_BUSY           (0x08)
-#define MPI2_SASSTATUS_UTC_WRONG_DESTINATION            (0x09)
-#define MPI2_SASSTATUS_SHORT_INFORMATION_UNIT           (0x0A)
-#define MPI2_SASSTATUS_LONG_INFORMATION_UNIT            (0x0B)
-#define MPI2_SASSTATUS_XFER_RDY_INCORRECT_WRITE_DATA    (0x0C)
-#define MPI2_SASSTATUS_XFER_RDY_REQUEST_OFFSET_ERROR    (0x0D)
-#define MPI2_SASSTATUS_XFER_RDY_NOT_EXPECTED            (0x0E)
-#define MPI2_SASSTATUS_DATA_INCORRECT_DATA_LENGTH       (0x0F)
-#define MPI2_SASSTATUS_DATA_TOO_MUCH_READ_DATA          (0x10)
-#define MPI2_SASSTATUS_DATA_OFFSET_ERROR                (0x11)
-#define MPI2_SASSTATUS_SDSF_NAK_RECEIVED                (0x12)
-#define MPI2_SASSTATUS_SDSF_CONNECTION_FAILED           (0x13)
-#define MPI2_SASSTATUS_INITIATOR_RESPONSE_TIMEOUT       (0x14)
-
-
-/*
- * Values for the SAS DeviceInfo field used in SAS Device Status Change Event
- * data and SAS Configuration pages.
- */
-#define MPI2_SAS_DEVICE_INFO_SEP                (0x00004000)
-#define MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE       (0x00002000)
-#define MPI2_SAS_DEVICE_INFO_LSI_DEVICE         (0x00001000)
-#define MPI2_SAS_DEVICE_INFO_DIRECT_ATTACH      (0x00000800)
-#define MPI2_SAS_DEVICE_INFO_SSP_TARGET         (0x00000400)
-#define MPI2_SAS_DEVICE_INFO_STP_TARGET         (0x00000200)
-#define MPI2_SAS_DEVICE_INFO_SMP_TARGET         (0x00000100)
-#define MPI2_SAS_DEVICE_INFO_SATA_DEVICE        (0x00000080)
-#define MPI2_SAS_DEVICE_INFO_SSP_INITIATOR      (0x00000040)
-#define MPI2_SAS_DEVICE_INFO_STP_INITIATOR      (0x00000020)
-#define MPI2_SAS_DEVICE_INFO_SMP_INITIATOR      (0x00000010)
-#define MPI2_SAS_DEVICE_INFO_SATA_HOST          (0x00000008)
-
-#define MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE   (0x00000007)
-#define MPI2_SAS_DEVICE_INFO_NO_DEVICE          (0x00000000)
-#define MPI2_SAS_DEVICE_INFO_END_DEVICE         (0x00000001)
-#define MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER      (0x00000002)
-#define MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER    (0x00000003)
-
-
-/*****************************************************************************
-*
-*        SAS Messages
-*
-*****************************************************************************/
-
-/****************************************************************************
-*  SMP Passthrough messages
-****************************************************************************/
-
-/* SMP Passthrough Request Message */
-typedef struct _MPI2_SMP_PASSTHROUGH_REQUEST
-{
-    U8                      PassthroughFlags;   /* 0x00 */
-    U8                      PhysicalPort;       /* 0x01 */
-    U8                      ChainOffset;        /* 0x02 */
-    U8                      Function;           /* 0x03 */
-    U16                     RequestDataLength;  /* 0x04 */
-    U8                      SGLFlags;           /* 0x06 */
-    U8                      MsgFlags;           /* 0x07 */
-    U8                      VP_ID;              /* 0x08 */
-    U8                      VF_ID;              /* 0x09 */
-    U16                     Reserved1;          /* 0x0A */
-    U32                     Reserved2;          /* 0x0C */
-    U64                     SASAddress;         /* 0x10 */
-    U32                     Reserved3;          /* 0x18 */
-    U32                     Reserved4;          /* 0x1C */
-    MPI2_SIMPLE_SGE_UNION   SGL;                /* 0x20 */
-} MPI2_SMP_PASSTHROUGH_REQUEST, MPI2_POINTER PTR_MPI2_SMP_PASSTHROUGH_REQUEST,
-  Mpi2SmpPassthroughRequest_t, MPI2_POINTER pMpi2SmpPassthroughRequest_t;
-
-/* values for PassthroughFlags field */
-#define MPI2_SMP_PT_REQ_PT_FLAGS_IMMEDIATE      (0x80)
-
-/* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */
-
-
-/* SMP Passthrough Reply Message */
-typedef struct _MPI2_SMP_PASSTHROUGH_REPLY
-{
-    U8                      PassthroughFlags;   /* 0x00 */
-    U8                      PhysicalPort;       /* 0x01 */
-    U8                      MsgLength;          /* 0x02 */
-    U8                      Function;           /* 0x03 */
-    U16                     ResponseDataLength; /* 0x04 */
-    U8                      SGLFlags;           /* 0x06 */
-    U8                      MsgFlags;           /* 0x07 */
-    U8                      VP_ID;              /* 0x08 */
-    U8                      VF_ID;              /* 0x09 */
-    U16                     Reserved1;          /* 0x0A */
-    U8                      Reserved2;          /* 0x0C */
-    U8                      SASStatus;          /* 0x0D */
-    U16                     IOCStatus;          /* 0x0E */
-    U32                     IOCLogInfo;         /* 0x10 */
-    U32                     Reserved3;          /* 0x14 */
-    U8                      ResponseData[4];    /* 0x18 */
-} MPI2_SMP_PASSTHROUGH_REPLY, MPI2_POINTER PTR_MPI2_SMP_PASSTHROUGH_REPLY,
-  Mpi2SmpPassthroughReply_t, MPI2_POINTER pMpi2SmpPassthroughReply_t;
-
-/* values for PassthroughFlags field */
-#define MPI2_SMP_PT_REPLY_PT_FLAGS_IMMEDIATE    (0x80)
-
-/* values for SASStatus field are at the top of this file */
-
-
-/****************************************************************************
-*  SATA Passthrough messages
-****************************************************************************/
-
-/* SATA Passthrough Request Message */
-typedef struct _MPI2_SATA_PASSTHROUGH_REQUEST
-{
-    U16                     DevHandle;          /* 0x00 */
-    U8                      ChainOffset;        /* 0x02 */
-    U8                      Function;           /* 0x03 */
-    U16                     PassthroughFlags;   /* 0x04 */
-    U8                      SGLFlags;           /* 0x06 */
-    U8                      MsgFlags;           /* 0x07 */
-    U8                      VP_ID;              /* 0x08 */
-    U8                      VF_ID;              /* 0x09 */
-    U16                     Reserved1;          /* 0x0A */
-    U32                     Reserved2;          /* 0x0C */
-    U32                     Reserved3;          /* 0x10 */
-    U32                     Reserved4;          /* 0x14 */
-    U32                     DataLength;         /* 0x18 */
-    U8                      CommandFIS[20];     /* 0x1C */
-    MPI2_SGE_IO_UNION       SGL;                /* 0x30 */
-} MPI2_SATA_PASSTHROUGH_REQUEST, MPI2_POINTER PTR_MPI2_SATA_PASSTHROUGH_REQUEST,
-  Mpi2SataPassthroughRequest_t, MPI2_POINTER pMpi2SataPassthroughRequest_t;
-
-/* values for PassthroughFlags field */
-#define MPI2_SATA_PT_REQ_PT_FLAGS_EXECUTE_DIAG      (0x0100)
-#define MPI2_SATA_PT_REQ_PT_FLAGS_DMA               (0x0020)
-#define MPI2_SATA_PT_REQ_PT_FLAGS_PIO               (0x0010)
-#define MPI2_SATA_PT_REQ_PT_FLAGS_UNSPECIFIED_VU    (0x0004)
-#define MPI2_SATA_PT_REQ_PT_FLAGS_WRITE             (0x0002)
-#define MPI2_SATA_PT_REQ_PT_FLAGS_READ              (0x0001)
-
-/* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */
-
-
-/* SATA Passthrough Reply Message */
-typedef struct _MPI2_SATA_PASSTHROUGH_REPLY
-{
-    U16                     DevHandle;          /* 0x00 */
-    U8                      MsgLength;          /* 0x02 */
-    U8                      Function;           /* 0x03 */
-    U16                     PassthroughFlags;   /* 0x04 */
-    U8                      SGLFlags;           /* 0x06 */
-    U8                      MsgFlags;           /* 0x07 */
-    U8                      VP_ID;              /* 0x08 */
-    U8                      VF_ID;              /* 0x09 */
-    U16                     Reserved1;          /* 0x0A */
-    U8                      Reserved2;          /* 0x0C */
-    U8                      SASStatus;          /* 0x0D */
-    U16                     IOCStatus;          /* 0x0E */
-    U32                     IOCLogInfo;         /* 0x10 */
-    U8                      StatusFIS[20];      /* 0x14 */
-    U32                     StatusControlRegisters; /* 0x28 */
-    U32                     TransferCount;      /* 0x2C */
-} MPI2_SATA_PASSTHROUGH_REPLY, MPI2_POINTER PTR_MPI2_SATA_PASSTHROUGH_REPLY,
-  Mpi2SataPassthroughReply_t, MPI2_POINTER pMpi2SataPassthroughReply_t;
-
-/* values for SASStatus field are at the top of this file */
-
-
-/****************************************************************************
-*  SAS IO Unit Control messages
-****************************************************************************/
-
-/* SAS IO Unit Control Request Message */
-typedef struct _MPI2_SAS_IOUNIT_CONTROL_REQUEST
-{
-    U8                      Operation;          /* 0x00 */
-    U8                      Reserved1;          /* 0x01 */
-    U8                      ChainOffset;        /* 0x02 */
-    U8                      Function;           /* 0x03 */
-    U16                     DevHandle;          /* 0x04 */
-    U8                      IOCParameter;       /* 0x06 */
-    U8                      MsgFlags;           /* 0x07 */
-    U8                      VP_ID;              /* 0x08 */
-    U8                      VF_ID;              /* 0x09 */
-    U16                     Reserved3;          /* 0x0A */
-    U16                     Reserved4;          /* 0x0C */
-    U8                      PhyNum;             /* 0x0E */
-    U8                      PrimFlags;          /* 0x0F */
-    U32                     Primitive;          /* 0x10 */
-    U8                      LookupMethod;       /* 0x14 */
-    U8                      Reserved5;          /* 0x15 */
-    U16                     SlotNumber;         /* 0x16 */
-    U64                     LookupAddress;      /* 0x18 */
-    U32                     IOCParameterValue;  /* 0x20 */
-    U32                     Reserved7;          /* 0x24 */
-    U32                     Reserved8;          /* 0x28 */
-} MPI2_SAS_IOUNIT_CONTROL_REQUEST,
-  MPI2_POINTER PTR_MPI2_SAS_IOUNIT_CONTROL_REQUEST,
-  Mpi2SasIoUnitControlRequest_t, MPI2_POINTER pMpi2SasIoUnitControlRequest_t;
-
-/* values for the Operation field */
-#define MPI2_SAS_OP_CLEAR_ALL_PERSISTENT        (0x02)
-#define MPI2_SAS_OP_PHY_LINK_RESET              (0x06)
-#define MPI2_SAS_OP_PHY_HARD_RESET              (0x07)
-#define MPI2_SAS_OP_PHY_CLEAR_ERROR_LOG         (0x08)
-#define MPI2_SAS_OP_SEND_PRIMITIVE              (0x0A)
-#define MPI2_SAS_OP_FORCE_FULL_DISCOVERY        (0x0B)
-#define MPI2_SAS_OP_TRANSMIT_PORT_SELECT_SIGNAL (0x0C)
-#define MPI2_SAS_OP_REMOVE_DEVICE               (0x0D)
-#define MPI2_SAS_OP_LOOKUP_MAPPING              (0x0E)
-#define MPI2_SAS_OP_SET_IOC_PARAMETER           (0x0F)
-#define MPI2_SAS_OP_DEV_ENABLE_NCQ              (0x14)
-#define MPI2_SAS_OP_DEV_DISABLE_NCQ             (0x15)
-#define MPI2_SAS_OP_PRODUCT_SPECIFIC_MIN        (0x80)
-
-/* values for the PrimFlags field */
-#define MPI2_SAS_PRIMFLAGS_SINGLE               (0x08)
-#define MPI2_SAS_PRIMFLAGS_TRIPLE               (0x02)
-#define MPI2_SAS_PRIMFLAGS_REDUNDANT            (0x01)
-
-/* values for the LookupMethod field */
-#define MPI2_SAS_LOOKUP_METHOD_SAS_ADDRESS          (0x01)
-#define MPI2_SAS_LOOKUP_METHOD_SAS_ENCLOSURE_SLOT   (0x02)
-#define MPI2_SAS_LOOKUP_METHOD_SAS_DEVICE_NAME      (0x03)
-
-
-/* SAS IO Unit Control Reply Message */
-typedef struct _MPI2_SAS_IOUNIT_CONTROL_REPLY
-{
-    U8                      Operation;          /* 0x00 */
-    U8                      Reserved1;          /* 0x01 */
-    U8                      MsgLength;          /* 0x02 */
-    U8                      Function;           /* 0x03 */
-    U16                     DevHandle;          /* 0x04 */
-    U8                      IOCParameter;       /* 0x06 */
-    U8                      MsgFlags;           /* 0x07 */
-    U8                      VP_ID;              /* 0x08 */
-    U8                      VF_ID;              /* 0x09 */
-    U16                     Reserved3;          /* 0x0A */
-    U16                     Reserved4;          /* 0x0C */
-    U16                     IOCStatus;          /* 0x0E */
-    U32                     IOCLogInfo;         /* 0x10 */
-} MPI2_SAS_IOUNIT_CONTROL_REPLY,
-  MPI2_POINTER PTR_MPI2_SAS_IOUNIT_CONTROL_REPLY,
-  Mpi2SasIoUnitControlReply_t, MPI2_POINTER pMpi2SasIoUnitControlReply_t;
-
-
-#endif
-
-
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_tool.h b/drivers/scsi/mpt2sas/mpi/mpi2_tool.h
deleted file mode 100644 (file)
index 659b8ac..0000000
+++ /dev/null
@@ -1,481 +0,0 @@
-/*
- *  Copyright (c) 2000-2014 LSI Corporation.
- *
- *
- *           Name:  mpi2_tool.h
- *          Title:  MPI diagnostic tool structures and definitions
- *  Creation Date:  March 26, 2007
- *
- *    mpi2_tool.h Version:  02.00.12
- *
- *  Version History
- *  ---------------
- *
- *  Date      Version   Description
- *  --------  --------  ------------------------------------------------------
- *  04-30-07  02.00.00  Corresponds to Fusion-MPT MPI Specification Rev A.
- *  12-18-07  02.00.01  Added Diagnostic Buffer Post and Diagnostic Release
- *                      structures and defines.
- *  02-29-08  02.00.02  Modified various names to make them 32-character unique.
- *  05-06-09  02.00.03  Added ISTWI Read Write Tool and Diagnostic CLI Tool.
- *  07-30-09  02.00.04  Added ExtendedType field to DiagnosticBufferPost request
- *                      and reply messages.
- *                      Added MPI2_DIAG_BUF_TYPE_EXTENDED.
- *                      Incremented MPI2_DIAG_BUF_TYPE_COUNT.
- *  05-12-10  02.00.05  Added Diagnostic Data Upload tool.
- *  08-11-10  02.00.06  Added defines that were missing for Diagnostic Buffer
- *                      Post Request.
- *  05-25-11  02.00.07  Added Flags field and related defines to
- *                      MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST.
- *  07-26-12  02.00.10  Modified MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST so that
- *                     it uses MPI Chain SGE as well as MPI Simple SGE.
- *  08-19-13  02.00.11  Added MPI2_TOOLBOX_TEXT_DISPLAY_TOOL and related info.
- *  01-08-14  02.00.12  Added MPI2_TOOLBOX_CLEAN_BIT26_PRODUCT_SPECIFIC.
- *  --------------------------------------------------------------------------
- */
-
-#ifndef MPI2_TOOL_H
-#define MPI2_TOOL_H
-
-/*****************************************************************************
-*
-*               Toolbox Messages
-*
-*****************************************************************************/
-
-/* defines for the Tools */
-#define MPI2_TOOLBOX_CLEAN_TOOL                     (0x00)
-#define MPI2_TOOLBOX_MEMORY_MOVE_TOOL               (0x01)
-#define MPI2_TOOLBOX_DIAG_DATA_UPLOAD_TOOL          (0x02)
-#define MPI2_TOOLBOX_ISTWI_READ_WRITE_TOOL          (0x03)
-#define MPI2_TOOLBOX_BEACON_TOOL                    (0x05)
-#define MPI2_TOOLBOX_DIAGNOSTIC_CLI_TOOL            (0x06)
-#define MPI2_TOOLBOX_TEXT_DISPLAY_TOOL              (0x07)
-
-
-/****************************************************************************
-*  Toolbox reply
-****************************************************************************/
-
-typedef struct _MPI2_TOOLBOX_REPLY
-{
-    U8                      Tool;                       /* 0x00 */
-    U8                      Reserved1;                  /* 0x01 */
-    U8                      MsgLength;                  /* 0x02 */
-    U8                      Function;                   /* 0x03 */
-    U16                     Reserved2;                  /* 0x04 */
-    U8                      Reserved3;                  /* 0x06 */
-    U8                      MsgFlags;                   /* 0x07 */
-    U8                      VP_ID;                      /* 0x08 */
-    U8                      VF_ID;                      /* 0x09 */
-    U16                     Reserved4;                  /* 0x0A */
-    U16                     Reserved5;                  /* 0x0C */
-    U16                     IOCStatus;                  /* 0x0E */
-    U32                     IOCLogInfo;                 /* 0x10 */
-} MPI2_TOOLBOX_REPLY, MPI2_POINTER PTR_MPI2_TOOLBOX_REPLY,
-  Mpi2ToolboxReply_t, MPI2_POINTER pMpi2ToolboxReply_t;
-
-
-/****************************************************************************
-*  Toolbox Clean Tool request
-****************************************************************************/
-
-typedef struct _MPI2_TOOLBOX_CLEAN_REQUEST
-{
-    U8                      Tool;                       /* 0x00 */
-    U8                      Reserved1;                  /* 0x01 */
-    U8                      ChainOffset;                /* 0x02 */
-    U8                      Function;                   /* 0x03 */
-    U16                     Reserved2;                  /* 0x04 */
-    U8                      Reserved3;                  /* 0x06 */
-    U8                      MsgFlags;                   /* 0x07 */
-    U8                      VP_ID;                      /* 0x08 */
-    U8                      VF_ID;                      /* 0x09 */
-    U16                     Reserved4;                  /* 0x0A */
-    U32                     Flags;                      /* 0x0C */
-   } MPI2_TOOLBOX_CLEAN_REQUEST, MPI2_POINTER PTR_MPI2_TOOLBOX_CLEAN_REQUEST,
-  Mpi2ToolboxCleanRequest_t, MPI2_POINTER pMpi2ToolboxCleanRequest_t;
-
-/* values for the Flags field */
-#define MPI2_TOOLBOX_CLEAN_BOOT_SERVICES            (0x80000000)
-#define MPI2_TOOLBOX_CLEAN_PERSIST_MANUFACT_PAGES   (0x40000000)
-#define MPI2_TOOLBOX_CLEAN_OTHER_PERSIST_PAGES      (0x20000000)
-#define MPI2_TOOLBOX_CLEAN_FW_CURRENT               (0x10000000)
-#define MPI2_TOOLBOX_CLEAN_FW_BACKUP                (0x08000000)
-#define MPI2_TOOLBOX_CLEAN_BIT26_PRODUCT_SPECIFIC   (0x04000000)
-#define MPI2_TOOLBOX_CLEAN_MEGARAID                 (0x02000000)
-#define MPI2_TOOLBOX_CLEAN_INITIALIZATION           (0x01000000)
-#define MPI2_TOOLBOX_CLEAN_FLASH                    (0x00000004)
-#define MPI2_TOOLBOX_CLEAN_SEEPROM                  (0x00000002)
-#define MPI2_TOOLBOX_CLEAN_NVSRAM                   (0x00000001)
-
-
-/****************************************************************************
-*  Toolbox Memory Move request
-****************************************************************************/
-
-typedef struct _MPI2_TOOLBOX_MEM_MOVE_REQUEST {
-    U8                      Tool;                       /* 0x00 */
-    U8                      Reserved1;                  /* 0x01 */
-    U8                      ChainOffset;                /* 0x02 */
-    U8                      Function;                   /* 0x03 */
-    U16                     Reserved2;                  /* 0x04 */
-    U8                      Reserved3;                  /* 0x06 */
-    U8                      MsgFlags;                   /* 0x07 */
-    U8                      VP_ID;                      /* 0x08 */
-    U8                      VF_ID;                      /* 0x09 */
-    U16                     Reserved4;                  /* 0x0A */
-    MPI2_SGE_SIMPLE_UNION   SGL;                        /* 0x0C */
-} MPI2_TOOLBOX_MEM_MOVE_REQUEST, MPI2_POINTER PTR_MPI2_TOOLBOX_MEM_MOVE_REQUEST,
-  Mpi2ToolboxMemMoveRequest_t, MPI2_POINTER pMpi2ToolboxMemMoveRequest_t;
-
-
-/****************************************************************************
-*  Toolbox Diagnostic Data Upload request
-****************************************************************************/
-
-typedef struct _MPI2_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST {
-       U8                      Tool;                       /* 0x00 */
-       U8                      Reserved1;                  /* 0x01 */
-       U8                      ChainOffset;                /* 0x02 */
-       U8                      Function;                   /* 0x03 */
-       U16                     Reserved2;                  /* 0x04 */
-       U8                      Reserved3;                  /* 0x06 */
-       U8                      MsgFlags;                   /* 0x07 */
-       U8                      VP_ID;                      /* 0x08 */
-       U8                      VF_ID;                      /* 0x09 */
-       U16                     Reserved4;                  /* 0x0A */
-       U8                      SGLFlags;                   /* 0x0C */
-       U8                      Reserved5;                  /* 0x0D */
-       U16                     Reserved6;                  /* 0x0E */
-       U32                     Flags;                      /* 0x10 */
-       U32                     DataLength;                 /* 0x14 */
-       MPI2_SGE_SIMPLE_UNION   SGL;                        /* 0x18 */
-} MPI2_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST,
-MPI2_POINTER PTR_MPI2_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST,
-Mpi2ToolboxDiagDataUploadRequest_t,
-MPI2_POINTER pMpi2ToolboxDiagDataUploadRequest_t;
-
-/* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */
-
-
-typedef struct _MPI2_DIAG_DATA_UPLOAD_HEADER {
-       U32                     DiagDataLength;             /* 00h */
-       U8                      FormatCode;                 /* 04h */
-       U8                      Reserved1;                  /* 05h */
-       U16                     Reserved2;                  /* 06h */
-} MPI2_DIAG_DATA_UPLOAD_HEADER, MPI2_POINTER PTR_MPI2_DIAG_DATA_UPLOAD_HEADER,
-Mpi2DiagDataUploadHeader_t, MPI2_POINTER pMpi2DiagDataUploadHeader_t;
-
-
-/****************************************************************************
-*  Toolbox ISTWI Read Write Tool
-****************************************************************************/
-
-/* Toolbox ISTWI Read Write Tool request message */
-typedef struct _MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST {
-    U8                      Tool;                       /* 0x00 */
-    U8                      Reserved1;                  /* 0x01 */
-    U8                      ChainOffset;                /* 0x02 */
-    U8                      Function;                   /* 0x03 */
-    U16                     Reserved2;                  /* 0x04 */
-    U8                      Reserved3;                  /* 0x06 */
-    U8                      MsgFlags;                   /* 0x07 */
-    U8                      VP_ID;                      /* 0x08 */
-    U8                      VF_ID;                      /* 0x09 */
-    U16                     Reserved4;                  /* 0x0A */
-    U32                     Reserved5;                  /* 0x0C */
-    U32                     Reserved6;                  /* 0x10 */
-    U8                      DevIndex;                   /* 0x14 */
-    U8                      Action;                     /* 0x15 */
-    U8                      SGLFlags;                   /* 0x16 */
-        U8                      Flags;                      /* 0x17 */
-    U16                     TxDataLength;               /* 0x18 */
-    U16                     RxDataLength;               /* 0x1A */
-    U32                     Reserved8;                  /* 0x1C */
-    U32                     Reserved9;                  /* 0x20 */
-    U32                     Reserved10;                 /* 0x24 */
-    U32                     Reserved11;                 /* 0x28 */
-    U32                     Reserved12;                 /* 0x2C */
-    MPI2_SGE_SIMPLE_UNION   SGL;                        /* 0x30 */
-} MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST,
-  MPI2_POINTER PTR_MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST,
-  Mpi2ToolboxIstwiReadWriteRequest_t,
-  MPI2_POINTER pMpi2ToolboxIstwiReadWriteRequest_t;
-
-/* values for the Action field */
-#define MPI2_TOOL_ISTWI_ACTION_READ_DATA            (0x01)
-#define MPI2_TOOL_ISTWI_ACTION_WRITE_DATA           (0x02)
-#define MPI2_TOOL_ISTWI_ACTION_SEQUENCE             (0x03)
-#define MPI2_TOOL_ISTWI_ACTION_RESERVE_BUS          (0x10)
-#define MPI2_TOOL_ISTWI_ACTION_RELEASE_BUS          (0x11)
-#define MPI2_TOOL_ISTWI_ACTION_RESET                (0x12)
-
-/* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */
-
-/* values for the Flags field */
-#define MPI2_TOOL_ISTWI_FLAG_AUTO_RESERVE_RELEASE   (0x80)
-#define MPI2_TOOL_ISTWI_FLAG_PAGE_ADDR_MASK         (0x07)
-
-/* Toolbox ISTWI Read Write Tool reply message */
-typedef struct _MPI2_TOOLBOX_ISTWI_REPLY {
-    U8                      Tool;                       /* 0x00 */
-    U8                      Reserved1;                  /* 0x01 */
-    U8                      MsgLength;                  /* 0x02 */
-    U8                      Function;                   /* 0x03 */
-    U16                     Reserved2;                  /* 0x04 */
-    U8                      Reserved3;                  /* 0x06 */
-    U8                      MsgFlags;                   /* 0x07 */
-    U8                      VP_ID;                      /* 0x08 */
-    U8                      VF_ID;                      /* 0x09 */
-    U16                     Reserved4;                  /* 0x0A */
-    U16                     Reserved5;                  /* 0x0C */
-    U16                     IOCStatus;                  /* 0x0E */
-    U32                     IOCLogInfo;                 /* 0x10 */
-    U8                      DevIndex;                   /* 0x14 */
-    U8                      Action;                     /* 0x15 */
-    U8                      IstwiStatus;                /* 0x16 */
-    U8                      Reserved6;                  /* 0x17 */
-    U16                     TxDataCount;                /* 0x18 */
-    U16                     RxDataCount;                /* 0x1A */
-} MPI2_TOOLBOX_ISTWI_REPLY, MPI2_POINTER PTR_MPI2_TOOLBOX_ISTWI_REPLY,
-  Mpi2ToolboxIstwiReply_t, MPI2_POINTER pMpi2ToolboxIstwiReply_t;
-
-
-/****************************************************************************
-*  Toolbox Beacon Tool request
-****************************************************************************/
-
-typedef struct _MPI2_TOOLBOX_BEACON_REQUEST
-{
-    U8                      Tool;                       /* 0x00 */
-    U8                      Reserved1;                  /* 0x01 */
-    U8                      ChainOffset;                /* 0x02 */
-    U8                      Function;                   /* 0x03 */
-    U16                     Reserved2;                  /* 0x04 */
-    U8                      Reserved3;                  /* 0x06 */
-    U8                      MsgFlags;                   /* 0x07 */
-    U8                      VP_ID;                      /* 0x08 */
-    U8                      VF_ID;                      /* 0x09 */
-    U16                     Reserved4;                  /* 0x0A */
-    U8                      Reserved5;                  /* 0x0C */
-    U8                      PhysicalPort;               /* 0x0D */
-    U8                      Reserved6;                  /* 0x0E */
-    U8                      Flags;                      /* 0x0F */
-} MPI2_TOOLBOX_BEACON_REQUEST, MPI2_POINTER PTR_MPI2_TOOLBOX_BEACON_REQUEST,
-  Mpi2ToolboxBeaconRequest_t, MPI2_POINTER pMpi2ToolboxBeaconRequest_t;
-
-/* values for the Flags field */
-#define MPI2_TOOLBOX_FLAGS_BEACONMODE_OFF       (0x00)
-#define MPI2_TOOLBOX_FLAGS_BEACONMODE_ON        (0x01)
-
-
-/****************************************************************************
-*  Toolbox Diagnostic CLI Tool
-****************************************************************************/
-
-#define MPI2_TOOLBOX_DIAG_CLI_CMD_LENGTH    (0x5C)
-
-/* MPI v2.0 Toolbox Diagnostic CLI Tool request message */
-typedef struct _MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST {
-    U8                      Tool;                       /* 0x00 */
-    U8                      Reserved1;                  /* 0x01 */
-    U8                      ChainOffset;                /* 0x02 */
-    U8                      Function;                   /* 0x03 */
-    U16                     Reserved2;                  /* 0x04 */
-    U8                      Reserved3;                  /* 0x06 */
-    U8                      MsgFlags;                   /* 0x07 */
-    U8                      VP_ID;                      /* 0x08 */
-    U8                      VF_ID;                      /* 0x09 */
-    U16                     Reserved4;                  /* 0x0A */
-    U8                      SGLFlags;                   /* 0x0C */
-    U8                      Reserved5;                  /* 0x0D */
-    U16                     Reserved6;                  /* 0x0E */
-    U32                     DataLength;                 /* 0x10 */
-    U8                      DiagnosticCliCommand
-               [MPI2_TOOLBOX_DIAG_CLI_CMD_LENGTH];     /* 0x14 */
-       MPI2_MPI_SGE_IO_UNION   SGL;                        /* 0x70 */
-} MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST,
-  MPI2_POINTER PTR_MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST,
-  Mpi2ToolboxDiagnosticCliRequest_t,
-  MPI2_POINTER pMpi2ToolboxDiagnosticCliRequest_t;
-
-/* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */
-
-
-/* Toolbox Diagnostic CLI Tool reply message */
-typedef struct _MPI2_TOOLBOX_DIAGNOSTIC_CLI_REPLY {
-    U8                      Tool;                       /* 0x00 */
-    U8                      Reserved1;                  /* 0x01 */
-    U8                      MsgLength;                  /* 0x02 */
-    U8                      Function;                   /* 0x03 */
-    U16                     Reserved2;                  /* 0x04 */
-    U8                      Reserved3;                  /* 0x06 */
-    U8                      MsgFlags;                   /* 0x07 */
-    U8                      VP_ID;                      /* 0x08 */
-    U8                      VF_ID;                      /* 0x09 */
-    U16                     Reserved4;                  /* 0x0A */
-    U16                     Reserved5;                  /* 0x0C */
-    U16                     IOCStatus;                  /* 0x0E */
-    U32                     IOCLogInfo;                 /* 0x10 */
-    U32                     ReturnedDataLength;         /* 0x14 */
-} MPI2_TOOLBOX_DIAGNOSTIC_CLI_REPLY,
-  MPI2_POINTER PTR_MPI2_TOOLBOX_DIAG_CLI_REPLY,
-  Mpi2ToolboxDiagnosticCliReply_t,
-  MPI2_POINTER pMpi2ToolboxDiagnosticCliReply_t;
-
-
-/****************************************************************************
-*  Toolbox Console Text Display Tool
-****************************************************************************/
-
-/* Toolbox Console Text Display Tool request message */
-typedef struct _MPI2_TOOLBOX_TEXT_DISPLAY_REQUEST {
-       U8                      Tool;               /* 0x00 */
-       U8                      Reserved1;          /* 0x01 */
-       U8                      ChainOffset;        /* 0x02 */
-       U8                      Function;           /* 0x03 */
-       U16                     Reserved2;          /* 0x04 */
-       U8                      Reserved3;          /* 0x06 */
-       U8                      MsgFlags;           /* 0x07 */
-       U8                      VP_ID;              /* 0x08 */
-       U8                      VF_ID;              /* 0x09 */
-       U16                     Reserved4;          /* 0x0A */
-       U8                      Console;            /* 0x0C */
-       U8                      Flags;              /* 0x0D */
-       U16                     Reserved6;          /* 0x0E */
-       U8                      TextToDisplay[4];   /* 0x10 */
-} MPI2_TOOLBOX_TEXT_DISPLAY_REQUEST,
-MPI2_POINTER PTR_MPI2_TOOLBOX_TEXT_DISPLAY_REQUEST,
-Mpi2ToolboxTextDisplayRequest_t,
-MPI2_POINTER pMpi2ToolboxTextDisplayRequest_t;
-
-/* defines for the Console field */
-#define MPI2_TOOLBOX_CONSOLE_TYPE_MASK          (0xF0)
-#define MPI2_TOOLBOX_CONSOLE_TYPE_DEFAULT       (0x00)
-#define MPI2_TOOLBOX_CONSOLE_TYPE_UART          (0x10)
-#define MPI2_TOOLBOX_CONSOLE_TYPE_ETHERNET      (0x20)
-
-#define MPI2_TOOLBOX_CONSOLE_NUMBER_MASK        (0x0F)
-
-/* defines for the Flags field */
-#define MPI2_TOOLBOX_CONSOLE_FLAG_TIMESTAMP     (0x01)
-
-
-
-/*****************************************************************************
-*
-*       Diagnostic Buffer Messages
-*
-*****************************************************************************/
-
-
-/****************************************************************************
-*  Diagnostic Buffer Post request
-****************************************************************************/
-
-typedef struct _MPI2_DIAG_BUFFER_POST_REQUEST
-{
-    U8                      ExtendedType;               /* 0x00 */
-    U8                      BufferType;                 /* 0x01 */
-    U8                      ChainOffset;                /* 0x02 */
-    U8                      Function;                   /* 0x03 */
-    U16                     Reserved2;                  /* 0x04 */
-    U8                      Reserved3;                  /* 0x06 */
-    U8                      MsgFlags;                   /* 0x07 */
-    U8                      VP_ID;                      /* 0x08 */
-    U8                      VF_ID;                      /* 0x09 */
-    U16                     Reserved4;                  /* 0x0A */
-    U64                     BufferAddress;              /* 0x0C */
-    U32                     BufferLength;               /* 0x14 */
-    U32                     Reserved5;                  /* 0x18 */
-    U32                     Reserved6;                  /* 0x1C */
-    U32                     Flags;                      /* 0x20 */
-    U32                     ProductSpecific[23];        /* 0x24 */
-} MPI2_DIAG_BUFFER_POST_REQUEST, MPI2_POINTER PTR_MPI2_DIAG_BUFFER_POST_REQUEST,
-  Mpi2DiagBufferPostRequest_t, MPI2_POINTER pMpi2DiagBufferPostRequest_t;
-
-/* values for the ExtendedType field */
-#define MPI2_DIAG_EXTENDED_TYPE_UTILIZATION         (0x02)
-
-/* values for the BufferType field */
-#define MPI2_DIAG_BUF_TYPE_TRACE                    (0x00)
-#define MPI2_DIAG_BUF_TYPE_SNAPSHOT                 (0x01)
-#define MPI2_DIAG_BUF_TYPE_EXTENDED                 (0x02)
-/* count of the number of buffer types */
-#define MPI2_DIAG_BUF_TYPE_COUNT                    (0x03)
-
-/* values for the Flags field */
-#define MPI2_DIAG_BUF_FLAG_RELEASE_ON_FULL          (0x00000002)
-#define MPI2_DIAG_BUF_FLAG_IMMEDIATE_RELEASE        (0x00000001)
-
-
-/****************************************************************************
-*  Diagnostic Buffer Post reply
-****************************************************************************/
-
-typedef struct _MPI2_DIAG_BUFFER_POST_REPLY
-{
-    U8                      ExtendedType;               /* 0x00 */
-    U8                      BufferType;                 /* 0x01 */
-    U8                      MsgLength;                  /* 0x02 */
-    U8                      Function;                   /* 0x03 */
-    U16                     Reserved2;                  /* 0x04 */
-    U8                      Reserved3;                  /* 0x06 */
-    U8                      MsgFlags;                   /* 0x07 */
-    U8                      VP_ID;                      /* 0x08 */
-    U8                      VF_ID;                      /* 0x09 */
-    U16                     Reserved4;                  /* 0x0A */
-    U16                     Reserved5;                  /* 0x0C */
-    U16                     IOCStatus;                  /* 0x0E */
-    U32                     IOCLogInfo;                 /* 0x10 */
-    U32                     TransferLength;             /* 0x14 */
-} MPI2_DIAG_BUFFER_POST_REPLY, MPI2_POINTER PTR_MPI2_DIAG_BUFFER_POST_REPLY,
-  Mpi2DiagBufferPostReply_t, MPI2_POINTER pMpi2DiagBufferPostReply_t;
-
-
-/****************************************************************************
-*  Diagnostic Release request
-****************************************************************************/
-
-typedef struct _MPI2_DIAG_RELEASE_REQUEST
-{
-    U8                      Reserved1;                  /* 0x00 */
-    U8                      BufferType;                 /* 0x01 */
-    U8                      ChainOffset;                /* 0x02 */
-    U8                      Function;                   /* 0x03 */
-    U16                     Reserved2;                  /* 0x04 */
-    U8                      Reserved3;                  /* 0x06 */
-    U8                      MsgFlags;                   /* 0x07 */
-    U8                      VP_ID;                      /* 0x08 */
-    U8                      VF_ID;                      /* 0x09 */
-    U16                     Reserved4;                  /* 0x0A */
-} MPI2_DIAG_RELEASE_REQUEST, MPI2_POINTER PTR_MPI2_DIAG_RELEASE_REQUEST,
-  Mpi2DiagReleaseRequest_t, MPI2_POINTER pMpi2DiagReleaseRequest_t;
-
-
-/****************************************************************************
-*  Diagnostic Buffer Post reply
-****************************************************************************/
-
-typedef struct _MPI2_DIAG_RELEASE_REPLY
-{
-    U8                      Reserved1;                  /* 0x00 */
-    U8                      BufferType;                 /* 0x01 */
-    U8                      MsgLength;                  /* 0x02 */
-    U8                      Function;                   /* 0x03 */
-    U16                     Reserved2;                  /* 0x04 */
-    U8                      Reserved3;                  /* 0x06 */
-    U8                      MsgFlags;                   /* 0x07 */
-    U8                      VP_ID;                      /* 0x08 */
-    U8                      VF_ID;                      /* 0x09 */
-    U16                     Reserved4;                  /* 0x0A */
-    U16                     Reserved5;                  /* 0x0C */
-    U16                     IOCStatus;                  /* 0x0E */
-    U32                     IOCLogInfo;                 /* 0x10 */
-} MPI2_DIAG_RELEASE_REPLY, MPI2_POINTER PTR_MPI2_DIAG_RELEASE_REPLY,
-  Mpi2DiagReleaseReply_t, MPI2_POINTER pMpi2DiagReleaseReply_t;
-
-
-#endif
-
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_type.h b/drivers/scsi/mpt2sas/mpi/mpi2_type.h
deleted file mode 100644 (file)
index 6b0dcdd..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- *  Copyright (c) 2000-2014 LSI Corporation.
- *
- *
- *           Name:  mpi2_type.h
- *          Title:  MPI basic type definitions
- *  Creation Date:  August 16, 2006
- *
- *    mpi2_type.h Version:  02.00.00
- *
- *  Version History
- *  ---------------
- *
- *  Date      Version   Description
- *  --------  --------  ------------------------------------------------------
- *  04-30-07  02.00.00  Corresponds to Fusion-MPT MPI Specification Rev A.
- *  --------------------------------------------------------------------------
- */
-
-#ifndef MPI2_TYPE_H
-#define MPI2_TYPE_H
-
-
-/*******************************************************************************
- * Define MPI2_POINTER if it hasn't already been defined. By default
- * MPI2_POINTER is defined to be a near pointer. MPI2_POINTER can be defined as
- * a far pointer by defining MPI2_POINTER as "far *" before this header file is
- * included.
- */
-#ifndef MPI2_POINTER
-#define MPI2_POINTER     *
-#endif
-
-/* the basic types may have already been included by mpi_type.h */
-#ifndef MPI_TYPE_H
-/*****************************************************************************
-*
-*               Basic Types
-*
-*****************************************************************************/
-
-typedef u8 U8;
-typedef __le16 U16;
-typedef __le32 U32;
-typedef __le64 U64 __attribute__((aligned(4)));
-
-/*****************************************************************************
-*
-*               Pointer Types
-*
-*****************************************************************************/
-
-typedef U8      *PU8;
-typedef U16     *PU16;
-typedef U32     *PU32;
-typedef U64     *PU64;
-
-#endif
-
-#endif
-
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
deleted file mode 100644 (file)
index c167911..0000000
+++ /dev/null
@@ -1,4899 +0,0 @@
-/*
- * This is the Fusion MPT base driver providing common API layer interface
- * for access to MPT (Message Passing Technology) firmware.
- *
- * This code is based on drivers/scsi/mpt2sas/mpt2_base.c
- * Copyright (C) 2007-2014  LSI Corporation
- * Copyright (C) 20013-2014 Avago Technologies
- *  (mailto: MPT-FusionLinux.pdl@avagotech.com)
- *
- * 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.
- *
- * NO WARRANTY
- * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
- * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
- * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
- * solely responsible for determining the appropriateness of using and
- * distributing the Program and assumes all risks associated with its
- * exercise of rights under this Agreement, including but not limited to
- * the risks and costs of program errors, damage to or loss of data,
- * programs or equipment, and unavailability or interruption of operations.
-
- * DISCLAIMER OF LIABILITY
- * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
- * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
- * USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/kdev_t.h>
-#include <linux/blkdev.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/dma-mapping.h>
-#include <linux/sort.h>
-#include <linux/io.h>
-#include <linux/time.h>
-#include <linux/kthread.h>
-#include <linux/aer.h>
-
-#include "mpt2sas_base.h"
-
-static MPT_CALLBACK    mpt_callbacks[MPT_MAX_CALLBACKS];
-
-#define FAULT_POLLING_INTERVAL 1000 /* in milliseconds */
-
-#define MAX_HBA_QUEUE_DEPTH    30000
-#define MAX_CHAIN_DEPTH                100000
-static int max_queue_depth = -1;
-module_param(max_queue_depth, int, 0);
-MODULE_PARM_DESC(max_queue_depth, " max controller queue depth ");
-
-static int max_sgl_entries = -1;
-module_param(max_sgl_entries, int, 0);
-MODULE_PARM_DESC(max_sgl_entries, " max sg entries ");
-
-static int msix_disable = -1;
-module_param(msix_disable, int, 0);
-MODULE_PARM_DESC(msix_disable, " disable msix routed interrupts (default=0)");
-
-static int max_msix_vectors = -1;
-module_param(max_msix_vectors, int, 0);
-MODULE_PARM_DESC(max_msix_vectors, " max msix vectors ");
-
-static int mpt2sas_fwfault_debug;
-MODULE_PARM_DESC(mpt2sas_fwfault_debug, " enable detection of firmware fault "
-       "and halt firmware - (default=0)");
-
-static int disable_discovery = -1;
-module_param(disable_discovery, int, 0);
-MODULE_PARM_DESC(disable_discovery, " disable discovery ");
-
-static int
-_base_get_ioc_facts(struct MPT2SAS_ADAPTER *ioc, int sleep_flag);
-
-static int
-_base_diag_reset(struct MPT2SAS_ADAPTER *ioc, int sleep_flag);
-
-/**
- * _scsih_set_fwfault_debug - global setting of ioc->fwfault_debug.
- *
- */
-static int
-_scsih_set_fwfault_debug(const char *val, struct kernel_param *kp)
-{
-       int ret = param_set_int(val, kp);
-       struct MPT2SAS_ADAPTER *ioc;
-
-       if (ret)
-               return ret;
-
-       /* global ioc spinlock to protect controller list on list operations */
-       printk(KERN_INFO "setting fwfault_debug(%d)\n", mpt2sas_fwfault_debug);
-       spin_lock(&gioc_lock);
-       list_for_each_entry(ioc, &mpt2sas_ioc_list, list)
-               ioc->fwfault_debug = mpt2sas_fwfault_debug;
-       spin_unlock(&gioc_lock);
-       return 0;
-}
-
-module_param_call(mpt2sas_fwfault_debug, _scsih_set_fwfault_debug,
-    param_get_int, &mpt2sas_fwfault_debug, 0644);
-
-/**
- *  mpt2sas_remove_dead_ioc_func - kthread context to remove dead ioc
- * @arg: input argument, used to derive ioc
- *
- * Return 0 if controller is removed from pci subsystem.
- * Return -1 for other case.
- */
-static int mpt2sas_remove_dead_ioc_func(void *arg)
-{
-               struct MPT2SAS_ADAPTER *ioc = (struct MPT2SAS_ADAPTER *)arg;
-               struct pci_dev *pdev;
-
-               if ((ioc == NULL))
-                       return -1;
-
-               pdev = ioc->pdev;
-               if ((pdev == NULL))
-                       return -1;
-               pci_stop_and_remove_bus_device_locked(pdev);
-               return 0;
-}
-
-
-/**
- * _base_fault_reset_work - workq handling ioc fault conditions
- * @work: input argument, used to derive ioc
- * Context: sleep.
- *
- * Return nothing.
- */
-static void
-_base_fault_reset_work(struct work_struct *work)
-{
-       struct MPT2SAS_ADAPTER *ioc =
-           container_of(work, struct MPT2SAS_ADAPTER, fault_reset_work.work);
-       unsigned long    flags;
-       u32 doorbell;
-       int rc;
-       struct task_struct *p;
-
-       spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
-       if (ioc->shost_recovery || ioc->pci_error_recovery)
-               goto rearm_timer;
-       spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
-
-       doorbell = mpt2sas_base_get_iocstate(ioc, 0);
-       if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_MASK) {
-               printk(MPT2SAS_INFO_FMT "%s : SAS host is non-operational !!!!\n",
-                       ioc->name, __func__);
-
-               /* It may be possible that EEH recovery can resolve some of
-                * pci bus failure issues rather removing the dead ioc function
-                * by considering controller is in a non-operational state. So
-                * here priority is given to the EEH recovery. If it doesn't
-                * not resolve this issue, mpt2sas driver will consider this
-                * controller to non-operational state and remove the dead ioc
-                * function.
-                */
-               if (ioc->non_operational_loop++ < 5) {
-                       spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock,
-                                                        flags);
-                       goto rearm_timer;
-               }
-
-               /*
-                * Call _scsih_flush_pending_cmds callback so that we flush all
-                * pending commands back to OS. This call is required to aovid
-                * deadlock at block layer. Dead IOC will fail to do diag reset,
-                * and this call is safe since dead ioc will never return any
-                * command back from HW.
-                */
-               ioc->schedule_dead_ioc_flush_running_cmds(ioc);
-               /*
-                * Set remove_host flag early since kernel thread will
-                * take some time to execute.
-                */
-               ioc->remove_host = 1;
-               /*Remove the Dead Host */
-               p = kthread_run(mpt2sas_remove_dead_ioc_func, ioc,
-                   "mpt2sas_dead_ioc_%d", ioc->id);
-               if (IS_ERR(p)) {
-                       printk(MPT2SAS_ERR_FMT
-                       "%s: Running mpt2sas_dead_ioc thread failed !!!!\n",
-                       ioc->name, __func__);
-               } else {
-                   printk(MPT2SAS_ERR_FMT
-                       "%s: Running mpt2sas_dead_ioc thread success !!!!\n",
-                       ioc->name, __func__);
-               }
-
-               return; /* don't rearm timer */
-       }
-
-       ioc->non_operational_loop = 0;
-
-       if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) {
-               rc = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
-                   FORCE_BIG_HAMMER);
-               printk(MPT2SAS_WARN_FMT "%s: hard reset: %s\n", ioc->name,
-                   __func__, (rc == 0) ? "success" : "failed");
-               doorbell = mpt2sas_base_get_iocstate(ioc, 0);
-               if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT)
-                       mpt2sas_base_fault_info(ioc, doorbell &
-                           MPI2_DOORBELL_DATA_MASK);
-       }
-
-       spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
- rearm_timer:
-       if (ioc->fault_reset_work_q)
-               queue_delayed_work(ioc->fault_reset_work_q,
-                   &ioc->fault_reset_work,
-                   msecs_to_jiffies(FAULT_POLLING_INTERVAL));
-       spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
-}
-
-/**
- * mpt2sas_base_start_watchdog - start the fault_reset_work_q
- * @ioc: per adapter object
- * Context: sleep.
- *
- * Return nothing.
- */
-void
-mpt2sas_base_start_watchdog(struct MPT2SAS_ADAPTER *ioc)
-{
-       unsigned long    flags;
-
-       if (ioc->fault_reset_work_q)
-               return;
-
-       /* initialize fault polling */
-       INIT_DELAYED_WORK(&ioc->fault_reset_work, _base_fault_reset_work);
-       snprintf(ioc->fault_reset_work_q_name,
-           sizeof(ioc->fault_reset_work_q_name), "poll_%d_status", ioc->id);
-       ioc->fault_reset_work_q =
-               create_singlethread_workqueue(ioc->fault_reset_work_q_name);
-       if (!ioc->fault_reset_work_q) {
-               printk(MPT2SAS_ERR_FMT "%s: failed (line=%d)\n",
-                   ioc->name, __func__, __LINE__);
-                       return;
-       }
-       spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
-       if (ioc->fault_reset_work_q)
-               queue_delayed_work(ioc->fault_reset_work_q,
-                   &ioc->fault_reset_work,
-                   msecs_to_jiffies(FAULT_POLLING_INTERVAL));
-       spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
-}
-
-/**
- * mpt2sas_base_stop_watchdog - stop the fault_reset_work_q
- * @ioc: per adapter object
- * Context: sleep.
- *
- * Return nothing.
- */
-void
-mpt2sas_base_stop_watchdog(struct MPT2SAS_ADAPTER *ioc)
-{
-       unsigned long    flags;
-       struct workqueue_struct *wq;
-
-       spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
-       wq = ioc->fault_reset_work_q;
-       ioc->fault_reset_work_q = NULL;
-       spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
-       if (wq) {
-               if (!cancel_delayed_work_sync(&ioc->fault_reset_work))
-                       flush_workqueue(wq);
-               destroy_workqueue(wq);
-       }
-}
-
-/**
- * mpt2sas_base_fault_info - verbose translation of firmware FAULT code
- * @ioc: per adapter object
- * @fault_code: fault code
- *
- * Return nothing.
- */
-void
-mpt2sas_base_fault_info(struct MPT2SAS_ADAPTER *ioc , u16 fault_code)
-{
-       printk(MPT2SAS_ERR_FMT "fault_state(0x%04x)!\n",
-           ioc->name, fault_code);
-}
-
-/**
- * mpt2sas_halt_firmware - halt's mpt controller firmware
- * @ioc: per adapter object
- *
- * For debugging timeout related issues.  Writing 0xCOFFEE00
- * to the doorbell register will halt controller firmware. With
- * the purpose to stop both driver and firmware, the enduser can
- * obtain a ring buffer from controller UART.
- */
-void
-mpt2sas_halt_firmware(struct MPT2SAS_ADAPTER *ioc)
-{
-       u32 doorbell;
-
-       if (!ioc->fwfault_debug)
-               return;
-
-       dump_stack();
-
-       doorbell = readl(&ioc->chip->Doorbell);
-       if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT)
-               mpt2sas_base_fault_info(ioc , doorbell);
-       else {
-               writel(0xC0FFEE00, &ioc->chip->Doorbell);
-               printk(MPT2SAS_ERR_FMT "Firmware is halted due to command "
-                   "timeout\n", ioc->name);
-       }
-
-       panic("panic in %s\n", __func__);
-}
-
-#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
-/**
- * _base_sas_ioc_info - verbose translation of the ioc status
- * @ioc: per adapter object
- * @mpi_reply: reply mf payload returned from firmware
- * @request_hdr: request mf
- *
- * Return nothing.
- */
-static void
-_base_sas_ioc_info(struct MPT2SAS_ADAPTER *ioc, MPI2DefaultReply_t *mpi_reply,
-     MPI2RequestHeader_t *request_hdr)
-{
-       u16 ioc_status = le16_to_cpu(mpi_reply->IOCStatus) &
-           MPI2_IOCSTATUS_MASK;
-       char *desc = NULL;
-       u16 frame_sz;
-       char *func_str = NULL;
-
-       /* SCSI_IO, RAID_PASS are handled from _scsih_scsi_ioc_info */
-       if (request_hdr->Function == MPI2_FUNCTION_SCSI_IO_REQUEST ||
-           request_hdr->Function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH ||
-           request_hdr->Function == MPI2_FUNCTION_EVENT_NOTIFICATION)
-               return;
-
-       if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
-               return;
-
-       switch (ioc_status) {
-
-/****************************************************************************
-*  Common IOCStatus values for all replies
-****************************************************************************/
-
-       case MPI2_IOCSTATUS_INVALID_FUNCTION:
-               desc = "invalid function";
-               break;
-       case MPI2_IOCSTATUS_BUSY:
-               desc = "busy";
-               break;
-       case MPI2_IOCSTATUS_INVALID_SGL:
-               desc = "invalid sgl";
-               break;
-       case MPI2_IOCSTATUS_INTERNAL_ERROR:
-               desc = "internal error";
-               break;
-       case MPI2_IOCSTATUS_INVALID_VPID:
-               desc = "invalid vpid";
-               break;
-       case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES:
-               desc = "insufficient resources";
-               break;
-       case MPI2_IOCSTATUS_INVALID_FIELD:
-               desc = "invalid field";
-               break;
-       case MPI2_IOCSTATUS_INVALID_STATE:
-               desc = "invalid state";
-               break;
-       case MPI2_IOCSTATUS_OP_STATE_NOT_SUPPORTED:
-               desc = "op state not supported";
-               break;
-
-/****************************************************************************
-*  Config IOCStatus values
-****************************************************************************/
-
-       case MPI2_IOCSTATUS_CONFIG_INVALID_ACTION:
-               desc = "config invalid action";
-               break;
-       case MPI2_IOCSTATUS_CONFIG_INVALID_TYPE:
-               desc = "config invalid type";
-               break;
-       case MPI2_IOCSTATUS_CONFIG_INVALID_PAGE:
-               desc = "config invalid page";
-               break;
-       case MPI2_IOCSTATUS_CONFIG_INVALID_DATA:
-               desc = "config invalid data";
-               break;
-       case MPI2_IOCSTATUS_CONFIG_NO_DEFAULTS:
-               desc = "config no defaults";
-               break;
-       case MPI2_IOCSTATUS_CONFIG_CANT_COMMIT:
-               desc = "config cant commit";
-               break;
-
-/****************************************************************************
-*  SCSI IO Reply
-****************************************************************************/
-
-       case MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR:
-       case MPI2_IOCSTATUS_SCSI_INVALID_DEVHANDLE:
-       case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
-       case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN:
-       case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN:
-       case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR:
-       case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR:
-       case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED:
-       case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
-       case MPI2_IOCSTATUS_SCSI_TASK_MGMT_FAILED:
-       case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED:
-       case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
-               break;
-
-/****************************************************************************
-*  For use by SCSI Initiator and SCSI Target end-to-end data protection
-****************************************************************************/
-
-       case MPI2_IOCSTATUS_EEDP_GUARD_ERROR:
-               desc = "eedp guard error";
-               break;
-       case MPI2_IOCSTATUS_EEDP_REF_TAG_ERROR:
-               desc = "eedp ref tag error";
-               break;
-       case MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR:
-               desc = "eedp app tag error";
-               break;
-
-/****************************************************************************
-*  SCSI Target values
-****************************************************************************/
-
-       case MPI2_IOCSTATUS_TARGET_INVALID_IO_INDEX:
-               desc = "target invalid io index";
-               break;
-       case MPI2_IOCSTATUS_TARGET_ABORTED:
-               desc = "target aborted";
-               break;
-       case MPI2_IOCSTATUS_TARGET_NO_CONN_RETRYABLE:
-               desc = "target no conn retryable";
-               break;
-       case MPI2_IOCSTATUS_TARGET_NO_CONNECTION:
-               desc = "target no connection";
-               break;
-       case MPI2_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH:
-               desc = "target xfer count mismatch";
-               break;
-       case MPI2_IOCSTATUS_TARGET_DATA_OFFSET_ERROR:
-               desc = "target data offset error";
-               break;
-       case MPI2_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA:
-               desc = "target too much write data";
-               break;
-       case MPI2_IOCSTATUS_TARGET_IU_TOO_SHORT:
-               desc = "target iu too short";
-               break;
-       case MPI2_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT:
-               desc = "target ack nak timeout";
-               break;
-       case MPI2_IOCSTATUS_TARGET_NAK_RECEIVED:
-               desc = "target nak received";
-               break;
-
-/****************************************************************************
-*  Serial Attached SCSI values
-****************************************************************************/
-
-       case MPI2_IOCSTATUS_SAS_SMP_REQUEST_FAILED:
-               desc = "smp request failed";
-               break;
-       case MPI2_IOCSTATUS_SAS_SMP_DATA_OVERRUN:
-               desc = "smp data overrun";
-               break;
-
-/****************************************************************************
-*  Diagnostic Buffer Post / Diagnostic Release values
-****************************************************************************/
-
-       case MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED:
-               desc = "diagnostic released";
-               break;
-       default:
-               break;
-       }
-
-       if (!desc)
-               return;
-
-       switch (request_hdr->Function) {
-       case MPI2_FUNCTION_CONFIG:
-               frame_sz = sizeof(Mpi2ConfigRequest_t) + ioc->sge_size;
-               func_str = "config_page";
-               break;
-       case MPI2_FUNCTION_SCSI_TASK_MGMT:
-               frame_sz = sizeof(Mpi2SCSITaskManagementRequest_t);
-               func_str = "task_mgmt";
-               break;
-       case MPI2_FUNCTION_SAS_IO_UNIT_CONTROL:
-               frame_sz = sizeof(Mpi2SasIoUnitControlRequest_t);
-               func_str = "sas_iounit_ctl";
-               break;
-       case MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR:
-               frame_sz = sizeof(Mpi2SepRequest_t);
-               func_str = "enclosure";
-               break;
-       case MPI2_FUNCTION_IOC_INIT:
-               frame_sz = sizeof(Mpi2IOCInitRequest_t);
-               func_str = "ioc_init";
-               break;
-       case MPI2_FUNCTION_PORT_ENABLE:
-               frame_sz = sizeof(Mpi2PortEnableRequest_t);
-               func_str = "port_enable";
-               break;
-       case MPI2_FUNCTION_SMP_PASSTHROUGH:
-               frame_sz = sizeof(Mpi2SmpPassthroughRequest_t) + ioc->sge_size;
-               func_str = "smp_passthru";
-               break;
-       default:
-               frame_sz = 32;
-               func_str = "unknown";
-               break;
-       }
-
-       printk(MPT2SAS_WARN_FMT "ioc_status: %s(0x%04x), request(0x%p),"
-           " (%s)\n", ioc->name, desc, ioc_status, request_hdr, func_str);
-
-       _debug_dump_mf(request_hdr, frame_sz/4);
-}
-
-/**
- * _base_display_event_data - verbose translation of firmware asyn events
- * @ioc: per adapter object
- * @mpi_reply: reply mf payload returned from firmware
- *
- * Return nothing.
- */
-static void
-_base_display_event_data(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2EventNotificationReply_t *mpi_reply)
-{
-       char *desc = NULL;
-       u16 event;
-
-       if (!(ioc->logging_level & MPT_DEBUG_EVENTS))
-               return;
-
-       event = le16_to_cpu(mpi_reply->Event);
-
-       switch (event) {
-       case MPI2_EVENT_LOG_DATA:
-               desc = "Log Data";
-               break;
-       case MPI2_EVENT_STATE_CHANGE:
-               desc = "Status Change";
-               break;
-       case MPI2_EVENT_HARD_RESET_RECEIVED:
-               desc = "Hard Reset Received";
-               break;
-       case MPI2_EVENT_EVENT_CHANGE:
-               desc = "Event Change";
-               break;
-       case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
-               desc = "Device Status Change";
-               break;
-       case MPI2_EVENT_IR_OPERATION_STATUS:
-               if (!ioc->hide_ir_msg)
-                       desc = "IR Operation Status";
-               break;
-       case MPI2_EVENT_SAS_DISCOVERY:
-       {
-               Mpi2EventDataSasDiscovery_t *event_data =
-                   (Mpi2EventDataSasDiscovery_t *)mpi_reply->EventData;
-               printk(MPT2SAS_INFO_FMT "Discovery: (%s)", ioc->name,
-                   (event_data->ReasonCode == MPI2_EVENT_SAS_DISC_RC_STARTED) ?
-                   "start" : "stop");
-               if (event_data->DiscoveryStatus)
-                       printk("discovery_status(0x%08x)",
-                           le32_to_cpu(event_data->DiscoveryStatus));
-               printk("\n");
-               return;
-       }
-       case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE:
-               desc = "SAS Broadcast Primitive";
-               break;
-       case MPI2_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
-               desc = "SAS Init Device Status Change";
-               break;
-       case MPI2_EVENT_SAS_INIT_TABLE_OVERFLOW:
-               desc = "SAS Init Table Overflow";
-               break;
-       case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
-               desc = "SAS Topology Change List";
-               break;
-       case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
-               desc = "SAS Enclosure Device Status Change";
-               break;
-       case MPI2_EVENT_IR_VOLUME:
-               if (!ioc->hide_ir_msg)
-                       desc = "IR Volume";
-               break;
-       case MPI2_EVENT_IR_PHYSICAL_DISK:
-               if (!ioc->hide_ir_msg)
-                       desc = "IR Physical Disk";
-               break;
-       case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
-               if (!ioc->hide_ir_msg)
-                       desc = "IR Configuration Change List";
-               break;
-       case MPI2_EVENT_LOG_ENTRY_ADDED:
-               if (!ioc->hide_ir_msg)
-                       desc = "Log Entry Added";
-               break;
-       case MPI2_EVENT_TEMP_THRESHOLD:
-               desc = "Temperature Threshold";
-               break;
-       }
-
-       if (!desc)
-               return;
-
-       printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, desc);
-}
-#endif
-
-/**
- * _base_sas_log_info - verbose translation of firmware log info
- * @ioc: per adapter object
- * @log_info: log info
- *
- * Return nothing.
- */
-static void
-_base_sas_log_info(struct MPT2SAS_ADAPTER *ioc , u32 log_info)
-{
-       union loginfo_type {
-               u32     loginfo;
-               struct {
-                       u32     subcode:16;
-                       u32     code:8;
-                       u32     originator:4;
-                       u32     bus_type:4;
-               } dw;
-       };
-       union loginfo_type sas_loginfo;
-       char *originator_str = NULL;
-
-       sas_loginfo.loginfo = log_info;
-       if (sas_loginfo.dw.bus_type != 3 /*SAS*/)
-               return;
-
-       /* each nexus loss loginfo */
-       if (log_info == 0x31170000)
-               return;
-
-       /* eat the loginfos associated with task aborts */
-       if (ioc->ignore_loginfos && (log_info == 0x30050000 || log_info ==
-           0x31140000 || log_info == 0x31130000))
-               return;
-
-       switch (sas_loginfo.dw.originator) {
-       case 0:
-               originator_str = "IOP";
-               break;
-       case 1:
-               originator_str = "PL";
-               break;
-       case 2:
-               if (!ioc->hide_ir_msg)
-                       originator_str = "IR";
-               else
-                       originator_str = "WarpDrive";
-               break;
-       }
-
-       printk(MPT2SAS_WARN_FMT "log_info(0x%08x): originator(%s), "
-           "code(0x%02x), sub_code(0x%04x)\n", ioc->name, log_info,
-            originator_str, sas_loginfo.dw.code,
-            sas_loginfo.dw.subcode);
-}
-
-/**
- * _base_display_reply_info -
- * @ioc: per adapter object
- * @smid: system request message index
- * @msix_index: MSIX table index supplied by the OS
- * @reply: reply message frame(lower 32bit addr)
- *
- * Return nothing.
- */
-static void
-_base_display_reply_info(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
-    u32 reply)
-{
-       MPI2DefaultReply_t *mpi_reply;
-       u16 ioc_status;
-
-       mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
-       if (unlikely(!mpi_reply)) {
-               printk(MPT2SAS_ERR_FMT "mpi_reply not valid at %s:%d/%s()!\n",
-                       ioc->name, __FILE__, __LINE__, __func__);
-               return;
-       }
-       ioc_status = le16_to_cpu(mpi_reply->IOCStatus);
-#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
-       if ((ioc_status & MPI2_IOCSTATUS_MASK) &&
-           (ioc->logging_level & MPT_DEBUG_REPLY)) {
-               _base_sas_ioc_info(ioc , mpi_reply,
-                  mpt2sas_base_get_msg_frame(ioc, smid));
-       }
-#endif
-       if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE)
-               _base_sas_log_info(ioc, le32_to_cpu(mpi_reply->IOCLogInfo));
-}
-
-/**
- * mpt2sas_base_done - base internal command completion routine
- * @ioc: per adapter object
- * @smid: system request message index
- * @msix_index: MSIX table index supplied by the OS
- * @reply: reply message frame(lower 32bit addr)
- *
- * Return 1 meaning mf should be freed from _base_interrupt
- *        0 means the mf is freed from this function.
- */
-u8
-mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
-    u32 reply)
-{
-       MPI2DefaultReply_t *mpi_reply;
-
-       mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
-       if (mpi_reply && mpi_reply->Function == MPI2_FUNCTION_EVENT_ACK)
-               return 1;
-
-       if (ioc->base_cmds.status == MPT2_CMD_NOT_USED)
-               return 1;
-
-       ioc->base_cmds.status |= MPT2_CMD_COMPLETE;
-       if (mpi_reply) {
-               ioc->base_cmds.status |= MPT2_CMD_REPLY_VALID;
-               memcpy(ioc->base_cmds.reply, mpi_reply, mpi_reply->MsgLength*4);
-       }
-       ioc->base_cmds.status &= ~MPT2_CMD_PENDING;
-
-       complete(&ioc->base_cmds.done);
-       return 1;
-}
-
-/**
- * _base_async_event - main callback handler for firmware asyn events
- * @ioc: per adapter object
- * @msix_index: MSIX table index supplied by the OS
- * @reply: reply message frame(lower 32bit addr)
- *
- * Returns void.
- */
-static void
-_base_async_event(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, u32 reply)
-{
-       Mpi2EventNotificationReply_t *mpi_reply;
-       Mpi2EventAckRequest_t *ack_request;
-       u16 smid;
-
-       mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
-       if (!mpi_reply)
-               return;
-       if (mpi_reply->Function != MPI2_FUNCTION_EVENT_NOTIFICATION)
-               return;
-#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
-       _base_display_event_data(ioc, mpi_reply);
-#endif
-       if (!(mpi_reply->AckRequired & MPI2_EVENT_NOTIFICATION_ACK_REQUIRED))
-               goto out;
-       smid = mpt2sas_base_get_smid(ioc, ioc->base_cb_idx);
-       if (!smid) {
-               printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
-                   ioc->name, __func__);
-               goto out;
-       }
-
-       ack_request = mpt2sas_base_get_msg_frame(ioc, smid);
-       memset(ack_request, 0, sizeof(Mpi2EventAckRequest_t));
-       ack_request->Function = MPI2_FUNCTION_EVENT_ACK;
-       ack_request->Event = mpi_reply->Event;
-       ack_request->EventContext = mpi_reply->EventContext;
-       ack_request->VF_ID = 0;  /* TODO */
-       ack_request->VP_ID = 0;
-       mpt2sas_base_put_smid_default(ioc, smid);
-
- out:
-
-       /* scsih callback handler */
-       mpt2sas_scsih_event_callback(ioc, msix_index, reply);
-
-       /* ctl callback handler */
-       mpt2sas_ctl_event_callback(ioc, msix_index, reply);
-
-       return;
-}
-
-/**
- * _base_get_cb_idx - obtain the callback index
- * @ioc: per adapter object
- * @smid: system request message index
- *
- * Return callback index.
- */
-static u8
-_base_get_cb_idx(struct MPT2SAS_ADAPTER *ioc, u16 smid)
-{
-       int i;
-       u8 cb_idx;
-
-       if (smid < ioc->hi_priority_smid) {
-               i = smid - 1;
-               cb_idx = ioc->scsi_lookup[i].cb_idx;
-       } else if (smid < ioc->internal_smid) {
-               i = smid - ioc->hi_priority_smid;
-               cb_idx = ioc->hpr_lookup[i].cb_idx;
-       } else if (smid <= ioc->hba_queue_depth) {
-               i = smid - ioc->internal_smid;
-               cb_idx = ioc->internal_lookup[i].cb_idx;
-       } else
-               cb_idx = 0xFF;
-       return cb_idx;
-}
-
-/**
- * _base_mask_interrupts - disable interrupts
- * @ioc: per adapter object
- *
- * Disabling ResetIRQ, Reply and Doorbell Interrupts
- *
- * Return nothing.
- */
-static void
-_base_mask_interrupts(struct MPT2SAS_ADAPTER *ioc)
-{
-       u32 him_register;
-
-       ioc->mask_interrupts = 1;
-       him_register = readl(&ioc->chip->HostInterruptMask);
-       him_register |= MPI2_HIM_DIM + MPI2_HIM_RIM + MPI2_HIM_RESET_IRQ_MASK;
-       writel(him_register, &ioc->chip->HostInterruptMask);
-       readl(&ioc->chip->HostInterruptMask);
-}
-
-/**
- * _base_unmask_interrupts - enable interrupts
- * @ioc: per adapter object
- *
- * Enabling only Reply Interrupts
- *
- * Return nothing.
- */
-static void
-_base_unmask_interrupts(struct MPT2SAS_ADAPTER *ioc)
-{
-       u32 him_register;
-
-       him_register = readl(&ioc->chip->HostInterruptMask);
-       him_register &= ~MPI2_HIM_RIM;
-       writel(him_register, &ioc->chip->HostInterruptMask);
-       ioc->mask_interrupts = 0;
-}
-
-union reply_descriptor {
-       u64 word;
-       struct {
-               u32 low;
-               u32 high;
-       } u;
-};
-
-/**
- * _base_interrupt - MPT adapter (IOC) specific interrupt handler.
- * @irq: irq number (not used)
- * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
- * @r: pt_regs pointer (not used)
- *
- * Return IRQ_HANDLE if processed, else IRQ_NONE.
- */
-static irqreturn_t
-_base_interrupt(int irq, void *bus_id)
-{
-       struct adapter_reply_queue *reply_q = bus_id;
-       union reply_descriptor rd;
-       u32 completed_cmds;
-       u8 request_desript_type;
-       u16 smid;
-       u8 cb_idx;
-       u32 reply;
-       u8 msix_index = reply_q->msix_index;
-       struct MPT2SAS_ADAPTER *ioc = reply_q->ioc;
-       Mpi2ReplyDescriptorsUnion_t *rpf;
-       u8 rc;
-
-       if (ioc->mask_interrupts)
-               return IRQ_NONE;
-
-       if (!atomic_add_unless(&reply_q->busy, 1, 1))
-               return IRQ_NONE;
-
-       rpf = &reply_q->reply_post_free[reply_q->reply_post_host_index];
-       request_desript_type = rpf->Default.ReplyFlags
-            & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
-       if (request_desript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED) {
-               atomic_dec(&reply_q->busy);
-               return IRQ_NONE;
-       }
-
-       completed_cmds = 0;
-       cb_idx = 0xFF;
-       do {
-               rd.word = le64_to_cpu(rpf->Words);
-               if (rd.u.low == UINT_MAX || rd.u.high == UINT_MAX)
-                       goto out;
-               reply = 0;
-               smid = le16_to_cpu(rpf->Default.DescriptorTypeDependent1);
-               if (request_desript_type ==
-                   MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) {
-                       reply = le32_to_cpu
-                               (rpf->AddressReply.ReplyFrameAddress);
-                       if (reply > ioc->reply_dma_max_address ||
-                           reply < ioc->reply_dma_min_address)
-                               reply = 0;
-               } else if (request_desript_type ==
-                   MPI2_RPY_DESCRIPT_FLAGS_TARGET_COMMAND_BUFFER)
-                       goto next;
-               else if (request_desript_type ==
-                   MPI2_RPY_DESCRIPT_FLAGS_TARGETASSIST_SUCCESS)
-                       goto next;
-               if (smid) {
-                       cb_idx = _base_get_cb_idx(ioc, smid);
-               if ((likely(cb_idx < MPT_MAX_CALLBACKS))
-                           && (likely(mpt_callbacks[cb_idx] != NULL))) {
-                               rc = mpt_callbacks[cb_idx](ioc, smid,
-                                   msix_index, reply);
-                       if (reply)
-                               _base_display_reply_info(ioc, smid,
-                                   msix_index, reply);
-                       if (rc)
-                               mpt2sas_base_free_smid(ioc, smid);
-                       }
-               }
-               if (!smid)
-                       _base_async_event(ioc, msix_index, reply);
-
-               /* reply free queue handling */
-               if (reply) {
-                       ioc->reply_free_host_index =
-                           (ioc->reply_free_host_index ==
-                           (ioc->reply_free_queue_depth - 1)) ?
-                           0 : ioc->reply_free_host_index + 1;
-                       ioc->reply_free[ioc->reply_free_host_index] =
-                           cpu_to_le32(reply);
-                       wmb();
-                       writel(ioc->reply_free_host_index,
-                           &ioc->chip->ReplyFreeHostIndex);
-               }
-
- next:
-
-               rpf->Words = cpu_to_le64(ULLONG_MAX);
-               reply_q->reply_post_host_index =
-                   (reply_q->reply_post_host_index ==
-                   (ioc->reply_post_queue_depth - 1)) ? 0 :
-                   reply_q->reply_post_host_index + 1;
-               request_desript_type =
-                   reply_q->reply_post_free[reply_q->reply_post_host_index].
-                   Default.ReplyFlags & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
-               completed_cmds++;
-               if (request_desript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED)
-                       goto out;
-               if (!reply_q->reply_post_host_index)
-                       rpf = reply_q->reply_post_free;
-               else
-                       rpf++;
-       } while (1);
-
- out:
-
-       if (!completed_cmds) {
-               atomic_dec(&reply_q->busy);
-               return IRQ_NONE;
-       }
-       wmb();
-       if (ioc->is_warpdrive) {
-               writel(reply_q->reply_post_host_index,
-               ioc->reply_post_host_index[msix_index]);
-               atomic_dec(&reply_q->busy);
-               return IRQ_HANDLED;
-       }
-       writel(reply_q->reply_post_host_index | (msix_index <<
-           MPI2_RPHI_MSIX_INDEX_SHIFT), &ioc->chip->ReplyPostHostIndex);
-       atomic_dec(&reply_q->busy);
-       return IRQ_HANDLED;
-}
-
-/**
- * _base_is_controller_msix_enabled - is controller support muli-reply queues
- * @ioc: per adapter object
- *
- */
-static inline int
-_base_is_controller_msix_enabled(struct MPT2SAS_ADAPTER *ioc)
-{
-       return (ioc->facts.IOCCapabilities &
-           MPI2_IOCFACTS_CAPABILITY_MSI_X_INDEX) && ioc->msix_enable;
-}
-
-/**
- * mpt2sas_base_flush_reply_queues - flushing the MSIX reply queues
- * @ioc: per adapter object
- * Context: ISR conext
- *
- * Called when a Task Management request has completed. We want
- * to flush the other reply queues so all the outstanding IO has been
- * completed back to OS before we process the TM completetion.
- *
- * Return nothing.
- */
-void
-mpt2sas_base_flush_reply_queues(struct MPT2SAS_ADAPTER *ioc)
-{
-       struct adapter_reply_queue *reply_q;
-
-       /* If MSIX capability is turned off
-        * then multi-queues are not enabled
-        */
-       if (!_base_is_controller_msix_enabled(ioc))
-               return;
-
-       list_for_each_entry(reply_q, &ioc->reply_queue_list, list) {
-               if (ioc->shost_recovery)
-                       return;
-               /* TMs are on msix_index == 0 */
-               if (reply_q->msix_index == 0)
-                       continue;
-               _base_interrupt(reply_q->vector, (void *)reply_q);
-       }
-}
-
-/**
- * mpt2sas_base_release_callback_handler - clear interrupt callback handler
- * @cb_idx: callback index
- *
- * Return nothing.
- */
-void
-mpt2sas_base_release_callback_handler(u8 cb_idx)
-{
-       mpt_callbacks[cb_idx] = NULL;
-}
-
-/**
- * mpt2sas_base_register_callback_handler - obtain index for the interrupt callback handler
- * @cb_func: callback function
- *
- * Returns cb_func.
- */
-u8
-mpt2sas_base_register_callback_handler(MPT_CALLBACK cb_func)
-{
-       u8 cb_idx;
-
-       for (cb_idx = MPT_MAX_CALLBACKS-1; cb_idx; cb_idx--)
-               if (mpt_callbacks[cb_idx] == NULL)
-                       break;
-
-       mpt_callbacks[cb_idx] = cb_func;
-       return cb_idx;
-}
-
-/**
- * mpt2sas_base_initialize_callback_handler - initialize the interrupt callback handler
- *
- * Return nothing.
- */
-void
-mpt2sas_base_initialize_callback_handler(void)
-{
-       u8 cb_idx;
-
-       for (cb_idx = 0; cb_idx < MPT_MAX_CALLBACKS; cb_idx++)
-               mpt2sas_base_release_callback_handler(cb_idx);
-}
-
-/**
- * mpt2sas_base_build_zero_len_sge - build zero length sg entry
- * @ioc: per adapter object
- * @paddr: virtual address for SGE
- *
- * Create a zero length scatter gather entry to insure the IOCs hardware has
- * something to use if the target device goes brain dead and tries
- * to send data even when none is asked for.
- *
- * Return nothing.
- */
-void
-mpt2sas_base_build_zero_len_sge(struct MPT2SAS_ADAPTER *ioc, void *paddr)
-{
-       u32 flags_length = (u32)((MPI2_SGE_FLAGS_LAST_ELEMENT |
-           MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_END_OF_LIST |
-           MPI2_SGE_FLAGS_SIMPLE_ELEMENT) <<
-           MPI2_SGE_FLAGS_SHIFT);
-       ioc->base_add_sg_single(paddr, flags_length, -1);
-}
-
-/**
- * _base_add_sg_single_32 - Place a simple 32 bit SGE at address pAddr.
- * @paddr: virtual address for SGE
- * @flags_length: SGE flags and data transfer length
- * @dma_addr: Physical address
- *
- * Return nothing.
- */
-static void
-_base_add_sg_single_32(void *paddr, u32 flags_length, dma_addr_t dma_addr)
-{
-       Mpi2SGESimple32_t *sgel = paddr;
-
-       flags_length |= (MPI2_SGE_FLAGS_32_BIT_ADDRESSING |
-           MPI2_SGE_FLAGS_SYSTEM_ADDRESS) << MPI2_SGE_FLAGS_SHIFT;
-       sgel->FlagsLength = cpu_to_le32(flags_length);
-       sgel->Address = cpu_to_le32(dma_addr);
-}
-
-
-/**
- * _base_add_sg_single_64 - Place a simple 64 bit SGE at address pAddr.
- * @paddr: virtual address for SGE
- * @flags_length: SGE flags and data transfer length
- * @dma_addr: Physical address
- *
- * Return nothing.
- */
-static void
-_base_add_sg_single_64(void *paddr, u32 flags_length, dma_addr_t dma_addr)
-{
-       Mpi2SGESimple64_t *sgel = paddr;
-
-       flags_length |= (MPI2_SGE_FLAGS_64_BIT_ADDRESSING |
-           MPI2_SGE_FLAGS_SYSTEM_ADDRESS) << MPI2_SGE_FLAGS_SHIFT;
-       sgel->FlagsLength = cpu_to_le32(flags_length);
-       sgel->Address = cpu_to_le64(dma_addr);
-}
-
-#define convert_to_kb(x) ((x) << (PAGE_SHIFT - 10))
-
-/**
- * _base_config_dma_addressing - set dma addressing
- * @ioc: per adapter object
- * @pdev: PCI device struct
- *
- * Returns 0 for success, non-zero for failure.
- */
-static int
-_base_config_dma_addressing(struct MPT2SAS_ADAPTER *ioc, struct pci_dev *pdev)
-{
-       struct sysinfo s;
-       u64 consistent_dma_mask;
-
-       if (ioc->dma_mask)
-               consistent_dma_mask = DMA_BIT_MASK(64);
-       else
-               consistent_dma_mask = DMA_BIT_MASK(32);
-
-       if (sizeof(dma_addr_t) > 4) {
-               const uint64_t required_mask =
-                   dma_get_required_mask(&pdev->dev);
-               if ((required_mask > DMA_BIT_MASK(32)) &&
-                   !pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) &&
-                   !pci_set_consistent_dma_mask(pdev, consistent_dma_mask)) {
-                       ioc->base_add_sg_single = &_base_add_sg_single_64;
-                       ioc->sge_size = sizeof(Mpi2SGESimple64_t);
-                       ioc->dma_mask = 64;
-                       goto out;
-               }
-       }
-
-       if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
-           && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
-               ioc->base_add_sg_single = &_base_add_sg_single_32;
-               ioc->sge_size = sizeof(Mpi2SGESimple32_t);
-               ioc->dma_mask = 32;
-       } else
-               return -ENODEV;
-
- out:
-       si_meminfo(&s);
-       printk(MPT2SAS_INFO_FMT
-           "%d BIT PCI BUS DMA ADDRESSING SUPPORTED, total mem (%ld kB)\n",
-           ioc->name, ioc->dma_mask, convert_to_kb(s.totalram));
-
-       return 0;
-}
-
-static int
-_base_change_consistent_dma_mask(struct MPT2SAS_ADAPTER *ioc,
-                                 struct pci_dev *pdev)
-{
-       if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) {
-               if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)))
-                       return -ENODEV;
-       }
-       return 0;
-}
-/**
- * _base_check_enable_msix - checks MSIX capabable.
- * @ioc: per adapter object
- *
- * Check to see if card is capable of MSIX, and set number
- * of available msix vectors
- */
-static int
-_base_check_enable_msix(struct MPT2SAS_ADAPTER *ioc)
-{
-       int base;
-       u16 message_control;
-
-
-       /* Check whether controller SAS2008 B0 controller,
-          if it is SAS2008 B0 controller use IO-APIC instead of MSIX */
-       if (ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2008 &&
-           ioc->pdev->revision == 0x01) {
-               return -EINVAL;
-       }
-
-       base = pci_find_capability(ioc->pdev, PCI_CAP_ID_MSIX);
-       if (!base) {
-               dfailprintk(ioc, printk(MPT2SAS_INFO_FMT "msix not "
-                   "supported\n", ioc->name));
-               return -EINVAL;
-       }
-
-       /* get msix vector count */
-       /* NUMA_IO not supported for older controllers */
-       if (ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2004 ||
-           ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2008 ||
-           ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2108_1 ||
-           ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2108_2 ||
-           ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2108_3 ||
-           ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2116_1 ||
-           ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2116_2)
-               ioc->msix_vector_count = 1;
-       else {
-               pci_read_config_word(ioc->pdev, base + 2, &message_control);
-               ioc->msix_vector_count = (message_control & 0x3FF) + 1;
-       }
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "msix is supported, "
-           "vector_count(%d)\n", ioc->name, ioc->msix_vector_count));
-
-       return 0;
-}
-
-/**
- * _base_free_irq - free irq
- * @ioc: per adapter object
- *
- * Freeing respective reply_queue from the list.
- */
-static void
-_base_free_irq(struct MPT2SAS_ADAPTER *ioc)
-{
-       struct adapter_reply_queue *reply_q, *next;
-
-       if (list_empty(&ioc->reply_queue_list))
-               return;
-
-       list_for_each_entry_safe(reply_q, next, &ioc->reply_queue_list, list) {
-               list_del(&reply_q->list);
-               irq_set_affinity_hint(reply_q->vector, NULL);
-               free_cpumask_var(reply_q->affinity_hint);
-               synchronize_irq(reply_q->vector);
-               free_irq(reply_q->vector, reply_q);
-               kfree(reply_q);
-       }
-}
-
-/**
- * _base_request_irq - request irq
- * @ioc: per adapter object
- * @index: msix index into vector table
- * @vector: irq vector
- *
- * Inserting respective reply_queue into the list.
- */
-static int
-_base_request_irq(struct MPT2SAS_ADAPTER *ioc, u8 index, u32 vector)
-{
-       struct adapter_reply_queue *reply_q;
-       int r;
-
-       reply_q =  kzalloc(sizeof(struct adapter_reply_queue), GFP_KERNEL);
-       if (!reply_q) {
-               printk(MPT2SAS_ERR_FMT "unable to allocate memory %d!\n",
-                   ioc->name, (int)sizeof(struct adapter_reply_queue));
-               return -ENOMEM;
-       }
-       reply_q->ioc = ioc;
-       reply_q->msix_index = index;
-       reply_q->vector = vector;
-
-       if (!alloc_cpumask_var(&reply_q->affinity_hint, GFP_KERNEL))
-               return -ENOMEM;
-       cpumask_clear(reply_q->affinity_hint);
-
-       atomic_set(&reply_q->busy, 0);
-       if (ioc->msix_enable)
-               snprintf(reply_q->name, MPT_NAME_LENGTH, "%s%d-msix%d",
-                   MPT2SAS_DRIVER_NAME, ioc->id, index);
-       else
-               snprintf(reply_q->name, MPT_NAME_LENGTH, "%s%d",
-                   MPT2SAS_DRIVER_NAME, ioc->id);
-       r = request_irq(vector, _base_interrupt, IRQF_SHARED, reply_q->name,
-           reply_q);
-       if (r) {
-               printk(MPT2SAS_ERR_FMT "unable to allocate interrupt %d!\n",
-                   reply_q->name, vector);
-               kfree(reply_q);
-               return -EBUSY;
-       }
-
-       INIT_LIST_HEAD(&reply_q->list);
-       list_add_tail(&reply_q->list, &ioc->reply_queue_list);
-       return 0;
-}
-
-/**
- * _base_assign_reply_queues - assigning msix index for each cpu
- * @ioc: per adapter object
- *
- * The enduser would need to set the affinity via /proc/irq/#/smp_affinity
- *
- * It would nice if we could call irq_set_affinity, however it is not
- * an exported symbol
- */
-static void
-_base_assign_reply_queues(struct MPT2SAS_ADAPTER *ioc)
-{
-       unsigned int cpu, nr_cpus, nr_msix, index = 0;
-       struct adapter_reply_queue *reply_q;
-
-       if (!_base_is_controller_msix_enabled(ioc))
-               return;
-
-       memset(ioc->cpu_msix_table, 0, ioc->cpu_msix_table_sz);
-
-       nr_cpus = num_online_cpus();
-       nr_msix = ioc->reply_queue_count = min(ioc->reply_queue_count,
-                                              ioc->facts.MaxMSIxVectors);
-       if (!nr_msix)
-               return;
-
-       cpu = cpumask_first(cpu_online_mask);
-
-       list_for_each_entry(reply_q, &ioc->reply_queue_list, list) {
-
-               unsigned int i, group = nr_cpus / nr_msix;
-
-               if (cpu >= nr_cpus)
-                       break;
-
-               if (index < nr_cpus % nr_msix)
-                       group++;
-
-               for (i = 0 ; i < group ; i++) {
-                       ioc->cpu_msix_table[cpu] = index;
-                       cpumask_or(reply_q->affinity_hint,
-                                  reply_q->affinity_hint, get_cpu_mask(cpu));
-                       cpu = cpumask_next(cpu, cpu_online_mask);
-               }
-
-               if (irq_set_affinity_hint(reply_q->vector,
-                                          reply_q->affinity_hint))
-                       dinitprintk(ioc, pr_info(MPT2SAS_FMT
-                           "error setting affinity hint for irq vector %d\n",
-                           ioc->name, reply_q->vector));
-               index++;
-       }
-}
-
-/**
- * _base_disable_msix - disables msix
- * @ioc: per adapter object
- *
- */
-static void
-_base_disable_msix(struct MPT2SAS_ADAPTER *ioc)
-{
-       if (ioc->msix_enable) {
-               pci_disable_msix(ioc->pdev);
-               ioc->msix_enable = 0;
-       }
-}
-
-/**
- * _base_enable_msix - enables msix, failback to io_apic
- * @ioc: per adapter object
- *
- */
-static int
-_base_enable_msix(struct MPT2SAS_ADAPTER *ioc)
-{
-       struct msix_entry *entries, *a;
-       int r;
-       int i;
-       u8 try_msix = 0;
-
-       if (msix_disable == -1 || msix_disable == 0)
-               try_msix = 1;
-
-       if (!try_msix)
-               goto try_ioapic;
-
-       if (_base_check_enable_msix(ioc) != 0)
-               goto try_ioapic;
-
-       ioc->reply_queue_count = min_t(int, ioc->cpu_count,
-           ioc->msix_vector_count);
-
-       if (!ioc->rdpq_array_enable && max_msix_vectors == -1)
-               max_msix_vectors = 8;
-
-       if (max_msix_vectors > 0) {
-               ioc->reply_queue_count = min_t(int, max_msix_vectors,
-                   ioc->reply_queue_count);
-               ioc->msix_vector_count = ioc->reply_queue_count;
-       } else if (max_msix_vectors == 0)
-               goto try_ioapic;
-
-       printk(MPT2SAS_INFO_FMT
-       "MSI-X vectors supported: %d, no of cores: %d, max_msix_vectors: %d\n",
-        ioc->name, ioc->msix_vector_count, ioc->cpu_count, max_msix_vectors);
-
-       entries = kcalloc(ioc->reply_queue_count, sizeof(struct msix_entry),
-           GFP_KERNEL);
-       if (!entries) {
-               dfailprintk(ioc, printk(MPT2SAS_INFO_FMT "kcalloc "
-                   "failed @ at %s:%d/%s() !!!\n", ioc->name, __FILE__,
-                   __LINE__, __func__));
-               goto try_ioapic;
-       }
-
-       for (i = 0, a = entries; i < ioc->reply_queue_count; i++, a++)
-               a->entry = i;
-
-       r = pci_enable_msix_exact(ioc->pdev, entries, ioc->reply_queue_count);
-       if (r) {
-               dfailprintk(ioc, printk(MPT2SAS_INFO_FMT
-                   "pci_enable_msix_exact failed (r=%d) !!!\n", ioc->name, r));
-               kfree(entries);
-               goto try_ioapic;
-       }
-
-       ioc->msix_enable = 1;
-       for (i = 0, a = entries; i < ioc->reply_queue_count; i++, a++) {
-               r = _base_request_irq(ioc, i, a->vector);
-               if (r) {
-                       _base_free_irq(ioc);
-                       _base_disable_msix(ioc);
-                       kfree(entries);
-                       goto try_ioapic;
-               }
-       }
-
-       kfree(entries);
-       return 0;
-
-/* failback to io_apic interrupt routing */
- try_ioapic:
-
-       ioc->reply_queue_count = 1;
-       r = _base_request_irq(ioc, 0, ioc->pdev->irq);
-
-       return r;
-}
-
-/**
- * mpt2sas_base_map_resources - map in controller resources (io/irq/memap)
- * @ioc: per adapter object
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc)
-{
-       struct pci_dev *pdev = ioc->pdev;
-       u32 memap_sz;
-       u32 pio_sz;
-       int i, r = 0;
-       u64 pio_chip = 0;
-       u64 chip_phys = 0;
-       struct adapter_reply_queue *reply_q;
-
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n",
-           ioc->name, __func__));
-
-       ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
-       if (pci_enable_device_mem(pdev)) {
-               printk(MPT2SAS_WARN_FMT "pci_enable_device_mem: "
-                   "failed\n", ioc->name);
-               ioc->bars = 0;
-               return -ENODEV;
-       }
-
-
-       if (pci_request_selected_regions(pdev, ioc->bars,
-           MPT2SAS_DRIVER_NAME)) {
-               printk(MPT2SAS_WARN_FMT "pci_request_selected_regions: "
-                   "failed\n", ioc->name);
-               ioc->bars = 0;
-               r = -ENODEV;
-               goto out_fail;
-       }
-
-       /* AER (Advanced Error Reporting) hooks */
-       pci_enable_pcie_error_reporting(pdev);
-
-       pci_set_master(pdev);
-
-       if (_base_config_dma_addressing(ioc, pdev) != 0) {
-               printk(MPT2SAS_WARN_FMT "no suitable DMA mask for %s\n",
-                   ioc->name, pci_name(pdev));
-               r = -ENODEV;
-               goto out_fail;
-       }
-
-       for (i = 0, memap_sz = 0, pio_sz = 0; (i < DEVICE_COUNT_RESOURCE) &&
-            (!memap_sz || !pio_sz); i++) {
-               if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
-                       if (pio_sz)
-                               continue;
-                       pio_chip = (u64)pci_resource_start(pdev, i);
-                       pio_sz = pci_resource_len(pdev, i);
-               } else {
-                       if (memap_sz)
-                               continue;
-                       /* verify memory resource is valid before using */
-                       if (pci_resource_flags(pdev, i) & IORESOURCE_MEM) {
-                               ioc->chip_phys = pci_resource_start(pdev, i);
-                               chip_phys = (u64)ioc->chip_phys;
-                               memap_sz = pci_resource_len(pdev, i);
-                               ioc->chip = ioremap(ioc->chip_phys, memap_sz);
-                       }
-               }
-       }
-
-       if (ioc->chip == NULL) {
-               printk(MPT2SAS_ERR_FMT "unable to map adapter memory! "
-                      "or resource not found\n", ioc->name);
-               r = -EINVAL;
-               goto out_fail;
-       }
-
-       _base_mask_interrupts(ioc);
-
-       r = _base_get_ioc_facts(ioc, CAN_SLEEP);
-       if (r)
-               goto out_fail;
-
-       if (!ioc->rdpq_array_enable_assigned) {
-               ioc->rdpq_array_enable = ioc->rdpq_array_capable;
-               ioc->rdpq_array_enable_assigned = 1;
-       }
-
-       r = _base_enable_msix(ioc);
-       if (r)
-               goto out_fail;
-
-       list_for_each_entry(reply_q, &ioc->reply_queue_list, list)
-               printk(MPT2SAS_INFO_FMT "%s: IRQ %d\n",
-                   reply_q->name,  ((ioc->msix_enable) ? "PCI-MSI-X enabled" :
-                   "IO-APIC enabled"), reply_q->vector);
-
-       printk(MPT2SAS_INFO_FMT "iomem(0x%016llx), mapped(0x%p), size(%d)\n",
-           ioc->name, (unsigned long long)chip_phys, ioc->chip, memap_sz);
-       printk(MPT2SAS_INFO_FMT "ioport(0x%016llx), size(%d)\n",
-           ioc->name, (unsigned long long)pio_chip, pio_sz);
-
-       /* Save PCI configuration state for recovery from PCI AER/EEH errors */
-       pci_save_state(pdev);
-
-       return 0;
-
- out_fail:
-       if (ioc->chip_phys)
-               iounmap(ioc->chip);
-       ioc->chip_phys = 0;
-       pci_release_selected_regions(ioc->pdev, ioc->bars);
-       pci_disable_pcie_error_reporting(pdev);
-       pci_disable_device(pdev);
-       return r;
-}
-
-/**
- * mpt2sas_base_get_msg_frame - obtain request mf pointer
- * @ioc: per adapter object
- * @smid: system request message index(smid zero is invalid)
- *
- * Returns virt pointer to message frame.
- */
-void *
-mpt2sas_base_get_msg_frame(struct MPT2SAS_ADAPTER *ioc, u16 smid)
-{
-       return (void *)(ioc->request + (smid * ioc->request_sz));
-}
-
-/**
- * mpt2sas_base_get_sense_buffer - obtain a sense buffer assigned to a mf request
- * @ioc: per adapter object
- * @smid: system request message index
- *
- * Returns virt pointer to sense buffer.
- */
-void *
-mpt2sas_base_get_sense_buffer(struct MPT2SAS_ADAPTER *ioc, u16 smid)
-{
-       return (void *)(ioc->sense + ((smid - 1) * SCSI_SENSE_BUFFERSIZE));
-}
-
-/**
- * mpt2sas_base_get_sense_buffer_dma - obtain a sense buffer assigned to a mf request
- * @ioc: per adapter object
- * @smid: system request message index
- *
- * Returns phys pointer to the low 32bit address of the sense buffer.
- */
-__le32
-mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc, u16 smid)
-{
-       return cpu_to_le32(ioc->sense_dma +
-                       ((smid - 1) * SCSI_SENSE_BUFFERSIZE));
-}
-
-/**
- * mpt2sas_base_get_reply_virt_addr - obtain reply frames virt address
- * @ioc: per adapter object
- * @phys_addr: lower 32 physical addr of the reply
- *
- * Converts 32bit lower physical addr into a virt address.
- */
-void *
-mpt2sas_base_get_reply_virt_addr(struct MPT2SAS_ADAPTER *ioc, u32 phys_addr)
-{
-       if (!phys_addr)
-               return NULL;
-       return ioc->reply + (phys_addr - (u32)ioc->reply_dma);
-}
-
-/**
- * mpt2sas_base_get_smid - obtain a free smid from internal queue
- * @ioc: per adapter object
- * @cb_idx: callback index
- *
- * Returns smid (zero is invalid)
- */
-u16
-mpt2sas_base_get_smid(struct MPT2SAS_ADAPTER *ioc, u8 cb_idx)
-{
-       unsigned long flags;
-       struct request_tracker *request;
-       u16 smid;
-
-       spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-       if (list_empty(&ioc->internal_free_list)) {
-               spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
-               printk(MPT2SAS_ERR_FMT "%s: smid not available\n",
-                   ioc->name, __func__);
-               return 0;
-       }
-
-       request = list_entry(ioc->internal_free_list.next,
-           struct request_tracker, tracker_list);
-       request->cb_idx = cb_idx;
-       smid = request->smid;
-       list_del(&request->tracker_list);
-       spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
-       return smid;
-}
-
-/**
- * mpt2sas_base_get_smid_scsiio - obtain a free smid from scsiio queue
- * @ioc: per adapter object
- * @cb_idx: callback index
- * @scmd: pointer to scsi command object
- *
- * Returns smid (zero is invalid)
- */
-u16
-mpt2sas_base_get_smid_scsiio(struct MPT2SAS_ADAPTER *ioc, u8 cb_idx,
-    struct scsi_cmnd *scmd)
-{
-       unsigned long flags;
-       struct scsiio_tracker *request;
-       u16 smid;
-
-       spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-       if (list_empty(&ioc->free_list)) {
-               spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
-               printk(MPT2SAS_ERR_FMT "%s: smid not available\n",
-                   ioc->name, __func__);
-               return 0;
-       }
-
-       request = list_entry(ioc->free_list.next,
-           struct scsiio_tracker, tracker_list);
-       request->scmd = scmd;
-       request->cb_idx = cb_idx;
-       smid = request->smid;
-       list_del(&request->tracker_list);
-       spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
-       return smid;
-}
-
-/**
- * mpt2sas_base_get_smid_hpr - obtain a free smid from hi-priority queue
- * @ioc: per adapter object
- * @cb_idx: callback index
- *
- * Returns smid (zero is invalid)
- */
-u16
-mpt2sas_base_get_smid_hpr(struct MPT2SAS_ADAPTER *ioc, u8 cb_idx)
-{
-       unsigned long flags;
-       struct request_tracker *request;
-       u16 smid;
-
-       spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-       if (list_empty(&ioc->hpr_free_list)) {
-               spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
-               return 0;
-       }
-
-       request = list_entry(ioc->hpr_free_list.next,
-           struct request_tracker, tracker_list);
-       request->cb_idx = cb_idx;
-       smid = request->smid;
-       list_del(&request->tracker_list);
-       spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
-       return smid;
-}
-
-
-/**
- * mpt2sas_base_free_smid - put smid back on free_list
- * @ioc: per adapter object
- * @smid: system request message index
- *
- * Return nothing.
- */
-void
-mpt2sas_base_free_smid(struct MPT2SAS_ADAPTER *ioc, u16 smid)
-{
-       unsigned long flags;
-       int i;
-       struct chain_tracker *chain_req, *next;
-
-       spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-       if (smid < ioc->hi_priority_smid) {
-               /* scsiio queue */
-               i = smid - 1;
-               if (!list_empty(&ioc->scsi_lookup[i].chain_list)) {
-                       list_for_each_entry_safe(chain_req, next,
-                           &ioc->scsi_lookup[i].chain_list, tracker_list) {
-                               list_del_init(&chain_req->tracker_list);
-                               list_add(&chain_req->tracker_list,
-                                   &ioc->free_chain_list);
-                       }
-               }
-               ioc->scsi_lookup[i].cb_idx = 0xFF;
-               ioc->scsi_lookup[i].scmd = NULL;
-               ioc->scsi_lookup[i].direct_io = 0;
-               list_add(&ioc->scsi_lookup[i].tracker_list,
-                   &ioc->free_list);
-               spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
-
-               /*
-                * See _wait_for_commands_to_complete() call with regards
-                * to this code.
-                */
-               if (ioc->shost_recovery && ioc->pending_io_count) {
-                       if (ioc->pending_io_count == 1)
-                               wake_up(&ioc->reset_wq);
-                       ioc->pending_io_count--;
-               }
-               return;
-       } else if (smid < ioc->internal_smid) {
-               /* hi-priority */
-               i = smid - ioc->hi_priority_smid;
-               ioc->hpr_lookup[i].cb_idx = 0xFF;
-               list_add(&ioc->hpr_lookup[i].tracker_list,
-                   &ioc->hpr_free_list);
-       } else if (smid <= ioc->hba_queue_depth) {
-               /* internal queue */
-               i = smid - ioc->internal_smid;
-               ioc->internal_lookup[i].cb_idx = 0xFF;
-               list_add(&ioc->internal_lookup[i].tracker_list,
-                   &ioc->internal_free_list);
-       }
-       spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
-}
-
-/**
- * _base_writeq - 64 bit write to MMIO
- * @ioc: per adapter object
- * @b: data payload
- * @addr: address in MMIO space
- * @writeq_lock: spin lock
- *
- * Glue for handling an atomic 64 bit word to MMIO. This special handling takes
- * care of 32 bit environment where its not quarenteed to send the entire word
- * in one transfer.
- */
-#ifndef writeq
-static inline void _base_writeq(__u64 b, volatile void __iomem *addr,
-    spinlock_t *writeq_lock)
-{
-       unsigned long flags;
-       __u64 data_out = cpu_to_le64(b);
-
-       spin_lock_irqsave(writeq_lock, flags);
-       writel((u32)(data_out), addr);
-       writel((u32)(data_out >> 32), (addr + 4));
-       spin_unlock_irqrestore(writeq_lock, flags);
-}
-#else
-static inline void _base_writeq(__u64 b, volatile void __iomem *addr,
-    spinlock_t *writeq_lock)
-{
-       writeq(cpu_to_le64(b), addr);
-}
-#endif
-
-static inline u8
-_base_get_msix_index(struct MPT2SAS_ADAPTER *ioc)
-{
-       return ioc->cpu_msix_table[raw_smp_processor_id()];
-}
-
-/**
- * mpt2sas_base_put_smid_scsi_io - send SCSI_IO request to firmware
- * @ioc: per adapter object
- * @smid: system request message index
- * @handle: device handle
- *
- * Return nothing.
- */
-void
-mpt2sas_base_put_smid_scsi_io(struct MPT2SAS_ADAPTER *ioc, u16 smid, u16 handle)
-{
-       Mpi2RequestDescriptorUnion_t descriptor;
-       u64 *request = (u64 *)&descriptor;
-
-
-       descriptor.SCSIIO.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
-       descriptor.SCSIIO.MSIxIndex =  _base_get_msix_index(ioc);
-       descriptor.SCSIIO.SMID = cpu_to_le16(smid);
-       descriptor.SCSIIO.DevHandle = cpu_to_le16(handle);
-       descriptor.SCSIIO.LMID = 0;
-       _base_writeq(*request, &ioc->chip->RequestDescriptorPostLow,
-           &ioc->scsi_lookup_lock);
-}
-
-
-/**
- * mpt2sas_base_put_smid_hi_priority - send Task Management request to firmware
- * @ioc: per adapter object
- * @smid: system request message index
- *
- * Return nothing.
- */
-void
-mpt2sas_base_put_smid_hi_priority(struct MPT2SAS_ADAPTER *ioc, u16 smid)
-{
-       Mpi2RequestDescriptorUnion_t descriptor;
-       u64 *request = (u64 *)&descriptor;
-
-       descriptor.HighPriority.RequestFlags =
-           MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY;
-       descriptor.HighPriority.MSIxIndex =  0;
-       descriptor.HighPriority.SMID = cpu_to_le16(smid);
-       descriptor.HighPriority.LMID = 0;
-       descriptor.HighPriority.Reserved1 = 0;
-       _base_writeq(*request, &ioc->chip->RequestDescriptorPostLow,
-           &ioc->scsi_lookup_lock);
-}
-
-/**
- * mpt2sas_base_put_smid_default - Default, primarily used for config pages
- * @ioc: per adapter object
- * @smid: system request message index
- *
- * Return nothing.
- */
-void
-mpt2sas_base_put_smid_default(struct MPT2SAS_ADAPTER *ioc, u16 smid)
-{
-       Mpi2RequestDescriptorUnion_t descriptor;
-       u64 *request = (u64 *)&descriptor;
-
-       descriptor.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
-       descriptor.Default.MSIxIndex =  _base_get_msix_index(ioc);
-       descriptor.Default.SMID = cpu_to_le16(smid);
-       descriptor.Default.LMID = 0;
-       descriptor.Default.DescriptorTypeDependent = 0;
-       _base_writeq(*request, &ioc->chip->RequestDescriptorPostLow,
-           &ioc->scsi_lookup_lock);
-}
-
-/**
- * mpt2sas_base_put_smid_target_assist - send Target Assist/Status to firmware
- * @ioc: per adapter object
- * @smid: system request message index
- * @io_index: value used to track the IO
- *
- * Return nothing.
- */
-void
-mpt2sas_base_put_smid_target_assist(struct MPT2SAS_ADAPTER *ioc, u16 smid,
-    u16 io_index)
-{
-       Mpi2RequestDescriptorUnion_t descriptor;
-       u64 *request = (u64 *)&descriptor;
-
-       descriptor.SCSITarget.RequestFlags =
-           MPI2_REQ_DESCRIPT_FLAGS_SCSI_TARGET;
-       descriptor.SCSITarget.MSIxIndex =  _base_get_msix_index(ioc);
-       descriptor.SCSITarget.SMID = cpu_to_le16(smid);
-       descriptor.SCSITarget.LMID = 0;
-       descriptor.SCSITarget.IoIndex = cpu_to_le16(io_index);
-       _base_writeq(*request, &ioc->chip->RequestDescriptorPostLow,
-           &ioc->scsi_lookup_lock);
-}
-
-/**
- * _base_display_dell_branding - Disply branding string
- * @ioc: per adapter object
- *
- * Return nothing.
- */
-static void
-_base_display_dell_branding(struct MPT2SAS_ADAPTER *ioc)
-{
-       char dell_branding[MPT2SAS_DELL_BRANDING_SIZE];
-
-       if (ioc->pdev->subsystem_vendor != PCI_VENDOR_ID_DELL)
-               return;
-
-       memset(dell_branding, 0, MPT2SAS_DELL_BRANDING_SIZE);
-       switch (ioc->pdev->subsystem_device) {
-       case MPT2SAS_DELL_6GBPS_SAS_HBA_SSDID:
-               strncpy(dell_branding, MPT2SAS_DELL_6GBPS_SAS_HBA_BRANDING,
-                   MPT2SAS_DELL_BRANDING_SIZE - 1);
-               break;
-       case MPT2SAS_DELL_PERC_H200_ADAPTER_SSDID:
-               strncpy(dell_branding, MPT2SAS_DELL_PERC_H200_ADAPTER_BRANDING,
-                   MPT2SAS_DELL_BRANDING_SIZE - 1);
-               break;
-       case MPT2SAS_DELL_PERC_H200_INTEGRATED_SSDID:
-               strncpy(dell_branding,
-                   MPT2SAS_DELL_PERC_H200_INTEGRATED_BRANDING,
-                   MPT2SAS_DELL_BRANDING_SIZE - 1);
-               break;
-       case MPT2SAS_DELL_PERC_H200_MODULAR_SSDID:
-               strncpy(dell_branding,
-                   MPT2SAS_DELL_PERC_H200_MODULAR_BRANDING,
-                   MPT2SAS_DELL_BRANDING_SIZE - 1);
-               break;
-       case MPT2SAS_DELL_PERC_H200_EMBEDDED_SSDID:
-               strncpy(dell_branding,
-                   MPT2SAS_DELL_PERC_H200_EMBEDDED_BRANDING,
-                   MPT2SAS_DELL_BRANDING_SIZE - 1);
-               break;
-       case MPT2SAS_DELL_PERC_H200_SSDID:
-               strncpy(dell_branding, MPT2SAS_DELL_PERC_H200_BRANDING,
-                   MPT2SAS_DELL_BRANDING_SIZE - 1);
-               break;
-       case MPT2SAS_DELL_6GBPS_SAS_SSDID:
-               strncpy(dell_branding, MPT2SAS_DELL_6GBPS_SAS_BRANDING,
-                   MPT2SAS_DELL_BRANDING_SIZE - 1);
-               break;
-       default:
-               sprintf(dell_branding, "0x%4X", ioc->pdev->subsystem_device);
-               break;
-       }
-
-       printk(MPT2SAS_INFO_FMT "%s: Vendor(0x%04X), Device(0x%04X),"
-           " SSVID(0x%04X), SSDID(0x%04X)\n", ioc->name, dell_branding,
-           ioc->pdev->vendor, ioc->pdev->device, ioc->pdev->subsystem_vendor,
-           ioc->pdev->subsystem_device);
-}
-
-/**
- * _base_display_intel_branding - Display branding string
- * @ioc: per adapter object
- *
- * Return nothing.
- */
-static void
-_base_display_intel_branding(struct MPT2SAS_ADAPTER *ioc)
-{
-       if (ioc->pdev->subsystem_vendor != PCI_VENDOR_ID_INTEL)
-               return;
-
-       switch (ioc->pdev->device) {
-       case MPI2_MFGPAGE_DEVID_SAS2008:
-               switch (ioc->pdev->subsystem_device) {
-               case MPT2SAS_INTEL_RMS2LL080_SSDID:
-                       printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-                           MPT2SAS_INTEL_RMS2LL080_BRANDING);
-                       break;
-               case MPT2SAS_INTEL_RMS2LL040_SSDID:
-                       printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-                           MPT2SAS_INTEL_RMS2LL040_BRANDING);
-                       break;
-               case MPT2SAS_INTEL_SSD910_SSDID:
-                       printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-                           MPT2SAS_INTEL_SSD910_BRANDING);
-                       break;
-               default:
-                       break;
-               }
-       case MPI2_MFGPAGE_DEVID_SAS2308_2:
-               switch (ioc->pdev->subsystem_device) {
-               case MPT2SAS_INTEL_RS25GB008_SSDID:
-                       printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-                           MPT2SAS_INTEL_RS25GB008_BRANDING);
-                       break;
-               case MPT2SAS_INTEL_RMS25JB080_SSDID:
-                       printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-                           MPT2SAS_INTEL_RMS25JB080_BRANDING);
-                       break;
-               case MPT2SAS_INTEL_RMS25JB040_SSDID:
-                       printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-                           MPT2SAS_INTEL_RMS25JB040_BRANDING);
-                       break;
-               case MPT2SAS_INTEL_RMS25KB080_SSDID:
-                       printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-                           MPT2SAS_INTEL_RMS25KB080_BRANDING);
-                       break;
-               case MPT2SAS_INTEL_RMS25KB040_SSDID:
-                       printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-                           MPT2SAS_INTEL_RMS25KB040_BRANDING);
-                       break;
-               case MPT2SAS_INTEL_RMS25LB040_SSDID:
-                       printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-                           MPT2SAS_INTEL_RMS25LB040_BRANDING);
-                       break;
-               case MPT2SAS_INTEL_RMS25LB080_SSDID:
-                       printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-                           MPT2SAS_INTEL_RMS25LB080_BRANDING);
-                       break;
-               default:
-                       break;
-               }
-       default:
-               break;
-       }
-}
-
-/**
- * _base_display_hp_branding - Display branding string
- * @ioc: per adapter object
- *
- * Return nothing.
- */
-static void
-_base_display_hp_branding(struct MPT2SAS_ADAPTER *ioc)
-{
-       if (ioc->pdev->subsystem_vendor != MPT2SAS_HP_3PAR_SSVID)
-               return;
-
-       switch (ioc->pdev->device) {
-       case MPI2_MFGPAGE_DEVID_SAS2004:
-               switch (ioc->pdev->subsystem_device) {
-               case MPT2SAS_HP_DAUGHTER_2_4_INTERNAL_SSDID:
-                       printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-                           MPT2SAS_HP_DAUGHTER_2_4_INTERNAL_BRANDING);
-                       break;
-               default:
-                       break;
-               }
-       case MPI2_MFGPAGE_DEVID_SAS2308_2:
-               switch (ioc->pdev->subsystem_device) {
-               case MPT2SAS_HP_2_4_INTERNAL_SSDID:
-                       printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-                           MPT2SAS_HP_2_4_INTERNAL_BRANDING);
-                       break;
-               case MPT2SAS_HP_2_4_EXTERNAL_SSDID:
-                       printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-                           MPT2SAS_HP_2_4_EXTERNAL_BRANDING);
-                       break;
-               case MPT2SAS_HP_1_4_INTERNAL_1_4_EXTERNAL_SSDID:
-                       printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-                           MPT2SAS_HP_1_4_INTERNAL_1_4_EXTERNAL_BRANDING);
-                       break;
-               case MPT2SAS_HP_EMBEDDED_2_4_INTERNAL_SSDID:
-                       printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-                           MPT2SAS_HP_EMBEDDED_2_4_INTERNAL_BRANDING);
-                       break;
-               default:
-                       break;
-               }
-       default:
-               break;
-       }
-}
-
-/**
- * _base_display_ioc_capabilities - Disply IOC's capabilities.
- * @ioc: per adapter object
- *
- * Return nothing.
- */
-static void
-_base_display_ioc_capabilities(struct MPT2SAS_ADAPTER *ioc)
-{
-       int i = 0;
-       char desc[16];
-       u32 iounit_pg1_flags;
-       u32 bios_version;
-
-       bios_version = le32_to_cpu(ioc->bios_pg3.BiosVersion);
-       strncpy(desc, ioc->manu_pg0.ChipName, 16);
-       printk(MPT2SAS_INFO_FMT "%s: FWVersion(%02d.%02d.%02d.%02d), "
-          "ChipRevision(0x%02x), BiosVersion(%02d.%02d.%02d.%02d)\n",
-           ioc->name, desc,
-          (ioc->facts.FWVersion.Word & 0xFF000000) >> 24,
-          (ioc->facts.FWVersion.Word & 0x00FF0000) >> 16,
-          (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8,
-          ioc->facts.FWVersion.Word & 0x000000FF,
-          ioc->pdev->revision,
-          (bios_version & 0xFF000000) >> 24,
-          (bios_version & 0x00FF0000) >> 16,
-          (bios_version & 0x0000FF00) >> 8,
-           bios_version & 0x000000FF);
-
-       _base_display_dell_branding(ioc);
-       _base_display_intel_branding(ioc);
-       _base_display_hp_branding(ioc);
-
-       printk(MPT2SAS_INFO_FMT "Protocol=(", ioc->name);
-
-       if (ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR) {
-               printk("Initiator");
-               i++;
-       }
-
-       if (ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_SCSI_TARGET) {
-               printk("%sTarget", i ? "," : "");
-               i++;
-       }
-
-       i = 0;
-       printk("), ");
-       printk("Capabilities=(");
-
-       if (!ioc->hide_ir_msg) {
-               if (ioc->facts.IOCCapabilities &
-                   MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID) {
-                       printk("Raid");
-                       i++;
-               }
-       }
-
-       if (ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR) {
-               printk("%sTLR", i ? "," : "");
-               i++;
-       }
-
-       if (ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_MULTICAST) {
-               printk("%sMulticast", i ? "," : "");
-               i++;
-       }
-
-       if (ioc->facts.IOCCapabilities &
-           MPI2_IOCFACTS_CAPABILITY_BIDIRECTIONAL_TARGET) {
-               printk("%sBIDI Target", i ? "," : "");
-               i++;
-       }
-
-       if (ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_EEDP) {
-               printk("%sEEDP", i ? "," : "");
-               i++;
-       }
-
-       if (ioc->facts.IOCCapabilities &
-           MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER) {
-               printk("%sSnapshot Buffer", i ? "," : "");
-               i++;
-       }
-
-       if (ioc->facts.IOCCapabilities &
-           MPI2_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER) {
-               printk("%sDiag Trace Buffer", i ? "," : "");
-               i++;
-       }
-
-       if (ioc->facts.IOCCapabilities &
-           MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER) {
-               printk(KERN_INFO "%sDiag Extended Buffer", i ? "," : "");
-               i++;
-       }
-
-       if (ioc->facts.IOCCapabilities &
-           MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING) {
-               printk("%sTask Set Full", i ? "," : "");
-               i++;
-       }
-
-       iounit_pg1_flags = le32_to_cpu(ioc->iounit_pg1.Flags);
-       if (!(iounit_pg1_flags & MPI2_IOUNITPAGE1_NATIVE_COMMAND_Q_DISABLE)) {
-               printk("%sNCQ", i ? "," : "");
-               i++;
-       }
-
-       printk(")\n");
-}
-
-/**
- * mpt2sas_base_update_missing_delay - change the missing delay timers
- * @ioc: per adapter object
- * @device_missing_delay: amount of time till device is reported missing
- * @io_missing_delay: interval IO is returned when there is a missing device
- *
- * Return nothing.
- *
- * Passed on the command line, this function will modify the device missing
- * delay, as well as the io missing delay. This should be called at driver
- * load time.
- */
-void
-mpt2sas_base_update_missing_delay(struct MPT2SAS_ADAPTER *ioc,
-       u16 device_missing_delay, u8 io_missing_delay)
-{
-       u16 dmd, dmd_new, dmd_orignal;
-       u8 io_missing_delay_original;
-       u16 sz;
-       Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
-       Mpi2ConfigReply_t mpi_reply;
-       u8 num_phys = 0;
-       u16 ioc_status;
-
-       mpt2sas_config_get_number_hba_phys(ioc, &num_phys);
-       if (!num_phys)
-               return;
-
-       sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (num_phys *
-           sizeof(Mpi2SasIOUnit1PhyData_t));
-       sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
-       if (!sas_iounit_pg1) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               goto out;
-       }
-       if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply,
-           sas_iounit_pg1, sz))) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               goto out;
-       }
-       ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-           MPI2_IOCSTATUS_MASK;
-       if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               goto out;
-       }
-
-       /* device missing delay */
-       dmd = sas_iounit_pg1->ReportDeviceMissingDelay;
-       if (dmd & MPI2_SASIOUNIT1_REPORT_MISSING_UNIT_16)
-               dmd = (dmd & MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16;
-       else
-               dmd = dmd & MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
-       dmd_orignal = dmd;
-       if (device_missing_delay > 0x7F) {
-               dmd = (device_missing_delay > 0x7F0) ? 0x7F0 :
-                   device_missing_delay;
-               dmd = dmd / 16;
-               dmd |= MPI2_SASIOUNIT1_REPORT_MISSING_UNIT_16;
-       } else
-               dmd = device_missing_delay;
-       sas_iounit_pg1->ReportDeviceMissingDelay = dmd;
-
-       /* io missing delay */
-       io_missing_delay_original = sas_iounit_pg1->IODeviceMissingDelay;
-       sas_iounit_pg1->IODeviceMissingDelay = io_missing_delay;
-
-       if (!mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1,
-           sz)) {
-               if (dmd & MPI2_SASIOUNIT1_REPORT_MISSING_UNIT_16)
-                       dmd_new = (dmd &
-                           MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16;
-               else
-                       dmd_new =
-                   dmd & MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
-               printk(MPT2SAS_INFO_FMT "device_missing_delay: old(%d), "
-                   "new(%d)\n", ioc->name, dmd_orignal, dmd_new);
-               printk(MPT2SAS_INFO_FMT "ioc_missing_delay: old(%d), "
-                   "new(%d)\n", ioc->name, io_missing_delay_original,
-                   io_missing_delay);
-               ioc->device_missing_delay = dmd_new;
-               ioc->io_missing_delay = io_missing_delay;
-       }
-
-out:
-       kfree(sas_iounit_pg1);
-}
-
-/**
- * _base_static_config_pages - static start of day config pages
- * @ioc: per adapter object
- *
- * Return nothing.
- */
-static void
-_base_static_config_pages(struct MPT2SAS_ADAPTER *ioc)
-{
-       Mpi2ConfigReply_t mpi_reply;
-       u32 iounit_pg1_flags;
-
-       mpt2sas_config_get_manufacturing_pg0(ioc, &mpi_reply, &ioc->manu_pg0);
-       if (ioc->ir_firmware)
-               mpt2sas_config_get_manufacturing_pg10(ioc, &mpi_reply,
-                   &ioc->manu_pg10);
-       mpt2sas_config_get_bios_pg2(ioc, &mpi_reply, &ioc->bios_pg2);
-       mpt2sas_config_get_bios_pg3(ioc, &mpi_reply, &ioc->bios_pg3);
-       mpt2sas_config_get_ioc_pg8(ioc, &mpi_reply, &ioc->ioc_pg8);
-       mpt2sas_config_get_iounit_pg0(ioc, &mpi_reply, &ioc->iounit_pg0);
-       mpt2sas_config_get_iounit_pg1(ioc, &mpi_reply, &ioc->iounit_pg1);
-       mpt2sas_config_get_iounit_pg8(ioc, &mpi_reply, &ioc->iounit_pg8);
-       _base_display_ioc_capabilities(ioc);
-
-       /*
-        * Enable task_set_full handling in iounit_pg1 when the
-        * facts capabilities indicate that its supported.
-        */
-       iounit_pg1_flags = le32_to_cpu(ioc->iounit_pg1.Flags);
-       if ((ioc->facts.IOCCapabilities &
-           MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING))
-               iounit_pg1_flags &=
-                   ~MPI2_IOUNITPAGE1_DISABLE_TASK_SET_FULL_HANDLING;
-       else
-               iounit_pg1_flags |=
-                   MPI2_IOUNITPAGE1_DISABLE_TASK_SET_FULL_HANDLING;
-       ioc->iounit_pg1.Flags = cpu_to_le32(iounit_pg1_flags);
-       mpt2sas_config_set_iounit_pg1(ioc, &mpi_reply, &ioc->iounit_pg1);
-
-       if (ioc->iounit_pg8.NumSensors)
-               ioc->temp_sensors_count = ioc->iounit_pg8.NumSensors;
-}
-
-/**
- * _base_release_memory_pools - release memory
- * @ioc: per adapter object
- *
- * Free memory allocated from _base_allocate_memory_pools.
- *
- * Return nothing.
- */
-static void
-_base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc)
-{
-       int i = 0;
-       struct reply_post_struct *rps;
-
-       dexitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-           __func__));
-
-       if (ioc->request) {
-               pci_free_consistent(ioc->pdev, ioc->request_dma_sz,
-                   ioc->request,  ioc->request_dma);
-               dexitprintk(ioc, printk(MPT2SAS_INFO_FMT "request_pool(0x%p)"
-                   ": free\n", ioc->name, ioc->request));
-               ioc->request = NULL;
-       }
-
-       if (ioc->sense) {
-               pci_pool_free(ioc->sense_dma_pool, ioc->sense, ioc->sense_dma);
-               if (ioc->sense_dma_pool)
-                       pci_pool_destroy(ioc->sense_dma_pool);
-               dexitprintk(ioc, printk(MPT2SAS_INFO_FMT "sense_pool(0x%p)"
-                   ": free\n", ioc->name, ioc->sense));
-               ioc->sense = NULL;
-       }
-
-       if (ioc->reply) {
-               pci_pool_free(ioc->reply_dma_pool, ioc->reply, ioc->reply_dma);
-               if (ioc->reply_dma_pool)
-                       pci_pool_destroy(ioc->reply_dma_pool);
-               dexitprintk(ioc, printk(MPT2SAS_INFO_FMT "reply_pool(0x%p)"
-                    ": free\n", ioc->name, ioc->reply));
-               ioc->reply = NULL;
-       }
-
-       if (ioc->reply_free) {
-               pci_pool_free(ioc->reply_free_dma_pool, ioc->reply_free,
-                   ioc->reply_free_dma);
-               if (ioc->reply_free_dma_pool)
-                       pci_pool_destroy(ioc->reply_free_dma_pool);
-               dexitprintk(ioc, printk(MPT2SAS_INFO_FMT "reply_free_pool"
-                   "(0x%p): free\n", ioc->name, ioc->reply_free));
-               ioc->reply_free = NULL;
-       }
-
-       if (ioc->reply_post) {
-               do {
-                       rps = &ioc->reply_post[i];
-                       if (rps->reply_post_free) {
-                               pci_pool_free(
-                                   ioc->reply_post_free_dma_pool,
-                                   rps->reply_post_free,
-                                   rps->reply_post_free_dma);
-                               dexitprintk(ioc, printk(MPT2SAS_INFO_FMT
-                                   "reply_post_free_pool(0x%p): free\n",
-                                   ioc->name, rps->reply_post_free));
-                               rps->reply_post_free = NULL;
-                       }
-               } while (ioc->rdpq_array_enable &&
-                          (++i < ioc->reply_queue_count));
-
-               if (ioc->reply_post_free_dma_pool)
-                       pci_pool_destroy(ioc->reply_post_free_dma_pool);
-               kfree(ioc->reply_post);
-       }
-
-       if (ioc->config_page) {
-               dexitprintk(ioc, printk(MPT2SAS_INFO_FMT
-                   "config_page(0x%p): free\n", ioc->name,
-                   ioc->config_page));
-               pci_free_consistent(ioc->pdev, ioc->config_page_sz,
-                   ioc->config_page, ioc->config_page_dma);
-       }
-
-       if (ioc->scsi_lookup) {
-               free_pages((ulong)ioc->scsi_lookup, ioc->scsi_lookup_pages);
-               ioc->scsi_lookup = NULL;
-       }
-       kfree(ioc->hpr_lookup);
-       kfree(ioc->internal_lookup);
-       if (ioc->chain_lookup) {
-               for (i = 0; i < ioc->chain_depth; i++) {
-                       if (ioc->chain_lookup[i].chain_buffer)
-                               pci_pool_free(ioc->chain_dma_pool,
-                                   ioc->chain_lookup[i].chain_buffer,
-                                   ioc->chain_lookup[i].chain_buffer_dma);
-               }
-               if (ioc->chain_dma_pool)
-                       pci_pool_destroy(ioc->chain_dma_pool);
-               free_pages((ulong)ioc->chain_lookup, ioc->chain_pages);
-               ioc->chain_lookup = NULL;
-       }
-}
-
-
-/**
- * _base_allocate_memory_pools - allocate start of day memory pools
- * @ioc: per adapter object
- * @sleep_flag: CAN_SLEEP or NO_SLEEP
- *
- * Returns 0 success, anything else error
- */
-static int
-_base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc,  int sleep_flag)
-{
-       struct mpt2sas_facts *facts;
-       u16 max_sge_elements;
-       u16 chains_needed_per_io;
-       u32 sz, total_sz, reply_post_free_sz;
-       u32 retry_sz;
-       u16 max_request_credit;
-       int i;
-
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-           __func__));
-
-       retry_sz = 0;
-       facts = &ioc->facts;
-
-       /* command line tunables  for max sgl entries */
-       if (max_sgl_entries != -1) {
-               ioc->shost->sg_tablesize =  min_t(unsigned short,
-                            max_sgl_entries, SCSI_MAX_SG_CHAIN_SEGMENTS);
-               if (ioc->shost->sg_tablesize > MPT2SAS_SG_DEPTH)
-                       printk(MPT2SAS_WARN_FMT
-                        "sg_tablesize(%u) is bigger than kernel defined"
-                        " SCSI_MAX_SG_SEGMENTS(%u)\n", ioc->name,
-                         ioc->shost->sg_tablesize, MPT2SAS_SG_DEPTH);
-       } else {
-               ioc->shost->sg_tablesize = MPT2SAS_SG_DEPTH;
-       }
-
-       /* command line tunables  for max controller queue depth */
-       if (max_queue_depth != -1 && max_queue_depth != 0) {
-               max_request_credit = min_t(u16, max_queue_depth +
-                       ioc->hi_priority_depth + ioc->internal_depth,
-                       facts->RequestCredit);
-               if (max_request_credit > MAX_HBA_QUEUE_DEPTH)
-                       max_request_credit =  MAX_HBA_QUEUE_DEPTH;
-       } else
-               max_request_credit = min_t(u16, facts->RequestCredit,
-                   MAX_HBA_QUEUE_DEPTH);
-
-       ioc->hba_queue_depth = max_request_credit;
-       ioc->hi_priority_depth = facts->HighPriorityCredit;
-       ioc->internal_depth = ioc->hi_priority_depth + 5;
-
-       /* request frame size */
-       ioc->request_sz = facts->IOCRequestFrameSize * 4;
-
-       /* reply frame size */
-       ioc->reply_sz = facts->ReplyFrameSize * 4;
-
- retry_allocation:
-       total_sz = 0;
-       /* calculate number of sg elements left over in the 1st frame */
-       max_sge_elements = ioc->request_sz - ((sizeof(Mpi2SCSIIORequest_t) -
-           sizeof(Mpi2SGEIOUnion_t)) + ioc->sge_size);
-       ioc->max_sges_in_main_message = max_sge_elements/ioc->sge_size;
-
-       /* now do the same for a chain buffer */
-       max_sge_elements = ioc->request_sz - ioc->sge_size;
-       ioc->max_sges_in_chain_message = max_sge_elements/ioc->sge_size;
-
-       ioc->chain_offset_value_for_main_message =
-           ((sizeof(Mpi2SCSIIORequest_t) - sizeof(Mpi2SGEIOUnion_t)) +
-            (ioc->max_sges_in_chain_message * ioc->sge_size)) / 4;
-
-       /*
-        *  MPT2SAS_SG_DEPTH = CONFIG_FUSION_MAX_SGE
-        */
-       chains_needed_per_io = ((ioc->shost->sg_tablesize -
-          ioc->max_sges_in_main_message)/ioc->max_sges_in_chain_message)
-           + 1;
-       if (chains_needed_per_io > facts->MaxChainDepth) {
-               chains_needed_per_io = facts->MaxChainDepth;
-               ioc->shost->sg_tablesize = min_t(u16,
-               ioc->max_sges_in_main_message + (ioc->max_sges_in_chain_message
-               * chains_needed_per_io), ioc->shost->sg_tablesize);
-       }
-       ioc->chains_needed_per_io = chains_needed_per_io;
-
-       /* reply free queue sizing - taking into account for 64 FW events */
-       ioc->reply_free_queue_depth = ioc->hba_queue_depth + 64;
-
-       /* calculate reply descriptor post queue depth */
-       ioc->reply_post_queue_depth = ioc->hba_queue_depth +
-                                       ioc->reply_free_queue_depth +  1;
-       /* align the reply post queue on the next 16 count boundary */
-       if (ioc->reply_post_queue_depth % 16)
-               ioc->reply_post_queue_depth += 16 -
-                       (ioc->reply_post_queue_depth % 16);
-
-
-       if (ioc->reply_post_queue_depth >
-           facts->MaxReplyDescriptorPostQueueDepth) {
-               ioc->reply_post_queue_depth =
-                       facts->MaxReplyDescriptorPostQueueDepth -
-                   (facts->MaxReplyDescriptorPostQueueDepth % 16);
-               ioc->hba_queue_depth =
-                       ((ioc->reply_post_queue_depth - 64) / 2) - 1;
-               ioc->reply_free_queue_depth = ioc->hba_queue_depth + 64;
-       }
-
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scatter gather: "
-           "sge_in_main_msg(%d), sge_per_chain(%d), sge_per_io(%d), "
-           "chains_per_io(%d)\n", ioc->name, ioc->max_sges_in_main_message,
-           ioc->max_sges_in_chain_message, ioc->shost->sg_tablesize,
-           ioc->chains_needed_per_io));
-
-       /* reply post queue, 16 byte align */
-       reply_post_free_sz = ioc->reply_post_queue_depth *
-           sizeof(Mpi2DefaultReplyDescriptor_t);
-
-       sz = reply_post_free_sz;
-       if (_base_is_controller_msix_enabled(ioc) && !ioc->rdpq_array_enable)
-               sz *= ioc->reply_queue_count;
-
-       ioc->reply_post = kcalloc((ioc->rdpq_array_enable) ?
-           (ioc->reply_queue_count):1,
-           sizeof(struct reply_post_struct), GFP_KERNEL);
-
-       if (!ioc->reply_post) {
-               printk(MPT2SAS_ERR_FMT "reply_post_free pool: kcalloc failed\n",
-                       ioc->name);
-               goto out;
-       }
-       ioc->reply_post_free_dma_pool = pci_pool_create("reply_post_free pool",
-           ioc->pdev, sz, 16, 0);
-       if (!ioc->reply_post_free_dma_pool) {
-               printk(MPT2SAS_ERR_FMT
-                "reply_post_free pool: pci_pool_create failed\n",
-                ioc->name);
-               goto out;
-       }
-       i = 0;
-       do {
-               ioc->reply_post[i].reply_post_free =
-                   pci_pool_alloc(ioc->reply_post_free_dma_pool,
-                   GFP_KERNEL,
-                   &ioc->reply_post[i].reply_post_free_dma);
-               if (!ioc->reply_post[i].reply_post_free) {
-                       printk(MPT2SAS_ERR_FMT
-                       "reply_post_free pool: pci_pool_alloc failed\n",
-                       ioc->name);
-                       goto out;
-               }
-               memset(ioc->reply_post[i].reply_post_free, 0, sz);
-               dinitprintk(ioc, printk(MPT2SAS_INFO_FMT
-                   "reply post free pool (0x%p): depth(%d),"
-                   "element_size(%d), pool_size(%d kB)\n", ioc->name,
-                   ioc->reply_post[i].reply_post_free,
-                   ioc->reply_post_queue_depth, 8, sz/1024));
-               dinitprintk(ioc, printk(MPT2SAS_INFO_FMT
-                   "reply_post_free_dma = (0x%llx)\n", ioc->name,
-                   (unsigned long long)
-                   ioc->reply_post[i].reply_post_free_dma));
-               total_sz += sz;
-       } while (ioc->rdpq_array_enable && (++i < ioc->reply_queue_count));
-
-       if (ioc->dma_mask == 64) {
-               if (_base_change_consistent_dma_mask(ioc, ioc->pdev) != 0) {
-                       printk(MPT2SAS_WARN_FMT
-                           "no suitable consistent DMA mask for %s\n",
-                           ioc->name, pci_name(ioc->pdev));
-                       goto out;
-               }
-       }
-
-       ioc->scsiio_depth = ioc->hba_queue_depth -
-           ioc->hi_priority_depth - ioc->internal_depth;
-
-       /* set the scsi host can_queue depth
-        * with some internal commands that could be outstanding
-        */
-       ioc->shost->can_queue = ioc->scsiio_depth;
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scsi host: "
-           "can_queue depth (%d)\n", ioc->name, ioc->shost->can_queue));
-
-       /* contiguous pool for request and chains, 16 byte align, one extra "
-        * "frame for smid=0
-        */
-       ioc->chain_depth = ioc->chains_needed_per_io * ioc->scsiio_depth;
-       sz = ((ioc->scsiio_depth + 1) * ioc->request_sz);
-
-       /* hi-priority queue */
-       sz += (ioc->hi_priority_depth * ioc->request_sz);
-
-       /* internal queue */
-       sz += (ioc->internal_depth * ioc->request_sz);
-
-       ioc->request_dma_sz = sz;
-       ioc->request = pci_alloc_consistent(ioc->pdev, sz, &ioc->request_dma);
-       if (!ioc->request) {
-               printk(MPT2SAS_ERR_FMT "request pool: pci_alloc_consistent "
-                   "failed: hba_depth(%d), chains_per_io(%d), frame_sz(%d), "
-                   "total(%d kB)\n", ioc->name, ioc->hba_queue_depth,
-                   ioc->chains_needed_per_io, ioc->request_sz, sz/1024);
-               if (ioc->scsiio_depth < MPT2SAS_SAS_QUEUE_DEPTH)
-                       goto out;
-               retry_sz += 64;
-               ioc->hba_queue_depth = max_request_credit - retry_sz;
-               goto retry_allocation;
-       }
-
-       if (retry_sz)
-               printk(MPT2SAS_ERR_FMT "request pool: pci_alloc_consistent "
-                   "succeed: hba_depth(%d), chains_per_io(%d), frame_sz(%d), "
-                   "total(%d kb)\n", ioc->name, ioc->hba_queue_depth,
-                   ioc->chains_needed_per_io, ioc->request_sz, sz/1024);
-
-
-       /* hi-priority queue */
-       ioc->hi_priority = ioc->request + ((ioc->scsiio_depth + 1) *
-           ioc->request_sz);
-       ioc->hi_priority_dma = ioc->request_dma + ((ioc->scsiio_depth + 1) *
-           ioc->request_sz);
-
-       /* internal queue */
-       ioc->internal = ioc->hi_priority + (ioc->hi_priority_depth *
-           ioc->request_sz);
-       ioc->internal_dma = ioc->hi_priority_dma + (ioc->hi_priority_depth *
-           ioc->request_sz);
-
-
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "request pool(0x%p): "
-           "depth(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name,
-           ioc->request, ioc->hba_queue_depth, ioc->request_sz,
-           (ioc->hba_queue_depth * ioc->request_sz)/1024));
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "request pool: dma(0x%llx)\n",
-           ioc->name, (unsigned long long) ioc->request_dma));
-       total_sz += sz;
-
-       sz = ioc->scsiio_depth * sizeof(struct scsiio_tracker);
-       ioc->scsi_lookup_pages = get_order(sz);
-       ioc->scsi_lookup = (struct scsiio_tracker *)__get_free_pages(
-           GFP_KERNEL, ioc->scsi_lookup_pages);
-       if (!ioc->scsi_lookup) {
-               printk(MPT2SAS_ERR_FMT "scsi_lookup: get_free_pages failed, "
-                   "sz(%d)\n", ioc->name, (int)sz);
-               goto out;
-       }
-
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scsiio(0x%p): "
-           "depth(%d)\n", ioc->name, ioc->request,
-           ioc->scsiio_depth));
-
-       ioc->chain_depth = min_t(u32, ioc->chain_depth, MAX_CHAIN_DEPTH);
-       sz = ioc->chain_depth * sizeof(struct chain_tracker);
-       ioc->chain_pages = get_order(sz);
-
-       ioc->chain_lookup = (struct chain_tracker *)__get_free_pages(
-           GFP_KERNEL, ioc->chain_pages);
-       if (!ioc->chain_lookup) {
-               printk(MPT2SAS_ERR_FMT "chain_lookup: get_free_pages failed, "
-                   "sz(%d)\n", ioc->name, (int)sz);
-               goto out;
-       }
-       ioc->chain_dma_pool = pci_pool_create("chain pool", ioc->pdev,
-           ioc->request_sz, 16, 0);
-       if (!ioc->chain_dma_pool) {
-               printk(MPT2SAS_ERR_FMT "chain_dma_pool: pci_pool_create "
-                   "failed\n", ioc->name);
-               goto out;
-       }
-       for (i = 0; i < ioc->chain_depth; i++) {
-               ioc->chain_lookup[i].chain_buffer = pci_pool_alloc(
-                   ioc->chain_dma_pool , GFP_KERNEL,
-                   &ioc->chain_lookup[i].chain_buffer_dma);
-               if (!ioc->chain_lookup[i].chain_buffer) {
-                       ioc->chain_depth = i;
-                       goto chain_done;
-               }
-               total_sz += ioc->request_sz;
-       }
-chain_done:
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "chain pool depth"
-           "(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name,
-           ioc->chain_depth, ioc->request_sz, ((ioc->chain_depth *
-           ioc->request_sz))/1024));
-
-       /* initialize hi-priority queue smid's */
-       ioc->hpr_lookup = kcalloc(ioc->hi_priority_depth,
-           sizeof(struct request_tracker), GFP_KERNEL);
-       if (!ioc->hpr_lookup) {
-               printk(MPT2SAS_ERR_FMT "hpr_lookup: kcalloc failed\n",
-                   ioc->name);
-               goto out;
-       }
-       ioc->hi_priority_smid = ioc->scsiio_depth + 1;
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "hi_priority(0x%p): "
-           "depth(%d), start smid(%d)\n", ioc->name, ioc->hi_priority,
-           ioc->hi_priority_depth, ioc->hi_priority_smid));
-
-       /* initialize internal queue smid's */
-       ioc->internal_lookup = kcalloc(ioc->internal_depth,
-           sizeof(struct request_tracker), GFP_KERNEL);
-       if (!ioc->internal_lookup) {
-               printk(MPT2SAS_ERR_FMT "internal_lookup: kcalloc failed\n",
-                   ioc->name);
-               goto out;
-       }
-       ioc->internal_smid = ioc->hi_priority_smid + ioc->hi_priority_depth;
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "internal(0x%p): "
-           "depth(%d), start smid(%d)\n", ioc->name, ioc->internal,
-            ioc->internal_depth, ioc->internal_smid));
-
-       /* sense buffers, 4 byte align */
-       sz = ioc->scsiio_depth * SCSI_SENSE_BUFFERSIZE;
-       ioc->sense_dma_pool = pci_pool_create("sense pool", ioc->pdev, sz, 4,
-           0);
-       if (!ioc->sense_dma_pool) {
-               printk(MPT2SAS_ERR_FMT "sense pool: pci_pool_create failed\n",
-                   ioc->name);
-               goto out;
-       }
-       ioc->sense = pci_pool_alloc(ioc->sense_dma_pool , GFP_KERNEL,
-           &ioc->sense_dma);
-       if (!ioc->sense) {
-               printk(MPT2SAS_ERR_FMT "sense pool: pci_pool_alloc failed\n",
-                   ioc->name);
-               goto out;
-       }
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT
-           "sense pool(0x%p): depth(%d), element_size(%d), pool_size"
-           "(%d kB)\n", ioc->name, ioc->sense, ioc->scsiio_depth,
-           SCSI_SENSE_BUFFERSIZE, sz/1024));
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "sense_dma(0x%llx)\n",
-           ioc->name, (unsigned long long)ioc->sense_dma));
-       total_sz += sz;
-
-       /* reply pool, 4 byte align */
-       sz = ioc->reply_free_queue_depth * ioc->reply_sz;
-       ioc->reply_dma_pool = pci_pool_create("reply pool", ioc->pdev, sz, 4,
-           0);
-       if (!ioc->reply_dma_pool) {
-               printk(MPT2SAS_ERR_FMT "reply pool: pci_pool_create failed\n",
-                   ioc->name);
-               goto out;
-       }
-       ioc->reply = pci_pool_alloc(ioc->reply_dma_pool , GFP_KERNEL,
-           &ioc->reply_dma);
-       if (!ioc->reply) {
-               printk(MPT2SAS_ERR_FMT "reply pool: pci_pool_alloc failed\n",
-                   ioc->name);
-               goto out;
-       }
-       ioc->reply_dma_min_address = (u32)(ioc->reply_dma);
-       ioc->reply_dma_max_address = (u32)(ioc->reply_dma) + sz;
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "reply pool(0x%p): depth"
-           "(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name, ioc->reply,
-           ioc->reply_free_queue_depth, ioc->reply_sz, sz/1024));
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "reply_dma(0x%llx)\n",
-           ioc->name, (unsigned long long)ioc->reply_dma));
-       total_sz += sz;
-
-       /* reply free queue, 16 byte align */
-       sz = ioc->reply_free_queue_depth * 4;
-       ioc->reply_free_dma_pool = pci_pool_create("reply_free pool",
-           ioc->pdev, sz, 16, 0);
-       if (!ioc->reply_free_dma_pool) {
-               printk(MPT2SAS_ERR_FMT "reply_free pool: pci_pool_create "
-                   "failed\n", ioc->name);
-               goto out;
-       }
-       ioc->reply_free = pci_pool_alloc(ioc->reply_free_dma_pool , GFP_KERNEL,
-           &ioc->reply_free_dma);
-       if (!ioc->reply_free) {
-               printk(MPT2SAS_ERR_FMT "reply_free pool: pci_pool_alloc "
-                   "failed\n", ioc->name);
-               goto out;
-       }
-       memset(ioc->reply_free, 0, sz);
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "reply_free pool(0x%p): "
-           "depth(%d), element_size(%d), pool_size(%d kB)\n", ioc->name,
-           ioc->reply_free, ioc->reply_free_queue_depth, 4, sz/1024));
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "reply_free_dma"
-           "(0x%llx)\n", ioc->name, (unsigned long long)ioc->reply_free_dma));
-       total_sz += sz;
-
-       ioc->config_page_sz = 512;
-       ioc->config_page = pci_alloc_consistent(ioc->pdev,
-           ioc->config_page_sz, &ioc->config_page_dma);
-       if (!ioc->config_page) {
-               printk(MPT2SAS_ERR_FMT "config page: pci_pool_alloc "
-                   "failed\n", ioc->name);
-               goto out;
-       }
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "config page(0x%p): size"
-           "(%d)\n", ioc->name, ioc->config_page, ioc->config_page_sz));
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "config_page_dma"
-           "(0x%llx)\n", ioc->name, (unsigned long long)ioc->config_page_dma));
-       total_sz += ioc->config_page_sz;
-
-       printk(MPT2SAS_INFO_FMT "Allocated physical memory: size(%d kB)\n",
-           ioc->name, total_sz/1024);
-       printk(MPT2SAS_INFO_FMT "Current Controller Queue Depth(%d), "
-           "Max Controller Queue Depth(%d)\n",
-           ioc->name, ioc->shost->can_queue, facts->RequestCredit);
-       printk(MPT2SAS_INFO_FMT "Scatter Gather Elements per IO(%d)\n",
-           ioc->name, ioc->shost->sg_tablesize);
-       return 0;
-
- out:
-       return -ENOMEM;
-}
-
-
-/**
- * mpt2sas_base_get_iocstate - Get the current state of a MPT adapter.
- * @ioc: Pointer to MPT_ADAPTER structure
- * @cooked: Request raw or cooked IOC state
- *
- * Returns all IOC Doorbell register bits if cooked==0, else just the
- * Doorbell bits in MPI_IOC_STATE_MASK.
- */
-u32
-mpt2sas_base_get_iocstate(struct MPT2SAS_ADAPTER *ioc, int cooked)
-{
-       u32 s, sc;
-
-       s = readl(&ioc->chip->Doorbell);
-       sc = s & MPI2_IOC_STATE_MASK;
-       return cooked ? sc : s;
-}
-
-/**
- * _base_wait_on_iocstate - waiting on a particular ioc state
- * @ioc_state: controller state { READY, OPERATIONAL, or RESET }
- * @timeout: timeout in second
- * @sleep_flag: CAN_SLEEP or NO_SLEEP
- *
- * Returns 0 for success, non-zero for failure.
- */
-static int
-_base_wait_on_iocstate(struct MPT2SAS_ADAPTER *ioc, u32 ioc_state, int timeout,
-    int sleep_flag)
-{
-       u32 count, cntdn;
-       u32 current_state;
-
-       count = 0;
-       cntdn = (sleep_flag == CAN_SLEEP) ? 1000*timeout : 2000*timeout;
-       do {
-               current_state = mpt2sas_base_get_iocstate(ioc, 1);
-               if (current_state == ioc_state)
-                       return 0;
-               if (count && current_state == MPI2_IOC_STATE_FAULT)
-                       break;
-               if (sleep_flag == CAN_SLEEP)
-                       msleep(1);
-               else
-                       udelay(500);
-               count++;
-       } while (--cntdn);
-
-       return current_state;
-}
-
-/**
- * _base_wait_for_doorbell_int - waiting for controller interrupt(generated by
- * a write to the doorbell)
- * @ioc: per adapter object
- * @timeout: timeout in second
- * @sleep_flag: CAN_SLEEP or NO_SLEEP
- *
- * Returns 0 for success, non-zero for failure.
- *
- * Notes: MPI2_HIS_IOC2SYS_DB_STATUS - set to one when IOC writes to doorbell.
- */
-static int
-_base_wait_for_doorbell_int(struct MPT2SAS_ADAPTER *ioc, int timeout,
-    int sleep_flag)
-{
-       u32 cntdn, count;
-       u32 int_status;
-
-       count = 0;
-       cntdn = (sleep_flag == CAN_SLEEP) ? 1000*timeout : 2000*timeout;
-       do {
-               int_status = readl(&ioc->chip->HostInterruptStatus);
-               if (int_status & MPI2_HIS_IOC2SYS_DB_STATUS) {
-                       dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
-                           "successful count(%d), timeout(%d)\n", ioc->name,
-                           __func__, count, timeout));
-                       return 0;
-               }
-               if (sleep_flag == CAN_SLEEP)
-                       msleep(1);
-               else
-                       udelay(500);
-               count++;
-       } while (--cntdn);
-
-       printk(MPT2SAS_ERR_FMT "%s: failed due to timeout count(%d), "
-           "int_status(%x)!\n", ioc->name, __func__, count, int_status);
-       return -EFAULT;
-}
-
-/**
- * _base_wait_for_doorbell_ack - waiting for controller to read the doorbell.
- * @ioc: per adapter object
- * @timeout: timeout in second
- * @sleep_flag: CAN_SLEEP or NO_SLEEP
- *
- * Returns 0 for success, non-zero for failure.
- *
- * Notes: MPI2_HIS_SYS2IOC_DB_STATUS - set to one when host writes to
- * doorbell.
- */
-static int
-_base_wait_for_doorbell_ack(struct MPT2SAS_ADAPTER *ioc, int timeout,
-    int sleep_flag)
-{
-       u32 cntdn, count;
-       u32 int_status;
-       u32 doorbell;
-
-       count = 0;
-       cntdn = (sleep_flag == CAN_SLEEP) ? 1000*timeout : 2000*timeout;
-       do {
-               int_status = readl(&ioc->chip->HostInterruptStatus);
-               if (!(int_status & MPI2_HIS_SYS2IOC_DB_STATUS)) {
-                       dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
-                           "successful count(%d), timeout(%d)\n", ioc->name,
-                           __func__, count, timeout));
-                       return 0;
-               } else if (int_status & MPI2_HIS_IOC2SYS_DB_STATUS) {
-                       doorbell = readl(&ioc->chip->Doorbell);
-                       if ((doorbell & MPI2_IOC_STATE_MASK) ==
-                           MPI2_IOC_STATE_FAULT) {
-                               mpt2sas_base_fault_info(ioc , doorbell);
-                               return -EFAULT;
-                       }
-               } else if (int_status == 0xFFFFFFFF)
-                       goto out;
-
-               if (sleep_flag == CAN_SLEEP)
-                       msleep(1);
-               else
-                       udelay(500);
-               count++;
-       } while (--cntdn);
-
- out:
-       printk(MPT2SAS_ERR_FMT "%s: failed due to timeout count(%d), "
-           "int_status(%x)!\n", ioc->name, __func__, count, int_status);
-       return -EFAULT;
-}
-
-/**
- * _base_wait_for_doorbell_not_used - waiting for doorbell to not be in use
- * @ioc: per adapter object
- * @timeout: timeout in second
- * @sleep_flag: CAN_SLEEP or NO_SLEEP
- *
- * Returns 0 for success, non-zero for failure.
- *
- */
-static int
-_base_wait_for_doorbell_not_used(struct MPT2SAS_ADAPTER *ioc, int timeout,
-    int sleep_flag)
-{
-       u32 cntdn, count;
-       u32 doorbell_reg;
-
-       count = 0;
-       cntdn = (sleep_flag == CAN_SLEEP) ? 1000*timeout : 2000*timeout;
-       do {
-               doorbell_reg = readl(&ioc->chip->Doorbell);
-               if (!(doorbell_reg & MPI2_DOORBELL_USED)) {
-                       dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
-                           "successful count(%d), timeout(%d)\n", ioc->name,
-                           __func__, count, timeout));
-                       return 0;
-               }
-               if (sleep_flag == CAN_SLEEP)
-                       msleep(1);
-               else
-                       udelay(500);
-               count++;
-       } while (--cntdn);
-
-       printk(MPT2SAS_ERR_FMT "%s: failed due to timeout count(%d), "
-           "doorbell_reg(%x)!\n", ioc->name, __func__, count, doorbell_reg);
-       return -EFAULT;
-}
-
-/**
- * _base_send_ioc_reset - send doorbell reset
- * @ioc: per adapter object
- * @reset_type: currently only supports: MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET
- * @timeout: timeout in second
- * @sleep_flag: CAN_SLEEP or NO_SLEEP
- *
- * Returns 0 for success, non-zero for failure.
- */
-static int
-_base_send_ioc_reset(struct MPT2SAS_ADAPTER *ioc, u8 reset_type, int timeout,
-    int sleep_flag)
-{
-       u32 ioc_state;
-       int r = 0;
-
-       if (reset_type != MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET) {
-               printk(MPT2SAS_ERR_FMT "%s: unknown reset_type\n",
-                   ioc->name, __func__);
-               return -EFAULT;
-       }
-
-       if (!(ioc->facts.IOCCapabilities &
-          MPI2_IOCFACTS_CAPABILITY_EVENT_REPLAY))
-               return -EFAULT;
-
-       printk(MPT2SAS_INFO_FMT "sending message unit reset !!\n", ioc->name);
-
-       writel(reset_type << MPI2_DOORBELL_FUNCTION_SHIFT,
-           &ioc->chip->Doorbell);
-       if ((_base_wait_for_doorbell_ack(ioc, 15, sleep_flag))) {
-               r = -EFAULT;
-               goto out;
-       }
-       ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_READY,
-           timeout, sleep_flag);
-       if (ioc_state) {
-               printk(MPT2SAS_ERR_FMT "%s: failed going to ready state "
-                   " (ioc_state=0x%x)\n", ioc->name, __func__, ioc_state);
-               r = -EFAULT;
-               goto out;
-       }
- out:
-       printk(MPT2SAS_INFO_FMT "message unit reset: %s\n",
-           ioc->name, ((r == 0) ? "SUCCESS" : "FAILED"));
-       return r;
-}
-
-/**
- * _base_handshake_req_reply_wait - send request thru doorbell interface
- * @ioc: per adapter object
- * @request_bytes: request length
- * @request: pointer having request payload
- * @reply_bytes: reply length
- * @reply: pointer to reply payload
- * @timeout: timeout in second
- * @sleep_flag: CAN_SLEEP or NO_SLEEP
- *
- * Returns 0 for success, non-zero for failure.
- */
-static int
-_base_handshake_req_reply_wait(struct MPT2SAS_ADAPTER *ioc, int request_bytes,
-    u32 *request, int reply_bytes, u16 *reply, int timeout, int sleep_flag)
-{
-       MPI2DefaultReply_t *default_reply = (MPI2DefaultReply_t *)reply;
-       int i;
-       u8 failed;
-       u16 dummy;
-       __le32 *mfp;
-
-       /* make sure doorbell is not in use */
-       if ((readl(&ioc->chip->Doorbell) & MPI2_DOORBELL_USED)) {
-               printk(MPT2SAS_ERR_FMT "doorbell is in use "
-                   " (line=%d)\n", ioc->name, __LINE__);
-               return -EFAULT;
-       }
-
-       /* clear pending doorbell interrupts from previous state changes */
-       if (readl(&ioc->chip->HostInterruptStatus) &
-           MPI2_HIS_IOC2SYS_DB_STATUS)
-               writel(0, &ioc->chip->HostInterruptStatus);
-
-       /* send message to ioc */
-       writel(((MPI2_FUNCTION_HANDSHAKE<<MPI2_DOORBELL_FUNCTION_SHIFT) |
-           ((request_bytes/4)<<MPI2_DOORBELL_ADD_DWORDS_SHIFT)),
-           &ioc->chip->Doorbell);
-
-       if ((_base_wait_for_doorbell_int(ioc, 5, NO_SLEEP))) {
-               printk(MPT2SAS_ERR_FMT "doorbell handshake "
-                  "int failed (line=%d)\n", ioc->name, __LINE__);
-               return -EFAULT;
-       }
-       writel(0, &ioc->chip->HostInterruptStatus);
-
-       if ((_base_wait_for_doorbell_ack(ioc, 5, sleep_flag))) {
-               printk(MPT2SAS_ERR_FMT "doorbell handshake "
-                   "ack failed (line=%d)\n", ioc->name, __LINE__);
-               return -EFAULT;
-       }
-
-       /* send message 32-bits at a time */
-       for (i = 0, failed = 0; i < request_bytes/4 && !failed; i++) {
-               writel(cpu_to_le32(request[i]), &ioc->chip->Doorbell);
-               if ((_base_wait_for_doorbell_ack(ioc, 5, sleep_flag)))
-                       failed = 1;
-       }
-
-       if (failed) {
-               printk(MPT2SAS_ERR_FMT "doorbell handshake "
-                   "sending request failed (line=%d)\n", ioc->name, __LINE__);
-               return -EFAULT;
-       }
-
-       /* now wait for the reply */
-       if ((_base_wait_for_doorbell_int(ioc, timeout, sleep_flag))) {
-               printk(MPT2SAS_ERR_FMT "doorbell handshake "
-                  "int failed (line=%d)\n", ioc->name, __LINE__);
-               return -EFAULT;
-       }
-
-       /* read the first two 16-bits, it gives the total length of the reply */
-       reply[0] = le16_to_cpu(readl(&ioc->chip->Doorbell)
-           & MPI2_DOORBELL_DATA_MASK);
-       writel(0, &ioc->chip->HostInterruptStatus);
-       if ((_base_wait_for_doorbell_int(ioc, 5, sleep_flag))) {
-               printk(MPT2SAS_ERR_FMT "doorbell handshake "
-                  "int failed (line=%d)\n", ioc->name, __LINE__);
-               return -EFAULT;
-       }
-       reply[1] = le16_to_cpu(readl(&ioc->chip->Doorbell)
-           & MPI2_DOORBELL_DATA_MASK);
-       writel(0, &ioc->chip->HostInterruptStatus);
-
-       for (i = 2; i < default_reply->MsgLength * 2; i++)  {
-               if ((_base_wait_for_doorbell_int(ioc, 5, sleep_flag))) {
-                       printk(MPT2SAS_ERR_FMT "doorbell "
-                           "handshake int failed (line=%d)\n", ioc->name,
-                           __LINE__);
-                       return -EFAULT;
-               }
-               if (i >=  reply_bytes/2) /* overflow case */
-                       dummy = readl(&ioc->chip->Doorbell);
-               else
-                       reply[i] = le16_to_cpu(readl(&ioc->chip->Doorbell)
-                           & MPI2_DOORBELL_DATA_MASK);
-               writel(0, &ioc->chip->HostInterruptStatus);
-       }
-
-       _base_wait_for_doorbell_int(ioc, 5, sleep_flag);
-       if (_base_wait_for_doorbell_not_used(ioc, 5, sleep_flag) != 0) {
-               dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "doorbell is in use "
-                   " (line=%d)\n", ioc->name, __LINE__));
-       }
-       writel(0, &ioc->chip->HostInterruptStatus);
-
-       if (ioc->logging_level & MPT_DEBUG_INIT) {
-               mfp = (__le32 *)reply;
-               printk(KERN_INFO "\toffset:data\n");
-               for (i = 0; i < reply_bytes/4; i++)
-                       printk(KERN_INFO "\t[0x%02x]:%08x\n", i*4,
-                           le32_to_cpu(mfp[i]));
-       }
-       return 0;
-}
-
-/**
- * mpt2sas_base_sas_iounit_control - send sas iounit control to FW
- * @ioc: per adapter object
- * @mpi_reply: the reply payload from FW
- * @mpi_request: the request payload sent to FW
- *
- * The SAS IO Unit Control Request message allows the host to perform low-level
- * operations, such as resets on the PHYs of the IO Unit, also allows the host
- * to obtain the IOC assigned device handles for a device if it has other
- * identifying information about the device, in addition allows the host to
- * remove IOC resources associated with the device.
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_base_sas_iounit_control(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2SasIoUnitControlReply_t *mpi_reply,
-    Mpi2SasIoUnitControlRequest_t *mpi_request)
-{
-       u16 smid;
-       u32 ioc_state;
-       unsigned long timeleft;
-       bool issue_reset = false;
-       int rc;
-       void *request;
-       u16 wait_state_count;
-
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-           __func__));
-
-       mutex_lock(&ioc->base_cmds.mutex);
-
-       if (ioc->base_cmds.status != MPT2_CMD_NOT_USED) {
-               printk(MPT2SAS_ERR_FMT "%s: base_cmd in use\n",
-                   ioc->name, __func__);
-               rc = -EAGAIN;
-               goto out;
-       }
-
-       wait_state_count = 0;
-       ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
-       while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
-               if (wait_state_count++ == 10) {
-                       printk(MPT2SAS_ERR_FMT
-                           "%s: failed due to ioc not operational\n",
-                           ioc->name, __func__);
-                       rc = -EFAULT;
-                       goto out;
-               }
-               ssleep(1);
-               ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
-               printk(MPT2SAS_INFO_FMT "%s: waiting for "
-                   "operational state(count=%d)\n", ioc->name,
-                   __func__, wait_state_count);
-       }
-
-       smid = mpt2sas_base_get_smid(ioc, ioc->base_cb_idx);
-       if (!smid) {
-               printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
-                   ioc->name, __func__);
-               rc = -EAGAIN;
-               goto out;
-       }
-
-       rc = 0;
-       ioc->base_cmds.status = MPT2_CMD_PENDING;
-       request = mpt2sas_base_get_msg_frame(ioc, smid);
-       ioc->base_cmds.smid = smid;
-       memcpy(request, mpi_request, sizeof(Mpi2SasIoUnitControlRequest_t));
-       if (mpi_request->Operation == MPI2_SAS_OP_PHY_HARD_RESET ||
-           mpi_request->Operation == MPI2_SAS_OP_PHY_LINK_RESET)
-               ioc->ioc_link_reset_in_progress = 1;
-       init_completion(&ioc->base_cmds.done);
-       mpt2sas_base_put_smid_default(ioc, smid);
-       timeleft = wait_for_completion_timeout(&ioc->base_cmds.done,
-           msecs_to_jiffies(10000));
-       if ((mpi_request->Operation == MPI2_SAS_OP_PHY_HARD_RESET ||
-           mpi_request->Operation == MPI2_SAS_OP_PHY_LINK_RESET) &&
-           ioc->ioc_link_reset_in_progress)
-               ioc->ioc_link_reset_in_progress = 0;
-       if (!(ioc->base_cmds.status & MPT2_CMD_COMPLETE)) {
-               printk(MPT2SAS_ERR_FMT "%s: timeout\n",
-                   ioc->name, __func__);
-               _debug_dump_mf(mpi_request,
-                   sizeof(Mpi2SasIoUnitControlRequest_t)/4);
-               if (!(ioc->base_cmds.status & MPT2_CMD_RESET))
-                       issue_reset = true;
-               goto issue_host_reset;
-       }
-       if (ioc->base_cmds.status & MPT2_CMD_REPLY_VALID)
-               memcpy(mpi_reply, ioc->base_cmds.reply,
-                   sizeof(Mpi2SasIoUnitControlReply_t));
-       else
-               memset(mpi_reply, 0, sizeof(Mpi2SasIoUnitControlReply_t));
-       ioc->base_cmds.status = MPT2_CMD_NOT_USED;
-       goto out;
-
- issue_host_reset:
-       if (issue_reset)
-               mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
-                   FORCE_BIG_HAMMER);
-       ioc->base_cmds.status = MPT2_CMD_NOT_USED;
-       rc = -EFAULT;
- out:
-       mutex_unlock(&ioc->base_cmds.mutex);
-       return rc;
-}
-
-
-/**
- * mpt2sas_base_scsi_enclosure_processor - sending request to sep device
- * @ioc: per adapter object
- * @mpi_reply: the reply payload from FW
- * @mpi_request: the request payload sent to FW
- *
- * The SCSI Enclosure Processor request message causes the IOC to
- * communicate with SES devices to control LED status signals.
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_base_scsi_enclosure_processor(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2SepReply_t *mpi_reply, Mpi2SepRequest_t *mpi_request)
-{
-       u16 smid;
-       u32 ioc_state;
-       unsigned long timeleft;
-       bool issue_reset = false;
-       int rc;
-       void *request;
-       u16 wait_state_count;
-
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-           __func__));
-
-       mutex_lock(&ioc->base_cmds.mutex);
-
-       if (ioc->base_cmds.status != MPT2_CMD_NOT_USED) {
-               printk(MPT2SAS_ERR_FMT "%s: base_cmd in use\n",
-                   ioc->name, __func__);
-               rc = -EAGAIN;
-               goto out;
-       }
-
-       wait_state_count = 0;
-       ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
-       while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
-               if (wait_state_count++ == 10) {
-                       printk(MPT2SAS_ERR_FMT
-                           "%s: failed due to ioc not operational\n",
-                           ioc->name, __func__);
-                       rc = -EFAULT;
-                       goto out;
-               }
-               ssleep(1);
-               ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
-               printk(MPT2SAS_INFO_FMT "%s: waiting for "
-                   "operational state(count=%d)\n", ioc->name,
-                   __func__, wait_state_count);
-       }
-
-       smid = mpt2sas_base_get_smid(ioc, ioc->base_cb_idx);
-       if (!smid) {
-               printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
-                   ioc->name, __func__);
-               rc = -EAGAIN;
-               goto out;
-       }
-
-       rc = 0;
-       ioc->base_cmds.status = MPT2_CMD_PENDING;
-       request = mpt2sas_base_get_msg_frame(ioc, smid);
-       ioc->base_cmds.smid = smid;
-       memcpy(request, mpi_request, sizeof(Mpi2SepReply_t));
-       init_completion(&ioc->base_cmds.done);
-       mpt2sas_base_put_smid_default(ioc, smid);
-       timeleft = wait_for_completion_timeout(&ioc->base_cmds.done,
-           msecs_to_jiffies(10000));
-       if (!(ioc->base_cmds.status & MPT2_CMD_COMPLETE)) {
-               printk(MPT2SAS_ERR_FMT "%s: timeout\n",
-                   ioc->name, __func__);
-               _debug_dump_mf(mpi_request,
-                   sizeof(Mpi2SepRequest_t)/4);
-               if (!(ioc->base_cmds.status & MPT2_CMD_RESET))
-                       issue_reset = true;
-               goto issue_host_reset;
-       }
-       if (ioc->base_cmds.status & MPT2_CMD_REPLY_VALID)
-               memcpy(mpi_reply, ioc->base_cmds.reply,
-                   sizeof(Mpi2SepReply_t));
-       else
-               memset(mpi_reply, 0, sizeof(Mpi2SepReply_t));
-       ioc->base_cmds.status = MPT2_CMD_NOT_USED;
-       goto out;
-
- issue_host_reset:
-       if (issue_reset)
-               mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
-                   FORCE_BIG_HAMMER);
-       ioc->base_cmds.status = MPT2_CMD_NOT_USED;
-       rc = -EFAULT;
- out:
-       mutex_unlock(&ioc->base_cmds.mutex);
-       return rc;
-}
-
-/**
- * _base_get_port_facts - obtain port facts reply and save in ioc
- * @ioc: per adapter object
- * @sleep_flag: CAN_SLEEP or NO_SLEEP
- *
- * Returns 0 for success, non-zero for failure.
- */
-static int
-_base_get_port_facts(struct MPT2SAS_ADAPTER *ioc, int port, int sleep_flag)
-{
-       Mpi2PortFactsRequest_t mpi_request;
-       Mpi2PortFactsReply_t mpi_reply;
-       struct mpt2sas_port_facts *pfacts;
-       int mpi_reply_sz, mpi_request_sz, r;
-
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-           __func__));
-
-       mpi_reply_sz = sizeof(Mpi2PortFactsReply_t);
-       mpi_request_sz = sizeof(Mpi2PortFactsRequest_t);
-       memset(&mpi_request, 0, mpi_request_sz);
-       mpi_request.Function = MPI2_FUNCTION_PORT_FACTS;
-       mpi_request.PortNumber = port;
-       r = _base_handshake_req_reply_wait(ioc, mpi_request_sz,
-           (u32 *)&mpi_request, mpi_reply_sz, (u16 *)&mpi_reply, 5, CAN_SLEEP);
-
-       if (r != 0) {
-               printk(MPT2SAS_ERR_FMT "%s: handshake failed (r=%d)\n",
-                   ioc->name, __func__, r);
-               return r;
-       }
-
-       pfacts = &ioc->pfacts[port];
-       memset(pfacts, 0, sizeof(struct mpt2sas_port_facts));
-       pfacts->PortNumber = mpi_reply.PortNumber;
-       pfacts->VP_ID = mpi_reply.VP_ID;
-       pfacts->VF_ID = mpi_reply.VF_ID;
-       pfacts->MaxPostedCmdBuffers =
-           le16_to_cpu(mpi_reply.MaxPostedCmdBuffers);
-
-       return 0;
-}
-
-/**
- * _base_wait_for_iocstate - Wait until the card is in READY or OPERATIONAL
- * @ioc: per adapter object
- * @timeout:
- * @sleep_flag: CAN_SLEEP or NO_SLEEP
- *
- * Returns 0 for success, non-zero for failure.
- */
-static int
-_base_wait_for_iocstate(struct MPT2SAS_ADAPTER *ioc, int timeout,
-       int sleep_flag)
-{
-       u32 ioc_state, doorbell;
-       int rc;
-
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-           __func__));
-
-       if (ioc->pci_error_recovery)
-               return 0;
-
-       doorbell = mpt2sas_base_get_iocstate(ioc, 0);
-       ioc_state = doorbell & MPI2_IOC_STATE_MASK;
-       dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: ioc_state(0x%08x)\n",
-           ioc->name, __func__, ioc_state));
-
-       switch (ioc_state) {
-       case MPI2_IOC_STATE_READY:
-       case MPI2_IOC_STATE_OPERATIONAL:
-               return 0;
-       }
-
-       if (doorbell & MPI2_DOORBELL_USED) {
-               dhsprintk(ioc, printk(MPT2SAS_INFO_FMT
-                   "unexpected doorbell activ!e\n", ioc->name));
-               goto issue_diag_reset;
-       }
-
-       if (ioc_state == MPI2_IOC_STATE_FAULT) {
-               mpt2sas_base_fault_info(ioc, doorbell &
-                   MPI2_DOORBELL_DATA_MASK);
-               goto issue_diag_reset;
-       }
-
-       ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_READY,
-           timeout, sleep_flag);
-       if (ioc_state) {
-               printk(MPT2SAS_ERR_FMT
-                   "%s: failed going to ready state (ioc_state=0x%x)\n",
-                   ioc->name, __func__, ioc_state);
-               return -EFAULT;
-       }
-
- issue_diag_reset:
-       rc = _base_diag_reset(ioc, sleep_flag);
-       return rc;
-}
-
-/**
- * _base_get_ioc_facts - obtain ioc facts reply and save in ioc
- * @ioc: per adapter object
- * @sleep_flag: CAN_SLEEP or NO_SLEEP
- *
- * Returns 0 for success, non-zero for failure.
- */
-static int
-_base_get_ioc_facts(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
-{
-       Mpi2IOCFactsRequest_t mpi_request;
-       Mpi2IOCFactsReply_t mpi_reply;
-       struct mpt2sas_facts *facts;
-       int mpi_reply_sz, mpi_request_sz, r;
-
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-           __func__));
-
-       r = _base_wait_for_iocstate(ioc, 10, sleep_flag);
-       if (r) {
-               printk(MPT2SAS_ERR_FMT "%s: failed getting to correct state\n",
-                       ioc->name, __func__);
-               return r;
-       }
-
-       mpi_reply_sz = sizeof(Mpi2IOCFactsReply_t);
-       mpi_request_sz = sizeof(Mpi2IOCFactsRequest_t);
-       memset(&mpi_request, 0, mpi_request_sz);
-       mpi_request.Function = MPI2_FUNCTION_IOC_FACTS;
-       r = _base_handshake_req_reply_wait(ioc, mpi_request_sz,
-           (u32 *)&mpi_request, mpi_reply_sz, (u16 *)&mpi_reply, 5, CAN_SLEEP);
-
-       if (r != 0) {
-               printk(MPT2SAS_ERR_FMT "%s: handshake failed (r=%d)\n",
-                   ioc->name, __func__, r);
-               return r;
-       }
-
-       facts = &ioc->facts;
-       memset(facts, 0, sizeof(struct mpt2sas_facts));
-       facts->MsgVersion = le16_to_cpu(mpi_reply.MsgVersion);
-       facts->HeaderVersion = le16_to_cpu(mpi_reply.HeaderVersion);
-       facts->VP_ID = mpi_reply.VP_ID;
-       facts->VF_ID = mpi_reply.VF_ID;
-       facts->IOCExceptions = le16_to_cpu(mpi_reply.IOCExceptions);
-       facts->MaxChainDepth = mpi_reply.MaxChainDepth;
-       facts->WhoInit = mpi_reply.WhoInit;
-       facts->NumberOfPorts = mpi_reply.NumberOfPorts;
-       facts->MaxMSIxVectors = mpi_reply.MaxMSIxVectors;
-       facts->RequestCredit = le16_to_cpu(mpi_reply.RequestCredit);
-       facts->MaxReplyDescriptorPostQueueDepth =
-           le16_to_cpu(mpi_reply.MaxReplyDescriptorPostQueueDepth);
-       facts->ProductID = le16_to_cpu(mpi_reply.ProductID);
-       facts->IOCCapabilities = le32_to_cpu(mpi_reply.IOCCapabilities);
-       if ((facts->IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID))
-               ioc->ir_firmware = 1;
-       if ((facts->IOCCapabilities &
-             MPI2_IOCFACTS_CAPABILITY_RDPQ_ARRAY_CAPABLE))
-               ioc->rdpq_array_capable = 1;
-       facts->FWVersion.Word = le32_to_cpu(mpi_reply.FWVersion.Word);
-       facts->IOCRequestFrameSize =
-           le16_to_cpu(mpi_reply.IOCRequestFrameSize);
-       facts->MaxInitiators = le16_to_cpu(mpi_reply.MaxInitiators);
-       facts->MaxTargets = le16_to_cpu(mpi_reply.MaxTargets);
-       ioc->shost->max_id = -1;
-       facts->MaxSasExpanders = le16_to_cpu(mpi_reply.MaxSasExpanders);
-       facts->MaxEnclosures = le16_to_cpu(mpi_reply.MaxEnclosures);
-       facts->ProtocolFlags = le16_to_cpu(mpi_reply.ProtocolFlags);
-       facts->HighPriorityCredit =
-           le16_to_cpu(mpi_reply.HighPriorityCredit);
-       facts->ReplyFrameSize = mpi_reply.ReplyFrameSize;
-       facts->MaxDevHandle = le16_to_cpu(mpi_reply.MaxDevHandle);
-
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "hba queue depth(%d), "
-           "max chains per io(%d)\n", ioc->name, facts->RequestCredit,
-           facts->MaxChainDepth));
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "request frame size(%d), "
-           "reply frame size(%d)\n", ioc->name,
-           facts->IOCRequestFrameSize * 4, facts->ReplyFrameSize * 4));
-       return 0;
-}
-
-/**
- * _base_send_ioc_init - send ioc_init to firmware
- * @ioc: per adapter object
- * @sleep_flag: CAN_SLEEP or NO_SLEEP
- *
- * Returns 0 for success, non-zero for failure.
- */
-static int
-_base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
-{
-       Mpi2IOCInitRequest_t mpi_request;
-       Mpi2IOCInitReply_t mpi_reply;
-       int i, r = 0;
-       struct timeval current_time;
-       u16 ioc_status;
-       u32 reply_post_free_array_sz = 0;
-       Mpi2IOCInitRDPQArrayEntry *reply_post_free_array = NULL;
-       dma_addr_t reply_post_free_array_dma;
-
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-           __func__));
-
-       memset(&mpi_request, 0, sizeof(Mpi2IOCInitRequest_t));
-       mpi_request.Function = MPI2_FUNCTION_IOC_INIT;
-       mpi_request.WhoInit = MPI2_WHOINIT_HOST_DRIVER;
-       mpi_request.VF_ID = 0; /* TODO */
-       mpi_request.VP_ID = 0;
-       mpi_request.MsgVersion = cpu_to_le16(MPI2_VERSION);
-       mpi_request.HeaderVersion = cpu_to_le16(MPI2_HEADER_VERSION);
-
-       if (_base_is_controller_msix_enabled(ioc))
-               mpi_request.HostMSIxVectors = ioc->reply_queue_count;
-       mpi_request.SystemRequestFrameSize = cpu_to_le16(ioc->request_sz/4);
-       mpi_request.ReplyDescriptorPostQueueDepth =
-           cpu_to_le16(ioc->reply_post_queue_depth);
-       mpi_request.ReplyFreeQueueDepth =
-           cpu_to_le16(ioc->reply_free_queue_depth);
-
-       mpi_request.SenseBufferAddressHigh =
-           cpu_to_le32((u64)ioc->sense_dma >> 32);
-       mpi_request.SystemReplyAddressHigh =
-           cpu_to_le32((u64)ioc->reply_dma >> 32);
-       mpi_request.SystemRequestFrameBaseAddress =
-           cpu_to_le64((u64)ioc->request_dma);
-       mpi_request.ReplyFreeQueueAddress =
-           cpu_to_le64((u64)ioc->reply_free_dma);
-
-       if (ioc->rdpq_array_enable) {
-               reply_post_free_array_sz = ioc->reply_queue_count *
-                   sizeof(Mpi2IOCInitRDPQArrayEntry);
-               reply_post_free_array = pci_alloc_consistent(ioc->pdev,
-                       reply_post_free_array_sz, &reply_post_free_array_dma);
-               if (!reply_post_free_array) {
-                       printk(MPT2SAS_ERR_FMT
-                       "reply_post_free_array: pci_alloc_consistent failed\n",
-                       ioc->name);
-                       r = -ENOMEM;
-                       goto out;
-               }
-               memset(reply_post_free_array, 0, reply_post_free_array_sz);
-               for (i = 0; i < ioc->reply_queue_count; i++)
-                       reply_post_free_array[i].RDPQBaseAddress =
-                           cpu_to_le64(
-                               (u64)ioc->reply_post[i].reply_post_free_dma);
-               mpi_request.MsgFlags = MPI2_IOCINIT_MSGFLAG_RDPQ_ARRAY_MODE;
-               mpi_request.ReplyDescriptorPostQueueAddress =
-                   cpu_to_le64((u64)reply_post_free_array_dma);
-       } else {
-               mpi_request.ReplyDescriptorPostQueueAddress =
-                   cpu_to_le64((u64)ioc->reply_post[0].reply_post_free_dma);
-       }
-
-       /* This time stamp specifies number of milliseconds
-        * since epoch ~ midnight January 1, 1970.
-        */
-       do_gettimeofday(&current_time);
-       mpi_request.TimeStamp = cpu_to_le64((u64)current_time.tv_sec * 1000 +
-           (current_time.tv_usec / 1000));
-
-       if (ioc->logging_level & MPT_DEBUG_INIT) {
-               __le32 *mfp;
-               int i;
-
-               mfp = (__le32 *)&mpi_request;
-               printk(KERN_INFO "\toffset:data\n");
-               for (i = 0; i < sizeof(Mpi2IOCInitRequest_t)/4; i++)
-                       printk(KERN_INFO "\t[0x%02x]:%08x\n", i*4,
-                           le32_to_cpu(mfp[i]));
-       }
-
-       r = _base_handshake_req_reply_wait(ioc,
-           sizeof(Mpi2IOCInitRequest_t), (u32 *)&mpi_request,
-           sizeof(Mpi2IOCInitReply_t), (u16 *)&mpi_reply, 10,
-           sleep_flag);
-
-       if (r != 0) {
-               printk(MPT2SAS_ERR_FMT "%s: handshake failed (r=%d)\n",
-                   ioc->name, __func__, r);
-               goto out;
-       }
-
-       ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
-       if (ioc_status != MPI2_IOCSTATUS_SUCCESS ||
-           mpi_reply.IOCLogInfo) {
-               printk(MPT2SAS_ERR_FMT "%s: failed\n", ioc->name, __func__);
-               r = -EIO;
-       }
-
-out:
-       if (reply_post_free_array)
-               pci_free_consistent(ioc->pdev, reply_post_free_array_sz,
-                                   reply_post_free_array,
-                                   reply_post_free_array_dma);
-       return r;
-}
-
-/**
- * mpt2sas_port_enable_done - command completion routine for port enable
- * @ioc: per adapter object
- * @smid: system request message index
- * @msix_index: MSIX table index supplied by the OS
- * @reply: reply message frame(lower 32bit addr)
- *
- * Return 1 meaning mf should be freed from _base_interrupt
- *        0 means the mf is freed from this function.
- */
-u8
-mpt2sas_port_enable_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
-       u32 reply)
-{
-       MPI2DefaultReply_t *mpi_reply;
-       u16 ioc_status;
-
-       mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
-       if (mpi_reply && mpi_reply->Function == MPI2_FUNCTION_EVENT_ACK)
-               return 1;
-
-       if (ioc->port_enable_cmds.status == MPT2_CMD_NOT_USED)
-               return 1;
-
-       ioc->port_enable_cmds.status |= MPT2_CMD_COMPLETE;
-       if (mpi_reply) {
-               ioc->port_enable_cmds.status |= MPT2_CMD_REPLY_VALID;
-               memcpy(ioc->port_enable_cmds.reply, mpi_reply,
-                   mpi_reply->MsgLength*4);
-       }
-       ioc->port_enable_cmds.status &= ~MPT2_CMD_PENDING;
-
-       ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
-
-       if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
-               ioc->port_enable_failed = 1;
-
-       if (ioc->is_driver_loading) {
-               if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
-                       mpt2sas_port_enable_complete(ioc);
-                       return 1;
-               } else {
-                       ioc->start_scan_failed = ioc_status;
-                       ioc->start_scan = 0;
-                       return 1;
-               }
-       }
-       complete(&ioc->port_enable_cmds.done);
-       return 1;
-}
-
-
-/**
- * _base_send_port_enable - send port_enable(discovery stuff) to firmware
- * @ioc: per adapter object
- * @sleep_flag: CAN_SLEEP or NO_SLEEP
- *
- * Returns 0 for success, non-zero for failure.
- */
-static int
-_base_send_port_enable(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
-{
-       Mpi2PortEnableRequest_t *mpi_request;
-       Mpi2PortEnableReply_t *mpi_reply;
-       unsigned long timeleft;
-       int r = 0;
-       u16 smid;
-       u16 ioc_status;
-
-       printk(MPT2SAS_INFO_FMT "sending port enable !!\n", ioc->name);
-
-       if (ioc->port_enable_cmds.status & MPT2_CMD_PENDING) {
-               printk(MPT2SAS_ERR_FMT "%s: internal command already in use\n",
-                   ioc->name, __func__);
-               return -EAGAIN;
-       }
-
-       smid = mpt2sas_base_get_smid(ioc, ioc->port_enable_cb_idx);
-       if (!smid) {
-               printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
-                   ioc->name, __func__);
-               return -EAGAIN;
-       }
-
-       ioc->port_enable_cmds.status = MPT2_CMD_PENDING;
-       mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
-       ioc->port_enable_cmds.smid = smid;
-       memset(mpi_request, 0, sizeof(Mpi2PortEnableRequest_t));
-       mpi_request->Function = MPI2_FUNCTION_PORT_ENABLE;
-
-       init_completion(&ioc->port_enable_cmds.done);
-       mpt2sas_base_put_smid_default(ioc, smid);
-       timeleft = wait_for_completion_timeout(&ioc->port_enable_cmds.done,
-           300*HZ);
-       if (!(ioc->port_enable_cmds.status & MPT2_CMD_COMPLETE)) {
-               printk(MPT2SAS_ERR_FMT "%s: timeout\n",
-                   ioc->name, __func__);
-               _debug_dump_mf(mpi_request,
-                   sizeof(Mpi2PortEnableRequest_t)/4);
-               if (ioc->port_enable_cmds.status & MPT2_CMD_RESET)
-                       r = -EFAULT;
-               else
-                       r = -ETIME;
-               goto out;
-       }
-       mpi_reply = ioc->port_enable_cmds.reply;
-
-       ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
-       if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
-               printk(MPT2SAS_ERR_FMT "%s: failed with (ioc_status=0x%08x)\n",
-                   ioc->name, __func__, ioc_status);
-               r = -EFAULT;
-               goto out;
-       }
- out:
-       ioc->port_enable_cmds.status = MPT2_CMD_NOT_USED;
-       printk(MPT2SAS_INFO_FMT "port enable: %s\n", ioc->name, ((r == 0) ?
-           "SUCCESS" : "FAILED"));
-       return r;
-}
-
-/**
- * mpt2sas_port_enable - initiate firmware discovery (don't wait for reply)
- * @ioc: per adapter object
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_port_enable(struct MPT2SAS_ADAPTER *ioc)
-{
-       Mpi2PortEnableRequest_t *mpi_request;
-       u16 smid;
-
-       printk(MPT2SAS_INFO_FMT "sending port enable !!\n", ioc->name);
-
-       if (ioc->port_enable_cmds.status & MPT2_CMD_PENDING) {
-               printk(MPT2SAS_ERR_FMT "%s: internal command already in use\n",
-                   ioc->name, __func__);
-               return -EAGAIN;
-       }
-
-       smid = mpt2sas_base_get_smid(ioc, ioc->port_enable_cb_idx);
-       if (!smid) {
-               printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
-                   ioc->name, __func__);
-               return -EAGAIN;
-       }
-
-       ioc->port_enable_cmds.status = MPT2_CMD_PENDING;
-       mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
-       ioc->port_enable_cmds.smid = smid;
-       memset(mpi_request, 0, sizeof(Mpi2PortEnableRequest_t));
-       mpi_request->Function = MPI2_FUNCTION_PORT_ENABLE;
-
-       mpt2sas_base_put_smid_default(ioc, smid);
-       return 0;
-}
-
-/**
- * _base_determine_wait_on_discovery - desposition
- * @ioc: per adapter object
- *
- * Decide whether to wait on discovery to complete. Used to either
- * locate boot device, or report volumes ahead of physical devices.
- *
- * Returns 1 for wait, 0 for don't wait
- */
-static int
-_base_determine_wait_on_discovery(struct MPT2SAS_ADAPTER *ioc)
-{
-       /* We wait for discovery to complete if IR firmware is loaded.
-        * The sas topology events arrive before PD events, so we need time to
-        * turn on the bit in ioc->pd_handles to indicate PD
-        * Also, it maybe required to report Volumes ahead of physical
-        * devices when MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING is set.
-        */
-       if (ioc->ir_firmware)
-               return 1;
-
-       /* if no Bios, then we don't need to wait */
-       if (!ioc->bios_pg3.BiosVersion)
-               return 0;
-
-       /* Bios is present, then we drop down here.
-        *
-        * If there any entries in the Bios Page 2, then we wait
-        * for discovery to complete.
-        */
-
-       /* Current Boot Device */
-       if ((ioc->bios_pg2.CurrentBootDeviceForm &
-           MPI2_BIOSPAGE2_FORM_MASK) ==
-           MPI2_BIOSPAGE2_FORM_NO_DEVICE_SPECIFIED &&
-       /* Request Boot Device */
-          (ioc->bios_pg2.ReqBootDeviceForm &
-           MPI2_BIOSPAGE2_FORM_MASK) ==
-           MPI2_BIOSPAGE2_FORM_NO_DEVICE_SPECIFIED &&
-       /* Alternate Request Boot Device */
-          (ioc->bios_pg2.ReqAltBootDeviceForm &
-           MPI2_BIOSPAGE2_FORM_MASK) ==
-           MPI2_BIOSPAGE2_FORM_NO_DEVICE_SPECIFIED)
-               return 0;
-
-       return 1;
-}
-
-
-/**
- * _base_unmask_events - turn on notification for this event
- * @ioc: per adapter object
- * @event: firmware event
- *
- * The mask is stored in ioc->event_masks.
- */
-static void
-_base_unmask_events(struct MPT2SAS_ADAPTER *ioc, u16 event)
-{
-       u32 desired_event;
-
-       if (event >= 128)
-               return;
-
-       desired_event = (1 << (event % 32));
-
-       if (event < 32)
-               ioc->event_masks[0] &= ~desired_event;
-       else if (event < 64)
-               ioc->event_masks[1] &= ~desired_event;
-       else if (event < 96)
-               ioc->event_masks[2] &= ~desired_event;
-       else if (event < 128)
-               ioc->event_masks[3] &= ~desired_event;
-}
-
-/**
- * _base_event_notification - send event notification
- * @ioc: per adapter object
- * @sleep_flag: CAN_SLEEP or NO_SLEEP
- *
- * Returns 0 for success, non-zero for failure.
- */
-static int
-_base_event_notification(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
-{
-       Mpi2EventNotificationRequest_t *mpi_request;
-       unsigned long timeleft;
-       u16 smid;
-       int r = 0;
-       int i;
-
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-           __func__));
-
-       if (ioc->base_cmds.status & MPT2_CMD_PENDING) {
-               printk(MPT2SAS_ERR_FMT "%s: internal command already in use\n",
-                   ioc->name, __func__);
-               return -EAGAIN;
-       }
-
-       smid = mpt2sas_base_get_smid(ioc, ioc->base_cb_idx);
-       if (!smid) {
-               printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
-                   ioc->name, __func__);
-               return -EAGAIN;
-       }
-       ioc->base_cmds.status = MPT2_CMD_PENDING;
-       mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
-       ioc->base_cmds.smid = smid;
-       memset(mpi_request, 0, sizeof(Mpi2EventNotificationRequest_t));
-       mpi_request->Function = MPI2_FUNCTION_EVENT_NOTIFICATION;
-       mpi_request->VF_ID = 0; /* TODO */
-       mpi_request->VP_ID = 0;
-       for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++)
-               mpi_request->EventMasks[i] =
-                   cpu_to_le32(ioc->event_masks[i]);
-       init_completion(&ioc->base_cmds.done);
-       mpt2sas_base_put_smid_default(ioc, smid);
-       timeleft = wait_for_completion_timeout(&ioc->base_cmds.done, 30*HZ);
-       if (!(ioc->base_cmds.status & MPT2_CMD_COMPLETE)) {
-               printk(MPT2SAS_ERR_FMT "%s: timeout\n",
-                   ioc->name, __func__);
-               _debug_dump_mf(mpi_request,
-                   sizeof(Mpi2EventNotificationRequest_t)/4);
-               if (ioc->base_cmds.status & MPT2_CMD_RESET)
-                       r = -EFAULT;
-               else
-                       r = -ETIME;
-       } else
-               dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: complete\n",
-                   ioc->name, __func__));
-       ioc->base_cmds.status = MPT2_CMD_NOT_USED;
-       return r;
-}
-
-/**
- * mpt2sas_base_validate_event_type - validating event types
- * @ioc: per adapter object
- * @event: firmware event
- *
- * This will turn on firmware event notification when application
- * ask for that event. We don't mask events that are already enabled.
- */
-void
-mpt2sas_base_validate_event_type(struct MPT2SAS_ADAPTER *ioc, u32 *event_type)
-{
-       int i, j;
-       u32 event_mask, desired_event;
-       u8 send_update_to_fw;
-
-       for (i = 0, send_update_to_fw = 0; i <
-           MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++) {
-               event_mask = ~event_type[i];
-               desired_event = 1;
-               for (j = 0; j < 32; j++) {
-                       if (!(event_mask & desired_event) &&
-                           (ioc->event_masks[i] & desired_event)) {
-                               ioc->event_masks[i] &= ~desired_event;
-                               send_update_to_fw = 1;
-                       }
-                       desired_event = (desired_event << 1);
-               }
-       }
-
-       if (!send_update_to_fw)
-               return;
-
-       mutex_lock(&ioc->base_cmds.mutex);
-       _base_event_notification(ioc, CAN_SLEEP);
-       mutex_unlock(&ioc->base_cmds.mutex);
-}
-
-/**
- * _base_diag_reset - the "big hammer" start of day reset
- * @ioc: per adapter object
- * @sleep_flag: CAN_SLEEP or NO_SLEEP
- *
- * Returns 0 for success, non-zero for failure.
- */
-static int
-_base_diag_reset(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
-{
-       u32 host_diagnostic;
-       u32 ioc_state;
-       u32 count;
-       u32 hcb_size;
-
-       printk(MPT2SAS_INFO_FMT "sending diag reset !!\n", ioc->name);
-       drsprintk(ioc, printk(MPT2SAS_INFO_FMT "clear interrupts\n",
-           ioc->name));
-
-       count = 0;
-       do {
-               /* Write magic sequence to WriteSequence register
-                * Loop until in diagnostic mode
-                */
-               drsprintk(ioc, printk(MPT2SAS_INFO_FMT "write magic "
-                   "sequence\n", ioc->name));
-               writel(MPI2_WRSEQ_FLUSH_KEY_VALUE, &ioc->chip->WriteSequence);
-               writel(MPI2_WRSEQ_1ST_KEY_VALUE, &ioc->chip->WriteSequence);
-               writel(MPI2_WRSEQ_2ND_KEY_VALUE, &ioc->chip->WriteSequence);
-               writel(MPI2_WRSEQ_3RD_KEY_VALUE, &ioc->chip->WriteSequence);
-               writel(MPI2_WRSEQ_4TH_KEY_VALUE, &ioc->chip->WriteSequence);
-               writel(MPI2_WRSEQ_5TH_KEY_VALUE, &ioc->chip->WriteSequence);
-               writel(MPI2_WRSEQ_6TH_KEY_VALUE, &ioc->chip->WriteSequence);
-
-               /* wait 100 msec */
-               if (sleep_flag == CAN_SLEEP)
-                       msleep(100);
-               else
-                       mdelay(100);
-
-               if (count++ > 20)
-                       goto out;
-
-               host_diagnostic = readl(&ioc->chip->HostDiagnostic);
-               drsprintk(ioc, printk(MPT2SAS_INFO_FMT "wrote magic "
-                   "sequence: count(%d), host_diagnostic(0x%08x)\n",
-                   ioc->name, count, host_diagnostic));
-
-       } while ((host_diagnostic & MPI2_DIAG_DIAG_WRITE_ENABLE) == 0);
-
-       hcb_size = readl(&ioc->chip->HCBSize);
-
-       drsprintk(ioc, printk(MPT2SAS_INFO_FMT "diag reset: issued\n",
-           ioc->name));
-       writel(host_diagnostic | MPI2_DIAG_RESET_ADAPTER,
-            &ioc->chip->HostDiagnostic);
-
-       /* This delay allows the chip PCIe hardware time to finish reset tasks*/
-       if (sleep_flag == CAN_SLEEP)
-               msleep(MPI2_HARD_RESET_PCIE_FIRST_READ_DELAY_MICRO_SEC/1000);
-       else
-               mdelay(MPI2_HARD_RESET_PCIE_FIRST_READ_DELAY_MICRO_SEC/1000);
-
-       /* Approximately 300 second max wait */
-       for (count = 0; count < (300000000 /
-           MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC); count++) {
-
-               host_diagnostic = readl(&ioc->chip->HostDiagnostic);
-
-               if (host_diagnostic == 0xFFFFFFFF)
-                       goto out;
-               if (!(host_diagnostic & MPI2_DIAG_RESET_ADAPTER))
-                       break;
-
-               /* Wait to pass the second read delay window */
-               if (sleep_flag == CAN_SLEEP)
-                       msleep(MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC
-                              /1000);
-               else
-                       mdelay(MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC
-                              /1000);
-       }
-
-       if (host_diagnostic & MPI2_DIAG_HCB_MODE) {
-
-               drsprintk(ioc, printk(MPT2SAS_INFO_FMT "restart the adapter "
-                   "assuming the HCB Address points to good F/W\n",
-                   ioc->name));
-               host_diagnostic &= ~MPI2_DIAG_BOOT_DEVICE_SELECT_MASK;
-               host_diagnostic |= MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW;
-               writel(host_diagnostic, &ioc->chip->HostDiagnostic);
-
-               drsprintk(ioc, printk(MPT2SAS_INFO_FMT
-                   "re-enable the HCDW\n", ioc->name));
-               writel(hcb_size | MPI2_HCB_SIZE_HCB_ENABLE,
-                   &ioc->chip->HCBSize);
-       }
-
-       drsprintk(ioc, printk(MPT2SAS_INFO_FMT "restart the adapter\n",
-           ioc->name));
-       writel(host_diagnostic & ~MPI2_DIAG_HOLD_IOC_RESET,
-           &ioc->chip->HostDiagnostic);
-
-       drsprintk(ioc, printk(MPT2SAS_INFO_FMT "disable writes to the "
-           "diagnostic register\n", ioc->name));
-       writel(MPI2_WRSEQ_FLUSH_KEY_VALUE, &ioc->chip->WriteSequence);
-
-       drsprintk(ioc, printk(MPT2SAS_INFO_FMT "Wait for FW to go to the "
-           "READY state\n", ioc->name));
-       ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_READY, 20,
-           sleep_flag);
-       if (ioc_state) {
-               printk(MPT2SAS_ERR_FMT "%s: failed going to ready state "
-                   " (ioc_state=0x%x)\n", ioc->name, __func__, ioc_state);
-               goto out;
-       }
-
-       printk(MPT2SAS_INFO_FMT "diag reset: SUCCESS\n", ioc->name);
-       return 0;
-
- out:
-       printk(MPT2SAS_ERR_FMT "diag reset: FAILED\n", ioc->name);
-       return -EFAULT;
-}
-
-/**
- * _base_make_ioc_ready - put controller in READY state
- * @ioc: per adapter object
- * @sleep_flag: CAN_SLEEP or NO_SLEEP
- * @type: FORCE_BIG_HAMMER or SOFT_RESET
- *
- * Returns 0 for success, non-zero for failure.
- */
-static int
-_base_make_ioc_ready(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
-    enum reset_type type)
-{
-       u32 ioc_state;
-       int rc;
-
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-           __func__));
-
-       if (ioc->pci_error_recovery)
-               return 0;
-
-       ioc_state = mpt2sas_base_get_iocstate(ioc, 0);
-       dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: ioc_state(0x%08x)\n",
-           ioc->name, __func__, ioc_state));
-
-       if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_READY)
-               return 0;
-
-       if (ioc_state & MPI2_DOORBELL_USED) {
-               dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "unexpected doorbell "
-                   "active!\n", ioc->name));
-               goto issue_diag_reset;
-       }
-
-       if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) {
-               mpt2sas_base_fault_info(ioc, ioc_state &
-                   MPI2_DOORBELL_DATA_MASK);
-               goto issue_diag_reset;
-       }
-
-       if (type == FORCE_BIG_HAMMER)
-               goto issue_diag_reset;
-
-       if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_OPERATIONAL)
-               if (!(_base_send_ioc_reset(ioc,
-                   MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET, 15, CAN_SLEEP))) {
-                       ioc->ioc_reset_count++;
-                       return 0;
-       }
-
- issue_diag_reset:
-       rc = _base_diag_reset(ioc, CAN_SLEEP);
-       ioc->ioc_reset_count++;
-       return rc;
-}
-
-/**
- * _base_make_ioc_operational - put controller in OPERATIONAL state
- * @ioc: per adapter object
- * @sleep_flag: CAN_SLEEP or NO_SLEEP
- *
- * Returns 0 for success, non-zero for failure.
- */
-static int
-_base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
-{
-       int r, i;
-       unsigned long   flags;
-       u32 reply_address;
-       u16 smid;
-       struct _tr_list *delayed_tr, *delayed_tr_next;
-       u8 hide_flag;
-       struct adapter_reply_queue *reply_q;
-       long reply_post_free;
-       u32 reply_post_free_sz, index = 0;
-
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-           __func__));
-
-       /* clean the delayed target reset list */
-       list_for_each_entry_safe(delayed_tr, delayed_tr_next,
-           &ioc->delayed_tr_list, list) {
-               list_del(&delayed_tr->list);
-               kfree(delayed_tr);
-       }
-
-       list_for_each_entry_safe(delayed_tr, delayed_tr_next,
-           &ioc->delayed_tr_volume_list, list) {
-               list_del(&delayed_tr->list);
-               kfree(delayed_tr);
-       }
-
-       /* initialize the scsi lookup free list */
-       spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-       INIT_LIST_HEAD(&ioc->free_list);
-       smid = 1;
-       for (i = 0; i < ioc->scsiio_depth; i++, smid++) {
-               INIT_LIST_HEAD(&ioc->scsi_lookup[i].chain_list);
-               ioc->scsi_lookup[i].cb_idx = 0xFF;
-               ioc->scsi_lookup[i].smid = smid;
-               ioc->scsi_lookup[i].scmd = NULL;
-               ioc->scsi_lookup[i].direct_io = 0;
-               list_add_tail(&ioc->scsi_lookup[i].tracker_list,
-                   &ioc->free_list);
-       }
-
-       /* hi-priority queue */
-       INIT_LIST_HEAD(&ioc->hpr_free_list);
-       smid = ioc->hi_priority_smid;
-       for (i = 0; i < ioc->hi_priority_depth; i++, smid++) {
-               ioc->hpr_lookup[i].cb_idx = 0xFF;
-               ioc->hpr_lookup[i].smid = smid;
-               list_add_tail(&ioc->hpr_lookup[i].tracker_list,
-                   &ioc->hpr_free_list);
-       }
-
-       /* internal queue */
-       INIT_LIST_HEAD(&ioc->internal_free_list);
-       smid = ioc->internal_smid;
-       for (i = 0; i < ioc->internal_depth; i++, smid++) {
-               ioc->internal_lookup[i].cb_idx = 0xFF;
-               ioc->internal_lookup[i].smid = smid;
-               list_add_tail(&ioc->internal_lookup[i].tracker_list,
-                   &ioc->internal_free_list);
-       }
-
-       /* chain pool */
-       INIT_LIST_HEAD(&ioc->free_chain_list);
-       for (i = 0; i < ioc->chain_depth; i++)
-               list_add_tail(&ioc->chain_lookup[i].tracker_list,
-                   &ioc->free_chain_list);
-
-       spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
-
-       /* initialize Reply Free Queue */
-       for (i = 0, reply_address = (u32)ioc->reply_dma ;
-           i < ioc->reply_free_queue_depth ; i++, reply_address +=
-           ioc->reply_sz)
-               ioc->reply_free[i] = cpu_to_le32(reply_address);
-
-       /* initialize reply queues */
-       if (ioc->is_driver_loading)
-               _base_assign_reply_queues(ioc);
-
-       /* initialize Reply Post Free Queue */
-       reply_post_free_sz = ioc->reply_post_queue_depth *
-           sizeof(Mpi2DefaultReplyDescriptor_t);
-       reply_post_free = (long)ioc->reply_post[index].reply_post_free;
-       list_for_each_entry(reply_q, &ioc->reply_queue_list, list) {
-               reply_q->reply_post_host_index = 0;
-               reply_q->reply_post_free = (Mpi2ReplyDescriptorsUnion_t *)
-                   reply_post_free;
-               for (i = 0; i < ioc->reply_post_queue_depth; i++)
-                       reply_q->reply_post_free[i].Words =
-                                                    cpu_to_le64(ULLONG_MAX);
-               if (!_base_is_controller_msix_enabled(ioc))
-                       goto skip_init_reply_post_free_queue;
-               /*
-                * If RDPQ is enabled, switch to the next allocation.
-                * Otherwise advance within the contiguous region.
-                */
-               if (ioc->rdpq_array_enable)
-                       reply_post_free = (long)
-                           ioc->reply_post[++index].reply_post_free;
-               else
-                       reply_post_free += reply_post_free_sz;
-       }
- skip_init_reply_post_free_queue:
-
-       r = _base_send_ioc_init(ioc, sleep_flag);
-       if (r)
-               return r;
-
-       /* initialize reply free host index */
-       ioc->reply_free_host_index = ioc->reply_free_queue_depth - 1;
-       writel(ioc->reply_free_host_index, &ioc->chip->ReplyFreeHostIndex);
-
-       /* initialize reply post host index */
-       list_for_each_entry(reply_q, &ioc->reply_queue_list, list) {
-               writel(reply_q->msix_index << MPI2_RPHI_MSIX_INDEX_SHIFT,
-                   &ioc->chip->ReplyPostHostIndex);
-               if (!_base_is_controller_msix_enabled(ioc))
-                       goto skip_init_reply_post_host_index;
-       }
-
- skip_init_reply_post_host_index:
-
-       _base_unmask_interrupts(ioc);
-
-       r = _base_event_notification(ioc, sleep_flag);
-       if (r)
-               return r;
-
-       if (sleep_flag == CAN_SLEEP)
-               _base_static_config_pages(ioc);
-
-
-       if (ioc->is_driver_loading) {
-               if (ioc->is_warpdrive && ioc->manu_pg10.OEMIdentifier
-                   == 0x80) {
-                       hide_flag = (u8) (
-                           le32_to_cpu(ioc->manu_pg10.OEMSpecificFlags0) &
-                           MFG_PAGE10_HIDE_SSDS_MASK);
-                       if (hide_flag != MFG_PAGE10_HIDE_SSDS_MASK)
-                               ioc->mfg_pg10_hide_flag = hide_flag;
-               }
-               ioc->wait_for_discovery_to_complete =
-                   _base_determine_wait_on_discovery(ioc);
-               return r; /* scan_start and scan_finished support */
-       }
-       r = _base_send_port_enable(ioc, sleep_flag);
-       if (r)
-               return r;
-
-       return r;
-}
-
-/**
- * mpt2sas_base_free_resources - free resources controller resources (io/irq/memap)
- * @ioc: per adapter object
- *
- * Return nothing.
- */
-void
-mpt2sas_base_free_resources(struct MPT2SAS_ADAPTER *ioc)
-{
-       struct pci_dev *pdev = ioc->pdev;
-
-       dexitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-           __func__));
-
-       /* synchronizing freeing resource with pci_access_mutex lock */
-       mutex_lock(&ioc->pci_access_mutex);
-       if (ioc->chip_phys && ioc->chip) {
-               _base_mask_interrupts(ioc);
-               ioc->shost_recovery = 1;
-               _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET);
-               ioc->shost_recovery = 0;
-       }
-
-       _base_free_irq(ioc);
-       _base_disable_msix(ioc);
-
-       if (ioc->chip_phys && ioc->chip)
-               iounmap(ioc->chip);
-       ioc->chip_phys = 0;
-
-       if (pci_is_enabled(pdev)) {
-               pci_release_selected_regions(ioc->pdev, ioc->bars);
-               pci_disable_pcie_error_reporting(pdev);
-               pci_disable_device(pdev);
-       }
-       mutex_unlock(&ioc->pci_access_mutex);
-       return;
-}
-
-/**
- * mpt2sas_base_attach - attach controller instance
- * @ioc: per adapter object
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
-{
-       int r, i;
-       int cpu_id, last_cpu_id = 0;
-
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-           __func__));
-
-       /* setup cpu_msix_table */
-       ioc->cpu_count = num_online_cpus();
-       for_each_online_cpu(cpu_id)
-               last_cpu_id = cpu_id;
-       ioc->cpu_msix_table_sz = last_cpu_id + 1;
-       ioc->cpu_msix_table = kzalloc(ioc->cpu_msix_table_sz, GFP_KERNEL);
-       ioc->reply_queue_count = 1;
-       if (!ioc->cpu_msix_table) {
-               dfailprintk(ioc, printk(MPT2SAS_INFO_FMT "allocation for "
-                   "cpu_msix_table failed!!!\n", ioc->name));
-               r = -ENOMEM;
-               goto out_free_resources;
-       }
-
-       if (ioc->is_warpdrive) {
-               ioc->reply_post_host_index = kcalloc(ioc->cpu_msix_table_sz,
-                   sizeof(resource_size_t *), GFP_KERNEL);
-               if (!ioc->reply_post_host_index) {
-                       dfailprintk(ioc, printk(MPT2SAS_INFO_FMT "allocation "
-                               "for cpu_msix_table failed!!!\n", ioc->name));
-                       r = -ENOMEM;
-                       goto out_free_resources;
-               }
-       }
-
-       ioc->rdpq_array_enable_assigned = 0;
-       ioc->dma_mask = 0;
-       r = mpt2sas_base_map_resources(ioc);
-       if (r)
-               goto out_free_resources;
-
-       if (ioc->is_warpdrive) {
-               ioc->reply_post_host_index[0] = (resource_size_t __iomem *)
-                   &ioc->chip->ReplyPostHostIndex;
-
-               for (i = 1; i < ioc->cpu_msix_table_sz; i++)
-                       ioc->reply_post_host_index[i] =
-                       (resource_size_t __iomem *)
-                       ((u8 __iomem *)&ioc->chip->Doorbell + (0x4000 + ((i - 1)
-                       * 4)));
-       }
-
-       pci_set_drvdata(ioc->pdev, ioc->shost);
-       r = _base_get_ioc_facts(ioc, CAN_SLEEP);
-       if (r)
-               goto out_free_resources;
-
-       r = _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET);
-       if (r)
-               goto out_free_resources;
-
-       ioc->pfacts = kcalloc(ioc->facts.NumberOfPorts,
-           sizeof(struct mpt2sas_port_facts), GFP_KERNEL);
-       if (!ioc->pfacts) {
-               r = -ENOMEM;
-               goto out_free_resources;
-       }
-
-       for (i = 0 ; i < ioc->facts.NumberOfPorts; i++) {
-               r = _base_get_port_facts(ioc, i, CAN_SLEEP);
-               if (r)
-                       goto out_free_resources;
-       }
-
-       r = _base_allocate_memory_pools(ioc, CAN_SLEEP);
-       if (r)
-               goto out_free_resources;
-
-       init_waitqueue_head(&ioc->reset_wq);
-       /* allocate memory pd handle bitmask list */
-       ioc->pd_handles_sz = (ioc->facts.MaxDevHandle / 8);
-       if (ioc->facts.MaxDevHandle % 8)
-               ioc->pd_handles_sz++;
-       ioc->pd_handles = kzalloc(ioc->pd_handles_sz,
-           GFP_KERNEL);
-       if (!ioc->pd_handles) {
-               r = -ENOMEM;
-               goto out_free_resources;
-       }
-       ioc->blocking_handles = kzalloc(ioc->pd_handles_sz,
-           GFP_KERNEL);
-       if (!ioc->blocking_handles) {
-               r = -ENOMEM;
-               goto out_free_resources;
-       }
-       ioc->fwfault_debug = mpt2sas_fwfault_debug;
-
-       /* base internal command bits */
-       mutex_init(&ioc->base_cmds.mutex);
-       ioc->base_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
-       ioc->base_cmds.status = MPT2_CMD_NOT_USED;
-
-       /* port_enable command bits */
-       ioc->port_enable_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
-       ioc->port_enable_cmds.status = MPT2_CMD_NOT_USED;
-
-       /* transport internal command bits */
-       ioc->transport_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
-       ioc->transport_cmds.status = MPT2_CMD_NOT_USED;
-       mutex_init(&ioc->transport_cmds.mutex);
-
-       /* scsih internal command bits */
-       ioc->scsih_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
-       ioc->scsih_cmds.status = MPT2_CMD_NOT_USED;
-       mutex_init(&ioc->scsih_cmds.mutex);
-
-       /* task management internal command bits */
-       ioc->tm_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
-       ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
-       mutex_init(&ioc->tm_cmds.mutex);
-
-       /* config page internal command bits */
-       ioc->config_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
-       ioc->config_cmds.status = MPT2_CMD_NOT_USED;
-       mutex_init(&ioc->config_cmds.mutex);
-
-       /* ctl module internal command bits */
-       ioc->ctl_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
-       ioc->ctl_cmds.sense = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL);
-       ioc->ctl_cmds.status = MPT2_CMD_NOT_USED;
-       mutex_init(&ioc->ctl_cmds.mutex);
-
-       if (!ioc->base_cmds.reply || !ioc->transport_cmds.reply ||
-           !ioc->scsih_cmds.reply || !ioc->tm_cmds.reply ||
-           !ioc->config_cmds.reply || !ioc->ctl_cmds.reply ||
-           !ioc->ctl_cmds.sense) {
-               r = -ENOMEM;
-               goto out_free_resources;
-       }
-
-       if (!ioc->base_cmds.reply || !ioc->transport_cmds.reply ||
-           !ioc->scsih_cmds.reply || !ioc->tm_cmds.reply ||
-           !ioc->config_cmds.reply || !ioc->ctl_cmds.reply) {
-               r = -ENOMEM;
-               goto out_free_resources;
-       }
-
-       for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++)
-               ioc->event_masks[i] = -1;
-
-       /* here we enable the events we care about */
-       _base_unmask_events(ioc, MPI2_EVENT_SAS_DISCOVERY);
-       _base_unmask_events(ioc, MPI2_EVENT_SAS_BROADCAST_PRIMITIVE);
-       _base_unmask_events(ioc, MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST);
-       _base_unmask_events(ioc, MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE);
-       _base_unmask_events(ioc, MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE);
-       _base_unmask_events(ioc, MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST);
-       _base_unmask_events(ioc, MPI2_EVENT_IR_VOLUME);
-       _base_unmask_events(ioc, MPI2_EVENT_IR_PHYSICAL_DISK);
-       _base_unmask_events(ioc, MPI2_EVENT_IR_OPERATION_STATUS);
-       _base_unmask_events(ioc, MPI2_EVENT_LOG_ENTRY_ADDED);
-       _base_unmask_events(ioc, MPI2_EVENT_TEMP_THRESHOLD);
-       r = _base_make_ioc_operational(ioc, CAN_SLEEP);
-       if (r)
-               goto out_free_resources;
-
-       ioc->non_operational_loop = 0;
-
-       return 0;
-
- out_free_resources:
-
-       ioc->remove_host = 1;
-       mpt2sas_base_free_resources(ioc);
-       _base_release_memory_pools(ioc);
-       pci_set_drvdata(ioc->pdev, NULL);
-       kfree(ioc->cpu_msix_table);
-       if (ioc->is_warpdrive)
-               kfree(ioc->reply_post_host_index);
-       kfree(ioc->pd_handles);
-       kfree(ioc->blocking_handles);
-       kfree(ioc->tm_cmds.reply);
-       kfree(ioc->transport_cmds.reply);
-       kfree(ioc->scsih_cmds.reply);
-       kfree(ioc->config_cmds.reply);
-       kfree(ioc->base_cmds.reply);
-       kfree(ioc->port_enable_cmds.reply);
-       kfree(ioc->ctl_cmds.reply);
-       kfree(ioc->ctl_cmds.sense);
-       kfree(ioc->pfacts);
-       ioc->ctl_cmds.reply = NULL;
-       ioc->base_cmds.reply = NULL;
-       ioc->tm_cmds.reply = NULL;
-       ioc->scsih_cmds.reply = NULL;
-       ioc->transport_cmds.reply = NULL;
-       ioc->config_cmds.reply = NULL;
-       ioc->pfacts = NULL;
-       return r;
-}
-
-
-/**
- * mpt2sas_base_detach - remove controller instance
- * @ioc: per adapter object
- *
- * Return nothing.
- */
-void
-mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc)
-{
-
-       dexitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-           __func__));
-
-       mpt2sas_base_stop_watchdog(ioc);
-       mpt2sas_base_free_resources(ioc);
-       _base_release_memory_pools(ioc);
-       pci_set_drvdata(ioc->pdev, NULL);
-       kfree(ioc->cpu_msix_table);
-       if (ioc->is_warpdrive)
-               kfree(ioc->reply_post_host_index);
-       kfree(ioc->pd_handles);
-       kfree(ioc->blocking_handles);
-       kfree(ioc->pfacts);
-       kfree(ioc->ctl_cmds.reply);
-       kfree(ioc->ctl_cmds.sense);
-       kfree(ioc->base_cmds.reply);
-       kfree(ioc->port_enable_cmds.reply);
-       kfree(ioc->tm_cmds.reply);
-       kfree(ioc->transport_cmds.reply);
-       kfree(ioc->scsih_cmds.reply);
-       kfree(ioc->config_cmds.reply);
-}
-
-/**
- * _base_reset_handler - reset callback handler (for base)
- * @ioc: per adapter object
- * @reset_phase: phase
- *
- * The handler for doing any required cleanup or initialization.
- *
- * The reset phase can be MPT2_IOC_PRE_RESET, MPT2_IOC_AFTER_RESET,
- * MPT2_IOC_DONE_RESET
- *
- * Return nothing.
- */
-static void
-_base_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
-{
-       mpt2sas_scsih_reset_handler(ioc, reset_phase);
-       mpt2sas_ctl_reset_handler(ioc, reset_phase);
-       switch (reset_phase) {
-       case MPT2_IOC_PRE_RESET:
-               dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
-                   "MPT2_IOC_PRE_RESET\n", ioc->name, __func__));
-               break;
-       case MPT2_IOC_AFTER_RESET:
-               dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
-                   "MPT2_IOC_AFTER_RESET\n", ioc->name, __func__));
-               if (ioc->transport_cmds.status & MPT2_CMD_PENDING) {
-                       ioc->transport_cmds.status |= MPT2_CMD_RESET;
-                       mpt2sas_base_free_smid(ioc, ioc->transport_cmds.smid);
-                       complete(&ioc->transport_cmds.done);
-               }
-               if (ioc->base_cmds.status & MPT2_CMD_PENDING) {
-                       ioc->base_cmds.status |= MPT2_CMD_RESET;
-                       mpt2sas_base_free_smid(ioc, ioc->base_cmds.smid);
-                       complete(&ioc->base_cmds.done);
-               }
-               if (ioc->port_enable_cmds.status & MPT2_CMD_PENDING) {
-                       ioc->port_enable_failed = 1;
-                       ioc->port_enable_cmds.status |= MPT2_CMD_RESET;
-                       mpt2sas_base_free_smid(ioc, ioc->port_enable_cmds.smid);
-                       if (ioc->is_driver_loading) {
-                               ioc->start_scan_failed =
-                                   MPI2_IOCSTATUS_INTERNAL_ERROR;
-                               ioc->start_scan = 0;
-                               ioc->port_enable_cmds.status =
-                                               MPT2_CMD_NOT_USED;
-                       } else
-                               complete(&ioc->port_enable_cmds.done);
-
-               }
-               if (ioc->config_cmds.status & MPT2_CMD_PENDING) {
-                       ioc->config_cmds.status |= MPT2_CMD_RESET;
-                       mpt2sas_base_free_smid(ioc, ioc->config_cmds.smid);
-                       ioc->config_cmds.smid = USHRT_MAX;
-                       complete(&ioc->config_cmds.done);
-               }
-               break;
-       case MPT2_IOC_DONE_RESET:
-               dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
-                   "MPT2_IOC_DONE_RESET\n", ioc->name, __func__));
-               break;
-       }
-}
-
-/**
- * _wait_for_commands_to_complete - reset controller
- * @ioc: Pointer to MPT_ADAPTER structure
- * @sleep_flag: CAN_SLEEP or NO_SLEEP
- *
- * This function waiting(3s) for all pending commands to complete
- * prior to putting controller in reset.
- */
-static void
-_wait_for_commands_to_complete(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
-{
-       u32 ioc_state;
-       unsigned long flags;
-       u16 i;
-
-       ioc->pending_io_count = 0;
-       if (sleep_flag != CAN_SLEEP)
-               return;
-
-       ioc_state = mpt2sas_base_get_iocstate(ioc, 0);
-       if ((ioc_state & MPI2_IOC_STATE_MASK) != MPI2_IOC_STATE_OPERATIONAL)
-               return;
-
-       /* pending command count */
-       spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-       for (i = 0; i < ioc->scsiio_depth; i++)
-               if (ioc->scsi_lookup[i].cb_idx != 0xFF)
-                       ioc->pending_io_count++;
-       spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
-
-       if (!ioc->pending_io_count)
-               return;
-
-       /* wait for pending commands to complete */
-       wait_event_timeout(ioc->reset_wq, ioc->pending_io_count == 0, 10 * HZ);
-}
-
-/**
- * mpt2sas_base_hard_reset_handler - reset controller
- * @ioc: Pointer to MPT_ADAPTER structure
- * @sleep_flag: CAN_SLEEP or NO_SLEEP
- * @type: FORCE_BIG_HAMMER or SOFT_RESET
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
-    enum reset_type type)
-{
-       int r;
-       unsigned long flags;
-
-       dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
-           __func__));
-
-       if (ioc->pci_error_recovery) {
-               printk(MPT2SAS_ERR_FMT "%s: pci error recovery reset\n",
-                   ioc->name, __func__);
-               r = 0;
-               goto out_unlocked;
-       }
-
-       if (mpt2sas_fwfault_debug)
-               mpt2sas_halt_firmware(ioc);
-
-       /* TODO - What we really should be doing is pulling
-        * out all the code associated with NO_SLEEP; its never used.
-        * That is legacy code from mpt fusion driver, ported over.
-        * I will leave this BUG_ON here for now till its been resolved.
-        */
-       BUG_ON(sleep_flag == NO_SLEEP);
-
-       /* wait for an active reset in progress to complete */
-       if (!mutex_trylock(&ioc->reset_in_progress_mutex)) {
-               do {
-                       ssleep(1);
-               } while (ioc->shost_recovery == 1);
-               dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: exit\n", ioc->name,
-                   __func__));
-               return ioc->ioc_reset_in_progress_status;
-       }
-
-       spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
-       ioc->shost_recovery = 1;
-       spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
-
-       _base_reset_handler(ioc, MPT2_IOC_PRE_RESET);
-       _wait_for_commands_to_complete(ioc, sleep_flag);
-       _base_mask_interrupts(ioc);
-       r = _base_make_ioc_ready(ioc, sleep_flag, type);
-       if (r)
-               goto out;
-       _base_reset_handler(ioc, MPT2_IOC_AFTER_RESET);
-
-       /* If this hard reset is called while port enable is active, then
-        * there is no reason to call make_ioc_operational
-        */
-       if (ioc->is_driver_loading && ioc->port_enable_failed) {
-               ioc->remove_host = 1;
-               r = -EFAULT;
-               goto out;
-       }
-
-       r = _base_get_ioc_facts(ioc, CAN_SLEEP);
-       if (r)
-               goto out;
-
-       if (ioc->rdpq_array_enable && !ioc->rdpq_array_capable)
-               panic("%s: Issue occurred with flashing controller firmware."
-                     "Please reboot the system and ensure that the correct"
-                     " firmware version is running\n", ioc->name);
-
-       r = _base_make_ioc_operational(ioc, sleep_flag);
-       if (!r)
-               _base_reset_handler(ioc, MPT2_IOC_DONE_RESET);
- out:
-       dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: %s\n",
-           ioc->name, __func__, ((r == 0) ? "SUCCESS" : "FAILED")));
-
-       spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
-       ioc->ioc_reset_in_progress_status = r;
-       ioc->shost_recovery = 0;
-       spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
-       mutex_unlock(&ioc->reset_in_progress_mutex);
-
- out_unlocked:
-       dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: exit\n", ioc->name,
-           __func__));
-       return r;
-}
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h
deleted file mode 100644 (file)
index 97ea360..0000000
+++ /dev/null
@@ -1,1235 +0,0 @@
-/*
- * This is the Fusion MPT base driver providing common API layer interface
- * for access to MPT (Message Passing Technology) firmware.
- *
- * This code is based on drivers/scsi/mpt2sas/mpt2_base.h
- * Copyright (C) 2007-2014  LSI Corporation
- * Copyright (C) 20013-2014 Avago Technologies
- *  (mailto: MPT-FusionLinux.pdl@avagotech.com)
- *
- * 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.
- *
- * NO WARRANTY
- * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
- * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
- * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
- * solely responsible for determining the appropriateness of using and
- * distributing the Program and assumes all risks associated with its
- * exercise of rights under this Agreement, including but not limited to
- * the risks and costs of program errors, damage to or loss of data,
- * programs or equipment, and unavailability or interruption of operations.
-
- * DISCLAIMER OF LIABILITY
- * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
- * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
- * USA.
- */
-
-#ifndef MPT2SAS_BASE_H_INCLUDED
-#define MPT2SAS_BASE_H_INCLUDED
-
-#include "mpi/mpi2_type.h"
-#include "mpi/mpi2.h"
-#include "mpi/mpi2_ioc.h"
-#include "mpi/mpi2_cnfg.h"
-#include "mpi/mpi2_init.h"
-#include "mpi/mpi2_raid.h"
-#include "mpi/mpi2_tool.h"
-#include "mpi/mpi2_sas.h"
-
-#include <scsi/scsi.h>
-#include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_device.h>
-#include <scsi/scsi_host.h>
-#include <scsi/scsi_tcq.h>
-#include <scsi/scsi_transport_sas.h>
-#include <scsi/scsi_dbg.h>
-#include <scsi/scsi_eh.h>
-
-#include "mpt2sas_debug.h"
-
-/* driver versioning info */
-#define MPT2SAS_DRIVER_NAME            "mpt2sas"
-#define MPT2SAS_AUTHOR "Avago Technologies <MPT-FusionLinux.pdl@avagotech.com>"
-#define MPT2SAS_DESCRIPTION    "LSI MPT Fusion SAS 2.0 Device Driver"
-#define MPT2SAS_DRIVER_VERSION         "20.100.00.00"
-#define MPT2SAS_MAJOR_VERSION          20
-#define MPT2SAS_MINOR_VERSION          100
-#define MPT2SAS_BUILD_VERSION          00
-#define MPT2SAS_RELEASE_VERSION                00
-
-/*
- * Set MPT2SAS_SG_DEPTH value based on user input.
- */
-#ifdef CONFIG_SCSI_MPT2SAS_MAX_SGE
-#if     CONFIG_SCSI_MPT2SAS_MAX_SGE  < 16
-#define MPT2SAS_SG_DEPTH       16
-#elif CONFIG_SCSI_MPT2SAS_MAX_SGE  > 128
-#define MPT2SAS_SG_DEPTH       128
-#else
-#define MPT2SAS_SG_DEPTH       CONFIG_SCSI_MPT2SAS_MAX_SGE
-#endif
-#else
-#define MPT2SAS_SG_DEPTH       128 /* MAX_HW_SEGMENTS */
-#endif
-
-
-/*
- * Generic Defines
- */
-#define MPT2SAS_SATA_QUEUE_DEPTH       32
-#define MPT2SAS_SAS_QUEUE_DEPTH                254
-#define MPT2SAS_RAID_QUEUE_DEPTH       128
-
-#define MPT_NAME_LENGTH                        32      /* generic length of strings */
-#define MPT_STRING_LENGTH              64
-
-#define MPT_MAX_CALLBACKS              16
-
-
-#define         CAN_SLEEP                      1
-#define  NO_SLEEP                      0
-
-#define INTERNAL_CMDS_COUNT            10      /* reserved cmds */
-
-#define MPI2_HIM_MASK                  0xFFFFFFFF /* mask every bit*/
-
-#define MPT2SAS_INVALID_DEVICE_HANDLE  0xFFFF
-
-
-/*
- * reset phases
- */
-#define MPT2_IOC_PRE_RESET             1 /* prior to host reset */
-#define MPT2_IOC_AFTER_RESET           2 /* just after host reset */
-#define MPT2_IOC_DONE_RESET            3 /* links re-initialized */
-
-/*
- * logging format
- */
-#define MPT2SAS_FMT                    "%s: "
-#define MPT2SAS_INFO_FMT               KERN_INFO MPT2SAS_FMT
-#define MPT2SAS_NOTE_FMT               KERN_NOTICE MPT2SAS_FMT
-#define MPT2SAS_WARN_FMT               KERN_WARNING MPT2SAS_FMT
-#define MPT2SAS_ERR_FMT                        KERN_ERR MPT2SAS_FMT
-
-/*
- * Dell HBA branding
- */
-#define MPT2SAS_DELL_BRANDING_SIZE                 32
-
-#define MPT2SAS_DELL_6GBPS_SAS_HBA_BRANDING        "Dell 6Gbps SAS HBA"
-#define MPT2SAS_DELL_PERC_H200_ADAPTER_BRANDING    "Dell PERC H200 Adapter"
-#define MPT2SAS_DELL_PERC_H200_INTEGRATED_BRANDING "Dell PERC H200 Integrated"
-#define MPT2SAS_DELL_PERC_H200_MODULAR_BRANDING    "Dell PERC H200 Modular"
-#define MPT2SAS_DELL_PERC_H200_EMBEDDED_BRANDING   "Dell PERC H200 Embedded"
-#define MPT2SAS_DELL_PERC_H200_BRANDING            "Dell PERC H200"
-#define MPT2SAS_DELL_6GBPS_SAS_BRANDING            "Dell 6Gbps SAS"
-
-/*
- * Dell HBA SSDIDs
- */
-#define MPT2SAS_DELL_6GBPS_SAS_HBA_SSDID           0x1F1C
-#define MPT2SAS_DELL_PERC_H200_ADAPTER_SSDID       0x1F1D
-#define MPT2SAS_DELL_PERC_H200_INTEGRATED_SSDID    0x1F1E
-#define MPT2SAS_DELL_PERC_H200_MODULAR_SSDID       0x1F1F
-#define MPT2SAS_DELL_PERC_H200_EMBEDDED_SSDID      0x1F20
-#define MPT2SAS_DELL_PERC_H200_SSDID               0x1F21
-#define MPT2SAS_DELL_6GBPS_SAS_SSDID               0x1F22
-
-/*
- * Intel HBA branding
- */
-#define MPT2SAS_INTEL_RMS25JB080_BRANDING    \
-                               "Intel(R) Integrated RAID Module RMS25JB080"
-#define MPT2SAS_INTEL_RMS25JB040_BRANDING    \
-                               "Intel(R) Integrated RAID Module RMS25JB040"
-#define MPT2SAS_INTEL_RMS25KB080_BRANDING    \
-                               "Intel(R) Integrated RAID Module RMS25KB080"
-#define MPT2SAS_INTEL_RMS25KB040_BRANDING    \
-                               "Intel(R) Integrated RAID Module RMS25KB040"
-#define MPT2SAS_INTEL_RMS25LB040_BRANDING      \
-                               "Intel(R) Integrated RAID Module RMS25LB040"
-#define MPT2SAS_INTEL_RMS25LB080_BRANDING      \
-                               "Intel(R) Integrated RAID Module RMS25LB080"
-#define MPT2SAS_INTEL_RMS2LL080_BRANDING       \
-                               "Intel Integrated RAID Module RMS2LL080"
-#define MPT2SAS_INTEL_RMS2LL040_BRANDING       \
-                               "Intel Integrated RAID Module RMS2LL040"
-#define MPT2SAS_INTEL_RS25GB008_BRANDING       \
-                               "Intel(R) RAID Controller RS25GB008"
-#define MPT2SAS_INTEL_SSD910_BRANDING          \
-                               "Intel(R) SSD 910 Series"
-/*
- * Intel HBA SSDIDs
- */
-#define MPT2SAS_INTEL_RMS25JB080_SSDID         0x3516
-#define MPT2SAS_INTEL_RMS25JB040_SSDID         0x3517
-#define MPT2SAS_INTEL_RMS25KB080_SSDID         0x3518
-#define MPT2SAS_INTEL_RMS25KB040_SSDID         0x3519
-#define MPT2SAS_INTEL_RMS25LB040_SSDID         0x351A
-#define MPT2SAS_INTEL_RMS25LB080_SSDID         0x351B
-#define MPT2SAS_INTEL_RMS2LL080_SSDID          0x350E
-#define MPT2SAS_INTEL_RMS2LL040_SSDID          0x350F
-#define MPT2SAS_INTEL_RS25GB008_SSDID          0x3000
-#define MPT2SAS_INTEL_SSD910_SSDID             0x3700
-
-/*
- * HP HBA branding
- */
-#define MPT2SAS_HP_3PAR_SSVID                0x1590
-#define MPT2SAS_HP_2_4_INTERNAL_BRANDING        "HP H220 Host Bus Adapter"
-#define MPT2SAS_HP_2_4_EXTERNAL_BRANDING        "HP H221 Host Bus Adapter"
-#define MPT2SAS_HP_1_4_INTERNAL_1_4_EXTERNAL_BRANDING "HP H222 Host Bus Adapter"
-#define MPT2SAS_HP_EMBEDDED_2_4_INTERNAL_BRANDING    "HP H220i Host Bus Adapter"
-#define MPT2SAS_HP_DAUGHTER_2_4_INTERNAL_BRANDING    "HP H210i Host Bus Adapter"
-
-/*
- * HO HBA SSDIDs
- */
-#define MPT2SAS_HP_2_4_INTERNAL_SSDID            0x0041
-#define MPT2SAS_HP_2_4_EXTERNAL_SSDID            0x0042
-#define MPT2SAS_HP_1_4_INTERNAL_1_4_EXTERNAL_SSDID    0x0043
-#define MPT2SAS_HP_EMBEDDED_2_4_INTERNAL_SSDID        0x0044
-#define MPT2SAS_HP_DAUGHTER_2_4_INTERNAL_SSDID        0x0046
-
-/*
- *  WarpDrive Specific Log codes
- */
-
-#define MPT2_WARPDRIVE_LOGENTRY                (0x8002)
-#define MPT2_WARPDRIVE_LC_SSDT         (0x41)
-#define MPT2_WARPDRIVE_LC_SSDLW                (0x43)
-#define MPT2_WARPDRIVE_LC_SSDLF                (0x44)
-#define MPT2_WARPDRIVE_LC_BRMF         (0x4D)
-
-/*
- * per target private data
- */
-#define MPT_TARGET_FLAGS_RAID_COMPONENT        0x01
-#define MPT_TARGET_FLAGS_VOLUME                0x02
-#define MPT_TARGET_FLAGS_DELETED       0x04
-
-/**
- * struct MPT2SAS_TARGET - starget private hostdata
- * @starget: starget object
- * @sas_address: target sas address
- * @raid_device: raid_device pointer to access volume data
- * @handle: device handle
- * @num_luns: number luns
- * @flags: MPT_TARGET_FLAGS_XXX flags
- * @deleted: target flaged for deletion
- * @tm_busy: target is busy with TM request.
- * @sdev: The sas_device associated with this target
- */
-struct MPT2SAS_TARGET {
-       struct scsi_target *starget;
-       u64     sas_address;
-       struct _raid_device *raid_device;
-       u16     handle;
-       int     num_luns;
-       u32     flags;
-       u8      deleted;
-       u8      tm_busy;
-       struct _sas_device *sdev;
-};
-
-
-/*
- * per device private data
- */
-#define MPT_DEVICE_FLAGS_INIT          0x01
-#define MPT_DEVICE_TLR_ON              0x02
-
-/**
- * struct MPT2SAS_DEVICE - sdev private hostdata
- * @sas_target: starget private hostdata
- * @lun: lun number
- * @flags: MPT_DEVICE_XXX flags
- * @configured_lun: lun is configured
- * @block: device is in SDEV_BLOCK state
- * @tlr_snoop_check: flag used in determining whether to disable TLR
- */
-
-/* OEM Identifiers */
-#define MFG10_OEM_ID_INVALID                   (0x00000000)
-#define MFG10_OEM_ID_DELL                      (0x00000001)
-#define MFG10_OEM_ID_FSC                       (0x00000002)
-#define MFG10_OEM_ID_SUN                       (0x00000003)
-#define MFG10_OEM_ID_IBM                       (0x00000004)
-
-/* GENERIC Flags 0*/
-#define MFG10_GF0_OCE_DISABLED                 (0x00000001)
-#define MFG10_GF0_R1E_DRIVE_COUNT              (0x00000002)
-#define MFG10_GF0_R10_DISPLAY                  (0x00000004)
-#define MFG10_GF0_SSD_DATA_SCRUB_DISABLE       (0x00000008)
-#define MFG10_GF0_SINGLE_DRIVE_R0              (0x00000010)
-
-/* OEM Specific Flags will come from OEM specific header files */
-typedef struct _MPI2_CONFIG_PAGE_MAN_10 {
-    MPI2_CONFIG_PAGE_HEADER Header;                                 /* 00h */
-    U8                      OEMIdentifier;                          /* 04h */
-    U8                      Reserved1;                              /* 05h */
-    U16                     Reserved2;                              /* 08h */
-    U32                     Reserved3;                              /* 0Ch */
-    U32                     GenericFlags0;                          /* 10h */
-    U32                     GenericFlags1;                          /* 14h */
-    U32                     Reserved4;                              /* 18h */
-    U32                     OEMSpecificFlags0;                      /* 1Ch */
-    U32                     OEMSpecificFlags1;                      /* 20h */
-    U32                     Reserved5[18];                          /* 24h-60h*/
-} MPI2_CONFIG_PAGE_MAN_10,
-  MPI2_POINTER PTR_MPI2_CONFIG_PAGE_MAN_10,
-  Mpi2ManufacturingPage10_t, MPI2_POINTER pMpi2ManufacturingPage10_t;
-
-#define MFG_PAGE10_HIDE_SSDS_MASK      (0x00000003)
-#define MFG_PAGE10_HIDE_ALL_DISKS      (0x00)
-#define MFG_PAGE10_EXPOSE_ALL_DISKS    (0x01)
-#define MFG_PAGE10_HIDE_IF_VOL_PRESENT (0x02)
-
-
-struct MPT2SAS_DEVICE {
-       struct MPT2SAS_TARGET *sas_target;
-       unsigned int    lun;
-       u32     flags;
-       u8      configured_lun;
-       u8      block;
-       u8      tlr_snoop_check;
-};
-
-#define MPT2_CMD_NOT_USED      0x8000  /* free */
-#define MPT2_CMD_COMPLETE      0x0001  /* completed */
-#define MPT2_CMD_PENDING       0x0002  /* pending */
-#define MPT2_CMD_REPLY_VALID   0x0004  /* reply is valid */
-#define MPT2_CMD_RESET         0x0008  /* host reset dropped the command */
-
-/**
- * struct _internal_cmd - internal commands struct
- * @mutex: mutex
- * @done: completion
- * @reply: reply message pointer
- * @sense: sense data
- * @status: MPT2_CMD_XXX status
- * @smid: system message id
- */
-struct _internal_cmd {
-       struct mutex mutex;
-       struct completion done;
-       void    *reply;
-       void    *sense;
-       u16     status;
-       u16     smid;
-};
-
-
-/**
- * struct _sas_device - attached device information
- * @list: sas device list
- * @starget: starget object
- * @sas_address: device sas address
- * @device_name: retrieved from the SAS IDENTIFY frame.
- * @handle: device handle
- * @sas_address_parent: sas address of parent expander or sas host
- * @enclosure_handle: enclosure handle
- * @enclosure_logical_id: enclosure logical identifier
- * @volume_handle: volume handle (valid when hidden raid member)
- * @volume_wwid: volume unique identifier
- * @device_info: bitfield provides detailed info about the device
- * @id: target id
- * @channel: target channel
- * @slot: number number
- * @phy: phy identifier provided in sas device page 0
- * @responding: used in _scsih_sas_device_mark_responding
- * @pfa_led_on: flag for PFA LED status
- */
-struct _sas_device {
-       struct list_head list;
-       struct scsi_target *starget;
-       u64     sas_address;
-       u64     device_name;
-       u16     handle;
-       u64     sas_address_parent;
-       u16     enclosure_handle;
-       u64     enclosure_logical_id;
-       u16     volume_handle;
-       u64     volume_wwid;
-       u32     device_info;
-       int     id;
-       int     channel;
-       u16     slot;
-       u8      phy;
-       u8      responding;
-       u8      pfa_led_on;
-       struct kref refcount;
-};
-
-static inline void sas_device_get(struct _sas_device *s)
-{
-       kref_get(&s->refcount);
-}
-
-static inline void sas_device_free(struct kref *r)
-{
-       kfree(container_of(r, struct _sas_device, refcount));
-}
-
-static inline void sas_device_put(struct _sas_device *s)
-{
-       kref_put(&s->refcount, sas_device_free);
-}
-
-/**
- * struct _raid_device - raid volume link list
- * @list: sas device list
- * @starget: starget object
- * @sdev: scsi device struct (volumes are single lun)
- * @wwid: unique identifier for the volume
- * @handle: device handle
- * @block_size: Block size of the volume
- * @id: target id
- * @channel: target channel
- * @volume_type: the raid level
- * @device_info: bitfield provides detailed info about the hidden components
- * @num_pds: number of hidden raid components
- * @responding: used in _scsih_raid_device_mark_responding
- * @percent_complete: resync percent complete
- * @direct_io_enabled: Whether direct io to PDs are allowed or not
- * @stripe_exponent: X where 2powX is the stripe sz in blocks
- * @block_exponent: X where 2powX is the block sz in bytes
- * @max_lba: Maximum number of LBA in the volume
- * @stripe_sz: Stripe Size of the volume
- * @device_info: Device info of the volume member disk
- * @pd_handle: Array of handles of the physical drives for direct I/O in le16
- */
-#define MPT_MAX_WARPDRIVE_PDS          8
-struct _raid_device {
-       struct list_head list;
-       struct scsi_target *starget;
-       struct scsi_device *sdev;
-       u64     wwid;
-       u16     handle;
-       u16     block_sz;
-       int     id;
-       int     channel;
-       u8      volume_type;
-       u8      num_pds;
-       u8      responding;
-       u8      percent_complete;
-       u8      direct_io_enabled;
-       u8      stripe_exponent;
-       u8      block_exponent;
-       u64     max_lba;
-       u32     stripe_sz;
-       u32     device_info;
-       u16     pd_handle[MPT_MAX_WARPDRIVE_PDS];
-};
-
-/**
- * struct _boot_device - boot device info
- * @is_raid: flag to indicate whether this is volume
- * @device: holds pointer for either struct _sas_device or
- *     struct _raid_device
- */
-struct _boot_device {
-       u8 is_raid;
-       void *device;
-};
-
-/**
- * struct _sas_port - wide/narrow sas port information
- * @port_list: list of ports belonging to expander
- * @num_phys: number of phys belonging to this port
- * @remote_identify: attached device identification
- * @rphy: sas transport rphy object
- * @port: sas transport wide/narrow port object
- * @phy_list: _sas_phy list objects belonging to this port
- */
-struct _sas_port {
-       struct list_head port_list;
-       u8      num_phys;
-       struct sas_identify remote_identify;
-       struct sas_rphy *rphy;
-       struct sas_port *port;
-       struct list_head phy_list;
-};
-
-/**
- * struct _sas_phy - phy information
- * @port_siblings: list of phys belonging to a port
- * @identify: phy identification
- * @remote_identify: attached device identification
- * @phy: sas transport phy object
- * @phy_id: unique phy id
- * @handle: device handle for this phy
- * @attached_handle: device handle for attached device
- * @phy_belongs_to_port: port has been created for this phy
- */
-struct _sas_phy {
-       struct list_head port_siblings;
-       struct sas_identify identify;
-       struct sas_identify remote_identify;
-       struct sas_phy *phy;
-       u8      phy_id;
-       u16     handle;
-       u16     attached_handle;
-       u8      phy_belongs_to_port;
-};
-
-/**
- * struct _sas_node - sas_host/expander information
- * @list: list of expanders
- * @parent_dev: parent device class
- * @num_phys: number phys belonging to this sas_host/expander
- * @sas_address: sas address of this sas_host/expander
- * @handle: handle for this sas_host/expander
- * @sas_address_parent: sas address of parent expander or sas host
- * @enclosure_handle: handle for this a member of an enclosure
- * @device_info: bitwise defining capabilities of this sas_host/expander
- * @responding: used in _scsih_expander_device_mark_responding
- * @phy: a list of phys that make up this sas_host/expander
- * @sas_port_list: list of ports attached to this sas_host/expander
- */
-struct _sas_node {
-       struct list_head list;
-       struct device *parent_dev;
-       u8      num_phys;
-       u64     sas_address;
-       u16     handle;
-       u64     sas_address_parent;
-       u16     enclosure_handle;
-       u64     enclosure_logical_id;
-       u8      responding;
-       struct  _sas_phy *phy;
-       struct list_head sas_port_list;
-};
-
-/**
- * enum reset_type - reset state
- * @FORCE_BIG_HAMMER: issue diagnostic reset
- * @SOFT_RESET: issue message_unit_reset, if fails to to big hammer
- */
-enum reset_type {
-       FORCE_BIG_HAMMER,
-       SOFT_RESET,
-};
-
-/**
- * struct chain_tracker - firmware chain tracker
- * @chain_buffer: chain buffer
- * @chain_buffer_dma: physical address
- * @tracker_list: list of free request (ioc->free_chain_list)
- */
-struct chain_tracker {
-       void *chain_buffer;
-       dma_addr_t chain_buffer_dma;
-       struct list_head tracker_list;
-};
-
-/**
- * struct scsiio_tracker - scsi mf request tracker
- * @smid: system message id
- * @scmd: scsi request pointer
- * @cb_idx: callback index
- * @direct_io: To indicate whether I/O is direct (WARPDRIVE)
- * @chain_list: list of chains associated to this IO
- * @tracker_list: list of free request (ioc->free_list)
- */
-struct scsiio_tracker {
-       u16     smid;
-       struct scsi_cmnd *scmd;
-       u8      cb_idx;
-       u8      direct_io;
-       struct list_head chain_list;
-       struct list_head tracker_list;
-};
-
-/**
- * struct request_tracker - firmware request tracker
- * @smid: system message id
- * @cb_idx: callback index
- * @tracker_list: list of free request (ioc->free_list)
- */
-struct request_tracker {
-       u16     smid;
-       u8      cb_idx;
-       struct list_head tracker_list;
-};
-
-/**
- * struct _tr_list - target reset list
- * @handle: device handle
- * @state: state machine
- */
-struct _tr_list {
-       struct list_head list;
-       u16     handle;
-       u16     state;
-};
-
-typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr);
-
-/**
- * struct adapter_reply_queue - the reply queue struct
- * @ioc: per adapter object
- * @msix_index: msix index into vector table
- * @vector: irq vector
- * @reply_post_host_index: head index in the pool where FW completes IO
- * @reply_post_free: reply post base virt address
- * @name: the name registered to request_irq()
- * @busy: isr is actively processing replies on another cpu
- * @list: this list
-*/
-struct adapter_reply_queue {
-       struct MPT2SAS_ADAPTER  *ioc;
-       u8                      msix_index;
-       unsigned int            vector;
-       u32                     reply_post_host_index;
-       Mpi2ReplyDescriptorsUnion_t *reply_post_free;
-       char                    name[MPT_NAME_LENGTH];
-       atomic_t                busy;
-       cpumask_var_t           affinity_hint;
-       struct list_head        list;
-};
-
-/* IOC Facts and Port Facts converted from little endian to cpu */
-union mpi2_version_union {
-       MPI2_VERSION_STRUCT             Struct;
-       u32                             Word;
-};
-
-struct mpt2sas_facts {
-       u16                     MsgVersion;
-       u16                     HeaderVersion;
-       u8                      IOCNumber;
-       u8                      VP_ID;
-       u8                      VF_ID;
-       u16                     IOCExceptions;
-       u16                     IOCStatus;
-       u32                     IOCLogInfo;
-       u8                      MaxChainDepth;
-       u8                      WhoInit;
-       u8                      NumberOfPorts;
-       u8                      MaxMSIxVectors;
-       u16                     RequestCredit;
-       u16                     ProductID;
-       u32                     IOCCapabilities;
-       union mpi2_version_union        FWVersion;
-       u16                     IOCRequestFrameSize;
-       u16                     Reserved3;
-       u16                     MaxInitiators;
-       u16                     MaxTargets;
-       u16                     MaxSasExpanders;
-       u16                     MaxEnclosures;
-       u16                     ProtocolFlags;
-       u16                     HighPriorityCredit;
-       u16                     MaxReplyDescriptorPostQueueDepth;
-       u8                      ReplyFrameSize;
-       u8                      MaxVolumes;
-       u16                     MaxDevHandle;
-       u16                     MaxPersistentEntries;
-       u16                     MinDevHandle;
-};
-
-struct mpt2sas_port_facts {
-       u8                      PortNumber;
-       u8                      VP_ID;
-       u8                      VF_ID;
-       u8                      PortType;
-       u16                     MaxPostedCmdBuffers;
-};
-
-struct reply_post_struct {
-       Mpi2ReplyDescriptorsUnion_t     *reply_post_free;
-       dma_addr_t                      reply_post_free_dma;
-};
-
-/**
- * enum mutex_type - task management mutex type
- * @TM_MUTEX_OFF: mutex is not required becuase calling function is acquiring it
- * @TM_MUTEX_ON: mutex is required
- */
-enum mutex_type {
-       TM_MUTEX_OFF = 0,
-       TM_MUTEX_ON = 1,
-};
-
-typedef void (*MPT2SAS_FLUSH_RUNNING_CMDS)(struct MPT2SAS_ADAPTER *ioc);
-/**
- * struct MPT2SAS_ADAPTER - per adapter struct
- * @list: ioc_list
- * @shost: shost object
- * @id: unique adapter id
- * @cpu_count: number online cpus
- * @name: generic ioc string
- * @tmp_string: tmp string used for logging
- * @pdev: pci pdev object
- * @chip: memory mapped register space
- * @chip_phys: physical addrss prior to mapping
- * @logging_level: see mpt2sas_debug.h
- * @fwfault_debug: debuging FW timeouts
- * @ir_firmware: IR firmware present
- * @bars: bitmask of BAR's that must be configured
- * @mask_interrupts: ignore interrupt
- * @dma_mask: used to set the consistent dma mask
- * @fault_reset_work_q_name: fw fault work queue
- * @fault_reset_work_q: ""
- * @fault_reset_work: ""
- * @firmware_event_name: fw event work queue
- * @firmware_event_thread: ""
- * @fw_events_off: flag to turn off fw event handling
- * @fw_event_lock:
- * @fw_event_list: list of fw events
- * @aen_event_read_flag: event log was read
- * @broadcast_aen_busy: broadcast aen waiting to be serviced
- * @shost_recovery: host reset in progress
- * @ioc_reset_in_progress_lock:
- * @ioc_link_reset_in_progress: phy/hard reset in progress
- * @ignore_loginfos: ignore loginfos during task management
- * @remove_host: flag for when driver unloads, to avoid sending dev resets
- * @pci_error_recovery: flag to prevent ioc access until slot reset completes
- * @wait_for_discovery_to_complete: flag set at driver load time when
- *                                               waiting on reporting devices
- * @is_driver_loading: flag set at driver load time
- * @port_enable_failed: flag set when port enable has failed
- * @start_scan: flag set from scan_start callback, cleared from _mpt2sas_fw_work
- * @start_scan_failed: means port enable failed, return's the ioc_status
- * @msix_enable: flag indicating msix is enabled
- * @msix_vector_count: number msix vectors
- * @cpu_msix_table: table for mapping cpus to msix index
- * @cpu_msix_table_sz: table size
- * @schedule_dead_ioc_flush_running_cmds: callback to flush pending commands
- * @scsi_io_cb_idx: shost generated commands
- * @tm_cb_idx: task management commands
- * @scsih_cb_idx: scsih internal commands
- * @transport_cb_idx: transport internal commands
- * @ctl_cb_idx: clt internal commands
- * @base_cb_idx: base internal commands
- * @config_cb_idx: base internal commands
- * @tm_tr_cb_idx : device removal target reset handshake
- * @tm_tr_volume_cb_idx : volume removal target reset
- * @base_cmds:
- * @transport_cmds:
- * @scsih_cmds:
- * @tm_cmds:
- * @ctl_cmds:
- * @config_cmds:
- * @base_add_sg_single: handler for either 32/64 bit sgl's
- * @event_type: bits indicating which events to log
- * @event_context: unique id for each logged event
- * @event_log: event log pointer
- * @event_masks: events that are masked
- * @facts: static facts data
- * @pfacts: static port facts data
- * @manu_pg0: static manufacturing page 0
- * @manu_pg10: static manufacturing page 10
- * @bios_pg2: static bios page 2
- * @bios_pg3: static bios page 3
- * @ioc_pg8: static ioc page 8
- * @iounit_pg0: static iounit page 0
- * @iounit_pg1: static iounit page 1
- * @iounit_pg8: static iounit page 8
- * @sas_hba: sas host object
- * @sas_expander_list: expander object list
- * @sas_node_lock:
- * @sas_device_list: sas device object list
- * @sas_device_init_list: sas device object list (used only at init time)
- * @sas_device_lock:
- * @io_missing_delay: time for IO completed by fw when PDR enabled
- * @device_missing_delay: time for device missing by fw when PDR enabled
- * @sas_id : used for setting volume target IDs
- * @blocking_handles: bitmask used to identify which devices need blocking
- * @pd_handles : bitmask for PD handles
- * @pd_handles_sz : size of pd_handle bitmask
- * @config_page_sz: config page size
- * @config_page: reserve memory for config page payload
- * @config_page_dma:
- * @hba_queue_depth: hba request queue depth
- * @sge_size: sg element size for either 32/64 bit
- * @scsiio_depth: SCSI_IO queue depth
- * @request_sz: per request frame size
- * @request: pool of request frames
- * @request_dma:
- * @request_dma_sz:
- * @scsi_lookup: firmware request tracker list
- * @scsi_lookup_lock:
- * @free_list: free list of request
- * @chain: pool of chains
- * @pending_io_count:
- * @reset_wq:
- * @chain_dma:
- * @max_sges_in_main_message: number sg elements in main message
- * @max_sges_in_chain_message: number sg elements per chain
- * @chains_needed_per_io: max chains per io
- * @chain_offset_value_for_main_message: location 1st sg in main
- * @chain_depth: total chains allocated
- * @hi_priority_smid:
- * @hi_priority:
- * @hi_priority_dma:
- * @hi_priority_depth:
- * @hpr_lookup:
- * @hpr_free_list:
- * @internal_smid:
- * @internal:
- * @internal_dma:
- * @internal_depth:
- * @internal_lookup:
- * @internal_free_list:
- * @sense: pool of sense
- * @sense_dma:
- * @sense_dma_pool:
- * @reply_depth: hba reply queue depth:
- * @reply_sz: per reply frame size:
- * @reply: pool of replys:
- * @reply_dma:
- * @reply_dma_pool:
- * @reply_free_queue_depth: reply free depth
- * @reply_free: pool for reply free queue (32 bit addr)
- * @reply_free_dma:
- * @reply_free_dma_pool:
- * @reply_free_host_index: tail index in pool to insert free replys
- * @reply_post_queue_depth: reply post queue depth
- * @reply_post_struct: struct for reply_post_free physical & virt address
- * @rdpq_array_capable: FW supports multiple reply queue addresses in ioc_init
- * @rdpq_array_enable: rdpq_array support is enabled in the driver
- * @rdpq_array_enable_assigned: this ensures that rdpq_array_enable flag
- *                             is assigned only ones
- * @reply_queue_count: number of reply queue's
- * @reply_queue_list: link list contaning the reply queue info
- * @reply_post_host_index: head index in the pool where FW completes IO
- * @delayed_tr_list: target reset link list
- * @delayed_tr_volume_list: volume target reset link list
- * @@temp_sensors_count: flag to carry the number of temperature sensors
- * @pci_access_mutex: Mutex to synchronize ioctl,sysfs show path and
- * pci resource handling. PCI resource freeing will lead to free
- * vital hardware/memory resource, which might be in use by cli/sysfs
- * path functions resulting in Null pointer reference followed by kernel
- * crash. To avoid the above race condition we use mutex syncrhonization
- * which ensures the syncrhonization between cli/sysfs_show path
- */
-struct MPT2SAS_ADAPTER {
-       struct list_head list;
-       struct Scsi_Host *shost;
-       u8              id;
-       int             cpu_count;
-       char            name[MPT_NAME_LENGTH];
-       char            tmp_string[MPT_STRING_LENGTH];
-       struct pci_dev  *pdev;
-       Mpi2SystemInterfaceRegs_t __iomem *chip;
-       resource_size_t chip_phys;
-       int             logging_level;
-       int             fwfault_debug;
-       u8              ir_firmware;
-       int             bars;
-       u8              mask_interrupts;
-       int             dma_mask;
-
-       /* fw fault handler */
-       char            fault_reset_work_q_name[20];
-       struct workqueue_struct *fault_reset_work_q;
-       struct delayed_work fault_reset_work;
-
-       /* fw event handler */
-       char            firmware_event_name[20];
-       struct workqueue_struct *firmware_event_thread;
-       spinlock_t      fw_event_lock;
-       struct list_head fw_event_list;
-
-        /* misc flags */
-       int             aen_event_read_flag;
-       u8              broadcast_aen_busy;
-       u16             broadcast_aen_pending;
-       u8              shost_recovery;
-
-       struct mutex    reset_in_progress_mutex;
-       spinlock_t      ioc_reset_in_progress_lock;
-       u8              ioc_link_reset_in_progress;
-       u8              ioc_reset_in_progress_status;
-
-       u8              ignore_loginfos;
-       u8              remove_host;
-       u8              pci_error_recovery;
-       u8              wait_for_discovery_to_complete;
-       struct completion       port_enable_done;
-       u8              is_driver_loading;
-       u8              port_enable_failed;
-
-       u8              start_scan;
-       u16             start_scan_failed;
-
-       u8              msix_enable;
-       u16             msix_vector_count;
-       u8              *cpu_msix_table;
-       resource_size_t __iomem **reply_post_host_index;
-       u16             cpu_msix_table_sz;
-       u32             ioc_reset_count;
-       MPT2SAS_FLUSH_RUNNING_CMDS schedule_dead_ioc_flush_running_cmds;
-       u32             non_operational_loop;
-
-       /* internal commands, callback index */
-       u8              scsi_io_cb_idx;
-       u8              tm_cb_idx;
-       u8              transport_cb_idx;
-       u8              scsih_cb_idx;
-       u8              ctl_cb_idx;
-       u8              base_cb_idx;
-       u8              port_enable_cb_idx;
-       u8              config_cb_idx;
-       u8              tm_tr_cb_idx;
-       u8              tm_tr_volume_cb_idx;
-       u8              tm_sas_control_cb_idx;
-       struct _internal_cmd base_cmds;
-       struct _internal_cmd port_enable_cmds;
-       struct _internal_cmd transport_cmds;
-       struct _internal_cmd scsih_cmds;
-       struct _internal_cmd tm_cmds;
-       struct _internal_cmd ctl_cmds;
-       struct _internal_cmd config_cmds;
-
-       MPT_ADD_SGE     base_add_sg_single;
-
-       /* event log */
-       u32             event_type[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS];
-       u32             event_context;
-       void            *event_log;
-       u32             event_masks[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS];
-
-       /* static config pages */
-       struct mpt2sas_facts facts;
-       struct mpt2sas_port_facts *pfacts;
-       Mpi2ManufacturingPage0_t manu_pg0;
-       Mpi2BiosPage2_t bios_pg2;
-       Mpi2BiosPage3_t bios_pg3;
-       Mpi2IOCPage8_t ioc_pg8;
-       Mpi2IOUnitPage0_t iounit_pg0;
-       Mpi2IOUnitPage1_t iounit_pg1;
-       Mpi2IOUnitPage8_t iounit_pg8;
-
-       struct _boot_device req_boot_device;
-       struct _boot_device req_alt_boot_device;
-       struct _boot_device current_boot_device;
-
-       /* sas hba, expander, and device list */
-       struct _sas_node sas_hba;
-       struct list_head sas_expander_list;
-       spinlock_t      sas_node_lock;
-       struct list_head sas_device_list;
-       struct list_head sas_device_init_list;
-       spinlock_t      sas_device_lock;
-       struct list_head raid_device_list;
-       spinlock_t      raid_device_lock;
-       u8              io_missing_delay;
-       u16             device_missing_delay;
-       int             sas_id;
-       void            *blocking_handles;
-       void            *pd_handles;
-       u16             pd_handles_sz;
-
-       /* config page */
-       u16             config_page_sz;
-       void            *config_page;
-       dma_addr_t      config_page_dma;
-
-       /* scsiio request */
-       u16             hba_queue_depth;
-       u16             sge_size;
-       u16             scsiio_depth;
-       u16             request_sz;
-       u8              *request;
-       dma_addr_t      request_dma;
-       u32             request_dma_sz;
-       struct scsiio_tracker *scsi_lookup;
-       ulong           scsi_lookup_pages;
-       spinlock_t      scsi_lookup_lock;
-       struct list_head free_list;
-       int             pending_io_count;
-       wait_queue_head_t reset_wq;
-
-       /* chain */
-       struct chain_tracker *chain_lookup;
-       struct list_head free_chain_list;
-       struct dma_pool *chain_dma_pool;
-       ulong           chain_pages;
-       u16             max_sges_in_main_message;
-       u16             max_sges_in_chain_message;
-       u16             chains_needed_per_io;
-       u16             chain_offset_value_for_main_message;
-       u32             chain_depth;
-
-       /* hi-priority queue */
-       u16             hi_priority_smid;
-       u8              *hi_priority;
-       dma_addr_t      hi_priority_dma;
-       u16             hi_priority_depth;
-       struct request_tracker *hpr_lookup;
-       struct list_head hpr_free_list;
-
-       /* internal queue */
-       u16             internal_smid;
-       u8              *internal;
-       dma_addr_t      internal_dma;
-       u16             internal_depth;
-       struct request_tracker *internal_lookup;
-       struct list_head internal_free_list;
-
-       /* sense */
-       u8              *sense;
-       dma_addr_t      sense_dma;
-       struct dma_pool *sense_dma_pool;
-
-       /* reply */
-       u16             reply_sz;
-       u8              *reply;
-       dma_addr_t      reply_dma;
-       u32             reply_dma_max_address;
-       u32             reply_dma_min_address;
-       struct dma_pool *reply_dma_pool;
-
-       /* reply free queue */
-       u16             reply_free_queue_depth;
-       __le32          *reply_free;
-       dma_addr_t      reply_free_dma;
-       struct dma_pool *reply_free_dma_pool;
-       u32             reply_free_host_index;
-
-       /* reply post queue */
-       u16             reply_post_queue_depth;
-       struct reply_post_struct *reply_post;
-       u8              rdpq_array_capable;
-       u8              rdpq_array_enable;
-       u8              rdpq_array_enable_assigned;
-       struct dma_pool *reply_post_free_dma_pool;
-       u8              reply_queue_count;
-       struct list_head reply_queue_list;
-
-       struct list_head delayed_tr_list;
-       struct list_head delayed_tr_volume_list;
-       u8              temp_sensors_count;
-
-       /* diag buffer support */
-       u8              *diag_buffer[MPI2_DIAG_BUF_TYPE_COUNT];
-       u32             diag_buffer_sz[MPI2_DIAG_BUF_TYPE_COUNT];
-       dma_addr_t      diag_buffer_dma[MPI2_DIAG_BUF_TYPE_COUNT];
-       u8              diag_buffer_status[MPI2_DIAG_BUF_TYPE_COUNT];
-       u32             unique_id[MPI2_DIAG_BUF_TYPE_COUNT];
-       Mpi2ManufacturingPage10_t manu_pg10;
-       u32             product_specific[MPI2_DIAG_BUF_TYPE_COUNT][23];
-       u32             diagnostic_flags[MPI2_DIAG_BUF_TYPE_COUNT];
-       u32             ring_buffer_offset;
-       u32             ring_buffer_sz;
-       u8              is_warpdrive;
-       u8              hide_ir_msg;
-       u8              mfg_pg10_hide_flag;
-       u8              hide_drives;
-
-       struct mutex pci_access_mutex;
-};
-
-typedef u8 (*MPT_CALLBACK)(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
-    u32 reply);
-
-
-/* base shared API */
-extern struct list_head mpt2sas_ioc_list;
-/* spinlock on list operations over IOCs
- * Case: when multiple warpdrive cards(IOCs) are in use
- * Each IOC will added to the ioc list stucture on initialization.
- * Watchdog threads run at regular intervals to check IOC for any
- * fault conditions which will trigger the dead_ioc thread to
- * deallocate pci resource, resulting deleting the IOC netry from list,
- * this deletion need to protected by spinlock to enusre that
- * ioc removal is syncrhonized, if not synchronized it might lead to
- * list_del corruption as the ioc list is traversed in cli path
- */
-extern spinlock_t gioc_lock;
-void mpt2sas_base_start_watchdog(struct MPT2SAS_ADAPTER *ioc);
-void mpt2sas_base_stop_watchdog(struct MPT2SAS_ADAPTER *ioc);
-
-int mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc);
-void mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc);
-int mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc);
-void mpt2sas_base_free_resources(struct MPT2SAS_ADAPTER *ioc);
-int mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
-    enum reset_type type);
-
-void *mpt2sas_base_get_msg_frame(struct MPT2SAS_ADAPTER *ioc, u16 smid);
-void *mpt2sas_base_get_sense_buffer(struct MPT2SAS_ADAPTER *ioc, u16 smid);
-void mpt2sas_base_build_zero_len_sge(struct MPT2SAS_ADAPTER *ioc, void *paddr);
-__le32 mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc,
-    u16 smid);
-void mpt2sas_base_flush_reply_queues(struct MPT2SAS_ADAPTER *ioc);
-
-/* hi-priority queue */
-u16 mpt2sas_base_get_smid_hpr(struct MPT2SAS_ADAPTER *ioc, u8 cb_idx);
-u16 mpt2sas_base_get_smid_scsiio(struct MPT2SAS_ADAPTER *ioc, u8 cb_idx,
-    struct scsi_cmnd *scmd);
-
-u16 mpt2sas_base_get_smid(struct MPT2SAS_ADAPTER *ioc, u8 cb_idx);
-void mpt2sas_base_free_smid(struct MPT2SAS_ADAPTER *ioc, u16 smid);
-void mpt2sas_base_put_smid_scsi_io(struct MPT2SAS_ADAPTER *ioc, u16 smid,
-    u16 handle);
-void mpt2sas_base_put_smid_hi_priority(struct MPT2SAS_ADAPTER *ioc, u16 smid);
-void mpt2sas_base_put_smid_target_assist(struct MPT2SAS_ADAPTER *ioc, u16 smid,
-    u16 io_index);
-void mpt2sas_base_put_smid_default(struct MPT2SAS_ADAPTER *ioc, u16 smid);
-void mpt2sas_base_initialize_callback_handler(void);
-u8 mpt2sas_base_register_callback_handler(MPT_CALLBACK cb_func);
-void mpt2sas_base_release_callback_handler(u8 cb_idx);
-
-u8 mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
-    u32 reply);
-u8 mpt2sas_port_enable_done(struct MPT2SAS_ADAPTER *ioc, u16 smid,
-       u8 msix_index,  u32 reply);
-void *mpt2sas_base_get_reply_virt_addr(struct MPT2SAS_ADAPTER *ioc, u32 phys_addr);
-
-u32 mpt2sas_base_get_iocstate(struct MPT2SAS_ADAPTER *ioc, int cooked);
-
-void mpt2sas_base_fault_info(struct MPT2SAS_ADAPTER *ioc , u16 fault_code);
-int mpt2sas_base_sas_iounit_control(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2SasIoUnitControlReply_t *mpi_reply, Mpi2SasIoUnitControlRequest_t
-    *mpi_request);
-int mpt2sas_base_scsi_enclosure_processor(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2SepReply_t *mpi_reply, Mpi2SepRequest_t *mpi_request);
-void mpt2sas_base_validate_event_type(struct MPT2SAS_ADAPTER *ioc, u32 *event_type);
-
-void mpt2sas_halt_firmware(struct MPT2SAS_ADAPTER *ioc);
-
-void mpt2sas_base_update_missing_delay(struct MPT2SAS_ADAPTER *ioc,
-       u16 device_missing_delay, u8 io_missing_delay);
-
-int mpt2sas_port_enable(struct MPT2SAS_ADAPTER *ioc);
-
-/* scsih shared API */
-void mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
-    u32 reply);
-int mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle,
-       uint channel, uint id, uint lun, u8 type, u16 smid_task,
-       ulong timeout, enum mutex_type m_type);
-void mpt2sas_scsih_set_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle);
-void mpt2sas_scsih_clear_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle);
-void mpt2sas_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address);
-void mpt2sas_device_remove_by_sas_address(struct MPT2SAS_ADAPTER *ioc,
-               u64 sas_address);
-struct _sas_node *mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER *ioc,
-    u16 handle);
-struct _sas_node *mpt2sas_scsih_expander_find_by_sas_address(struct MPT2SAS_ADAPTER
-    *ioc, u64 sas_address);
-struct _sas_device *mpt2sas_get_sdev_by_addr(
-    struct MPT2SAS_ADAPTER *ioc, u64 sas_address);
-struct _sas_device *__mpt2sas_get_sdev_by_addr(
-    struct MPT2SAS_ADAPTER *ioc, u64 sas_address);
-
-void mpt2sas_port_enable_complete(struct MPT2SAS_ADAPTER *ioc);
-void mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase);
-
-/* config shared API */
-u8 mpt2sas_config_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
-    u32 reply);
-int mpt2sas_config_get_number_hba_phys(struct MPT2SAS_ADAPTER *ioc, u8 *num_phys);
-int mpt2sas_config_get_manufacturing_pg0(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page);
-int mpt2sas_config_get_manufacturing_pg10(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage10_t *config_page);
-int mpt2sas_config_get_bios_pg2(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
-    *mpi_reply, Mpi2BiosPage2_t *config_page);
-int mpt2sas_config_get_bios_pg3(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
-    *mpi_reply, Mpi2BiosPage3_t *config_page);
-int mpt2sas_config_get_iounit_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
-    *mpi_reply, Mpi2IOUnitPage0_t *config_page);
-int mpt2sas_config_get_sas_device_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
-    *mpi_reply, Mpi2SasDevicePage0_t *config_page, u32 form, u32 handle);
-int mpt2sas_config_get_sas_device_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
-    *mpi_reply, Mpi2SasDevicePage1_t *config_page, u32 form, u32 handle);
-int mpt2sas_config_get_sas_iounit_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
-    *mpi_reply, Mpi2SasIOUnitPage0_t *config_page, u16 sz);
-int mpt2sas_config_get_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
-    *mpi_reply, Mpi2IOUnitPage1_t *config_page);
-int mpt2sas_config_set_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
-    *mpi_reply, Mpi2IOUnitPage1_t *config_page);
-int mpt2sas_config_get_iounit_pg8(struct MPT2SAS_ADAPTER *ioc,
-       Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage8_t *config_page);
-int mpt2sas_config_get_iounit_pg3(struct MPT2SAS_ADAPTER *ioc,
-       Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz);
-int mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
-    *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz);
-int mpt2sas_config_set_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz);
-int mpt2sas_config_get_ioc_pg8(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
-    *mpi_reply, Mpi2IOCPage8_t *config_page);
-int mpt2sas_config_get_expander_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
-    *mpi_reply, Mpi2ExpanderPage0_t *config_page, u32 form, u32 handle);
-int mpt2sas_config_get_expander_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
-    *mpi_reply, Mpi2ExpanderPage1_t *config_page, u32 phy_number, u16 handle);
-int mpt2sas_config_get_enclosure_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
-    *mpi_reply, Mpi2SasEnclosurePage0_t *config_page, u32 form, u32 handle);
-int mpt2sas_config_get_phy_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
-    *mpi_reply, Mpi2SasPhyPage0_t *config_page, u32 phy_number);
-int mpt2sas_config_get_phy_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
-    *mpi_reply, Mpi2SasPhyPage1_t *config_page, u32 phy_number);
-int mpt2sas_config_get_raid_volume_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
-    *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form, u32 handle);
-int mpt2sas_config_get_number_pds(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 *num_pds);
-int mpt2sas_config_get_raid_volume_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
-    *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 form, u32 handle, u16 sz);
-int mpt2sas_config_get_phys_disk_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
-    *mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page, u32 form,
-    u32 form_specific);
-int mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER *ioc, u16 pd_handle,
-    u16 *volume_handle);
-int mpt2sas_config_get_volume_wwid(struct MPT2SAS_ADAPTER *ioc, u16 volume_handle,
-    u64 *wwid);
-/* ctl shared API */
-extern struct device_attribute *mpt2sas_host_attrs[];
-extern struct device_attribute *mpt2sas_dev_attrs[];
-void mpt2sas_ctl_init(void);
-void mpt2sas_ctl_exit(void);
-u8 mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
-    u32 reply);
-void mpt2sas_ctl_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase);
-void mpt2sas_ctl_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
-    u32 reply);
-void mpt2sas_ctl_add_to_event_log(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2EventNotificationReply_t *mpi_reply);
-
-void mpt2sas_enable_diag_buffer(struct MPT2SAS_ADAPTER *ioc,
-       u8 bits_to_regsiter);
-
-/* transport shared API */
-u8 mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
-    u32 reply);
-struct _sas_port *mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc,
-     u16 handle, u64 sas_address);
-void mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
-     u64 sas_address_parent);
-int mpt2sas_transport_add_host_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy
-    *mpt2sas_phy, Mpi2SasPhyPage0_t phy_pg0, struct device *parent_dev);
-int mpt2sas_transport_add_expander_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy
-    *mpt2sas_phy, Mpi2ExpanderPage1_t expander_pg1, struct device *parent_dev);
-void mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc,
-     u64 sas_address, u16 handle, u8 phy_number, u8 link_rate);
-extern struct sas_function_template mpt2sas_transport_functions;
-extern struct scsi_transport_template *mpt2sas_transport_template;
-extern int scsi_internal_device_block(struct scsi_device *sdev);
-extern u8 mpt2sas_stm_zero_smid_handler(struct MPT2SAS_ADAPTER *ioc,
-    u8 msix_index, u32 reply);
-extern int scsi_internal_device_unblock(struct scsi_device *sdev,
-                                       enum scsi_device_state new_state);
-
-#endif /* MPT2SAS_BASE_H_INCLUDED */
diff --git a/drivers/scsi/mpt2sas/mpt2sas_config.c b/drivers/scsi/mpt2sas/mpt2sas_config.c
deleted file mode 100644 (file)
index c43815b..0000000
+++ /dev/null
@@ -1,1527 +0,0 @@
-/*
- * This module provides common API for accessing firmware configuration pages
- *
- * This code is based on drivers/scsi/mpt2sas/mpt2_base.c
- * Copyright (C) 2007-2014  LSI Corporation
- * Copyright (C) 20013-2014 Avago Technologies
- *  (mailto: MPT-FusionLinux.pdl@avagotech.com)
- *
- * 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.
- *
- * NO WARRANTY
- * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
- * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
- * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
- * solely responsible for determining the appropriateness of using and
- * distributing the Program and assumes all risks associated with its
- * exercise of rights under this Agreement, including but not limited to
- * the risks and costs of program errors, damage to or loss of data,
- * programs or equipment, and unavailability or interruption of operations.
-
- * DISCLAIMER OF LIABILITY
- * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
- * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
- * USA.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/blkdev.h>
-#include <linux/sched.h>
-#include <linux/workqueue.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-
-#include "mpt2sas_base.h"
-
-/* local definitions */
-
-/* Timeout for config page request (in seconds) */
-#define MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT 15
-
-/* Common sgl flags for READING a config page. */
-#define MPT2_CONFIG_COMMON_SGLFLAGS ((MPI2_SGE_FLAGS_SIMPLE_ELEMENT | \
-    MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER \
-    | MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT)
-
-/* Common sgl flags for WRITING a config page. */
-#define MPT2_CONFIG_COMMON_WRITE_SGLFLAGS ((MPI2_SGE_FLAGS_SIMPLE_ELEMENT | \
-    MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER \
-    | MPI2_SGE_FLAGS_END_OF_LIST | MPI2_SGE_FLAGS_HOST_TO_IOC) \
-    << MPI2_SGE_FLAGS_SHIFT)
-
-/**
- * struct config_request - obtain dma memory via routine
- * @sz: size
- * @page: virt pointer
- * @page_dma: phys pointer
- *
- */
-struct config_request{
-       u16                     sz;
-       void                    *page;
-       dma_addr_t              page_dma;
-};
-
-#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
-/**
- * _config_display_some_debug - debug routine
- * @ioc: per adapter object
- * @smid: system request message index
- * @calling_function_name: string pass from calling function
- * @mpi_reply: reply message frame
- * Context: none.
- *
- * Function for displaying debug info helpful when debugging issues
- * in this module.
- */
-static void
-_config_display_some_debug(struct MPT2SAS_ADAPTER *ioc, u16 smid,
-    char *calling_function_name, MPI2DefaultReply_t *mpi_reply)
-{
-       Mpi2ConfigRequest_t *mpi_request;
-       char *desc = NULL;
-
-       if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
-               return;
-
-       mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
-       switch (mpi_request->Header.PageType & MPI2_CONFIG_PAGETYPE_MASK) {
-       case MPI2_CONFIG_PAGETYPE_IO_UNIT:
-               desc = "io_unit";
-               break;
-       case MPI2_CONFIG_PAGETYPE_IOC:
-               desc = "ioc";
-               break;
-       case MPI2_CONFIG_PAGETYPE_BIOS:
-               desc = "bios";
-               break;
-       case MPI2_CONFIG_PAGETYPE_RAID_VOLUME:
-               desc = "raid_volume";
-               break;
-       case MPI2_CONFIG_PAGETYPE_MANUFACTURING:
-               desc = "manufaucturing";
-               break;
-       case MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK:
-               desc = "physdisk";
-               break;
-       case MPI2_CONFIG_PAGETYPE_EXTENDED:
-               switch (mpi_request->ExtPageType) {
-               case MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT:
-                       desc = "sas_io_unit";
-                       break;
-               case MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER:
-                       desc = "sas_expander";
-                       break;
-               case MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE:
-                       desc = "sas_device";
-                       break;
-               case MPI2_CONFIG_EXTPAGETYPE_SAS_PHY:
-                       desc = "sas_phy";
-                       break;
-               case MPI2_CONFIG_EXTPAGETYPE_LOG:
-                       desc = "log";
-                       break;
-               case MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE:
-                       desc = "enclosure";
-                       break;
-               case MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG:
-                       desc = "raid_config";
-                       break;
-               case MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING:
-                       desc = "driver_mapping";
-                       break;
-               }
-               break;
-       }
-
-       if (!desc)
-               return;
-
-       printk(MPT2SAS_INFO_FMT "%s: %s(%d), action(%d), form(0x%08x), "
-           "smid(%d)\n", ioc->name, calling_function_name, desc,
-           mpi_request->Header.PageNumber, mpi_request->Action,
-           le32_to_cpu(mpi_request->PageAddress), smid);
-
-       if (!mpi_reply)
-               return;
-
-       if (mpi_reply->IOCStatus || mpi_reply->IOCLogInfo)
-               printk(MPT2SAS_INFO_FMT
-                   "\tiocstatus(0x%04x), loginfo(0x%08x)\n",
-                   ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
-                   le32_to_cpu(mpi_reply->IOCLogInfo));
-}
-#endif
-
-/**
- * _config_alloc_config_dma_memory - obtain physical memory
- * @ioc: per adapter object
- * @mem: struct config_request
- *
- * A wrapper for obtaining dma-able memory for config page request.
- *
- * Returns 0 for success, non-zero for failure.
- */
-static int
-_config_alloc_config_dma_memory(struct MPT2SAS_ADAPTER *ioc,
-    struct config_request *mem)
-{
-       int r = 0;
-
-       if (mem->sz > ioc->config_page_sz) {
-               mem->page = dma_alloc_coherent(&ioc->pdev->dev, mem->sz,
-                   &mem->page_dma, GFP_KERNEL);
-               if (!mem->page) {
-                       printk(MPT2SAS_ERR_FMT "%s: dma_alloc_coherent"
-                           " failed asking for (%d) bytes!!\n",
-                           ioc->name, __func__, mem->sz);
-                       r = -ENOMEM;
-               }
-       } else { /* use tmp buffer if less than 512 bytes */
-               mem->page = ioc->config_page;
-               mem->page_dma = ioc->config_page_dma;
-       }
-       return r;
-}
-
-/**
- * _config_free_config_dma_memory - wrapper to free the memory
- * @ioc: per adapter object
- * @mem: struct config_request
- *
- * A wrapper to free dma-able memory when using _config_alloc_config_dma_memory.
- *
- * Returns 0 for success, non-zero for failure.
- */
-static void
-_config_free_config_dma_memory(struct MPT2SAS_ADAPTER *ioc,
-    struct config_request *mem)
-{
-       if (mem->sz > ioc->config_page_sz)
-               dma_free_coherent(&ioc->pdev->dev, mem->sz, mem->page,
-                   mem->page_dma);
-}
-
-/**
- * mpt2sas_config_done - config page completion routine
- * @ioc: per adapter object
- * @smid: system request message index
- * @msix_index: MSIX table index supplied by the OS
- * @reply: reply message frame(lower 32bit addr)
- * Context: none.
- *
- * The callback handler when using _config_request.
- *
- * Return 1 meaning mf should be freed from _base_interrupt
- *        0 means the mf is freed from this function.
- */
-u8
-mpt2sas_config_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
-    u32 reply)
-{
-       MPI2DefaultReply_t *mpi_reply;
-
-       if (ioc->config_cmds.status == MPT2_CMD_NOT_USED)
-               return 1;
-       if (ioc->config_cmds.smid != smid)
-               return 1;
-       ioc->config_cmds.status |= MPT2_CMD_COMPLETE;
-       mpi_reply =  mpt2sas_base_get_reply_virt_addr(ioc, reply);
-       if (mpi_reply) {
-               ioc->config_cmds.status |= MPT2_CMD_REPLY_VALID;
-               memcpy(ioc->config_cmds.reply, mpi_reply,
-                   mpi_reply->MsgLength*4);
-       }
-       ioc->config_cmds.status &= ~MPT2_CMD_PENDING;
-#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
-       _config_display_some_debug(ioc, smid, "config_done", mpi_reply);
-#endif
-       ioc->config_cmds.smid = USHRT_MAX;
-       complete(&ioc->config_cmds.done);
-       return 1;
-}
-
-/**
- * _config_request - main routine for sending config page requests
- * @ioc: per adapter object
- * @mpi_request: request message frame
- * @mpi_reply: reply mf payload returned from firmware
- * @timeout: timeout in seconds
- * @config_page: contents of the config page
- * @config_page_sz: size of config page
- * Context: sleep
- *
- * A generic API for config page requests to firmware.
- *
- * The ioc->config_cmds.status flag should be MPT2_CMD_NOT_USED before calling
- * this API.
- *
- * The callback index is set inside `ioc->config_cb_idx.
- *
- * Returns 0 for success, non-zero for failure.
- */
-static int
-_config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
-    *mpi_request, Mpi2ConfigReply_t *mpi_reply, int timeout,
-    void *config_page, u16 config_page_sz)
-{
-       u16 smid;
-       u32 ioc_state;
-       unsigned long timeleft;
-       Mpi2ConfigRequest_t *config_request;
-       int r;
-       u8 retry_count, issue_host_reset = 0;
-       u16 wait_state_count;
-       struct config_request mem;
-
-       mutex_lock(&ioc->config_cmds.mutex);
-       if (ioc->config_cmds.status != MPT2_CMD_NOT_USED) {
-               printk(MPT2SAS_ERR_FMT "%s: config_cmd in use\n",
-                   ioc->name, __func__);
-               mutex_unlock(&ioc->config_cmds.mutex);
-               return -EAGAIN;
-       }
-
-       retry_count = 0;
-       memset(&mem, 0, sizeof(struct config_request));
-
-       mpi_request->VF_ID = 0; /* TODO */
-       mpi_request->VP_ID = 0;
-
-       if (config_page) {
-               mpi_request->Header.PageVersion = mpi_reply->Header.PageVersion;
-               mpi_request->Header.PageNumber = mpi_reply->Header.PageNumber;
-               mpi_request->Header.PageType = mpi_reply->Header.PageType;
-               mpi_request->Header.PageLength = mpi_reply->Header.PageLength;
-               mpi_request->ExtPageLength = mpi_reply->ExtPageLength;
-               mpi_request->ExtPageType = mpi_reply->ExtPageType;
-               if (mpi_request->Header.PageLength)
-                       mem.sz = mpi_request->Header.PageLength * 4;
-               else
-                       mem.sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
-               r = _config_alloc_config_dma_memory(ioc, &mem);
-               if (r != 0)
-                       goto out;
-               if (mpi_request->Action ==
-                   MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT ||
-                   mpi_request->Action ==
-                   MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM) {
-                       ioc->base_add_sg_single(&mpi_request->PageBufferSGE,
-                           MPT2_CONFIG_COMMON_WRITE_SGLFLAGS | mem.sz,
-                           mem.page_dma);
-                       memcpy(mem.page, config_page, min_t(u16, mem.sz,
-                           config_page_sz));
-               } else {
-                       memset(config_page, 0, config_page_sz);
-                       ioc->base_add_sg_single(&mpi_request->PageBufferSGE,
-                           MPT2_CONFIG_COMMON_SGLFLAGS | mem.sz, mem.page_dma);
-               }
-       }
-
- retry_config:
-       if (retry_count) {
-               if (retry_count > 2) { /* attempt only 2 retries */
-                       r = -EFAULT;
-                       goto free_mem;
-               }
-               printk(MPT2SAS_INFO_FMT "%s: attempting retry (%d)\n",
-                   ioc->name, __func__, retry_count);
-       }
-       wait_state_count = 0;
-       ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
-       while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
-               if (wait_state_count++ == MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT) {
-                       printk(MPT2SAS_ERR_FMT
-                           "%s: failed due to ioc not operational\n",
-                           ioc->name, __func__);
-                       ioc->config_cmds.status = MPT2_CMD_NOT_USED;
-                       r = -EFAULT;
-                       goto free_mem;
-               }
-               ssleep(1);
-               ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
-               printk(MPT2SAS_INFO_FMT "%s: waiting for "
-                   "operational state(count=%d)\n", ioc->name,
-                   __func__, wait_state_count);
-       }
-       if (wait_state_count)
-               printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n",
-                   ioc->name, __func__);
-
-       smid = mpt2sas_base_get_smid(ioc, ioc->config_cb_idx);
-       if (!smid) {
-               printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
-                   ioc->name, __func__);
-               ioc->config_cmds.status = MPT2_CMD_NOT_USED;
-               r = -EAGAIN;
-               goto free_mem;
-       }
-
-       r = 0;
-       memset(mpi_reply, 0, sizeof(Mpi2ConfigReply_t));
-       ioc->config_cmds.status = MPT2_CMD_PENDING;
-       config_request = mpt2sas_base_get_msg_frame(ioc, smid);
-       ioc->config_cmds.smid = smid;
-       memcpy(config_request, mpi_request, sizeof(Mpi2ConfigRequest_t));
-#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
-       _config_display_some_debug(ioc, smid, "config_request", NULL);
-#endif
-       init_completion(&ioc->config_cmds.done);
-       mpt2sas_base_put_smid_default(ioc, smid);
-       timeleft = wait_for_completion_timeout(&ioc->config_cmds.done,
-           timeout*HZ);
-       if (!(ioc->config_cmds.status & MPT2_CMD_COMPLETE)) {
-               printk(MPT2SAS_ERR_FMT "%s: timeout\n",
-                   ioc->name, __func__);
-               _debug_dump_mf(mpi_request,
-                   sizeof(Mpi2ConfigRequest_t)/4);
-               retry_count++;
-               if (ioc->config_cmds.smid == smid)
-                       mpt2sas_base_free_smid(ioc, smid);
-               if ((ioc->shost_recovery) || (ioc->config_cmds.status &
-                   MPT2_CMD_RESET) || ioc->pci_error_recovery)
-                       goto retry_config;
-               issue_host_reset = 1;
-               r = -EFAULT;
-               goto free_mem;
-       }
-
-       if (ioc->config_cmds.status & MPT2_CMD_REPLY_VALID)
-               memcpy(mpi_reply, ioc->config_cmds.reply,
-                   sizeof(Mpi2ConfigReply_t));
-       if (retry_count)
-               printk(MPT2SAS_INFO_FMT "%s: retry (%d) completed!!\n",
-                   ioc->name, __func__, retry_count);
-       if (config_page && mpi_request->Action ==
-           MPI2_CONFIG_ACTION_PAGE_READ_CURRENT)
-               memcpy(config_page, mem.page, min_t(u16, mem.sz,
-                   config_page_sz));
- free_mem:
-       if (config_page)
-               _config_free_config_dma_memory(ioc, &mem);
- out:
-       ioc->config_cmds.status = MPT2_CMD_NOT_USED;
-       mutex_unlock(&ioc->config_cmds.mutex);
-
-       if (issue_host_reset)
-               mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
-                   FORCE_BIG_HAMMER);
-       return r;
-}
-
-/**
- * mpt2sas_config_get_manufacturing_pg0 - obtain manufacturing page 0
- * @ioc: per adapter object
- * @mpi_reply: reply mf payload returned from firmware
- * @config_page: contents of the config page
- * Context: sleep.
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_config_get_manufacturing_pg0(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page)
-{
-       Mpi2ConfigRequest_t mpi_request;
-       int r;
-
-       memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
-       mpi_request.Function = MPI2_FUNCTION_CONFIG;
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
-       mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
-       mpi_request.Header.PageNumber = 0;
-       mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
-       mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
-       if (r)
-               goto out;
-
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
-           sizeof(*config_page));
- out:
-       return r;
-}
-
-/**
- * mpt2sas_config_get_manufacturing_pg10 - obtain manufacturing page 10
- * @ioc: per adapter object
- * @mpi_reply: reply mf payload returned from firmware
- * @config_page: contents of the config page
- * Context: sleep.
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_config_get_manufacturing_pg10(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage10_t *config_page)
-{
-       Mpi2ConfigRequest_t mpi_request;
-       int r;
-
-       memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
-       mpi_request.Function = MPI2_FUNCTION_CONFIG;
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
-       mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
-       mpi_request.Header.PageNumber = 10;
-       mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
-       mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
-       if (r)
-               goto out;
-
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
-           sizeof(*config_page));
- out:
-       return r;
-}
-
-/**
- * mpt2sas_config_get_bios_pg2 - obtain bios page 2
- * @ioc: per adapter object
- * @mpi_reply: reply mf payload returned from firmware
- * @config_page: contents of the config page
- * Context: sleep.
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_config_get_bios_pg2(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage2_t *config_page)
-{
-       Mpi2ConfigRequest_t mpi_request;
-       int r;
-
-       memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
-       mpi_request.Function = MPI2_FUNCTION_CONFIG;
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
-       mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
-       mpi_request.Header.PageNumber = 2;
-       mpi_request.Header.PageVersion = MPI2_BIOSPAGE2_PAGEVERSION;
-       mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
-       if (r)
-               goto out;
-
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
-           sizeof(*config_page));
- out:
-       return r;
-}
-
-/**
- * mpt2sas_config_get_bios_pg3 - obtain bios page 3
- * @ioc: per adapter object
- * @mpi_reply: reply mf payload returned from firmware
- * @config_page: contents of the config page
- * Context: sleep.
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_config_get_bios_pg3(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
-    *mpi_reply, Mpi2BiosPage3_t *config_page)
-{
-       Mpi2ConfigRequest_t mpi_request;
-       int r;
-
-       memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
-       mpi_request.Function = MPI2_FUNCTION_CONFIG;
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
-       mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
-       mpi_request.Header.PageNumber = 3;
-       mpi_request.Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION;
-       mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
-       if (r)
-               goto out;
-
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
-           sizeof(*config_page));
- out:
-       return r;
-}
-
-/**
- * mpt2sas_config_get_iounit_pg0 - obtain iounit page 0
- * @ioc: per adapter object
- * @mpi_reply: reply mf payload returned from firmware
- * @config_page: contents of the config page
- * Context: sleep.
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_config_get_iounit_pg0(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage0_t *config_page)
-{
-       Mpi2ConfigRequest_t mpi_request;
-       int r;
-
-       memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
-       mpi_request.Function = MPI2_FUNCTION_CONFIG;
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
-       mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
-       mpi_request.Header.PageNumber = 0;
-       mpi_request.Header.PageVersion = MPI2_IOUNITPAGE0_PAGEVERSION;
-       mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
-       if (r)
-               goto out;
-
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
-           sizeof(*config_page));
- out:
-       return r;
-}
-
-/**
- * mpt2sas_config_get_iounit_pg1 - obtain iounit page 1
- * @ioc: per adapter object
- * @mpi_reply: reply mf payload returned from firmware
- * @config_page: contents of the config page
- * Context: sleep.
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_config_get_iounit_pg1(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page)
-{
-       Mpi2ConfigRequest_t mpi_request;
-       int r;
-
-       memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
-       mpi_request.Function = MPI2_FUNCTION_CONFIG;
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
-       mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
-       mpi_request.Header.PageNumber = 1;
-       mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;
-       mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
-       if (r)
-               goto out;
-
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
-           sizeof(*config_page));
- out:
-       return r;
-}
-
-/**
- * mpt2sas_config_set_iounit_pg1 - set iounit page 1
- * @ioc: per adapter object
- * @mpi_reply: reply mf payload returned from firmware
- * @config_page: contents of the config page
- * Context: sleep.
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_config_set_iounit_pg1(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page)
-{
-       Mpi2ConfigRequest_t mpi_request;
-       int r;
-
-       memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
-       mpi_request.Function = MPI2_FUNCTION_CONFIG;
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
-       mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
-       mpi_request.Header.PageNumber = 1;
-       mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;
-       mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
-       if (r)
-               goto out;
-
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
-           sizeof(*config_page));
- out:
-       return r;
-}
-
-/**
- * mpt2sas_config_get_iounit_pg3 - obtain iounit page 3
- * @ioc: per adapter object
- * @mpi_reply: reply mf payload returned from firmware
- * @config_page: contents of the config page
- * @sz: size of buffer passed in config_page
- * Context: sleep.
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_config_get_iounit_pg3(struct MPT2SAS_ADAPTER *ioc,
-       Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz)
-{
-       Mpi2ConfigRequest_t mpi_request;
-       int r;
-
-       memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
-       mpi_request.Function = MPI2_FUNCTION_CONFIG;
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
-       mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
-       mpi_request.Header.PageNumber = 3;
-       mpi_request.Header.PageVersion = MPI2_IOUNITPAGE3_PAGEVERSION;
-       mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
-       if (r)
-               goto out;
-
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
- out:
-       return r;
-}
-
-/**
- * mpt2sas_config_get_iounit_pg8 - obtain iounit page 8
- * @ioc: per adapter object
- * @mpi_reply: reply mf payload returned from firmware
- * @config_page: contents of the config page
- * Context: sleep.
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_config_get_iounit_pg8(struct MPT2SAS_ADAPTER *ioc,
-       Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage8_t *config_page)
-{
-       Mpi2ConfigRequest_t mpi_request;
-       int r;
-
-       memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
-       mpi_request.Function = MPI2_FUNCTION_CONFIG;
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
-       mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
-       mpi_request.Header.PageNumber = 8;
-       mpi_request.Header.PageVersion = MPI2_IOUNITPAGE8_PAGEVERSION;
-       mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
-       if (r)
-               goto out;
-
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
-           sizeof(*config_page));
- out:
-       return r;
-}
-
-/**
- * mpt2sas_config_get_ioc_pg8 - obtain ioc page 8
- * @ioc: per adapter object
- * @mpi_reply: reply mf payload returned from firmware
- * @config_page: contents of the config page
- * Context: sleep.
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_config_get_ioc_pg8(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage8_t *config_page)
-{
-       Mpi2ConfigRequest_t mpi_request;
-       int r;
-
-       memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
-       mpi_request.Function = MPI2_FUNCTION_CONFIG;
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
-       mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
-       mpi_request.Header.PageNumber = 8;
-       mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
-       mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
-       if (r)
-               goto out;
-
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
-           sizeof(*config_page));
- out:
-       return r;
-}
-
-/**
- * mpt2sas_config_get_sas_device_pg0 - obtain sas device page 0
- * @ioc: per adapter object
- * @mpi_reply: reply mf payload returned from firmware
- * @config_page: contents of the config page
- * @form: GET_NEXT_HANDLE or HANDLE
- * @handle: device handle
- * Context: sleep.
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_config_get_sas_device_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
-    *mpi_reply, Mpi2SasDevicePage0_t *config_page, u32 form, u32 handle)
-{
-       Mpi2ConfigRequest_t mpi_request;
-       int r;
-
-       memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
-       mpi_request.Function = MPI2_FUNCTION_CONFIG;
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
-       mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
-       mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
-       mpi_request.Header.PageVersion = MPI2_SASDEVICE0_PAGEVERSION;
-       mpi_request.Header.PageNumber = 0;
-       mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
-       if (r)
-               goto out;
-
-       mpi_request.PageAddress = cpu_to_le32(form | handle);
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
-           sizeof(*config_page));
- out:
-       return r;
-}
-
-/**
- * mpt2sas_config_get_sas_device_pg1 - obtain sas device page 1
- * @ioc: per adapter object
- * @mpi_reply: reply mf payload returned from firmware
- * @config_page: contents of the config page
- * @form: GET_NEXT_HANDLE or HANDLE
- * @handle: device handle
- * Context: sleep.
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_config_get_sas_device_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
-    *mpi_reply, Mpi2SasDevicePage1_t *config_page, u32 form, u32 handle)
-{
-       Mpi2ConfigRequest_t mpi_request;
-       int r;
-
-       memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
-       mpi_request.Function = MPI2_FUNCTION_CONFIG;
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
-       mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
-       mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
-       mpi_request.Header.PageVersion = MPI2_SASDEVICE1_PAGEVERSION;
-       mpi_request.Header.PageNumber = 1;
-       mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
-       if (r)
-               goto out;
-
-       mpi_request.PageAddress = cpu_to_le32(form | handle);
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
-           sizeof(*config_page));
- out:
-       return r;
-}
-
-/**
- * mpt2sas_config_get_number_hba_phys - obtain number of phys on the host
- * @ioc: per adapter object
- * @num_phys: pointer returned with the number of phys
- * Context: sleep.
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_config_get_number_hba_phys(struct MPT2SAS_ADAPTER *ioc, u8 *num_phys)
-{
-       Mpi2ConfigRequest_t mpi_request;
-       int r;
-       u16 ioc_status;
-       Mpi2ConfigReply_t mpi_reply;
-       Mpi2SasIOUnitPage0_t config_page;
-
-       *num_phys = 0;
-       memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
-       mpi_request.Function = MPI2_FUNCTION_CONFIG;
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
-       mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
-       mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
-       mpi_request.Header.PageNumber = 0;
-       mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
-       mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
-       r = _config_request(ioc, &mpi_request, &mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
-       if (r)
-               goto out;
-
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-       r = _config_request(ioc, &mpi_request, &mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page,
-           sizeof(Mpi2SasIOUnitPage0_t));
-       if (!r) {
-               ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-                   MPI2_IOCSTATUS_MASK;
-               if (ioc_status == MPI2_IOCSTATUS_SUCCESS)
-                       *num_phys = config_page.NumPhys;
-       }
- out:
-       return r;
-}
-
-/**
- * mpt2sas_config_get_sas_iounit_pg0 - obtain sas iounit page 0
- * @ioc: per adapter object
- * @mpi_reply: reply mf payload returned from firmware
- * @config_page: contents of the config page
- * @sz: size of buffer passed in config_page
- * Context: sleep.
- *
- * Calling function should call config_get_number_hba_phys prior to
- * this function, so enough memory is allocated for config_page.
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_config_get_sas_iounit_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
-    *mpi_reply, Mpi2SasIOUnitPage0_t *config_page, u16 sz)
-{
-       Mpi2ConfigRequest_t mpi_request;
-       int r;
-
-       memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
-       mpi_request.Function = MPI2_FUNCTION_CONFIG;
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
-       mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
-       mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
-       mpi_request.Header.PageNumber = 0;
-       mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
-       mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
-       if (r)
-               goto out;
-
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
- out:
-       return r;
-}
-
-/**
- * mpt2sas_config_get_sas_iounit_pg1 - obtain sas iounit page 1
- * @ioc: per adapter object
- * @mpi_reply: reply mf payload returned from firmware
- * @config_page: contents of the config page
- * @sz: size of buffer passed in config_page
- * Context: sleep.
- *
- * Calling function should call config_get_number_hba_phys prior to
- * this function, so enough memory is allocated for config_page.
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
-    *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz)
-{
-       Mpi2ConfigRequest_t mpi_request;
-       int r;
-
-       memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
-       mpi_request.Function = MPI2_FUNCTION_CONFIG;
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
-       mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
-       mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
-       mpi_request.Header.PageNumber = 1;
-       mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION;
-       mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
-       if (r)
-               goto out;
-
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
- out:
-       return r;
-}
-
-/**
- * mpt2sas_config_set_sas_iounit_pg1 - send sas iounit page 1
- * @ioc: per adapter object
- * @mpi_reply: reply mf payload returned from firmware
- * @config_page: contents of the config page
- * @sz: size of buffer passed in config_page
- * Context: sleep.
- *
- * Calling function should call config_get_number_hba_phys prior to
- * this function, so enough memory is allocated for config_page.
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_config_set_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
-    *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz)
-{
-       Mpi2ConfigRequest_t mpi_request;
-       int r;
-
-       memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
-       mpi_request.Function = MPI2_FUNCTION_CONFIG;
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
-       mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
-       mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
-       mpi_request.Header.PageNumber = 1;
-       mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION;
-       mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
-       if (r)
-               goto out;
-
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
-       _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
- out:
-       return r;
-}
-
-/**
- * mpt2sas_config_get_expander_pg0 - obtain expander page 0
- * @ioc: per adapter object
- * @mpi_reply: reply mf payload returned from firmware
- * @config_page: contents of the config page
- * @form: GET_NEXT_HANDLE or HANDLE
- * @handle: expander handle
- * Context: sleep.
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_config_get_expander_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
-    *mpi_reply, Mpi2ExpanderPage0_t *config_page, u32 form, u32 handle)
-{
-       Mpi2ConfigRequest_t mpi_request;
-       int r;
-
-       memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
-       mpi_request.Function = MPI2_FUNCTION_CONFIG;
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
-       mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
-       mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
-       mpi_request.Header.PageNumber = 0;
-       mpi_request.Header.PageVersion = MPI2_SASEXPANDER0_PAGEVERSION;
-       mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
-       if (r)
-               goto out;
-
-       mpi_request.PageAddress = cpu_to_le32(form | handle);
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
-           sizeof(*config_page));
- out:
-       return r;
-}
-
-/**
- * mpt2sas_config_get_expander_pg1 - obtain expander page 1
- * @ioc: per adapter object
- * @mpi_reply: reply mf payload returned from firmware
- * @config_page: contents of the config page
- * @phy_number: phy number
- * @handle: expander handle
- * Context: sleep.
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_config_get_expander_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
-    *mpi_reply, Mpi2ExpanderPage1_t *config_page, u32 phy_number,
-    u16 handle)
-{
-       Mpi2ConfigRequest_t mpi_request;
-       int r;
-
-       memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
-       mpi_request.Function = MPI2_FUNCTION_CONFIG;
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
-       mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
-       mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
-       mpi_request.Header.PageNumber = 1;
-       mpi_request.Header.PageVersion = MPI2_SASEXPANDER1_PAGEVERSION;
-       mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
-       if (r)
-               goto out;
-
-       mpi_request.PageAddress =
-           cpu_to_le32(MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM |
-           (phy_number << MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT) | handle);
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
-           sizeof(*config_page));
- out:
-       return r;
-}
-
-/**
- * mpt2sas_config_get_enclosure_pg0 - obtain enclosure page 0
- * @ioc: per adapter object
- * @mpi_reply: reply mf payload returned from firmware
- * @config_page: contents of the config page
- * @form: GET_NEXT_HANDLE or HANDLE
- * @handle: expander handle
- * Context: sleep.
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_config_get_enclosure_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
-    *mpi_reply, Mpi2SasEnclosurePage0_t *config_page, u32 form, u32 handle)
-{
-       Mpi2ConfigRequest_t mpi_request;
-       int r;
-
-       memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
-       mpi_request.Function = MPI2_FUNCTION_CONFIG;
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
-       mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
-       mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE;
-       mpi_request.Header.PageNumber = 0;
-       mpi_request.Header.PageVersion = MPI2_SASENCLOSURE0_PAGEVERSION;
-       mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
-       if (r)
-               goto out;
-
-       mpi_request.PageAddress = cpu_to_le32(form | handle);
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
-           sizeof(*config_page));
- out:
-       return r;
-}
-
-/**
- * mpt2sas_config_get_phy_pg0 - obtain phy page 0
- * @ioc: per adapter object
- * @mpi_reply: reply mf payload returned from firmware
- * @config_page: contents of the config page
- * @phy_number: phy number
- * Context: sleep.
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_config_get_phy_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
-    *mpi_reply, Mpi2SasPhyPage0_t *config_page, u32 phy_number)
-{
-       Mpi2ConfigRequest_t mpi_request;
-       int r;
-
-       memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
-       mpi_request.Function = MPI2_FUNCTION_CONFIG;
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
-       mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
-       mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;
-       mpi_request.Header.PageNumber = 0;
-       mpi_request.Header.PageVersion = MPI2_SASPHY0_PAGEVERSION;
-       mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
-       if (r)
-               goto out;
-
-       mpi_request.PageAddress =
-           cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
-           sizeof(*config_page));
- out:
-       return r;
-}
-
-/**
- * mpt2sas_config_get_phy_pg1 - obtain phy page 1
- * @ioc: per adapter object
- * @mpi_reply: reply mf payload returned from firmware
- * @config_page: contents of the config page
- * @phy_number: phy number
- * Context: sleep.
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_config_get_phy_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
-    *mpi_reply, Mpi2SasPhyPage1_t *config_page, u32 phy_number)
-{
-       Mpi2ConfigRequest_t mpi_request;
-       int r;
-
-       memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
-       mpi_request.Function = MPI2_FUNCTION_CONFIG;
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
-       mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
-       mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;
-       mpi_request.Header.PageNumber = 1;
-       mpi_request.Header.PageVersion = MPI2_SASPHY1_PAGEVERSION;
-       mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
-       if (r)
-               goto out;
-
-       mpi_request.PageAddress =
-           cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
-           sizeof(*config_page));
- out:
-       return r;
-}
-
-/**
- * mpt2sas_config_get_raid_volume_pg1 - obtain raid volume page 1
- * @ioc: per adapter object
- * @mpi_reply: reply mf payload returned from firmware
- * @config_page: contents of the config page
- * @form: GET_NEXT_HANDLE or HANDLE
- * @handle: volume handle
- * Context: sleep.
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_config_get_raid_volume_pg1(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form,
-    u32 handle)
-{
-       Mpi2ConfigRequest_t mpi_request;
-       int r;
-
-       memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
-       mpi_request.Function = MPI2_FUNCTION_CONFIG;
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
-       mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
-       mpi_request.Header.PageNumber = 1;
-       mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE1_PAGEVERSION;
-       mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
-       if (r)
-               goto out;
-
-       mpi_request.PageAddress = cpu_to_le32(form | handle);
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
-           sizeof(*config_page));
- out:
-       return r;
-}
-
-/**
- * mpt2sas_config_get_number_pds - obtain number of phys disk assigned to volume
- * @ioc: per adapter object
- * @handle: volume handle
- * @num_pds: returns pds count
- * Context: sleep.
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_config_get_number_pds(struct MPT2SAS_ADAPTER *ioc, u16 handle,
-    u8 *num_pds)
-{
-       Mpi2ConfigRequest_t mpi_request;
-       Mpi2RaidVolPage0_t config_page;
-       Mpi2ConfigReply_t mpi_reply;
-       int r;
-       u16 ioc_status;
-
-       memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
-       *num_pds = 0;
-       mpi_request.Function = MPI2_FUNCTION_CONFIG;
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
-       mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
-       mpi_request.Header.PageNumber = 0;
-       mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
-       mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
-       r = _config_request(ioc, &mpi_request, &mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
-       if (r)
-               goto out;
-
-       mpi_request.PageAddress =
-           cpu_to_le32(MPI2_RAID_VOLUME_PGAD_FORM_HANDLE | handle);
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-       r = _config_request(ioc, &mpi_request, &mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page,
-           sizeof(Mpi2RaidVolPage0_t));
-       if (!r) {
-               ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-                   MPI2_IOCSTATUS_MASK;
-               if (ioc_status == MPI2_IOCSTATUS_SUCCESS)
-                       *num_pds = config_page.NumPhysDisks;
-       }
-
- out:
-       return r;
-}
-
-/**
- * mpt2sas_config_get_raid_volume_pg0 - obtain raid volume page 0
- * @ioc: per adapter object
- * @mpi_reply: reply mf payload returned from firmware
- * @config_page: contents of the config page
- * @form: GET_NEXT_HANDLE or HANDLE
- * @handle: volume handle
- * @sz: size of buffer passed in config_page
- * Context: sleep.
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_config_get_raid_volume_pg0(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 form,
-    u32 handle, u16 sz)
-{
-       Mpi2ConfigRequest_t mpi_request;
-       int r;
-
-       memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
-       mpi_request.Function = MPI2_FUNCTION_CONFIG;
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
-       mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
-       mpi_request.Header.PageNumber = 0;
-       mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
-       mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
-       if (r)
-               goto out;
-
-       mpi_request.PageAddress = cpu_to_le32(form | handle);
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
- out:
-       return r;
-}
-
-/**
- * mpt2sas_config_get_phys_disk_pg0 - obtain phys disk page 0
- * @ioc: per adapter object
- * @mpi_reply: reply mf payload returned from firmware
- * @config_page: contents of the config page
- * @form: GET_NEXT_PHYSDISKNUM, PHYSDISKNUM, DEVHANDLE
- * @form_specific: specific to the form
- * Context: sleep.
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_config_get_phys_disk_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
-    *mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page, u32 form,
-    u32 form_specific)
-{
-       Mpi2ConfigRequest_t mpi_request;
-       int r;
-
-       memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
-       mpi_request.Function = MPI2_FUNCTION_CONFIG;
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
-       mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK;
-       mpi_request.Header.PageNumber = 0;
-       mpi_request.Header.PageVersion = MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION;
-       mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
-       if (r)
-               goto out;
-
-       mpi_request.PageAddress = cpu_to_le32(form | form_specific);
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-       r = _config_request(ioc, &mpi_request, mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
-           sizeof(*config_page));
- out:
-       return r;
-}
-
-/**
- * mpt2sas_config_get_volume_handle - returns volume handle for give hidden raid components
- * @ioc: per adapter object
- * @pd_handle: phys disk handle
- * @volume_handle: volume handle
- * Context: sleep.
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER *ioc, u16 pd_handle,
-    u16 *volume_handle)
-{
-       Mpi2RaidConfigurationPage0_t *config_page = NULL;
-       Mpi2ConfigRequest_t mpi_request;
-       Mpi2ConfigReply_t mpi_reply;
-       int r, i, config_page_sz;
-       u16 ioc_status;
-       int config_num;
-       u16 element_type;
-       u16 phys_disk_dev_handle;
-
-       *volume_handle = 0;
-       memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
-       mpi_request.Function = MPI2_FUNCTION_CONFIG;
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
-       mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
-       mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG;
-       mpi_request.Header.PageVersion = MPI2_RAIDCONFIG0_PAGEVERSION;
-       mpi_request.Header.PageNumber = 0;
-       mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
-       r = _config_request(ioc, &mpi_request, &mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
-       if (r)
-               goto out;
-
-       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-       config_page_sz = (le16_to_cpu(mpi_reply.ExtPageLength) * 4);
-       config_page = kmalloc(config_page_sz, GFP_KERNEL);
-       if (!config_page) {
-               r = -1;
-               goto out;
-       }
-       config_num = 0xff;
-       while (1) {
-               mpi_request.PageAddress = cpu_to_le32(config_num +
-                   MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM);
-               r = _config_request(ioc, &mpi_request, &mpi_reply,
-                   MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
-                   config_page_sz);
-               if (r)
-                       goto out;
-               r = -1;
-               ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-                   MPI2_IOCSTATUS_MASK;
-               if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
-                       goto out;
-               for (i = 0; i < config_page->NumElements; i++) {
-                       element_type = le16_to_cpu(config_page->
-                           ConfigElement[i].ElementFlags) &
-                           MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE;
-                       if (element_type ==
-                           MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT ||
-                           element_type ==
-                           MPI2_RAIDCONFIG0_EFLAGS_OCE_ELEMENT) {
-                               phys_disk_dev_handle =
-                                   le16_to_cpu(config_page->ConfigElement[i].
-                                   PhysDiskDevHandle);
-                               if (phys_disk_dev_handle == pd_handle) {
-                                       *volume_handle =
-                                           le16_to_cpu(config_page->
-                                           ConfigElement[i].VolDevHandle);
-                                       r = 0;
-                                       goto out;
-                               }
-                       } else if (element_type ==
-                           MPI2_RAIDCONFIG0_EFLAGS_HOT_SPARE_ELEMENT) {
-                               *volume_handle = 0;
-                               r = 0;
-                               goto out;
-                       }
-               }
-               config_num = config_page->ConfigNum;
-       }
- out:
-       kfree(config_page);
-       return r;
-}
-
-/**
- * mpt2sas_config_get_volume_wwid - returns wwid given the volume handle
- * @ioc: per adapter object
- * @volume_handle: volume handle
- * @wwid: volume wwid
- * Context: sleep.
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_config_get_volume_wwid(struct MPT2SAS_ADAPTER *ioc, u16 volume_handle,
-    u64 *wwid)
-{
-       Mpi2ConfigReply_t mpi_reply;
-       Mpi2RaidVolPage1_t raid_vol_pg1;
-
-       *wwid = 0;
-       if (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
-           &raid_vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE,
-           volume_handle))) {
-               *wwid = le64_to_cpu(raid_vol_pg1.WWID);
-               return 0;
-       } else
-               return -1;
-}
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
deleted file mode 100644 (file)
index 3694b63..0000000
+++ /dev/null
@@ -1,3101 +0,0 @@
-/*
- * Management Module Support for MPT (Message Passing Technology) based
- * controllers
- *
- * This code is based on drivers/scsi/mpt2sas/mpt2_ctl.c
- * Copyright (C) 2007-2014  LSI Corporation
- * Copyright (C) 20013-2014 Avago Technologies
- *  (mailto: MPT-FusionLinux.pdl@avagotech.com)
- *
- * 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.
- *
- * NO WARRANTY
- * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
- * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
- * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
- * solely responsible for determining the appropriateness of using and
- * distributing the Program and assumes all risks associated with its
- * exercise of rights under this Agreement, including but not limited to
- * the risks and costs of program errors, damage to or loss of data,
- * programs or equipment, and unavailability or interruption of operations.
-
- * DISCLAIMER OF LIABILITY
- * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
- * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
- * USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/mutex.h>
-#include <linux/compat.h>
-#include <linux/poll.h>
-
-#include <linux/io.h>
-#include <linux/uaccess.h>
-
-#include "mpt2sas_base.h"
-#include "mpt2sas_ctl.h"
-
-static DEFINE_MUTEX(_ctl_mutex);
-static struct fasync_struct *async_queue;
-static DECLARE_WAIT_QUEUE_HEAD(ctl_poll_wait);
-
-static int _ctl_send_release(struct MPT2SAS_ADAPTER *ioc, u8 buffer_type,
-    u8 *issue_reset);
-
-/**
- * enum block_state - blocking state
- * @NON_BLOCKING: non blocking
- * @BLOCKING: blocking
- *
- * These states are for ioctls that need to wait for a response
- * from firmware, so they probably require sleep.
- */
-enum block_state {
-       NON_BLOCKING,
-       BLOCKING,
-};
-
-#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
-/**
- * _ctl_sas_device_find_by_handle - sas device search
- * @ioc: per adapter object
- * @handle: sas device handle (assigned by firmware)
- * Context: Calling function should acquire ioc->sas_device_lock
- *
- * This searches for sas_device based on sas_address, then return sas_device
- * object.
- */
-static struct _sas_device *
-_ctl_sas_device_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
-{
-       struct _sas_device *sas_device, *r;
-
-       r = NULL;
-       list_for_each_entry(sas_device, &ioc->sas_device_list, list) {
-               if (sas_device->handle != handle)
-                       continue;
-               r = sas_device;
-               goto out;
-       }
-
- out:
-       return r;
-}
-
-/**
- * _ctl_display_some_debug - debug routine
- * @ioc: per adapter object
- * @smid: system request message index
- * @calling_function_name: string pass from calling function
- * @mpi_reply: reply message frame
- * Context: none.
- *
- * Function for displaying debug info helpful when debugging issues
- * in this module.
- */
-static void
-_ctl_display_some_debug(struct MPT2SAS_ADAPTER *ioc, u16 smid,
-    char *calling_function_name, MPI2DefaultReply_t *mpi_reply)
-{
-       Mpi2ConfigRequest_t *mpi_request;
-       char *desc = NULL;
-
-       if (!(ioc->logging_level & MPT_DEBUG_IOCTL))
-               return;
-
-       mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
-       switch (mpi_request->Function) {
-       case MPI2_FUNCTION_SCSI_IO_REQUEST:
-       {
-               Mpi2SCSIIORequest_t *scsi_request =
-                   (Mpi2SCSIIORequest_t *)mpi_request;
-
-               snprintf(ioc->tmp_string, MPT_STRING_LENGTH,
-                   "scsi_io, cmd(0x%02x), cdb_len(%d)",
-                   scsi_request->CDB.CDB32[0],
-                   le16_to_cpu(scsi_request->IoFlags) & 0xF);
-               desc = ioc->tmp_string;
-               break;
-       }
-       case MPI2_FUNCTION_SCSI_TASK_MGMT:
-               desc = "task_mgmt";
-               break;
-       case MPI2_FUNCTION_IOC_INIT:
-               desc = "ioc_init";
-               break;
-       case MPI2_FUNCTION_IOC_FACTS:
-               desc = "ioc_facts";
-               break;
-       case MPI2_FUNCTION_CONFIG:
-       {
-               Mpi2ConfigRequest_t *config_request =
-                   (Mpi2ConfigRequest_t *)mpi_request;
-
-               snprintf(ioc->tmp_string, MPT_STRING_LENGTH,
-                   "config, type(0x%02x), ext_type(0x%02x), number(%d)",
-                   (config_request->Header.PageType &
-                    MPI2_CONFIG_PAGETYPE_MASK), config_request->ExtPageType,
-                   config_request->Header.PageNumber);
-               desc = ioc->tmp_string;
-               break;
-       }
-       case MPI2_FUNCTION_PORT_FACTS:
-               desc = "port_facts";
-               break;
-       case MPI2_FUNCTION_PORT_ENABLE:
-               desc = "port_enable";
-               break;
-       case MPI2_FUNCTION_EVENT_NOTIFICATION:
-               desc = "event_notification";
-               break;
-       case MPI2_FUNCTION_FW_DOWNLOAD:
-               desc = "fw_download";
-               break;
-       case MPI2_FUNCTION_FW_UPLOAD:
-               desc = "fw_upload";
-               break;
-       case MPI2_FUNCTION_RAID_ACTION:
-               desc = "raid_action";
-               break;
-       case MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH:
-       {
-               Mpi2SCSIIORequest_t *scsi_request =
-                   (Mpi2SCSIIORequest_t *)mpi_request;
-
-               snprintf(ioc->tmp_string, MPT_STRING_LENGTH,
-                   "raid_pass, cmd(0x%02x), cdb_len(%d)",
-                   scsi_request->CDB.CDB32[0],
-                   le16_to_cpu(scsi_request->IoFlags) & 0xF);
-               desc = ioc->tmp_string;
-               break;
-       }
-       case MPI2_FUNCTION_SAS_IO_UNIT_CONTROL:
-               desc = "sas_iounit_cntl";
-               break;
-       case MPI2_FUNCTION_SATA_PASSTHROUGH:
-               desc = "sata_pass";
-               break;
-       case MPI2_FUNCTION_DIAG_BUFFER_POST:
-               desc = "diag_buffer_post";
-               break;
-       case MPI2_FUNCTION_DIAG_RELEASE:
-               desc = "diag_release";
-               break;
-       case MPI2_FUNCTION_SMP_PASSTHROUGH:
-               desc = "smp_passthrough";
-               break;
-       }
-
-       if (!desc)
-               return;
-
-       printk(MPT2SAS_INFO_FMT "%s: %s, smid(%d)\n",
-           ioc->name, calling_function_name, desc, smid);
-
-       if (!mpi_reply)
-               return;
-
-       if (mpi_reply->IOCStatus || mpi_reply->IOCLogInfo)
-               printk(MPT2SAS_INFO_FMT
-                   "\tiocstatus(0x%04x), loginfo(0x%08x)\n",
-                   ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
-                   le32_to_cpu(mpi_reply->IOCLogInfo));
-
-       if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST ||
-           mpi_request->Function ==
-           MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) {
-               Mpi2SCSIIOReply_t *scsi_reply =
-                   (Mpi2SCSIIOReply_t *)mpi_reply;
-               struct _sas_device *sas_device = NULL;
-               unsigned long flags;
-
-               spin_lock_irqsave(&ioc->sas_device_lock, flags);
-               sas_device = _ctl_sas_device_find_by_handle(ioc,
-                   le16_to_cpu(scsi_reply->DevHandle));
-               if (sas_device) {
-                       printk(MPT2SAS_WARN_FMT "\tsas_address(0x%016llx), "
-                           "phy(%d)\n", ioc->name, (unsigned long long)
-                           sas_device->sas_address, sas_device->phy);
-                       printk(MPT2SAS_WARN_FMT
-                           "\tenclosure_logical_id(0x%016llx), slot(%d)\n",
-                           ioc->name, sas_device->enclosure_logical_id,
-                           sas_device->slot);
-               }
-               spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-               if (scsi_reply->SCSIState || scsi_reply->SCSIStatus)
-                       printk(MPT2SAS_INFO_FMT
-                           "\tscsi_state(0x%02x), scsi_status"
-                           "(0x%02x)\n", ioc->name,
-                           scsi_reply->SCSIState,
-                           scsi_reply->SCSIStatus);
-       }
-}
-#endif
-
-/**
- * mpt2sas_ctl_done - ctl module completion routine
- * @ioc: per adapter object
- * @smid: system request message index
- * @msix_index: MSIX table index supplied by the OS
- * @reply: reply message frame(lower 32bit addr)
- * Context: none.
- *
- * The callback handler when using ioc->ctl_cb_idx.
- *
- * Return 1 meaning mf should be freed from _base_interrupt
- *        0 means the mf is freed from this function.
- */
-u8
-mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
-       u32 reply)
-{
-       MPI2DefaultReply_t *mpi_reply;
-       Mpi2SCSIIOReply_t *scsiio_reply;
-       const void *sense_data;
-       u32 sz;
-
-       if (ioc->ctl_cmds.status == MPT2_CMD_NOT_USED)
-               return 1;
-       if (ioc->ctl_cmds.smid != smid)
-               return 1;
-       ioc->ctl_cmds.status |= MPT2_CMD_COMPLETE;
-       mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
-       if (mpi_reply) {
-               memcpy(ioc->ctl_cmds.reply, mpi_reply, mpi_reply->MsgLength*4);
-               ioc->ctl_cmds.status |= MPT2_CMD_REPLY_VALID;
-               /* get sense data */
-               if (mpi_reply->Function == MPI2_FUNCTION_SCSI_IO_REQUEST ||
-                   mpi_reply->Function ==
-                   MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) {
-                       scsiio_reply = (Mpi2SCSIIOReply_t *)mpi_reply;
-                       if (scsiio_reply->SCSIState &
-                           MPI2_SCSI_STATE_AUTOSENSE_VALID) {
-                               sz = min_t(u32, SCSI_SENSE_BUFFERSIZE,
-                                   le32_to_cpu(scsiio_reply->SenseCount));
-                               sense_data = mpt2sas_base_get_sense_buffer(ioc,
-                                   smid);
-                               memcpy(ioc->ctl_cmds.sense, sense_data, sz);
-                       }
-               }
-       }
-#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
-       _ctl_display_some_debug(ioc, smid, "ctl_done", mpi_reply);
-#endif
-       ioc->ctl_cmds.status &= ~MPT2_CMD_PENDING;
-       complete(&ioc->ctl_cmds.done);
-       return 1;
-}
-
-/**
- * _ctl_check_event_type - determines when an event needs logging
- * @ioc: per adapter object
- * @event: firmware event
- *
- * The bitmask in ioc->event_type[] indicates which events should be
- * be saved in the driver event_log.  This bitmask is set by application.
- *
- * Returns 1 when event should be captured, or zero means no match.
- */
-static int
-_ctl_check_event_type(struct MPT2SAS_ADAPTER *ioc, u16 event)
-{
-       u16 i;
-       u32 desired_event;
-
-       if (event >= 128 || !event || !ioc->event_log)
-               return 0;
-
-       desired_event = (1 << (event % 32));
-       if (!desired_event)
-               desired_event = 1;
-       i = event / 32;
-       return desired_event & ioc->event_type[i];
-}
-
-/**
- * mpt2sas_ctl_add_to_event_log - add event
- * @ioc: per adapter object
- * @mpi_reply: reply message frame
- *
- * Return nothing.
- */
-void
-mpt2sas_ctl_add_to_event_log(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2EventNotificationReply_t *mpi_reply)
-{
-       struct MPT2_IOCTL_EVENTS *event_log;
-       u16 event;
-       int i;
-       u32 sz, event_data_sz;
-       u8 send_aen = 0;
-
-       if (!ioc->event_log)
-               return;
-
-       event = le16_to_cpu(mpi_reply->Event);
-
-       if (_ctl_check_event_type(ioc, event)) {
-
-               /* insert entry into circular event_log */
-               i = ioc->event_context % MPT2SAS_CTL_EVENT_LOG_SIZE;
-               event_log = ioc->event_log;
-               event_log[i].event = event;
-               event_log[i].context = ioc->event_context++;
-
-               event_data_sz = le16_to_cpu(mpi_reply->EventDataLength)*4;
-               sz = min_t(u32, event_data_sz, MPT2_EVENT_DATA_SIZE);
-               memset(event_log[i].data, 0, MPT2_EVENT_DATA_SIZE);
-               memcpy(event_log[i].data, mpi_reply->EventData, sz);
-               send_aen = 1;
-       }
-
-       /* This aen_event_read_flag flag is set until the
-        * application has read the event log.
-        * For MPI2_EVENT_LOG_ENTRY_ADDED, we always notify.
-        */
-       if (event == MPI2_EVENT_LOG_ENTRY_ADDED ||
-           (send_aen && !ioc->aen_event_read_flag)) {
-               ioc->aen_event_read_flag = 1;
-               wake_up_interruptible(&ctl_poll_wait);
-               if (async_queue)
-                       kill_fasync(&async_queue, SIGIO, POLL_IN);
-       }
-}
-
-/**
- * mpt2sas_ctl_event_callback - firmware event handler (called at ISR time)
- * @ioc: per adapter object
- * @msix_index: MSIX table index supplied by the OS
- * @reply: reply message frame(lower 32bit addr)
- * Context: interrupt.
- *
- * This function merely adds a new work task into ioc->firmware_event_thread.
- * The tasks are worked from _firmware_event_work in user context.
- *
- * Returns void.
- */
-void
-mpt2sas_ctl_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
-       u32 reply)
-{
-       Mpi2EventNotificationReply_t *mpi_reply;
-
-       mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
-       if (unlikely(!mpi_reply)) {
-               printk(MPT2SAS_ERR_FMT "mpi_reply not valid at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               return;
-       }
-       mpt2sas_ctl_add_to_event_log(ioc, mpi_reply);
-       return;
-}
-
-/**
- * _ctl_verify_adapter - validates ioc_number passed from application
- * @ioc: per adapter object
- * @iocpp: The ioc pointer is returned in this.
- *
- * Return (-1) means error, else ioc_number.
- */
-static int
-_ctl_verify_adapter(int ioc_number, struct MPT2SAS_ADAPTER **iocpp)
-{
-       struct MPT2SAS_ADAPTER *ioc;
-       /* global ioc lock to protect controller on list operations */
-       spin_lock(&gioc_lock);
-       list_for_each_entry(ioc, &mpt2sas_ioc_list, list) {
-               if (ioc->id != ioc_number)
-                       continue;
-               spin_unlock(&gioc_lock);
-               *iocpp = ioc;
-               return ioc_number;
-       }
-       spin_unlock(&gioc_lock);
-       *iocpp = NULL;
-       return -1;
-}
-
-/**
- * mpt2sas_ctl_reset_handler - reset callback handler (for ctl)
- * @ioc: per adapter object
- * @reset_phase: phase
- *
- * The handler for doing any required cleanup or initialization.
- *
- * The reset phase can be MPT2_IOC_PRE_RESET, MPT2_IOC_AFTER_RESET,
- * MPT2_IOC_DONE_RESET
- */
-void
-mpt2sas_ctl_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
-{
-       int i;
-       u8 issue_reset;
-
-       switch (reset_phase) {
-       case MPT2_IOC_PRE_RESET:
-               dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
-                   "MPT2_IOC_PRE_RESET\n", ioc->name, __func__));
-               for (i = 0; i < MPI2_DIAG_BUF_TYPE_COUNT; i++) {
-                       if (!(ioc->diag_buffer_status[i] &
-                           MPT2_DIAG_BUFFER_IS_REGISTERED))
-                               continue;
-                       if ((ioc->diag_buffer_status[i] &
-                           MPT2_DIAG_BUFFER_IS_RELEASED))
-                               continue;
-                       _ctl_send_release(ioc, i, &issue_reset);
-               }
-               break;
-       case MPT2_IOC_AFTER_RESET:
-               dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
-                   "MPT2_IOC_AFTER_RESET\n", ioc->name, __func__));
-               if (ioc->ctl_cmds.status & MPT2_CMD_PENDING) {
-                       ioc->ctl_cmds.status |= MPT2_CMD_RESET;
-                       mpt2sas_base_free_smid(ioc, ioc->ctl_cmds.smid);
-                       complete(&ioc->ctl_cmds.done);
-               }
-               break;
-       case MPT2_IOC_DONE_RESET:
-               dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
-                   "MPT2_IOC_DONE_RESET\n", ioc->name, __func__));
-
-               for (i = 0; i < MPI2_DIAG_BUF_TYPE_COUNT; i++) {
-                       if (!(ioc->diag_buffer_status[i] &
-                           MPT2_DIAG_BUFFER_IS_REGISTERED))
-                               continue;
-                       if ((ioc->diag_buffer_status[i] &
-                           MPT2_DIAG_BUFFER_IS_RELEASED))
-                               continue;
-                       ioc->diag_buffer_status[i] |=
-                           MPT2_DIAG_BUFFER_IS_DIAG_RESET;
-               }
-               break;
-       }
-}
-
-/**
- * _ctl_fasync -
- * @fd -
- * @filep -
- * @mode -
- *
- * Called when application request fasyn callback handler.
- */
-static int
-_ctl_fasync(int fd, struct file *filep, int mode)
-{
-       return fasync_helper(fd, filep, mode, &async_queue);
-}
-
-/**
- * _ctl_poll -
- * @file -
- * @wait -
- *
- */
-static unsigned int
-_ctl_poll(struct file *filep, poll_table *wait)
-{
-       struct MPT2SAS_ADAPTER *ioc;
-
-       poll_wait(filep, &ctl_poll_wait, wait);
-
-       /* global ioc lock to protect controller on list operations */
-       spin_lock(&gioc_lock);
-       list_for_each_entry(ioc, &mpt2sas_ioc_list, list) {
-               if (ioc->aen_event_read_flag) {
-                       spin_unlock(&gioc_lock);
-                       return POLLIN | POLLRDNORM;
-               }
-       }
-       spin_unlock(&gioc_lock);
-       return 0;
-}
-
-/**
- * _ctl_set_task_mid - assign an active smid to tm request
- * @ioc: per adapter object
- * @karg - (struct mpt2_ioctl_command)
- * @tm_request - pointer to mf from user space
- *
- * Returns 0 when an smid if found, else fail.
- * during failure, the reply frame is filled.
- */
-static int
-_ctl_set_task_mid(struct MPT2SAS_ADAPTER *ioc, struct mpt2_ioctl_command *karg,
-    Mpi2SCSITaskManagementRequest_t *tm_request)
-{
-       u8 found = 0;
-       u16 i;
-       u16 handle;
-       struct scsi_cmnd *scmd;
-       struct MPT2SAS_DEVICE *priv_data;
-       unsigned long flags;
-       Mpi2SCSITaskManagementReply_t *tm_reply;
-       u32 sz;
-       u32 lun;
-       char *desc = NULL;
-
-       if (tm_request->TaskType == MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
-               desc = "abort_task";
-       else if (tm_request->TaskType == MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK)
-               desc = "query_task";
-       else
-               return 0;
-
-       lun = scsilun_to_int((struct scsi_lun *)tm_request->LUN);
-
-       handle = le16_to_cpu(tm_request->DevHandle);
-       spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-       for (i = ioc->scsiio_depth; i && !found; i--) {
-               scmd = ioc->scsi_lookup[i - 1].scmd;
-               if (scmd == NULL || scmd->device == NULL ||
-                   scmd->device->hostdata == NULL)
-                       continue;
-               if (lun != scmd->device->lun)
-                       continue;
-               priv_data = scmd->device->hostdata;
-               if (priv_data->sas_target == NULL)
-                       continue;
-               if (priv_data->sas_target->handle != handle)
-                       continue;
-               tm_request->TaskMID = cpu_to_le16(ioc->scsi_lookup[i - 1].smid);
-               found = 1;
-       }
-       spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
-
-       if (!found) {
-               dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
-                   "handle(0x%04x), lun(%d), no active mid!!\n", ioc->name,
-                   desc, le16_to_cpu(tm_request->DevHandle), lun));
-               tm_reply = ioc->ctl_cmds.reply;
-               tm_reply->DevHandle = tm_request->DevHandle;
-               tm_reply->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
-               tm_reply->TaskType = tm_request->TaskType;
-               tm_reply->MsgLength = sizeof(Mpi2SCSITaskManagementReply_t)/4;
-               tm_reply->VP_ID = tm_request->VP_ID;
-               tm_reply->VF_ID = tm_request->VF_ID;
-               sz = min_t(u32, karg->max_reply_bytes, ioc->reply_sz);
-               if (copy_to_user(karg->reply_frame_buf_ptr, ioc->ctl_cmds.reply,
-                   sz))
-                       printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__,
-                           __LINE__, __func__);
-               return 1;
-       }
-
-       dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
-           "handle(0x%04x), lun(%d), task_mid(%d)\n", ioc->name,
-           desc, le16_to_cpu(tm_request->DevHandle), lun,
-            le16_to_cpu(tm_request->TaskMID)));
-       return 0;
-}
-
-/**
- * _ctl_do_mpt_command - main handler for MPT2COMMAND opcode
- * @ioc: per adapter object
- * @karg - (struct mpt2_ioctl_command)
- * @mf - pointer to mf in user space
- */
-static long
-_ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc, struct mpt2_ioctl_command karg,
-       void __user *mf)
-{
-       MPI2RequestHeader_t *mpi_request = NULL, *request;
-       MPI2DefaultReply_t *mpi_reply;
-       u32 ioc_state;
-       u16 ioc_status;
-       u16 smid;
-       unsigned long timeout, timeleft;
-       u8 issue_reset;
-       u32 sz;
-       void *psge;
-       void *data_out = NULL;
-       dma_addr_t data_out_dma;
-       size_t data_out_sz = 0;
-       void *data_in = NULL;
-       dma_addr_t data_in_dma;
-       size_t data_in_sz = 0;
-       u32 sgl_flags;
-       long ret;
-       u16 wait_state_count;
-
-       issue_reset = 0;
-
-       if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) {
-               printk(MPT2SAS_ERR_FMT "%s: ctl_cmd in use\n",
-                   ioc->name, __func__);
-               ret = -EAGAIN;
-               goto out;
-       }
-
-       wait_state_count = 0;
-       ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
-       while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
-               if (wait_state_count++ == 10) {
-                       printk(MPT2SAS_ERR_FMT
-                           "%s: failed due to ioc not operational\n",
-                           ioc->name, __func__);
-                       ret = -EFAULT;
-                       goto out;
-               }
-               ssleep(1);
-               ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
-               printk(MPT2SAS_INFO_FMT "%s: waiting for "
-                   "operational state(count=%d)\n", ioc->name,
-                   __func__, wait_state_count);
-       }
-       if (wait_state_count)
-               printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n",
-                   ioc->name, __func__);
-
-       mpi_request = kzalloc(ioc->request_sz, GFP_KERNEL);
-       if (!mpi_request) {
-               printk(MPT2SAS_ERR_FMT "%s: failed obtaining a memory for "
-                   "mpi_request\n", ioc->name, __func__);
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       /* Check for overflow and wraparound */
-       if (karg.data_sge_offset * 4 > ioc->request_sz ||
-           karg.data_sge_offset > (UINT_MAX / 4)) {
-               ret = -EINVAL;
-               goto out;
-       }
-
-       /* copy in request message frame from user */
-       if (copy_from_user(mpi_request, mf, karg.data_sge_offset*4)) {
-               printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__, __LINE__,
-                   __func__);
-               ret = -EFAULT;
-               goto out;
-       }
-
-       if (mpi_request->Function == MPI2_FUNCTION_SCSI_TASK_MGMT) {
-               smid = mpt2sas_base_get_smid_hpr(ioc, ioc->ctl_cb_idx);
-               if (!smid) {
-                       printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
-                           ioc->name, __func__);
-                       ret = -EAGAIN;
-                       goto out;
-               }
-       } else {
-
-               smid = mpt2sas_base_get_smid_scsiio(ioc, ioc->ctl_cb_idx, NULL);
-               if (!smid) {
-                       printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
-                           ioc->name, __func__);
-                       ret = -EAGAIN;
-                       goto out;
-               }
-       }
-
-       ret = 0;
-       ioc->ctl_cmds.status = MPT2_CMD_PENDING;
-       memset(ioc->ctl_cmds.reply, 0, ioc->reply_sz);
-       request = mpt2sas_base_get_msg_frame(ioc, smid);
-       memcpy(request, mpi_request, karg.data_sge_offset*4);
-       ioc->ctl_cmds.smid = smid;
-       data_out_sz = karg.data_out_size;
-       data_in_sz = karg.data_in_size;
-
-       if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST ||
-           mpi_request->Function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) {
-               if (!le16_to_cpu(mpi_request->FunctionDependent1) ||
-                   le16_to_cpu(mpi_request->FunctionDependent1) >
-                   ioc->facts.MaxDevHandle) {
-                       ret = -EINVAL;
-                       mpt2sas_base_free_smid(ioc, smid);
-                       goto out;
-               }
-       }
-
-       /* obtain dma-able memory for data transfer */
-       if (data_out_sz) /* WRITE */ {
-               data_out = pci_alloc_consistent(ioc->pdev, data_out_sz,
-                   &data_out_dma);
-               if (!data_out) {
-                       printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__,
-                           __LINE__, __func__);
-                       ret = -ENOMEM;
-                       mpt2sas_base_free_smid(ioc, smid);
-                       goto out;
-               }
-               if (copy_from_user(data_out, karg.data_out_buf_ptr,
-                       data_out_sz)) {
-                       printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__,
-                           __LINE__, __func__);
-                       ret =  -EFAULT;
-                       mpt2sas_base_free_smid(ioc, smid);
-                       goto out;
-               }
-       }
-
-       if (data_in_sz) /* READ */ {
-               data_in = pci_alloc_consistent(ioc->pdev, data_in_sz,
-                   &data_in_dma);
-               if (!data_in) {
-                       printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__,
-                           __LINE__, __func__);
-                       ret = -ENOMEM;
-                       mpt2sas_base_free_smid(ioc, smid);
-                       goto out;
-               }
-       }
-
-       /* add scatter gather elements */
-       psge = (void *)request + (karg.data_sge_offset*4);
-
-       if (!data_out_sz && !data_in_sz) {
-               mpt2sas_base_build_zero_len_sge(ioc, psge);
-       } else if (data_out_sz && data_in_sz) {
-               /* WRITE sgel first */
-               sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
-                   MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC);
-               sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
-               ioc->base_add_sg_single(psge, sgl_flags |
-                   data_out_sz, data_out_dma);
-
-               /* incr sgel */
-               psge += ioc->sge_size;
-
-               /* READ sgel last */
-               sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
-                   MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER |
-                   MPI2_SGE_FLAGS_END_OF_LIST);
-               sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
-               ioc->base_add_sg_single(psge, sgl_flags |
-                   data_in_sz, data_in_dma);
-       } else if (data_out_sz) /* WRITE */ {
-               sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
-                   MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER |
-                   MPI2_SGE_FLAGS_END_OF_LIST | MPI2_SGE_FLAGS_HOST_TO_IOC);
-               sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
-               ioc->base_add_sg_single(psge, sgl_flags |
-                   data_out_sz, data_out_dma);
-       } else if (data_in_sz) /* READ */ {
-               sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
-                   MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER |
-                   MPI2_SGE_FLAGS_END_OF_LIST);
-               sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
-               ioc->base_add_sg_single(psge, sgl_flags |
-                   data_in_sz, data_in_dma);
-       }
-
-       /* send command to firmware */
-#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
-       _ctl_display_some_debug(ioc, smid, "ctl_request", NULL);
-#endif
-
-       init_completion(&ioc->ctl_cmds.done);
-       switch (mpi_request->Function) {
-       case MPI2_FUNCTION_SCSI_IO_REQUEST:
-       case MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH:
-       {
-               Mpi2SCSIIORequest_t *scsiio_request =
-                   (Mpi2SCSIIORequest_t *)request;
-               scsiio_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE;
-               scsiio_request->SenseBufferLowAddress =
-                   mpt2sas_base_get_sense_buffer_dma(ioc, smid);
-               memset(ioc->ctl_cmds.sense, 0, SCSI_SENSE_BUFFERSIZE);
-               if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST)
-                       mpt2sas_base_put_smid_scsi_io(ioc, smid,
-                           le16_to_cpu(mpi_request->FunctionDependent1));
-               else
-                       mpt2sas_base_put_smid_default(ioc, smid);
-               break;
-       }
-       case MPI2_FUNCTION_SCSI_TASK_MGMT:
-       {
-               Mpi2SCSITaskManagementRequest_t *tm_request =
-                   (Mpi2SCSITaskManagementRequest_t *)request;
-
-               dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "TASK_MGMT: "
-                   "handle(0x%04x), task_type(0x%02x)\n", ioc->name,
-                   le16_to_cpu(tm_request->DevHandle), tm_request->TaskType));
-
-               if (tm_request->TaskType ==
-                   MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK ||
-                   tm_request->TaskType ==
-                   MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK) {
-                       if (_ctl_set_task_mid(ioc, &karg, tm_request)) {
-                               mpt2sas_base_free_smid(ioc, smid);
-                               goto out;
-                       }
-               }
-
-               mpt2sas_scsih_set_tm_flag(ioc, le16_to_cpu(
-                   tm_request->DevHandle));
-               mpt2sas_base_put_smid_hi_priority(ioc, smid);
-               break;
-       }
-       case MPI2_FUNCTION_SMP_PASSTHROUGH:
-       {
-               Mpi2SmpPassthroughRequest_t *smp_request =
-                   (Mpi2SmpPassthroughRequest_t *)mpi_request;
-               u8 *data;
-
-               /* ioc determines which port to use */
-               smp_request->PhysicalPort = 0xFF;
-               if (smp_request->PassthroughFlags &
-                   MPI2_SMP_PT_REQ_PT_FLAGS_IMMEDIATE)
-                       data = (u8 *)&smp_request->SGL;
-               else {
-                       if (unlikely(data_out == NULL)) {
-                               printk(KERN_ERR "failure at %s:%d/%s()!\n",
-                                   __FILE__, __LINE__, __func__);
-                               mpt2sas_base_free_smid(ioc, smid);
-                               ret = -EINVAL;
-                               goto out;
-                       }
-                       data = data_out;
-               }
-
-               if (data[1] == 0x91 && (data[10] == 1 || data[10] == 2)) {
-                       ioc->ioc_link_reset_in_progress = 1;
-                       ioc->ignore_loginfos = 1;
-               }
-               mpt2sas_base_put_smid_default(ioc, smid);
-               break;
-       }
-       case MPI2_FUNCTION_SAS_IO_UNIT_CONTROL:
-       {
-               Mpi2SasIoUnitControlRequest_t *sasiounit_request =
-                   (Mpi2SasIoUnitControlRequest_t *)mpi_request;
-
-               if (sasiounit_request->Operation == MPI2_SAS_OP_PHY_HARD_RESET
-                   || sasiounit_request->Operation ==
-                   MPI2_SAS_OP_PHY_LINK_RESET) {
-                       ioc->ioc_link_reset_in_progress = 1;
-                       ioc->ignore_loginfos = 1;
-               }
-               mpt2sas_base_put_smid_default(ioc, smid);
-               break;
-       }
-       default:
-               mpt2sas_base_put_smid_default(ioc, smid);
-               break;
-       }
-
-       if (karg.timeout < MPT2_IOCTL_DEFAULT_TIMEOUT)
-               timeout = MPT2_IOCTL_DEFAULT_TIMEOUT;
-       else
-               timeout = karg.timeout;
-       timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done,
-           timeout*HZ);
-       if (mpi_request->Function == MPI2_FUNCTION_SCSI_TASK_MGMT) {
-               Mpi2SCSITaskManagementRequest_t *tm_request =
-                   (Mpi2SCSITaskManagementRequest_t *)mpi_request;
-               mpt2sas_scsih_clear_tm_flag(ioc, le16_to_cpu(
-                   tm_request->DevHandle));
-       } else if ((mpi_request->Function == MPI2_FUNCTION_SMP_PASSTHROUGH ||
-           mpi_request->Function == MPI2_FUNCTION_SAS_IO_UNIT_CONTROL) &&
-               ioc->ioc_link_reset_in_progress) {
-               ioc->ioc_link_reset_in_progress = 0;
-               ioc->ignore_loginfos = 0;
-       }
-       if (!(ioc->ctl_cmds.status & MPT2_CMD_COMPLETE)) {
-               printk(MPT2SAS_ERR_FMT "%s: timeout\n", ioc->name,
-                   __func__);
-               _debug_dump_mf(mpi_request, karg.data_sge_offset);
-               if (!(ioc->ctl_cmds.status & MPT2_CMD_RESET))
-                       issue_reset = 1;
-               goto issue_host_reset;
-       }
-
-       mpi_reply = ioc->ctl_cmds.reply;
-       ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
-
-#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
-       if (mpi_reply->Function == MPI2_FUNCTION_SCSI_TASK_MGMT &&
-           (ioc->logging_level & MPT_DEBUG_TM)) {
-               Mpi2SCSITaskManagementReply_t *tm_reply =
-                   (Mpi2SCSITaskManagementReply_t *)mpi_reply;
-
-               printk(MPT2SAS_INFO_FMT "TASK_MGMT: "
-                   "IOCStatus(0x%04x), IOCLogInfo(0x%08x), "
-                   "TerminationCount(0x%08x)\n", ioc->name,
-                   le16_to_cpu(tm_reply->IOCStatus),
-                   le32_to_cpu(tm_reply->IOCLogInfo),
-                   le32_to_cpu(tm_reply->TerminationCount));
-       }
-#endif
-       /* copy out xdata to user */
-       if (data_in_sz) {
-               if (copy_to_user(karg.data_in_buf_ptr, data_in,
-                   data_in_sz)) {
-                       printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__,
-                           __LINE__, __func__);
-                       ret = -ENODATA;
-                       goto out;
-               }
-       }
-
-       /* copy out reply message frame to user */
-       if (karg.max_reply_bytes) {
-               sz = min_t(u32, karg.max_reply_bytes, ioc->reply_sz);
-               if (copy_to_user(karg.reply_frame_buf_ptr, ioc->ctl_cmds.reply,
-                   sz)) {
-                       printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__,
-                           __LINE__, __func__);
-                       ret = -ENODATA;
-                       goto out;
-               }
-       }
-
-       /* copy out sense to user */
-       if (karg.max_sense_bytes && (mpi_request->Function ==
-           MPI2_FUNCTION_SCSI_IO_REQUEST || mpi_request->Function ==
-           MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
-               sz = min_t(u32, karg.max_sense_bytes, SCSI_SENSE_BUFFERSIZE);
-               if (copy_to_user(karg.sense_data_ptr,
-                       ioc->ctl_cmds.sense, sz)) {
-                       printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__,
-                           __LINE__, __func__);
-                       ret = -ENODATA;
-                       goto out;
-               }
-       }
-
- issue_host_reset:
-       if (issue_reset) {
-               ret = -ENODATA;
-               if ((mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST ||
-                   mpi_request->Function ==
-                   MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH ||
-                   mpi_request->Function == MPI2_FUNCTION_SATA_PASSTHROUGH)) {
-                       printk(MPT2SAS_INFO_FMT "issue target reset: handle "
-                           "= (0x%04x)\n", ioc->name,
-                           le16_to_cpu(mpi_request->FunctionDependent1));
-                       mpt2sas_halt_firmware(ioc);
-                       mpt2sas_scsih_issue_tm(ioc,
-                           le16_to_cpu(mpi_request->FunctionDependent1), 0, 0,
-                           0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 10,
-                           TM_MUTEX_ON);
-                       ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
-               } else
-                       mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
-                           FORCE_BIG_HAMMER);
-       }
-
- out:
-
-       /* free memory associated with sg buffers */
-       if (data_in)
-               pci_free_consistent(ioc->pdev, data_in_sz, data_in,
-                   data_in_dma);
-
-       if (data_out)
-               pci_free_consistent(ioc->pdev, data_out_sz, data_out,
-                   data_out_dma);
-
-       kfree(mpi_request);
-       ioc->ctl_cmds.status = MPT2_CMD_NOT_USED;
-       return ret;
-}
-
-/**
- * _ctl_getiocinfo - main handler for MPT2IOCINFO opcode
- * @ioc: per adapter object
- * @arg - user space buffer containing ioctl content
- */
-static long
-_ctl_getiocinfo(struct MPT2SAS_ADAPTER *ioc, void __user *arg)
-{
-       struct mpt2_ioctl_iocinfo karg;
-
-       if (copy_from_user(&karg, arg, sizeof(karg))) {
-               printk(KERN_ERR "failure at %s:%d/%s()!\n",
-                   __FILE__, __LINE__, __func__);
-               return -EFAULT;
-       }
-
-       dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
-           __func__));
-
-       memset(&karg, 0 , sizeof(karg));
-       if (ioc->is_warpdrive)
-               karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2_SSS6200;
-       else
-               karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2;
-       if (ioc->pfacts)
-               karg.port_number = ioc->pfacts[0].PortNumber;
-       karg.hw_rev = ioc->pdev->revision;
-       karg.pci_id = ioc->pdev->device;
-       karg.subsystem_device = ioc->pdev->subsystem_device;
-       karg.subsystem_vendor = ioc->pdev->subsystem_vendor;
-       karg.pci_information.u.bits.bus = ioc->pdev->bus->number;
-       karg.pci_information.u.bits.device = PCI_SLOT(ioc->pdev->devfn);
-       karg.pci_information.u.bits.function = PCI_FUNC(ioc->pdev->devfn);
-       karg.pci_information.segment_id = pci_domain_nr(ioc->pdev->bus);
-       karg.firmware_version = ioc->facts.FWVersion.Word;
-       strcpy(karg.driver_version, MPT2SAS_DRIVER_NAME);
-       strcat(karg.driver_version, "-");
-       strcat(karg.driver_version, MPT2SAS_DRIVER_VERSION);
-       karg.bios_version = le32_to_cpu(ioc->bios_pg3.BiosVersion);
-
-       if (copy_to_user(arg, &karg, sizeof(karg))) {
-               printk(KERN_ERR "failure at %s:%d/%s()!\n",
-                   __FILE__, __LINE__, __func__);
-               return -EFAULT;
-       }
-       return 0;
-}
-
-/**
- * _ctl_eventquery - main handler for MPT2EVENTQUERY opcode
- * @ioc: per adapter object
- * @arg - user space buffer containing ioctl content
- */
-static long
-_ctl_eventquery(struct MPT2SAS_ADAPTER *ioc, void __user *arg)
-{
-       struct mpt2_ioctl_eventquery karg;
-
-       if (copy_from_user(&karg, arg, sizeof(karg))) {
-               printk(KERN_ERR "failure at %s:%d/%s()!\n",
-                   __FILE__, __LINE__, __func__);
-               return -EFAULT;
-       }
-
-       dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
-           __func__));
-
-       karg.event_entries = MPT2SAS_CTL_EVENT_LOG_SIZE;
-       memcpy(karg.event_types, ioc->event_type,
-           MPI2_EVENT_NOTIFY_EVENTMASK_WORDS * sizeof(u32));
-
-       if (copy_to_user(arg, &karg, sizeof(karg))) {
-               printk(KERN_ERR "failure at %s:%d/%s()!\n",
-                   __FILE__, __LINE__, __func__);
-               return -EFAULT;
-       }
-       return 0;
-}
-
-/**
- * _ctl_eventenable - main handler for MPT2EVENTENABLE opcode
- * @ioc: per adapter object
- * @arg - user space buffer containing ioctl content
- */
-static long
-_ctl_eventenable(struct MPT2SAS_ADAPTER *ioc, void __user *arg)
-{
-       struct mpt2_ioctl_eventenable karg;
-
-       if (copy_from_user(&karg, arg, sizeof(karg))) {
-               printk(KERN_ERR "failure at %s:%d/%s()!\n",
-                   __FILE__, __LINE__, __func__);
-               return -EFAULT;
-       }
-
-       dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
-           __func__));
-
-       if (ioc->event_log)
-               return 0;
-       memcpy(ioc->event_type, karg.event_types,
-           MPI2_EVENT_NOTIFY_EVENTMASK_WORDS * sizeof(u32));
-       mpt2sas_base_validate_event_type(ioc, ioc->event_type);
-
-       /* initialize event_log */
-       ioc->event_context = 0;
-       ioc->aen_event_read_flag = 0;
-       ioc->event_log = kcalloc(MPT2SAS_CTL_EVENT_LOG_SIZE,
-           sizeof(struct MPT2_IOCTL_EVENTS), GFP_KERNEL);
-       if (!ioc->event_log) {
-               printk(KERN_ERR "failure at %s:%d/%s()!\n",
-                   __FILE__, __LINE__, __func__);
-               return -ENOMEM;
-       }
-       return 0;
-}
-
-/**
- * _ctl_eventreport - main handler for MPT2EVENTREPORT opcode
- * @ioc: per adapter object
- * @arg - user space buffer containing ioctl content
- */
-static long
-_ctl_eventreport(struct MPT2SAS_ADAPTER *ioc, void __user *arg)
-{
-       struct mpt2_ioctl_eventreport karg;
-       u32 number_bytes, max_events, max;
-       struct mpt2_ioctl_eventreport __user *uarg = arg;
-
-       if (copy_from_user(&karg, arg, sizeof(karg))) {
-               printk(KERN_ERR "failure at %s:%d/%s()!\n",
-                   __FILE__, __LINE__, __func__);
-               return -EFAULT;
-       }
-
-       dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
-           __func__));
-
-       number_bytes = karg.hdr.max_data_size -
-           sizeof(struct mpt2_ioctl_header);
-       max_events = number_bytes/sizeof(struct MPT2_IOCTL_EVENTS);
-       max = min_t(u32, MPT2SAS_CTL_EVENT_LOG_SIZE, max_events);
-
-       /* If fewer than 1 event is requested, there must have
-        * been some type of error.
-        */
-       if (!max || !ioc->event_log)
-               return -ENODATA;
-
-       number_bytes = max * sizeof(struct MPT2_IOCTL_EVENTS);
-       if (copy_to_user(uarg->event_data, ioc->event_log, number_bytes)) {
-               printk(KERN_ERR "failure at %s:%d/%s()!\n",
-                   __FILE__, __LINE__, __func__);
-               return -EFAULT;
-       }
-
-       /* reset flag so SIGIO can restart */
-       ioc->aen_event_read_flag = 0;
-       return 0;
-}
-
-/**
- * _ctl_do_reset - main handler for MPT2HARDRESET opcode
- * @ioc: per adapter object
- * @arg - user space buffer containing ioctl content
- */
-static long
-_ctl_do_reset(struct MPT2SAS_ADAPTER *ioc, void __user *arg)
-{
-       struct mpt2_ioctl_diag_reset karg;
-       int retval;
-
-       if (copy_from_user(&karg, arg, sizeof(karg))) {
-               printk(KERN_ERR "failure at %s:%d/%s()!\n",
-                   __FILE__, __LINE__, __func__);
-               return -EFAULT;
-       }
-
-       if (ioc->shost_recovery || ioc->pci_error_recovery ||
-               ioc->is_driver_loading)
-               return -EAGAIN;
-       dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
-           __func__));
-
-       retval = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
-           FORCE_BIG_HAMMER);
-       printk(MPT2SAS_INFO_FMT "host reset: %s\n",
-           ioc->name, ((!retval) ? "SUCCESS" : "FAILED"));
-       return 0;
-}
-
-/**
- * _ctl_btdh_search_sas_device - searching for sas device
- * @ioc: per adapter object
- * @btdh: btdh ioctl payload
- */
-static int
-_ctl_btdh_search_sas_device(struct MPT2SAS_ADAPTER *ioc,
-    struct mpt2_ioctl_btdh_mapping *btdh)
-{
-       struct _sas_device *sas_device;
-       unsigned long flags;
-       int rc = 0;
-
-       if (list_empty(&ioc->sas_device_list))
-               return rc;
-
-       spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       list_for_each_entry(sas_device, &ioc->sas_device_list, list) {
-               if (btdh->bus == 0xFFFFFFFF && btdh->id == 0xFFFFFFFF &&
-                   btdh->handle == sas_device->handle) {
-                       btdh->bus = sas_device->channel;
-                       btdh->id = sas_device->id;
-                       rc = 1;
-                       goto out;
-               } else if (btdh->bus == sas_device->channel && btdh->id ==
-                   sas_device->id && btdh->handle == 0xFFFF) {
-                       btdh->handle = sas_device->handle;
-                       rc = 1;
-                       goto out;
-               }
-       }
- out:
-       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-       return rc;
-}
-
-/**
- * _ctl_btdh_search_raid_device - searching for raid device
- * @ioc: per adapter object
- * @btdh: btdh ioctl payload
- */
-static int
-_ctl_btdh_search_raid_device(struct MPT2SAS_ADAPTER *ioc,
-    struct mpt2_ioctl_btdh_mapping *btdh)
-{
-       struct _raid_device *raid_device;
-       unsigned long flags;
-       int rc = 0;
-
-       if (list_empty(&ioc->raid_device_list))
-               return rc;
-
-       spin_lock_irqsave(&ioc->raid_device_lock, flags);
-       list_for_each_entry(raid_device, &ioc->raid_device_list, list) {
-               if (btdh->bus == 0xFFFFFFFF && btdh->id == 0xFFFFFFFF &&
-                   btdh->handle == raid_device->handle) {
-                       btdh->bus = raid_device->channel;
-                       btdh->id = raid_device->id;
-                       rc = 1;
-                       goto out;
-               } else if (btdh->bus == raid_device->channel && btdh->id ==
-                   raid_device->id && btdh->handle == 0xFFFF) {
-                       btdh->handle = raid_device->handle;
-                       rc = 1;
-                       goto out;
-               }
-       }
- out:
-       spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
-       return rc;
-}
-
-/**
- * _ctl_btdh_mapping - main handler for MPT2BTDHMAPPING opcode
- * @ioc: per adapter object
- * @arg - user space buffer containing ioctl content
- */
-static long
-_ctl_btdh_mapping(struct MPT2SAS_ADAPTER *ioc, void __user *arg)
-{
-       struct mpt2_ioctl_btdh_mapping karg;
-       int rc;
-
-       if (copy_from_user(&karg, arg, sizeof(karg))) {
-               printk(KERN_ERR "failure at %s:%d/%s()!\n",
-                   __FILE__, __LINE__, __func__);
-               return -EFAULT;
-       }
-
-       dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-           __func__));
-
-       rc = _ctl_btdh_search_sas_device(ioc, &karg);
-       if (!rc)
-               _ctl_btdh_search_raid_device(ioc, &karg);
-
-       if (copy_to_user(arg, &karg, sizeof(karg))) {
-               printk(KERN_ERR "failure at %s:%d/%s()!\n",
-                   __FILE__, __LINE__, __func__);
-               return -EFAULT;
-       }
-       return 0;
-}
-
-/**
- * _ctl_diag_capability - return diag buffer capability
- * @ioc: per adapter object
- * @buffer_type: specifies either TRACE, SNAPSHOT, or EXTENDED
- *
- * returns 1 when diag buffer support is enabled in firmware
- */
-static u8
-_ctl_diag_capability(struct MPT2SAS_ADAPTER *ioc, u8 buffer_type)
-{
-       u8 rc = 0;
-
-       switch (buffer_type) {
-       case MPI2_DIAG_BUF_TYPE_TRACE:
-               if (ioc->facts.IOCCapabilities &
-                   MPI2_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER)
-                       rc = 1;
-               break;
-       case MPI2_DIAG_BUF_TYPE_SNAPSHOT:
-               if (ioc->facts.IOCCapabilities &
-                   MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER)
-                       rc = 1;
-               break;
-       case MPI2_DIAG_BUF_TYPE_EXTENDED:
-               if (ioc->facts.IOCCapabilities &
-                   MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER)
-                       rc = 1;
-       }
-
-       return rc;
-}
-
-/**
- * _ctl_diag_register_2 - wrapper for registering diag buffer support
- * @ioc: per adapter object
- * @diag_register: the diag_register struct passed in from user space
- *
- */
-static long
-_ctl_diag_register_2(struct MPT2SAS_ADAPTER *ioc,
-    struct mpt2_diag_register *diag_register)
-{
-       int rc, i;
-       void *request_data = NULL;
-       dma_addr_t request_data_dma;
-       u32 request_data_sz = 0;
-       Mpi2DiagBufferPostRequest_t *mpi_request;
-       Mpi2DiagBufferPostReply_t *mpi_reply;
-       u8 buffer_type;
-       unsigned long timeleft;
-       u16 smid;
-       u16 ioc_status;
-       u8 issue_reset = 0;
-
-       dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-           __func__));
-
-       if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) {
-               printk(MPT2SAS_ERR_FMT "%s: ctl_cmd in use\n",
-                   ioc->name, __func__);
-               rc = -EAGAIN;
-               goto out;
-       }
-
-       buffer_type = diag_register->buffer_type;
-       if (!_ctl_diag_capability(ioc, buffer_type)) {
-               printk(MPT2SAS_ERR_FMT "%s: doesn't have capability for "
-                   "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type);
-               return -EPERM;
-       }
-
-       if (ioc->diag_buffer_status[buffer_type] &
-           MPT2_DIAG_BUFFER_IS_REGISTERED) {
-               printk(MPT2SAS_ERR_FMT "%s: already has a registered "
-                   "buffer for buffer_type(0x%02x)\n", ioc->name, __func__,
-                   buffer_type);
-               return -EINVAL;
-       }
-
-       if (diag_register->requested_buffer_size % 4)  {
-               printk(MPT2SAS_ERR_FMT "%s: the requested_buffer_size "
-                   "is not 4 byte aligned\n", ioc->name, __func__);
-               return -EINVAL;
-       }
-
-       smid = mpt2sas_base_get_smid(ioc, ioc->ctl_cb_idx);
-       if (!smid) {
-               printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
-                   ioc->name, __func__);
-               rc = -EAGAIN;
-               goto out;
-       }
-
-       rc = 0;
-       ioc->ctl_cmds.status = MPT2_CMD_PENDING;
-       memset(ioc->ctl_cmds.reply, 0, ioc->reply_sz);
-       mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
-       ioc->ctl_cmds.smid = smid;
-
-       request_data = ioc->diag_buffer[buffer_type];
-       request_data_sz = diag_register->requested_buffer_size;
-       ioc->unique_id[buffer_type] = diag_register->unique_id;
-       ioc->diag_buffer_status[buffer_type] = 0;
-       memcpy(ioc->product_specific[buffer_type],
-           diag_register->product_specific, MPT2_PRODUCT_SPECIFIC_DWORDS);
-       ioc->diagnostic_flags[buffer_type] = diag_register->diagnostic_flags;
-
-       if (request_data) {
-               request_data_dma = ioc->diag_buffer_dma[buffer_type];
-               if (request_data_sz != ioc->diag_buffer_sz[buffer_type]) {
-                       pci_free_consistent(ioc->pdev,
-                           ioc->diag_buffer_sz[buffer_type],
-                           request_data, request_data_dma);
-                       request_data = NULL;
-               }
-       }
-
-       if (request_data == NULL) {
-               ioc->diag_buffer_sz[buffer_type] = 0;
-               ioc->diag_buffer_dma[buffer_type] = 0;
-               request_data = pci_alloc_consistent(
-                       ioc->pdev, request_data_sz, &request_data_dma);
-               if (request_data == NULL) {
-                       printk(MPT2SAS_ERR_FMT "%s: failed allocating memory"
-                           " for diag buffers, requested size(%d)\n",
-                           ioc->name, __func__, request_data_sz);
-                       mpt2sas_base_free_smid(ioc, smid);
-                       return -ENOMEM;
-               }
-               ioc->diag_buffer[buffer_type] = request_data;
-               ioc->diag_buffer_sz[buffer_type] = request_data_sz;
-               ioc->diag_buffer_dma[buffer_type] = request_data_dma;
-       }
-
-       mpi_request->Function = MPI2_FUNCTION_DIAG_BUFFER_POST;
-       mpi_request->BufferType = diag_register->buffer_type;
-       mpi_request->Flags = cpu_to_le32(diag_register->diagnostic_flags);
-       mpi_request->BufferAddress = cpu_to_le64(request_data_dma);
-       mpi_request->BufferLength = cpu_to_le32(request_data_sz);
-       mpi_request->VF_ID = 0; /* TODO */
-       mpi_request->VP_ID = 0;
-
-       dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: diag_buffer(0x%p), "
-           "dma(0x%llx), sz(%d)\n", ioc->name, __func__, request_data,
-           (unsigned long long)request_data_dma,
-           le32_to_cpu(mpi_request->BufferLength)));
-
-       for (i = 0; i < MPT2_PRODUCT_SPECIFIC_DWORDS; i++)
-               mpi_request->ProductSpecific[i] =
-                       cpu_to_le32(ioc->product_specific[buffer_type][i]);
-
-       init_completion(&ioc->ctl_cmds.done);
-       mpt2sas_base_put_smid_default(ioc, smid);
-       timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done,
-           MPT2_IOCTL_DEFAULT_TIMEOUT*HZ);
-
-       if (!(ioc->ctl_cmds.status & MPT2_CMD_COMPLETE)) {
-               printk(MPT2SAS_ERR_FMT "%s: timeout\n", ioc->name,
-                   __func__);
-               _debug_dump_mf(mpi_request,
-                   sizeof(Mpi2DiagBufferPostRequest_t)/4);
-               if (!(ioc->ctl_cmds.status & MPT2_CMD_RESET))
-                       issue_reset = 1;
-               goto issue_host_reset;
-       }
-
-       /* process the completed Reply Message Frame */
-       if ((ioc->ctl_cmds.status & MPT2_CMD_REPLY_VALID) == 0) {
-               printk(MPT2SAS_ERR_FMT "%s: no reply message\n",
-                   ioc->name, __func__);
-               rc = -EFAULT;
-               goto out;
-       }
-
-       mpi_reply = ioc->ctl_cmds.reply;
-       ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
-
-       if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
-               ioc->diag_buffer_status[buffer_type] |=
-                       MPT2_DIAG_BUFFER_IS_REGISTERED;
-               dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: success\n",
-                   ioc->name, __func__));
-       } else {
-               printk(MPT2SAS_INFO_FMT "%s: ioc_status(0x%04x) "
-                   "log_info(0x%08x)\n", ioc->name, __func__,
-                   ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo));
-               rc = -EFAULT;
-       }
-
- issue_host_reset:
-       if (issue_reset)
-               mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
-                   FORCE_BIG_HAMMER);
-
- out:
-
-       if (rc && request_data)
-               pci_free_consistent(ioc->pdev, request_data_sz,
-                   request_data, request_data_dma);
-
-       ioc->ctl_cmds.status = MPT2_CMD_NOT_USED;
-       return rc;
-}
-
-/**
- * mpt2sas_enable_diag_buffer - enabling diag_buffers support driver load time
- * @ioc: per adapter object
- * @bits_to_register: bitwise field where trace is bit 0, and snapshot is bit 1
- *
- * This is called when command line option diag_buffer_enable is enabled
- * at driver load time.
- */
-void
-mpt2sas_enable_diag_buffer(struct MPT2SAS_ADAPTER *ioc, u8 bits_to_register)
-{
-       struct mpt2_diag_register diag_register;
-
-       memset(&diag_register, 0, sizeof(struct mpt2_diag_register));
-
-       if (bits_to_register & 1) {
-               printk(MPT2SAS_INFO_FMT "registering trace buffer support\n",
-                   ioc->name);
-               diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_TRACE;
-               /* register for 1MB buffers  */
-               diag_register.requested_buffer_size = (1024 * 1024);
-               diag_register.unique_id = 0x7075900;
-               _ctl_diag_register_2(ioc,  &diag_register);
-       }
-
-       if (bits_to_register & 2) {
-               printk(MPT2SAS_INFO_FMT "registering snapshot buffer support\n",
-                   ioc->name);
-               diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_SNAPSHOT;
-               /* register for 2MB buffers  */
-               diag_register.requested_buffer_size = 2 * (1024 * 1024);
-               diag_register.unique_id = 0x7075901;
-               _ctl_diag_register_2(ioc,  &diag_register);
-       }
-
-       if (bits_to_register & 4) {
-               printk(MPT2SAS_INFO_FMT "registering extended buffer support\n",
-                   ioc->name);
-               diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_EXTENDED;
-               /* register for 2MB buffers  */
-               diag_register.requested_buffer_size = 2 * (1024 * 1024);
-               diag_register.unique_id = 0x7075901;
-               _ctl_diag_register_2(ioc,  &diag_register);
-       }
-}
-
-/**
- * _ctl_diag_register - application register with driver
- * @ioc: per adapter object
- * @arg - user space buffer containing ioctl content
- *
- * This will allow the driver to setup any required buffers that will be
- * needed by firmware to communicate with the driver.
- */
-static long
-_ctl_diag_register(struct MPT2SAS_ADAPTER *ioc, void __user *arg)
-{
-       struct mpt2_diag_register karg;
-       long rc;
-
-       if (copy_from_user(&karg, arg, sizeof(karg))) {
-               printk(KERN_ERR "failure at %s:%d/%s()!\n",
-                   __FILE__, __LINE__, __func__);
-               return -EFAULT;
-       }
-
-       rc = _ctl_diag_register_2(ioc, &karg);
-       return rc;
-}
-
-/**
- * _ctl_diag_unregister - application unregister with driver
- * @ioc: per adapter object
- * @arg - user space buffer containing ioctl content
- *
- * This will allow the driver to cleanup any memory allocated for diag
- * messages and to free up any resources.
- */
-static long
-_ctl_diag_unregister(struct MPT2SAS_ADAPTER *ioc, void __user *arg)
-{
-       struct mpt2_diag_unregister karg;
-       void *request_data;
-       dma_addr_t request_data_dma;
-       u32 request_data_sz;
-       u8 buffer_type;
-
-       if (copy_from_user(&karg, arg, sizeof(karg))) {
-               printk(KERN_ERR "failure at %s:%d/%s()!\n",
-                   __FILE__, __LINE__, __func__);
-               return -EFAULT;
-       }
-
-       dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-           __func__));
-
-       buffer_type = karg.unique_id & 0x000000ff;
-       if (!_ctl_diag_capability(ioc, buffer_type)) {
-               printk(MPT2SAS_ERR_FMT "%s: doesn't have capability for "
-                   "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type);
-               return -EPERM;
-       }
-
-       if ((ioc->diag_buffer_status[buffer_type] &
-           MPT2_DIAG_BUFFER_IS_REGISTERED) == 0) {
-               printk(MPT2SAS_ERR_FMT "%s: buffer_type(0x%02x) is not "
-                   "registered\n", ioc->name, __func__, buffer_type);
-               return -EINVAL;
-       }
-       if ((ioc->diag_buffer_status[buffer_type] &
-           MPT2_DIAG_BUFFER_IS_RELEASED) == 0) {
-               printk(MPT2SAS_ERR_FMT "%s: buffer_type(0x%02x) has not been "
-                   "released\n", ioc->name, __func__, buffer_type);
-               return -EINVAL;
-       }
-
-       if (karg.unique_id != ioc->unique_id[buffer_type]) {
-               printk(MPT2SAS_ERR_FMT "%s: unique_id(0x%08x) is not "
-                   "registered\n", ioc->name, __func__, karg.unique_id);
-               return -EINVAL;
-       }
-
-       request_data = ioc->diag_buffer[buffer_type];
-       if (!request_data) {
-               printk(MPT2SAS_ERR_FMT "%s: doesn't have memory allocated for "
-                   "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type);
-               return -ENOMEM;
-       }
-
-       request_data_sz = ioc->diag_buffer_sz[buffer_type];
-       request_data_dma = ioc->diag_buffer_dma[buffer_type];
-       pci_free_consistent(ioc->pdev, request_data_sz,
-           request_data, request_data_dma);
-       ioc->diag_buffer[buffer_type] = NULL;
-       ioc->diag_buffer_status[buffer_type] = 0;
-       return 0;
-}
-
-/**
- * _ctl_diag_query - query relevant info associated with diag buffers
- * @ioc: per adapter object
- * @arg - user space buffer containing ioctl content
- *
- * The application will send only buffer_type and unique_id.  Driver will
- * inspect unique_id first, if valid, fill in all the info.  If unique_id is
- * 0x00, the driver will return info specified by Buffer Type.
- */
-static long
-_ctl_diag_query(struct MPT2SAS_ADAPTER *ioc, void __user *arg)
-{
-       struct mpt2_diag_query karg;
-       void *request_data;
-       int i;
-       u8 buffer_type;
-
-       if (copy_from_user(&karg, arg, sizeof(karg))) {
-               printk(KERN_ERR "failure at %s:%d/%s()!\n",
-                   __FILE__, __LINE__, __func__);
-               return -EFAULT;
-       }
-
-       dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-           __func__));
-
-       karg.application_flags = 0;
-       buffer_type = karg.buffer_type;
-
-       if (!_ctl_diag_capability(ioc, buffer_type)) {
-               printk(MPT2SAS_ERR_FMT "%s: doesn't have capability for "
-                   "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type);
-               return -EPERM;
-       }
-
-       if ((ioc->diag_buffer_status[buffer_type] &
-           MPT2_DIAG_BUFFER_IS_REGISTERED) == 0) {
-               printk(MPT2SAS_ERR_FMT "%s: buffer_type(0x%02x) is not "
-                   "registered\n", ioc->name, __func__, buffer_type);
-               return -EINVAL;
-       }
-
-       if (karg.unique_id & 0xffffff00) {
-               if (karg.unique_id != ioc->unique_id[buffer_type]) {
-                       printk(MPT2SAS_ERR_FMT "%s: unique_id(0x%08x) is not "
-                           "registered\n", ioc->name, __func__,
-                           karg.unique_id);
-                       return -EINVAL;
-               }
-       }
-
-       request_data = ioc->diag_buffer[buffer_type];
-       if (!request_data) {
-               printk(MPT2SAS_ERR_FMT "%s: doesn't have buffer for "
-                   "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type);
-               return -ENOMEM;
-       }
-
-       if (ioc->diag_buffer_status[buffer_type] & MPT2_DIAG_BUFFER_IS_RELEASED)
-               karg.application_flags = (MPT2_APP_FLAGS_APP_OWNED |
-                   MPT2_APP_FLAGS_BUFFER_VALID);
-       else
-               karg.application_flags = (MPT2_APP_FLAGS_APP_OWNED |
-                   MPT2_APP_FLAGS_BUFFER_VALID |
-                   MPT2_APP_FLAGS_FW_BUFFER_ACCESS);
-
-       for (i = 0; i < MPT2_PRODUCT_SPECIFIC_DWORDS; i++)
-               karg.product_specific[i] =
-                   ioc->product_specific[buffer_type][i];
-
-       karg.total_buffer_size = ioc->diag_buffer_sz[buffer_type];
-       karg.driver_added_buffer_size = 0;
-       karg.unique_id = ioc->unique_id[buffer_type];
-       karg.diagnostic_flags = ioc->diagnostic_flags[buffer_type];
-
-       if (copy_to_user(arg, &karg, sizeof(struct mpt2_diag_query))) {
-               printk(MPT2SAS_ERR_FMT "%s: unable to write mpt2_diag_query "
-                   "data @ %p\n", ioc->name, __func__, arg);
-               return -EFAULT;
-       }
-       return 0;
-}
-
-/**
- * _ctl_send_release - Diag Release Message
- * @ioc: per adapter object
- * @buffer_type - specifies either TRACE, SNAPSHOT, or EXTENDED
- * @issue_reset - specifies whether host reset is required.
- *
- */
-static int
-_ctl_send_release(struct MPT2SAS_ADAPTER *ioc, u8 buffer_type, u8 *issue_reset)
-{
-       Mpi2DiagReleaseRequest_t *mpi_request;
-       Mpi2DiagReleaseReply_t *mpi_reply;
-       u16 smid;
-       u16 ioc_status;
-       u32 ioc_state;
-       int rc;
-       unsigned long timeleft;
-
-       dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-           __func__));
-
-       rc = 0;
-       *issue_reset = 0;
-
-       ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
-       if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
-               dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
-                   "skipping due to FAULT state\n", ioc->name,
-                   __func__));
-               rc = -EAGAIN;
-               goto out;
-       }
-
-       if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) {
-               printk(MPT2SAS_ERR_FMT "%s: ctl_cmd in use\n",
-                   ioc->name, __func__);
-               rc = -EAGAIN;
-               goto out;
-       }
-
-       smid = mpt2sas_base_get_smid(ioc, ioc->ctl_cb_idx);
-       if (!smid) {
-               printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
-                   ioc->name, __func__);
-               rc = -EAGAIN;
-               goto out;
-       }
-
-       ioc->ctl_cmds.status = MPT2_CMD_PENDING;
-       memset(ioc->ctl_cmds.reply, 0, ioc->reply_sz);
-       mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
-       ioc->ctl_cmds.smid = smid;
-
-       mpi_request->Function = MPI2_FUNCTION_DIAG_RELEASE;
-       mpi_request->BufferType = buffer_type;
-       mpi_request->VF_ID = 0; /* TODO */
-       mpi_request->VP_ID = 0;
-
-       init_completion(&ioc->ctl_cmds.done);
-       mpt2sas_base_put_smid_default(ioc, smid);
-       timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done,
-           MPT2_IOCTL_DEFAULT_TIMEOUT*HZ);
-
-       if (!(ioc->ctl_cmds.status & MPT2_CMD_COMPLETE)) {
-               printk(MPT2SAS_ERR_FMT "%s: timeout\n", ioc->name,
-                   __func__);
-               _debug_dump_mf(mpi_request,
-                   sizeof(Mpi2DiagReleaseRequest_t)/4);
-               if (!(ioc->ctl_cmds.status & MPT2_CMD_RESET))
-                       *issue_reset = 1;
-               rc = -EFAULT;
-               goto out;
-       }
-
-       /* process the completed Reply Message Frame */
-       if ((ioc->ctl_cmds.status & MPT2_CMD_REPLY_VALID) == 0) {
-               printk(MPT2SAS_ERR_FMT "%s: no reply message\n",
-                   ioc->name, __func__);
-               rc = -EFAULT;
-               goto out;
-       }
-
-       mpi_reply = ioc->ctl_cmds.reply;
-       ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
-
-       if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
-               ioc->diag_buffer_status[buffer_type] |=
-                   MPT2_DIAG_BUFFER_IS_RELEASED;
-               dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: success\n",
-                   ioc->name, __func__));
-       } else {
-               printk(MPT2SAS_INFO_FMT "%s: ioc_status(0x%04x) "
-                   "log_info(0x%08x)\n", ioc->name, __func__,
-                   ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo));
-               rc = -EFAULT;
-       }
-
- out:
-       ioc->ctl_cmds.status = MPT2_CMD_NOT_USED;
-       return rc;
-}
-
-/**
- * _ctl_diag_release - request to send Diag Release Message to firmware
- * @arg - user space buffer containing ioctl content
- *
- * This allows ownership of the specified buffer to returned to the driver,
- * allowing an application to read the buffer without fear that firmware is
- * overwritting information in the buffer.
- */
-static long
-_ctl_diag_release(struct MPT2SAS_ADAPTER *ioc, void __user *arg)
-{
-       struct mpt2_diag_release karg;
-       void *request_data;
-       int rc;
-       u8 buffer_type;
-       u8 issue_reset = 0;
-
-       if (copy_from_user(&karg, arg, sizeof(karg))) {
-               printk(KERN_ERR "failure at %s:%d/%s()!\n",
-                   __FILE__, __LINE__, __func__);
-               return -EFAULT;
-       }
-
-       dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-           __func__));
-
-       buffer_type = karg.unique_id & 0x000000ff;
-       if (!_ctl_diag_capability(ioc, buffer_type)) {
-               printk(MPT2SAS_ERR_FMT "%s: doesn't have capability for "
-                   "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type);
-               return -EPERM;
-       }
-
-       if ((ioc->diag_buffer_status[buffer_type] &
-           MPT2_DIAG_BUFFER_IS_REGISTERED) == 0) {
-               printk(MPT2SAS_ERR_FMT "%s: buffer_type(0x%02x) is not "
-                   "registered\n", ioc->name, __func__, buffer_type);
-               return -EINVAL;
-       }
-
-       if (karg.unique_id != ioc->unique_id[buffer_type]) {
-               printk(MPT2SAS_ERR_FMT "%s: unique_id(0x%08x) is not "
-                   "registered\n", ioc->name, __func__, karg.unique_id);
-               return -EINVAL;
-       }
-
-       if (ioc->diag_buffer_status[buffer_type] &
-           MPT2_DIAG_BUFFER_IS_RELEASED) {
-               printk(MPT2SAS_ERR_FMT "%s: buffer_type(0x%02x) "
-                   "is already released\n", ioc->name, __func__,
-                   buffer_type);
-               return 0;
-       }
-
-       request_data = ioc->diag_buffer[buffer_type];
-
-       if (!request_data) {
-               printk(MPT2SAS_ERR_FMT "%s: doesn't have memory allocated for "
-                   "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type);
-               return -ENOMEM;
-       }
-
-       /* buffers were released by due to host reset */
-       if ((ioc->diag_buffer_status[buffer_type] &
-           MPT2_DIAG_BUFFER_IS_DIAG_RESET)) {
-               ioc->diag_buffer_status[buffer_type] |=
-                   MPT2_DIAG_BUFFER_IS_RELEASED;
-               ioc->diag_buffer_status[buffer_type] &=
-                   ~MPT2_DIAG_BUFFER_IS_DIAG_RESET;
-               printk(MPT2SAS_ERR_FMT "%s: buffer_type(0x%02x) "
-                   "was released due to host reset\n", ioc->name, __func__,
-                   buffer_type);
-               return 0;
-       }
-
-       rc = _ctl_send_release(ioc, buffer_type, &issue_reset);
-
-       if (issue_reset)
-               mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
-                   FORCE_BIG_HAMMER);
-
-       return rc;
-}
-
-/**
- * _ctl_diag_read_buffer - request for copy of the diag buffer
- * @ioc: per adapter object
- * @arg - user space buffer containing ioctl content
- */
-static long
-_ctl_diag_read_buffer(struct MPT2SAS_ADAPTER *ioc, void __user *arg)
-{
-       struct mpt2_diag_read_buffer karg;
-       struct mpt2_diag_read_buffer __user *uarg = arg;
-       void *request_data, *diag_data;
-       Mpi2DiagBufferPostRequest_t *mpi_request;
-       Mpi2DiagBufferPostReply_t *mpi_reply;
-       int rc, i;
-       u8 buffer_type;
-       unsigned long timeleft, request_size, copy_size;
-       u16 smid;
-       u16 ioc_status;
-       u8 issue_reset = 0;
-
-       if (copy_from_user(&karg, arg, sizeof(karg))) {
-               printk(KERN_ERR "failure at %s:%d/%s()!\n",
-                   __FILE__, __LINE__, __func__);
-               return -EFAULT;
-       }
-
-       dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
-           __func__));
-
-       buffer_type = karg.unique_id & 0x000000ff;
-       if (!_ctl_diag_capability(ioc, buffer_type)) {
-               printk(MPT2SAS_ERR_FMT "%s: doesn't have capability for "
-                   "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type);
-               return -EPERM;
-       }
-
-       if (karg.unique_id != ioc->unique_id[buffer_type]) {
-               printk(MPT2SAS_ERR_FMT "%s: unique_id(0x%08x) is not "
-                   "registered\n", ioc->name, __func__, karg.unique_id);
-               return -EINVAL;
-       }
-
-       request_data = ioc->diag_buffer[buffer_type];
-       if (!request_data) {
-               printk(MPT2SAS_ERR_FMT "%s: doesn't have buffer for "
-                   "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type);
-               return -ENOMEM;
-       }
-
-       request_size = ioc->diag_buffer_sz[buffer_type];
-
-       if ((karg.starting_offset % 4) || (karg.bytes_to_read % 4)) {
-               printk(MPT2SAS_ERR_FMT "%s: either the starting_offset "
-                   "or bytes_to_read are not 4 byte aligned\n", ioc->name,
-                   __func__);
-               return -EINVAL;
-       }
-
-       if (karg.starting_offset > request_size)
-               return -EINVAL;
-
-       diag_data = (void *)(request_data + karg.starting_offset);
-       dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: diag_buffer(%p), "
-           "offset(%d), sz(%d)\n", ioc->name, __func__,
-           diag_data, karg.starting_offset, karg.bytes_to_read));
-
-       /* Truncate data on requests that are too large */
-       if ((diag_data + karg.bytes_to_read < diag_data) ||
-           (diag_data + karg.bytes_to_read > request_data + request_size))
-               copy_size = request_size - karg.starting_offset;
-       else
-               copy_size = karg.bytes_to_read;
-
-       if (copy_to_user((void __user *)uarg->diagnostic_data,
-           diag_data, copy_size)) {
-               printk(MPT2SAS_ERR_FMT "%s: Unable to write "
-                   "mpt_diag_read_buffer_t data @ %p\n", ioc->name,
-                   __func__, diag_data);
-               return -EFAULT;
-       }
-
-       if ((karg.flags & MPT2_FLAGS_REREGISTER) == 0)
-               return 0;
-
-       dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: Reregister "
-               "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type));
-       if ((ioc->diag_buffer_status[buffer_type] &
-           MPT2_DIAG_BUFFER_IS_RELEASED) == 0) {
-               dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
-                   "buffer_type(0x%02x) is still registered\n", ioc->name,
-                    __func__, buffer_type));
-               return 0;
-       }
-       /* Get a free request frame and save the message context.
-       */
-
-       if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) {
-               printk(MPT2SAS_ERR_FMT "%s: ctl_cmd in use\n",
-                   ioc->name, __func__);
-               rc = -EAGAIN;
-               goto out;
-       }
-
-       smid = mpt2sas_base_get_smid(ioc, ioc->ctl_cb_idx);
-       if (!smid) {
-               printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
-                   ioc->name, __func__);
-               rc = -EAGAIN;
-               goto out;
-       }
-
-       rc = 0;
-       ioc->ctl_cmds.status = MPT2_CMD_PENDING;
-       memset(ioc->ctl_cmds.reply, 0, ioc->reply_sz);
-       mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
-       ioc->ctl_cmds.smid = smid;
-
-       mpi_request->Function = MPI2_FUNCTION_DIAG_BUFFER_POST;
-       mpi_request->BufferType = buffer_type;
-       mpi_request->BufferLength =
-           cpu_to_le32(ioc->diag_buffer_sz[buffer_type]);
-       mpi_request->BufferAddress =
-           cpu_to_le64(ioc->diag_buffer_dma[buffer_type]);
-       for (i = 0; i < MPT2_PRODUCT_SPECIFIC_DWORDS; i++)
-               mpi_request->ProductSpecific[i] =
-                       cpu_to_le32(ioc->product_specific[buffer_type][i]);
-       mpi_request->VF_ID = 0; /* TODO */
-       mpi_request->VP_ID = 0;
-
-       init_completion(&ioc->ctl_cmds.done);
-       mpt2sas_base_put_smid_default(ioc, smid);
-       timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done,
-           MPT2_IOCTL_DEFAULT_TIMEOUT*HZ);
-
-       if (!(ioc->ctl_cmds.status & MPT2_CMD_COMPLETE)) {
-               printk(MPT2SAS_ERR_FMT "%s: timeout\n", ioc->name,
-                   __func__);
-               _debug_dump_mf(mpi_request,
-                   sizeof(Mpi2DiagBufferPostRequest_t)/4);
-               if (!(ioc->ctl_cmds.status & MPT2_CMD_RESET))
-                       issue_reset = 1;
-               goto issue_host_reset;
-       }
-
-       /* process the completed Reply Message Frame */
-       if ((ioc->ctl_cmds.status & MPT2_CMD_REPLY_VALID) == 0) {
-               printk(MPT2SAS_ERR_FMT "%s: no reply message\n",
-                   ioc->name, __func__);
-               rc = -EFAULT;
-               goto out;
-       }
-
-       mpi_reply = ioc->ctl_cmds.reply;
-       ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
-
-       if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
-               ioc->diag_buffer_status[buffer_type] |=
-                   MPT2_DIAG_BUFFER_IS_REGISTERED;
-               dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: success\n",
-                   ioc->name, __func__));
-       } else {
-               printk(MPT2SAS_INFO_FMT "%s: ioc_status(0x%04x) "
-                   "log_info(0x%08x)\n", ioc->name, __func__,
-                   ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo));
-               rc = -EFAULT;
-       }
-
- issue_host_reset:
-       if (issue_reset)
-               mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
-                   FORCE_BIG_HAMMER);
-
- out:
-
-       ioc->ctl_cmds.status = MPT2_CMD_NOT_USED;
-       return rc;
-}
-
-
-#ifdef CONFIG_COMPAT
-/**
- * _ctl_compat_mpt_command - convert 32bit pointers to 64bit.
- * @ioc: per adapter object
- * @cmd - ioctl opcode
- * @arg - (struct mpt2_ioctl_command32)
- *
- * MPT2COMMAND32 - Handle 32bit applications running on 64bit os.
- */
-static long
-_ctl_compat_mpt_command(struct MPT2SAS_ADAPTER *ioc, unsigned cmd,
-       void __user *arg)
-{
-       struct mpt2_ioctl_command32 karg32;
-       struct mpt2_ioctl_command32 __user *uarg;
-       struct mpt2_ioctl_command karg;
-
-       if (_IOC_SIZE(cmd) != sizeof(struct mpt2_ioctl_command32))
-               return -EINVAL;
-
-       uarg = (struct mpt2_ioctl_command32 __user *) arg;
-
-       if (copy_from_user(&karg32, (char __user *)arg, sizeof(karg32))) {
-               printk(KERN_ERR "failure at %s:%d/%s()!\n",
-                   __FILE__, __LINE__, __func__);
-               return -EFAULT;
-       }
-
-       memset(&karg, 0, sizeof(struct mpt2_ioctl_command));
-       karg.hdr.ioc_number = karg32.hdr.ioc_number;
-       karg.hdr.port_number = karg32.hdr.port_number;
-       karg.hdr.max_data_size = karg32.hdr.max_data_size;
-       karg.timeout = karg32.timeout;
-       karg.max_reply_bytes = karg32.max_reply_bytes;
-       karg.data_in_size = karg32.data_in_size;
-       karg.data_out_size = karg32.data_out_size;
-       karg.max_sense_bytes = karg32.max_sense_bytes;
-       karg.data_sge_offset = karg32.data_sge_offset;
-       karg.reply_frame_buf_ptr = compat_ptr(karg32.reply_frame_buf_ptr);
-       karg.data_in_buf_ptr = compat_ptr(karg32.data_in_buf_ptr);
-       karg.data_out_buf_ptr = compat_ptr(karg32.data_out_buf_ptr);
-       karg.sense_data_ptr = compat_ptr(karg32.sense_data_ptr);
-       return _ctl_do_mpt_command(ioc, karg, &uarg->mf);
-}
-#endif
-
-/**
- * _ctl_ioctl_main - main ioctl entry point
- * @file - (struct file)
- * @cmd - ioctl opcode
- * @arg -
- * compat - handles 32 bit applications in 64bit os
- */
-static long
-_ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg,
-       u8 compat)
-{
-       struct MPT2SAS_ADAPTER *ioc;
-       struct mpt2_ioctl_header ioctl_header;
-       enum block_state state;
-       long ret = -EINVAL;
-
-       /* get IOCTL header */
-       if (copy_from_user(&ioctl_header, (char __user *)arg,
-           sizeof(struct mpt2_ioctl_header))) {
-               printk(KERN_ERR "failure at %s:%d/%s()!\n",
-                   __FILE__, __LINE__, __func__);
-               return -EFAULT;
-       }
-
-       if (_ctl_verify_adapter(ioctl_header.ioc_number, &ioc) == -1 || !ioc)
-               return -ENODEV;
-       /* pci_access_mutex lock acquired by ioctl path */
-       mutex_lock(&ioc->pci_access_mutex);
-       if (ioc->shost_recovery || ioc->pci_error_recovery ||
-               ioc->is_driver_loading || ioc->remove_host) {
-               ret = -EAGAIN;
-               goto out_unlock_pciaccess;
-       }
-
-       state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING : BLOCKING;
-       if (state == NON_BLOCKING) {
-               if (!mutex_trylock(&ioc->ctl_cmds.mutex)) {
-                       ret = -EAGAIN;
-                       goto out_unlock_pciaccess;
-               }
-       } else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex)) {
-               ret = -ERESTARTSYS;
-               goto out_unlock_pciaccess;
-       }
-
-       switch (cmd) {
-       case MPT2IOCINFO:
-               if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_iocinfo))
-                       ret = _ctl_getiocinfo(ioc, arg);
-               break;
-#ifdef CONFIG_COMPAT
-       case MPT2COMMAND32:
-#endif
-       case MPT2COMMAND:
-       {
-               struct mpt2_ioctl_command __user *uarg;
-               struct mpt2_ioctl_command karg;
-#ifdef CONFIG_COMPAT
-               if (compat) {
-                       ret = _ctl_compat_mpt_command(ioc, cmd, arg);
-                       break;
-               }
-#endif
-               if (copy_from_user(&karg, arg, sizeof(karg))) {
-                       printk(KERN_ERR "failure at %s:%d/%s()!\n",
-                           __FILE__, __LINE__, __func__);
-                       ret = -EFAULT;
-                       break;
-               }
-
-               if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_command)) {
-                       uarg = arg;
-                       ret = _ctl_do_mpt_command(ioc, karg, &uarg->mf);
-               }
-               break;
-       }
-       case MPT2EVENTQUERY:
-               if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_eventquery))
-                       ret = _ctl_eventquery(ioc, arg);
-               break;
-       case MPT2EVENTENABLE:
-               if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_eventenable))
-                       ret = _ctl_eventenable(ioc, arg);
-               break;
-       case MPT2EVENTREPORT:
-               ret = _ctl_eventreport(ioc, arg);
-               break;
-       case MPT2HARDRESET:
-               if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_diag_reset))
-                       ret = _ctl_do_reset(ioc, arg);
-               break;
-       case MPT2BTDHMAPPING:
-               if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_btdh_mapping))
-                       ret = _ctl_btdh_mapping(ioc, arg);
-               break;
-       case MPT2DIAGREGISTER:
-               if (_IOC_SIZE(cmd) == sizeof(struct mpt2_diag_register))
-                       ret = _ctl_diag_register(ioc, arg);
-               break;
-       case MPT2DIAGUNREGISTER:
-               if (_IOC_SIZE(cmd) == sizeof(struct mpt2_diag_unregister))
-                       ret = _ctl_diag_unregister(ioc, arg);
-               break;
-       case MPT2DIAGQUERY:
-               if (_IOC_SIZE(cmd) == sizeof(struct mpt2_diag_query))
-                       ret = _ctl_diag_query(ioc, arg);
-               break;
-       case MPT2DIAGRELEASE:
-               if (_IOC_SIZE(cmd) == sizeof(struct mpt2_diag_release))
-                       ret = _ctl_diag_release(ioc, arg);
-               break;
-       case MPT2DIAGREADBUFFER:
-               if (_IOC_SIZE(cmd) == sizeof(struct mpt2_diag_read_buffer))
-                       ret = _ctl_diag_read_buffer(ioc, arg);
-               break;
-       default:
-
-               dctlprintk(ioc, printk(MPT2SAS_INFO_FMT
-                   "unsupported ioctl opcode(0x%08x)\n", ioc->name, cmd));
-               break;
-       }
-
-       mutex_unlock(&ioc->ctl_cmds.mutex);
-out_unlock_pciaccess:
-       mutex_unlock(&ioc->pci_access_mutex);
-       return ret;
-}
-
-/**
- * _ctl_ioctl - main ioctl entry point (unlocked)
- * @file - (struct file)
- * @cmd - ioctl opcode
- * @arg -
- */
-static long
-_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-       long ret;
-
-       ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 0);
-       return ret;
-}
-#ifdef CONFIG_COMPAT
-/**
- * _ctl_ioctl_compat - main ioctl entry point (compat)
- * @file -
- * @cmd -
- * @arg -
- *
- * This routine handles 32 bit applications in 64bit os.
- */
-static long
-_ctl_ioctl_compat(struct file *file, unsigned cmd, unsigned long arg)
-{
-       long ret;
-
-       ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 1);
-       return ret;
-}
-#endif
-
-/* scsi host attributes */
-
-/**
- * _ctl_version_fw_show - firmware version
- * @cdev - pointer to embedded class device
- * @buf - the buffer returned
- *
- * A sysfs 'read-only' shost attribute.
- */
-static ssize_t
-_ctl_version_fw_show(struct device *cdev, struct device_attribute *attr,
-    char *buf)
-{
-       struct Scsi_Host *shost = class_to_shost(cdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-
-       return snprintf(buf, PAGE_SIZE, "%02d.%02d.%02d.%02d\n",
-           (ioc->facts.FWVersion.Word & 0xFF000000) >> 24,
-           (ioc->facts.FWVersion.Word & 0x00FF0000) >> 16,
-           (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8,
-           ioc->facts.FWVersion.Word & 0x000000FF);
-}
-static DEVICE_ATTR(version_fw, S_IRUGO, _ctl_version_fw_show, NULL);
-
-/**
- * _ctl_version_bios_show - bios version
- * @cdev - pointer to embedded class device
- * @buf - the buffer returned
- *
- * A sysfs 'read-only' shost attribute.
- */
-static ssize_t
-_ctl_version_bios_show(struct device *cdev, struct device_attribute *attr,
-    char *buf)
-{
-       struct Scsi_Host *shost = class_to_shost(cdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-
-       u32 version = le32_to_cpu(ioc->bios_pg3.BiosVersion);
-
-       return snprintf(buf, PAGE_SIZE, "%02d.%02d.%02d.%02d\n",
-           (version & 0xFF000000) >> 24,
-           (version & 0x00FF0000) >> 16,
-           (version & 0x0000FF00) >> 8,
-           version & 0x000000FF);
-}
-static DEVICE_ATTR(version_bios, S_IRUGO, _ctl_version_bios_show, NULL);
-
-/**
- * _ctl_version_mpi_show - MPI (message passing interface) version
- * @cdev - pointer to embedded class device
- * @buf - the buffer returned
- *
- * A sysfs 'read-only' shost attribute.
- */
-static ssize_t
-_ctl_version_mpi_show(struct device *cdev, struct device_attribute *attr,
-    char *buf)
-{
-       struct Scsi_Host *shost = class_to_shost(cdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-
-       return snprintf(buf, PAGE_SIZE, "%03x.%02x\n",
-           ioc->facts.MsgVersion, ioc->facts.HeaderVersion >> 8);
-}
-static DEVICE_ATTR(version_mpi, S_IRUGO, _ctl_version_mpi_show, NULL);
-
-/**
- * _ctl_version_product_show - product name
- * @cdev - pointer to embedded class device
- * @buf - the buffer returned
- *
- * A sysfs 'read-only' shost attribute.
- */
-static ssize_t
-_ctl_version_product_show(struct device *cdev, struct device_attribute *attr,
-    char *buf)
-{
-       struct Scsi_Host *shost = class_to_shost(cdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-
-       return snprintf(buf, 16, "%s\n", ioc->manu_pg0.ChipName);
-}
-static DEVICE_ATTR(version_product, S_IRUGO,
-   _ctl_version_product_show, NULL);
-
-/**
- * _ctl_version_nvdata_persistent_show - ndvata persistent version
- * @cdev - pointer to embedded class device
- * @buf - the buffer returned
- *
- * A sysfs 'read-only' shost attribute.
- */
-static ssize_t
-_ctl_version_nvdata_persistent_show(struct device *cdev,
-    struct device_attribute *attr, char *buf)
-{
-       struct Scsi_Host *shost = class_to_shost(cdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-
-       return snprintf(buf, PAGE_SIZE, "%08xh\n",
-           le32_to_cpu(ioc->iounit_pg0.NvdataVersionPersistent.Word));
-}
-static DEVICE_ATTR(version_nvdata_persistent, S_IRUGO,
-    _ctl_version_nvdata_persistent_show, NULL);
-
-/**
- * _ctl_version_nvdata_default_show - nvdata default version
- * @cdev - pointer to embedded class device
- * @buf - the buffer returned
- *
- * A sysfs 'read-only' shost attribute.
- */
-static ssize_t
-_ctl_version_nvdata_default_show(struct device *cdev,
-    struct device_attribute *attr, char *buf)
-{
-       struct Scsi_Host *shost = class_to_shost(cdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-
-       return snprintf(buf, PAGE_SIZE, "%08xh\n",
-           le32_to_cpu(ioc->iounit_pg0.NvdataVersionDefault.Word));
-}
-static DEVICE_ATTR(version_nvdata_default, S_IRUGO,
-    _ctl_version_nvdata_default_show, NULL);
-
-/**
- * _ctl_board_name_show - board name
- * @cdev - pointer to embedded class device
- * @buf - the buffer returned
- *
- * A sysfs 'read-only' shost attribute.
- */
-static ssize_t
-_ctl_board_name_show(struct device *cdev, struct device_attribute *attr,
-    char *buf)
-{
-       struct Scsi_Host *shost = class_to_shost(cdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-
-       return snprintf(buf, 16, "%s\n", ioc->manu_pg0.BoardName);
-}
-static DEVICE_ATTR(board_name, S_IRUGO, _ctl_board_name_show, NULL);
-
-/**
- * _ctl_board_assembly_show - board assembly name
- * @cdev - pointer to embedded class device
- * @buf - the buffer returned
- *
- * A sysfs 'read-only' shost attribute.
- */
-static ssize_t
-_ctl_board_assembly_show(struct device *cdev, struct device_attribute *attr,
-    char *buf)
-{
-       struct Scsi_Host *shost = class_to_shost(cdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-
-       return snprintf(buf, 16, "%s\n", ioc->manu_pg0.BoardAssembly);
-}
-static DEVICE_ATTR(board_assembly, S_IRUGO,
-    _ctl_board_assembly_show, NULL);
-
-/**
- * _ctl_board_tracer_show - board tracer number
- * @cdev - pointer to embedded class device
- * @buf - the buffer returned
- *
- * A sysfs 'read-only' shost attribute.
- */
-static ssize_t
-_ctl_board_tracer_show(struct device *cdev, struct device_attribute *attr,
-    char *buf)
-{
-       struct Scsi_Host *shost = class_to_shost(cdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-
-       return snprintf(buf, 16, "%s\n", ioc->manu_pg0.BoardTracerNumber);
-}
-static DEVICE_ATTR(board_tracer, S_IRUGO,
-    _ctl_board_tracer_show, NULL);
-
-/**
- * _ctl_io_delay_show - io missing delay
- * @cdev - pointer to embedded class device
- * @buf - the buffer returned
- *
- * This is for firmware implemention for deboucing device
- * removal events.
- *
- * A sysfs 'read-only' shost attribute.
- */
-static ssize_t
-_ctl_io_delay_show(struct device *cdev, struct device_attribute *attr,
-    char *buf)
-{
-       struct Scsi_Host *shost = class_to_shost(cdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-
-       return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->io_missing_delay);
-}
-static DEVICE_ATTR(io_delay, S_IRUGO,
-    _ctl_io_delay_show, NULL);
-
-/**
- * _ctl_device_delay_show - device missing delay
- * @cdev - pointer to embedded class device
- * @buf - the buffer returned
- *
- * This is for firmware implemention for deboucing device
- * removal events.
- *
- * A sysfs 'read-only' shost attribute.
- */
-static ssize_t
-_ctl_device_delay_show(struct device *cdev, struct device_attribute *attr,
-    char *buf)
-{
-       struct Scsi_Host *shost = class_to_shost(cdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-
-       return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->device_missing_delay);
-}
-static DEVICE_ATTR(device_delay, S_IRUGO,
-    _ctl_device_delay_show, NULL);
-
-/**
- * _ctl_fw_queue_depth_show - global credits
- * @cdev - pointer to embedded class device
- * @buf - the buffer returned
- *
- * This is firmware queue depth limit
- *
- * A sysfs 'read-only' shost attribute.
- */
-static ssize_t
-_ctl_fw_queue_depth_show(struct device *cdev, struct device_attribute *attr,
-    char *buf)
-{
-       struct Scsi_Host *shost = class_to_shost(cdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-
-       return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->facts.RequestCredit);
-}
-static DEVICE_ATTR(fw_queue_depth, S_IRUGO,
-    _ctl_fw_queue_depth_show, NULL);
-
-/**
- * _ctl_sas_address_show - sas address
- * @cdev - pointer to embedded class device
- * @buf - the buffer returned
- *
- * This is the controller sas address
- *
- * A sysfs 'read-only' shost attribute.
- */
-static ssize_t
-_ctl_host_sas_address_show(struct device *cdev, struct device_attribute *attr,
-    char *buf)
-{
-       struct Scsi_Host *shost = class_to_shost(cdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-
-       return snprintf(buf, PAGE_SIZE, "0x%016llx\n",
-           (unsigned long long)ioc->sas_hba.sas_address);
-}
-static DEVICE_ATTR(host_sas_address, S_IRUGO,
-    _ctl_host_sas_address_show, NULL);
-
-/**
- * _ctl_logging_level_show - logging level
- * @cdev - pointer to embedded class device
- * @buf - the buffer returned
- *
- * A sysfs 'read/write' shost attribute.
- */
-static ssize_t
-_ctl_logging_level_show(struct device *cdev, struct device_attribute *attr,
-    char *buf)
-{
-       struct Scsi_Host *shost = class_to_shost(cdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-
-       return snprintf(buf, PAGE_SIZE, "%08xh\n", ioc->logging_level);
-}
-static ssize_t
-_ctl_logging_level_store(struct device *cdev, struct device_attribute *attr,
-    const char *buf, size_t count)
-{
-       struct Scsi_Host *shost = class_to_shost(cdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-       int val = 0;
-
-       if (sscanf(buf, "%x", &val) != 1)
-               return -EINVAL;
-
-       ioc->logging_level = val;
-       printk(MPT2SAS_INFO_FMT "logging_level=%08xh\n", ioc->name,
-           ioc->logging_level);
-       return strlen(buf);
-}
-static DEVICE_ATTR(logging_level, S_IRUGO | S_IWUSR,
-    _ctl_logging_level_show, _ctl_logging_level_store);
-
-/* device attributes */
-/*
- * _ctl_fwfault_debug_show - show/store fwfault_debug
- * @cdev - pointer to embedded class device
- * @buf - the buffer returned
- *
- * mpt2sas_fwfault_debug is command line option
- * A sysfs 'read/write' shost attribute.
- */
-static ssize_t
-_ctl_fwfault_debug_show(struct device *cdev,
-    struct device_attribute *attr, char *buf)
-{
-       struct Scsi_Host *shost = class_to_shost(cdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-
-       return snprintf(buf, PAGE_SIZE, "%d\n", ioc->fwfault_debug);
-}
-static ssize_t
-_ctl_fwfault_debug_store(struct device *cdev,
-    struct device_attribute *attr, const char *buf, size_t count)
-{
-       struct Scsi_Host *shost = class_to_shost(cdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-       int val = 0;
-
-       if (sscanf(buf, "%d", &val) != 1)
-               return -EINVAL;
-
-       ioc->fwfault_debug = val;
-       printk(MPT2SAS_INFO_FMT "fwfault_debug=%d\n", ioc->name,
-           ioc->fwfault_debug);
-       return strlen(buf);
-}
-static DEVICE_ATTR(fwfault_debug, S_IRUGO | S_IWUSR,
-    _ctl_fwfault_debug_show, _ctl_fwfault_debug_store);
-
-
-/**
- * _ctl_ioc_reset_count_show - ioc reset count
- * @cdev - pointer to embedded class device
- * @buf - the buffer returned
- *
- * This is firmware queue depth limit
- *
- * A sysfs 'read-only' shost attribute.
- */
-static ssize_t
-_ctl_ioc_reset_count_show(struct device *cdev, struct device_attribute *attr,
-    char *buf)
-{
-       struct Scsi_Host *shost = class_to_shost(cdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-
-       return snprintf(buf, PAGE_SIZE, "%08d\n", ioc->ioc_reset_count);
-}
-static DEVICE_ATTR(ioc_reset_count, S_IRUGO,
-    _ctl_ioc_reset_count_show, NULL);
-
-/**
- * _ctl_ioc_reply_queue_count_show - number of reply queues
- * @cdev - pointer to embedded class device
- * @buf - the buffer returned
- *
- * This is number of reply queues
- *
- * A sysfs 'read-only' shost attribute.
- */
-static ssize_t
-_ctl_ioc_reply_queue_count_show(struct device *cdev,
-        struct device_attribute *attr, char *buf)
-{
-       u8 reply_queue_count;
-       struct Scsi_Host *shost = class_to_shost(cdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-
-       if ((ioc->facts.IOCCapabilities &
-           MPI2_IOCFACTS_CAPABILITY_MSI_X_INDEX) && ioc->msix_enable)
-               reply_queue_count = ioc->reply_queue_count;
-       else
-               reply_queue_count = 1;
-       return snprintf(buf, PAGE_SIZE, "%d\n", reply_queue_count);
-}
-static DEVICE_ATTR(reply_queue_count, S_IRUGO,
-        _ctl_ioc_reply_queue_count_show, NULL);
-
-/**
- * _ctl_BRM_status_show - Backup Rail Monitor Status
- * @cdev - pointer to embedded class device
- * @buf - the buffer returned
- *
- * This is number of reply queues
- *
- * A sysfs 'read-only' shost attribute.
- */
-static ssize_t
-_ctl_BRM_status_show(struct device *cdev, struct device_attribute *attr,
-       char *buf)
-{
-       struct Scsi_Host *shost = class_to_shost(cdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-       Mpi2IOUnitPage3_t *io_unit_pg3 = NULL;
-       Mpi2ConfigReply_t mpi_reply;
-       u16 backup_rail_monitor_status = 0;
-       u16 ioc_status;
-       int sz;
-       ssize_t rc = 0;
-
-       if (!ioc->is_warpdrive) {
-               printk(MPT2SAS_ERR_FMT "%s: BRM attribute is only for"\
-                   "warpdrive\n", ioc->name, __func__);
-               goto out;
-       }
-       /* pci_access_mutex lock acquired by sysfs show path */
-       mutex_lock(&ioc->pci_access_mutex);
-       if (ioc->pci_error_recovery || ioc->remove_host) {
-               mutex_unlock(&ioc->pci_access_mutex);
-               return 0;
-       }
-
-       /* allocate upto GPIOVal 36 entries */
-       sz = offsetof(Mpi2IOUnitPage3_t, GPIOVal) + (sizeof(u16) * 36);
-       io_unit_pg3 = kzalloc(sz, GFP_KERNEL);
-       if (!io_unit_pg3) {
-               printk(MPT2SAS_ERR_FMT "%s: failed allocating memory"\
-                   "for iounit_pg3: (%d) bytes\n", ioc->name, __func__, sz);
-               goto out;
-       }
-
-       if (mpt2sas_config_get_iounit_pg3(ioc, &mpi_reply, io_unit_pg3, sz) !=
-           0) {
-               printk(MPT2SAS_ERR_FMT
-                   "%s: failed reading iounit_pg3\n", ioc->name,
-                   __func__);
-               goto out;
-       }
-
-       ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
-       if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
-               printk(MPT2SAS_ERR_FMT "%s: iounit_pg3 failed with"\
-                   "ioc_status(0x%04x)\n", ioc->name, __func__, ioc_status);
-               goto out;
-       }
-
-       if (io_unit_pg3->GPIOCount < 25) {
-               printk(MPT2SAS_ERR_FMT "%s: iounit_pg3->GPIOCount less than"\
-                    "25 entries, detected (%d) entries\n", ioc->name, __func__,
-                   io_unit_pg3->GPIOCount);
-               goto out;
-       }
-
-       /* BRM status is in bit zero of GPIOVal[24] */
-       backup_rail_monitor_status = le16_to_cpu(io_unit_pg3->GPIOVal[24]);
-       rc = snprintf(buf, PAGE_SIZE, "%d\n", (backup_rail_monitor_status & 1));
-
- out:
-       kfree(io_unit_pg3);
-       mutex_unlock(&ioc->pci_access_mutex);
-       return rc;
-}
-static DEVICE_ATTR(BRM_status, S_IRUGO, _ctl_BRM_status_show, NULL);
-
-struct DIAG_BUFFER_START {
-       __le32 Size;
-       __le32 DiagVersion;
-       u8 BufferType;
-       u8 Reserved[3];
-       __le32 Reserved1;
-       __le32 Reserved2;
-       __le32 Reserved3;
-};
-/**
- * _ctl_host_trace_buffer_size_show - host buffer size (trace only)
- * @cdev - pointer to embedded class device
- * @buf - the buffer returned
- *
- * A sysfs 'read-only' shost attribute.
- */
-static ssize_t
-_ctl_host_trace_buffer_size_show(struct device *cdev,
-    struct device_attribute *attr, char *buf)
-{
-       struct Scsi_Host *shost = class_to_shost(cdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-       u32 size = 0;
-       struct DIAG_BUFFER_START *request_data;
-
-       if (!ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE]) {
-               printk(MPT2SAS_ERR_FMT "%s: host_trace_buffer is not "
-                   "registered\n", ioc->name, __func__);
-               return 0;
-       }
-
-       if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
-           MPT2_DIAG_BUFFER_IS_REGISTERED) == 0) {
-               printk(MPT2SAS_ERR_FMT "%s: host_trace_buffer is not "
-                   "registered\n", ioc->name, __func__);
-               return 0;
-       }
-
-       request_data = (struct DIAG_BUFFER_START *)
-           ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE];
-       if ((le32_to_cpu(request_data->DiagVersion) == 0x00000000 ||
-           le32_to_cpu(request_data->DiagVersion) == 0x01000000) &&
-           le32_to_cpu(request_data->Reserved3) == 0x4742444c)
-               size = le32_to_cpu(request_data->Size);
-
-       ioc->ring_buffer_sz = size;
-       return snprintf(buf, PAGE_SIZE, "%d\n", size);
-}
-static DEVICE_ATTR(host_trace_buffer_size, S_IRUGO,
-        _ctl_host_trace_buffer_size_show, NULL);
-
-/**
- * _ctl_host_trace_buffer_show - firmware ring buffer (trace only)
- * @cdev - pointer to embedded class device
- * @buf - the buffer returned
- *
- * A sysfs 'read/write' shost attribute.
- *
- * You will only be able to read 4k bytes of ring buffer at a time.
- * In order to read beyond 4k bytes, you will have to write out the
- * offset to the same attribute, it will move the pointer.
- */
-static ssize_t
-_ctl_host_trace_buffer_show(struct device *cdev, struct device_attribute *attr,
-     char *buf)
-{
-       struct Scsi_Host *shost = class_to_shost(cdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-       void *request_data;
-       u32 size;
-
-       if (!ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE]) {
-               printk(MPT2SAS_ERR_FMT "%s: host_trace_buffer is not "
-                   "registered\n", ioc->name, __func__);
-               return 0;
-       }
-
-       if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
-           MPT2_DIAG_BUFFER_IS_REGISTERED) == 0) {
-               printk(MPT2SAS_ERR_FMT "%s: host_trace_buffer is not "
-                   "registered\n", ioc->name, __func__);
-               return 0;
-       }
-
-       if (ioc->ring_buffer_offset > ioc->ring_buffer_sz)
-               return 0;
-
-       size = ioc->ring_buffer_sz - ioc->ring_buffer_offset;
-       size = (size > PAGE_SIZE) ? PAGE_SIZE : size;
-       request_data = ioc->diag_buffer[0] + ioc->ring_buffer_offset;
-       memcpy(buf, request_data, size);
-       return size;
-}
-
-static ssize_t
-_ctl_host_trace_buffer_store(struct device *cdev, struct device_attribute *attr,
-    const char *buf, size_t count)
-{
-       struct Scsi_Host *shost = class_to_shost(cdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-       int val = 0;
-
-       if (sscanf(buf, "%d", &val) != 1)
-               return -EINVAL;
-
-       ioc->ring_buffer_offset = val;
-       return strlen(buf);
-}
-static DEVICE_ATTR(host_trace_buffer, S_IRUGO | S_IWUSR,
-    _ctl_host_trace_buffer_show, _ctl_host_trace_buffer_store);
-
-/*****************************************/
-
-/**
- * _ctl_host_trace_buffer_enable_show - firmware ring buffer (trace only)
- * @cdev - pointer to embedded class device
- * @buf - the buffer returned
- *
- * A sysfs 'read/write' shost attribute.
- *
- * This is a mechnism to post/release host_trace_buffers
- */
-static ssize_t
-_ctl_host_trace_buffer_enable_show(struct device *cdev,
-    struct device_attribute *attr, char *buf)
-{
-       struct Scsi_Host *shost = class_to_shost(cdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-
-       if ((!ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE]) ||
-          ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
-           MPT2_DIAG_BUFFER_IS_REGISTERED) == 0))
-               return snprintf(buf, PAGE_SIZE, "off\n");
-       else if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
-           MPT2_DIAG_BUFFER_IS_RELEASED))
-               return snprintf(buf, PAGE_SIZE, "release\n");
-       else
-               return snprintf(buf, PAGE_SIZE, "post\n");
-}
-
-static ssize_t
-_ctl_host_trace_buffer_enable_store(struct device *cdev,
-    struct device_attribute *attr, const char *buf, size_t count)
-{
-       struct Scsi_Host *shost = class_to_shost(cdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-       char str[10] = "";
-       struct mpt2_diag_register diag_register;
-       u8 issue_reset = 0;
-
-       if (sscanf(buf, "%9s", str) != 1)
-               return -EINVAL;
-
-       if (!strcmp(str, "post")) {
-               /* exit out if host buffers are already posted */
-               if ((ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE]) &&
-                   (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
-                   MPT2_DIAG_BUFFER_IS_REGISTERED) &&
-                   ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
-                   MPT2_DIAG_BUFFER_IS_RELEASED) == 0))
-                       goto out;
-               memset(&diag_register, 0, sizeof(struct mpt2_diag_register));
-               printk(MPT2SAS_INFO_FMT "posting host trace buffers\n",
-                   ioc->name);
-               diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_TRACE;
-               diag_register.requested_buffer_size = (1024 * 1024);
-               diag_register.unique_id = 0x7075900;
-               ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] = 0;
-               _ctl_diag_register_2(ioc,  &diag_register);
-       } else if (!strcmp(str, "release")) {
-               /* exit out if host buffers are already released */
-               if (!ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE])
-                       goto out;
-               if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
-                   MPT2_DIAG_BUFFER_IS_REGISTERED) == 0)
-                       goto out;
-               if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
-                   MPT2_DIAG_BUFFER_IS_RELEASED))
-                       goto out;
-               printk(MPT2SAS_INFO_FMT "releasing host trace buffer\n",
-                   ioc->name);
-               _ctl_send_release(ioc, MPI2_DIAG_BUF_TYPE_TRACE, &issue_reset);
-       }
-
- out:
-       return strlen(buf);
-}
-static DEVICE_ATTR(host_trace_buffer_enable, S_IRUGO | S_IWUSR,
-    _ctl_host_trace_buffer_enable_show, _ctl_host_trace_buffer_enable_store);
-
-struct device_attribute *mpt2sas_host_attrs[] = {
-       &dev_attr_version_fw,
-       &dev_attr_version_bios,
-       &dev_attr_version_mpi,
-       &dev_attr_version_product,
-       &dev_attr_version_nvdata_persistent,
-       &dev_attr_version_nvdata_default,
-       &dev_attr_board_name,
-       &dev_attr_board_assembly,
-       &dev_attr_board_tracer,
-       &dev_attr_io_delay,
-       &dev_attr_device_delay,
-       &dev_attr_logging_level,
-       &dev_attr_fwfault_debug,
-       &dev_attr_fw_queue_depth,
-       &dev_attr_host_sas_address,
-       &dev_attr_ioc_reset_count,
-       &dev_attr_host_trace_buffer_size,
-       &dev_attr_host_trace_buffer,
-       &dev_attr_host_trace_buffer_enable,
-       &dev_attr_reply_queue_count,
-       &dev_attr_BRM_status,
-       NULL,
-};
-
-/**
- * _ctl_device_sas_address_show - sas address
- * @cdev - pointer to embedded class device
- * @buf - the buffer returned
- *
- * This is the sas address for the target
- *
- * A sysfs 'read-only' shost attribute.
- */
-static ssize_t
-_ctl_device_sas_address_show(struct device *dev, struct device_attribute *attr,
-    char *buf)
-{
-       struct scsi_device *sdev = to_scsi_device(dev);
-       struct MPT2SAS_DEVICE *sas_device_priv_data = sdev->hostdata;
-
-       return snprintf(buf, PAGE_SIZE, "0x%016llx\n",
-           (unsigned long long)sas_device_priv_data->sas_target->sas_address);
-}
-static DEVICE_ATTR(sas_address, S_IRUGO, _ctl_device_sas_address_show, NULL);
-
-/**
- * _ctl_device_handle_show - device handle
- * @cdev - pointer to embedded class device
- * @buf - the buffer returned
- *
- * This is the firmware assigned device handle
- *
- * A sysfs 'read-only' shost attribute.
- */
-static ssize_t
-_ctl_device_handle_show(struct device *dev, struct device_attribute *attr,
-    char *buf)
-{
-       struct scsi_device *sdev = to_scsi_device(dev);
-       struct MPT2SAS_DEVICE *sas_device_priv_data = sdev->hostdata;
-
-       return snprintf(buf, PAGE_SIZE, "0x%04x\n",
-           sas_device_priv_data->sas_target->handle);
-}
-static DEVICE_ATTR(sas_device_handle, S_IRUGO, _ctl_device_handle_show, NULL);
-
-struct device_attribute *mpt2sas_dev_attrs[] = {
-       &dev_attr_sas_address,
-       &dev_attr_sas_device_handle,
-       NULL,
-};
-
-static const struct file_operations ctl_fops = {
-       .owner = THIS_MODULE,
-       .unlocked_ioctl = _ctl_ioctl,
-       .poll = _ctl_poll,
-       .fasync = _ctl_fasync,
-#ifdef CONFIG_COMPAT
-       .compat_ioctl = _ctl_ioctl_compat,
-#endif
-       .llseek = noop_llseek,
-};
-
-static struct miscdevice ctl_dev = {
-       .minor  = MPT2SAS_MINOR,
-       .name   = MPT2SAS_DEV_NAME,
-       .fops   = &ctl_fops,
-};
-
-/**
- * mpt2sas_ctl_init - main entry point for ctl.
- *
- */
-void
-mpt2sas_ctl_init(void)
-{
-       async_queue = NULL;
-       if (misc_register(&ctl_dev) < 0)
-               printk(KERN_ERR "%s can't register misc device [minor=%d]\n",
-                   MPT2SAS_DRIVER_NAME, MPT2SAS_MINOR);
-
-       init_waitqueue_head(&ctl_poll_wait);
-}
-
-/**
- * mpt2sas_ctl_exit - exit point for ctl
- *
- */
-void
-mpt2sas_ctl_exit(void)
-{
-       struct MPT2SAS_ADAPTER *ioc;
-       int i;
-
-       list_for_each_entry(ioc, &mpt2sas_ioc_list, list) {
-
-               /* free memory associated to diag buffers */
-               for (i = 0; i < MPI2_DIAG_BUF_TYPE_COUNT; i++) {
-                       if (!ioc->diag_buffer[i])
-                               continue;
-                       pci_free_consistent(ioc->pdev, ioc->diag_buffer_sz[i],
-                           ioc->diag_buffer[i], ioc->diag_buffer_dma[i]);
-                       ioc->diag_buffer[i] = NULL;
-                       ioc->diag_buffer_status[i] = 0;
-               }
-
-               kfree(ioc->event_log);
-       }
-       misc_deregister(&ctl_dev);
-}
-
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.h b/drivers/scsi/mpt2sas/mpt2sas_ctl.h
deleted file mode 100644 (file)
index 46b2fc5..0000000
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
- * Management Module Support for MPT (Message Passing Technology) based
- * controllers
- *
- * This code is based on drivers/scsi/mpt2sas/mpt2_ctl.h
- * Copyright (C) 2007-2014  LSI Corporation
- * Copyright (C) 20013-2014 Avago Technologies
- *  (mailto: MPT-FusionLinux.pdl@avagotech.com)
- *
- * 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.
- *
- * NO WARRANTY
- * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
- * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
- * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
- * solely responsible for determining the appropriateness of using and
- * distributing the Program and assumes all risks associated with its
- * exercise of rights under this Agreement, including but not limited to
- * the risks and costs of program errors, damage to or loss of data,
- * programs or equipment, and unavailability or interruption of operations.
-
- * DISCLAIMER OF LIABILITY
- * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
- * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
- * USA.
- */
-
-#ifndef MPT2SAS_CTL_H_INCLUDED
-#define MPT2SAS_CTL_H_INCLUDED
-
-#ifdef __KERNEL__
-#include <linux/miscdevice.h>
-#endif
-
-#define MPT2SAS_DEV_NAME       "mpt2ctl"
-#define MPT2_MAGIC_NUMBER      'L'
-#define MPT2_IOCTL_DEFAULT_TIMEOUT (10) /* in seconds */
-
-/**
- * IOCTL opcodes
- */
-#define MPT2IOCINFO    _IOWR(MPT2_MAGIC_NUMBER, 17, \
-    struct mpt2_ioctl_iocinfo)
-#define MPT2COMMAND    _IOWR(MPT2_MAGIC_NUMBER, 20, \
-    struct mpt2_ioctl_command)
-#ifdef CONFIG_COMPAT
-#define MPT2COMMAND32  _IOWR(MPT2_MAGIC_NUMBER, 20, \
-    struct mpt2_ioctl_command32)
-#endif
-#define MPT2EVENTQUERY _IOWR(MPT2_MAGIC_NUMBER, 21, \
-    struct mpt2_ioctl_eventquery)
-#define MPT2EVENTENABLE        _IOWR(MPT2_MAGIC_NUMBER, 22, \
-    struct mpt2_ioctl_eventenable)
-#define MPT2EVENTREPORT        _IOWR(MPT2_MAGIC_NUMBER, 23, \
-    struct mpt2_ioctl_eventreport)
-#define MPT2HARDRESET  _IOWR(MPT2_MAGIC_NUMBER, 24, \
-    struct mpt2_ioctl_diag_reset)
-#define MPT2BTDHMAPPING        _IOWR(MPT2_MAGIC_NUMBER, 31, \
-    struct mpt2_ioctl_btdh_mapping)
-
-/* diag buffer support */
-#define MPT2DIAGREGISTER _IOWR(MPT2_MAGIC_NUMBER, 26, \
-    struct mpt2_diag_register)
-#define MPT2DIAGRELEASE        _IOWR(MPT2_MAGIC_NUMBER, 27, \
-    struct mpt2_diag_release)
-#define MPT2DIAGUNREGISTER _IOWR(MPT2_MAGIC_NUMBER, 28, \
-    struct mpt2_diag_unregister)
-#define MPT2DIAGQUERY  _IOWR(MPT2_MAGIC_NUMBER, 29, \
-    struct mpt2_diag_query)
-#define MPT2DIAGREADBUFFER _IOWR(MPT2_MAGIC_NUMBER, 30, \
-    struct mpt2_diag_read_buffer)
-
-/**
- * struct mpt2_ioctl_header - main header structure
- * @ioc_number -  IOC unit number
- * @port_number - IOC port number
- * @max_data_size - maximum number bytes to transfer on read
- */
-struct mpt2_ioctl_header {
-       uint32_t ioc_number;
-       uint32_t port_number;
-       uint32_t max_data_size;
-};
-
-/**
- * struct mpt2_ioctl_diag_reset - diagnostic reset
- * @hdr - generic header
- */
-struct mpt2_ioctl_diag_reset {
-       struct mpt2_ioctl_header hdr;
-};
-
-
-/**
- * struct mpt2_ioctl_pci_info - pci device info
- * @device - pci device id
- * @function - pci function id
- * @bus - pci bus id
- * @segment_id - pci segment id
- */
-struct mpt2_ioctl_pci_info {
-       union {
-               struct {
-                       uint32_t device:5;
-                       uint32_t function:3;
-                       uint32_t bus:24;
-               } bits;
-               uint32_t  word;
-       } u;
-       uint32_t segment_id;
-};
-
-
-#define MPT2_IOCTL_INTERFACE_SCSI      (0x00)
-#define MPT2_IOCTL_INTERFACE_FC                (0x01)
-#define MPT2_IOCTL_INTERFACE_FC_IP     (0x02)
-#define MPT2_IOCTL_INTERFACE_SAS       (0x03)
-#define MPT2_IOCTL_INTERFACE_SAS2      (0x04)
-#define MPT2_IOCTL_INTERFACE_SAS2_SSS6200      (0x05)
-#define MPT2_IOCTL_VERSION_LENGTH      (32)
-
-/**
- * struct mpt2_ioctl_iocinfo - generic controller info
- * @hdr - generic header
- * @adapter_type - type of adapter (spi, fc, sas)
- * @port_number - port number
- * @pci_id - PCI Id
- * @hw_rev - hardware revision
- * @sub_system_device - PCI subsystem Device ID
- * @sub_system_vendor - PCI subsystem Vendor ID
- * @rsvd0 - reserved
- * @firmware_version - firmware version
- * @bios_version - BIOS version
- * @driver_version - driver version - 32 ASCII characters
- * @rsvd1 - reserved
- * @scsi_id - scsi id of adapter 0
- * @rsvd2 - reserved
- * @pci_information - pci info (2nd revision)
- */
-struct mpt2_ioctl_iocinfo {
-       struct mpt2_ioctl_header hdr;
-       uint32_t adapter_type;
-       uint32_t port_number;
-       uint32_t pci_id;
-       uint32_t hw_rev;
-       uint32_t subsystem_device;
-       uint32_t subsystem_vendor;
-       uint32_t rsvd0;
-       uint32_t firmware_version;
-       uint32_t bios_version;
-       uint8_t driver_version[MPT2_IOCTL_VERSION_LENGTH];
-       uint8_t rsvd1;
-       uint8_t scsi_id;
-       uint16_t rsvd2;
-       struct mpt2_ioctl_pci_info pci_information;
-};
-
-
-/* number of event log entries */
-#define MPT2SAS_CTL_EVENT_LOG_SIZE (50)
-
-/**
- * struct mpt2_ioctl_eventquery - query event count and type
- * @hdr - generic header
- * @event_entries - number of events returned by get_event_report
- * @rsvd - reserved
- * @event_types - type of events currently being captured
- */
-struct mpt2_ioctl_eventquery {
-       struct mpt2_ioctl_header hdr;
-       uint16_t event_entries;
-       uint16_t rsvd;
-       uint32_t event_types[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS];
-};
-
-/**
- * struct mpt2_ioctl_eventenable - enable/disable event capturing
- * @hdr - generic header
- * @event_types - toggle off/on type of events to be captured
- */
-struct mpt2_ioctl_eventenable {
-       struct mpt2_ioctl_header hdr;
-       uint32_t event_types[4];
-};
-
-#define MPT2_EVENT_DATA_SIZE (192)
-/**
- * struct MPT2_IOCTL_EVENTS -
- * @event - the event that was reported
- * @context - unique value for each event assigned by driver
- * @data - event data returned in fw reply message
- */
-struct MPT2_IOCTL_EVENTS {
-       uint32_t event;
-       uint32_t context;
-       uint8_t data[MPT2_EVENT_DATA_SIZE];
-};
-
-/**
- * struct mpt2_ioctl_eventreport - returing event log
- * @hdr - generic header
- * @event_data - (see struct MPT2_IOCTL_EVENTS)
- */
-struct mpt2_ioctl_eventreport {
-       struct mpt2_ioctl_header hdr;
-       struct MPT2_IOCTL_EVENTS event_data[1];
-};
-
-/**
- * struct mpt2_ioctl_command - generic mpt firmware passthru ioctl
- * @hdr - generic header
- * @timeout - command timeout in seconds. (if zero then use driver default
- *  value).
- * @reply_frame_buf_ptr - reply location
- * @data_in_buf_ptr - destination for read
- * @data_out_buf_ptr - data source for write
- * @sense_data_ptr - sense data location
- * @max_reply_bytes - maximum number of reply bytes to be sent to app.
- * @data_in_size - number bytes for data transfer in (read)
- * @data_out_size - number bytes for data transfer out (write)
- * @max_sense_bytes - maximum number of bytes for auto sense buffers
- * @data_sge_offset - offset in words from the start of the request message to
- * the first SGL
- * @mf[1];
- */
-struct mpt2_ioctl_command {
-       struct mpt2_ioctl_header hdr;
-       uint32_t timeout;
-       void __user *reply_frame_buf_ptr;
-       void __user *data_in_buf_ptr;
-       void __user *data_out_buf_ptr;
-       void __user *sense_data_ptr;
-       uint32_t max_reply_bytes;
-       uint32_t data_in_size;
-       uint32_t data_out_size;
-       uint32_t max_sense_bytes;
-       uint32_t data_sge_offset;
-       uint8_t mf[1];
-};
-
-#ifdef CONFIG_COMPAT
-struct mpt2_ioctl_command32 {
-       struct mpt2_ioctl_header hdr;
-       uint32_t timeout;
-       uint32_t reply_frame_buf_ptr;
-       uint32_t data_in_buf_ptr;
-       uint32_t data_out_buf_ptr;
-       uint32_t sense_data_ptr;
-       uint32_t max_reply_bytes;
-       uint32_t data_in_size;
-       uint32_t data_out_size;
-       uint32_t max_sense_bytes;
-       uint32_t data_sge_offset;
-       uint8_t mf[1];
-};
-#endif
-
-/**
- * struct mpt2_ioctl_btdh_mapping - mapping info
- * @hdr - generic header
- * @id - target device identification number
- * @bus - SCSI bus number that the target device exists on
- * @handle - device handle for the target device
- * @rsvd - reserved
- *
- * To obtain a bus/id the application sets
- * handle to valid handle, and bus/id to 0xFFFF.
- *
- * To obtain the device handle the application sets
- * bus/id valid value, and the handle to 0xFFFF.
- */
-struct mpt2_ioctl_btdh_mapping {
-       struct mpt2_ioctl_header hdr;
-       uint32_t id;
-       uint32_t bus;
-       uint16_t handle;
-       uint16_t rsvd;
-};
-
-
-/* status bits for ioc->diag_buffer_status */
-#define MPT2_DIAG_BUFFER_IS_REGISTERED (0x01)
-#define MPT2_DIAG_BUFFER_IS_RELEASED   (0x02)
-#define MPT2_DIAG_BUFFER_IS_DIAG_RESET (0x04)
-
-/* application flags for mpt2_diag_register, mpt2_diag_query */
-#define MPT2_APP_FLAGS_APP_OWNED       (0x0001)
-#define MPT2_APP_FLAGS_BUFFER_VALID    (0x0002)
-#define MPT2_APP_FLAGS_FW_BUFFER_ACCESS        (0x0004)
-
-/* flags for mpt2_diag_read_buffer */
-#define MPT2_FLAGS_REREGISTER          (0x0001)
-
-#define MPT2_PRODUCT_SPECIFIC_DWORDS           23
-
-/**
- * struct mpt2_diag_register - application register with driver
- * @hdr - generic header
- * @reserved -
- * @buffer_type - specifies either TRACE, SNAPSHOT, or EXTENDED
- * @application_flags - misc flags
- * @diagnostic_flags - specifies flags affecting command processing
- * @product_specific - product specific information
- * @requested_buffer_size - buffers size in bytes
- * @unique_id - tag specified by application that is used to signal ownership
- *  of the buffer.
- *
- * This will allow the driver to setup any required buffers that will be
- * needed by firmware to communicate with the driver.
- */
-struct mpt2_diag_register {
-       struct mpt2_ioctl_header hdr;
-       uint8_t reserved;
-       uint8_t buffer_type;
-       uint16_t application_flags;
-       uint32_t diagnostic_flags;
-       uint32_t product_specific[MPT2_PRODUCT_SPECIFIC_DWORDS];
-       uint32_t requested_buffer_size;
-       uint32_t unique_id;
-};
-
-/**
- * struct mpt2_diag_unregister - application unregister with driver
- * @hdr - generic header
- * @unique_id - tag uniquely identifies the buffer to be unregistered
- *
- * This will allow the driver to cleanup any memory allocated for diag
- * messages and to free up any resources.
- */
-struct mpt2_diag_unregister {
-       struct mpt2_ioctl_header hdr;
-       uint32_t unique_id;
-};
-
-/**
- * struct mpt2_diag_query - query relevant info associated with diag buffers
- * @hdr - generic header
- * @reserved -
- * @buffer_type - specifies either TRACE, SNAPSHOT, or EXTENDED
- * @application_flags - misc flags
- * @diagnostic_flags - specifies flags affecting command processing
- * @product_specific - product specific information
- * @total_buffer_size - diag buffer size in bytes
- * @driver_added_buffer_size - size of extra space appended to end of buffer
- * @unique_id - unique id associated with this buffer.
- *
- * The application will send only buffer_type and unique_id.  Driver will
- * inspect unique_id first, if valid, fill in all the info.  If unique_id is
- * 0x00, the driver will return info specified by Buffer Type.
- */
-struct mpt2_diag_query {
-       struct mpt2_ioctl_header hdr;
-       uint8_t reserved;
-       uint8_t buffer_type;
-       uint16_t application_flags;
-       uint32_t diagnostic_flags;
-       uint32_t product_specific[MPT2_PRODUCT_SPECIFIC_DWORDS];
-       uint32_t total_buffer_size;
-       uint32_t driver_added_buffer_size;
-       uint32_t unique_id;
-};
-
-/**
- * struct mpt2_diag_release -  request to send Diag Release Message to firmware
- * @hdr - generic header
- * @unique_id - tag uniquely identifies the buffer to be released
- *
- * This allows ownership of the specified buffer to returned to the driver,
- * allowing an application to read the buffer without fear that firmware is
- * overwritting information in the buffer.
- */
-struct mpt2_diag_release {
-       struct mpt2_ioctl_header hdr;
-       uint32_t unique_id;
-};
-
-/**
- * struct mpt2_diag_read_buffer - request for copy of the diag buffer
- * @hdr - generic header
- * @status -
- * @reserved -
- * @flags - misc flags
- * @starting_offset - starting offset within drivers buffer where to start
- *  reading data at into the specified application buffer
- * @bytes_to_read - number of bytes to copy from the drivers buffer into the
- *  application buffer starting at starting_offset.
- * @unique_id - unique id associated with this buffer.
- * @diagnostic_data - data payload
- */
-struct mpt2_diag_read_buffer {
-       struct mpt2_ioctl_header hdr;
-       uint8_t status;
-       uint8_t reserved;
-       uint16_t flags;
-       uint32_t starting_offset;
-       uint32_t bytes_to_read;
-       uint32_t unique_id;
-       uint32_t diagnostic_data[1];
-};
-
-#endif /* MPT2SAS_CTL_H_INCLUDED */
diff --git a/drivers/scsi/mpt2sas/mpt2sas_debug.h b/drivers/scsi/mpt2sas/mpt2sas_debug.h
deleted file mode 100644 (file)
index 277120d..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Logging Support for MPT (Message Passing Technology) based controllers
- *
- * This code is based on drivers/scsi/mpt2sas/mpt2_debug.c
- * Copyright (C) 2007-2014  LSI Corporation
- * Copyright (C) 20013-2014 Avago Technologies
- *  (mailto: MPT-FusionLinux.pdl@avagotech.com)
- *
- * 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.
- *
- * NO WARRANTY
- * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
- * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
- * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
- * solely responsible for determining the appropriateness of using and
- * distributing the Program and assumes all risks associated with its
- * exercise of rights under this Agreement, including but not limited to
- * the risks and costs of program errors, damage to or loss of data,
- * programs or equipment, and unavailability or interruption of operations.
-
- * DISCLAIMER OF LIABILITY
- * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
- * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
- * USA.
- */
-
-#ifndef MPT2SAS_DEBUG_H_INCLUDED
-#define MPT2SAS_DEBUG_H_INCLUDED
-
-#define MPT_DEBUG                      0x00000001
-#define MPT_DEBUG_MSG_FRAME            0x00000002
-#define MPT_DEBUG_SG                   0x00000004
-#define MPT_DEBUG_EVENTS               0x00000008
-#define MPT_DEBUG_EVENT_WORK_TASK      0x00000010
-#define MPT_DEBUG_INIT                 0x00000020
-#define MPT_DEBUG_EXIT                 0x00000040
-#define MPT_DEBUG_FAIL                 0x00000080
-#define MPT_DEBUG_TM                   0x00000100
-#define MPT_DEBUG_REPLY                        0x00000200
-#define MPT_DEBUG_HANDSHAKE            0x00000400
-#define MPT_DEBUG_CONFIG               0x00000800
-#define MPT_DEBUG_DL                   0x00001000
-#define MPT_DEBUG_RESET                        0x00002000
-#define MPT_DEBUG_SCSI                 0x00004000
-#define MPT_DEBUG_IOCTL                        0x00008000
-#define MPT_DEBUG_CSMISAS              0x00010000
-#define MPT_DEBUG_SAS                  0x00020000
-#define MPT_DEBUG_TRANSPORT            0x00040000
-#define MPT_DEBUG_TASK_SET_FULL                0x00080000
-
-#define MPT_DEBUG_TARGET_MODE          0x00100000
-
-
-/*
- * CONFIG_SCSI_MPT2SAS_LOGGING - enabled in Kconfig
- */
-
-#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
-#define MPT_CHECK_LOGGING(IOC, CMD, BITS)                      \
-{                                                              \
-       if (IOC->logging_level & BITS)                          \
-               CMD;                                            \
-}
-#else
-#define MPT_CHECK_LOGGING(IOC, CMD, BITS)
-#endif /* CONFIG_SCSI_MPT2SAS_LOGGING */
-
-
-/*
- * debug macros
- */
-
-#define dprintk(IOC, CMD)                      \
-       MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG)
-
-#define dsgprintk(IOC, CMD)                    \
-       MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_SG)
-
-#define devtprintk(IOC, CMD)                   \
-       MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_EVENTS)
-
-#define dewtprintk(IOC, CMD)           \
-       MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_EVENT_WORK_TASK)
-
-#define dinitprintk(IOC, CMD)                  \
-       MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_INIT)
-
-#define dexitprintk(IOC, CMD)                  \
-       MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_EXIT)
-
-#define dfailprintk(IOC, CMD)                  \
-       MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_FAIL)
-
-#define dtmprintk(IOC, CMD)                    \
-       MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_TM)
-
-#define dreplyprintk(IOC, CMD)                 \
-       MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_REPLY)
-
-#define dhsprintk(IOC, CMD)                    \
-       MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_HANDSHAKE)
-
-#define dcprintk(IOC, CMD)                     \
-       MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_CONFIG)
-
-#define ddlprintk(IOC, CMD)                    \
-       MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_DL)
-
-#define drsprintk(IOC, CMD)                    \
-       MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_RESET)
-
-#define dsprintk(IOC, CMD)                     \
-       MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_SCSI)
-
-#define dctlprintk(IOC, CMD)                   \
-       MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_IOCTL)
-
-#define dcsmisasprintk(IOC, CMD)               \
-       MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_CSMISAS)
-
-#define dsasprintk(IOC, CMD)                   \
-       MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_SAS)
-
-#define dsastransport(IOC, CMD)                \
-       MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_SAS_WIDE)
-
-#define dmfprintk(IOC, CMD)                    \
-       MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_MSG_FRAME)
-
-#define dtsfprintk(IOC, CMD)                   \
-       MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_TASK_SET_FULL)
-
-#define dtransportprintk(IOC, CMD)                     \
-       MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_TRANSPORT)
-
-#define dTMprintk(IOC, CMD)                    \
-       MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_TARGET_MODE)
-
-/* inline functions for dumping debug data*/
-#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
-/**
- * _debug_dump_mf - print message frame contents
- * @mpi_request: pointer to message frame
- * @sz: number of dwords
- */
-static inline void
-_debug_dump_mf(void *mpi_request, int sz)
-{
-       int i;
-       __le32 *mfp = (__le32 *)mpi_request;
-
-       printk(KERN_INFO "mf:\n\t");
-       for (i = 0; i < sz; i++) {
-               if (i && ((i % 8) == 0))
-                       printk("\n\t");
-               printk("%08x ", le32_to_cpu(mfp[i]));
-       }
-       printk("\n");
-}
-#else
-#define _debug_dump_mf(mpi_request, sz)
-#endif /* CONFIG_SCSI_MPT2SAS_LOGGING */
-
-#endif /* MPT2SAS_DEBUG_H_INCLUDED */
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
deleted file mode 100644 (file)
index 0ad09b2..0000000
+++ /dev/null
@@ -1,8855 +0,0 @@
-/*
- * Scsi Host Layer for MPT (Message Passing Technology) based controllers
- *
- * This code is based on drivers/scsi/mpt2sas/mpt2_scsih.c
- * Copyright (C) 2007-2014  LSI Corporation
- * Copyright (C) 20013-2014 Avago Technologies
- *  (mailto: MPT-FusionLinux.pdl@avagotech.com)
- *
- * 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.
- *
- * NO WARRANTY
- * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
- * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
- * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
- * solely responsible for determining the appropriateness of using and
- * distributing the Program and assumes all risks associated with its
- * exercise of rights under this Agreement, including but not limited to
- * the risks and costs of program errors, damage to or loss of data,
- * programs or equipment, and unavailability or interruption of operations.
-
- * DISCLAIMER OF LIABILITY
- * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
- * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
- * USA.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/blkdev.h>
-#include <linux/sched.h>
-#include <linux/workqueue.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/aer.h>
-#include <linux/raid_class.h>
-#include <linux/slab.h>
-
-#include <asm/unaligned.h>
-
-#include "mpt2sas_base.h"
-
-MODULE_AUTHOR(MPT2SAS_AUTHOR);
-MODULE_DESCRIPTION(MPT2SAS_DESCRIPTION);
-MODULE_LICENSE("GPL");
-MODULE_VERSION(MPT2SAS_DRIVER_VERSION);
-
-#define RAID_CHANNEL 1
-
-/* forward proto's */
-static void _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
-    struct _sas_node *sas_expander);
-static void _firmware_event_work(struct work_struct *work);
-
-static u8 _scsih_check_for_pending_tm(struct MPT2SAS_ADAPTER *ioc, u16 smid);
-
-static void _scsih_scan_start(struct Scsi_Host *shost);
-static int _scsih_scan_finished(struct Scsi_Host *shost, unsigned long time);
-
-/* global parameters */
-LIST_HEAD(mpt2sas_ioc_list);
-/* global ioc lock for list operations */
-DEFINE_SPINLOCK(gioc_lock);
-/* local parameters */
-static u8 scsi_io_cb_idx = -1;
-static u8 tm_cb_idx = -1;
-static u8 ctl_cb_idx = -1;
-static u8 base_cb_idx = -1;
-static u8 port_enable_cb_idx = -1;
-static u8 transport_cb_idx = -1;
-static u8 scsih_cb_idx = -1;
-static u8 config_cb_idx = -1;
-static int mpt_ids;
-
-static u8 tm_tr_cb_idx = -1 ;
-static u8 tm_tr_volume_cb_idx = -1 ;
-static u8 tm_sas_control_cb_idx = -1;
-
-/* command line options */
-static u32 logging_level;
-MODULE_PARM_DESC(logging_level, " bits for enabling additional logging info "
-    "(default=0)");
-
-static ushort max_sectors = 0xFFFF;
-module_param(max_sectors, ushort, 0);
-MODULE_PARM_DESC(max_sectors, "max sectors, range 64 to 32767  default=32767");
-
-static int missing_delay[2] = {-1, -1};
-module_param_array(missing_delay, int, NULL, 0);
-MODULE_PARM_DESC(missing_delay, " device missing delay , io missing delay");
-
-/* scsi-mid layer global parmeter is max_report_luns, which is 511 */
-#define MPT2SAS_MAX_LUN (16895)
-static int max_lun = MPT2SAS_MAX_LUN;
-module_param(max_lun, int, 0);
-MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
-
-/* diag_buffer_enable is bitwise
- * bit 0 set = TRACE
- * bit 1 set = SNAPSHOT
- * bit 2 set = EXTENDED
- *
- * Either bit can be set, or both
- */
-static int diag_buffer_enable = -1;
-module_param(diag_buffer_enable, int, 0);
-MODULE_PARM_DESC(diag_buffer_enable, " post diag buffers "
-       "(TRACE=1/SNAPSHOT=2/EXTENDED=4/default=0)");
-
-static int disable_discovery = -1;
-module_param(disable_discovery, int, 0);
-MODULE_PARM_DESC(disable_discovery, " disable discovery ");
-
-/* permit overriding the host protection capabilities mask (EEDP/T10 PI) */
-static int prot_mask = 0;
-module_param(prot_mask, int, 0);
-MODULE_PARM_DESC(prot_mask, " host protection capabilities mask, def=7 ");
-
-/**
- * struct sense_info - common structure for obtaining sense keys
- * @skey: sense key
- * @asc: additional sense code
- * @ascq: additional sense code qualifier
- */
-struct sense_info {
-       u8 skey;
-       u8 asc;
-       u8 ascq;
-};
-
-
-#define MPT2SAS_TURN_ON_PFA_LED (0xFFFC)
-#define MPT2SAS_PORT_ENABLE_COMPLETE (0xFFFD)
-#define MPT2SAS_REMOVE_UNRESPONDING_DEVICES (0xFFFF)
-/**
- * struct fw_event_work - firmware event struct
- * @list: link list framework
- * @work: work object (ioc->fault_reset_work_q)
- * @cancel_pending_work: flag set during reset handling
- * @ioc: per adapter object
- * @device_handle: device handle
- * @VF_ID: virtual function id
- * @VP_ID: virtual port id
- * @ignore: flag meaning this event has been marked to ignore
- * @event: firmware event MPI2_EVENT_XXX defined in mpt2_ioc.h
- * @event_data: reply event data payload follows
- *
- * This object stored on ioc->fw_event_list.
- */
-struct fw_event_work {
-       struct list_head        list;
-       u8                      cancel_pending_work;
-       struct delayed_work     delayed_work;
-       struct MPT2SAS_ADAPTER *ioc;
-       u16                     device_handle;
-       u8                      VF_ID;
-       u8                      VP_ID;
-       u8                      ignore;
-       u16                     event;
-       struct kref             refcount;
-       char                    event_data[0] __aligned(4);
-};
-
-static void fw_event_work_free(struct kref *r)
-{
-       kfree(container_of(r, struct fw_event_work, refcount));
-}
-
-static void fw_event_work_get(struct fw_event_work *fw_work)
-{
-       kref_get(&fw_work->refcount);
-}
-
-static void fw_event_work_put(struct fw_event_work *fw_work)
-{
-       kref_put(&fw_work->refcount, fw_event_work_free);
-}
-
-static struct fw_event_work *alloc_fw_event_work(int len)
-{
-       struct fw_event_work *fw_event;
-
-       fw_event = kzalloc(sizeof(*fw_event) + len, GFP_ATOMIC);
-       if (!fw_event)
-               return NULL;
-
-       kref_init(&fw_event->refcount);
-       return fw_event;
-}
-
-/* raid transport support */
-static struct raid_template *mpt2sas_raid_template;
-
-/**
- * struct _scsi_io_transfer - scsi io transfer
- * @handle: sas device handle (assigned by firmware)
- * @is_raid: flag set for hidden raid components
- * @dir: DMA_TO_DEVICE, DMA_FROM_DEVICE,
- * @data_length: data transfer length
- * @data_dma: dma pointer to data
- * @sense: sense data
- * @lun: lun number
- * @cdb_length: cdb length
- * @cdb: cdb contents
- * @timeout: timeout for this command
- * @VF_ID: virtual function id
- * @VP_ID: virtual port id
- * @valid_reply: flag set for reply message
- * @sense_length: sense length
- * @ioc_status: ioc status
- * @scsi_state: scsi state
- * @scsi_status: scsi staus
- * @log_info: log information
- * @transfer_length: data length transfer when there is a reply message
- *
- * Used for sending internal scsi commands to devices within this module.
- * Refer to _scsi_send_scsi_io().
- */
-struct _scsi_io_transfer {
-       u16     handle;
-       u8      is_raid;
-       enum dma_data_direction dir;
-       u32     data_length;
-       dma_addr_t data_dma;
-       u8      sense[SCSI_SENSE_BUFFERSIZE];
-       u32     lun;
-       u8      cdb_length;
-       u8      cdb[32];
-       u8      timeout;
-       u8      VF_ID;
-       u8      VP_ID;
-       u8      valid_reply;
-  /* the following bits are only valid when 'valid_reply = 1' */
-       u32     sense_length;
-       u16     ioc_status;
-       u8      scsi_state;
-       u8      scsi_status;
-       u32     log_info;
-       u32     transfer_length;
-};
-
-/*
- * The pci device ids are defined in mpi/mpi2_cnfg.h.
- */
-static struct pci_device_id scsih_pci_table[] = {
-       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2004,
-               PCI_ANY_ID, PCI_ANY_ID },
-       /* Falcon ~ 2008*/
-       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2008,
-               PCI_ANY_ID, PCI_ANY_ID },
-       /* Liberator ~ 2108 */
-       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_1,
-               PCI_ANY_ID, PCI_ANY_ID },
-       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_2,
-               PCI_ANY_ID, PCI_ANY_ID },
-       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_3,
-               PCI_ANY_ID, PCI_ANY_ID },
-       /* Meteor ~ 2116 */
-       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_1,
-               PCI_ANY_ID, PCI_ANY_ID },
-       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_2,
-               PCI_ANY_ID, PCI_ANY_ID },
-       /* Thunderbolt ~ 2208 */
-       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_1,
-               PCI_ANY_ID, PCI_ANY_ID },
-       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_2,
-               PCI_ANY_ID, PCI_ANY_ID },
-       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_3,
-               PCI_ANY_ID, PCI_ANY_ID },
-       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_4,
-               PCI_ANY_ID, PCI_ANY_ID },
-       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_5,
-               PCI_ANY_ID, PCI_ANY_ID },
-       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_6,
-               PCI_ANY_ID, PCI_ANY_ID },
-       /* Mustang ~ 2308 */
-       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_1,
-               PCI_ANY_ID, PCI_ANY_ID },
-       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_2,
-               PCI_ANY_ID, PCI_ANY_ID },
-       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_3,
-               PCI_ANY_ID, PCI_ANY_ID },
-       /* SSS6200 */
-       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SSS6200,
-               PCI_ANY_ID, PCI_ANY_ID },
-       {0}     /* Terminating entry */
-};
-MODULE_DEVICE_TABLE(pci, scsih_pci_table);
-
-/**
- * _scsih_set_debug_level - global setting of ioc->logging_level.
- *
- * Note: The logging levels are defined in mpt2sas_debug.h.
- */
-static int
-_scsih_set_debug_level(const char *val, struct kernel_param *kp)
-{
-       int ret = param_set_int(val, kp);
-       struct MPT2SAS_ADAPTER *ioc;
-
-       if (ret)
-               return ret;
-
-       printk(KERN_INFO "setting logging_level(0x%08x)\n", logging_level);
-       spin_lock(&gioc_lock);
-       list_for_each_entry(ioc, &mpt2sas_ioc_list, list)
-               ioc->logging_level = logging_level;
-       spin_unlock(&gioc_lock);
-       return 0;
-}
-module_param_call(logging_level, _scsih_set_debug_level, param_get_int,
-    &logging_level, 0644);
-
-/**
- * _scsih_srch_boot_sas_address - search based on sas_address
- * @sas_address: sas address
- * @boot_device: boot device object from bios page 2
- *
- * Returns 1 when there's a match, 0 means no match.
- */
-static inline int
-_scsih_srch_boot_sas_address(u64 sas_address,
-    Mpi2BootDeviceSasWwid_t *boot_device)
-{
-       return (sas_address == le64_to_cpu(boot_device->SASAddress)) ?  1 : 0;
-}
-
-/**
- * _scsih_srch_boot_device_name - search based on device name
- * @device_name: device name specified in INDENTIFY fram
- * @boot_device: boot device object from bios page 2
- *
- * Returns 1 when there's a match, 0 means no match.
- */
-static inline int
-_scsih_srch_boot_device_name(u64 device_name,
-    Mpi2BootDeviceDeviceName_t *boot_device)
-{
-       return (device_name == le64_to_cpu(boot_device->DeviceName)) ? 1 : 0;
-}
-
-/**
- * _scsih_srch_boot_encl_slot - search based on enclosure_logical_id/slot
- * @enclosure_logical_id: enclosure logical id
- * @slot_number: slot number
- * @boot_device: boot device object from bios page 2
- *
- * Returns 1 when there's a match, 0 means no match.
- */
-static inline int
-_scsih_srch_boot_encl_slot(u64 enclosure_logical_id, u16 slot_number,
-    Mpi2BootDeviceEnclosureSlot_t *boot_device)
-{
-       return (enclosure_logical_id == le64_to_cpu(boot_device->
-           EnclosureLogicalID) && slot_number == le16_to_cpu(boot_device->
-           SlotNumber)) ? 1 : 0;
-}
-
-/**
- * _scsih_is_boot_device - search for matching boot device.
- * @sas_address: sas address
- * @device_name: device name specified in INDENTIFY fram
- * @enclosure_logical_id: enclosure logical id
- * @slot_number: slot number
- * @form: specifies boot device form
- * @boot_device: boot device object from bios page 2
- *
- * Returns 1 when there's a match, 0 means no match.
- */
-static int
-_scsih_is_boot_device(u64 sas_address, u64 device_name,
-    u64 enclosure_logical_id, u16 slot, u8 form,
-    Mpi2BiosPage2BootDevice_t *boot_device)
-{
-       int rc = 0;
-
-       switch (form) {
-       case MPI2_BIOSPAGE2_FORM_SAS_WWID:
-               if (!sas_address)
-                       break;
-               rc = _scsih_srch_boot_sas_address(
-                   sas_address, &boot_device->SasWwid);
-               break;
-       case MPI2_BIOSPAGE2_FORM_ENCLOSURE_SLOT:
-               if (!enclosure_logical_id)
-                       break;
-               rc = _scsih_srch_boot_encl_slot(
-                   enclosure_logical_id,
-                   slot, &boot_device->EnclosureSlot);
-               break;
-       case MPI2_BIOSPAGE2_FORM_DEVICE_NAME:
-               if (!device_name)
-                       break;
-               rc = _scsih_srch_boot_device_name(
-                   device_name, &boot_device->DeviceName);
-               break;
-       case MPI2_BIOSPAGE2_FORM_NO_DEVICE_SPECIFIED:
-               break;
-       }
-
-       return rc;
-}
-
-/**
- * _scsih_get_sas_address - set the sas_address for given device handle
- * @handle: device handle
- * @sas_address: sas address
- *
- * Returns 0 success, non-zero when failure
- */
-static int
-_scsih_get_sas_address(struct MPT2SAS_ADAPTER *ioc, u16 handle,
-    u64 *sas_address)
-{
-       Mpi2SasDevicePage0_t sas_device_pg0;
-       Mpi2ConfigReply_t mpi_reply;
-       u32 ioc_status;
-       *sas_address = 0;
-
-       if (handle <= ioc->sas_hba.num_phys) {
-               *sas_address = ioc->sas_hba.sas_address;
-               return 0;
-       }
-
-       if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
-           MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name,
-               __FILE__, __LINE__, __func__);
-               return -ENXIO;
-       }
-
-       ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
-       if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
-               *sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
-               return 0;
-       }
-
-       /* we hit this becuase the given parent handle doesn't exist */
-       if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
-               return -ENXIO;
-       /* else error case */
-       printk(MPT2SAS_ERR_FMT "handle(0x%04x), ioc_status(0x%04x), "
-           "failure at %s:%d/%s()!\n", ioc->name, handle, ioc_status,
-            __FILE__, __LINE__, __func__);
-       return -EIO;
-}
-
-/**
- * _scsih_determine_boot_device - determine boot device.
- * @ioc: per adapter object
- * @device: either sas_device or raid_device object
- * @is_raid: [flag] 1 = raid object, 0 = sas object
- *
- * Determines whether this device should be first reported device to
- * to scsi-ml or sas transport, this purpose is for persistent boot device.
- * There are primary, alternate, and current entries in bios page 2. The order
- * priority is primary, alternate, then current.  This routine saves
- * the corresponding device object and is_raid flag in the ioc object.
- * The saved data to be used later in _scsih_probe_boot_devices().
- */
-static void
-_scsih_determine_boot_device(struct MPT2SAS_ADAPTER *ioc,
-    void *device, u8 is_raid)
-{
-       struct _sas_device *sas_device;
-       struct _raid_device *raid_device;
-       u64 sas_address;
-       u64 device_name;
-       u64 enclosure_logical_id;
-       u16 slot;
-
-        /* only process this function when driver loads */
-       if (!ioc->is_driver_loading)
-               return;
-
-        /* no Bios, return immediately */
-       if (!ioc->bios_pg3.BiosVersion)
-               return;
-
-       if (!is_raid) {
-               sas_device = device;
-               sas_address = sas_device->sas_address;
-               device_name = sas_device->device_name;
-               enclosure_logical_id = sas_device->enclosure_logical_id;
-               slot = sas_device->slot;
-       } else {
-               raid_device = device;
-               sas_address = raid_device->wwid;
-               device_name = 0;
-               enclosure_logical_id = 0;
-               slot = 0;
-       }
-
-       if (!ioc->req_boot_device.device) {
-               if (_scsih_is_boot_device(sas_address, device_name,
-                   enclosure_logical_id, slot,
-                   (ioc->bios_pg2.ReqBootDeviceForm &
-                   MPI2_BIOSPAGE2_FORM_MASK),
-                   &ioc->bios_pg2.RequestedBootDevice)) {
-                       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT
-                          "%s: req_boot_device(0x%016llx)\n",
-                           ioc->name, __func__,
-                           (unsigned long long)sas_address));
-                       ioc->req_boot_device.device = device;
-                       ioc->req_boot_device.is_raid = is_raid;
-               }
-       }
-
-       if (!ioc->req_alt_boot_device.device) {
-               if (_scsih_is_boot_device(sas_address, device_name,
-                   enclosure_logical_id, slot,
-                   (ioc->bios_pg2.ReqAltBootDeviceForm &
-                   MPI2_BIOSPAGE2_FORM_MASK),
-                   &ioc->bios_pg2.RequestedAltBootDevice)) {
-                       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT
-                          "%s: req_alt_boot_device(0x%016llx)\n",
-                           ioc->name, __func__,
-                           (unsigned long long)sas_address));
-                       ioc->req_alt_boot_device.device = device;
-                       ioc->req_alt_boot_device.is_raid = is_raid;
-               }
-       }
-
-       if (!ioc->current_boot_device.device) {
-               if (_scsih_is_boot_device(sas_address, device_name,
-                   enclosure_logical_id, slot,
-                   (ioc->bios_pg2.CurrentBootDeviceForm &
-                   MPI2_BIOSPAGE2_FORM_MASK),
-                   &ioc->bios_pg2.CurrentBootDevice)) {
-                       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT
-                          "%s: current_boot_device(0x%016llx)\n",
-                           ioc->name, __func__,
-                           (unsigned long long)sas_address));
-                       ioc->current_boot_device.device = device;
-                       ioc->current_boot_device.is_raid = is_raid;
-               }
-       }
-}
-
-static struct _sas_device *
-__mpt2sas_get_sdev_from_target(struct MPT2SAS_ADAPTER *ioc,
-               struct MPT2SAS_TARGET *tgt_priv)
-{
-       struct _sas_device *ret;
-
-       assert_spin_locked(&ioc->sas_device_lock);
-
-       ret = tgt_priv->sdev;
-       if (ret)
-               sas_device_get(ret);
-
-       return ret;
-}
-
-static struct _sas_device *
-mpt2sas_get_sdev_from_target(struct MPT2SAS_ADAPTER *ioc,
-               struct MPT2SAS_TARGET *tgt_priv)
-{
-       struct _sas_device *ret;
-       unsigned long flags;
-
-       spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       ret = __mpt2sas_get_sdev_from_target(ioc, tgt_priv);
-       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-
-       return ret;
-}
-
-
-struct _sas_device *
-__mpt2sas_get_sdev_by_addr(struct MPT2SAS_ADAPTER *ioc,
-    u64 sas_address)
-{
-       struct _sas_device *sas_device;
-
-       assert_spin_locked(&ioc->sas_device_lock);
-
-       list_for_each_entry(sas_device, &ioc->sas_device_list, list)
-               if (sas_device->sas_address == sas_address)
-                       goto found_device;
-
-       list_for_each_entry(sas_device, &ioc->sas_device_init_list, list)
-               if (sas_device->sas_address == sas_address)
-                       goto found_device;
-
-       return NULL;
-
-found_device:
-       sas_device_get(sas_device);
-       return sas_device;
-}
-
-/**
- * mpt2sas_get_sdev_by_addr - sas device search
- * @ioc: per adapter object
- * @sas_address: sas address
- * Context: Calling function should acquire ioc->sas_device_lock
- *
- * This searches for sas_device based on sas_address, then return sas_device
- * object.
- */
-struct _sas_device *
-mpt2sas_get_sdev_by_addr(struct MPT2SAS_ADAPTER *ioc,
-    u64 sas_address)
-{
-       struct _sas_device *sas_device;
-       unsigned long flags;
-
-       spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       sas_device = __mpt2sas_get_sdev_by_addr(ioc,
-                       sas_address);
-       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-
-       return sas_device;
-}
-
-static struct _sas_device *
-__mpt2sas_get_sdev_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
-{
-       struct _sas_device *sas_device;
-
-       assert_spin_locked(&ioc->sas_device_lock);
-
-       list_for_each_entry(sas_device, &ioc->sas_device_list, list)
-               if (sas_device->handle == handle)
-                       goto found_device;
-
-       list_for_each_entry(sas_device, &ioc->sas_device_init_list, list)
-               if (sas_device->handle == handle)
-                       goto found_device;
-
-       return NULL;
-
-found_device:
-       sas_device_get(sas_device);
-       return sas_device;
-}
-
-/**
- * mpt2sas_get_sdev_by_handle - sas device search
- * @ioc: per adapter object
- * @handle: sas device handle (assigned by firmware)
- * Context: Calling function should acquire ioc->sas_device_lock
- *
- * This searches for sas_device based on sas_address, then return sas_device
- * object.
- */
-static struct _sas_device *
-mpt2sas_get_sdev_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
-{
-       struct _sas_device *sas_device;
-       unsigned long flags;
-
-       spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       sas_device = __mpt2sas_get_sdev_by_handle(ioc, handle);
-       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-
-       return sas_device;
-}
-
-/**
- * _scsih_sas_device_remove - remove sas_device from list.
- * @ioc: per adapter object
- * @sas_device: the sas_device object
- * Context: This function will acquire ioc->sas_device_lock.
- *
- * If sas_device is on the list, remove it and decrement its reference count.
- */
-static void
-_scsih_sas_device_remove(struct MPT2SAS_ADAPTER *ioc,
-    struct _sas_device *sas_device)
-{
-       unsigned long flags;
-
-       if (!sas_device)
-               return;
-
-       /*
-        * The lock serializes access to the list, but we still need to verify
-        * that nobody removed the entry while we were waiting on the lock.
-        */
-       spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       if (!list_empty(&sas_device->list)) {
-               list_del_init(&sas_device->list);
-               sas_device_put(sas_device);
-       }
-       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-}
-
-
-/**
- * _scsih_sas_device_add - insert sas_device to the list.
- * @ioc: per adapter object
- * @sas_device: the sas_device object
- * Context: This function will acquire ioc->sas_device_lock.
- *
- * Adding new object to the ioc->sas_device_list.
- */
-static void
-_scsih_sas_device_add(struct MPT2SAS_ADAPTER *ioc,
-    struct _sas_device *sas_device)
-{
-       unsigned long flags;
-
-       dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: handle"
-           "(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__,
-           sas_device->handle, (unsigned long long)sas_device->sas_address));
-
-       spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       sas_device_get(sas_device);
-       list_add_tail(&sas_device->list, &ioc->sas_device_list);
-       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-
-       if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
-            sas_device->sas_address_parent)) {
-               _scsih_sas_device_remove(ioc, sas_device);
-       } else if (!sas_device->starget) {
-               /* When asyn scanning is enabled, its not possible to remove
-                * devices while scanning is turned on due to an oops in
-                * scsi_sysfs_add_sdev()->add_device()->sysfs_addrm_start()
-                */
-               if (!ioc->is_driver_loading) {
-                       mpt2sas_transport_port_remove(ioc,
-                       sas_device->sas_address,
-                       sas_device->sas_address_parent);
-                       _scsih_sas_device_remove(ioc, sas_device);
-               }
-       }
-}
-
-/**
- * _scsih_sas_device_init_add - insert sas_device to the list.
- * @ioc: per adapter object
- * @sas_device: the sas_device object
- * Context: This function will acquire ioc->sas_device_lock.
- *
- * Adding new object at driver load time to the ioc->sas_device_init_list.
- */
-static void
-_scsih_sas_device_init_add(struct MPT2SAS_ADAPTER *ioc,
-    struct _sas_device *sas_device)
-{
-       unsigned long flags;
-
-       dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: handle"
-           "(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__,
-           sas_device->handle, (unsigned long long)sas_device->sas_address));
-
-       spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       sas_device_get(sas_device);
-       list_add_tail(&sas_device->list, &ioc->sas_device_init_list);
-       _scsih_determine_boot_device(ioc, sas_device, 0);
-       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-}
-
-/**
- * _scsih_raid_device_find_by_id - raid device search
- * @ioc: per adapter object
- * @id: sas device target id
- * @channel: sas device channel
- * Context: Calling function should acquire ioc->raid_device_lock
- *
- * This searches for raid_device based on target id, then return raid_device
- * object.
- */
-static struct _raid_device *
-_scsih_raid_device_find_by_id(struct MPT2SAS_ADAPTER *ioc, int id, int channel)
-{
-       struct _raid_device *raid_device, *r;
-
-       r = NULL;
-       list_for_each_entry(raid_device, &ioc->raid_device_list, list) {
-               if (raid_device->id == id && raid_device->channel == channel) {
-                       r = raid_device;
-                       goto out;
-               }
-       }
-
- out:
-       return r;
-}
-
-/**
- * _scsih_raid_device_find_by_handle - raid device search
- * @ioc: per adapter object
- * @handle: sas device handle (assigned by firmware)
- * Context: Calling function should acquire ioc->raid_device_lock
- *
- * This searches for raid_device based on handle, then return raid_device
- * object.
- */
-static struct _raid_device *
-_scsih_raid_device_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
-{
-       struct _raid_device *raid_device, *r;
-
-       r = NULL;
-       list_for_each_entry(raid_device, &ioc->raid_device_list, list) {
-               if (raid_device->handle != handle)
-                       continue;
-               r = raid_device;
-               goto out;
-       }
-
- out:
-       return r;
-}
-
-/**
- * _scsih_raid_device_find_by_wwid - raid device search
- * @ioc: per adapter object
- * @handle: sas device handle (assigned by firmware)
- * Context: Calling function should acquire ioc->raid_device_lock
- *
- * This searches for raid_device based on wwid, then return raid_device
- * object.
- */
-static struct _raid_device *
-_scsih_raid_device_find_by_wwid(struct MPT2SAS_ADAPTER *ioc, u64 wwid)
-{
-       struct _raid_device *raid_device, *r;
-
-       r = NULL;
-       list_for_each_entry(raid_device, &ioc->raid_device_list, list) {
-               if (raid_device->wwid != wwid)
-                       continue;
-               r = raid_device;
-               goto out;
-       }
-
- out:
-       return r;
-}
-
-/**
- * _scsih_raid_device_add - add raid_device object
- * @ioc: per adapter object
- * @raid_device: raid_device object
- *
- * This is added to the raid_device_list link list.
- */
-static void
-_scsih_raid_device_add(struct MPT2SAS_ADAPTER *ioc,
-    struct _raid_device *raid_device)
-{
-       unsigned long flags;
-
-       dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: handle"
-           "(0x%04x), wwid(0x%016llx)\n", ioc->name, __func__,
-           raid_device->handle, (unsigned long long)raid_device->wwid));
-
-       spin_lock_irqsave(&ioc->raid_device_lock, flags);
-       list_add_tail(&raid_device->list, &ioc->raid_device_list);
-       spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
-}
-
-/**
- * _scsih_raid_device_remove - delete raid_device object
- * @ioc: per adapter object
- * @raid_device: raid_device object
- *
- */
-static void
-_scsih_raid_device_remove(struct MPT2SAS_ADAPTER *ioc,
-    struct _raid_device *raid_device)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&ioc->raid_device_lock, flags);
-       list_del(&raid_device->list);
-       kfree(raid_device);
-       spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
-}
-
-/**
- * mpt2sas_scsih_expander_find_by_handle - expander device search
- * @ioc: per adapter object
- * @handle: expander handle (assigned by firmware)
- * Context: Calling function should acquire ioc->sas_device_lock
- *
- * This searches for expander device based on handle, then returns the
- * sas_node object.
- */
-struct _sas_node *
-mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
-{
-       struct _sas_node *sas_expander, *r;
-
-       r = NULL;
-       list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
-               if (sas_expander->handle != handle)
-                       continue;
-               r = sas_expander;
-               goto out;
-       }
- out:
-       return r;
-}
-
-/**
- * mpt2sas_scsih_expander_find_by_sas_address - expander device search
- * @ioc: per adapter object
- * @sas_address: sas address
- * Context: Calling function should acquire ioc->sas_node_lock.
- *
- * This searches for expander device based on sas_address, then returns the
- * sas_node object.
- */
-struct _sas_node *
-mpt2sas_scsih_expander_find_by_sas_address(struct MPT2SAS_ADAPTER *ioc,
-    u64 sas_address)
-{
-       struct _sas_node *sas_expander, *r;
-
-       r = NULL;
-       list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
-               if (sas_expander->sas_address != sas_address)
-                       continue;
-               r = sas_expander;
-               goto out;
-       }
- out:
-       return r;
-}
-
-/**
- * _scsih_expander_node_add - insert expander device to the list.
- * @ioc: per adapter object
- * @sas_expander: the sas_device object
- * Context: This function will acquire ioc->sas_node_lock.
- *
- * Adding new object to the ioc->sas_expander_list.
- *
- * Return nothing.
- */
-static void
-_scsih_expander_node_add(struct MPT2SAS_ADAPTER *ioc,
-    struct _sas_node *sas_expander)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&ioc->sas_node_lock, flags);
-       list_add_tail(&sas_expander->list, &ioc->sas_expander_list);
-       spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
-}
-
-/**
- * _scsih_is_end_device - determines if device is an end device
- * @device_info: bitfield providing information about the device.
- * Context: none
- *
- * Returns 1 if end device.
- */
-static int
-_scsih_is_end_device(u32 device_info)
-{
-       if (device_info & MPI2_SAS_DEVICE_INFO_END_DEVICE &&
-               ((device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET) |
-               (device_info & MPI2_SAS_DEVICE_INFO_STP_TARGET) |
-               (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE)))
-               return 1;
-       else
-               return 0;
-}
-
-/**
- * _scsih_scsi_lookup_get - returns scmd entry
- * @ioc: per adapter object
- * @smid: system request message index
- *
- * Returns the smid stored scmd pointer.
- */
-static struct scsi_cmnd *
-_scsih_scsi_lookup_get(struct MPT2SAS_ADAPTER *ioc, u16 smid)
-{
-       return ioc->scsi_lookup[smid - 1].scmd;
-}
-
-/**
- * _scsih_scsi_lookup_get_clear - returns scmd entry
- * @ioc: per adapter object
- * @smid: system request message index
- *
- * Returns the smid stored scmd pointer.
- * Then will derefrence the stored scmd pointer.
- */
-static inline struct scsi_cmnd *
-_scsih_scsi_lookup_get_clear(struct MPT2SAS_ADAPTER *ioc, u16 smid)
-{
-       unsigned long flags;
-       struct scsi_cmnd *scmd;
-
-       spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-       scmd = ioc->scsi_lookup[smid - 1].scmd;
-       ioc->scsi_lookup[smid - 1].scmd = NULL;
-       spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
-
-       return scmd;
-}
-
-/**
- * _scsih_scsi_lookup_find_by_scmd - scmd lookup
- * @ioc: per adapter object
- * @smid: system request message index
- * @scmd: pointer to scsi command object
- * Context: This function will acquire ioc->scsi_lookup_lock.
- *
- * This will search for a scmd pointer in the scsi_lookup array,
- * returning the revelent smid.  A returned value of zero means invalid.
- */
-static u16
-_scsih_scsi_lookup_find_by_scmd(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd
-    *scmd)
-{
-       u16 smid;
-       unsigned long   flags;
-       int i;
-
-       spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-       smid = 0;
-       for (i = 0; i < ioc->scsiio_depth; i++) {
-               if (ioc->scsi_lookup[i].scmd == scmd) {
-                       smid = ioc->scsi_lookup[i].smid;
-                       goto out;
-               }
-       }
- out:
-       spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
-       return smid;
-}
-
-/**
- * _scsih_scsi_lookup_find_by_target - search for matching channel:id
- * @ioc: per adapter object
- * @id: target id
- * @channel: channel
- * Context: This function will acquire ioc->scsi_lookup_lock.
- *
- * This will search for a matching channel:id in the scsi_lookup array,
- * returning 1 if found.
- */
-static u8
-_scsih_scsi_lookup_find_by_target(struct MPT2SAS_ADAPTER *ioc, int id,
-    int channel)
-{
-       u8 found;
-       unsigned long   flags;
-       int i;
-
-       spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-       found = 0;
-       for (i = 0 ; i < ioc->scsiio_depth; i++) {
-               if (ioc->scsi_lookup[i].scmd &&
-                   (ioc->scsi_lookup[i].scmd->device->id == id &&
-                   ioc->scsi_lookup[i].scmd->device->channel == channel)) {
-                       found = 1;
-                       goto out;
-               }
-       }
- out:
-       spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
-       return found;
-}
-
-/**
- * _scsih_scsi_lookup_find_by_lun - search for matching channel:id:lun
- * @ioc: per adapter object
- * @id: target id
- * @lun: lun number
- * @channel: channel
- * Context: This function will acquire ioc->scsi_lookup_lock.
- *
- * This will search for a matching channel:id:lun in the scsi_lookup array,
- * returning 1 if found.
- */
-static u8
-_scsih_scsi_lookup_find_by_lun(struct MPT2SAS_ADAPTER *ioc, int id,
-    unsigned int lun, int channel)
-{
-       u8 found;
-       unsigned long   flags;
-       int i;
-
-       spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-       found = 0;
-       for (i = 0 ; i < ioc->scsiio_depth; i++) {
-               if (ioc->scsi_lookup[i].scmd &&
-                   (ioc->scsi_lookup[i].scmd->device->id == id &&
-                   ioc->scsi_lookup[i].scmd->device->channel == channel &&
-                   ioc->scsi_lookup[i].scmd->device->lun == lun)) {
-                       found = 1;
-                       goto out;
-               }
-       }
- out:
-       spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
-       return found;
-}
-
-/**
- * _scsih_get_chain_buffer_tracker - obtain chain tracker
- * @ioc: per adapter object
- * @smid: smid associated to an IO request
- *
- * Returns chain tracker(from ioc->free_chain_list)
- */
-static struct chain_tracker *
-_scsih_get_chain_buffer_tracker(struct MPT2SAS_ADAPTER *ioc, u16 smid)
-{
-       struct chain_tracker *chain_req;
-       unsigned long flags;
-
-       spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-       if (list_empty(&ioc->free_chain_list)) {
-               spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
-               dfailprintk(ioc, printk(MPT2SAS_WARN_FMT "chain buffers not "
-                       "available\n", ioc->name));
-               return NULL;
-       }
-       chain_req = list_entry(ioc->free_chain_list.next,
-           struct chain_tracker, tracker_list);
-       list_del_init(&chain_req->tracker_list);
-       list_add_tail(&chain_req->tracker_list,
-           &ioc->scsi_lookup[smid - 1].chain_list);
-       spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
-       return chain_req;
-}
-
-/**
- * _scsih_build_scatter_gather - main sg creation routine
- * @ioc: per adapter object
- * @scmd: scsi command
- * @smid: system request message index
- * Context: none.
- *
- * The main routine that builds scatter gather table from a given
- * scsi request sent via the .queuecommand main handler.
- *
- * Returns 0 success, anything else error
- */
-static int
-_scsih_build_scatter_gather(struct MPT2SAS_ADAPTER *ioc,
-    struct scsi_cmnd *scmd, u16 smid)
-{
-       Mpi2SCSIIORequest_t *mpi_request;
-       dma_addr_t chain_dma;
-       struct scatterlist *sg_scmd;
-       void *sg_local, *chain;
-       u32 chain_offset;
-       u32 chain_length;
-       u32 chain_flags;
-       int sges_left;
-       u32 sges_in_segment;
-       u32 sgl_flags;
-       u32 sgl_flags_last_element;
-       u32 sgl_flags_end_buffer;
-       struct chain_tracker *chain_req;
-
-       mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
-
-       /* init scatter gather flags */
-       sgl_flags = MPI2_SGE_FLAGS_SIMPLE_ELEMENT;
-       if (scmd->sc_data_direction == DMA_TO_DEVICE)
-               sgl_flags |= MPI2_SGE_FLAGS_HOST_TO_IOC;
-       sgl_flags_last_element = (sgl_flags | MPI2_SGE_FLAGS_LAST_ELEMENT)
-           << MPI2_SGE_FLAGS_SHIFT;
-       sgl_flags_end_buffer = (sgl_flags | MPI2_SGE_FLAGS_LAST_ELEMENT |
-           MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_END_OF_LIST)
-           << MPI2_SGE_FLAGS_SHIFT;
-       sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
-
-       sg_scmd = scsi_sglist(scmd);
-       sges_left = scsi_dma_map(scmd);
-       if (sges_left < 0) {
-               sdev_printk(KERN_ERR, scmd->device, "pci_map_sg"
-               " failed: request for %d bytes!\n", scsi_bufflen(scmd));
-               return -ENOMEM;
-       }
-
-       sg_local = &mpi_request->SGL;
-       sges_in_segment = ioc->max_sges_in_main_message;
-       if (sges_left <= sges_in_segment)
-               goto fill_in_last_segment;
-
-       mpi_request->ChainOffset = (offsetof(Mpi2SCSIIORequest_t, SGL) +
-           (sges_in_segment * ioc->sge_size))/4;
-
-       /* fill in main message segment when there is a chain following */
-       while (sges_in_segment) {
-               if (sges_in_segment == 1)
-                       ioc->base_add_sg_single(sg_local,
-                           sgl_flags_last_element | sg_dma_len(sg_scmd),
-                           sg_dma_address(sg_scmd));
-               else
-                       ioc->base_add_sg_single(sg_local, sgl_flags |
-                           sg_dma_len(sg_scmd), sg_dma_address(sg_scmd));
-               sg_scmd = sg_next(sg_scmd);
-               sg_local += ioc->sge_size;
-               sges_left--;
-               sges_in_segment--;
-       }
-
-       /* initializing the chain flags and pointers */
-       chain_flags = MPI2_SGE_FLAGS_CHAIN_ELEMENT << MPI2_SGE_FLAGS_SHIFT;
-       chain_req = _scsih_get_chain_buffer_tracker(ioc, smid);
-       if (!chain_req)
-               return -1;
-       chain = chain_req->chain_buffer;
-       chain_dma = chain_req->chain_buffer_dma;
-       do {
-               sges_in_segment = (sges_left <=
-                   ioc->max_sges_in_chain_message) ? sges_left :
-                   ioc->max_sges_in_chain_message;
-               chain_offset = (sges_left == sges_in_segment) ?
-                   0 : (sges_in_segment * ioc->sge_size)/4;
-               chain_length = sges_in_segment * ioc->sge_size;
-               if (chain_offset) {
-                       chain_offset = chain_offset <<
-                           MPI2_SGE_CHAIN_OFFSET_SHIFT;
-                       chain_length += ioc->sge_size;
-               }
-               ioc->base_add_sg_single(sg_local, chain_flags | chain_offset |
-                   chain_length, chain_dma);
-               sg_local = chain;
-               if (!chain_offset)
-                       goto fill_in_last_segment;
-
-               /* fill in chain segments */
-               while (sges_in_segment) {
-                       if (sges_in_segment == 1)
-                               ioc->base_add_sg_single(sg_local,
-                                   sgl_flags_last_element |
-                                   sg_dma_len(sg_scmd),
-                                   sg_dma_address(sg_scmd));
-                       else
-                               ioc->base_add_sg_single(sg_local, sgl_flags |
-                                   sg_dma_len(sg_scmd),
-                                   sg_dma_address(sg_scmd));
-                       sg_scmd = sg_next(sg_scmd);
-                       sg_local += ioc->sge_size;
-                       sges_left--;
-                       sges_in_segment--;
-               }
-
-               chain_req = _scsih_get_chain_buffer_tracker(ioc, smid);
-               if (!chain_req)
-                       return -1;
-               chain = chain_req->chain_buffer;
-               chain_dma = chain_req->chain_buffer_dma;
-       } while (1);
-
-
- fill_in_last_segment:
-
-       /* fill the last segment */
-       while (sges_left) {
-               if (sges_left == 1)
-                       ioc->base_add_sg_single(sg_local, sgl_flags_end_buffer |
-                           sg_dma_len(sg_scmd), sg_dma_address(sg_scmd));
-               else
-                       ioc->base_add_sg_single(sg_local, sgl_flags |
-                           sg_dma_len(sg_scmd), sg_dma_address(sg_scmd));
-               sg_scmd = sg_next(sg_scmd);
-               sg_local += ioc->sge_size;
-               sges_left--;
-       }
-
-       return 0;
-}
-
-/**
- * _scsih_change_queue_depth - setting device queue depth
- * @sdev: scsi device struct
- * @qdepth: requested queue depth
- *
- * Returns queue depth.
- */
-static int
-_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
-{
-       struct Scsi_Host *shost = sdev->host;
-       int max_depth;
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-       struct MPT2SAS_DEVICE *sas_device_priv_data;
-       struct MPT2SAS_TARGET *sas_target_priv_data;
-       struct _sas_device *sas_device;
-       unsigned long flags;
-
-       max_depth = shost->can_queue;
-
-       /* limit max device queue for SATA to 32 */
-       sas_device_priv_data = sdev->hostdata;
-       if (!sas_device_priv_data)
-               goto not_sata;
-       sas_target_priv_data = sas_device_priv_data->sas_target;
-       if (!sas_target_priv_data)
-               goto not_sata;
-       if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME))
-               goto not_sata;
-
-       spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       sas_device = __mpt2sas_get_sdev_from_target(ioc, sas_target_priv_data);
-       if (sas_device) {
-               if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE)
-                       max_depth = MPT2SAS_SATA_QUEUE_DEPTH;
-
-               sas_device_put(sas_device);
-       }
-       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-
- not_sata:
-       if (!sdev->tagged_supported)
-               max_depth = 1;
-       if (qdepth > max_depth)
-               qdepth = max_depth;
-       return scsi_change_queue_depth(sdev, qdepth);
-}
-
-/**
- * _scsih_target_alloc - target add routine
- * @starget: scsi target struct
- *
- * Returns 0 if ok. Any other return is assumed to be an error and
- * the device is ignored.
- */
-static int
-_scsih_target_alloc(struct scsi_target *starget)
-{
-       struct Scsi_Host *shost = dev_to_shost(&starget->dev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-       struct MPT2SAS_TARGET *sas_target_priv_data;
-       struct _sas_device *sas_device;
-       struct _raid_device *raid_device;
-       unsigned long flags;
-       struct sas_rphy *rphy;
-
-       sas_target_priv_data = kzalloc(sizeof(*sas_target_priv_data),
-                                      GFP_KERNEL);
-       if (!sas_target_priv_data)
-               return -ENOMEM;
-
-       starget->hostdata = sas_target_priv_data;
-       sas_target_priv_data->starget = starget;
-       sas_target_priv_data->handle = MPT2SAS_INVALID_DEVICE_HANDLE;
-
-       /* RAID volumes */
-       if (starget->channel == RAID_CHANNEL) {
-               spin_lock_irqsave(&ioc->raid_device_lock, flags);
-               raid_device = _scsih_raid_device_find_by_id(ioc, starget->id,
-                   starget->channel);
-               if (raid_device) {
-                       sas_target_priv_data->handle = raid_device->handle;
-                       sas_target_priv_data->sas_address = raid_device->wwid;
-                       sas_target_priv_data->flags |= MPT_TARGET_FLAGS_VOLUME;
-                       if (ioc->is_warpdrive)
-                               sas_target_priv_data->raid_device = raid_device;
-                       raid_device->starget = starget;
-               }
-               spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
-               return 0;
-       }
-
-       /* sas/sata devices */
-       spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       rphy = dev_to_rphy(starget->dev.parent);
-       sas_device = __mpt2sas_get_sdev_by_addr(ioc,
-          rphy->identify.sas_address);
-
-       if (sas_device) {
-               sas_target_priv_data->handle = sas_device->handle;
-               sas_target_priv_data->sas_address = sas_device->sas_address;
-               sas_target_priv_data->sdev = sas_device;
-               sas_device->starget = starget;
-               sas_device->id = starget->id;
-               sas_device->channel = starget->channel;
-               if (test_bit(sas_device->handle, ioc->pd_handles))
-                       sas_target_priv_data->flags |=
-                           MPT_TARGET_FLAGS_RAID_COMPONENT;
-
-       }
-       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-
-       return 0;
-}
-
-/**
- * _scsih_target_destroy - target destroy routine
- * @starget: scsi target struct
- *
- * Returns nothing.
- */
-static void
-_scsih_target_destroy(struct scsi_target *starget)
-{
-       struct Scsi_Host *shost = dev_to_shost(&starget->dev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-       struct MPT2SAS_TARGET *sas_target_priv_data;
-       struct _sas_device *sas_device;
-       struct _raid_device *raid_device;
-       unsigned long flags;
-       struct sas_rphy *rphy;
-
-       sas_target_priv_data = starget->hostdata;
-       if (!sas_target_priv_data)
-               return;
-
-       if (starget->channel == RAID_CHANNEL) {
-               spin_lock_irqsave(&ioc->raid_device_lock, flags);
-               raid_device = _scsih_raid_device_find_by_id(ioc, starget->id,
-                   starget->channel);
-               if (raid_device) {
-                       raid_device->starget = NULL;
-                       raid_device->sdev = NULL;
-               }
-               spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
-               goto out;
-       }
-
-       spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       rphy = dev_to_rphy(starget->dev.parent);
-       sas_device = __mpt2sas_get_sdev_from_target(ioc, sas_target_priv_data);
-       if (sas_device && (sas_device->starget == starget) &&
-           (sas_device->id == starget->id) &&
-           (sas_device->channel == starget->channel))
-               sas_device->starget = NULL;
-
-       if (sas_device) {
-               /*
-                * Corresponding get() is in _scsih_target_alloc()
-                */
-               sas_target_priv_data->sdev = NULL;
-               sas_device_put(sas_device);
-
-               sas_device_put(sas_device);
-       }
-       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-
- out:
-       kfree(sas_target_priv_data);
-       starget->hostdata = NULL;
-}
-
-/**
- * _scsih_slave_alloc - device add routine
- * @sdev: scsi device struct
- *
- * Returns 0 if ok. Any other return is assumed to be an error and
- * the device is ignored.
- */
-static int
-_scsih_slave_alloc(struct scsi_device *sdev)
-{
-       struct Scsi_Host *shost;
-       struct MPT2SAS_ADAPTER *ioc;
-       struct MPT2SAS_TARGET *sas_target_priv_data;
-       struct MPT2SAS_DEVICE *sas_device_priv_data;
-       struct scsi_target *starget;
-       struct _raid_device *raid_device;
-       struct _sas_device *sas_device;
-       unsigned long flags;
-
-       sas_device_priv_data = kzalloc(sizeof(*sas_device_priv_data),
-                                      GFP_KERNEL);
-       if (!sas_device_priv_data)
-               return -ENOMEM;
-
-       sas_device_priv_data->lun = sdev->lun;
-       sas_device_priv_data->flags = MPT_DEVICE_FLAGS_INIT;
-
-       starget = scsi_target(sdev);
-       sas_target_priv_data = starget->hostdata;
-       sas_target_priv_data->num_luns++;
-       sas_device_priv_data->sas_target = sas_target_priv_data;
-       sdev->hostdata = sas_device_priv_data;
-       if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_RAID_COMPONENT))
-               sdev->no_uld_attach = 1;
-
-       shost = dev_to_shost(&starget->dev);
-       ioc = shost_priv(shost);
-       if (starget->channel == RAID_CHANNEL) {
-               spin_lock_irqsave(&ioc->raid_device_lock, flags);
-               raid_device = _scsih_raid_device_find_by_id(ioc,
-                   starget->id, starget->channel);
-               if (raid_device)
-                       raid_device->sdev = sdev; /* raid is single lun */
-               spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
-       }
-
-       if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) {
-               spin_lock_irqsave(&ioc->sas_device_lock, flags);
-               sas_device = __mpt2sas_get_sdev_by_addr(ioc,
-                               sas_target_priv_data->sas_address);
-               if (sas_device && (sas_device->starget == NULL)) {
-                       sdev_printk(KERN_INFO, sdev,
-                            "%s : sas_device->starget set to starget @ %d\n",
-                            __func__, __LINE__);
-                       sas_device->starget = starget;
-               }
-
-               if (sas_device)
-                       sas_device_put(sas_device);
-
-               spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-       }
-
-       return 0;
-}
-
-/**
- * _scsih_slave_destroy - device destroy routine
- * @sdev: scsi device struct
- *
- * Returns nothing.
- */
-static void
-_scsih_slave_destroy(struct scsi_device *sdev)
-{
-       struct MPT2SAS_TARGET *sas_target_priv_data;
-       struct scsi_target *starget;
-       struct Scsi_Host *shost;
-       struct MPT2SAS_ADAPTER *ioc;
-       struct _sas_device *sas_device;
-       unsigned long flags;
-
-       if (!sdev->hostdata)
-               return;
-
-       starget = scsi_target(sdev);
-       sas_target_priv_data = starget->hostdata;
-       sas_target_priv_data->num_luns--;
-
-       shost = dev_to_shost(&starget->dev);
-       ioc = shost_priv(shost);
-
-       if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) {
-               spin_lock_irqsave(&ioc->sas_device_lock, flags);
-               sas_device = __mpt2sas_get_sdev_from_target(ioc,
-                               sas_target_priv_data);
-               if (sas_device && !sas_target_priv_data->num_luns)
-                       sas_device->starget = NULL;
-
-               if (sas_device)
-                       sas_device_put(sas_device);
-               spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-       }
-
-       kfree(sdev->hostdata);
-       sdev->hostdata = NULL;
-}
-
-/**
- * _scsih_display_sata_capabilities - sata capabilities
- * @ioc: per adapter object
- * @handle: device handle
- * @sdev: scsi device struct
- */
-static void
-_scsih_display_sata_capabilities(struct MPT2SAS_ADAPTER *ioc,
-       u16 handle, struct scsi_device *sdev)
-{
-       Mpi2ConfigReply_t mpi_reply;
-       Mpi2SasDevicePage0_t sas_device_pg0;
-       u32 ioc_status;
-       u16 flags;
-       u32 device_info;
-
-       if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
-           MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               return;
-       }
-
-       ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-           MPI2_IOCSTATUS_MASK;
-       if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               return;
-       }
-
-       flags = le16_to_cpu(sas_device_pg0.Flags);
-       device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
-
-       sdev_printk(KERN_INFO, sdev,
-           "atapi(%s), ncq(%s), asyn_notify(%s), smart(%s), fua(%s), "
-           "sw_preserve(%s)\n",
-           (device_info & MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE) ? "y" : "n",
-           (flags & MPI2_SAS_DEVICE0_FLAGS_SATA_NCQ_SUPPORTED) ? "y" : "n",
-           (flags & MPI2_SAS_DEVICE0_FLAGS_SATA_ASYNCHRONOUS_NOTIFY) ? "y" :
-           "n",
-           (flags & MPI2_SAS_DEVICE0_FLAGS_SATA_SMART_SUPPORTED) ? "y" : "n",
-           (flags & MPI2_SAS_DEVICE0_FLAGS_SATA_FUA_SUPPORTED) ? "y" : "n",
-           (flags & MPI2_SAS_DEVICE0_FLAGS_SATA_SW_PRESERVE) ? "y" : "n");
-}
-
-/**
- * _scsih_is_raid - return boolean indicating device is raid volume
- * @dev the device struct object
- */
-static int
-_scsih_is_raid(struct device *dev)
-{
-       struct scsi_device *sdev = to_scsi_device(dev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(sdev->host);
-
-       if (ioc->is_warpdrive)
-               return 0;
-       return (sdev->channel == RAID_CHANNEL) ? 1 : 0;
-}
-
-/**
- * _scsih_get_resync - get raid volume resync percent complete
- * @dev the device struct object
- */
-static void
-_scsih_get_resync(struct device *dev)
-{
-       struct scsi_device *sdev = to_scsi_device(dev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(sdev->host);
-       static struct _raid_device *raid_device;
-       unsigned long flags;
-       Mpi2RaidVolPage0_t vol_pg0;
-       Mpi2ConfigReply_t mpi_reply;
-       u32 volume_status_flags;
-       u8 percent_complete;
-       u16 handle;
-
-       percent_complete = 0;
-       handle = 0;
-       if (ioc->is_warpdrive)
-               goto out;
-
-       spin_lock_irqsave(&ioc->raid_device_lock, flags);
-       raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id,
-           sdev->channel);
-       if (raid_device) {
-               handle = raid_device->handle;
-               percent_complete = raid_device->percent_complete;
-       }
-       spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
-
-       if (!handle)
-               goto out;
-
-       if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0,
-            MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, handle,
-            sizeof(Mpi2RaidVolPage0_t))) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               percent_complete = 0;
-               goto out;
-       }
-
-       volume_status_flags = le32_to_cpu(vol_pg0.VolumeStatusFlags);
-       if (!(volume_status_flags &
-           MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS))
-               percent_complete = 0;
-
- out:
-       raid_set_resync(mpt2sas_raid_template, dev, percent_complete);
-}
-
-/**
- * _scsih_get_state - get raid volume level
- * @dev the device struct object
- */
-static void
-_scsih_get_state(struct device *dev)
-{
-       struct scsi_device *sdev = to_scsi_device(dev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(sdev->host);
-       static struct _raid_device *raid_device;
-       unsigned long flags;
-       Mpi2RaidVolPage0_t vol_pg0;
-       Mpi2ConfigReply_t mpi_reply;
-       u32 volstate;
-       enum raid_state state = RAID_STATE_UNKNOWN;
-       u16 handle = 0;
-
-       spin_lock_irqsave(&ioc->raid_device_lock, flags);
-       raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id,
-           sdev->channel);
-       if (raid_device)
-               handle = raid_device->handle;
-       spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
-
-       if (!raid_device)
-               goto out;
-
-       if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0,
-            MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, handle,
-            sizeof(Mpi2RaidVolPage0_t))) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               goto out;
-       }
-
-       volstate = le32_to_cpu(vol_pg0.VolumeStatusFlags);
-       if (volstate & MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) {
-               state = RAID_STATE_RESYNCING;
-               goto out;
-       }
-
-       switch (vol_pg0.VolumeState) {
-       case MPI2_RAID_VOL_STATE_OPTIMAL:
-       case MPI2_RAID_VOL_STATE_ONLINE:
-               state = RAID_STATE_ACTIVE;
-               break;
-       case  MPI2_RAID_VOL_STATE_DEGRADED:
-               state = RAID_STATE_DEGRADED;
-               break;
-       case MPI2_RAID_VOL_STATE_FAILED:
-       case MPI2_RAID_VOL_STATE_MISSING:
-               state = RAID_STATE_OFFLINE;
-               break;
-       }
- out:
-       raid_set_state(mpt2sas_raid_template, dev, state);
-}
-
-/**
- * _scsih_set_level - set raid level
- * @sdev: scsi device struct
- * @volume_type: volume type
- */
-static void
-_scsih_set_level(struct scsi_device *sdev, u8 volume_type)
-{
-       enum raid_level level = RAID_LEVEL_UNKNOWN;
-
-       switch (volume_type) {
-       case MPI2_RAID_VOL_TYPE_RAID0:
-               level = RAID_LEVEL_0;
-               break;
-       case MPI2_RAID_VOL_TYPE_RAID10:
-               level = RAID_LEVEL_10;
-               break;
-       case MPI2_RAID_VOL_TYPE_RAID1E:
-               level = RAID_LEVEL_1E;
-               break;
-       case MPI2_RAID_VOL_TYPE_RAID1:
-               level = RAID_LEVEL_1;
-               break;
-       }
-
-       raid_set_level(mpt2sas_raid_template, &sdev->sdev_gendev, level);
-}
-
-/**
- * _scsih_get_volume_capabilities - volume capabilities
- * @ioc: per adapter object
- * @sas_device: the raid_device object
- *
- * Returns 0 for success, else 1
- */
-static int
-_scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc,
-    struct _raid_device *raid_device)
-{
-       Mpi2RaidVolPage0_t *vol_pg0;
-       Mpi2RaidPhysDiskPage0_t pd_pg0;
-       Mpi2SasDevicePage0_t sas_device_pg0;
-       Mpi2ConfigReply_t mpi_reply;
-       u16 sz;
-       u8 num_pds;
-
-       if ((mpt2sas_config_get_number_pds(ioc, raid_device->handle,
-           &num_pds)) || !num_pds) {
-               dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
-                   "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__,
-                   __func__));
-               return 1;
-       }
-
-       raid_device->num_pds = num_pds;
-       sz = offsetof(Mpi2RaidVolPage0_t, PhysDisk) + (num_pds *
-           sizeof(Mpi2RaidVol0PhysDisk_t));
-       vol_pg0 = kzalloc(sz, GFP_KERNEL);
-       if (!vol_pg0) {
-               dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
-                   "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__,
-                   __func__));
-               return 1;
-       }
-
-       if ((mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, vol_pg0,
-            MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, sz))) {
-               dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
-                   "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__,
-                   __func__));
-               kfree(vol_pg0);
-               return 1;
-       }
-
-       raid_device->volume_type = vol_pg0->VolumeType;
-
-       /* figure out what the underlying devices are by
-        * obtaining the device_info bits for the 1st device
-        */
-       if (!(mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply,
-           &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_PHYSDISKNUM,
-           vol_pg0->PhysDisk[0].PhysDiskNum))) {
-               if (!(mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
-                   &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE,
-                   le16_to_cpu(pd_pg0.DevHandle)))) {
-                       raid_device->device_info =
-                           le32_to_cpu(sas_device_pg0.DeviceInfo);
-               }
-       }
-
-       kfree(vol_pg0);
-       return 0;
-}
-/**
- * _scsih_disable_ddio - Disable direct I/O for all the volumes
- * @ioc: per adapter object
- */
-static void
-_scsih_disable_ddio(struct MPT2SAS_ADAPTER *ioc)
-{
-       Mpi2RaidVolPage1_t vol_pg1;
-       Mpi2ConfigReply_t mpi_reply;
-       struct _raid_device *raid_device;
-       u16 handle;
-       u16 ioc_status;
-       unsigned long flags;
-
-       handle = 0xFFFF;
-       while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
-           &vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
-               ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-                   MPI2_IOCSTATUS_MASK;
-               if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
-                       break;
-               handle = le16_to_cpu(vol_pg1.DevHandle);
-               spin_lock_irqsave(&ioc->raid_device_lock, flags);
-               raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
-               if (raid_device)
-                       raid_device->direct_io_enabled = 0;
-               spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
-       }
-       return;
-}
-
-
-/**
- * _scsih_get_num_volumes - Get number of volumes in the ioc
- * @ioc: per adapter object
- */
-static u8
-_scsih_get_num_volumes(struct MPT2SAS_ADAPTER *ioc)
-{
-       Mpi2RaidVolPage1_t vol_pg1;
-       Mpi2ConfigReply_t mpi_reply;
-       u16 handle;
-       u8 vol_cnt = 0;
-       u16 ioc_status;
-
-       handle = 0xFFFF;
-       while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
-           &vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
-               ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-                   MPI2_IOCSTATUS_MASK;
-               if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
-                       break;
-               vol_cnt++;
-               handle = le16_to_cpu(vol_pg1.DevHandle);
-       }
-       return vol_cnt;
-}
-
-
-/**
- * _scsih_init_warpdrive_properties - Set properties for warpdrive direct I/O.
- * @ioc: per adapter object
- * @raid_device: the raid_device object
- */
-static void
-_scsih_init_warpdrive_properties(struct MPT2SAS_ADAPTER *ioc,
-       struct _raid_device *raid_device)
-{
-       Mpi2RaidVolPage0_t *vol_pg0;
-       Mpi2RaidPhysDiskPage0_t pd_pg0;
-       Mpi2ConfigReply_t mpi_reply;
-       u16 sz;
-       u8 num_pds, count;
-       unsigned long stripe_sz, block_sz;
-       u8 stripe_exp, block_exp;
-       u64 dev_max_lba;
-
-       if (!ioc->is_warpdrive)
-               return;
-
-       if (ioc->mfg_pg10_hide_flag ==  MFG_PAGE10_EXPOSE_ALL_DISKS) {
-               printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
-                   "globally as drives are exposed\n", ioc->name);
-               return;
-       }
-       if (_scsih_get_num_volumes(ioc) > 1) {
-               _scsih_disable_ddio(ioc);
-               printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
-                   "globally as number of drives > 1\n", ioc->name);
-               return;
-       }
-       if ((mpt2sas_config_get_number_pds(ioc, raid_device->handle,
-           &num_pds)) || !num_pds) {
-               printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
-                   "Failure in computing number of drives\n", ioc->name);
-               return;
-       }
-
-       sz = offsetof(Mpi2RaidVolPage0_t, PhysDisk) + (num_pds *
-           sizeof(Mpi2RaidVol0PhysDisk_t));
-       vol_pg0 = kzalloc(sz, GFP_KERNEL);
-       if (!vol_pg0) {
-               printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
-                   "Memory allocation failure for RVPG0\n", ioc->name);
-               return;
-       }
-
-       if ((mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, vol_pg0,
-            MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, sz))) {
-               printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
-                   "Failure in retrieving RVPG0\n", ioc->name);
-               kfree(vol_pg0);
-               return;
-       }
-
-       /*
-        * WARPDRIVE:If number of physical disks in a volume exceeds the max pds
-        * assumed for WARPDRIVE, disable direct I/O
-        */
-       if (num_pds > MPT_MAX_WARPDRIVE_PDS) {
-               printk(MPT2SAS_WARN_FMT "WarpDrive : Direct IO is disabled "
-                   "for the drive with handle(0x%04x): num_mem=%d, "
-                   "max_mem_allowed=%d\n", ioc->name, raid_device->handle,
-                   num_pds, MPT_MAX_WARPDRIVE_PDS);
-               kfree(vol_pg0);
-               return;
-       }
-       for (count = 0; count < num_pds; count++) {
-               if (mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply,
-                   &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_PHYSDISKNUM,
-                   vol_pg0->PhysDisk[count].PhysDiskNum) ||
-                    le16_to_cpu(pd_pg0.DevHandle) ==
-                   MPT2SAS_INVALID_DEVICE_HANDLE) {
-                       printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is "
-                           "disabled for the drive with handle(0x%04x) member"
-                           "handle retrieval failed for member number=%d\n",
-                           ioc->name, raid_device->handle,
-                           vol_pg0->PhysDisk[count].PhysDiskNum);
-                       goto out_error;
-               }
-               /* Disable direct I/O if member drive lba exceeds 4 bytes */
-               dev_max_lba = le64_to_cpu(pd_pg0.DeviceMaxLBA);
-               if (dev_max_lba >> 32) {
-                       printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is "
-                           "disabled for the drive with handle(0x%04x) member"
-                           "handle (0x%04x) unsupported max lba 0x%016llx\n",
-                           ioc->name, raid_device->handle,
-                           le16_to_cpu(pd_pg0.DevHandle),
-                           (unsigned long long)dev_max_lba);
-                       goto out_error;
-               }
-
-               raid_device->pd_handle[count] = le16_to_cpu(pd_pg0.DevHandle);
-       }
-
-       /*
-        * Assumption for WD: Direct I/O is not supported if the volume is
-        * not RAID0
-        */
-       if (raid_device->volume_type != MPI2_RAID_VOL_TYPE_RAID0) {
-               printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
-                   "for the drive with handle(0x%04x): type=%d, "
-                   "s_sz=%uK, blk_size=%u\n", ioc->name,
-                   raid_device->handle, raid_device->volume_type,
-                   (le32_to_cpu(vol_pg0->StripeSize) *
-                   le16_to_cpu(vol_pg0->BlockSize)) / 1024,
-                   le16_to_cpu(vol_pg0->BlockSize));
-               goto out_error;
-       }
-
-       stripe_sz = le32_to_cpu(vol_pg0->StripeSize);
-       stripe_exp = find_first_bit(&stripe_sz, 32);
-       if (stripe_exp == 32) {
-               printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
-               "for the drive with handle(0x%04x) invalid stripe sz %uK\n",
-                   ioc->name, raid_device->handle,
-                   (le32_to_cpu(vol_pg0->StripeSize) *
-                   le16_to_cpu(vol_pg0->BlockSize)) / 1024);
-               goto out_error;
-       }
-       raid_device->stripe_exponent = stripe_exp;
-       block_sz = le16_to_cpu(vol_pg0->BlockSize);
-       block_exp = find_first_bit(&block_sz, 16);
-       if (block_exp == 16) {
-               printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
-                   "for the drive with handle(0x%04x) invalid block sz %u\n",
-                   ioc->name, raid_device->handle,
-                   le16_to_cpu(vol_pg0->BlockSize));
-               goto out_error;
-       }
-       raid_device->block_exponent = block_exp;
-       raid_device->direct_io_enabled = 1;
-
-       printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is Enabled for the drive"
-           " with handle(0x%04x)\n", ioc->name, raid_device->handle);
-       /*
-        * WARPDRIVE: Though the following fields are not used for direct IO,
-        * stored for future purpose:
-        */
-       raid_device->max_lba = le64_to_cpu(vol_pg0->MaxLBA);
-       raid_device->stripe_sz = le32_to_cpu(vol_pg0->StripeSize);
-       raid_device->block_sz = le16_to_cpu(vol_pg0->BlockSize);
-
-
-       kfree(vol_pg0);
-       return;
-
-out_error:
-       raid_device->direct_io_enabled = 0;
-       for (count = 0; count < num_pds; count++)
-               raid_device->pd_handle[count] = 0;
-       kfree(vol_pg0);
-       return;
-}
-
-/**
- * _scsih_enable_tlr - setting TLR flags
- * @ioc: per adapter object
- * @sdev: scsi device struct
- *
- * Enabling Transaction Layer Retries for tape devices when
- * vpd page 0x90 is present
- *
- */
-static void
-_scsih_enable_tlr(struct MPT2SAS_ADAPTER *ioc, struct scsi_device *sdev)
-{
-       /* only for TAPE */
-       if (sdev->type != TYPE_TAPE)
-               return;
-
-       if (!(ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR))
-               return;
-
-       sas_enable_tlr(sdev);
-       sdev_printk(KERN_INFO, sdev, "TLR %s\n",
-           sas_is_tlr_enabled(sdev) ? "Enabled" : "Disabled");
-       return;
-
-}
-
-/**
- * _scsih_slave_configure - device configure routine.
- * @sdev: scsi device struct
- *
- * Returns 0 if ok. Any other return is assumed to be an error and
- * the device is ignored.
- */
-static int
-_scsih_slave_configure(struct scsi_device *sdev)
-{
-       struct Scsi_Host *shost = sdev->host;
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-       struct MPT2SAS_DEVICE *sas_device_priv_data;
-       struct MPT2SAS_TARGET *sas_target_priv_data;
-       struct _sas_device *sas_device;
-       struct _raid_device *raid_device;
-       unsigned long flags;
-       int qdepth;
-       u8 ssp_target = 0;
-       char *ds = "";
-       char *r_level = "";
-       u16 handle, volume_handle = 0;
-       u64 volume_wwid = 0;
-
-       qdepth = 1;
-       sas_device_priv_data = sdev->hostdata;
-       sas_device_priv_data->configured_lun = 1;
-       sas_device_priv_data->flags &= ~MPT_DEVICE_FLAGS_INIT;
-       sas_target_priv_data = sas_device_priv_data->sas_target;
-       handle = sas_target_priv_data->handle;
-
-       /* raid volume handling */
-       if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME) {
-
-               spin_lock_irqsave(&ioc->raid_device_lock, flags);
-               raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
-               spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
-               if (!raid_device) {
-                       dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
-                           "failure at %s:%d/%s()!\n", ioc->name, __FILE__,
-                           __LINE__, __func__));
-                       return 1;
-               }
-
-               if (_scsih_get_volume_capabilities(ioc, raid_device)) {
-                       dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
-                           "failure at %s:%d/%s()!\n", ioc->name, __FILE__,
-                           __LINE__, __func__));
-                       return 1;
-               }
-               /*
-                * WARPDRIVE: Initialize the required data for Direct IO
-                */
-               _scsih_init_warpdrive_properties(ioc, raid_device);
-
-               /* RAID Queue Depth Support
-                * IS volume = underlying qdepth of drive type, either
-                *    MPT2SAS_SAS_QUEUE_DEPTH or MPT2SAS_SATA_QUEUE_DEPTH
-                * IM/IME/R10 = 128 (MPT2SAS_RAID_QUEUE_DEPTH)
-                */
-               if (raid_device->device_info &
-                   MPI2_SAS_DEVICE_INFO_SSP_TARGET) {
-                       qdepth = MPT2SAS_SAS_QUEUE_DEPTH;
-                       ds = "SSP";
-               } else {
-                       qdepth = MPT2SAS_SATA_QUEUE_DEPTH;
-                        if (raid_device->device_info &
-                           MPI2_SAS_DEVICE_INFO_SATA_DEVICE)
-                               ds = "SATA";
-                       else
-                               ds = "STP";
-               }
-
-               switch (raid_device->volume_type) {
-               case MPI2_RAID_VOL_TYPE_RAID0:
-                       r_level = "RAID0";
-                       break;
-               case MPI2_RAID_VOL_TYPE_RAID1E:
-                       qdepth = MPT2SAS_RAID_QUEUE_DEPTH;
-                       if (ioc->manu_pg10.OEMIdentifier &&
-                           (le32_to_cpu(ioc->manu_pg10.GenericFlags0) &
-                           MFG10_GF0_R10_DISPLAY) &&
-                           !(raid_device->num_pds % 2))
-                               r_level = "RAID10";
-                       else
-                               r_level = "RAID1E";
-                       break;
-               case MPI2_RAID_VOL_TYPE_RAID1:
-                       qdepth = MPT2SAS_RAID_QUEUE_DEPTH;
-                       r_level = "RAID1";
-                       break;
-               case MPI2_RAID_VOL_TYPE_RAID10:
-                       qdepth = MPT2SAS_RAID_QUEUE_DEPTH;
-                       r_level = "RAID10";
-                       break;
-               case MPI2_RAID_VOL_TYPE_UNKNOWN:
-               default:
-                       qdepth = MPT2SAS_RAID_QUEUE_DEPTH;
-                       r_level = "RAIDX";
-                       break;
-               }
-
-               if (!ioc->hide_ir_msg)
-                       sdev_printk(KERN_INFO, sdev, "%s: handle(0x%04x), "
-                           "wwid(0x%016llx), pd_count(%d), type(%s)\n",
-                           r_level, raid_device->handle,
-                           (unsigned long long)raid_device->wwid,
-                           raid_device->num_pds, ds);
-               _scsih_change_queue_depth(sdev, qdepth);
-               /* raid transport support */
-               if (!ioc->is_warpdrive)
-                       _scsih_set_level(sdev, raid_device->volume_type);
-               return 0;
-       }
-
-       /* non-raid handling */
-       if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
-               if (mpt2sas_config_get_volume_handle(ioc, handle,
-                   &volume_handle)) {
-                       dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
-                           "failure at %s:%d/%s()!\n", ioc->name,
-                           __FILE__, __LINE__, __func__));
-                       return 1;
-               }
-               if (volume_handle && mpt2sas_config_get_volume_wwid(ioc,
-                   volume_handle, &volume_wwid)) {
-                       dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
-                           "failure at %s:%d/%s()!\n", ioc->name,
-                           __FILE__, __LINE__, __func__));
-                       return 1;
-               }
-       }
-
-       spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       sas_device = __mpt2sas_get_sdev_by_addr(ioc,
-          sas_device_priv_data->sas_target->sas_address);
-       if (!sas_device) {
-               spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-               dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
-                       "failure at %s:%d/%s()!\n", ioc->name, __FILE__,
-                       __LINE__, __func__));
-               return 1;
-       }
-       sas_device->volume_handle = volume_handle;
-       sas_device->volume_wwid = volume_wwid;
-       if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET) {
-               qdepth = MPT2SAS_SAS_QUEUE_DEPTH;
-               ssp_target = 1;
-               ds = "SSP";
-       } else {
-               qdepth = MPT2SAS_SATA_QUEUE_DEPTH;
-               if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_STP_TARGET)
-                       ds = "STP";
-               else if (sas_device->device_info &
-                   MPI2_SAS_DEVICE_INFO_SATA_DEVICE)
-                       ds = "SATA";
-       }
-       sdev_printk(KERN_INFO, sdev, "%s: handle(0x%04x), "
-           "sas_addr(0x%016llx), phy(%d), device_name(0x%016llx)\n",
-           ds, sas_device->handle,
-           (unsigned long long)sas_device->sas_address,
-           sas_device->phy,
-           (unsigned long long)sas_device->device_name);
-       sdev_printk(KERN_INFO, sdev, "%s: "
-           "enclosure_logical_id(0x%016llx), slot(%d)\n", ds,
-           (unsigned long long) sas_device->enclosure_logical_id,
-           sas_device->slot);
-
-       sas_device_put(sas_device);
-       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-       if (!ssp_target)
-               _scsih_display_sata_capabilities(ioc, handle, sdev);
-
-       _scsih_change_queue_depth(sdev, qdepth);
-
-       if (ssp_target) {
-               sas_read_port_mode_page(sdev);
-               _scsih_enable_tlr(ioc, sdev);
-       }
-
-       return 0;
-}
-
-/**
- * _scsih_bios_param - fetch head, sector, cylinder info for a disk
- * @sdev: scsi device struct
- * @bdev: pointer to block device context
- * @capacity: device size (in 512 byte sectors)
- * @params: three element array to place output:
- *              params[0] number of heads (max 255)
- *              params[1] number of sectors (max 63)
- *              params[2] number of cylinders
- *
- * Return nothing.
- */
-static int
-_scsih_bios_param(struct scsi_device *sdev, struct block_device *bdev,
-    sector_t capacity, int params[])
-{
-       int             heads;
-       int             sectors;
-       sector_t        cylinders;
-       ulong           dummy;
-
-       heads = 64;
-       sectors = 32;
-
-       dummy = heads * sectors;
-       cylinders = capacity;
-       sector_div(cylinders, dummy);
-
-       /*
-        * Handle extended translation size for logical drives
-        * > 1Gb
-        */
-       if ((ulong)capacity >= 0x200000) {
-               heads = 255;
-               sectors = 63;
-               dummy = heads * sectors;
-               cylinders = capacity;
-               sector_div(cylinders, dummy);
-       }
-
-       /* return result */
-       params[0] = heads;
-       params[1] = sectors;
-       params[2] = cylinders;
-
-       return 0;
-}
-
-/**
- * _scsih_response_code - translation of device response code
- * @ioc: per adapter object
- * @response_code: response code returned by the device
- *
- * Return nothing.
- */
-static void
-_scsih_response_code(struct MPT2SAS_ADAPTER *ioc, u8 response_code)
-{
-       char *desc;
-
-       switch (response_code) {
-       case MPI2_SCSITASKMGMT_RSP_TM_COMPLETE:
-               desc = "task management request completed";
-               break;
-       case MPI2_SCSITASKMGMT_RSP_INVALID_FRAME:
-               desc = "invalid frame";
-               break;
-       case MPI2_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
-               desc = "task management request not supported";
-               break;
-       case MPI2_SCSITASKMGMT_RSP_TM_FAILED:
-               desc = "task management request failed";
-               break;
-       case MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED:
-               desc = "task management request succeeded";
-               break;
-       case MPI2_SCSITASKMGMT_RSP_TM_INVALID_LUN:
-               desc = "invalid lun";
-               break;
-       case 0xA:
-               desc = "overlapped tag attempted";
-               break;
-       case MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
-               desc = "task queued, however not sent to target";
-               break;
-       default:
-               desc = "unknown";
-               break;
-       }
-       printk(MPT2SAS_WARN_FMT "response_code(0x%01x): %s\n",
-               ioc->name, response_code, desc);
-}
-
-/**
- * _scsih_tm_done - tm completion routine
- * @ioc: per adapter object
- * @smid: system request message index
- * @msix_index: MSIX table index supplied by the OS
- * @reply: reply message frame(lower 32bit addr)
- * Context: none.
- *
- * The callback handler when using scsih_issue_tm.
- *
- * Return 1 meaning mf should be freed from _base_interrupt
- *        0 means the mf is freed from this function.
- */
-static u8
-_scsih_tm_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
-{
-       MPI2DefaultReply_t *mpi_reply;
-
-       if (ioc->tm_cmds.status == MPT2_CMD_NOT_USED)
-               return 1;
-       if (ioc->tm_cmds.smid != smid)
-               return 1;
-       mpt2sas_base_flush_reply_queues(ioc);
-       ioc->tm_cmds.status |= MPT2_CMD_COMPLETE;
-       mpi_reply =  mpt2sas_base_get_reply_virt_addr(ioc, reply);
-       if (mpi_reply) {
-               memcpy(ioc->tm_cmds.reply, mpi_reply, mpi_reply->MsgLength*4);
-               ioc->tm_cmds.status |= MPT2_CMD_REPLY_VALID;
-       }
-       ioc->tm_cmds.status &= ~MPT2_CMD_PENDING;
-       complete(&ioc->tm_cmds.done);
-       return 1;
-}
-
-/**
- * mpt2sas_scsih_set_tm_flag - set per target tm_busy
- * @ioc: per adapter object
- * @handle: device handle
- *
- * During taskmangement request, we need to freeze the device queue.
- */
-void
-mpt2sas_scsih_set_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle)
-{
-       struct MPT2SAS_DEVICE *sas_device_priv_data;
-       struct scsi_device *sdev;
-       u8 skip = 0;
-
-       shost_for_each_device(sdev, ioc->shost) {
-               if (skip)
-                       continue;
-               sas_device_priv_data = sdev->hostdata;
-               if (!sas_device_priv_data)
-                       continue;
-               if (sas_device_priv_data->sas_target->handle == handle) {
-                       sas_device_priv_data->sas_target->tm_busy = 1;
-                       skip = 1;
-                       ioc->ignore_loginfos = 1;
-               }
-       }
-}
-
-/**
- * mpt2sas_scsih_clear_tm_flag - clear per target tm_busy
- * @ioc: per adapter object
- * @handle: device handle
- *
- * During taskmangement request, we need to freeze the device queue.
- */
-void
-mpt2sas_scsih_clear_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle)
-{
-       struct MPT2SAS_DEVICE *sas_device_priv_data;
-       struct scsi_device *sdev;
-       u8 skip = 0;
-
-       shost_for_each_device(sdev, ioc->shost) {
-               if (skip)
-                       continue;
-               sas_device_priv_data = sdev->hostdata;
-               if (!sas_device_priv_data)
-                       continue;
-               if (sas_device_priv_data->sas_target->handle == handle) {
-                       sas_device_priv_data->sas_target->tm_busy = 0;
-                       skip = 1;
-                       ioc->ignore_loginfos = 0;
-               }
-       }
-}
-
-
-/**
- * mpt2sas_scsih_issue_tm - main routine for sending tm requests
- * @ioc: per adapter struct
- * @device_handle: device handle
- * @channel: the channel assigned by the OS
- * @id: the id assigned by the OS
- * @lun: lun number
- * @type: MPI2_SCSITASKMGMT_TASKTYPE__XXX (defined in mpi2_init.h)
- * @smid_task: smid assigned to the task
- * @timeout: timeout in seconds
- * @m_type: TM_MUTEX_ON or TM_MUTEX_OFF
- * Context: user
- *
- * A generic API for sending task management requests to firmware.
- *
- * The callback index is set inside `ioc->tm_cb_idx`.
- *
- * Return SUCCESS or FAILED.
- */
-int
-mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint channel,
-    uint id, uint lun, u8 type, u16 smid_task, ulong timeout,
-       enum mutex_type m_type)
-{
-       Mpi2SCSITaskManagementRequest_t *mpi_request;
-       Mpi2SCSITaskManagementReply_t *mpi_reply;
-       u16 smid = 0;
-       u32 ioc_state;
-       unsigned long timeleft;
-       struct scsiio_tracker *scsi_lookup = NULL;
-       int rc;
-
-       if (m_type == TM_MUTEX_ON)
-               mutex_lock(&ioc->tm_cmds.mutex);
-       if (ioc->tm_cmds.status != MPT2_CMD_NOT_USED) {
-               printk(MPT2SAS_INFO_FMT "%s: tm_cmd busy!!!\n",
-                   __func__, ioc->name);
-               rc = FAILED;
-               goto err_out;
-       }
-
-       if (ioc->shost_recovery || ioc->remove_host ||
-           ioc->pci_error_recovery) {
-               printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
-                   __func__, ioc->name);
-               rc = FAILED;
-               goto err_out;
-       }
-
-       ioc_state = mpt2sas_base_get_iocstate(ioc, 0);
-       if (ioc_state & MPI2_DOORBELL_USED) {
-               dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "unexpected doorbell "
-                   "active!\n", ioc->name));
-               rc = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
-                   FORCE_BIG_HAMMER);
-               rc = (!rc) ? SUCCESS : FAILED;
-               goto err_out;
-       }
-
-       if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) {
-               mpt2sas_base_fault_info(ioc, ioc_state &
-                   MPI2_DOORBELL_DATA_MASK);
-               rc = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
-                   FORCE_BIG_HAMMER);
-               rc = (!rc) ? SUCCESS : FAILED;
-               goto err_out;
-       }
-
-       smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_cb_idx);
-       if (!smid) {
-               printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
-                   ioc->name, __func__);
-               rc = FAILED;
-               goto err_out;
-       }
-
-       if (type == MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
-               scsi_lookup = &ioc->scsi_lookup[smid_task - 1];
-
-       dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "sending tm: handle(0x%04x),"
-           " task_type(0x%02x), smid(%d)\n", ioc->name, handle, type,
-           smid_task));
-       ioc->tm_cmds.status = MPT2_CMD_PENDING;
-       mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
-       ioc->tm_cmds.smid = smid;
-       memset(mpi_request, 0, sizeof(Mpi2SCSITaskManagementRequest_t));
-       memset(ioc->tm_cmds.reply, 0, sizeof(Mpi2SCSITaskManagementReply_t));
-       mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
-       mpi_request->DevHandle = cpu_to_le16(handle);
-       mpi_request->TaskType = type;
-       mpi_request->TaskMID = cpu_to_le16(smid_task);
-       int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN);
-       mpt2sas_scsih_set_tm_flag(ioc, handle);
-       init_completion(&ioc->tm_cmds.done);
-       mpt2sas_base_put_smid_hi_priority(ioc, smid);
-       timeleft = wait_for_completion_timeout(&ioc->tm_cmds.done, timeout*HZ);
-       if (!(ioc->tm_cmds.status & MPT2_CMD_COMPLETE)) {
-               printk(MPT2SAS_ERR_FMT "%s: timeout\n",
-                   ioc->name, __func__);
-               _debug_dump_mf(mpi_request,
-                   sizeof(Mpi2SCSITaskManagementRequest_t)/4);
-               if (!(ioc->tm_cmds.status & MPT2_CMD_RESET)) {
-                       rc = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
-                           FORCE_BIG_HAMMER);
-                       rc = (!rc) ? SUCCESS : FAILED;
-                       ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
-                       mpt2sas_scsih_clear_tm_flag(ioc, handle);
-                       goto err_out;
-               }
-       }
-
-       if (ioc->tm_cmds.status & MPT2_CMD_REPLY_VALID) {
-               mpi_reply = ioc->tm_cmds.reply;
-               dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "complete tm: "
-                   "ioc_status(0x%04x), loginfo(0x%08x), term_count(0x%08x)\n",
-                   ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
-                   le32_to_cpu(mpi_reply->IOCLogInfo),
-                   le32_to_cpu(mpi_reply->TerminationCount)));
-               if (ioc->logging_level & MPT_DEBUG_TM) {
-                       _scsih_response_code(ioc, mpi_reply->ResponseCode);
-                       if (mpi_reply->IOCStatus)
-                               _debug_dump_mf(mpi_request,
-                                   sizeof(Mpi2SCSITaskManagementRequest_t)/4);
-               }
-       }
-
-       switch (type) {
-       case MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK:
-               rc = SUCCESS;
-               if (scsi_lookup->scmd == NULL)
-                       break;
-               rc = FAILED;
-               break;
-
-       case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
-               if (_scsih_scsi_lookup_find_by_target(ioc, id, channel))
-                       rc = FAILED;
-               else
-                       rc = SUCCESS;
-               break;
-
-       case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
-       case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
-               if (_scsih_scsi_lookup_find_by_lun(ioc, id, lun, channel))
-                       rc = FAILED;
-               else
-                       rc = SUCCESS;
-               break;
-       case MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK:
-               rc = SUCCESS;
-               break;
-       default:
-               rc = FAILED;
-               break;
-       }
-
-       mpt2sas_scsih_clear_tm_flag(ioc, handle);
-       ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
-       if (m_type == TM_MUTEX_ON)
-               mutex_unlock(&ioc->tm_cmds.mutex);
-
-       return rc;
-
- err_out:
-       if (m_type == TM_MUTEX_ON)
-               mutex_unlock(&ioc->tm_cmds.mutex);
-       return rc;
-}
-
-/**
- * _scsih_tm_display_info - displays info about the device
- * @ioc: per adapter struct
- * @scmd: pointer to scsi command object
- *
- * Called by task management callback handlers.
- */
-static void
-_scsih_tm_display_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd)
-{
-       struct scsi_target *starget = scmd->device->sdev_target;
-       struct MPT2SAS_TARGET *priv_target = starget->hostdata;
-       struct _sas_device *sas_device = NULL;
-       unsigned long flags;
-       char *device_str = NULL;
-
-       if (!priv_target)
-               return;
-       if (ioc->hide_ir_msg)
-               device_str = "WarpDrive";
-       else
-               device_str = "volume";
-
-       scsi_print_command(scmd);
-       if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) {
-               starget_printk(KERN_INFO, starget, "%s handle(0x%04x), "
-                   "%s wwid(0x%016llx)\n", device_str, priv_target->handle,
-                   device_str, (unsigned long long)priv_target->sas_address);
-       } else {
-               spin_lock_irqsave(&ioc->sas_device_lock, flags);
-               sas_device = __mpt2sas_get_sdev_from_target(ioc, priv_target);
-               if (sas_device) {
-                       if (priv_target->flags &
-                           MPT_TARGET_FLAGS_RAID_COMPONENT) {
-                               starget_printk(KERN_INFO, starget,
-                                   "volume handle(0x%04x), "
-                                   "volume wwid(0x%016llx)\n",
-                                   sas_device->volume_handle,
-                                  (unsigned long long)sas_device->volume_wwid);
-                       }
-                       starget_printk(KERN_INFO, starget,
-                           "handle(0x%04x), sas_address(0x%016llx), phy(%d)\n",
-                           sas_device->handle,
-                           (unsigned long long)sas_device->sas_address,
-                           sas_device->phy);
-                       starget_printk(KERN_INFO, starget,
-                           "enclosure_logical_id(0x%016llx), slot(%d)\n",
-                          (unsigned long long)sas_device->enclosure_logical_id,
-                           sas_device->slot);
-
-                       sas_device_put(sas_device);
-               }
-               spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-       }
-}
-
-/**
- * _scsih_abort - eh threads main abort routine
- * @scmd: pointer to scsi command object
- *
- * Returns SUCCESS if command aborted else FAILED
- */
-static int
-_scsih_abort(struct scsi_cmnd *scmd)
-{
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
-       struct MPT2SAS_DEVICE *sas_device_priv_data;
-       u16 smid;
-       u16 handle;
-       int r;
-
-       sdev_printk(KERN_INFO, scmd->device, "attempting task abort! "
-           "scmd(%p)\n", scmd);
-       _scsih_tm_display_info(ioc, scmd);
-
-       sas_device_priv_data = scmd->device->hostdata;
-       if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
-               sdev_printk(KERN_INFO, scmd->device, "device been deleted! "
-                   "scmd(%p)\n", scmd);
-               scmd->result = DID_NO_CONNECT << 16;
-               scmd->scsi_done(scmd);
-               r = SUCCESS;
-               goto out;
-       }
-
-       /* search for the command */
-       smid = _scsih_scsi_lookup_find_by_scmd(ioc, scmd);
-       if (!smid) {
-               scmd->result = DID_RESET << 16;
-               r = SUCCESS;
-               goto out;
-       }
-
-       /* for hidden raid components and volumes this is not supported */
-       if (sas_device_priv_data->sas_target->flags &
-           MPT_TARGET_FLAGS_RAID_COMPONENT ||
-           sas_device_priv_data->sas_target->flags & MPT_TARGET_FLAGS_VOLUME) {
-               scmd->result = DID_RESET << 16;
-               r = FAILED;
-               goto out;
-       }
-
-       mpt2sas_halt_firmware(ioc);
-
-       handle = sas_device_priv_data->sas_target->handle;
-       r = mpt2sas_scsih_issue_tm(ioc, handle, scmd->device->channel,
-           scmd->device->id, scmd->device->lun,
-           MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30, TM_MUTEX_ON);
-
- out:
-       sdev_printk(KERN_INFO, scmd->device, "task abort: %s scmd(%p)\n",
-           ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
-       return r;
-}
-
-/**
- * _scsih_dev_reset - eh threads main device reset routine
- * @scmd: pointer to scsi command object
- *
- * Returns SUCCESS if command aborted else FAILED
- */
-static int
-_scsih_dev_reset(struct scsi_cmnd *scmd)
-{
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
-       struct MPT2SAS_DEVICE *sas_device_priv_data;
-       struct _sas_device *sas_device = NULL;
-       u16     handle;
-       int r;
-
-       struct scsi_target *starget = scmd->device->sdev_target;
-       struct MPT2SAS_TARGET *target_priv_data = starget->hostdata;
-
-       starget_printk(KERN_INFO, starget, "attempting device reset! "
-           "scmd(%p)\n", scmd);
-       _scsih_tm_display_info(ioc, scmd);
-
-       sas_device_priv_data = scmd->device->hostdata;
-       if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
-               starget_printk(KERN_INFO, starget, "device been deleted! "
-                   "scmd(%p)\n", scmd);
-               scmd->result = DID_NO_CONNECT << 16;
-               scmd->scsi_done(scmd);
-               r = SUCCESS;
-               goto out;
-       }
-
-       /* for hidden raid components obtain the volume_handle */
-       handle = 0;
-       if (sas_device_priv_data->sas_target->flags &
-           MPT_TARGET_FLAGS_RAID_COMPONENT) {
-               sas_device = mpt2sas_get_sdev_from_target(ioc,
-                               target_priv_data);
-               if (sas_device)
-                       handle = sas_device->volume_handle;
-       } else
-               handle = sas_device_priv_data->sas_target->handle;
-
-       if (!handle) {
-               scmd->result = DID_RESET << 16;
-               r = FAILED;
-               goto out;
-       }
-
-       r = mpt2sas_scsih_issue_tm(ioc, handle, scmd->device->channel,
-           scmd->device->id, scmd->device->lun,
-           MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET, 0, 30, TM_MUTEX_ON);
-
- out:
-       sdev_printk(KERN_INFO, scmd->device, "device reset: %s scmd(%p)\n",
-           ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
-
-       if (sas_device)
-               sas_device_put(sas_device);
-
-       return r;
-}
-
-/**
- * _scsih_target_reset - eh threads main target reset routine
- * @scmd: pointer to scsi command object
- *
- * Returns SUCCESS if command aborted else FAILED
- */
-static int
-_scsih_target_reset(struct scsi_cmnd *scmd)
-{
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
-       struct MPT2SAS_DEVICE *sas_device_priv_data;
-       struct _sas_device *sas_device = NULL;
-       u16     handle;
-       int r;
-       struct scsi_target *starget = scmd->device->sdev_target;
-       struct MPT2SAS_TARGET *target_priv_data = starget->hostdata;
-
-       starget_printk(KERN_INFO, starget, "attempting target reset! "
-           "scmd(%p)\n", scmd);
-       _scsih_tm_display_info(ioc, scmd);
-
-       sas_device_priv_data = scmd->device->hostdata;
-       if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
-               starget_printk(KERN_INFO, starget, "target been deleted! "
-                   "scmd(%p)\n", scmd);
-               scmd->result = DID_NO_CONNECT << 16;
-               scmd->scsi_done(scmd);
-               r = SUCCESS;
-               goto out;
-       }
-
-       /* for hidden raid components obtain the volume_handle */
-       handle = 0;
-       if (sas_device_priv_data->sas_target->flags &
-           MPT_TARGET_FLAGS_RAID_COMPONENT) {
-               sas_device = mpt2sas_get_sdev_from_target(ioc,
-                               target_priv_data);
-               if (sas_device)
-                       handle = sas_device->volume_handle;
-       } else
-               handle = sas_device_priv_data->sas_target->handle;
-
-       if (!handle) {
-               scmd->result = DID_RESET << 16;
-               r = FAILED;
-               goto out;
-       }
-
-       r = mpt2sas_scsih_issue_tm(ioc, handle, scmd->device->channel,
-           scmd->device->id, 0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0,
-           30, TM_MUTEX_ON);
-
- out:
-       starget_printk(KERN_INFO, starget, "target reset: %s scmd(%p)\n",
-           ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
-
-       if (sas_device)
-               sas_device_put(sas_device);
-
-       return r;
-}
-
-/**
- * _scsih_host_reset - eh threads main host reset routine
- * @scmd: pointer to scsi command object
- *
- * Returns SUCCESS if command aborted else FAILED
- */
-static int
-_scsih_host_reset(struct scsi_cmnd *scmd)
-{
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
-       int r, retval;
-
-       printk(MPT2SAS_INFO_FMT "attempting host reset! scmd(%p)\n",
-           ioc->name, scmd);
-       scsi_print_command(scmd);
-
-       if (ioc->is_driver_loading) {
-               printk(MPT2SAS_INFO_FMT "Blocking the host reset\n",
-                                                         ioc->name);
-               r = FAILED;
-               goto out;
-       }
-
-       retval = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
-           FORCE_BIG_HAMMER);
-       r = (retval < 0) ? FAILED : SUCCESS;
-
- out:
-       printk(MPT2SAS_INFO_FMT "host reset: %s scmd(%p)\n",
-           ioc->name, ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
-
-       return r;
-}
-
-/**
- * _scsih_fw_event_add - insert and queue up fw_event
- * @ioc: per adapter object
- * @fw_event: object describing the event
- * Context: This function will acquire ioc->fw_event_lock.
- *
- * This adds the firmware event object into link list, then queues it up to
- * be processed from user context.
- *
- * Return nothing.
- */
-static void
-_scsih_fw_event_add(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work *fw_event)
-{
-       unsigned long flags;
-
-       if (ioc->firmware_event_thread == NULL)
-               return;
-
-       spin_lock_irqsave(&ioc->fw_event_lock, flags);
-       fw_event_work_get(fw_event);
-       list_add_tail(&fw_event->list, &ioc->fw_event_list);
-       INIT_DELAYED_WORK(&fw_event->delayed_work, _firmware_event_work);
-       fw_event_work_get(fw_event);
-       queue_delayed_work(ioc->firmware_event_thread,
-           &fw_event->delayed_work, 0);
-       spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
-}
-
-/**
- * _scsih_fw_event_del_from_list - delete fw_event from the list
- * @ioc: per adapter object
- * @fw_event: object describing the event
- * Context: This function will acquire ioc->fw_event_lock.
- *
- * If the fw_event is on the fw_event_list, remove it and do a put.
- *
- * Return nothing.
- */
-static void
-_scsih_fw_event_del_from_list(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work
-    *fw_event)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&ioc->fw_event_lock, flags);
-       if (!list_empty(&fw_event->list)) {
-               list_del_init(&fw_event->list);
-               fw_event_work_put(fw_event);
-       }
-       spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
-}
-
-/**
- * _scsih_error_recovery_delete_devices - remove devices not responding
- * @ioc: per adapter object
- *
- * Return nothing.
- */
-static void
-_scsih_error_recovery_delete_devices(struct MPT2SAS_ADAPTER *ioc)
-{
-       struct fw_event_work *fw_event;
-
-       if (ioc->is_driver_loading)
-               return;
-
-       fw_event = alloc_fw_event_work(0);
-       if (!fw_event)
-               return;
-
-       fw_event->event = MPT2SAS_REMOVE_UNRESPONDING_DEVICES;
-       fw_event->ioc = ioc;
-       _scsih_fw_event_add(ioc, fw_event);
-       fw_event_work_put(fw_event);
-}
-
-/**
- * mpt2sas_port_enable_complete - port enable completed (fake event)
- * @ioc: per adapter object
- *
- * Return nothing.
- */
-void
-mpt2sas_port_enable_complete(struct MPT2SAS_ADAPTER *ioc)
-{
-       struct fw_event_work *fw_event;
-
-       fw_event = alloc_fw_event_work(0);
-       if (!fw_event)
-               return;
-       fw_event->event = MPT2SAS_PORT_ENABLE_COMPLETE;
-       fw_event->ioc = ioc;
-       _scsih_fw_event_add(ioc, fw_event);
-       fw_event_work_put(fw_event);
-}
-
-static struct fw_event_work *dequeue_next_fw_event(struct MPT2SAS_ADAPTER *ioc)
-{
-       unsigned long flags;
-       struct fw_event_work *fw_event = NULL;
-
-       spin_lock_irqsave(&ioc->fw_event_lock, flags);
-       if (!list_empty(&ioc->fw_event_list)) {
-               fw_event = list_first_entry(&ioc->fw_event_list,
-                               struct fw_event_work, list);
-               list_del_init(&fw_event->list);
-       }
-       spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
-
-       return fw_event;
-}
-
-/**
- * _scsih_fw_event_cleanup_queue - cleanup event queue
- * @ioc: per adapter object
- *
- * Walk the firmware event queue, either killing timers, or waiting
- * for outstanding events to complete
- *
- * Return nothing.
- */
-static void
-_scsih_fw_event_cleanup_queue(struct MPT2SAS_ADAPTER *ioc)
-{
-       struct fw_event_work *fw_event;
-
-       if (list_empty(&ioc->fw_event_list) ||
-            !ioc->firmware_event_thread || in_interrupt())
-               return;
-
-       while ((fw_event = dequeue_next_fw_event(ioc))) {
-               /*
-                * Wait on the fw_event to complete. If this returns 1, then
-                * the event was never executed, and we need a put for the
-                * reference the delayed_work had on the fw_event.
-                *
-                * If it did execute, we wait for it to finish, and the put will
-                * happen from _firmware_event_work()
-                */
-               if (cancel_delayed_work_sync(&fw_event->delayed_work))
-                       fw_event_work_put(fw_event);
-
-               fw_event_work_put(fw_event);
-       }
-}
-
-/**
- * _scsih_ublock_io_all_device - unblock every device
- * @ioc: per adapter object
- *
- * change the device state from block to running
- */
-static void
-_scsih_ublock_io_all_device(struct MPT2SAS_ADAPTER *ioc)
-{
-       struct MPT2SAS_DEVICE *sas_device_priv_data;
-       struct scsi_device *sdev;
-
-       shost_for_each_device(sdev, ioc->shost) {
-               sas_device_priv_data = sdev->hostdata;
-               if (!sas_device_priv_data)
-                       continue;
-               if (!sas_device_priv_data->block)
-                       continue;
-               sas_device_priv_data->block = 0;
-               dewtprintk(ioc, sdev_printk(KERN_INFO, sdev, "device_running, "
-                   "handle(0x%04x)\n",
-                   sas_device_priv_data->sas_target->handle));
-               scsi_internal_device_unblock(sdev, SDEV_RUNNING);
-       }
-}
-/**
- * _scsih_ublock_io_device - set the device state to SDEV_RUNNING
- * @ioc: per adapter object
- * @handle: device handle
- *
- * During device pull we need to appropiately set the sdev state.
- */
-static void
-_scsih_ublock_io_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address)
-{
-       struct MPT2SAS_DEVICE *sas_device_priv_data;
-       struct scsi_device *sdev;
-
-       shost_for_each_device(sdev, ioc->shost) {
-               sas_device_priv_data = sdev->hostdata;
-               if (!sas_device_priv_data)
-                       continue;
-               if (!sas_device_priv_data->block)
-                       continue;
-               if (sas_device_priv_data->sas_target->sas_address ==
-                                                               sas_address) {
-                       dewtprintk(ioc, sdev_printk(KERN_INFO, sdev,
-                           MPT2SAS_INFO_FMT "SDEV_RUNNING: "
-                           "sas address(0x%016llx)\n", ioc->name,
-                               (unsigned long long)sas_address));
-                       sas_device_priv_data->block = 0;
-                       scsi_internal_device_unblock(sdev, SDEV_RUNNING);
-               }
-       }
-}
-
-/**
- * _scsih_block_io_all_device - set the device state to SDEV_BLOCK
- * @ioc: per adapter object
- * @handle: device handle
- *
- * During device pull we need to appropiately set the sdev state.
- */
-static void
-_scsih_block_io_all_device(struct MPT2SAS_ADAPTER *ioc)
-{
-       struct MPT2SAS_DEVICE *sas_device_priv_data;
-       struct scsi_device *sdev;
-
-       shost_for_each_device(sdev, ioc->shost) {
-               sas_device_priv_data = sdev->hostdata;
-               if (!sas_device_priv_data)
-                       continue;
-               if (sas_device_priv_data->block)
-                       continue;
-               sas_device_priv_data->block = 1;
-               dewtprintk(ioc, sdev_printk(KERN_INFO, sdev, "device_blocked, "
-                   "handle(0x%04x)\n",
-                   sas_device_priv_data->sas_target->handle));
-               scsi_internal_device_block(sdev);
-       }
-}
-
-
-/**
- * _scsih_block_io_device - set the device state to SDEV_BLOCK
- * @ioc: per adapter object
- * @handle: device handle
- *
- * During device pull we need to appropiately set the sdev state.
- */
-static void
-_scsih_block_io_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
-{
-       struct MPT2SAS_DEVICE *sas_device_priv_data;
-       struct scsi_device *sdev;
-
-       shost_for_each_device(sdev, ioc->shost) {
-               sas_device_priv_data = sdev->hostdata;
-               if (!sas_device_priv_data)
-                       continue;
-               if (sas_device_priv_data->block)
-                       continue;
-               if (sas_device_priv_data->sas_target->handle == handle) {
-                       dewtprintk(ioc, sdev_printk(KERN_INFO, sdev,
-                           MPT2SAS_INFO_FMT "SDEV_BLOCK: "
-                           "handle(0x%04x)\n", ioc->name, handle));
-                       sas_device_priv_data->block = 1;
-                       scsi_internal_device_block(sdev);
-               }
-       }
-}
-
-/**
- * _scsih_block_io_to_children_attached_to_ex
- * @ioc: per adapter object
- * @sas_expander: the sas_device object
- *
- * This routine set sdev state to SDEV_BLOCK for all devices
- * attached to this expander. This function called when expander is
- * pulled.
- */
-static void
-_scsih_block_io_to_children_attached_to_ex(struct MPT2SAS_ADAPTER *ioc,
-    struct _sas_node *sas_expander)
-{
-       struct _sas_port *mpt2sas_port;
-       struct _sas_device *sas_device;
-       struct _sas_node *expander_sibling;
-       unsigned long flags;
-
-       if (!sas_expander)
-               return;
-
-       list_for_each_entry(mpt2sas_port,
-          &sas_expander->sas_port_list, port_list) {
-               if (mpt2sas_port->remote_identify.device_type == SAS_END_DEVICE) {
-                       spin_lock_irqsave(&ioc->sas_device_lock, flags);
-                       sas_device = __mpt2sas_get_sdev_by_addr(ioc,
-                                       mpt2sas_port->remote_identify.sas_address);
-                       if (sas_device) {
-                               set_bit(sas_device->handle,
-                                               ioc->blocking_handles);
-                               sas_device_put(sas_device);
-                       }
-                       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-               }
-       }
-
-       list_for_each_entry(mpt2sas_port,
-          &sas_expander->sas_port_list, port_list) {
-
-               if (mpt2sas_port->remote_identify.device_type ==
-                   SAS_EDGE_EXPANDER_DEVICE ||
-                   mpt2sas_port->remote_identify.device_type ==
-                   SAS_FANOUT_EXPANDER_DEVICE) {
-                       expander_sibling =
-                           mpt2sas_scsih_expander_find_by_sas_address(
-                           ioc, mpt2sas_port->remote_identify.sas_address);
-                       _scsih_block_io_to_children_attached_to_ex(ioc,
-                           expander_sibling);
-               }
-       }
-}
-
-/**
- * _scsih_block_io_to_children_attached_directly
- * @ioc: per adapter object
- * @event_data: topology change event data
- *
- * This routine set sdev state to SDEV_BLOCK for all devices
- * direct attached during device pull.
- */
-static void
-_scsih_block_io_to_children_attached_directly(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2EventDataSasTopologyChangeList_t *event_data)
-{
-       int i;
-       u16 handle;
-       u16 reason_code;
-       u8 phy_number;
-
-       for (i = 0; i < event_data->NumEntries; i++) {
-               handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
-               if (!handle)
-                       continue;
-               phy_number = event_data->StartPhyNum + i;
-               reason_code = event_data->PHY[i].PhyStatus &
-                   MPI2_EVENT_SAS_TOPO_RC_MASK;
-               if (reason_code == MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING)
-                       _scsih_block_io_device(ioc, handle);
-       }
-}
-
-/**
- * _scsih_tm_tr_send - send task management request
- * @ioc: per adapter object
- * @handle: device handle
- * Context: interrupt time.
- *
- * This code is to initiate the device removal handshake protocol
- * with controller firmware.  This function will issue target reset
- * using high priority request queue.  It will send a sas iounit
- * control request (MPI2_SAS_OP_REMOVE_DEVICE) from this completion.
- *
- * This is designed to send muliple task management request at the same
- * time to the fifo. If the fifo is full, we will append the request,
- * and process it in a future completion.
- */
-static void
-_scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
-{
-       Mpi2SCSITaskManagementRequest_t *mpi_request;
-       u16 smid;
-       struct _sas_device *sas_device = NULL;
-       struct MPT2SAS_TARGET *sas_target_priv_data = NULL;
-       u64 sas_address = 0;
-       unsigned long flags;
-       struct _tr_list *delayed_tr;
-       u32 ioc_state;
-
-       if (ioc->remove_host) {
-               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host has been "
-                   "removed: handle(0x%04x)\n", __func__, ioc->name, handle));
-               return;
-       } else if (ioc->pci_error_recovery) {
-               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host in pci "
-                   "error recovery: handle(0x%04x)\n", __func__, ioc->name,
-                   handle));
-               return;
-       }
-       ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
-       if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
-               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host is not "
-                  "operational: handle(0x%04x)\n", __func__, ioc->name,
-                  handle));
-               return;
-       }
-
-       /* if PD, then return */
-       if (test_bit(handle, ioc->pd_handles))
-               return;
-
-       spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       sas_device = __mpt2sas_get_sdev_by_handle(ioc, handle);
-       if (sas_device && sas_device->starget &&
-            sas_device->starget->hostdata) {
-               sas_target_priv_data = sas_device->starget->hostdata;
-               sas_target_priv_data->deleted = 1;
-               sas_address = sas_device->sas_address;
-       }
-       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-
-       if (sas_target_priv_data) {
-               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "setting delete flag: "
-               "handle(0x%04x), sas_addr(0x%016llx)\n", ioc->name, handle,
-                       (unsigned long long)sas_address));
-               _scsih_ublock_io_device(ioc, sas_address);
-               sas_target_priv_data->handle = MPT2SAS_INVALID_DEVICE_HANDLE;
-       }
-
-       smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx);
-       if (!smid) {
-               delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC);
-               if (!delayed_tr)
-                       goto out;
-               INIT_LIST_HEAD(&delayed_tr->list);
-               delayed_tr->handle = handle;
-               list_add_tail(&delayed_tr->list, &ioc->delayed_tr_list);
-               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
-                   "DELAYED:tr:handle(0x%04x), (open)\n",
-                   ioc->name, handle));
-               goto out;
-       }
-
-       dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "tr_send:handle(0x%04x), "
-           "(open), smid(%d), cb(%d)\n", ioc->name, handle, smid,
-           ioc->tm_tr_cb_idx));
-       mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
-       memset(mpi_request, 0, sizeof(Mpi2SCSITaskManagementRequest_t));
-       mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
-       mpi_request->DevHandle = cpu_to_le16(handle);
-       mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
-       mpt2sas_base_put_smid_hi_priority(ioc, smid);
-out:
-       if (sas_device)
-               sas_device_put(sas_device);
-}
-
-
-
-/**
- * _scsih_sas_control_complete - completion routine
- * @ioc: per adapter object
- * @smid: system request message index
- * @msix_index: MSIX table index supplied by the OS
- * @reply: reply message frame(lower 32bit addr)
- * Context: interrupt time.
- *
- * This is the sas iounit control completion routine.
- * This code is part of the code to initiate the device removal
- * handshake protocol with controller firmware.
- *
- * Return 1 meaning mf should be freed from _base_interrupt
- *        0 means the mf is freed from this function.
- */
-static u8
-_scsih_sas_control_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid,
-    u8 msix_index, u32 reply)
-{
-       Mpi2SasIoUnitControlReply_t *mpi_reply =
-           mpt2sas_base_get_reply_virt_addr(ioc, reply);
-       if (likely(mpi_reply)) {
-               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
-               "sc_complete:handle(0x%04x), (open) "
-               "smid(%d), ioc_status(0x%04x), loginfo(0x%08x)\n",
-               ioc->name, le16_to_cpu(mpi_reply->DevHandle), smid,
-               le16_to_cpu(mpi_reply->IOCStatus),
-               le32_to_cpu(mpi_reply->IOCLogInfo)));
-       } else {
-               printk(MPT2SAS_ERR_FMT "mpi_reply not valid at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-       }
-       return 1;
-}
-
-/**
- * _scsih_tm_tr_volume_send - send target reset request for volumes
- * @ioc: per adapter object
- * @handle: device handle
- * Context: interrupt time.
- *
- * This is designed to send muliple task management request at the same
- * time to the fifo. If the fifo is full, we will append the request,
- * and process it in a future completion.
- */
-static void
-_scsih_tm_tr_volume_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
-{
-       Mpi2SCSITaskManagementRequest_t *mpi_request;
-       u16 smid;
-       struct _tr_list *delayed_tr;
-
-       if (ioc->shost_recovery || ioc->remove_host ||
-           ioc->pci_error_recovery) {
-               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host reset in "
-                  "progress!\n", __func__, ioc->name));
-               return;
-       }
-
-       smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_volume_cb_idx);
-       if (!smid) {
-               delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC);
-               if (!delayed_tr)
-                       return;
-               INIT_LIST_HEAD(&delayed_tr->list);
-               delayed_tr->handle = handle;
-               list_add_tail(&delayed_tr->list, &ioc->delayed_tr_volume_list);
-               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
-                   "DELAYED:tr:handle(0x%04x), (open)\n",
-                   ioc->name, handle));
-               return;
-       }
-
-       dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "tr_send:handle(0x%04x), "
-           "(open), smid(%d), cb(%d)\n", ioc->name, handle, smid,
-           ioc->tm_tr_volume_cb_idx));
-       mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
-       memset(mpi_request, 0, sizeof(Mpi2SCSITaskManagementRequest_t));
-       mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
-       mpi_request->DevHandle = cpu_to_le16(handle);
-       mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
-       mpt2sas_base_put_smid_hi_priority(ioc, smid);
-}
-
-/**
- * _scsih_tm_volume_tr_complete - target reset completion
- * @ioc: per adapter object
- * @smid: system request message index
- * @msix_index: MSIX table index supplied by the OS
- * @reply: reply message frame(lower 32bit addr)
- * Context: interrupt time.
- *
- * Return 1 meaning mf should be freed from _base_interrupt
- *        0 means the mf is freed from this function.
- */
-static u8
-_scsih_tm_volume_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid,
-    u8 msix_index, u32 reply)
-{
-       u16 handle;
-       Mpi2SCSITaskManagementRequest_t *mpi_request_tm;
-       Mpi2SCSITaskManagementReply_t *mpi_reply =
-           mpt2sas_base_get_reply_virt_addr(ioc, reply);
-
-       if (ioc->shost_recovery || ioc->remove_host ||
-           ioc->pci_error_recovery) {
-               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host reset in "
-                  "progress!\n", __func__, ioc->name));
-               return 1;
-       }
-       if (unlikely(!mpi_reply)) {
-               printk(MPT2SAS_ERR_FMT "mpi_reply not valid at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               return 1;
-       }
-       mpi_request_tm = mpt2sas_base_get_msg_frame(ioc, smid);
-       handle = le16_to_cpu(mpi_request_tm->DevHandle);
-       if (handle != le16_to_cpu(mpi_reply->DevHandle)) {
-               dewtprintk(ioc, printk("spurious interrupt: "
-                   "handle(0x%04x:0x%04x), smid(%d)!!!\n", handle,
-                   le16_to_cpu(mpi_reply->DevHandle), smid));
-               return 0;
-       }
-
-       dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
-           "tr_complete:handle(0x%04x), (open) smid(%d), ioc_status(0x%04x), "
-           "loginfo(0x%08x), completed(%d)\n", ioc->name,
-           handle, smid, le16_to_cpu(mpi_reply->IOCStatus),
-           le32_to_cpu(mpi_reply->IOCLogInfo),
-           le32_to_cpu(mpi_reply->TerminationCount)));
-
-       return _scsih_check_for_pending_tm(ioc, smid);
-}
-
-/**
- * _scsih_tm_tr_complete -
- * @ioc: per adapter object
- * @smid: system request message index
- * @msix_index: MSIX table index supplied by the OS
- * @reply: reply message frame(lower 32bit addr)
- * Context: interrupt time.
- *
- * This is the target reset completion routine.
- * This code is part of the code to initiate the device removal
- * handshake protocol with controller firmware.
- * It will send a sas iounit control request (MPI2_SAS_OP_REMOVE_DEVICE)
- *
- * Return 1 meaning mf should be freed from _base_interrupt
- *        0 means the mf is freed from this function.
- */
-static u8
-_scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
-    u32 reply)
-{
-       u16 handle;
-       Mpi2SCSITaskManagementRequest_t *mpi_request_tm;
-       Mpi2SCSITaskManagementReply_t *mpi_reply =
-           mpt2sas_base_get_reply_virt_addr(ioc, reply);
-       Mpi2SasIoUnitControlRequest_t *mpi_request;
-       u16 smid_sas_ctrl;
-       u32 ioc_state;
-
-       if (ioc->remove_host) {
-               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host has been "
-                  "removed\n", __func__, ioc->name));
-               return 1;
-       } else if (ioc->pci_error_recovery) {
-               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host in pci "
-                   "error recovery\n", __func__, ioc->name));
-               return 1;
-       }
-       ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
-       if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
-               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host is not "
-                   "operational\n", __func__, ioc->name));
-               return 1;
-       }
-       if (unlikely(!mpi_reply)) {
-               printk(MPT2SAS_ERR_FMT "mpi_reply not valid at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               return 1;
-       }
-       mpi_request_tm = mpt2sas_base_get_msg_frame(ioc, smid);
-       handle = le16_to_cpu(mpi_request_tm->DevHandle);
-       if (handle != le16_to_cpu(mpi_reply->DevHandle)) {
-               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "spurious interrupt: "
-                   "handle(0x%04x:0x%04x), smid(%d)!!!\n", ioc->name, handle,
-                   le16_to_cpu(mpi_reply->DevHandle), smid));
-               return 0;
-       }
-
-       dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
-           "tr_complete:handle(0x%04x), (open) smid(%d), ioc_status(0x%04x), "
-           "loginfo(0x%08x), completed(%d)\n", ioc->name,
-           handle, smid, le16_to_cpu(mpi_reply->IOCStatus),
-           le32_to_cpu(mpi_reply->IOCLogInfo),
-           le32_to_cpu(mpi_reply->TerminationCount)));
-
-       smid_sas_ctrl = mpt2sas_base_get_smid(ioc, ioc->tm_sas_control_cb_idx);
-       if (!smid_sas_ctrl) {
-               printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
-                   ioc->name, __func__);
-               return 1;
-       }
-
-       dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "sc_send:handle(0x%04x), "
-           "(open), smid(%d), cb(%d)\n", ioc->name, handle, smid_sas_ctrl,
-           ioc->tm_sas_control_cb_idx));
-       mpi_request = mpt2sas_base_get_msg_frame(ioc, smid_sas_ctrl);
-       memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t));
-       mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
-       mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE;
-       mpi_request->DevHandle = mpi_request_tm->DevHandle;
-       mpt2sas_base_put_smid_default(ioc, smid_sas_ctrl);
-
-       return _scsih_check_for_pending_tm(ioc, smid);
-}
-
-/**
- * _scsih_check_for_pending_tm - check for pending task management
- * @ioc: per adapter object
- * @smid: system request message index
- *
- * This will check delayed target reset list, and feed the
- * next reqeust.
- *
- * Return 1 meaning mf should be freed from _base_interrupt
- *        0 means the mf is freed from this function.
- */
-static u8
-_scsih_check_for_pending_tm(struct MPT2SAS_ADAPTER *ioc, u16 smid)
-{
-       struct _tr_list *delayed_tr;
-
-       if (!list_empty(&ioc->delayed_tr_volume_list)) {
-               delayed_tr = list_entry(ioc->delayed_tr_volume_list.next,
-                   struct _tr_list, list);
-               mpt2sas_base_free_smid(ioc, smid);
-               _scsih_tm_tr_volume_send(ioc, delayed_tr->handle);
-               list_del(&delayed_tr->list);
-               kfree(delayed_tr);
-               return 0;
-       }
-
-       if (!list_empty(&ioc->delayed_tr_list)) {
-               delayed_tr = list_entry(ioc->delayed_tr_list.next,
-                   struct _tr_list, list);
-               mpt2sas_base_free_smid(ioc, smid);
-               _scsih_tm_tr_send(ioc, delayed_tr->handle);
-               list_del(&delayed_tr->list);
-               kfree(delayed_tr);
-               return 0;
-       }
-
-       return 1;
-}
-
-/**
- * _scsih_check_topo_delete_events - sanity check on topo events
- * @ioc: per adapter object
- * @event_data: the event data payload
- *
- * This routine added to better handle cable breaker.
- *
- * This handles the case where driver receives multiple expander
- * add and delete events in a single shot.  When there is a delete event
- * the routine will void any pending add events waiting in the event queue.
- *
- * Return nothing.
- */
-static void
-_scsih_check_topo_delete_events(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2EventDataSasTopologyChangeList_t *event_data)
-{
-       struct fw_event_work *fw_event;
-       Mpi2EventDataSasTopologyChangeList_t *local_event_data;
-       u16 expander_handle;
-       struct _sas_node *sas_expander;
-       unsigned long flags;
-       int i, reason_code;
-       u16 handle;
-
-       for (i = 0 ; i < event_data->NumEntries; i++) {
-               handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
-               if (!handle)
-                       continue;
-               reason_code = event_data->PHY[i].PhyStatus &
-                   MPI2_EVENT_SAS_TOPO_RC_MASK;
-               if (reason_code == MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING)
-                       _scsih_tm_tr_send(ioc, handle);
-       }
-
-       expander_handle = le16_to_cpu(event_data->ExpanderDevHandle);
-       if (expander_handle < ioc->sas_hba.num_phys) {
-               _scsih_block_io_to_children_attached_directly(ioc, event_data);
-               return;
-       }
-       if (event_data->ExpStatus ==
-           MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING) {
-               /* put expander attached devices into blocking state */
-               spin_lock_irqsave(&ioc->sas_node_lock, flags);
-               sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc,
-                   expander_handle);
-               _scsih_block_io_to_children_attached_to_ex(ioc, sas_expander);
-               spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
-               do {
-                       handle = find_first_bit(ioc->blocking_handles,
-                           ioc->facts.MaxDevHandle);
-                       if (handle < ioc->facts.MaxDevHandle)
-                               _scsih_block_io_device(ioc, handle);
-               } while (test_and_clear_bit(handle, ioc->blocking_handles));
-       } else if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_RESPONDING)
-               _scsih_block_io_to_children_attached_directly(ioc, event_data);
-
-       if (event_data->ExpStatus != MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING)
-               return;
-
-       /* mark ignore flag for pending events */
-       spin_lock_irqsave(&ioc->fw_event_lock, flags);
-       list_for_each_entry(fw_event, &ioc->fw_event_list, list) {
-               if (fw_event->event != MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST ||
-                   fw_event->ignore)
-                       continue;
-               local_event_data = (Mpi2EventDataSasTopologyChangeList_t *)
-                       fw_event->event_data;
-               if (local_event_data->ExpStatus ==
-                   MPI2_EVENT_SAS_TOPO_ES_ADDED ||
-                   local_event_data->ExpStatus ==
-                   MPI2_EVENT_SAS_TOPO_ES_RESPONDING) {
-                       if (le16_to_cpu(local_event_data->ExpanderDevHandle) ==
-                           expander_handle) {
-                               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
-                                   "setting ignoring flag\n", ioc->name));
-                               fw_event->ignore = 1;
-                       }
-               }
-       }
-       spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
-}
-
-/**
- * _scsih_set_volume_delete_flag - setting volume delete flag
- * @ioc: per adapter object
- * @handle: device handle
- *
- * This
- * Return nothing.
- */
-static void
-_scsih_set_volume_delete_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle)
-{
-       struct _raid_device *raid_device;
-       struct MPT2SAS_TARGET *sas_target_priv_data;
-       unsigned long flags;
-
-       spin_lock_irqsave(&ioc->raid_device_lock, flags);
-       raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
-       if (raid_device && raid_device->starget &&
-           raid_device->starget->hostdata) {
-               sas_target_priv_data =
-                   raid_device->starget->hostdata;
-               sas_target_priv_data->deleted = 1;
-               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
-                   "setting delete flag: handle(0x%04x), "
-                   "wwid(0x%016llx)\n", ioc->name, handle,
-                   (unsigned long long) raid_device->wwid));
-       }
-       spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
-}
-
-/**
- * _scsih_set_volume_handle_for_tr - set handle for target reset to volume
- * @handle: input handle
- * @a: handle for volume a
- * @b: handle for volume b
- *
- * IR firmware only supports two raid volumes.  The purpose of this
- * routine is to set the volume handle in either a or b. When the given
- * input handle is non-zero, or when a and b have not been set before.
- */
-static void
-_scsih_set_volume_handle_for_tr(u16 handle, u16 *a, u16 *b)
-{
-       if (!handle || handle == *a || handle == *b)
-               return;
-       if (!*a)
-               *a = handle;
-       else if (!*b)
-               *b = handle;
-}
-
-/**
- * _scsih_check_ir_config_unhide_events - check for UNHIDE events
- * @ioc: per adapter object
- * @event_data: the event data payload
- * Context: interrupt time.
- *
- * This routine will send target reset to volume, followed by target
- * resets to the PDs. This is called when a PD has been removed, or
- * volume has been deleted or removed. When the target reset is sent
- * to volume, the PD target resets need to be queued to start upon
- * completion of the volume target reset.
- *
- * Return nothing.
- */
-static void
-_scsih_check_ir_config_unhide_events(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2EventDataIrConfigChangeList_t *event_data)
-{
-       Mpi2EventIrConfigElement_t *element;
-       int i;
-       u16 handle, volume_handle, a, b;
-       struct _tr_list *delayed_tr;
-
-       a = 0;
-       b = 0;
-
-       if (ioc->is_warpdrive)
-               return;
-
-       /* Volume Resets for Deleted or Removed */
-       element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
-       for (i = 0; i < event_data->NumElements; i++, element++) {
-               if (element->ReasonCode ==
-                   MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED ||
-                   element->ReasonCode ==
-                   MPI2_EVENT_IR_CHANGE_RC_REMOVED) {
-                       volume_handle = le16_to_cpu(element->VolDevHandle);
-                       _scsih_set_volume_delete_flag(ioc, volume_handle);
-                       _scsih_set_volume_handle_for_tr(volume_handle, &a, &b);
-               }
-       }
-
-       /* Volume Resets for UNHIDE events */
-       element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
-       for (i = 0; i < event_data->NumElements; i++, element++) {
-               if (le32_to_cpu(event_data->Flags) &
-                   MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG)
-                       continue;
-               if (element->ReasonCode == MPI2_EVENT_IR_CHANGE_RC_UNHIDE) {
-                       volume_handle = le16_to_cpu(element->VolDevHandle);
-                       _scsih_set_volume_handle_for_tr(volume_handle, &a, &b);
-               }
-       }
-
-       if (a)
-               _scsih_tm_tr_volume_send(ioc, a);
-       if (b)
-               _scsih_tm_tr_volume_send(ioc, b);
-
-       /* PD target resets */
-       element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
-       for (i = 0; i < event_data->NumElements; i++, element++) {
-               if (element->ReasonCode != MPI2_EVENT_IR_CHANGE_RC_UNHIDE)
-                       continue;
-               handle = le16_to_cpu(element->PhysDiskDevHandle);
-               volume_handle = le16_to_cpu(element->VolDevHandle);
-               clear_bit(handle, ioc->pd_handles);
-               if (!volume_handle)
-                       _scsih_tm_tr_send(ioc, handle);
-               else if (volume_handle == a || volume_handle == b) {
-                       delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC);
-                       BUG_ON(!delayed_tr);
-                       INIT_LIST_HEAD(&delayed_tr->list);
-                       delayed_tr->handle = handle;
-                       list_add_tail(&delayed_tr->list, &ioc->delayed_tr_list);
-                       dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
-                           "DELAYED:tr:handle(0x%04x), (open)\n", ioc->name,
-                           handle));
-               } else
-                       _scsih_tm_tr_send(ioc, handle);
-       }
-}
-
-
-/**
- * _scsih_check_volume_delete_events - set delete flag for volumes
- * @ioc: per adapter object
- * @event_data: the event data payload
- * Context: interrupt time.
- *
- * This will handle the case when the cable connected to entire volume is
- * pulled. We will take care of setting the deleted flag so normal IO will
- * not be sent.
- *
- * Return nothing.
- */
-static void
-_scsih_check_volume_delete_events(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2EventDataIrVolume_t *event_data)
-{
-       u32 state;
-
-       if (event_data->ReasonCode != MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED)
-               return;
-       state = le32_to_cpu(event_data->NewValue);
-       if (state == MPI2_RAID_VOL_STATE_MISSING || state ==
-           MPI2_RAID_VOL_STATE_FAILED)
-               _scsih_set_volume_delete_flag(ioc,
-                   le16_to_cpu(event_data->VolDevHandle));
-}
-
-/**
- * _scsih_temp_threshold_events - display temperature threshold exceeded events
- * @ioc: per adapter object
- * @event_data: the temp threshold event data
- * Context: interrupt time.
- *
- * Return nothing.
- */
-static void
-_scsih_temp_threshold_events(struct MPT2SAS_ADAPTER *ioc,
-       Mpi2EventDataTemperature_t *event_data)
-{
-       if (ioc->temp_sensors_count >= event_data->SensorNum) {
-               printk(MPT2SAS_ERR_FMT "Temperature Threshold flags %s%s%s%s"
-                 " exceeded for Sensor: %d !!!\n", ioc->name,
-                 ((le16_to_cpu(event_data->Status) & 0x1) == 1) ? "0 " : " ",
-                 ((le16_to_cpu(event_data->Status) & 0x2) == 2) ? "1 " : " ",
-                 ((le16_to_cpu(event_data->Status) & 0x4) == 4) ? "2 " : " ",
-                 ((le16_to_cpu(event_data->Status) & 0x8) == 8) ? "3 " : " ",
-                 event_data->SensorNum);
-               printk(MPT2SAS_ERR_FMT "Current Temp In Celsius: %d\n",
-                       ioc->name, event_data->CurrentTemperature);
-       }
-}
-
-/**
- * _scsih_flush_running_cmds - completing outstanding commands.
- * @ioc: per adapter object
- *
- * The flushing out of all pending scmd commands following host reset,
- * where all IO is dropped to the floor.
- *
- * Return nothing.
- */
-static void
-_scsih_flush_running_cmds(struct MPT2SAS_ADAPTER *ioc)
-{
-       struct scsi_cmnd *scmd;
-       u16 smid;
-       u16 count = 0;
-
-       for (smid = 1; smid <= ioc->scsiio_depth; smid++) {
-               scmd = _scsih_scsi_lookup_get_clear(ioc, smid);
-               if (!scmd)
-                       continue;
-               count++;
-               mpt2sas_base_free_smid(ioc, smid);
-               scsi_dma_unmap(scmd);
-               if (ioc->pci_error_recovery)
-                       scmd->result = DID_NO_CONNECT << 16;
-               else
-                       scmd->result = DID_RESET << 16;
-               scmd->scsi_done(scmd);
-       }
-       dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "completing %d cmds\n",
-           ioc->name, count));
-}
-
-/**
- * _scsih_setup_eedp - setup MPI request for EEDP transfer
- * @scmd: pointer to scsi command object
- * @mpi_request: pointer to the SCSI_IO reqest message frame
- *
- * Supporting protection 1 and 3.
- *
- * Returns nothing
- */
-static void
-_scsih_setup_eedp(struct scsi_cmnd *scmd, Mpi2SCSIIORequest_t *mpi_request)
-{
-       u16 eedp_flags;
-       unsigned char prot_op = scsi_get_prot_op(scmd);
-       unsigned char prot_type = scsi_get_prot_type(scmd);
-
-       if (prot_type == SCSI_PROT_DIF_TYPE0 || prot_op == SCSI_PROT_NORMAL)
-               return;
-
-       if (prot_op ==  SCSI_PROT_READ_STRIP)
-               eedp_flags = MPI2_SCSIIO_EEDPFLAGS_CHECK_REMOVE_OP;
-       else if (prot_op ==  SCSI_PROT_WRITE_INSERT)
-               eedp_flags = MPI2_SCSIIO_EEDPFLAGS_INSERT_OP;
-       else
-               return;
-
-       switch (prot_type) {
-       case SCSI_PROT_DIF_TYPE1:
-       case SCSI_PROT_DIF_TYPE2:
-
-               /*
-               * enable ref/guard checking
-               * auto increment ref tag
-               */
-               eedp_flags |= MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG |
-                   MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG |
-                   MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD;
-               mpi_request->CDB.EEDP32.PrimaryReferenceTag =
-                   cpu_to_be32(scsi_get_lba(scmd));
-               break;
-
-       case SCSI_PROT_DIF_TYPE3:
-
-               /*
-               * enable guard checking
-               */
-               eedp_flags |= MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD;
-               break;
-       }
-       mpi_request->EEDPBlockSize = cpu_to_le32(scmd->device->sector_size);
-       mpi_request->EEDPFlags = cpu_to_le16(eedp_flags);
-}
-
-/**
- * _scsih_eedp_error_handling - return sense code for EEDP errors
- * @scmd: pointer to scsi command object
- * @ioc_status: ioc status
- *
- * Returns nothing
- */
-static void
-_scsih_eedp_error_handling(struct scsi_cmnd *scmd, u16 ioc_status)
-{
-       u8 ascq;
-
-       switch (ioc_status) {
-       case MPI2_IOCSTATUS_EEDP_GUARD_ERROR:
-               ascq = 0x01;
-               break;
-       case MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR:
-               ascq = 0x02;
-               break;
-       case MPI2_IOCSTATUS_EEDP_REF_TAG_ERROR:
-               ascq = 0x03;
-               break;
-       default:
-               ascq = 0x00;
-               break;
-       }
-
-       scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST, 0x10, ascq);
-       scmd->result = DRIVER_SENSE << 24 | (DID_ABORT << 16) |
-           SAM_STAT_CHECK_CONDITION;
-}
-
-/**
- * _scsih_scsi_direct_io_get - returns direct io flag
- * @ioc: per adapter object
- * @smid: system request message index
- *
- * Returns the smid stored scmd pointer.
- */
-static inline u8
-_scsih_scsi_direct_io_get(struct MPT2SAS_ADAPTER *ioc, u16 smid)
-{
-       return ioc->scsi_lookup[smid - 1].direct_io;
-}
-
-/**
- * _scsih_scsi_direct_io_set - sets direct io flag
- * @ioc: per adapter object
- * @smid: system request message index
- * @direct_io: Zero or non-zero value to set in the direct_io flag
- *
- * Returns Nothing.
- */
-static inline void
-_scsih_scsi_direct_io_set(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 direct_io)
-{
-       ioc->scsi_lookup[smid - 1].direct_io = direct_io;
-}
-
-
-/**
- * _scsih_setup_direct_io - setup MPI request for WARPDRIVE Direct I/O
- * @ioc: per adapter object
- * @scmd: pointer to scsi command object
- * @raid_device: pointer to raid device data structure
- * @mpi_request: pointer to the SCSI_IO reqest message frame
- * @smid: system request message index
- *
- * Returns nothing
- */
-static void
-_scsih_setup_direct_io(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
-       struct _raid_device *raid_device, Mpi2SCSIIORequest_t *mpi_request,
-       u16 smid)
-{
-       sector_t v_lba, p_lba, stripe_off, column, io_size;
-       u32 stripe_sz, stripe_exp;
-       u8 num_pds, cmd = scmd->cmnd[0];
-
-       if (cmd != READ_10 && cmd != WRITE_10 &&
-           cmd != READ_16 && cmd != WRITE_16)
-               return;
-
-       if (cmd == READ_10 || cmd == WRITE_10)
-               v_lba = get_unaligned_be32(&mpi_request->CDB.CDB32[2]);
-       else
-               v_lba = get_unaligned_be64(&mpi_request->CDB.CDB32[2]);
-
-       io_size = scsi_bufflen(scmd) >> raid_device->block_exponent;
-
-       if (v_lba + io_size - 1 > raid_device->max_lba)
-               return;
-
-       stripe_sz = raid_device->stripe_sz;
-       stripe_exp = raid_device->stripe_exponent;
-       stripe_off = v_lba & (stripe_sz - 1);
-
-       /* Return unless IO falls within a stripe */
-       if (stripe_off + io_size > stripe_sz)
-               return;
-
-       num_pds = raid_device->num_pds;
-       p_lba = v_lba >> stripe_exp;
-       column = sector_div(p_lba, num_pds);
-       p_lba = (p_lba << stripe_exp) + stripe_off;
-
-       mpi_request->DevHandle = cpu_to_le16(raid_device->pd_handle[column]);
-
-       if (cmd == READ_10 || cmd == WRITE_10)
-               put_unaligned_be32(lower_32_bits(p_lba),
-                                  &mpi_request->CDB.CDB32[2]);
-       else
-               put_unaligned_be64(p_lba, &mpi_request->CDB.CDB32[2]);
-
-       _scsih_scsi_direct_io_set(ioc, smid, 1);
-}
-
-/**
- * _scsih_qcmd - main scsi request entry point
- * @scmd: pointer to scsi command object
- * @done: function pointer to be invoked on completion
- *
- * The callback index is set inside `ioc->scsi_io_cb_idx`.
- *
- * Returns 0 on success.  If there's a failure, return either:
- * SCSI_MLQUEUE_DEVICE_BUSY if the device queue is full, or
- * SCSI_MLQUEUE_HOST_BUSY if the entire host queue is full
- */
-static int
-_scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
-{
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-       struct MPT2SAS_DEVICE *sas_device_priv_data;
-       struct MPT2SAS_TARGET *sas_target_priv_data;
-       struct _raid_device *raid_device;
-       Mpi2SCSIIORequest_t *mpi_request;
-       u32 mpi_control;
-       u16 smid;
-
-       sas_device_priv_data = scmd->device->hostdata;
-       if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
-               scmd->result = DID_NO_CONNECT << 16;
-               scmd->scsi_done(scmd);
-               return 0;
-       }
-
-       if (ioc->pci_error_recovery || ioc->remove_host) {
-               scmd->result = DID_NO_CONNECT << 16;
-               scmd->scsi_done(scmd);
-               return 0;
-       }
-
-       sas_target_priv_data = sas_device_priv_data->sas_target;
-       /* invalid device handle */
-       if (sas_target_priv_data->handle == MPT2SAS_INVALID_DEVICE_HANDLE) {
-               scmd->result = DID_NO_CONNECT << 16;
-               scmd->scsi_done(scmd);
-               return 0;
-       }
-
-       /* host recovery or link resets sent via IOCTLs */
-       if (ioc->shost_recovery || ioc->ioc_link_reset_in_progress)
-               return SCSI_MLQUEUE_HOST_BUSY;
-       /* device busy with task management */
-       else if (sas_device_priv_data->block || sas_target_priv_data->tm_busy)
-               return SCSI_MLQUEUE_DEVICE_BUSY;
-       /* device has been deleted */
-       else if (sas_target_priv_data->deleted) {
-               scmd->result = DID_NO_CONNECT << 16;
-               scmd->scsi_done(scmd);
-               return 0;
-       }
-
-       if (scmd->sc_data_direction == DMA_FROM_DEVICE)
-               mpi_control = MPI2_SCSIIO_CONTROL_READ;
-       else if (scmd->sc_data_direction == DMA_TO_DEVICE)
-               mpi_control = MPI2_SCSIIO_CONTROL_WRITE;
-       else
-               mpi_control = MPI2_SCSIIO_CONTROL_NODATATRANSFER;
-
-       /* set tags */
-       mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
-
-       /* Make sure Device is not raid volume.
-        * We do not expose raid functionality to upper layer for warpdrive.
-        */
-       if (!ioc->is_warpdrive && !_scsih_is_raid(&scmd->device->sdev_gendev) &&
-           sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32)
-               mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON;
-
-       smid = mpt2sas_base_get_smid_scsiio(ioc, ioc->scsi_io_cb_idx, scmd);
-       if (!smid) {
-               printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
-                   ioc->name, __func__);
-               goto out;
-       }
-       mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
-       memset(mpi_request, 0, sizeof(Mpi2SCSIIORequest_t));
-       _scsih_setup_eedp(scmd, mpi_request);
-       if (scmd->cmd_len == 32)
-               mpi_control |= 4 << MPI2_SCSIIO_CONTROL_ADDCDBLEN_SHIFT;
-       mpi_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
-       if (sas_device_priv_data->sas_target->flags &
-           MPT_TARGET_FLAGS_RAID_COMPONENT)
-               mpi_request->Function = MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
-       else
-       mpi_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
-       mpi_request->DevHandle =
-           cpu_to_le16(sas_device_priv_data->sas_target->handle);
-       mpi_request->DataLength = cpu_to_le32(scsi_bufflen(scmd));
-       mpi_request->Control = cpu_to_le32(mpi_control);
-       mpi_request->IoFlags = cpu_to_le16(scmd->cmd_len);
-       mpi_request->MsgFlags = MPI2_SCSIIO_MSGFLAGS_SYSTEM_SENSE_ADDR;
-       mpi_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE;
-       mpi_request->SenseBufferLowAddress =
-           mpt2sas_base_get_sense_buffer_dma(ioc, smid);
-       mpi_request->SGLOffset0 = offsetof(Mpi2SCSIIORequest_t, SGL) / 4;
-       mpi_request->SGLFlags = cpu_to_le16(MPI2_SCSIIO_SGLFLAGS_TYPE_MPI +
-           MPI2_SCSIIO_SGLFLAGS_SYSTEM_ADDR);
-       mpi_request->VF_ID = 0; /* TODO */
-       mpi_request->VP_ID = 0;
-       int_to_scsilun(sas_device_priv_data->lun, (struct scsi_lun *)
-           mpi_request->LUN);
-       memcpy(mpi_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len);
-
-       if (!mpi_request->DataLength) {
-               mpt2sas_base_build_zero_len_sge(ioc, &mpi_request->SGL);
-       } else {
-               if (_scsih_build_scatter_gather(ioc, scmd, smid)) {
-                       mpt2sas_base_free_smid(ioc, smid);
-                       goto out;
-               }
-       }
-
-       raid_device = sas_target_priv_data->raid_device;
-       if (raid_device && raid_device->direct_io_enabled)
-               _scsih_setup_direct_io(ioc, scmd, raid_device, mpi_request,
-                   smid);
-
-       if (likely(mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST))
-               mpt2sas_base_put_smid_scsi_io(ioc, smid,
-                   le16_to_cpu(mpi_request->DevHandle));
-       else
-               mpt2sas_base_put_smid_default(ioc, smid);
-       return 0;
-
- out:
-       return SCSI_MLQUEUE_HOST_BUSY;
-}
-
-/**
- * _scsih_normalize_sense - normalize descriptor and fixed format sense data
- * @sense_buffer: sense data returned by target
- * @data: normalized skey/asc/ascq
- *
- * Return nothing.
- */
-static void
-_scsih_normalize_sense(char *sense_buffer, struct sense_info *data)
-{
-       if ((sense_buffer[0] & 0x7F) >= 0x72) {
-               /* descriptor format */
-               data->skey = sense_buffer[1] & 0x0F;
-               data->asc = sense_buffer[2];
-               data->ascq = sense_buffer[3];
-       } else {
-               /* fixed format */
-               data->skey = sense_buffer[2] & 0x0F;
-               data->asc = sense_buffer[12];
-               data->ascq = sense_buffer[13];
-       }
-}
-
-#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
-/**
- * _scsih_scsi_ioc_info - translated non-successful SCSI_IO request
- * @ioc: per adapter object
- * @scmd: pointer to scsi command object
- * @mpi_reply: reply mf payload returned from firmware
- *
- * scsi_status - SCSI Status code returned from target device
- * scsi_state - state info associated with SCSI_IO determined by ioc
- * ioc_status - ioc supplied status info
- *
- * Return nothing.
- */
-static void
-_scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
-    Mpi2SCSIIOReply_t *mpi_reply, u16 smid)
-{
-       u32 response_info;
-       u8 *response_bytes;
-       u16 ioc_status = le16_to_cpu(mpi_reply->IOCStatus) &
-           MPI2_IOCSTATUS_MASK;
-       u8 scsi_state = mpi_reply->SCSIState;
-       u8 scsi_status = mpi_reply->SCSIStatus;
-       char *desc_ioc_state = NULL;
-       char *desc_scsi_status = NULL;
-       char *desc_scsi_state = ioc->tmp_string;
-       u32 log_info = le32_to_cpu(mpi_reply->IOCLogInfo);
-       struct _sas_device *sas_device = NULL;
-       struct scsi_target *starget = scmd->device->sdev_target;
-       struct MPT2SAS_TARGET *priv_target = starget->hostdata;
-       char *device_str = NULL;
-
-       if (!priv_target)
-               return;
-
-       if (ioc->hide_ir_msg)
-               device_str = "WarpDrive";
-       else
-               device_str = "volume";
-
-       if (log_info == 0x31170000)
-               return;
-
-       switch (ioc_status) {
-       case MPI2_IOCSTATUS_SUCCESS:
-               desc_ioc_state = "success";
-               break;
-       case MPI2_IOCSTATUS_INVALID_FUNCTION:
-               desc_ioc_state = "invalid function";
-               break;
-       case MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR:
-               desc_ioc_state = "scsi recovered error";
-               break;
-       case MPI2_IOCSTATUS_SCSI_INVALID_DEVHANDLE:
-               desc_ioc_state = "scsi invalid dev handle";
-               break;
-       case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
-               desc_ioc_state = "scsi device not there";
-               break;
-       case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN:
-               desc_ioc_state = "scsi data overrun";
-               break;
-       case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN:
-               desc_ioc_state = "scsi data underrun";
-               break;
-       case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR:
-               desc_ioc_state = "scsi io data error";
-               break;
-       case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR:
-               desc_ioc_state = "scsi protocol error";
-               break;
-       case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED:
-               desc_ioc_state = "scsi task terminated";
-               break;
-       case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
-               desc_ioc_state = "scsi residual mismatch";
-               break;
-       case MPI2_IOCSTATUS_SCSI_TASK_MGMT_FAILED:
-               desc_ioc_state = "scsi task mgmt failed";
-               break;
-       case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED:
-               desc_ioc_state = "scsi ioc terminated";
-               break;
-       case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
-               desc_ioc_state = "scsi ext terminated";
-               break;
-       case MPI2_IOCSTATUS_EEDP_GUARD_ERROR:
-               desc_ioc_state = "eedp guard error";
-               break;
-       case MPI2_IOCSTATUS_EEDP_REF_TAG_ERROR:
-               desc_ioc_state = "eedp ref tag error";
-               break;
-       case MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR:
-               desc_ioc_state = "eedp app tag error";
-               break;
-       default:
-               desc_ioc_state = "unknown";
-               break;
-       }
-
-       switch (scsi_status) {
-       case MPI2_SCSI_STATUS_GOOD:
-               desc_scsi_status = "good";
-               break;
-       case MPI2_SCSI_STATUS_CHECK_CONDITION:
-               desc_scsi_status = "check condition";
-               break;
-       case MPI2_SCSI_STATUS_CONDITION_MET:
-               desc_scsi_status = "condition met";
-               break;
-       case MPI2_SCSI_STATUS_BUSY:
-               desc_scsi_status = "busy";
-               break;
-       case MPI2_SCSI_STATUS_INTERMEDIATE:
-               desc_scsi_status = "intermediate";
-               break;
-       case MPI2_SCSI_STATUS_INTERMEDIATE_CONDMET:
-               desc_scsi_status = "intermediate condmet";
-               break;
-       case MPI2_SCSI_STATUS_RESERVATION_CONFLICT:
-               desc_scsi_status = "reservation conflict";
-               break;
-       case MPI2_SCSI_STATUS_COMMAND_TERMINATED:
-               desc_scsi_status = "command terminated";
-               break;
-       case MPI2_SCSI_STATUS_TASK_SET_FULL:
-               desc_scsi_status = "task set full";
-               break;
-       case MPI2_SCSI_STATUS_ACA_ACTIVE:
-               desc_scsi_status = "aca active";
-               break;
-       case MPI2_SCSI_STATUS_TASK_ABORTED:
-               desc_scsi_status = "task aborted";
-               break;
-       default:
-               desc_scsi_status = "unknown";
-               break;
-       }
-
-       desc_scsi_state[0] = '\0';
-       if (!scsi_state)
-               desc_scsi_state = " ";
-       if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID)
-               strcat(desc_scsi_state, "response info ");
-       if (scsi_state & MPI2_SCSI_STATE_TERMINATED)
-               strcat(desc_scsi_state, "state terminated ");
-       if (scsi_state & MPI2_SCSI_STATE_NO_SCSI_STATUS)
-               strcat(desc_scsi_state, "no status ");
-       if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_FAILED)
-               strcat(desc_scsi_state, "autosense failed ");
-       if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID)
-               strcat(desc_scsi_state, "autosense valid ");
-
-       scsi_print_command(scmd);
-
-       if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) {
-               printk(MPT2SAS_WARN_FMT "\t%s wwid(0x%016llx)\n", ioc->name,
-                   device_str, (unsigned long long)priv_target->sas_address);
-       } else {
-               sas_device = mpt2sas_get_sdev_from_target(ioc, priv_target);
-               if (sas_device) {
-                       printk(MPT2SAS_WARN_FMT "\tsas_address(0x%016llx), "
-                           "phy(%d)\n", ioc->name, sas_device->sas_address,
-                           sas_device->phy);
-                       printk(MPT2SAS_WARN_FMT
-                           "\tenclosure_logical_id(0x%016llx), slot(%d)\n",
-                           ioc->name, sas_device->enclosure_logical_id,
-                           sas_device->slot);
-
-                       sas_device_put(sas_device);
-               }
-       }
-
-       printk(MPT2SAS_WARN_FMT "\thandle(0x%04x), ioc_status(%s)(0x%04x), "
-           "smid(%d)\n", ioc->name, le16_to_cpu(mpi_reply->DevHandle),
-           desc_ioc_state, ioc_status, smid);
-       printk(MPT2SAS_WARN_FMT "\trequest_len(%d), underflow(%d), "
-           "resid(%d)\n", ioc->name, scsi_bufflen(scmd), scmd->underflow,
-           scsi_get_resid(scmd));
-       printk(MPT2SAS_WARN_FMT "\ttag(%d), transfer_count(%d), "
-           "sc->result(0x%08x)\n", ioc->name, le16_to_cpu(mpi_reply->TaskTag),
-           le32_to_cpu(mpi_reply->TransferCount), scmd->result);
-       printk(MPT2SAS_WARN_FMT "\tscsi_status(%s)(0x%02x), "
-           "scsi_state(%s)(0x%02x)\n", ioc->name, desc_scsi_status,
-           scsi_status, desc_scsi_state, scsi_state);
-
-       if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) {
-               struct sense_info data;
-               _scsih_normalize_sense(scmd->sense_buffer, &data);
-               printk(MPT2SAS_WARN_FMT "\t[sense_key,asc,ascq]: "
-                   "[0x%02x,0x%02x,0x%02x], count(%d)\n", ioc->name, data.skey,
-                   data.asc, data.ascq, le32_to_cpu(mpi_reply->SenseCount));
-       }
-
-       if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) {
-               response_info = le32_to_cpu(mpi_reply->ResponseInfo);
-               response_bytes = (u8 *)&response_info;
-               _scsih_response_code(ioc, response_bytes[0]);
-       }
-}
-#endif
-
-/**
- * _scsih_turn_on_pfa_led - illuminate PFA LED
- * @ioc: per adapter object
- * @handle: device handle
- * Context: process
- *
- * Return nothing.
- */
-static void
-_scsih_turn_on_pfa_led(struct MPT2SAS_ADAPTER *ioc, u16 handle)
-{
-       Mpi2SepReply_t mpi_reply;
-       Mpi2SepRequest_t mpi_request;
-       struct _sas_device *sas_device;
-
-       sas_device = mpt2sas_get_sdev_by_handle(ioc, handle);
-       if (!sas_device)
-               return;
-
-       memset(&mpi_request, 0, sizeof(Mpi2SepRequest_t));
-       mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
-       mpi_request.Action = MPI2_SEP_REQ_ACTION_WRITE_STATUS;
-       mpi_request.SlotStatus =
-           cpu_to_le32(MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
-       mpi_request.DevHandle = cpu_to_le16(handle);
-       mpi_request.Flags = MPI2_SEP_REQ_FLAGS_DEVHANDLE_ADDRESS;
-       if ((mpt2sas_base_scsi_enclosure_processor(ioc, &mpi_reply,
-           &mpi_request)) != 0) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name,
-               __FILE__, __LINE__, __func__);
-               goto out;
-       }
-       sas_device->pfa_led_on = 1;
-
-
-       if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) {
-               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
-                "enclosure_processor: ioc_status (0x%04x), loginfo(0x%08x)\n",
-                ioc->name, le16_to_cpu(mpi_reply.IOCStatus),
-                le32_to_cpu(mpi_reply.IOCLogInfo)));
-               goto out;
-       }
-out:
-       sas_device_put(sas_device);
-}
-
-/**
- * _scsih_turn_off_pfa_led - turn off PFA LED
- * @ioc: per adapter object
- * @sas_device: sas device whose PFA LED has to turned off
- * Context: process
- *
- * Return nothing.
- */
-static void
-_scsih_turn_off_pfa_led(struct MPT2SAS_ADAPTER *ioc,
-       struct _sas_device *sas_device)
-{
-       Mpi2SepReply_t mpi_reply;
-       Mpi2SepRequest_t mpi_request;
-
-       memset(&mpi_request, 0, sizeof(Mpi2SepRequest_t));
-       mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
-       mpi_request.Action = MPI2_SEP_REQ_ACTION_WRITE_STATUS;
-       mpi_request.SlotStatus = 0;
-       mpi_request.Slot = cpu_to_le16(sas_device->slot);
-       mpi_request.DevHandle = 0;
-       mpi_request.EnclosureHandle = cpu_to_le16(sas_device->enclosure_handle);
-       mpi_request.Flags = MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS;
-       if ((mpt2sas_base_scsi_enclosure_processor(ioc, &mpi_reply,
-           &mpi_request)) != 0) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name,
-               __FILE__, __LINE__, __func__);
-               return;
-       }
-
-       if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) {
-               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "enclosure_processor: "
-                   "ioc_status (0x%04x), loginfo(0x%08x)\n", ioc->name,
-                   le16_to_cpu(mpi_reply.IOCStatus),
-                   le32_to_cpu(mpi_reply.IOCLogInfo)));
-               return;
-       }
-}
-
-/**
- * _scsih_send_event_to_turn_on_pfa_led - fire delayed event
- * @ioc: per adapter object
- * @handle: device handle
- * Context: interrupt.
- *
- * Return nothing.
- */
-static void
-_scsih_send_event_to_turn_on_pfa_led(struct MPT2SAS_ADAPTER *ioc, u16 handle)
-{
-       struct fw_event_work *fw_event;
-
-       fw_event = alloc_fw_event_work(0);
-       if (!fw_event)
-               return;
-       fw_event->event = MPT2SAS_TURN_ON_PFA_LED;
-       fw_event->device_handle = handle;
-       fw_event->ioc = ioc;
-       _scsih_fw_event_add(ioc, fw_event);
-       fw_event_work_put(fw_event);
-}
-
-/**
- * _scsih_smart_predicted_fault - process smart errors
- * @ioc: per adapter object
- * @handle: device handle
- * Context: interrupt.
- *
- * Return nothing.
- */
-static void
-_scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle)
-{
-       struct scsi_target *starget;
-       struct MPT2SAS_TARGET *sas_target_priv_data;
-       Mpi2EventNotificationReply_t *event_reply;
-       Mpi2EventDataSasDeviceStatusChange_t *event_data;
-       struct _sas_device *sas_device;
-       ssize_t sz;
-       unsigned long flags;
-
-       /* only handle non-raid devices */
-       spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       sas_device = __mpt2sas_get_sdev_by_handle(ioc, handle);
-       if (!sas_device) {
-               goto out_unlock;
-       }
-       starget = sas_device->starget;
-       sas_target_priv_data = starget->hostdata;
-
-       if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_RAID_COMPONENT) ||
-          ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)))
-               goto out_unlock;
-
-       starget_printk(KERN_WARNING, starget, "predicted fault\n");
-       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-
-       if (ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM)
-               _scsih_send_event_to_turn_on_pfa_led(ioc, handle);
-
-       /* insert into event log */
-       sz = offsetof(Mpi2EventNotificationReply_t, EventData) +
-            sizeof(Mpi2EventDataSasDeviceStatusChange_t);
-       event_reply = kzalloc(sz, GFP_ATOMIC);
-       if (!event_reply) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               goto out;
-       }
-
-       event_reply->Function = MPI2_FUNCTION_EVENT_NOTIFICATION;
-       event_reply->Event =
-           cpu_to_le16(MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE);
-       event_reply->MsgLength = sz/4;
-       event_reply->EventDataLength =
-           cpu_to_le16(sizeof(Mpi2EventDataSasDeviceStatusChange_t)/4);
-       event_data = (Mpi2EventDataSasDeviceStatusChange_t *)
-           event_reply->EventData;
-       event_data->ReasonCode = MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA;
-       event_data->ASC = 0x5D;
-       event_data->DevHandle = cpu_to_le16(handle);
-       event_data->SASAddress = cpu_to_le64(sas_target_priv_data->sas_address);
-       mpt2sas_ctl_add_to_event_log(ioc, event_reply);
-       kfree(event_reply);
-out:
-       if (sas_device)
-               sas_device_put(sas_device);
-       return;
-
-out_unlock:
-       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-       goto out;
-}
-
-/**
- * _scsih_io_done - scsi request callback
- * @ioc: per adapter object
- * @smid: system request message index
- * @msix_index: MSIX table index supplied by the OS
- * @reply: reply message frame(lower 32bit addr)
- *
- * Callback handler when using _scsih_qcmd.
- *
- * Return 1 meaning mf should be freed from _base_interrupt
- *        0 means the mf is freed from this function.
- */
-static u8
-_scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
-{
-       Mpi2SCSIIORequest_t *mpi_request;
-       Mpi2SCSIIOReply_t *mpi_reply;
-       struct scsi_cmnd *scmd;
-       u16 ioc_status;
-       u32 xfer_cnt;
-       u8 scsi_state;
-       u8 scsi_status;
-       u32 log_info;
-       struct MPT2SAS_DEVICE *sas_device_priv_data;
-       u32 response_code = 0;
-       unsigned long flags;
-
-       mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
-       scmd = _scsih_scsi_lookup_get_clear(ioc, smid);
-       if (scmd == NULL)
-               return 1;
-
-       mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
-
-       if (mpi_reply == NULL) {
-               scmd->result = DID_OK << 16;
-               goto out;
-       }
-
-       sas_device_priv_data = scmd->device->hostdata;
-       if (!sas_device_priv_data || !sas_device_priv_data->sas_target ||
-            sas_device_priv_data->sas_target->deleted) {
-               scmd->result = DID_NO_CONNECT << 16;
-               goto out;
-       }
-       ioc_status = le16_to_cpu(mpi_reply->IOCStatus);
-       /*
-        * WARPDRIVE: If direct_io is set then it is directIO,
-        * the failed direct I/O should be redirected to volume
-        */
-       if (_scsih_scsi_direct_io_get(ioc, smid) &&
-           ((ioc_status & MPI2_IOCSTATUS_MASK)
-           != MPI2_IOCSTATUS_SCSI_TASK_TERMINATED)) {
-               spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-               ioc->scsi_lookup[smid - 1].scmd = scmd;
-               _scsih_scsi_direct_io_set(ioc, smid, 0);
-               spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
-               memcpy(mpi_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len);
-               mpi_request->DevHandle =
-                   cpu_to_le16(sas_device_priv_data->sas_target->handle);
-               mpt2sas_base_put_smid_scsi_io(ioc, smid,
-                   sas_device_priv_data->sas_target->handle);
-               return 0;
-       }
-
-
-       /* turning off TLR */
-       scsi_state = mpi_reply->SCSIState;
-       if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID)
-               response_code =
-                   le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF;
-       if (!sas_device_priv_data->tlr_snoop_check) {
-               sas_device_priv_data->tlr_snoop_check++;
-       /* Make sure Device is not raid volume.
-        * We do not expose raid functionality to upper layer for warpdrive.
-        */
-       if (!ioc->is_warpdrive && !_scsih_is_raid(&scmd->device->sdev_gendev) &&
-               sas_is_tlr_enabled(scmd->device) &&
-                   response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) {
-                       sas_disable_tlr(scmd->device);
-                       sdev_printk(KERN_INFO, scmd->device, "TLR disabled\n");
-               }
-       }
-
-       xfer_cnt = le32_to_cpu(mpi_reply->TransferCount);
-       scsi_set_resid(scmd, scsi_bufflen(scmd) - xfer_cnt);
-       if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE)
-               log_info =  le32_to_cpu(mpi_reply->IOCLogInfo);
-       else
-               log_info = 0;
-       ioc_status &= MPI2_IOCSTATUS_MASK;
-       scsi_status = mpi_reply->SCSIStatus;
-
-       if (ioc_status == MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
-           (scsi_status == MPI2_SCSI_STATUS_BUSY ||
-            scsi_status == MPI2_SCSI_STATUS_RESERVATION_CONFLICT ||
-            scsi_status == MPI2_SCSI_STATUS_TASK_SET_FULL)) {
-               ioc_status = MPI2_IOCSTATUS_SUCCESS;
-       }
-
-       if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) {
-               struct sense_info data;
-               const void *sense_data = mpt2sas_base_get_sense_buffer(ioc,
-                   smid);
-               u32 sz = min_t(u32, SCSI_SENSE_BUFFERSIZE,
-                   le32_to_cpu(mpi_reply->SenseCount));
-               memcpy(scmd->sense_buffer, sense_data, sz);
-               _scsih_normalize_sense(scmd->sense_buffer, &data);
-               /* failure prediction threshold exceeded */
-               if (data.asc == 0x5D)
-                       _scsih_smart_predicted_fault(ioc,
-                           le16_to_cpu(mpi_reply->DevHandle));
-       }
-
-       switch (ioc_status) {
-       case MPI2_IOCSTATUS_BUSY:
-       case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES:
-               scmd->result = SAM_STAT_BUSY;
-               break;
-
-       case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
-               scmd->result = DID_NO_CONNECT << 16;
-               break;
-
-       case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED:
-               if (sas_device_priv_data->block) {
-                       scmd->result = DID_TRANSPORT_DISRUPTED << 16;
-                       goto out;
-               }
-               if (log_info == 0x32010081) {
-                       scmd->result = DID_RESET << 16;
-                       break;
-               }
-               scmd->result = DID_SOFT_ERROR << 16;
-               break;
-       case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED:
-       case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
-               scmd->result = DID_RESET << 16;
-               break;
-
-       case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
-               if ((xfer_cnt == 0) || (scmd->underflow > xfer_cnt))
-                       scmd->result = DID_SOFT_ERROR << 16;
-               else
-                       scmd->result = (DID_OK << 16) | scsi_status;
-               break;
-
-       case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN:
-               scmd->result = (DID_OK << 16) | scsi_status;
-
-               if ((scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID))
-                       break;
-
-               if (xfer_cnt < scmd->underflow) {
-                       if (scsi_status == SAM_STAT_BUSY)
-                               scmd->result = SAM_STAT_BUSY;
-                       else
-                               scmd->result = DID_SOFT_ERROR << 16;
-               } else if (scsi_state & (MPI2_SCSI_STATE_AUTOSENSE_FAILED |
-                    MPI2_SCSI_STATE_NO_SCSI_STATUS))
-                       scmd->result = DID_SOFT_ERROR << 16;
-               else if (scsi_state & MPI2_SCSI_STATE_TERMINATED)
-                       scmd->result = DID_RESET << 16;
-               else if (!xfer_cnt && scmd->cmnd[0] == REPORT_LUNS) {
-                       mpi_reply->SCSIState = MPI2_SCSI_STATE_AUTOSENSE_VALID;
-                       mpi_reply->SCSIStatus = SAM_STAT_CHECK_CONDITION;
-                       scmd->result = (DRIVER_SENSE << 24) |
-                           SAM_STAT_CHECK_CONDITION;
-                       scmd->sense_buffer[0] = 0x70;
-                       scmd->sense_buffer[2] = ILLEGAL_REQUEST;
-                       scmd->sense_buffer[12] = 0x20;
-                       scmd->sense_buffer[13] = 0;
-               }
-               break;
-
-       case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN:
-               scsi_set_resid(scmd, 0);
-       case MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR:
-       case MPI2_IOCSTATUS_SUCCESS:
-               scmd->result = (DID_OK << 16) | scsi_status;
-               if (response_code ==
-                   MPI2_SCSITASKMGMT_RSP_INVALID_FRAME ||
-                   (scsi_state & (MPI2_SCSI_STATE_AUTOSENSE_FAILED |
-                    MPI2_SCSI_STATE_NO_SCSI_STATUS)))
-                       scmd->result = DID_SOFT_ERROR << 16;
-               else if (scsi_state & MPI2_SCSI_STATE_TERMINATED)
-                       scmd->result = DID_RESET << 16;
-               break;
-
-       case MPI2_IOCSTATUS_EEDP_GUARD_ERROR:
-       case MPI2_IOCSTATUS_EEDP_REF_TAG_ERROR:
-       case MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR:
-               _scsih_eedp_error_handling(scmd, ioc_status);
-               break;
-       case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR:
-       case MPI2_IOCSTATUS_INVALID_FUNCTION:
-       case MPI2_IOCSTATUS_INVALID_SGL:
-       case MPI2_IOCSTATUS_INTERNAL_ERROR:
-       case MPI2_IOCSTATUS_INVALID_FIELD:
-       case MPI2_IOCSTATUS_INVALID_STATE:
-       case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR:
-       case MPI2_IOCSTATUS_SCSI_TASK_MGMT_FAILED:
-       default:
-               scmd->result = DID_SOFT_ERROR << 16;
-               break;
-
-       }
-
-#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
-       if (scmd->result && (ioc->logging_level & MPT_DEBUG_REPLY))
-               _scsih_scsi_ioc_info(ioc , scmd, mpi_reply, smid);
-#endif
-
- out:
-       scsi_dma_unmap(scmd);
-       scmd->scsi_done(scmd);
-       return 1;
-}
-
-/**
- * _scsih_sas_host_refresh - refreshing sas host object contents
- * @ioc: per adapter object
- * Context: user
- *
- * During port enable, fw will send topology events for every device. Its
- * possible that the handles may change from the previous setting, so this
- * code keeping handles updating if changed.
- *
- * Return nothing.
- */
-static void
-_scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc)
-{
-       u16 sz;
-       u16 ioc_status;
-       int i;
-       Mpi2ConfigReply_t mpi_reply;
-       Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL;
-       u16 attached_handle;
-       u8 link_rate;
-
-       dtmprintk(ioc, printk(MPT2SAS_INFO_FMT
-           "updating handles for sas_host(0x%016llx)\n",
-           ioc->name, (unsigned long long)ioc->sas_hba.sas_address));
-
-       sz = offsetof(Mpi2SasIOUnitPage0_t, PhyData) + (ioc->sas_hba.num_phys
-           * sizeof(Mpi2SasIOUnit0PhyData_t));
-       sas_iounit_pg0 = kzalloc(sz, GFP_KERNEL);
-       if (!sas_iounit_pg0) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               return;
-       }
-
-       if ((mpt2sas_config_get_sas_iounit_pg0(ioc, &mpi_reply,
-           sas_iounit_pg0, sz)) != 0)
-               goto out;
-       ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
-       if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
-               goto out;
-       for (i = 0; i < ioc->sas_hba.num_phys ; i++) {
-               link_rate = sas_iounit_pg0->PhyData[i].NegotiatedLinkRate >> 4;
-               if (i == 0)
-                       ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0->
-                           PhyData[0].ControllerDevHandle);
-               ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle;
-               attached_handle = le16_to_cpu(sas_iounit_pg0->PhyData[i].
-                   AttachedDevHandle);
-               if (attached_handle && link_rate < MPI2_SAS_NEG_LINK_RATE_1_5)
-                       link_rate = MPI2_SAS_NEG_LINK_RATE_1_5;
-               mpt2sas_transport_update_links(ioc, ioc->sas_hba.sas_address,
-                   attached_handle, i, link_rate);
-       }
- out:
-       kfree(sas_iounit_pg0);
-}
-
-/**
- * _scsih_sas_host_add - create sas host object
- * @ioc: per adapter object
- *
- * Creating host side data object, stored in ioc->sas_hba
- *
- * Return nothing.
- */
-static void
-_scsih_sas_host_add(struct MPT2SAS_ADAPTER *ioc)
-{
-       int i;
-       Mpi2ConfigReply_t mpi_reply;
-       Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL;
-       Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
-       Mpi2SasPhyPage0_t phy_pg0;
-       Mpi2SasDevicePage0_t sas_device_pg0;
-       Mpi2SasEnclosurePage0_t enclosure_pg0;
-       u16 ioc_status;
-       u16 sz;
-       u16 device_missing_delay;
-
-       mpt2sas_config_get_number_hba_phys(ioc, &ioc->sas_hba.num_phys);
-       if (!ioc->sas_hba.num_phys) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               return;
-       }
-
-       /* sas_iounit page 0 */
-       sz = offsetof(Mpi2SasIOUnitPage0_t, PhyData) + (ioc->sas_hba.num_phys *
-           sizeof(Mpi2SasIOUnit0PhyData_t));
-       sas_iounit_pg0 = kzalloc(sz, GFP_KERNEL);
-       if (!sas_iounit_pg0) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               return;
-       }
-       if ((mpt2sas_config_get_sas_iounit_pg0(ioc, &mpi_reply,
-           sas_iounit_pg0, sz))) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               goto out;
-       }
-       ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-           MPI2_IOCSTATUS_MASK;
-       if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               goto out;
-       }
-
-       /* sas_iounit page 1 */
-       sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys *
-           sizeof(Mpi2SasIOUnit1PhyData_t));
-       sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
-       if (!sas_iounit_pg1) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               goto out;
-       }
-       if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply,
-           sas_iounit_pg1, sz))) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               goto out;
-       }
-       ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-           MPI2_IOCSTATUS_MASK;
-       if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               goto out;
-       }
-
-       ioc->io_missing_delay =
-           le16_to_cpu(sas_iounit_pg1->IODeviceMissingDelay);
-       device_missing_delay =
-           le16_to_cpu(sas_iounit_pg1->ReportDeviceMissingDelay);
-       if (device_missing_delay & MPI2_SASIOUNIT1_REPORT_MISSING_UNIT_16)
-               ioc->device_missing_delay = (device_missing_delay &
-                   MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16;
-       else
-               ioc->device_missing_delay = device_missing_delay &
-                   MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
-
-       ioc->sas_hba.parent_dev = &ioc->shost->shost_gendev;
-       ioc->sas_hba.phy = kcalloc(ioc->sas_hba.num_phys,
-           sizeof(struct _sas_phy), GFP_KERNEL);
-       if (!ioc->sas_hba.phy) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               goto out;
-       }
-       for (i = 0; i < ioc->sas_hba.num_phys ; i++) {
-               if ((mpt2sas_config_get_phy_pg0(ioc, &mpi_reply, &phy_pg0,
-                   i))) {
-                       printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                           ioc->name, __FILE__, __LINE__, __func__);
-                       goto out;
-               }
-               ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-                   MPI2_IOCSTATUS_MASK;
-               if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
-                       printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                           ioc->name, __FILE__, __LINE__, __func__);
-                       goto out;
-               }
-
-               if (i == 0)
-                       ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0->
-                           PhyData[0].ControllerDevHandle);
-               ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle;
-               ioc->sas_hba.phy[i].phy_id = i;
-               mpt2sas_transport_add_host_phy(ioc, &ioc->sas_hba.phy[i],
-                   phy_pg0, ioc->sas_hba.parent_dev);
-       }
-       if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
-           MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, ioc->sas_hba.handle))) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               goto out;
-       }
-       ioc->sas_hba.enclosure_handle =
-           le16_to_cpu(sas_device_pg0.EnclosureHandle);
-       ioc->sas_hba.sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
-       printk(MPT2SAS_INFO_FMT "host_add: handle(0x%04x), "
-           "sas_addr(0x%016llx), phys(%d)\n", ioc->name, ioc->sas_hba.handle,
-           (unsigned long long) ioc->sas_hba.sas_address,
-           ioc->sas_hba.num_phys) ;
-
-       if (ioc->sas_hba.enclosure_handle) {
-               if (!(mpt2sas_config_get_enclosure_pg0(ioc, &mpi_reply,
-                   &enclosure_pg0,
-                  MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE,
-                  ioc->sas_hba.enclosure_handle))) {
-                       ioc->sas_hba.enclosure_logical_id =
-                           le64_to_cpu(enclosure_pg0.EnclosureLogicalID);
-               }
-       }
-
- out:
-       kfree(sas_iounit_pg1);
-       kfree(sas_iounit_pg0);
-}
-
-/**
- * _scsih_expander_add -  creating expander object
- * @ioc: per adapter object
- * @handle: expander handle
- *
- * Creating expander object, stored in ioc->sas_expander_list.
- *
- * Return 0 for success, else error.
- */
-static int
-_scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle)
-{
-       struct _sas_node *sas_expander;
-       Mpi2ConfigReply_t mpi_reply;
-       Mpi2ExpanderPage0_t expander_pg0;
-       Mpi2ExpanderPage1_t expander_pg1;
-       Mpi2SasEnclosurePage0_t enclosure_pg0;
-       u32 ioc_status;
-       u16 parent_handle;
-       u64 sas_address, sas_address_parent = 0;
-       int i;
-       unsigned long flags;
-       struct _sas_port *mpt2sas_port = NULL;
-       int rc = 0;
-
-       if (!handle)
-               return -1;
-
-       if (ioc->shost_recovery || ioc->pci_error_recovery)
-               return -1;
-
-       if ((mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0,
-           MPI2_SAS_EXPAND_PGAD_FORM_HNDL, handle))) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               return -1;
-       }
-
-       ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-           MPI2_IOCSTATUS_MASK;
-       if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               return -1;
-       }
-
-       /* handle out of order topology events */
-       parent_handle = le16_to_cpu(expander_pg0.ParentDevHandle);
-       if (_scsih_get_sas_address(ioc, parent_handle, &sas_address_parent)
-           != 0) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               return -1;
-       }
-       if (sas_address_parent != ioc->sas_hba.sas_address) {
-               spin_lock_irqsave(&ioc->sas_node_lock, flags);
-               sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc,
-                   sas_address_parent);
-               spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
-               if (!sas_expander) {
-                       rc = _scsih_expander_add(ioc, parent_handle);
-                       if (rc != 0)
-                               return rc;
-               }
-       }
-
-       spin_lock_irqsave(&ioc->sas_node_lock, flags);
-       sas_address = le64_to_cpu(expander_pg0.SASAddress);
-       sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc,
-           sas_address);
-       spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
-
-       if (sas_expander)
-               return 0;
-
-       sas_expander = kzalloc(sizeof(struct _sas_node),
-           GFP_KERNEL);
-       if (!sas_expander) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               return -1;
-       }
-
-       sas_expander->handle = handle;
-       sas_expander->num_phys = expander_pg0.NumPhys;
-       sas_expander->sas_address_parent = sas_address_parent;
-       sas_expander->sas_address = sas_address;
-
-       printk(MPT2SAS_INFO_FMT "expander_add: handle(0x%04x),"
-           " parent(0x%04x), sas_addr(0x%016llx), phys(%d)\n", ioc->name,
-           handle, parent_handle, (unsigned long long)
-           sas_expander->sas_address, sas_expander->num_phys);
-
-       if (!sas_expander->num_phys)
-               goto out_fail;
-       sas_expander->phy = kcalloc(sas_expander->num_phys,
-           sizeof(struct _sas_phy), GFP_KERNEL);
-       if (!sas_expander->phy) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               rc = -1;
-               goto out_fail;
-       }
-
-       INIT_LIST_HEAD(&sas_expander->sas_port_list);
-       mpt2sas_port = mpt2sas_transport_port_add(ioc, handle,
-           sas_address_parent);
-       if (!mpt2sas_port) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               rc = -1;
-               goto out_fail;
-       }
-       sas_expander->parent_dev = &mpt2sas_port->rphy->dev;
-
-       for (i = 0 ; i < sas_expander->num_phys ; i++) {
-               if ((mpt2sas_config_get_expander_pg1(ioc, &mpi_reply,
-                   &expander_pg1, i, handle))) {
-                       printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                           ioc->name, __FILE__, __LINE__, __func__);
-                       rc = -1;
-                       goto out_fail;
-               }
-               sas_expander->phy[i].handle = handle;
-               sas_expander->phy[i].phy_id = i;
-
-               if ((mpt2sas_transport_add_expander_phy(ioc,
-                   &sas_expander->phy[i], expander_pg1,
-                   sas_expander->parent_dev))) {
-                       printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                           ioc->name, __FILE__, __LINE__, __func__);
-                       rc = -1;
-                       goto out_fail;
-               }
-       }
-
-       if (sas_expander->enclosure_handle) {
-               if (!(mpt2sas_config_get_enclosure_pg0(ioc, &mpi_reply,
-                   &enclosure_pg0, MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE,
-                  sas_expander->enclosure_handle))) {
-                       sas_expander->enclosure_logical_id =
-                           le64_to_cpu(enclosure_pg0.EnclosureLogicalID);
-               }
-       }
-
-       _scsih_expander_node_add(ioc, sas_expander);
-        return 0;
-
- out_fail:
-
-       if (mpt2sas_port)
-               mpt2sas_transport_port_remove(ioc, sas_expander->sas_address,
-                   sas_address_parent);
-       kfree(sas_expander);
-       return rc;
-}
-
-/**
- * _scsih_done -  scsih callback handler.
- * @ioc: per adapter object
- * @smid: system request message index
- * @msix_index: MSIX table index supplied by the OS
- * @reply: reply message frame(lower 32bit addr)
- *
- * Callback handler when sending internal generated message frames.
- * The callback index passed is `ioc->scsih_cb_idx`
- *
- * Return 1 meaning mf should be freed from _base_interrupt
- *        0 means the mf is freed from this function.
- */
-static u8
-_scsih_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
-{
-       MPI2DefaultReply_t *mpi_reply;
-
-       mpi_reply =  mpt2sas_base_get_reply_virt_addr(ioc, reply);
-       if (ioc->scsih_cmds.status == MPT2_CMD_NOT_USED)
-               return 1;
-       if (ioc->scsih_cmds.smid != smid)
-               return 1;
-       ioc->scsih_cmds.status |= MPT2_CMD_COMPLETE;
-       if (mpi_reply) {
-               memcpy(ioc->scsih_cmds.reply, mpi_reply,
-                   mpi_reply->MsgLength*4);
-               ioc->scsih_cmds.status |= MPT2_CMD_REPLY_VALID;
-       }
-       ioc->scsih_cmds.status &= ~MPT2_CMD_PENDING;
-       complete(&ioc->scsih_cmds.done);
-       return 1;
-}
-
-/**
- * mpt2sas_expander_remove - removing expander object
- * @ioc: per adapter object
- * @sas_address: expander sas_address
- *
- * Return nothing.
- */
-void
-mpt2sas_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address)
-{
-       struct _sas_node *sas_expander;
-       unsigned long flags;
-
-       if (ioc->shost_recovery)
-               return;
-
-       spin_lock_irqsave(&ioc->sas_node_lock, flags);
-       sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc,
-           sas_address);
-       if (sas_expander)
-               list_del(&sas_expander->list);
-       spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
-       if (sas_expander)
-               _scsih_expander_node_remove(ioc, sas_expander);
-}
-
-/**
- * _scsih_check_access_status - check access flags
- * @ioc: per adapter object
- * @sas_address: sas address
- * @handle: sas device handle
- * @access_flags: errors returned during discovery of the device
- *
- * Return 0 for success, else failure
- */
-static u8
-_scsih_check_access_status(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
-   u16 handle, u8 access_status)
-{
-       u8 rc = 1;
-       char *desc = NULL;
-
-       switch (access_status) {
-       case MPI2_SAS_DEVICE0_ASTATUS_NO_ERRORS:
-       case MPI2_SAS_DEVICE0_ASTATUS_SATA_NEEDS_INITIALIZATION:
-               rc = 0;
-               break;
-       case MPI2_SAS_DEVICE0_ASTATUS_SATA_CAPABILITY_FAILED:
-               desc = "sata capability failed";
-               break;
-       case MPI2_SAS_DEVICE0_ASTATUS_SATA_AFFILIATION_CONFLICT:
-               desc = "sata affiliation conflict";
-               break;
-       case MPI2_SAS_DEVICE0_ASTATUS_ROUTE_NOT_ADDRESSABLE:
-               desc = "route not addressable";
-               break;
-       case MPI2_SAS_DEVICE0_ASTATUS_SMP_ERROR_NOT_ADDRESSABLE:
-               desc = "smp error not addressable";
-               break;
-       case MPI2_SAS_DEVICE0_ASTATUS_DEVICE_BLOCKED:
-               desc = "device blocked";
-               break;
-       case MPI2_SAS_DEVICE0_ASTATUS_SATA_INIT_FAILED:
-       case MPI2_SAS_DEVICE0_ASTATUS_SIF_UNKNOWN:
-       case MPI2_SAS_DEVICE0_ASTATUS_SIF_AFFILIATION_CONFLICT:
-       case MPI2_SAS_DEVICE0_ASTATUS_SIF_DIAG:
-       case MPI2_SAS_DEVICE0_ASTATUS_SIF_IDENTIFICATION:
-       case MPI2_SAS_DEVICE0_ASTATUS_SIF_CHECK_POWER:
-       case MPI2_SAS_DEVICE0_ASTATUS_SIF_PIO_SN:
-       case MPI2_SAS_DEVICE0_ASTATUS_SIF_MDMA_SN:
-       case MPI2_SAS_DEVICE0_ASTATUS_SIF_UDMA_SN:
-       case MPI2_SAS_DEVICE0_ASTATUS_SIF_ZONING_VIOLATION:
-       case MPI2_SAS_DEVICE0_ASTATUS_SIF_NOT_ADDRESSABLE:
-       case MPI2_SAS_DEVICE0_ASTATUS_SIF_MAX:
-               desc = "sata initialization failed";
-               break;
-       default:
-               desc = "unknown";
-               break;
-       }
-
-       if (!rc)
-               return 0;
-
-       printk(MPT2SAS_ERR_FMT "discovery errors(%s): sas_address(0x%016llx), "
-           "handle(0x%04x)\n", ioc->name, desc,
-           (unsigned long long)sas_address, handle);
-       return rc;
-}
-
-static void
-_scsih_check_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
-{
-       Mpi2ConfigReply_t mpi_reply;
-       Mpi2SasDevicePage0_t sas_device_pg0;
-       struct _sas_device *sas_device;
-       u32 ioc_status;
-       unsigned long flags;
-       u64 sas_address;
-       struct scsi_target *starget;
-       struct MPT2SAS_TARGET *sas_target_priv_data;
-       u32 device_info;
-
-
-       if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
-           MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle)))
-               return;
-
-       ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
-       if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
-               return;
-
-       /* check if this is end device */
-       device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
-       if (!(_scsih_is_end_device(device_info)))
-               return;
-
-       spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
-       sas_device = __mpt2sas_get_sdev_by_addr(ioc,
-           sas_address);
-
-       if (!sas_device) {
-               printk(MPT2SAS_ERR_FMT "device is not present "
-                   "handle(0x%04x), no sas_device!!!\n", ioc->name, handle);
-               goto out_unlock;
-       }
-
-       if (unlikely(sas_device->handle != handle)) {
-               starget = sas_device->starget;
-               sas_target_priv_data = starget->hostdata;
-               starget_printk(KERN_INFO, starget, "handle changed from(0x%04x)"
-                  " to (0x%04x)!!!\n", sas_device->handle, handle);
-               sas_target_priv_data->handle = handle;
-               sas_device->handle = handle;
-       }
-
-       /* check if device is present */
-       if (!(le16_to_cpu(sas_device_pg0.Flags) &
-           MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)) {
-               printk(MPT2SAS_ERR_FMT "device is not present "
-                   "handle(0x%04x), flags!!!\n", ioc->name, handle);
-               goto out_unlock;
-       }
-
-       /* check if there were any issues with discovery */
-       if (_scsih_check_access_status(ioc, sas_address, handle,
-           sas_device_pg0.AccessStatus))
-               goto out_unlock;
-
-       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-       _scsih_ublock_io_device(ioc, sas_address);
-       if (sas_device)
-               sas_device_put(sas_device);
-       return;
-
-out_unlock:
-       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-       if (sas_device)
-               sas_device_put(sas_device);
-}
-
-/**
- * _scsih_add_device -  creating sas device object
- * @ioc: per adapter object
- * @handle: sas device handle
- * @phy_num: phy number end device attached to
- * @is_pd: is this hidden raid component
- *
- * Creating end device object, stored in ioc->sas_device_list.
- *
- * Returns 0 for success, non-zero for failure.
- */
-static int
-_scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd)
-{
-       Mpi2ConfigReply_t mpi_reply;
-       Mpi2SasDevicePage0_t sas_device_pg0;
-       Mpi2SasEnclosurePage0_t enclosure_pg0;
-       struct _sas_device *sas_device;
-       u32 ioc_status;
-       __le64 sas_address;
-       u32 device_info;
-
-       if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
-           MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               return -1;
-       }
-
-       ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-           MPI2_IOCSTATUS_MASK;
-       if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               return -1;
-       }
-
-       sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
-
-       /* check if device is present */
-       if (!(le16_to_cpu(sas_device_pg0.Flags) &
-           MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               printk(MPT2SAS_ERR_FMT "Flags = 0x%04x\n",
-                   ioc->name, le16_to_cpu(sas_device_pg0.Flags));
-               return -1;
-       }
-
-       /* check if there were any issues with discovery */
-       if (_scsih_check_access_status(ioc, sas_address, handle,
-           sas_device_pg0.AccessStatus))
-               return -1;
-
-       /* check if this is end device */
-       device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
-       if (!(_scsih_is_end_device(device_info))) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               return -1;
-       }
-
-       sas_device = mpt2sas_get_sdev_by_addr(ioc,
-           sas_address);
-
-       if (sas_device) {
-               sas_device_put(sas_device);
-               return 0;
-       }
-
-       sas_device = kzalloc(sizeof(struct _sas_device),
-           GFP_KERNEL);
-       if (!sas_device) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               return -1;
-       }
-
-       kref_init(&sas_device->refcount);
-       sas_device->handle = handle;
-       if (_scsih_get_sas_address(ioc, le16_to_cpu
-               (sas_device_pg0.ParentDevHandle),
-               &sas_device->sas_address_parent) != 0)
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-       sas_device->enclosure_handle =
-           le16_to_cpu(sas_device_pg0.EnclosureHandle);
-       sas_device->slot =
-           le16_to_cpu(sas_device_pg0.Slot);
-       sas_device->device_info = device_info;
-       sas_device->sas_address = sas_address;
-       sas_device->phy = sas_device_pg0.PhyNum;
-
-       /* get enclosure_logical_id */
-       if (sas_device->enclosure_handle && !(mpt2sas_config_get_enclosure_pg0(
-          ioc, &mpi_reply, &enclosure_pg0, MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE,
-          sas_device->enclosure_handle)))
-               sas_device->enclosure_logical_id =
-                   le64_to_cpu(enclosure_pg0.EnclosureLogicalID);
-
-       /* get device name */
-       sas_device->device_name = le64_to_cpu(sas_device_pg0.DeviceName);
-
-       if (ioc->wait_for_discovery_to_complete)
-               _scsih_sas_device_init_add(ioc, sas_device);
-       else
-               _scsih_sas_device_add(ioc, sas_device);
-
-       sas_device_put(sas_device);
-       return 0;
-}
-
-/**
- * _scsih_remove_device -  removing sas device object
- * @ioc: per adapter object
- * @sas_device_delete: the sas_device object
- *
- * Return nothing.
- */
-static void
-_scsih_remove_device(struct MPT2SAS_ADAPTER *ioc,
-    struct _sas_device *sas_device)
-{
-       struct MPT2SAS_TARGET *sas_target_priv_data;
-
-       if ((ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM) &&
-               (sas_device->pfa_led_on)) {
-               _scsih_turn_off_pfa_led(ioc, sas_device);
-               sas_device->pfa_led_on = 0;
-       }
-
-       dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: "
-           "handle(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__,
-               sas_device->handle, (unsigned long long)
-           sas_device->sas_address));
-
-       if (sas_device->starget && sas_device->starget->hostdata) {
-               sas_target_priv_data = sas_device->starget->hostdata;
-               sas_target_priv_data->deleted = 1;
-               _scsih_ublock_io_device(ioc, sas_device->sas_address);
-               sas_target_priv_data->handle =
-                    MPT2SAS_INVALID_DEVICE_HANDLE;
-       }
-
-       if (!ioc->hide_drives)
-               mpt2sas_transport_port_remove(ioc,
-                   sas_device->sas_address,
-                   sas_device->sas_address_parent);
-
-       printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr"
-           "(0x%016llx)\n", ioc->name, sas_device->handle,
-           (unsigned long long) sas_device->sas_address);
-
-       dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: exit: "
-           "handle(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__,
-           sas_device->handle, (unsigned long long)
-           sas_device->sas_address));
-}
-/**
- * _scsih_device_remove_by_handle - removing device object by handle
- * @ioc: per adapter object
- * @handle: device handle
- *
- * Return nothing.
- */
-static void
-_scsih_device_remove_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
-{
-       struct _sas_device *sas_device;
-       unsigned long flags;
-
-       if (ioc->shost_recovery)
-               return;
-
-       spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       sas_device = __mpt2sas_get_sdev_by_handle(ioc, handle);
-       if (sas_device) {
-               list_del_init(&sas_device->list);
-               sas_device_put(sas_device);
-       }
-       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-
-       if (sas_device) {
-               _scsih_remove_device(ioc, sas_device);
-               sas_device_put(sas_device);
-       }
-}
-
-/**
- * mpt2sas_device_remove_by_sas_address - removing device object by sas address
- * @ioc: per adapter object
- * @sas_address: device sas_address
- *
- * Return nothing.
- */
-void
-mpt2sas_device_remove_by_sas_address(struct MPT2SAS_ADAPTER *ioc,
-       u64 sas_address)
-{
-       struct _sas_device *sas_device;
-       unsigned long flags;
-
-       if (ioc->shost_recovery)
-               return;
-
-       spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       sas_device = __mpt2sas_get_sdev_by_addr(ioc, sas_address);
-       if (sas_device) {
-               list_del_init(&sas_device->list);
-               sas_device_put(sas_device);
-       }
-       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-
-       if (sas_device) {
-               _scsih_remove_device(ioc, sas_device);
-               sas_device_put(sas_device);
-       }
-}
-#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
-/**
- * _scsih_sas_topology_change_event_debug - debug for topology event
- * @ioc: per adapter object
- * @event_data: event data payload
- * Context: user.
- */
-static void
-_scsih_sas_topology_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2EventDataSasTopologyChangeList_t *event_data)
-{
-       int i;
-       u16 handle;
-       u16 reason_code;
-       u8 phy_number;
-       char *status_str = NULL;
-       u8 link_rate, prev_link_rate;
-
-       switch (event_data->ExpStatus) {
-       case MPI2_EVENT_SAS_TOPO_ES_ADDED:
-               status_str = "add";
-               break;
-       case MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING:
-               status_str = "remove";
-               break;
-       case MPI2_EVENT_SAS_TOPO_ES_RESPONDING:
-       case 0:
-               status_str =  "responding";
-               break;
-       case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING:
-               status_str = "remove delay";
-               break;
-       default:
-               status_str = "unknown status";
-               break;
-       }
-       printk(MPT2SAS_INFO_FMT "sas topology change: (%s)\n",
-           ioc->name, status_str);
-       printk(KERN_INFO "\thandle(0x%04x), enclosure_handle(0x%04x) "
-           "start_phy(%02d), count(%d)\n",
-           le16_to_cpu(event_data->ExpanderDevHandle),
-           le16_to_cpu(event_data->EnclosureHandle),
-           event_data->StartPhyNum, event_data->NumEntries);
-       for (i = 0; i < event_data->NumEntries; i++) {
-               handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
-               if (!handle)
-                       continue;
-               phy_number = event_data->StartPhyNum + i;
-               reason_code = event_data->PHY[i].PhyStatus &
-                   MPI2_EVENT_SAS_TOPO_RC_MASK;
-               switch (reason_code) {
-               case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
-                       status_str = "target add";
-                       break;
-               case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
-                       status_str = "target remove";
-                       break;
-               case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING:
-                       status_str = "delay target remove";
-                       break;
-               case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
-                       status_str = "link rate change";
-                       break;
-               case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE:
-                       status_str = "target responding";
-                       break;
-               default:
-                       status_str = "unknown";
-                       break;
-               }
-               link_rate = event_data->PHY[i].LinkRate >> 4;
-               prev_link_rate = event_data->PHY[i].LinkRate & 0xF;
-               printk(KERN_INFO "\tphy(%02d), attached_handle(0x%04x): %s:"
-                   " link rate: new(0x%02x), old(0x%02x)\n", phy_number,
-                   handle, status_str, link_rate, prev_link_rate);
-
-       }
-}
-#endif
-
-/**
- * _scsih_sas_topology_change_event - handle topology changes
- * @ioc: per adapter object
- * @fw_event: The fw_event_work object
- * Context: user.
- *
- */
-static void
-_scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
-    struct fw_event_work *fw_event)
-{
-       int i;
-       u16 parent_handle, handle;
-       u16 reason_code;
-       u8 phy_number, max_phys;
-       struct _sas_node *sas_expander;
-       u64 sas_address;
-       unsigned long flags;
-       u8 link_rate, prev_link_rate;
-       Mpi2EventDataSasTopologyChangeList_t *event_data =
-               (Mpi2EventDataSasTopologyChangeList_t *)
-               fw_event->event_data;
-
-#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
-       if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
-               _scsih_sas_topology_change_event_debug(ioc, event_data);
-#endif
-
-       if (ioc->remove_host || ioc->pci_error_recovery)
-               return;
-
-       if (!ioc->sas_hba.num_phys)
-               _scsih_sas_host_add(ioc);
-       else
-               _scsih_sas_host_refresh(ioc);
-
-       if (fw_event->ignore) {
-               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "ignoring expander "
-                   "event\n", ioc->name));
-               return;
-       }
-
-       parent_handle = le16_to_cpu(event_data->ExpanderDevHandle);
-
-       /* handle expander add */
-       if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_ADDED)
-               if (_scsih_expander_add(ioc, parent_handle) != 0)
-                       return;
-
-       spin_lock_irqsave(&ioc->sas_node_lock, flags);
-       sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc,
-           parent_handle);
-       if (sas_expander) {
-               sas_address = sas_expander->sas_address;
-               max_phys = sas_expander->num_phys;
-       } else if (parent_handle < ioc->sas_hba.num_phys) {
-               sas_address = ioc->sas_hba.sas_address;
-               max_phys = ioc->sas_hba.num_phys;
-       } else {
-       spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
-               return;
-       }
-       spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
-
-       /* handle siblings events */
-       for (i = 0; i < event_data->NumEntries; i++) {
-               if (fw_event->ignore) {
-                       dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "ignoring "
-                           "expander event\n", ioc->name));
-                       return;
-               }
-               if (ioc->shost_recovery || ioc->remove_host ||
-                   ioc->pci_error_recovery)
-                       return;
-               phy_number = event_data->StartPhyNum + i;
-               if (phy_number >= max_phys)
-                       continue;
-               reason_code = event_data->PHY[i].PhyStatus &
-                   MPI2_EVENT_SAS_TOPO_RC_MASK;
-               if ((event_data->PHY[i].PhyStatus &
-                   MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT) && (reason_code !=
-                   MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING))
-                       continue;
-               handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
-               if (!handle)
-                       continue;
-               link_rate = event_data->PHY[i].LinkRate >> 4;
-               prev_link_rate = event_data->PHY[i].LinkRate & 0xF;
-               switch (reason_code) {
-               case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
-
-                       if (ioc->shost_recovery)
-                               break;
-
-                       if (link_rate == prev_link_rate)
-                               break;
-
-                       mpt2sas_transport_update_links(ioc, sas_address,
-                           handle, phy_number, link_rate);
-
-                       if (link_rate < MPI2_SAS_NEG_LINK_RATE_1_5)
-                               break;
-
-                       _scsih_check_device(ioc, handle);
-                       break;
-               case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
-
-                       if (ioc->shost_recovery)
-                               break;
-
-                       mpt2sas_transport_update_links(ioc, sas_address,
-                           handle, phy_number, link_rate);
-
-                       _scsih_add_device(ioc, handle, phy_number, 0);
-                       break;
-               case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
-
-                       _scsih_device_remove_by_handle(ioc, handle);
-                       break;
-               }
-       }
-
-       /* handle expander removal */
-       if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING &&
-           sas_expander)
-               mpt2sas_expander_remove(ioc, sas_address);
-
-}
-
-#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
-/**
- * _scsih_sas_device_status_change_event_debug - debug for device event
- * @event_data: event data payload
- * Context: user.
- *
- * Return nothing.
- */
-static void
-_scsih_sas_device_status_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2EventDataSasDeviceStatusChange_t *event_data)
-{
-       char *reason_str = NULL;
-
-       switch (event_data->ReasonCode) {
-       case MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
-               reason_str = "smart data";
-               break;
-       case MPI2_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
-               reason_str = "unsupported device discovered";
-               break;
-       case MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
-               reason_str = "internal device reset";
-               break;
-       case MPI2_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
-               reason_str = "internal task abort";
-               break;
-       case MPI2_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
-               reason_str = "internal task abort set";
-               break;
-       case MPI2_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
-               reason_str = "internal clear task set";
-               break;
-       case MPI2_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
-               reason_str = "internal query task";
-               break;
-       case MPI2_EVENT_SAS_DEV_STAT_RC_SATA_INIT_FAILURE:
-               reason_str = "sata init failure";
-               break;
-       case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET:
-               reason_str = "internal device reset complete";
-               break;
-       case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_TASK_ABORT_INTERNAL:
-               reason_str = "internal task abort complete";
-               break;
-       case MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION:
-               reason_str = "internal async notification";
-               break;
-       case MPI2_EVENT_SAS_DEV_STAT_RC_EXPANDER_REDUCED_FUNCTIONALITY:
-               reason_str = "expander reduced functionality";
-               break;
-       case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_EXPANDER_REDUCED_FUNCTIONALITY:
-               reason_str = "expander reduced functionality complete";
-               break;
-       default:
-               reason_str = "unknown reason";
-               break;
-       }
-       printk(MPT2SAS_INFO_FMT "device status change: (%s)\n"
-           "\thandle(0x%04x), sas address(0x%016llx), tag(%d)",
-           ioc->name, reason_str, le16_to_cpu(event_data->DevHandle),
-           (unsigned long long)le64_to_cpu(event_data->SASAddress),
-           le16_to_cpu(event_data->TaskTag));
-       if (event_data->ReasonCode == MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA)
-               printk(MPT2SAS_INFO_FMT ", ASC(0x%x), ASCQ(0x%x)\n", ioc->name,
-                   event_data->ASC, event_data->ASCQ);
-       printk(KERN_INFO "\n");
-}
-#endif
-
-/**
- * _scsih_sas_device_status_change_event - handle device status change
- * @ioc: per adapter object
- * @fw_event: The fw_event_work object
- * Context: user.
- *
- * Return nothing.
- */
-static void
-_scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc,
-    struct fw_event_work *fw_event)
-{
-       struct MPT2SAS_TARGET *target_priv_data;
-       struct _sas_device *sas_device;
-       u64 sas_address;
-       unsigned long flags;
-       Mpi2EventDataSasDeviceStatusChange_t *event_data =
-               (Mpi2EventDataSasDeviceStatusChange_t *)
-               fw_event->event_data;
-
-#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
-       if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
-               _scsih_sas_device_status_change_event_debug(ioc,
-                    event_data);
-#endif
-
-       /* In MPI Revision K (0xC), the internal device reset complete was
-        * implemented, so avoid setting tm_busy flag for older firmware.
-        */
-       if ((ioc->facts.HeaderVersion >> 8) < 0xC)
-               return;
-
-       if (event_data->ReasonCode !=
-           MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET &&
-          event_data->ReasonCode !=
-           MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET)
-               return;
-
-       spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       sas_address = le64_to_cpu(event_data->SASAddress);
-       sas_device = __mpt2sas_get_sdev_by_addr(ioc,
-           sas_address);
-
-       if (!sas_device || !sas_device->starget)
-               goto out;
-
-       target_priv_data = sas_device->starget->hostdata;
-       if (!target_priv_data)
-               goto out;
-
-       if (event_data->ReasonCode ==
-           MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET)
-               target_priv_data->tm_busy = 1;
-       else
-               target_priv_data->tm_busy = 0;
-
-out:
-       if (sas_device)
-               sas_device_put(sas_device);
-
-       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-
-}
-
-#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
-/**
- * _scsih_sas_enclosure_dev_status_change_event_debug - debug for enclosure event
- * @ioc: per adapter object
- * @event_data: event data payload
- * Context: user.
- *
- * Return nothing.
- */
-static void
-_scsih_sas_enclosure_dev_status_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2EventDataSasEnclDevStatusChange_t *event_data)
-{
-       char *reason_str = NULL;
-
-       switch (event_data->ReasonCode) {
-       case MPI2_EVENT_SAS_ENCL_RC_ADDED:
-               reason_str = "enclosure add";
-               break;
-       case MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING:
-               reason_str = "enclosure remove";
-               break;
-       default:
-               reason_str = "unknown reason";
-               break;
-       }
-
-       printk(MPT2SAS_INFO_FMT "enclosure status change: (%s)\n"
-           "\thandle(0x%04x), enclosure logical id(0x%016llx)"
-           " number slots(%d)\n", ioc->name, reason_str,
-           le16_to_cpu(event_data->EnclosureHandle),
-           (unsigned long long)le64_to_cpu(event_data->EnclosureLogicalID),
-           le16_to_cpu(event_data->StartSlot));
-}
-#endif
-
-/**
- * _scsih_sas_enclosure_dev_status_change_event - handle enclosure events
- * @ioc: per adapter object
- * @fw_event: The fw_event_work object
- * Context: user.
- *
- * Return nothing.
- */
-static void
-_scsih_sas_enclosure_dev_status_change_event(struct MPT2SAS_ADAPTER *ioc,
-    struct fw_event_work *fw_event)
-{
-#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
-       if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
-               _scsih_sas_enclosure_dev_status_change_event_debug(ioc,
-                    (Mpi2EventDataSasEnclDevStatusChange_t *)
-                    fw_event->event_data);
-#endif
-}
-
-/**
- * _scsih_sas_broadcast_primitive_event - handle broadcast events
- * @ioc: per adapter object
- * @fw_event: The fw_event_work object
- * Context: user.
- *
- * Return nothing.
- */
-static void
-_scsih_sas_broadcast_primitive_event(struct MPT2SAS_ADAPTER *ioc,
-    struct fw_event_work *fw_event)
-{
-       struct scsi_cmnd *scmd;
-       struct scsi_device *sdev;
-       u16 smid, handle;
-       u32 lun;
-       struct MPT2SAS_DEVICE *sas_device_priv_data;
-       u32 termination_count;
-       u32 query_count;
-       Mpi2SCSITaskManagementReply_t *mpi_reply;
-       Mpi2EventDataSasBroadcastPrimitive_t *event_data =
-               (Mpi2EventDataSasBroadcastPrimitive_t *)
-               fw_event->event_data;
-       u16 ioc_status;
-       unsigned long flags;
-       int r;
-       u8 max_retries = 0;
-       u8 task_abort_retries;
-
-       mutex_lock(&ioc->tm_cmds.mutex);
-       pr_info(MPT2SAS_FMT
-               "%s: enter: phy number(%d), width(%d)\n",
-               ioc->name, __func__, event_data->PhyNum,
-               event_data->PortWidth);
-
-       _scsih_block_io_all_device(ioc);
-
-       spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-       mpi_reply = ioc->tm_cmds.reply;
-broadcast_aen_retry:
-
-       /* sanity checks for retrying this loop */
-       if (max_retries++ == 5) {
-               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: giving up\n",
-                   ioc->name, __func__));
-               goto out;
-       } else if (max_retries > 1)
-               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: %d retry\n",
-                   ioc->name, __func__, max_retries - 1));
-
-       termination_count = 0;
-       query_count = 0;
-       for (smid = 1; smid <= ioc->scsiio_depth; smid++) {
-               if (ioc->shost_recovery)
-                       goto out;
-               scmd = _scsih_scsi_lookup_get(ioc, smid);
-               if (!scmd)
-                       continue;
-               sdev = scmd->device;
-               sas_device_priv_data = sdev->hostdata;
-               if (!sas_device_priv_data || !sas_device_priv_data->sas_target)
-                       continue;
-                /* skip hidden raid components */
-               if (sas_device_priv_data->sas_target->flags &
-                   MPT_TARGET_FLAGS_RAID_COMPONENT)
-                       continue;
-                /* skip volumes */
-               if (sas_device_priv_data->sas_target->flags &
-                   MPT_TARGET_FLAGS_VOLUME)
-                       continue;
-
-               handle = sas_device_priv_data->sas_target->handle;
-               lun = sas_device_priv_data->lun;
-               query_count++;
-
-               if (ioc->shost_recovery)
-                       goto out;
-
-               spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
-               r = mpt2sas_scsih_issue_tm(ioc, handle, 0, 0, lun,
-                   MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30,
-                   TM_MUTEX_OFF);
-               if (r == FAILED) {
-                       sdev_printk(KERN_WARNING, sdev,
-                           "mpt2sas_scsih_issue_tm: FAILED when sending "
-                           "QUERY_TASK: scmd(%p)\n", scmd);
-                       spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-                       goto broadcast_aen_retry;
-               }
-               ioc_status = le16_to_cpu(mpi_reply->IOCStatus)
-                   & MPI2_IOCSTATUS_MASK;
-               if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
-                       sdev_printk(KERN_WARNING, sdev, "query task: FAILED "
-                           "with IOCSTATUS(0x%04x), scmd(%p)\n", ioc_status,
-                           scmd);
-                       spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-                       goto broadcast_aen_retry;
-               }
-
-               /* see if IO is still owned by IOC and target */
-               if (mpi_reply->ResponseCode ==
-                    MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED ||
-                    mpi_reply->ResponseCode ==
-                    MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC) {
-                       spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-                       continue;
-               }
-               task_abort_retries = 0;
- tm_retry:
-               if (task_abort_retries++ == 60) {
-                       dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
-                           "%s: ABORT_TASK: giving up\n", ioc->name,
-                           __func__));
-                       spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-                       goto broadcast_aen_retry;
-               }
-
-               if (ioc->shost_recovery)
-                       goto out_no_lock;
-
-               r = mpt2sas_scsih_issue_tm(ioc, handle, sdev->channel, sdev->id,
-                   sdev->lun, MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30,
-                   TM_MUTEX_OFF);
-               if (r == FAILED) {
-                       sdev_printk(KERN_WARNING, sdev,
-                           "mpt2sas_scsih_issue_tm: ABORT_TASK: FAILED : "
-                           "scmd(%p)\n", scmd);
-                       goto tm_retry;
-               }
-
-               if (task_abort_retries > 1)
-                       sdev_printk(KERN_WARNING, sdev,
-                           "mpt2sas_scsih_issue_tm: ABORT_TASK: RETRIES (%d):"
-                           " scmd(%p)\n",
-                           task_abort_retries - 1, scmd);
-
-               termination_count += le32_to_cpu(mpi_reply->TerminationCount);
-               spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-       }
-
-       if (ioc->broadcast_aen_pending) {
-               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: loop back due to"
-                    " pending AEN\n", ioc->name, __func__));
-                ioc->broadcast_aen_pending = 0;
-                goto broadcast_aen_retry;
-       }
-
- out:
-       spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
- out_no_lock:
-
-       dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
-           "%s - exit, query_count = %d termination_count = %d\n",
-           ioc->name, __func__, query_count, termination_count));
-
-       ioc->broadcast_aen_busy = 0;
-       if (!ioc->shost_recovery)
-               _scsih_ublock_io_all_device(ioc);
-       mutex_unlock(&ioc->tm_cmds.mutex);
-}
-
-/**
- * _scsih_sas_discovery_event - handle discovery events
- * @ioc: per adapter object
- * @fw_event: The fw_event_work object
- * Context: user.
- *
- * Return nothing.
- */
-static void
-_scsih_sas_discovery_event(struct MPT2SAS_ADAPTER *ioc,
-    struct fw_event_work *fw_event)
-{
-       Mpi2EventDataSasDiscovery_t *event_data =
-               (Mpi2EventDataSasDiscovery_t *)
-               fw_event->event_data;
-
-#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
-       if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) {
-               printk(MPT2SAS_INFO_FMT "discovery event: (%s)", ioc->name,
-                   (event_data->ReasonCode == MPI2_EVENT_SAS_DISC_RC_STARTED) ?
-                   "start" : "stop");
-       if (event_data->DiscoveryStatus)
-               printk("discovery_status(0x%08x)",
-                   le32_to_cpu(event_data->DiscoveryStatus));
-       printk("\n");
-       }
-#endif
-
-       if (event_data->ReasonCode == MPI2_EVENT_SAS_DISC_RC_STARTED &&
-           !ioc->sas_hba.num_phys) {
-               if (disable_discovery > 0 && ioc->shost_recovery) {
-                       /* Wait for the reset to complete */
-                       while (ioc->shost_recovery)
-                               ssleep(1);
-               }
-               _scsih_sas_host_add(ioc);
-       }
-}
-
-/**
- * _scsih_reprobe_lun - reprobing lun
- * @sdev: scsi device struct
- * @no_uld_attach: sdev->no_uld_attach flag setting
- *
- **/
-static void
-_scsih_reprobe_lun(struct scsi_device *sdev, void *no_uld_attach)
-{
-       int rc;
-
-       sdev->no_uld_attach = no_uld_attach ? 1 : 0;
-       sdev_printk(KERN_INFO, sdev, "%s raid component\n",
-           sdev->no_uld_attach ? "hidding" : "exposing");
-       rc = scsi_device_reprobe(sdev);
-}
-
-/**
- * _scsih_sas_volume_add - add new volume
- * @ioc: per adapter object
- * @element: IR config element data
- * Context: user.
- *
- * Return nothing.
- */
-static void
-_scsih_sas_volume_add(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2EventIrConfigElement_t *element)
-{
-       struct _raid_device *raid_device;
-       unsigned long flags;
-       u64 wwid;
-       u16 handle = le16_to_cpu(element->VolDevHandle);
-       int rc;
-
-       mpt2sas_config_get_volume_wwid(ioc, handle, &wwid);
-       if (!wwid) {
-               printk(MPT2SAS_ERR_FMT
-                   "failure at %s:%d/%s()!\n", ioc->name,
-                   __FILE__, __LINE__, __func__);
-               return;
-       }
-
-       spin_lock_irqsave(&ioc->raid_device_lock, flags);
-       raid_device = _scsih_raid_device_find_by_wwid(ioc, wwid);
-       spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
-
-       if (raid_device)
-               return;
-
-       raid_device = kzalloc(sizeof(struct _raid_device), GFP_KERNEL);
-       if (!raid_device) {
-               printk(MPT2SAS_ERR_FMT
-                   "failure at %s:%d/%s()!\n", ioc->name,
-                   __FILE__, __LINE__, __func__);
-               return;
-       }
-
-       raid_device->id = ioc->sas_id++;
-       raid_device->channel = RAID_CHANNEL;
-       raid_device->handle = handle;
-       raid_device->wwid = wwid;
-       _scsih_raid_device_add(ioc, raid_device);
-       if (!ioc->wait_for_discovery_to_complete) {
-               rc = scsi_add_device(ioc->shost, RAID_CHANNEL,
-                   raid_device->id, 0);
-               if (rc)
-                       _scsih_raid_device_remove(ioc, raid_device);
-       } else {
-               spin_lock_irqsave(&ioc->raid_device_lock, flags);
-               _scsih_determine_boot_device(ioc, raid_device, 1);
-               spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
-       }
-}
-
-/**
- * _scsih_sas_volume_delete - delete volume
- * @ioc: per adapter object
- * @handle: volume device handle
- * Context: user.
- *
- * Return nothing.
- */
-static void
-_scsih_sas_volume_delete(struct MPT2SAS_ADAPTER *ioc, u16 handle)
-{
-       struct _raid_device *raid_device;
-       unsigned long flags;
-       struct MPT2SAS_TARGET *sas_target_priv_data;
-       struct scsi_target *starget = NULL;
-
-       spin_lock_irqsave(&ioc->raid_device_lock, flags);
-       raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
-       if (raid_device) {
-               if (raid_device->starget) {
-                       starget = raid_device->starget;
-                       sas_target_priv_data = starget->hostdata;
-                       sas_target_priv_data->deleted = 1;
-               }
-               printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), wwid"
-                   "(0x%016llx)\n", ioc->name,  raid_device->handle,
-                   (unsigned long long) raid_device->wwid);
-               list_del(&raid_device->list);
-               kfree(raid_device);
-       }
-       spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
-       if (starget)
-               scsi_remove_target(&starget->dev);
-}
-
-/**
- * _scsih_sas_pd_expose - expose pd component to /dev/sdX
- * @ioc: per adapter object
- * @element: IR config element data
- * Context: user.
- *
- * Return nothing.
- */
-static void
-_scsih_sas_pd_expose(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2EventIrConfigElement_t *element)
-{
-       struct _sas_device *sas_device;
-       struct scsi_target *starget = NULL;
-       struct MPT2SAS_TARGET *sas_target_priv_data;
-       unsigned long flags;
-       u16 handle = le16_to_cpu(element->PhysDiskDevHandle);
-
-       spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       sas_device = __mpt2sas_get_sdev_by_handle(ioc, handle);
-       if (sas_device) {
-               sas_device->volume_handle = 0;
-               sas_device->volume_wwid = 0;
-               clear_bit(handle, ioc->pd_handles);
-               if (sas_device->starget && sas_device->starget->hostdata) {
-                       starget = sas_device->starget;
-                       sas_target_priv_data = starget->hostdata;
-                       sas_target_priv_data->flags &=
-                           ~MPT_TARGET_FLAGS_RAID_COMPONENT;
-               }
-       }
-       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-       if (!sas_device)
-               return;
-
-       /* exposing raid component */
-       if (starget)
-               starget_for_each_device(starget, NULL, _scsih_reprobe_lun);
-
-       sas_device_put(sas_device);
-}
-
-/**
- * _scsih_sas_pd_hide - hide pd component from /dev/sdX
- * @ioc: per adapter object
- * @element: IR config element data
- * Context: user.
- *
- * Return nothing.
- */
-static void
-_scsih_sas_pd_hide(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2EventIrConfigElement_t *element)
-{
-       struct _sas_device *sas_device;
-       struct scsi_target *starget = NULL;
-       struct MPT2SAS_TARGET *sas_target_priv_data;
-       unsigned long flags;
-       u16 handle = le16_to_cpu(element->PhysDiskDevHandle);
-       u16 volume_handle = 0;
-       u64 volume_wwid = 0;
-
-       mpt2sas_config_get_volume_handle(ioc, handle, &volume_handle);
-       if (volume_handle)
-               mpt2sas_config_get_volume_wwid(ioc, volume_handle,
-                   &volume_wwid);
-
-       spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       sas_device = __mpt2sas_get_sdev_by_handle(ioc, handle);
-       if (sas_device) {
-               set_bit(handle, ioc->pd_handles);
-               if (sas_device->starget && sas_device->starget->hostdata) {
-                       starget = sas_device->starget;
-                       sas_target_priv_data = starget->hostdata;
-                       sas_target_priv_data->flags |=
-                           MPT_TARGET_FLAGS_RAID_COMPONENT;
-                       sas_device->volume_handle = volume_handle;
-                       sas_device->volume_wwid = volume_wwid;
-               }
-       }
-       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-       if (!sas_device)
-               return;
-
-       /* hiding raid component */
-       if (starget)
-               starget_for_each_device(starget, (void *)1, _scsih_reprobe_lun);
-
-       sas_device_put(sas_device);
-}
-
-/**
- * _scsih_sas_pd_delete - delete pd component
- * @ioc: per adapter object
- * @element: IR config element data
- * Context: user.
- *
- * Return nothing.
- */
-static void
-_scsih_sas_pd_delete(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2EventIrConfigElement_t *element)
-{
-       u16 handle = le16_to_cpu(element->PhysDiskDevHandle);
-
-       _scsih_device_remove_by_handle(ioc, handle);
-}
-
-/**
- * _scsih_sas_pd_add - remove pd component
- * @ioc: per adapter object
- * @element: IR config element data
- * Context: user.
- *
- * Return nothing.
- */
-static void
-_scsih_sas_pd_add(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2EventIrConfigElement_t *element)
-{
-       struct _sas_device *sas_device;
-       u16 handle = le16_to_cpu(element->PhysDiskDevHandle);
-       Mpi2ConfigReply_t mpi_reply;
-       Mpi2SasDevicePage0_t sas_device_pg0;
-       u32 ioc_status;
-       u64 sas_address;
-       u16 parent_handle;
-
-       set_bit(handle, ioc->pd_handles);
-
-       sas_device = mpt2sas_get_sdev_by_handle(ioc, handle);
-       if (sas_device) {
-               sas_device_put(sas_device);
-               return;
-       }
-
-       if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
-           MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               return;
-       }
-
-       ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-           MPI2_IOCSTATUS_MASK;
-       if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               return;
-       }
-
-       parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
-       if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address))
-               mpt2sas_transport_update_links(ioc, sas_address, handle,
-                   sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
-
-       _scsih_add_device(ioc, handle, 0, 1);
-}
-
-#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
-/**
- * _scsih_sas_ir_config_change_event_debug - debug for IR Config Change events
- * @ioc: per adapter object
- * @event_data: event data payload
- * Context: user.
- *
- * Return nothing.
- */
-static void
-_scsih_sas_ir_config_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2EventDataIrConfigChangeList_t *event_data)
-{
-       Mpi2EventIrConfigElement_t *element;
-       u8 element_type;
-       int i;
-       char *reason_str = NULL, *element_str = NULL;
-
-       element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
-
-       printk(MPT2SAS_INFO_FMT "raid config change: (%s), elements(%d)\n",
-           ioc->name, (le32_to_cpu(event_data->Flags) &
-           MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ?
-           "foreign" : "native", event_data->NumElements);
-       for (i = 0; i < event_data->NumElements; i++, element++) {
-               switch (element->ReasonCode) {
-               case MPI2_EVENT_IR_CHANGE_RC_ADDED:
-                       reason_str = "add";
-                       break;
-               case MPI2_EVENT_IR_CHANGE_RC_REMOVED:
-                       reason_str = "remove";
-                       break;
-               case MPI2_EVENT_IR_CHANGE_RC_NO_CHANGE:
-                       reason_str = "no change";
-                       break;
-               case MPI2_EVENT_IR_CHANGE_RC_HIDE:
-                       reason_str = "hide";
-                       break;
-               case MPI2_EVENT_IR_CHANGE_RC_UNHIDE:
-                       reason_str = "unhide";
-                       break;
-               case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED:
-                       reason_str = "volume_created";
-                       break;
-               case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED:
-                       reason_str = "volume_deleted";
-                       break;
-               case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED:
-                       reason_str = "pd_created";
-                       break;
-               case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED:
-                       reason_str = "pd_deleted";
-                       break;
-               default:
-                       reason_str = "unknown reason";
-                       break;
-               }
-               element_type = le16_to_cpu(element->ElementFlags) &
-                   MPI2_EVENT_IR_CHANGE_EFLAGS_ELEMENT_TYPE_MASK;
-               switch (element_type) {
-               case MPI2_EVENT_IR_CHANGE_EFLAGS_VOLUME_ELEMENT:
-                       element_str = "volume";
-                       break;
-               case MPI2_EVENT_IR_CHANGE_EFLAGS_VOLPHYSDISK_ELEMENT:
-                       element_str = "phys disk";
-                       break;
-               case MPI2_EVENT_IR_CHANGE_EFLAGS_HOTSPARE_ELEMENT:
-                       element_str = "hot spare";
-                       break;
-               default:
-                       element_str = "unknown element";
-                       break;
-               }
-               printk(KERN_INFO "\t(%s:%s), vol handle(0x%04x), "
-                   "pd handle(0x%04x), pd num(0x%02x)\n", element_str,
-                   reason_str, le16_to_cpu(element->VolDevHandle),
-                   le16_to_cpu(element->PhysDiskDevHandle),
-                   element->PhysDiskNum);
-       }
-}
-#endif
-
-/**
- * _scsih_sas_ir_config_change_event - handle ir configuration change events
- * @ioc: per adapter object
- * @fw_event: The fw_event_work object
- * Context: user.
- *
- * Return nothing.
- */
-static void
-_scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc,
-    struct fw_event_work *fw_event)
-{
-       Mpi2EventIrConfigElement_t *element;
-       int i;
-       u8 foreign_config;
-       Mpi2EventDataIrConfigChangeList_t *event_data =
-               (Mpi2EventDataIrConfigChangeList_t *)
-               fw_event->event_data;
-
-#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
-       if ((ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
-           && !ioc->hide_ir_msg)
-               _scsih_sas_ir_config_change_event_debug(ioc, event_data);
-
-#endif
-
-       if (ioc->shost_recovery)
-               return;
-
-       foreign_config = (le32_to_cpu(event_data->Flags) &
-           MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ? 1 : 0;
-
-       element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
-       for (i = 0; i < event_data->NumElements; i++, element++) {
-
-               switch (element->ReasonCode) {
-               case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED:
-               case MPI2_EVENT_IR_CHANGE_RC_ADDED:
-                       if (!foreign_config)
-                               _scsih_sas_volume_add(ioc, element);
-                       break;
-               case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED:
-               case MPI2_EVENT_IR_CHANGE_RC_REMOVED:
-                       if (!foreign_config)
-                               _scsih_sas_volume_delete(ioc,
-                                   le16_to_cpu(element->VolDevHandle));
-                       break;
-               case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED:
-                       if (!ioc->is_warpdrive)
-                               _scsih_sas_pd_hide(ioc, element);
-                       break;
-               case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED:
-                       if (!ioc->is_warpdrive)
-                               _scsih_sas_pd_expose(ioc, element);
-                       break;
-               case MPI2_EVENT_IR_CHANGE_RC_HIDE:
-                       if (!ioc->is_warpdrive)
-                               _scsih_sas_pd_add(ioc, element);
-                       break;
-               case MPI2_EVENT_IR_CHANGE_RC_UNHIDE:
-                       if (!ioc->is_warpdrive)
-                               _scsih_sas_pd_delete(ioc, element);
-                       break;
-               }
-       }
-}
-
-/**
- * _scsih_sas_ir_volume_event - IR volume event
- * @ioc: per adapter object
- * @fw_event: The fw_event_work object
- * Context: user.
- *
- * Return nothing.
- */
-static void
-_scsih_sas_ir_volume_event(struct MPT2SAS_ADAPTER *ioc,
-    struct fw_event_work *fw_event)
-{
-       u64 wwid;
-       unsigned long flags;
-       struct _raid_device *raid_device;
-       u16 handle;
-       u32 state;
-       int rc;
-       Mpi2EventDataIrVolume_t *event_data =
-               (Mpi2EventDataIrVolume_t *)
-               fw_event->event_data;
-
-       if (ioc->shost_recovery)
-               return;
-
-       if (event_data->ReasonCode != MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED)
-               return;
-
-       handle = le16_to_cpu(event_data->VolDevHandle);
-       state = le32_to_cpu(event_data->NewValue);
-       if (!ioc->hide_ir_msg)
-               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: handle(0x%04x), "
-                   "old(0x%08x), new(0x%08x)\n", ioc->name, __func__,  handle,
-                   le32_to_cpu(event_data->PreviousValue), state));
-
-       switch (state) {
-       case MPI2_RAID_VOL_STATE_MISSING:
-       case MPI2_RAID_VOL_STATE_FAILED:
-               _scsih_sas_volume_delete(ioc, handle);
-               break;
-
-       case MPI2_RAID_VOL_STATE_ONLINE:
-       case MPI2_RAID_VOL_STATE_DEGRADED:
-       case MPI2_RAID_VOL_STATE_OPTIMAL:
-
-               spin_lock_irqsave(&ioc->raid_device_lock, flags);
-               raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
-               spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
-
-               if (raid_device)
-                       break;
-
-               mpt2sas_config_get_volume_wwid(ioc, handle, &wwid);
-               if (!wwid) {
-                       printk(MPT2SAS_ERR_FMT
-                           "failure at %s:%d/%s()!\n", ioc->name,
-                           __FILE__, __LINE__, __func__);
-                       break;
-               }
-
-               raid_device = kzalloc(sizeof(struct _raid_device), GFP_KERNEL);
-               if (!raid_device) {
-                       printk(MPT2SAS_ERR_FMT
-                           "failure at %s:%d/%s()!\n", ioc->name,
-                           __FILE__, __LINE__, __func__);
-                       break;
-               }
-
-               raid_device->id = ioc->sas_id++;
-               raid_device->channel = RAID_CHANNEL;
-               raid_device->handle = handle;
-               raid_device->wwid = wwid;
-               _scsih_raid_device_add(ioc, raid_device);
-               rc = scsi_add_device(ioc->shost, RAID_CHANNEL,
-                   raid_device->id, 0);
-               if (rc)
-                       _scsih_raid_device_remove(ioc, raid_device);
-               break;
-
-       case MPI2_RAID_VOL_STATE_INITIALIZING:
-       default:
-               break;
-       }
-}
-
-/**
- * _scsih_sas_ir_physical_disk_event - PD event
- * @ioc: per adapter object
- * @fw_event: The fw_event_work object
- * Context: user.
- *
- * Return nothing.
- */
-static void
-_scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc,
-    struct fw_event_work *fw_event)
-{
-       u16 handle, parent_handle;
-       u32 state;
-       struct _sas_device *sas_device;
-       Mpi2ConfigReply_t mpi_reply;
-       Mpi2SasDevicePage0_t sas_device_pg0;
-       u32 ioc_status;
-       Mpi2EventDataIrPhysicalDisk_t *event_data =
-               (Mpi2EventDataIrPhysicalDisk_t *)
-               fw_event->event_data;
-       u64 sas_address;
-
-       if (ioc->shost_recovery)
-               return;
-
-       if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED)
-               return;
-
-       handle = le16_to_cpu(event_data->PhysDiskDevHandle);
-       state = le32_to_cpu(event_data->NewValue);
-
-       if (!ioc->hide_ir_msg)
-               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: handle(0x%04x), "
-                   "old(0x%08x), new(0x%08x)\n", ioc->name, __func__,  handle,
-                   le32_to_cpu(event_data->PreviousValue), state));
-
-       switch (state) {
-       case MPI2_RAID_PD_STATE_ONLINE:
-       case MPI2_RAID_PD_STATE_DEGRADED:
-       case MPI2_RAID_PD_STATE_REBUILDING:
-       case MPI2_RAID_PD_STATE_OPTIMAL:
-       case MPI2_RAID_PD_STATE_HOT_SPARE:
-
-               if (!ioc->is_warpdrive)
-                       set_bit(handle, ioc->pd_handles);
-
-               sas_device = mpt2sas_get_sdev_by_handle(ioc, handle);
-               if (sas_device) {
-                       sas_device_put(sas_device);
-                       return;
-               }
-
-               if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
-                   &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE,
-                   handle))) {
-                       printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                           ioc->name, __FILE__, __LINE__, __func__);
-                       return;
-               }
-
-               ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-                   MPI2_IOCSTATUS_MASK;
-               if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
-                       printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                           ioc->name, __FILE__, __LINE__, __func__);
-                       return;
-               }
-
-               parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
-               if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address))
-                       mpt2sas_transport_update_links(ioc, sas_address, handle,
-                           sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
-
-               _scsih_add_device(ioc, handle, 0, 1);
-
-               break;
-
-       case MPI2_RAID_PD_STATE_OFFLINE:
-       case MPI2_RAID_PD_STATE_NOT_CONFIGURED:
-       case MPI2_RAID_PD_STATE_NOT_COMPATIBLE:
-       default:
-               break;
-       }
-}
-
-#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
-/**
- * _scsih_sas_ir_operation_status_event_debug - debug for IR op event
- * @ioc: per adapter object
- * @event_data: event data payload
- * Context: user.
- *
- * Return nothing.
- */
-static void
-_scsih_sas_ir_operation_status_event_debug(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2EventDataIrOperationStatus_t *event_data)
-{
-       char *reason_str = NULL;
-
-       switch (event_data->RAIDOperation) {
-       case MPI2_EVENT_IR_RAIDOP_RESYNC:
-               reason_str = "resync";
-               break;
-       case MPI2_EVENT_IR_RAIDOP_ONLINE_CAP_EXPANSION:
-               reason_str = "online capacity expansion";
-               break;
-       case MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK:
-               reason_str = "consistency check";
-               break;
-       case MPI2_EVENT_IR_RAIDOP_BACKGROUND_INIT:
-               reason_str = "background init";
-               break;
-       case MPI2_EVENT_IR_RAIDOP_MAKE_DATA_CONSISTENT:
-               reason_str = "make data consistent";
-               break;
-       }
-
-       if (!reason_str)
-               return;
-
-       printk(MPT2SAS_INFO_FMT "raid operational status: (%s)"
-           "\thandle(0x%04x), percent complete(%d)\n",
-           ioc->name, reason_str,
-           le16_to_cpu(event_data->VolDevHandle),
-           event_data->PercentComplete);
-}
-#endif
-
-/**
- * _scsih_sas_ir_operation_status_event - handle RAID operation events
- * @ioc: per adapter object
- * @fw_event: The fw_event_work object
- * Context: user.
- *
- * Return nothing.
- */
-static void
-_scsih_sas_ir_operation_status_event(struct MPT2SAS_ADAPTER *ioc,
-    struct fw_event_work *fw_event)
-{
-       Mpi2EventDataIrOperationStatus_t *event_data =
-               (Mpi2EventDataIrOperationStatus_t *)
-               fw_event->event_data;
-       static struct _raid_device *raid_device;
-       unsigned long flags;
-       u16 handle;
-
-#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
-       if ((ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
-           && !ioc->hide_ir_msg)
-               _scsih_sas_ir_operation_status_event_debug(ioc,
-                    event_data);
-#endif
-
-       /* code added for raid transport support */
-       if (event_data->RAIDOperation == MPI2_EVENT_IR_RAIDOP_RESYNC) {
-
-               spin_lock_irqsave(&ioc->raid_device_lock, flags);
-               handle = le16_to_cpu(event_data->VolDevHandle);
-               raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
-               if (raid_device)
-                       raid_device->percent_complete =
-                           event_data->PercentComplete;
-               spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
-       }
-}
-
-/**
- * _scsih_prep_device_scan - initialize parameters prior to device scan
- * @ioc: per adapter object
- *
- * Set the deleted flag prior to device scan.  If the device is found during
- * the scan, then we clear the deleted flag.
- */
-static void
-_scsih_prep_device_scan(struct MPT2SAS_ADAPTER *ioc)
-{
-       struct MPT2SAS_DEVICE *sas_device_priv_data;
-       struct scsi_device *sdev;
-
-       shost_for_each_device(sdev, ioc->shost) {
-               sas_device_priv_data = sdev->hostdata;
-               if (sas_device_priv_data && sas_device_priv_data->sas_target)
-                       sas_device_priv_data->sas_target->deleted = 1;
-       }
-}
-
-/**
- * _scsih_mark_responding_sas_device - mark a sas_devices as responding
- * @ioc: per adapter object
- * @sas_address: sas address
- * @slot: enclosure slot id
- * @handle: device handle
- *
- * After host reset, find out whether devices are still responding.
- * Used in _scsi_remove_unresponsive_sas_devices.
- *
- * Return nothing.
- */
-static void
-_scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
-    u16 slot, u16 handle)
-{
-       struct MPT2SAS_TARGET *sas_target_priv_data = NULL;
-       struct scsi_target *starget;
-       struct _sas_device *sas_device;
-       unsigned long flags;
-
-       spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       list_for_each_entry(sas_device, &ioc->sas_device_list, list) {
-               if (sas_device->sas_address == sas_address &&
-                   sas_device->slot == slot) {
-                       sas_device->responding = 1;
-                       starget = sas_device->starget;
-                       if (starget && starget->hostdata) {
-                               sas_target_priv_data = starget->hostdata;
-                               sas_target_priv_data->tm_busy = 0;
-                               sas_target_priv_data->deleted = 0;
-                       } else
-                               sas_target_priv_data = NULL;
-                       if (starget)
-                               starget_printk(KERN_INFO, starget,
-                                   "handle(0x%04x), sas_addr(0x%016llx), "
-                                   "enclosure logical id(0x%016llx), "
-                                   "slot(%d)\n", handle,
-                                   (unsigned long long)sas_device->sas_address,
-                                   (unsigned long long)
-                                   sas_device->enclosure_logical_id,
-                                   sas_device->slot);
-                       if (sas_device->handle == handle)
-                               goto out;
-                       printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n",
-                           sas_device->handle);
-                       sas_device->handle = handle;
-                       if (sas_target_priv_data)
-                               sas_target_priv_data->handle = handle;
-                       goto out;
-               }
-       }
- out:
-       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-}
-
-/**
- * _scsih_search_responding_sas_devices -
- * @ioc: per adapter object
- *
- * After host reset, find out whether devices are still responding.
- * If not remove.
- *
- * Return nothing.
- */
-static void
-_scsih_search_responding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
-{
-       Mpi2SasDevicePage0_t sas_device_pg0;
-       Mpi2ConfigReply_t mpi_reply;
-       u16 ioc_status;
-       __le64 sas_address;
-       u16 handle;
-       u32 device_info;
-       u16 slot;
-
-       printk(MPT2SAS_INFO_FMT "search for end-devices: start\n", ioc->name);
-
-       if (list_empty(&ioc->sas_device_list))
-               goto out;
-
-       handle = 0xFFFF;
-       while (!(mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
-           &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE,
-           handle))) {
-               ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-                   MPI2_IOCSTATUS_MASK;
-               if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
-                       break;
-               handle = le16_to_cpu(sas_device_pg0.DevHandle);
-               device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
-               if (!(_scsih_is_end_device(device_info)))
-                       continue;
-               sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
-               slot = le16_to_cpu(sas_device_pg0.Slot);
-               _scsih_mark_responding_sas_device(ioc, sas_address, slot,
-                   handle);
-       }
-out:
-       printk(MPT2SAS_INFO_FMT "search for end-devices: complete\n",
-           ioc->name);
-}
-
-/**
- * _scsih_mark_responding_raid_device - mark a raid_device as responding
- * @ioc: per adapter object
- * @wwid: world wide identifier for raid volume
- * @handle: device handle
- *
- * After host reset, find out whether devices are still responding.
- * Used in _scsi_remove_unresponsive_raid_devices.
- *
- * Return nothing.
- */
-static void
-_scsih_mark_responding_raid_device(struct MPT2SAS_ADAPTER *ioc, u64 wwid,
-    u16 handle)
-{
-       struct MPT2SAS_TARGET *sas_target_priv_data;
-       struct scsi_target *starget;
-       struct _raid_device *raid_device;
-       unsigned long flags;
-
-       spin_lock_irqsave(&ioc->raid_device_lock, flags);
-       list_for_each_entry(raid_device, &ioc->raid_device_list, list) {
-               if (raid_device->wwid == wwid && raid_device->starget) {
-                       starget = raid_device->starget;
-                       if (starget && starget->hostdata) {
-                               sas_target_priv_data = starget->hostdata;
-                               sas_target_priv_data->deleted = 0;
-                       } else
-                               sas_target_priv_data = NULL;
-                       raid_device->responding = 1;
-                       spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
-                       starget_printk(KERN_INFO, raid_device->starget,
-                           "handle(0x%04x), wwid(0x%016llx)\n", handle,
-                           (unsigned long long)raid_device->wwid);
-                       /*
-                        * WARPDRIVE: The handles of the PDs might have changed
-                        * across the host reset so re-initialize the
-                        * required data for Direct IO
-                        */
-                       _scsih_init_warpdrive_properties(ioc, raid_device);
-                       spin_lock_irqsave(&ioc->raid_device_lock, flags);
-                       if (raid_device->handle == handle) {
-                               spin_unlock_irqrestore(&ioc->raid_device_lock,
-                                   flags);
-                               return;
-                       }
-                       printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n",
-                           raid_device->handle);
-                       raid_device->handle = handle;
-                       if (sas_target_priv_data)
-                               sas_target_priv_data->handle = handle;
-                       spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
-                       return;
-               }
-       }
-
-       spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
-}
-
-/**
- * _scsih_search_responding_raid_devices -
- * @ioc: per adapter object
- *
- * After host reset, find out whether devices are still responding.
- * If not remove.
- *
- * Return nothing.
- */
-static void
-_scsih_search_responding_raid_devices(struct MPT2SAS_ADAPTER *ioc)
-{
-       Mpi2RaidVolPage1_t volume_pg1;
-       Mpi2RaidVolPage0_t volume_pg0;
-       Mpi2RaidPhysDiskPage0_t pd_pg0;
-       Mpi2ConfigReply_t mpi_reply;
-       u16 ioc_status;
-       u16 handle;
-       u8 phys_disk_num;
-
-       if (!ioc->ir_firmware)
-               return;
-
-       printk(MPT2SAS_INFO_FMT "search for raid volumes: start\n",
-           ioc->name);
-
-       if (list_empty(&ioc->raid_device_list))
-               goto out;
-
-       handle = 0xFFFF;
-       while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
-           &volume_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
-               ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-                   MPI2_IOCSTATUS_MASK;
-               if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
-                       break;
-               handle = le16_to_cpu(volume_pg1.DevHandle);
-
-               if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply,
-                   &volume_pg0, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, handle,
-                    sizeof(Mpi2RaidVolPage0_t)))
-                       continue;
-
-               if (volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_OPTIMAL ||
-                   volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_ONLINE ||
-                   volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_DEGRADED)
-                       _scsih_mark_responding_raid_device(ioc,
-                           le64_to_cpu(volume_pg1.WWID), handle);
-       }
-
-       /* refresh the pd_handles */
-       if (!ioc->is_warpdrive) {
-               phys_disk_num = 0xFF;
-               memset(ioc->pd_handles, 0, ioc->pd_handles_sz);
-               while (!(mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply,
-                   &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_GET_NEXT_PHYSDISKNUM,
-                   phys_disk_num))) {
-                       ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-                           MPI2_IOCSTATUS_MASK;
-                       if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
-                               break;
-                       phys_disk_num = pd_pg0.PhysDiskNum;
-                       handle = le16_to_cpu(pd_pg0.DevHandle);
-                       set_bit(handle, ioc->pd_handles);
-               }
-       }
-out:
-       printk(MPT2SAS_INFO_FMT "search for responding raid volumes: "
-           "complete\n", ioc->name);
-}
-
-/**
- * _scsih_mark_responding_expander - mark a expander as responding
- * @ioc: per adapter object
- * @sas_address: sas address
- * @handle:
- *
- * After host reset, find out whether devices are still responding.
- * Used in _scsi_remove_unresponsive_expanders.
- *
- * Return nothing.
- */
-static void
-_scsih_mark_responding_expander(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
-     u16 handle)
-{
-       struct _sas_node *sas_expander;
-       unsigned long flags;
-       int i;
-
-       spin_lock_irqsave(&ioc->sas_node_lock, flags);
-       list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
-               if (sas_expander->sas_address != sas_address)
-                       continue;
-               sas_expander->responding = 1;
-               if (sas_expander->handle == handle)
-                       goto out;
-               printk(KERN_INFO "\texpander(0x%016llx): handle changed"
-                   " from(0x%04x) to (0x%04x)!!!\n",
-                   (unsigned long long)sas_expander->sas_address,
-                   sas_expander->handle, handle);
-               sas_expander->handle = handle;
-               for (i = 0 ; i < sas_expander->num_phys ; i++)
-                       sas_expander->phy[i].handle = handle;
-               goto out;
-       }
- out:
-       spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
-}
-
-/**
- * _scsih_search_responding_expanders -
- * @ioc: per adapter object
- *
- * After host reset, find out whether devices are still responding.
- * If not remove.
- *
- * Return nothing.
- */
-static void
-_scsih_search_responding_expanders(struct MPT2SAS_ADAPTER *ioc)
-{
-       Mpi2ExpanderPage0_t expander_pg0;
-       Mpi2ConfigReply_t mpi_reply;
-       u16 ioc_status;
-       u64 sas_address;
-       u16 handle;
-
-       printk(MPT2SAS_INFO_FMT "search for expanders: start\n", ioc->name);
-
-       if (list_empty(&ioc->sas_expander_list))
-               goto out;
-
-       handle = 0xFFFF;
-       while (!(mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0,
-           MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL, handle))) {
-
-               ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-                   MPI2_IOCSTATUS_MASK;
-               if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
-                       break;
-
-               handle = le16_to_cpu(expander_pg0.DevHandle);
-               sas_address = le64_to_cpu(expander_pg0.SASAddress);
-               printk(KERN_INFO "\texpander present: handle(0x%04x), "
-                   "sas_addr(0x%016llx)\n", handle,
-                   (unsigned long long)sas_address);
-               _scsih_mark_responding_expander(ioc, sas_address, handle);
-       }
-
- out:
-       printk(MPT2SAS_INFO_FMT "search for expanders: complete\n", ioc->name);
-}
-
-/**
- * _scsih_remove_unresponding_sas_devices - removing unresponding devices
- * @ioc: per adapter object
- *
- * Return nothing.
- */
-static void
-_scsih_remove_unresponding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
-{
-       struct _sas_device *sas_device, *sas_device_next;
-       struct _sas_node *sas_expander, *sas_expander_next;
-       struct _raid_device *raid_device, *raid_device_next;
-       struct list_head tmp_list;
-       unsigned long flags;
-       LIST_HEAD(head);
-
-       printk(MPT2SAS_INFO_FMT "removing unresponding devices: start\n",
-           ioc->name);
-
-       /* removing unresponding end devices */
-       printk(MPT2SAS_INFO_FMT "removing unresponding devices: end-devices\n",
-           ioc->name);
-
-       /*
-        * Iterate, pulling off devices marked as non-responding. We become the
-        * owner for the reference the list had on any object we prune.
-        */
-       spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       list_for_each_entry_safe(sas_device, sas_device_next,
-                       &ioc->sas_device_list, list) {
-               if (!sas_device->responding)
-                       list_move_tail(&sas_device->list, &head);
-               else
-                       sas_device->responding = 0;
-       }
-       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-
-       /*
-        * Now, uninitialize and remove the unresponding devices we pruned.
-        */
-       list_for_each_entry_safe(sas_device, sas_device_next, &head, list) {
-               _scsih_remove_device(ioc, sas_device);
-               list_del_init(&sas_device->list);
-               sas_device_put(sas_device);
-       }
-
-       /* removing unresponding volumes */
-       if (ioc->ir_firmware) {
-               printk(MPT2SAS_INFO_FMT "removing unresponding devices: "
-                   "volumes\n", ioc->name);
-               list_for_each_entry_safe(raid_device, raid_device_next,
-                   &ioc->raid_device_list, list) {
-                       if (!raid_device->responding)
-                               _scsih_sas_volume_delete(ioc,
-                                   raid_device->handle);
-                       else
-                               raid_device->responding = 0;
-               }
-       }
-       /* removing unresponding expanders */
-       printk(MPT2SAS_INFO_FMT "removing unresponding devices: expanders\n",
-           ioc->name);
-       spin_lock_irqsave(&ioc->sas_node_lock, flags);
-       INIT_LIST_HEAD(&tmp_list);
-       list_for_each_entry_safe(sas_expander, sas_expander_next,
-           &ioc->sas_expander_list, list) {
-               if (!sas_expander->responding)
-                       list_move_tail(&sas_expander->list, &tmp_list);
-               else
-                       sas_expander->responding = 0;
-       }
-       spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
-       list_for_each_entry_safe(sas_expander, sas_expander_next, &tmp_list,
-           list) {
-               list_del(&sas_expander->list);
-               _scsih_expander_node_remove(ioc, sas_expander);
-       }
-       printk(MPT2SAS_INFO_FMT "removing unresponding devices: complete\n",
-           ioc->name);
-       /* unblock devices */
-       _scsih_ublock_io_all_device(ioc);
-}
-
-static void
-_scsih_refresh_expander_links(struct MPT2SAS_ADAPTER *ioc,
-       struct _sas_node *sas_expander, u16 handle)
-{
-       Mpi2ExpanderPage1_t expander_pg1;
-       Mpi2ConfigReply_t mpi_reply;
-       int i;
-
-       for (i = 0 ; i < sas_expander->num_phys ; i++) {
-               if ((mpt2sas_config_get_expander_pg1(ioc, &mpi_reply,
-                   &expander_pg1, i, handle))) {
-                       printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                           ioc->name, __FILE__, __LINE__, __func__);
-                       return;
-               }
-
-               mpt2sas_transport_update_links(ioc, sas_expander->sas_address,
-                   le16_to_cpu(expander_pg1.AttachedDevHandle), i,
-                   expander_pg1.NegotiatedLinkRate >> 4);
-       }
-}
-
-/**
- * _scsih_scan_for_devices_after_reset - scan for devices after host reset
- * @ioc: per adapter object
- *
- * Return nothing.
- */
-static void
-_scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc)
-{
-       Mpi2ExpanderPage0_t expander_pg0;
-       Mpi2SasDevicePage0_t sas_device_pg0;
-       Mpi2RaidVolPage1_t volume_pg1;
-       Mpi2RaidVolPage0_t volume_pg0;
-       Mpi2RaidPhysDiskPage0_t pd_pg0;
-       Mpi2EventIrConfigElement_t element;
-       Mpi2ConfigReply_t mpi_reply;
-       u8 phys_disk_num;
-       u16 ioc_status;
-       u16 handle, parent_handle;
-       u64 sas_address;
-       struct _sas_device *sas_device;
-       struct _sas_node *expander_device;
-       static struct _raid_device *raid_device;
-       u8 retry_count;
-       unsigned long flags;
-
-       printk(MPT2SAS_INFO_FMT "scan devices: start\n", ioc->name);
-
-       _scsih_sas_host_refresh(ioc);
-
-       printk(MPT2SAS_INFO_FMT "\tscan devices: expanders start\n",
-               ioc->name);
-       /* expanders */
-       handle = 0xFFFF;
-       while (!(mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0,
-           MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL, handle))) {
-               ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-                   MPI2_IOCSTATUS_MASK;
-               if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
-                       printk(MPT2SAS_INFO_FMT "\tbreak from expander scan: "
-                               "ioc_status(0x%04x), loginfo(0x%08x)\n",
-                               ioc->name, ioc_status,
-                               le32_to_cpu(mpi_reply.IOCLogInfo));
-                       break;
-               }
-               handle = le16_to_cpu(expander_pg0.DevHandle);
-               spin_lock_irqsave(&ioc->sas_node_lock, flags);
-               expander_device = mpt2sas_scsih_expander_find_by_sas_address(
-                   ioc, le64_to_cpu(expander_pg0.SASAddress));
-               spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
-               if (expander_device)
-                       _scsih_refresh_expander_links(ioc, expander_device,
-                           handle);
-               else {
-                       printk(MPT2SAS_INFO_FMT "\tBEFORE adding expander: "
-                               "handle (0x%04x), sas_addr(0x%016llx)\n",
-                               ioc->name, handle, (unsigned long long)
-                               le64_to_cpu(expander_pg0.SASAddress));
-                       _scsih_expander_add(ioc, handle);
-                       printk(MPT2SAS_INFO_FMT "\tAFTER adding expander: "
-                               "handle (0x%04x), sas_addr(0x%016llx)\n",
-                               ioc->name, handle, (unsigned long long)
-                               le64_to_cpu(expander_pg0.SASAddress));
-               }
-       }
-
-       printk(MPT2SAS_INFO_FMT "\tscan devices: expanders complete\n",
-               ioc->name);
-
-       if (!ioc->ir_firmware)
-               goto skip_to_sas;
-
-       printk(MPT2SAS_INFO_FMT "\tscan devices phys disk start\n", ioc->name);
-       /* phys disk */
-       phys_disk_num = 0xFF;
-       while (!(mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply,
-           &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_GET_NEXT_PHYSDISKNUM,
-           phys_disk_num))) {
-               ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-                   MPI2_IOCSTATUS_MASK;
-               if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
-                       printk(MPT2SAS_INFO_FMT "\tbreak from phys disk scan:"
-                               "ioc_status(0x%04x), loginfo(0x%08x)\n",
-                               ioc->name, ioc_status,
-                               le32_to_cpu(mpi_reply.IOCLogInfo));
-                       break;
-               }
-               phys_disk_num = pd_pg0.PhysDiskNum;
-               handle = le16_to_cpu(pd_pg0.DevHandle);
-               sas_device = mpt2sas_get_sdev_by_handle(ioc, handle);
-               if (sas_device) {
-                       sas_device_put(sas_device);
-                       continue;
-               }
-               if (mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
-                   &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE,
-                   handle) != 0)
-                       continue;
-               ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-                       MPI2_IOCSTATUS_MASK;
-               if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
-                       printk(MPT2SAS_INFO_FMT "\tbreak from phys disk scan "
-                               "ioc_status(0x%04x), loginfo(0x%08x)\n",
-                               ioc->name, ioc_status,
-                               le32_to_cpu(mpi_reply.IOCLogInfo));
-                       break;
-               }
-               parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
-               if (!_scsih_get_sas_address(ioc, parent_handle,
-                   &sas_address)) {
-                       printk(MPT2SAS_INFO_FMT "\tBEFORE adding phys disk: "
-                               " handle (0x%04x), sas_addr(0x%016llx)\n",
-                               ioc->name, handle, (unsigned long long)
-                               le64_to_cpu(sas_device_pg0.SASAddress));
-                       mpt2sas_transport_update_links(ioc, sas_address,
-                           handle, sas_device_pg0.PhyNum,
-                           MPI2_SAS_NEG_LINK_RATE_1_5);
-                       set_bit(handle, ioc->pd_handles);
-                       retry_count = 0;
-                       /* This will retry adding the end device.
-                       * _scsih_add_device() will decide on retries and
-                       * return "1" when it should be retried
-                       */
-                       while (_scsih_add_device(ioc, handle, retry_count++,
-                               1)) {
-                                       ssleep(1);
-                       }
-                       printk(MPT2SAS_INFO_FMT "\tAFTER adding phys disk: "
-                               " handle (0x%04x), sas_addr(0x%016llx)\n",
-                               ioc->name, handle, (unsigned long long)
-                               le64_to_cpu(sas_device_pg0.SASAddress));
-               }
-       }
-
-       printk(MPT2SAS_INFO_FMT "\tscan devices: phys disk complete\n",
-               ioc->name);
-
-       printk(MPT2SAS_INFO_FMT "\tscan devices: volumes start\n", ioc->name);
-       /* volumes */
-       handle = 0xFFFF;
-       while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
-           &volume_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
-               ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-                   MPI2_IOCSTATUS_MASK;
-               if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
-                       printk(MPT2SAS_INFO_FMT "\tbreak from volume scan: "
-                               "ioc_status(0x%04x), loginfo(0x%08x)\n",
-                               ioc->name, ioc_status,
-                               le32_to_cpu(mpi_reply.IOCLogInfo));
-                       break;
-               }
-               handle = le16_to_cpu(volume_pg1.DevHandle);
-               spin_lock_irqsave(&ioc->raid_device_lock, flags);
-               raid_device = _scsih_raid_device_find_by_wwid(ioc,
-                   le64_to_cpu(volume_pg1.WWID));
-               spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
-               if (raid_device)
-                       continue;
-               if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply,
-                   &volume_pg0, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, handle,
-                    sizeof(Mpi2RaidVolPage0_t)))
-                       continue;
-               ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-                       MPI2_IOCSTATUS_MASK;
-               if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
-                       printk(MPT2SAS_INFO_FMT "\tbreak from volume scan: "
-                               "ioc_status(0x%04x), loginfo(0x%08x)\n",
-                               ioc->name, ioc_status,
-                               le32_to_cpu(mpi_reply.IOCLogInfo));
-                       break;
-               }
-               if (volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_OPTIMAL ||
-                   volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_ONLINE ||
-                   volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_DEGRADED) {
-                       memset(&element, 0, sizeof(Mpi2EventIrConfigElement_t));
-                       element.ReasonCode = MPI2_EVENT_IR_CHANGE_RC_ADDED;
-                       element.VolDevHandle = volume_pg1.DevHandle;
-                       printk(MPT2SAS_INFO_FMT "\tBEFORE adding volume: "
-                               " handle (0x%04x)\n", ioc->name,
-                               volume_pg1.DevHandle);
-                       _scsih_sas_volume_add(ioc, &element);
-                       printk(MPT2SAS_INFO_FMT "\tAFTER adding volume: "
-                               " handle (0x%04x)\n", ioc->name,
-                               volume_pg1.DevHandle);
-               }
-       }
-
-       printk(MPT2SAS_INFO_FMT "\tscan devices: volumes complete\n",
-               ioc->name);
-
- skip_to_sas:
-
-       printk(MPT2SAS_INFO_FMT "\tscan devices: end devices start\n",
-               ioc->name);
-       /* sas devices */
-       handle = 0xFFFF;
-       while (!(mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
-           &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE,
-           handle))) {
-               ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-                   MPI2_IOCSTATUS_MASK;
-               if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
-                       printk(MPT2SAS_INFO_FMT "\tbreak from end device scan:"
-                               " ioc_status(0x%04x), loginfo(0x%08x)\n",
-                               ioc->name, ioc_status,
-                               le32_to_cpu(mpi_reply.IOCLogInfo));
-                               break;
-               }
-               handle = le16_to_cpu(sas_device_pg0.DevHandle);
-               if (!(_scsih_is_end_device(
-                   le32_to_cpu(sas_device_pg0.DeviceInfo))))
-                       continue;
-               sas_device = mpt2sas_get_sdev_by_addr(ioc,
-                   le64_to_cpu(sas_device_pg0.SASAddress));
-               if (sas_device) {
-                       sas_device_put(sas_device);
-                       continue;
-               }
-               parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
-               if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) {
-                       printk(MPT2SAS_INFO_FMT "\tBEFORE adding end device: "
-                               "handle (0x%04x), sas_addr(0x%016llx)\n",
-                               ioc->name, handle, (unsigned long long)
-                               le64_to_cpu(sas_device_pg0.SASAddress));
-                       mpt2sas_transport_update_links(ioc, sas_address, handle,
-                           sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
-                       retry_count = 0;
-                       /* This will retry adding the end device.
-                        * _scsih_add_device() will decide on retries and
-                        * return "1" when it should be retried
-                        */
-                       while (_scsih_add_device(ioc, handle, retry_count++,
-                               0)) {
-                                       ssleep(1);
-                       }
-                       printk(MPT2SAS_INFO_FMT "\tAFTER adding end device: "
-                               "handle (0x%04x), sas_addr(0x%016llx)\n",
-                               ioc->name, handle, (unsigned long long)
-                               le64_to_cpu(sas_device_pg0.SASAddress));
-               }
-       }
-
-       printk(MPT2SAS_INFO_FMT "\tscan devices: end devices complete\n",
-               ioc->name);
-
-       printk(MPT2SAS_INFO_FMT "scan devices: complete\n", ioc->name);
-}
-
-
-/**
- * mpt2sas_scsih_reset_handler - reset callback handler (for scsih)
- * @ioc: per adapter object
- * @reset_phase: phase
- *
- * The handler for doing any required cleanup or initialization.
- *
- * The reset phase can be MPT2_IOC_PRE_RESET, MPT2_IOC_AFTER_RESET,
- * MPT2_IOC_DONE_RESET
- *
- * Return nothing.
- */
-void
-mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
-{
-       switch (reset_phase) {
-       case MPT2_IOC_PRE_RESET:
-               dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
-                   "MPT2_IOC_PRE_RESET\n", ioc->name, __func__));
-               break;
-       case MPT2_IOC_AFTER_RESET:
-               dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
-                   "MPT2_IOC_AFTER_RESET\n", ioc->name, __func__));
-               if (ioc->scsih_cmds.status & MPT2_CMD_PENDING) {
-                       ioc->scsih_cmds.status |= MPT2_CMD_RESET;
-                       mpt2sas_base_free_smid(ioc, ioc->scsih_cmds.smid);
-                       complete(&ioc->scsih_cmds.done);
-               }
-               if (ioc->tm_cmds.status & MPT2_CMD_PENDING) {
-                       ioc->tm_cmds.status |= MPT2_CMD_RESET;
-                       mpt2sas_base_free_smid(ioc, ioc->tm_cmds.smid);
-                       complete(&ioc->tm_cmds.done);
-               }
-               _scsih_fw_event_cleanup_queue(ioc);
-               _scsih_flush_running_cmds(ioc);
-               break;
-       case MPT2_IOC_DONE_RESET:
-               dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
-                   "MPT2_IOC_DONE_RESET\n", ioc->name, __func__));
-               _scsih_sas_host_refresh(ioc);
-               _scsih_prep_device_scan(ioc);
-               _scsih_search_responding_sas_devices(ioc);
-               _scsih_search_responding_raid_devices(ioc);
-               _scsih_search_responding_expanders(ioc);
-               if ((!ioc->is_driver_loading) && !(disable_discovery > 0 &&
-                   !ioc->sas_hba.num_phys)) {
-                       _scsih_prep_device_scan(ioc);
-                       _scsih_search_responding_sas_devices(ioc);
-                       _scsih_search_responding_raid_devices(ioc);
-                       _scsih_search_responding_expanders(ioc);
-                       _scsih_error_recovery_delete_devices(ioc);
-               }
-               break;
-       }
-}
-
-/**
- * _firmware_event_work - delayed task for processing firmware events
- * @ioc: per adapter object
- * @work: equal to the fw_event_work object
- * Context: user.
- *
- * Return nothing.
- */
-static void
-_firmware_event_work(struct work_struct *work)
-{
-       struct fw_event_work *fw_event = container_of(work,
-           struct fw_event_work, delayed_work.work);
-       struct MPT2SAS_ADAPTER *ioc = fw_event->ioc;
-
-       _scsih_fw_event_del_from_list(ioc, fw_event);
-
-       /* the queue is being flushed so ignore this event */
-       if (ioc->remove_host || ioc->pci_error_recovery) {
-               fw_event_work_put(fw_event);
-               return;
-       }
-
-       switch (fw_event->event) {
-       case MPT2SAS_REMOVE_UNRESPONDING_DEVICES:
-               while (scsi_host_in_recovery(ioc->shost) ||
-                               ioc->shost_recovery) {
-                       /*
-                        * If we're unloading, bail. Otherwise, this can become
-                        * an infinite loop.
-                        */
-                       if (ioc->remove_host)
-                               goto out;
-
-                       ssleep(1);
-               }
-               _scsih_remove_unresponding_sas_devices(ioc);
-               _scsih_scan_for_devices_after_reset(ioc);
-               break;
-       case MPT2SAS_PORT_ENABLE_COMPLETE:
-               ioc->start_scan = 0;
-
-               if (missing_delay[0] != -1 && missing_delay[1] != -1)
-                       mpt2sas_base_update_missing_delay(ioc, missing_delay[0],
-                               missing_delay[1]);
-
-               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "port enable: complete "
-                   "from worker thread\n", ioc->name));
-               break;
-       case MPT2SAS_TURN_ON_PFA_LED:
-               _scsih_turn_on_pfa_led(ioc, fw_event->device_handle);
-               break;
-       case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
-               _scsih_sas_topology_change_event(ioc, fw_event);
-               break;
-       case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
-               _scsih_sas_device_status_change_event(ioc,
-                   fw_event);
-               break;
-       case MPI2_EVENT_SAS_DISCOVERY:
-               _scsih_sas_discovery_event(ioc,
-                   fw_event);
-               break;
-       case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE:
-               _scsih_sas_broadcast_primitive_event(ioc,
-                   fw_event);
-               break;
-       case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
-               _scsih_sas_enclosure_dev_status_change_event(ioc,
-                   fw_event);
-               break;
-       case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
-               _scsih_sas_ir_config_change_event(ioc, fw_event);
-               break;
-       case MPI2_EVENT_IR_VOLUME:
-               _scsih_sas_ir_volume_event(ioc, fw_event);
-               break;
-       case MPI2_EVENT_IR_PHYSICAL_DISK:
-               _scsih_sas_ir_physical_disk_event(ioc, fw_event);
-               break;
-       case MPI2_EVENT_IR_OPERATION_STATUS:
-               _scsih_sas_ir_operation_status_event(ioc, fw_event);
-               break;
-       }
-out:
-       fw_event_work_put(fw_event);
-}
-
-/**
- * mpt2sas_scsih_event_callback - firmware event handler (called at ISR time)
- * @ioc: per adapter object
- * @msix_index: MSIX table index supplied by the OS
- * @reply: reply message frame(lower 32bit addr)
- * Context: interrupt.
- *
- * This function merely adds a new work task into ioc->firmware_event_thread.
- * The tasks are worked from _firmware_event_work in user context.
- *
- * Returns void.
- */
-void
-mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
-       u32 reply)
-{
-       struct fw_event_work *fw_event;
-       Mpi2EventNotificationReply_t *mpi_reply;
-       u16 event;
-       u16 sz;
-
-       /* events turned off due to host reset or driver unloading */
-       if (ioc->remove_host || ioc->pci_error_recovery)
-               return;
-
-       mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
-
-       if (unlikely(!mpi_reply)) {
-               printk(MPT2SAS_ERR_FMT "mpi_reply not valid at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               return;
-       }
-
-       event = le16_to_cpu(mpi_reply->Event);
-
-       switch (event) {
-       /* handle these */
-       case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE:
-       {
-               Mpi2EventDataSasBroadcastPrimitive_t *baen_data =
-                   (Mpi2EventDataSasBroadcastPrimitive_t *)
-                   mpi_reply->EventData;
-
-               if (baen_data->Primitive !=
-                   MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT)
-                       return;
-
-               if (ioc->broadcast_aen_busy) {
-                       ioc->broadcast_aen_pending++;
-                       return;
-               } else
-                       ioc->broadcast_aen_busy = 1;
-               break;
-       }
-
-       case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
-               _scsih_check_topo_delete_events(ioc,
-                   (Mpi2EventDataSasTopologyChangeList_t *)
-                   mpi_reply->EventData);
-               break;
-       case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
-               _scsih_check_ir_config_unhide_events(ioc,
-                   (Mpi2EventDataIrConfigChangeList_t *)
-                   mpi_reply->EventData);
-               break;
-       case MPI2_EVENT_IR_VOLUME:
-               _scsih_check_volume_delete_events(ioc,
-                   (Mpi2EventDataIrVolume_t *)
-                   mpi_reply->EventData);
-               break;
-       case MPI2_EVENT_LOG_ENTRY_ADDED:
-       {
-               Mpi2EventDataLogEntryAdded_t *log_entry;
-               __le32 *log_code;
-
-               if (!ioc->is_warpdrive)
-                       break;
-
-               log_entry = (Mpi2EventDataLogEntryAdded_t *)
-                   mpi_reply->EventData;
-               log_code = (__le32 *)log_entry->LogData;
-
-               if (le16_to_cpu(log_entry->LogEntryQualifier)
-                   != MPT2_WARPDRIVE_LOGENTRY)
-                       break;
-
-               switch (le32_to_cpu(*log_code)) {
-               case MPT2_WARPDRIVE_LC_SSDT:
-                       printk(MPT2SAS_WARN_FMT "WarpDrive Warning: "
-                           "IO Throttling has occurred in the WarpDrive "
-                           "subsystem. Check WarpDrive documentation for "
-                           "additional details.\n", ioc->name);
-                       break;
-               case MPT2_WARPDRIVE_LC_SSDLW:
-                       printk(MPT2SAS_WARN_FMT "WarpDrive Warning: "
-                           "Program/Erase Cycles for the WarpDrive subsystem "
-                           "in degraded range. Check WarpDrive documentation "
-                           "for additional details.\n", ioc->name);
-                       break;
-               case MPT2_WARPDRIVE_LC_SSDLF:
-                       printk(MPT2SAS_ERR_FMT "WarpDrive Fatal Error: "
-                           "There are no Program/Erase Cycles for the "
-                           "WarpDrive subsystem. The storage device will be "
-                           "in read-only mode. Check WarpDrive documentation "
-                           "for additional details.\n", ioc->name);
-                       break;
-               case MPT2_WARPDRIVE_LC_BRMF:
-                       printk(MPT2SAS_ERR_FMT "WarpDrive Fatal Error: "
-                           "The Backup Rail Monitor has failed on the "
-                           "WarpDrive subsystem. Check WarpDrive "
-                           "documentation for additional details.\n",
-                           ioc->name);
-                       break;
-               }
-
-               break;
-       }
-       case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
-       case MPI2_EVENT_IR_OPERATION_STATUS:
-       case MPI2_EVENT_SAS_DISCOVERY:
-       case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
-       case MPI2_EVENT_IR_PHYSICAL_DISK:
-               break;
-
-       case MPI2_EVENT_TEMP_THRESHOLD:
-               _scsih_temp_threshold_events(ioc,
-                       (Mpi2EventDataTemperature_t *)
-                       mpi_reply->EventData);
-               break;
-
-       default: /* ignore the rest */
-               return;
-       }
-
-       sz = le16_to_cpu(mpi_reply->EventDataLength) * 4;
-       fw_event = alloc_fw_event_work(sz);
-       if (!fw_event) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               return;
-       }
-
-       memcpy(fw_event->event_data, mpi_reply->EventData, sz);
-       fw_event->ioc = ioc;
-       fw_event->VF_ID = mpi_reply->VF_ID;
-       fw_event->VP_ID = mpi_reply->VP_ID;
-       fw_event->event = event;
-       _scsih_fw_event_add(ioc, fw_event);
-       fw_event_work_put(fw_event);
-       return;
-}
-
-/* shost template */
-static struct scsi_host_template scsih_driver_template = {
-       .module                         = THIS_MODULE,
-       .name                           = "Fusion MPT SAS Host",
-       .proc_name                      = MPT2SAS_DRIVER_NAME,
-       .queuecommand                   = _scsih_qcmd,
-       .target_alloc                   = _scsih_target_alloc,
-       .slave_alloc                    = _scsih_slave_alloc,
-       .slave_configure                = _scsih_slave_configure,
-       .target_destroy                 = _scsih_target_destroy,
-       .slave_destroy                  = _scsih_slave_destroy,
-       .scan_finished                  = _scsih_scan_finished,
-       .scan_start                     = _scsih_scan_start,
-       .change_queue_depth             = _scsih_change_queue_depth,
-       .eh_abort_handler               = _scsih_abort,
-       .eh_device_reset_handler        = _scsih_dev_reset,
-       .eh_target_reset_handler        = _scsih_target_reset,
-       .eh_host_reset_handler          = _scsih_host_reset,
-       .bios_param                     = _scsih_bios_param,
-       .can_queue                      = 1,
-       .this_id                        = -1,
-       .sg_tablesize                   = MPT2SAS_SG_DEPTH,
-       .max_sectors                    = 32767,
-       .cmd_per_lun                    = 7,
-       .use_clustering                 = ENABLE_CLUSTERING,
-       .shost_attrs                    = mpt2sas_host_attrs,
-       .sdev_attrs                     = mpt2sas_dev_attrs,
-       .track_queue_depth              = 1,
-};
-
-/**
- * _scsih_expander_node_remove - removing expander device from list.
- * @ioc: per adapter object
- * @sas_expander: the sas_device object
- * Context: Calling function should acquire ioc->sas_node_lock.
- *
- * Removing object and freeing associated memory from the
- * ioc->sas_expander_list.
- *
- * Return nothing.
- */
-static void
-_scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
-    struct _sas_node *sas_expander)
-{
-       struct _sas_port *mpt2sas_port, *next;
-
-       /* remove sibling ports attached to this expander */
-       list_for_each_entry_safe(mpt2sas_port, next,
-          &sas_expander->sas_port_list, port_list) {
-               if (ioc->shost_recovery)
-                       return;
-               if (mpt2sas_port->remote_identify.device_type ==
-                   SAS_END_DEVICE)
-                       mpt2sas_device_remove_by_sas_address(ioc,
-                           mpt2sas_port->remote_identify.sas_address);
-               else if (mpt2sas_port->remote_identify.device_type ==
-                   SAS_EDGE_EXPANDER_DEVICE ||
-                   mpt2sas_port->remote_identify.device_type ==
-                   SAS_FANOUT_EXPANDER_DEVICE)
-                       mpt2sas_expander_remove(ioc,
-                           mpt2sas_port->remote_identify.sas_address);
-       }
-
-       mpt2sas_transport_port_remove(ioc, sas_expander->sas_address,
-           sas_expander->sas_address_parent);
-
-       printk(MPT2SAS_INFO_FMT "expander_remove: handle"
-          "(0x%04x), sas_addr(0x%016llx)\n", ioc->name,
-           sas_expander->handle, (unsigned long long)
-           sas_expander->sas_address);
-
-       kfree(sas_expander->phy);
-       kfree(sas_expander);
-}
-
-/**
- * _scsih_ir_shutdown - IR shutdown notification
- * @ioc: per adapter object
- *
- * Sending RAID Action to alert the Integrated RAID subsystem of the IOC that
- * the host system is shutting down.
- *
- * Return nothing.
- */
-static void
-_scsih_ir_shutdown(struct MPT2SAS_ADAPTER *ioc)
-{
-       Mpi2RaidActionRequest_t *mpi_request;
-       Mpi2RaidActionReply_t *mpi_reply;
-       u16 smid;
-
-       /* is IR firmware build loaded ? */
-       if (!ioc->ir_firmware)
-               return;
-
-       mutex_lock(&ioc->scsih_cmds.mutex);
-
-       if (ioc->scsih_cmds.status != MPT2_CMD_NOT_USED) {
-               printk(MPT2SAS_ERR_FMT "%s: scsih_cmd in use\n",
-                   ioc->name, __func__);
-               goto out;
-       }
-       ioc->scsih_cmds.status = MPT2_CMD_PENDING;
-
-       smid = mpt2sas_base_get_smid(ioc, ioc->scsih_cb_idx);
-       if (!smid) {
-               printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
-                   ioc->name, __func__);
-               ioc->scsih_cmds.status = MPT2_CMD_NOT_USED;
-               goto out;
-       }
-
-       mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
-       ioc->scsih_cmds.smid = smid;
-       memset(mpi_request, 0, sizeof(Mpi2RaidActionRequest_t));
-
-       mpi_request->Function = MPI2_FUNCTION_RAID_ACTION;
-       mpi_request->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED;
-
-       if (!ioc->hide_ir_msg)
-               printk(MPT2SAS_INFO_FMT "IR shutdown (sending)\n", ioc->name);
-       init_completion(&ioc->scsih_cmds.done);
-       mpt2sas_base_put_smid_default(ioc, smid);
-       wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ);
-
-       if (!(ioc->scsih_cmds.status & MPT2_CMD_COMPLETE)) {
-               printk(MPT2SAS_ERR_FMT "%s: timeout\n",
-                   ioc->name, __func__);
-               goto out;
-       }
-
-       if (ioc->scsih_cmds.status & MPT2_CMD_REPLY_VALID) {
-               mpi_reply = ioc->scsih_cmds.reply;
-
-               if (!ioc->hide_ir_msg)
-                       printk(MPT2SAS_INFO_FMT "IR shutdown (complete): "
-                           "ioc_status(0x%04x), loginfo(0x%08x)\n",
-                           ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
-                           le32_to_cpu(mpi_reply->IOCLogInfo));
-       }
-
- out:
-       ioc->scsih_cmds.status = MPT2_CMD_NOT_USED;
-       mutex_unlock(&ioc->scsih_cmds.mutex);
-}
-
-/**
- * _scsih_shutdown - routine call during system shutdown
- * @pdev: PCI device struct
- *
- * Return nothing.
- */
-static void
-_scsih_shutdown(struct pci_dev *pdev)
-{
-       struct Scsi_Host *shost = pci_get_drvdata(pdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-       struct workqueue_struct *wq;
-       unsigned long flags;
-
-       ioc->remove_host = 1;
-       _scsih_fw_event_cleanup_queue(ioc);
-
-       spin_lock_irqsave(&ioc->fw_event_lock, flags);
-       wq = ioc->firmware_event_thread;
-       ioc->firmware_event_thread = NULL;
-       spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
-       if (wq)
-               destroy_workqueue(wq);
-
-       _scsih_ir_shutdown(ioc);
-       mpt2sas_base_detach(ioc);
-}
-
-/**
- * _scsih_remove - detach and remove add host
- * @pdev: PCI device struct
- *
- * Routine called when unloading the driver.
- * Return nothing.
- */
-static void
-_scsih_remove(struct pci_dev *pdev)
-{
-       struct Scsi_Host *shost = pci_get_drvdata(pdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-       struct _sas_port *mpt2sas_port, *next_port;
-       struct _raid_device *raid_device, *next;
-       struct MPT2SAS_TARGET *sas_target_priv_data;
-       struct workqueue_struct *wq;
-       unsigned long flags;
-
-       ioc->remove_host = 1;
-       _scsih_fw_event_cleanup_queue(ioc);
-
-       spin_lock_irqsave(&ioc->fw_event_lock, flags);
-       wq = ioc->firmware_event_thread;
-       ioc->firmware_event_thread = NULL;
-       spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
-       if (wq)
-               destroy_workqueue(wq);
-
-       /* release all the volumes */
-       _scsih_ir_shutdown(ioc);
-       list_for_each_entry_safe(raid_device, next, &ioc->raid_device_list,
-           list) {
-               if (raid_device->starget) {
-                       sas_target_priv_data =
-                           raid_device->starget->hostdata;
-                       sas_target_priv_data->deleted = 1;
-                       scsi_remove_target(&raid_device->starget->dev);
-               }
-               printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), wwid"
-                   "(0x%016llx)\n", ioc->name,  raid_device->handle,
-                   (unsigned long long) raid_device->wwid);
-               _scsih_raid_device_remove(ioc, raid_device);
-       }
-
-       /* free ports attached to the sas_host */
-       list_for_each_entry_safe(mpt2sas_port, next_port,
-          &ioc->sas_hba.sas_port_list, port_list) {
-               if (mpt2sas_port->remote_identify.device_type ==
-                   SAS_END_DEVICE)
-                       mpt2sas_device_remove_by_sas_address(ioc,
-                           mpt2sas_port->remote_identify.sas_address);
-               else if (mpt2sas_port->remote_identify.device_type ==
-                   SAS_EDGE_EXPANDER_DEVICE ||
-                   mpt2sas_port->remote_identify.device_type ==
-                   SAS_FANOUT_EXPANDER_DEVICE)
-                       mpt2sas_expander_remove(ioc,
-                           mpt2sas_port->remote_identify.sas_address);
-       }
-
-       /* free phys attached to the sas_host */
-       if (ioc->sas_hba.num_phys) {
-               kfree(ioc->sas_hba.phy);
-               ioc->sas_hba.phy = NULL;
-               ioc->sas_hba.num_phys = 0;
-       }
-
-       sas_remove_host(shost);
-       scsi_remove_host(shost);
-       mpt2sas_base_detach(ioc);
-       spin_lock(&gioc_lock);
-       list_del(&ioc->list);
-       spin_unlock(&gioc_lock);
-       scsi_host_put(shost);
-}
-
-/**
- * _scsih_probe_boot_devices - reports 1st device
- * @ioc: per adapter object
- *
- * If specified in bios page 2, this routine reports the 1st
- * device scsi-ml or sas transport for persistent boot device
- * purposes.  Please refer to function _scsih_determine_boot_device()
- */
-static void
-_scsih_probe_boot_devices(struct MPT2SAS_ADAPTER *ioc)
-{
-       u8 is_raid;
-       void *device;
-       struct _sas_device *sas_device;
-       struct _raid_device *raid_device;
-       u16 handle;
-       u64 sas_address_parent;
-       u64 sas_address;
-       unsigned long flags;
-       int rc;
-
-        /* no Bios, return immediately */
-       if (!ioc->bios_pg3.BiosVersion)
-               return;
-
-       device = NULL;
-       is_raid = 0;
-       if (ioc->req_boot_device.device) {
-               device =  ioc->req_boot_device.device;
-               is_raid = ioc->req_boot_device.is_raid;
-       } else if (ioc->req_alt_boot_device.device) {
-               device =  ioc->req_alt_boot_device.device;
-               is_raid = ioc->req_alt_boot_device.is_raid;
-       } else if (ioc->current_boot_device.device) {
-               device =  ioc->current_boot_device.device;
-               is_raid = ioc->current_boot_device.is_raid;
-       }
-
-       if (!device)
-               return;
-
-       if (is_raid) {
-               raid_device = device;
-               rc = scsi_add_device(ioc->shost, RAID_CHANNEL,
-                   raid_device->id, 0);
-               if (rc)
-                       _scsih_raid_device_remove(ioc, raid_device);
-       } else {
-               spin_lock_irqsave(&ioc->sas_device_lock, flags);
-               sas_device = device;
-               handle = sas_device->handle;
-               sas_address_parent = sas_device->sas_address_parent;
-               sas_address = sas_device->sas_address;
-               list_move_tail(&sas_device->list, &ioc->sas_device_list);
-               spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-
-               if (ioc->hide_drives)
-                       return;
-               if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
-                   sas_device->sas_address_parent)) {
-                       _scsih_sas_device_remove(ioc, sas_device);
-               } else if (!sas_device->starget) {
-                       if (!ioc->is_driver_loading) {
-                               mpt2sas_transport_port_remove(ioc,
-                                       sas_address,
-                                       sas_address_parent);
-                               _scsih_sas_device_remove(ioc, sas_device);
-                       }
-               }
-       }
-}
-
-/**
- * _scsih_probe_raid - reporting raid volumes to scsi-ml
- * @ioc: per adapter object
- *
- * Called during initial loading of the driver.
- */
-static void
-_scsih_probe_raid(struct MPT2SAS_ADAPTER *ioc)
-{
-       struct _raid_device *raid_device, *raid_next;
-       int rc;
-
-       list_for_each_entry_safe(raid_device, raid_next,
-           &ioc->raid_device_list, list) {
-               if (raid_device->starget)
-                       continue;
-               rc = scsi_add_device(ioc->shost, RAID_CHANNEL,
-                   raid_device->id, 0);
-               if (rc)
-                       _scsih_raid_device_remove(ioc, raid_device);
-       }
-}
-
-static struct _sas_device *get_next_sas_device(struct MPT2SAS_ADAPTER *ioc)
-{
-       struct _sas_device *sas_device = NULL;
-       unsigned long flags;
-
-       spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       if (!list_empty(&ioc->sas_device_init_list)) {
-               sas_device = list_first_entry(&ioc->sas_device_init_list,
-                               struct _sas_device, list);
-               sas_device_get(sas_device);
-       }
-       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-
-       return sas_device;
-}
-
-static void sas_device_make_active(struct MPT2SAS_ADAPTER *ioc,
-               struct _sas_device *sas_device)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&ioc->sas_device_lock, flags);
-
-       /*
-        * Since we dropped the lock during the call to port_add(), we need to
-        * be careful here that somebody else didn't move or delete this item
-        * while we were busy with other things.
-        *
-        * If it was on the list, we need a put() for the reference the list
-        * had. Either way, we need a get() for the destination list.
-        */
-       if (!list_empty(&sas_device->list)) {
-               list_del_init(&sas_device->list);
-               sas_device_put(sas_device);
-       }
-
-       sas_device_get(sas_device);
-       list_add_tail(&sas_device->list, &ioc->sas_device_list);
-
-       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-}
-
-/**
- * _scsih_probe_sas - reporting sas devices to sas transport
- * @ioc: per adapter object
- *
- * Called during initial loading of the driver.
- */
-static void
-_scsih_probe_sas(struct MPT2SAS_ADAPTER *ioc)
-{
-       struct _sas_device *sas_device;
-
-       if (ioc->hide_drives)
-               return;
-
-       while ((sas_device = get_next_sas_device(ioc))) {
-               if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
-                               sas_device->sas_address_parent)) {
-                       _scsih_sas_device_remove(ioc, sas_device);
-                       sas_device_put(sas_device);
-                       continue;
-               } else if (!sas_device->starget) {
-                       if (!ioc->is_driver_loading) {
-                               mpt2sas_transport_port_remove(ioc,
-                                               sas_device->sas_address,
-                                               sas_device->sas_address_parent);
-                               _scsih_sas_device_remove(ioc, sas_device);
-                               sas_device_put(sas_device);
-                               continue;
-                       }
-               }
-
-               sas_device_make_active(ioc, sas_device);
-               sas_device_put(sas_device);
-       }
-}
-
-/**
- * _scsih_probe_devices - probing for devices
- * @ioc: per adapter object
- *
- * Called during initial loading of the driver.
- */
-static void
-_scsih_probe_devices(struct MPT2SAS_ADAPTER *ioc)
-{
-       u16 volume_mapping_flags;
-
-       if (!(ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR))
-               return;  /* return when IOC doesn't support initiator mode */
-
-       _scsih_probe_boot_devices(ioc);
-
-       if (ioc->ir_firmware) {
-               volume_mapping_flags =
-                   le16_to_cpu(ioc->ioc_pg8.IRVolumeMappingFlags) &
-                   MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE;
-               if (volume_mapping_flags ==
-                   MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING) {
-                       _scsih_probe_raid(ioc);
-                       _scsih_probe_sas(ioc);
-               } else {
-                       _scsih_probe_sas(ioc);
-                       _scsih_probe_raid(ioc);
-               }
-       } else
-               _scsih_probe_sas(ioc);
-}
-
-
-/**
- * _scsih_scan_start - scsi lld callback for .scan_start
- * @shost: SCSI host pointer
- *
- * The shost has the ability to discover targets on its own instead
- * of scanning the entire bus.  In our implemention, we will kick off
- * firmware discovery.
- */
-static void
-_scsih_scan_start(struct Scsi_Host *shost)
-{
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-       int rc;
-
-       if (diag_buffer_enable != -1 && diag_buffer_enable != 0)
-               mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable);
-
-       if (disable_discovery > 0)
-               return;
-
-       ioc->start_scan = 1;
-       rc = mpt2sas_port_enable(ioc);
-
-       if (rc != 0)
-               printk(MPT2SAS_INFO_FMT "port enable: FAILED\n", ioc->name);
-}
-
-/**
- * _scsih_scan_finished - scsi lld callback for .scan_finished
- * @shost: SCSI host pointer
- * @time: elapsed time of the scan in jiffies
- *
- * This function will be called periodically until it returns 1 with the
- * scsi_host and the elapsed time of the scan in jiffies. In our implemention,
- * we wait for firmware discovery to complete, then return 1.
- */
-static int
-_scsih_scan_finished(struct Scsi_Host *shost, unsigned long time)
-{
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-
-       if (disable_discovery > 0) {
-               ioc->is_driver_loading = 0;
-               ioc->wait_for_discovery_to_complete = 0;
-               return 1;
-       }
-
-       if (time >= (300 * HZ)) {
-               ioc->base_cmds.status = MPT2_CMD_NOT_USED;
-               printk(MPT2SAS_INFO_FMT "port enable: FAILED with timeout "
-                   "(timeout=300s)\n", ioc->name);
-               ioc->is_driver_loading = 0;
-               return 1;
-       }
-
-       if (ioc->start_scan)
-               return 0;
-
-       if (ioc->start_scan_failed) {
-               printk(MPT2SAS_INFO_FMT "port enable: FAILED with "
-                   "(ioc_status=0x%08x)\n", ioc->name, ioc->start_scan_failed);
-               ioc->is_driver_loading = 0;
-               ioc->wait_for_discovery_to_complete = 0;
-               ioc->remove_host = 1;
-               return 1;
-       }
-
-       printk(MPT2SAS_INFO_FMT "port enable: SUCCESS\n", ioc->name);
-       ioc->base_cmds.status = MPT2_CMD_NOT_USED;
-
-       if (ioc->wait_for_discovery_to_complete) {
-               ioc->wait_for_discovery_to_complete = 0;
-               _scsih_probe_devices(ioc);
-       }
-       mpt2sas_base_start_watchdog(ioc);
-       ioc->is_driver_loading = 0;
-       return 1;
-}
-
-
-/**
- * _scsih_probe - attach and add scsi host
- * @pdev: PCI device struct
- * @id: pci device id
- *
- * Returns 0 success, anything else error.
- */
-static int
-_scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
-{
-       struct MPT2SAS_ADAPTER *ioc;
-       struct Scsi_Host *shost;
-       int rv;
-
-       shost = scsi_host_alloc(&scsih_driver_template,
-           sizeof(struct MPT2SAS_ADAPTER));
-       if (!shost)
-               return -ENODEV;
-
-       /* init local params */
-       ioc = shost_priv(shost);
-       memset(ioc, 0, sizeof(struct MPT2SAS_ADAPTER));
-       INIT_LIST_HEAD(&ioc->list);
-       spin_lock(&gioc_lock);
-       list_add_tail(&ioc->list, &mpt2sas_ioc_list);
-       spin_unlock(&gioc_lock);
-       ioc->shost = shost;
-       ioc->id = mpt_ids++;
-       sprintf(ioc->name, "%s%d", MPT2SAS_DRIVER_NAME, ioc->id);
-       ioc->pdev = pdev;
-       if (id->device == MPI2_MFGPAGE_DEVID_SSS6200) {
-               ioc->is_warpdrive = 1;
-               ioc->hide_ir_msg = 1;
-       } else
-               ioc->mfg_pg10_hide_flag = MFG_PAGE10_EXPOSE_ALL_DISKS;
-       ioc->scsi_io_cb_idx = scsi_io_cb_idx;
-       ioc->tm_cb_idx = tm_cb_idx;
-       ioc->ctl_cb_idx = ctl_cb_idx;
-       ioc->base_cb_idx = base_cb_idx;
-       ioc->port_enable_cb_idx = port_enable_cb_idx;
-       ioc->transport_cb_idx = transport_cb_idx;
-       ioc->scsih_cb_idx = scsih_cb_idx;
-       ioc->config_cb_idx = config_cb_idx;
-       ioc->tm_tr_cb_idx = tm_tr_cb_idx;
-       ioc->tm_tr_volume_cb_idx = tm_tr_volume_cb_idx;
-       ioc->tm_sas_control_cb_idx = tm_sas_control_cb_idx;
-       ioc->logging_level = logging_level;
-       ioc->schedule_dead_ioc_flush_running_cmds = &_scsih_flush_running_cmds;
-       /* misc semaphores and spin locks */
-       mutex_init(&ioc->reset_in_progress_mutex);
-       /* initializing pci_access_mutex lock */
-       mutex_init(&ioc->pci_access_mutex);
-       spin_lock_init(&ioc->ioc_reset_in_progress_lock);
-       spin_lock_init(&ioc->scsi_lookup_lock);
-       spin_lock_init(&ioc->sas_device_lock);
-       spin_lock_init(&ioc->sas_node_lock);
-       spin_lock_init(&ioc->fw_event_lock);
-       spin_lock_init(&ioc->raid_device_lock);
-
-       INIT_LIST_HEAD(&ioc->sas_device_list);
-       INIT_LIST_HEAD(&ioc->sas_device_init_list);
-       INIT_LIST_HEAD(&ioc->sas_expander_list);
-       INIT_LIST_HEAD(&ioc->fw_event_list);
-       INIT_LIST_HEAD(&ioc->raid_device_list);
-       INIT_LIST_HEAD(&ioc->sas_hba.sas_port_list);
-       INIT_LIST_HEAD(&ioc->delayed_tr_list);
-       INIT_LIST_HEAD(&ioc->delayed_tr_volume_list);
-       INIT_LIST_HEAD(&ioc->reply_queue_list);
-
-       /* init shost parameters */
-       shost->max_cmd_len = 32;
-       shost->max_lun = max_lun;
-       shost->transportt = mpt2sas_transport_template;
-       shost->unique_id = ioc->id;
-
-       if (max_sectors != 0xFFFF) {
-               if (max_sectors < 64) {
-                       shost->max_sectors = 64;
-                       printk(MPT2SAS_WARN_FMT "Invalid value %d passed "
-                           "for max_sectors, range is 64 to 32767. Assigning "
-                           "value of 64.\n", ioc->name, max_sectors);
-               } else if (max_sectors > 32767) {
-                       shost->max_sectors = 32767;
-                       printk(MPT2SAS_WARN_FMT "Invalid value %d passed "
-                           "for max_sectors, range is 64 to 8192. Assigning "
-                           "default value of 32767.\n", ioc->name,
-                           max_sectors);
-               } else {
-                       shost->max_sectors = max_sectors & 0xFFFE;
-                       printk(MPT2SAS_INFO_FMT "The max_sectors value is "
-                           "set to %d\n", ioc->name, shost->max_sectors);
-               }
-       }
-
-       /* register EEDP capabilities with SCSI layer */
-       if (prot_mask)
-               scsi_host_set_prot(shost, prot_mask);
-       else
-               scsi_host_set_prot(shost, SHOST_DIF_TYPE1_PROTECTION
-                                  | SHOST_DIF_TYPE2_PROTECTION
-                                  | SHOST_DIF_TYPE3_PROTECTION);
-
-       scsi_host_set_guard(shost, SHOST_DIX_GUARD_CRC);
-
-       /* event thread */
-       snprintf(ioc->firmware_event_name, sizeof(ioc->firmware_event_name),
-           "fw_event%d", ioc->id);
-       ioc->firmware_event_thread = create_singlethread_workqueue(
-           ioc->firmware_event_name);
-       if (!ioc->firmware_event_thread) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               rv = -ENODEV;
-               goto out_thread_fail;
-       }
-
-       ioc->is_driver_loading = 1;
-       if ((mpt2sas_base_attach(ioc))) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               rv = -ENODEV;
-               goto out_attach_fail;
-       }
-
-       if (ioc->is_warpdrive) {
-               if (ioc->mfg_pg10_hide_flag ==  MFG_PAGE10_EXPOSE_ALL_DISKS)
-                       ioc->hide_drives = 0;
-               else if (ioc->mfg_pg10_hide_flag ==  MFG_PAGE10_HIDE_ALL_DISKS)
-                       ioc->hide_drives = 1;
-               else {
-                       if (_scsih_get_num_volumes(ioc))
-                               ioc->hide_drives = 1;
-                       else
-                               ioc->hide_drives = 0;
-               }
-       } else
-               ioc->hide_drives = 0;
-
-       rv = scsi_add_host(shost, &pdev->dev);
-       if (rv) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               goto out_add_shost_fail;
-       }
-
-       scsi_scan_host(shost);
-
-       return 0;
-
- out_add_shost_fail:
-       mpt2sas_base_detach(ioc);
- out_attach_fail:
-       destroy_workqueue(ioc->firmware_event_thread);
- out_thread_fail:
-       spin_lock(&gioc_lock);
-       list_del(&ioc->list);
-       spin_unlock(&gioc_lock);
-       scsi_host_put(shost);
-       return rv;
-}
-
-#ifdef CONFIG_PM
-/**
- * _scsih_suspend - power management suspend main entry point
- * @pdev: PCI device struct
- * @state: PM state change to (usually PCI_D3)
- *
- * Returns 0 success, anything else error.
- */
-static int
-_scsih_suspend(struct pci_dev *pdev, pm_message_t state)
-{
-       struct Scsi_Host *shost = pci_get_drvdata(pdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-       pci_power_t device_state;
-
-       mpt2sas_base_stop_watchdog(ioc);
-       scsi_block_requests(shost);
-       _scsih_ir_shutdown(ioc);
-       device_state = pci_choose_state(pdev, state);
-       printk(MPT2SAS_INFO_FMT "pdev=0x%p, slot=%s, entering "
-           "operating state [D%d]\n", ioc->name, pdev,
-           pci_name(pdev), device_state);
-
-       mpt2sas_base_free_resources(ioc);
-       pci_save_state(pdev);
-       pci_set_power_state(pdev, device_state);
-       return 0;
-}
-
-/**
- * _scsih_resume - power management resume main entry point
- * @pdev: PCI device struct
- *
- * Returns 0 success, anything else error.
- */
-static int
-_scsih_resume(struct pci_dev *pdev)
-{
-       struct Scsi_Host *shost = pci_get_drvdata(pdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-       pci_power_t device_state = pdev->current_state;
-       int r;
-
-       printk(MPT2SAS_INFO_FMT "pdev=0x%p, slot=%s, previous "
-           "operating state [D%d]\n", ioc->name, pdev,
-           pci_name(pdev), device_state);
-
-       pci_set_power_state(pdev, PCI_D0);
-       pci_enable_wake(pdev, PCI_D0, 0);
-       pci_restore_state(pdev);
-       ioc->pdev = pdev;
-       r = mpt2sas_base_map_resources(ioc);
-       if (r)
-               return r;
-
-       mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, SOFT_RESET);
-       scsi_unblock_requests(shost);
-       mpt2sas_base_start_watchdog(ioc);
-       return 0;
-}
-#endif /* CONFIG_PM */
-
-/**
- * _scsih_pci_error_detected - Called when a PCI error is detected.
- * @pdev: PCI device struct
- * @state: PCI channel state
- *
- * Description: Called when a PCI error is detected.
- *
- * Return value:
- *      PCI_ERS_RESULT_NEED_RESET or PCI_ERS_RESULT_DISCONNECT
- */
-static pci_ers_result_t
-_scsih_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
-{
-       struct Scsi_Host *shost = pci_get_drvdata(pdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-
-       printk(MPT2SAS_INFO_FMT "PCI error: detected callback, state(%d)!!\n",
-           ioc->name, state);
-
-       switch (state) {
-       case pci_channel_io_normal:
-               return PCI_ERS_RESULT_CAN_RECOVER;
-       case pci_channel_io_frozen:
-               /* Fatal error, prepare for slot reset */
-               ioc->pci_error_recovery = 1;
-               scsi_block_requests(ioc->shost);
-               mpt2sas_base_stop_watchdog(ioc);
-               mpt2sas_base_free_resources(ioc);
-               return PCI_ERS_RESULT_NEED_RESET;
-       case pci_channel_io_perm_failure:
-               /* Permanent error, prepare for device removal */
-               ioc->pci_error_recovery = 1;
-               mpt2sas_base_stop_watchdog(ioc);
-               _scsih_flush_running_cmds(ioc);
-               return PCI_ERS_RESULT_DISCONNECT;
-       }
-       return PCI_ERS_RESULT_NEED_RESET;
-}
-
-/**
- * _scsih_pci_slot_reset - Called when PCI slot has been reset.
- * @pdev: PCI device struct
- *
- * Description: This routine is called by the pci error recovery
- * code after the PCI slot has been reset, just before we
- * should resume normal operations.
- */
-static pci_ers_result_t
-_scsih_pci_slot_reset(struct pci_dev *pdev)
-{
-       struct Scsi_Host *shost = pci_get_drvdata(pdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-       int rc;
-
-       printk(MPT2SAS_INFO_FMT "PCI error: slot reset callback!!\n",
-               ioc->name);
-
-       ioc->pci_error_recovery = 0;
-       ioc->pdev = pdev;
-       pci_restore_state(pdev);
-       rc = mpt2sas_base_map_resources(ioc);
-       if (rc)
-               return PCI_ERS_RESULT_DISCONNECT;
-
-
-       rc = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
-           FORCE_BIG_HAMMER);
-
-       printk(MPT2SAS_WARN_FMT "hard reset: %s\n", ioc->name,
-           (rc == 0) ? "success" : "failed");
-
-       if (!rc)
-               return PCI_ERS_RESULT_RECOVERED;
-       else
-               return PCI_ERS_RESULT_DISCONNECT;
-}
-
-/**
- * _scsih_pci_resume() - resume normal ops after PCI reset
- * @pdev: pointer to PCI device
- *
- * Called when the error recovery driver tells us that its
- * OK to resume normal operation. Use completion to allow
- * halted scsi ops to resume.
- */
-static void
-_scsih_pci_resume(struct pci_dev *pdev)
-{
-       struct Scsi_Host *shost = pci_get_drvdata(pdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-
-       printk(MPT2SAS_INFO_FMT "PCI error: resume callback!!\n", ioc->name);
-
-       pci_cleanup_aer_uncorrect_error_status(pdev);
-       mpt2sas_base_start_watchdog(ioc);
-       scsi_unblock_requests(ioc->shost);
-}
-
-/**
- * _scsih_pci_mmio_enabled - Enable MMIO and dump debug registers
- * @pdev: pointer to PCI device
- */
-static pci_ers_result_t
-_scsih_pci_mmio_enabled(struct pci_dev *pdev)
-{
-       struct Scsi_Host *shost = pci_get_drvdata(pdev);
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-
-       printk(MPT2SAS_INFO_FMT "PCI error: mmio enabled callback!!\n",
-           ioc->name);
-
-       /* TODO - dump whatever for debugging purposes */
-
-       /* Request a slot reset. */
-       return PCI_ERS_RESULT_NEED_RESET;
-}
-
-static const struct pci_error_handlers _scsih_err_handler = {
-       .error_detected = _scsih_pci_error_detected,
-       .mmio_enabled = _scsih_pci_mmio_enabled,
-       .slot_reset =   _scsih_pci_slot_reset,
-       .resume =       _scsih_pci_resume,
-};
-
-static struct pci_driver scsih_driver = {
-       .name           = MPT2SAS_DRIVER_NAME,
-       .id_table       = scsih_pci_table,
-       .probe          = _scsih_probe,
-       .remove         = _scsih_remove,
-       .shutdown       = _scsih_shutdown,
-       .err_handler    = &_scsih_err_handler,
-#ifdef CONFIG_PM
-       .suspend        = _scsih_suspend,
-       .resume         = _scsih_resume,
-#endif
-};
-
-/* raid transport support */
-static struct raid_function_template mpt2sas_raid_functions = {
-       .cookie         = &scsih_driver_template,
-       .is_raid        = _scsih_is_raid,
-       .get_resync     = _scsih_get_resync,
-       .get_state      = _scsih_get_state,
-};
-
-/**
- * _scsih_init - main entry point for this driver.
- *
- * Returns 0 success, anything else error.
- */
-static int __init
-_scsih_init(void)
-{
-       int error;
-
-       mpt_ids = 0;
-       printk(KERN_INFO "%s version %s loaded\n", MPT2SAS_DRIVER_NAME,
-           MPT2SAS_DRIVER_VERSION);
-
-       mpt2sas_transport_template =
-           sas_attach_transport(&mpt2sas_transport_functions);
-       if (!mpt2sas_transport_template)
-               return -ENODEV;
-       /* raid transport support */
-       mpt2sas_raid_template = raid_class_attach(&mpt2sas_raid_functions);
-       if (!mpt2sas_raid_template) {
-               sas_release_transport(mpt2sas_transport_template);
-               return -ENODEV;
-       }
-
-       mpt2sas_base_initialize_callback_handler();
-
-        /* queuecommand callback hander */
-       scsi_io_cb_idx = mpt2sas_base_register_callback_handler(_scsih_io_done);
-
-       /* task management callback handler */
-       tm_cb_idx = mpt2sas_base_register_callback_handler(_scsih_tm_done);
-
-       /* base internal commands callback handler */
-       base_cb_idx = mpt2sas_base_register_callback_handler(mpt2sas_base_done);
-       port_enable_cb_idx = mpt2sas_base_register_callback_handler(
-               mpt2sas_port_enable_done);
-
-       /* transport internal commands callback handler */
-       transport_cb_idx = mpt2sas_base_register_callback_handler(
-           mpt2sas_transport_done);
-
-       /* scsih internal commands callback handler */
-       scsih_cb_idx = mpt2sas_base_register_callback_handler(_scsih_done);
-
-       /* configuration page API internal commands callback handler */
-       config_cb_idx = mpt2sas_base_register_callback_handler(
-           mpt2sas_config_done);
-
-       /* ctl module callback handler */
-       ctl_cb_idx = mpt2sas_base_register_callback_handler(mpt2sas_ctl_done);
-
-       tm_tr_cb_idx = mpt2sas_base_register_callback_handler(
-           _scsih_tm_tr_complete);
-
-       tm_tr_volume_cb_idx = mpt2sas_base_register_callback_handler(
-           _scsih_tm_volume_tr_complete);
-
-       tm_sas_control_cb_idx = mpt2sas_base_register_callback_handler(
-           _scsih_sas_control_complete);
-
-       mpt2sas_ctl_init();
-
-       error = pci_register_driver(&scsih_driver);
-       if (error) {
-               /* raid transport support */
-               raid_class_release(mpt2sas_raid_template);
-               sas_release_transport(mpt2sas_transport_template);
-       }
-
-       return error;
-}
-
-/**
- * _scsih_exit - exit point for this driver (when it is a module).
- *
- * Returns 0 success, anything else error.
- */
-static void __exit
-_scsih_exit(void)
-{
-       printk(KERN_INFO "mpt2sas version %s unloading\n",
-           MPT2SAS_DRIVER_VERSION);
-
-       pci_unregister_driver(&scsih_driver);
-
-       mpt2sas_ctl_exit();
-
-       mpt2sas_base_release_callback_handler(scsi_io_cb_idx);
-       mpt2sas_base_release_callback_handler(tm_cb_idx);
-       mpt2sas_base_release_callback_handler(base_cb_idx);
-       mpt2sas_base_release_callback_handler(port_enable_cb_idx);
-       mpt2sas_base_release_callback_handler(transport_cb_idx);
-       mpt2sas_base_release_callback_handler(scsih_cb_idx);
-       mpt2sas_base_release_callback_handler(config_cb_idx);
-       mpt2sas_base_release_callback_handler(ctl_cb_idx);
-
-       mpt2sas_base_release_callback_handler(tm_tr_cb_idx);
-       mpt2sas_base_release_callback_handler(tm_tr_volume_cb_idx);
-       mpt2sas_base_release_callback_handler(tm_sas_control_cb_idx);
-
-       /* raid transport support */
-       raid_class_release(mpt2sas_raid_template);
-       sas_release_transport(mpt2sas_transport_template);
-
-}
-
-module_init(_scsih_init);
-module_exit(_scsih_exit);
diff --git a/drivers/scsi/mpt2sas/mpt2sas_transport.c b/drivers/scsi/mpt2sas/mpt2sas_transport.c
deleted file mode 100644 (file)
index af86800..0000000
+++ /dev/null
@@ -1,2173 +0,0 @@
-/*
- * SAS Transport Layer for MPT (Message Passing Technology) based controllers
- *
- * This code is based on drivers/scsi/mpt2sas/mpt2_transport.c
- * Copyright (C) 2007-2014  LSI Corporation
- * Copyright (C) 20013-2014 Avago Technologies
- *  (mailto: MPT-FusionLinux.pdl@avagotech.com)
- *
- * 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.
- *
- * NO WARRANTY
- * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
- * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
- * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
- * solely responsible for determining the appropriateness of using and
- * distributing the Program and assumes all risks associated with its
- * exercise of rights under this Agreement, including but not limited to
- * the risks and costs of program errors, damage to or loss of data,
- * programs or equipment, and unavailability or interruption of operations.
-
- * DISCLAIMER OF LIABILITY
- * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
- * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
- * USA.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/workqueue.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_device.h>
-#include <scsi/scsi_host.h>
-#include <scsi/scsi_transport_sas.h>
-#include <scsi/scsi_dbg.h>
-
-#include "mpt2sas_base.h"
-/**
- * _transport_sas_node_find_by_sas_address - sas node search
- * @ioc: per adapter object
- * @sas_address: sas address of expander or sas host
- * Context: Calling function should acquire ioc->sas_node_lock.
- *
- * Search for either hba phys or expander device based on handle, then returns
- * the sas_node object.
- */
-static struct _sas_node *
-_transport_sas_node_find_by_sas_address(struct MPT2SAS_ADAPTER *ioc,
-    u64 sas_address)
-{
-       if (ioc->sas_hba.sas_address == sas_address)
-               return &ioc->sas_hba;
-       else
-               return mpt2sas_scsih_expander_find_by_sas_address(ioc,
-                   sas_address);
-}
-
-/**
- * _transport_convert_phy_link_rate -
- * @link_rate: link rate returned from mpt firmware
- *
- * Convert link_rate from mpi fusion into sas_transport form.
- */
-static enum sas_linkrate
-_transport_convert_phy_link_rate(u8 link_rate)
-{
-       enum sas_linkrate rc;
-
-       switch (link_rate) {
-       case MPI2_SAS_NEG_LINK_RATE_1_5:
-               rc = SAS_LINK_RATE_1_5_GBPS;
-               break;
-       case MPI2_SAS_NEG_LINK_RATE_3_0:
-               rc = SAS_LINK_RATE_3_0_GBPS;
-               break;
-       case MPI2_SAS_NEG_LINK_RATE_6_0:
-               rc = SAS_LINK_RATE_6_0_GBPS;
-               break;
-       case MPI2_SAS_NEG_LINK_RATE_PHY_DISABLED:
-               rc = SAS_PHY_DISABLED;
-               break;
-       case MPI2_SAS_NEG_LINK_RATE_NEGOTIATION_FAILED:
-               rc = SAS_LINK_RATE_FAILED;
-               break;
-       case MPI2_SAS_NEG_LINK_RATE_PORT_SELECTOR:
-               rc = SAS_SATA_PORT_SELECTOR;
-               break;
-       case MPI2_SAS_NEG_LINK_RATE_SMP_RESET_IN_PROGRESS:
-               rc = SAS_PHY_RESET_IN_PROGRESS;
-               break;
-       default:
-       case MPI2_SAS_NEG_LINK_RATE_SATA_OOB_COMPLETE:
-       case MPI2_SAS_NEG_LINK_RATE_UNKNOWN_LINK_RATE:
-               rc = SAS_LINK_RATE_UNKNOWN;
-               break;
-       }
-       return rc;
-}
-
-/**
- * _transport_set_identify - set identify for phys and end devices
- * @ioc: per adapter object
- * @handle: device handle
- * @identify: sas identify info
- *
- * Populates sas identify info.
- *
- * Returns 0 for success, non-zero for failure.
- */
-static int
-_transport_set_identify(struct MPT2SAS_ADAPTER *ioc, u16 handle,
-    struct sas_identify *identify)
-{
-       Mpi2SasDevicePage0_t sas_device_pg0;
-       Mpi2ConfigReply_t mpi_reply;
-       u32 device_info;
-       u32 ioc_status;
-
-       if (ioc->shost_recovery || ioc->pci_error_recovery) {
-               printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
-                   __func__, ioc->name);
-               return -EFAULT;
-       }
-
-       if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
-           MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-
-                   ioc->name, __FILE__, __LINE__, __func__);
-               return -ENXIO;
-       }
-
-       ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-           MPI2_IOCSTATUS_MASK;
-       if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
-               printk(MPT2SAS_ERR_FMT "handle(0x%04x), ioc_status(0x%04x)"
-                   "\nfailure at %s:%d/%s()!\n", ioc->name, handle, ioc_status,
-                    __FILE__, __LINE__, __func__);
-               return -EIO;
-       }
-
-       memset(identify, 0, sizeof(struct sas_identify));
-       device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
-
-       /* sas_address */
-       identify->sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
-
-       /* phy number of the parent device this device is linked to */
-       identify->phy_identifier = sas_device_pg0.PhyNum;
-
-       /* device_type */
-       switch (device_info & MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
-       case MPI2_SAS_DEVICE_INFO_NO_DEVICE:
-               identify->device_type = SAS_PHY_UNUSED;
-               break;
-       case MPI2_SAS_DEVICE_INFO_END_DEVICE:
-               identify->device_type = SAS_END_DEVICE;
-               break;
-       case MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER:
-               identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
-               break;
-       case MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER:
-               identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
-               break;
-       }
-
-       /* initiator_port_protocols */
-       if (device_info & MPI2_SAS_DEVICE_INFO_SSP_INITIATOR)
-               identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
-       if (device_info & MPI2_SAS_DEVICE_INFO_STP_INITIATOR)
-               identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
-       if (device_info & MPI2_SAS_DEVICE_INFO_SMP_INITIATOR)
-               identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
-       if (device_info & MPI2_SAS_DEVICE_INFO_SATA_HOST)
-               identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
-
-       /* target_port_protocols */
-       if (device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET)
-               identify->target_port_protocols |= SAS_PROTOCOL_SSP;
-       if (device_info & MPI2_SAS_DEVICE_INFO_STP_TARGET)
-               identify->target_port_protocols |= SAS_PROTOCOL_STP;
-       if (device_info & MPI2_SAS_DEVICE_INFO_SMP_TARGET)
-               identify->target_port_protocols |= SAS_PROTOCOL_SMP;
-       if (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE)
-               identify->target_port_protocols |= SAS_PROTOCOL_SATA;
-
-       return 0;
-}
-
-/**
- * mpt2sas_transport_done -  internal transport layer callback handler.
- * @ioc: per adapter object
- * @smid: system request message index
- * @msix_index: MSIX table index supplied by the OS
- * @reply: reply message frame(lower 32bit addr)
- *
- * Callback handler when sending internal generated transport cmds.
- * The callback index passed is `ioc->transport_cb_idx`
- *
- * Return 1 meaning mf should be freed from _base_interrupt
- *        0 means the mf is freed from this function.
- */
-u8
-mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
-    u32 reply)
-{
-       MPI2DefaultReply_t *mpi_reply;
-
-       mpi_reply =  mpt2sas_base_get_reply_virt_addr(ioc, reply);
-       if (ioc->transport_cmds.status == MPT2_CMD_NOT_USED)
-               return 1;
-       if (ioc->transport_cmds.smid != smid)
-               return 1;
-       ioc->transport_cmds.status |= MPT2_CMD_COMPLETE;
-       if (mpi_reply) {
-               memcpy(ioc->transport_cmds.reply, mpi_reply,
-                   mpi_reply->MsgLength*4);
-               ioc->transport_cmds.status |= MPT2_CMD_REPLY_VALID;
-       }
-       ioc->transport_cmds.status &= ~MPT2_CMD_PENDING;
-       complete(&ioc->transport_cmds.done);
-       return 1;
-}
-
-/* report manufacture request structure */
-struct rep_manu_request{
-       u8 smp_frame_type;
-       u8 function;
-       u8 reserved;
-       u8 request_length;
-};
-
-/* report manufacture reply structure */
-struct rep_manu_reply{
-       u8 smp_frame_type; /* 0x41 */
-       u8 function; /* 0x01 */
-       u8 function_result;
-       u8 response_length;
-       u16 expander_change_count;
-       u8 reserved0[2];
-       u8 sas_format;
-       u8 reserved2[3];
-       u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN];
-       u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN];
-       u8 product_rev[SAS_EXPANDER_PRODUCT_REV_LEN];
-       u8 component_vendor_id[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN];
-       u16 component_id;
-       u8 component_revision_id;
-       u8 reserved3;
-       u8 vendor_specific[8];
-};
-
-/**
- * _transport_expander_report_manufacture - obtain SMP report_manufacture
- * @ioc: per adapter object
- * @sas_address: expander sas address
- * @edev: the sas_expander_device object
- *
- * Fills in the sas_expander_device object when SMP port is created.
- *
- * Returns 0 for success, non-zero for failure.
- */
-static int
-_transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc,
-    u64 sas_address, struct sas_expander_device *edev)
-{
-       Mpi2SmpPassthroughRequest_t *mpi_request;
-       Mpi2SmpPassthroughReply_t *mpi_reply;
-       struct rep_manu_reply *manufacture_reply;
-       struct rep_manu_request *manufacture_request;
-       int rc;
-       u16 smid;
-       u32 ioc_state;
-       unsigned long timeleft;
-       void *psge;
-       u32 sgl_flags;
-       u8 issue_reset = 0;
-       void *data_out = NULL;
-       dma_addr_t data_out_dma;
-       u32 sz;
-       u16 wait_state_count;
-
-       if (ioc->shost_recovery || ioc->pci_error_recovery) {
-               printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
-                   __func__, ioc->name);
-               return -EFAULT;
-       }
-
-       mutex_lock(&ioc->transport_cmds.mutex);
-
-       if (ioc->transport_cmds.status != MPT2_CMD_NOT_USED) {
-               printk(MPT2SAS_ERR_FMT "%s: transport_cmds in use\n",
-                   ioc->name, __func__);
-               rc = -EAGAIN;
-               goto out;
-       }
-       ioc->transport_cmds.status = MPT2_CMD_PENDING;
-
-       wait_state_count = 0;
-       ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
-       while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
-               if (wait_state_count++ == 10) {
-                       printk(MPT2SAS_ERR_FMT
-                           "%s: failed due to ioc not operational\n",
-                           ioc->name, __func__);
-                       rc = -EFAULT;
-                       goto out;
-               }
-               ssleep(1);
-               ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
-               printk(MPT2SAS_INFO_FMT "%s: waiting for "
-                   "operational state(count=%d)\n", ioc->name,
-                   __func__, wait_state_count);
-       }
-       if (wait_state_count)
-               printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n",
-                   ioc->name, __func__);
-
-       smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx);
-       if (!smid) {
-               printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
-                   ioc->name, __func__);
-               rc = -EAGAIN;
-               goto out;
-       }
-
-       rc = 0;
-       mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
-       ioc->transport_cmds.smid = smid;
-
-       sz = sizeof(struct rep_manu_request) + sizeof(struct rep_manu_reply);
-       data_out = pci_alloc_consistent(ioc->pdev, sz, &data_out_dma);
-
-       if (!data_out) {
-               printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__,
-                   __LINE__, __func__);
-               rc = -ENOMEM;
-               mpt2sas_base_free_smid(ioc, smid);
-               goto out;
-       }
-
-       manufacture_request = data_out;
-       manufacture_request->smp_frame_type = 0x40;
-       manufacture_request->function = 1;
-       manufacture_request->reserved = 0;
-       manufacture_request->request_length = 0;
-
-       memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
-       mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
-       mpi_request->PhysicalPort = 0xFF;
-       mpi_request->VF_ID = 0; /* TODO */
-       mpi_request->VP_ID = 0;
-       mpi_request->SASAddress = cpu_to_le64(sas_address);
-       mpi_request->RequestDataLength =
-           cpu_to_le16(sizeof(struct rep_manu_request));
-       psge = &mpi_request->SGL;
-
-       /* WRITE sgel first */
-       sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
-           MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC);
-       sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
-       ioc->base_add_sg_single(psge, sgl_flags |
-           sizeof(struct rep_manu_request), data_out_dma);
-
-       /* incr sgel */
-       psge += ioc->sge_size;
-
-       /* READ sgel last */
-       sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
-           MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER |
-           MPI2_SGE_FLAGS_END_OF_LIST);
-       sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
-       ioc->base_add_sg_single(psge, sgl_flags |
-           sizeof(struct rep_manu_reply), data_out_dma +
-           sizeof(struct rep_manu_request));
-
-       dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "report_manufacture - "
-           "send to sas_addr(0x%016llx)\n", ioc->name,
-           (unsigned long long)sas_address));
-       init_completion(&ioc->transport_cmds.done);
-       mpt2sas_base_put_smid_default(ioc, smid);
-       timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done,
-           10*HZ);
-
-       if (!(ioc->transport_cmds.status & MPT2_CMD_COMPLETE)) {
-               printk(MPT2SAS_ERR_FMT "%s: timeout\n",
-                   ioc->name, __func__);
-               _debug_dump_mf(mpi_request,
-                   sizeof(Mpi2SmpPassthroughRequest_t)/4);
-               if (!(ioc->transport_cmds.status & MPT2_CMD_RESET))
-                       issue_reset = 1;
-               goto issue_host_reset;
-       }
-
-       dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "report_manufacture - "
-           "complete\n", ioc->name));
-
-       if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) {
-               u8 *tmp;
-
-               mpi_reply = ioc->transport_cmds.reply;
-
-               dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
-                   "report_manufacture - reply data transfer size(%d)\n",
-                   ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength)));
-
-               if (le16_to_cpu(mpi_reply->ResponseDataLength) !=
-                   sizeof(struct rep_manu_reply))
-                       goto out;
-
-               manufacture_reply = data_out + sizeof(struct rep_manu_request);
-               strncpy(edev->vendor_id, manufacture_reply->vendor_id,
-                    SAS_EXPANDER_VENDOR_ID_LEN);
-               strncpy(edev->product_id, manufacture_reply->product_id,
-                    SAS_EXPANDER_PRODUCT_ID_LEN);
-               strncpy(edev->product_rev, manufacture_reply->product_rev,
-                    SAS_EXPANDER_PRODUCT_REV_LEN);
-               edev->level = manufacture_reply->sas_format & 1;
-               if (edev->level) {
-                       strncpy(edev->component_vendor_id,
-                           manufacture_reply->component_vendor_id,
-                            SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN);
-                       tmp = (u8 *)&manufacture_reply->component_id;
-                       edev->component_id = tmp[0] << 8 | tmp[1];
-                       edev->component_revision_id =
-                           manufacture_reply->component_revision_id;
-               }
-       } else
-               dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
-                   "report_manufacture - no reply\n", ioc->name));
-
- issue_host_reset:
-       if (issue_reset)
-               mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
-                   FORCE_BIG_HAMMER);
- out:
-       ioc->transport_cmds.status = MPT2_CMD_NOT_USED;
-       if (data_out)
-               pci_free_consistent(ioc->pdev, sz, data_out, data_out_dma);
-
-       mutex_unlock(&ioc->transport_cmds.mutex);
-       return rc;
-}
-
-/**
- * _transport_delete_port - helper function to removing a port
- * @ioc: per adapter object
- * @mpt2sas_port: mpt2sas per port object
- *
- * Returns nothing.
- */
-static void
-_transport_delete_port(struct MPT2SAS_ADAPTER *ioc,
-       struct _sas_port *mpt2sas_port)
-{
-       u64 sas_address = mpt2sas_port->remote_identify.sas_address;
-       enum sas_device_type device_type =
-           mpt2sas_port->remote_identify.device_type;
-
-       dev_printk(KERN_INFO, &mpt2sas_port->port->dev,
-           "remove: sas_addr(0x%016llx)\n",
-           (unsigned long long) sas_address);
-
-       ioc->logging_level |= MPT_DEBUG_TRANSPORT;
-       if (device_type == SAS_END_DEVICE)
-               mpt2sas_device_remove_by_sas_address(ioc, sas_address);
-       else if (device_type == SAS_EDGE_EXPANDER_DEVICE ||
-           device_type == SAS_FANOUT_EXPANDER_DEVICE)
-               mpt2sas_expander_remove(ioc, sas_address);
-       ioc->logging_level &= ~MPT_DEBUG_TRANSPORT;
-}
-
-/**
- * _transport_delete_phy - helper function to removing single phy from port
- * @ioc: per adapter object
- * @mpt2sas_port: mpt2sas per port object
- * @mpt2sas_phy: mpt2sas per phy object
- *
- * Returns nothing.
- */
-static void
-_transport_delete_phy(struct MPT2SAS_ADAPTER *ioc,
-       struct _sas_port *mpt2sas_port, struct _sas_phy *mpt2sas_phy)
-{
-       u64 sas_address = mpt2sas_port->remote_identify.sas_address;
-
-       dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev,
-           "remove: sas_addr(0x%016llx), phy(%d)\n",
-           (unsigned long long) sas_address, mpt2sas_phy->phy_id);
-
-       list_del(&mpt2sas_phy->port_siblings);
-       mpt2sas_port->num_phys--;
-       sas_port_delete_phy(mpt2sas_port->port, mpt2sas_phy->phy);
-       mpt2sas_phy->phy_belongs_to_port = 0;
-}
-
-/**
- * _transport_add_phy - helper function to adding single phy to port
- * @ioc: per adapter object
- * @mpt2sas_port: mpt2sas per port object
- * @mpt2sas_phy: mpt2sas per phy object
- *
- * Returns nothing.
- */
-static void
-_transport_add_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_port *mpt2sas_port,
-       struct _sas_phy *mpt2sas_phy)
-{
-       u64 sas_address = mpt2sas_port->remote_identify.sas_address;
-
-       dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev,
-           "add: sas_addr(0x%016llx), phy(%d)\n", (unsigned long long)
-           sas_address, mpt2sas_phy->phy_id);
-
-       list_add_tail(&mpt2sas_phy->port_siblings, &mpt2sas_port->phy_list);
-       mpt2sas_port->num_phys++;
-       sas_port_add_phy(mpt2sas_port->port, mpt2sas_phy->phy);
-       mpt2sas_phy->phy_belongs_to_port = 1;
-}
-
-/**
- * _transport_add_phy_to_an_existing_port - adding new phy to existing port
- * @ioc: per adapter object
- * @sas_node: sas node object (either expander or sas host)
- * @mpt2sas_phy: mpt2sas per phy object
- * @sas_address: sas address of device/expander were phy needs to be added to
- *
- * Returns nothing.
- */
-static void
-_transport_add_phy_to_an_existing_port(struct MPT2SAS_ADAPTER *ioc,
-struct _sas_node *sas_node, struct _sas_phy *mpt2sas_phy, u64 sas_address)
-{
-       struct _sas_port *mpt2sas_port;
-       struct _sas_phy *phy_srch;
-
-       if (mpt2sas_phy->phy_belongs_to_port == 1)
-               return;
-
-       list_for_each_entry(mpt2sas_port, &sas_node->sas_port_list,
-           port_list) {
-               if (mpt2sas_port->remote_identify.sas_address !=
-                   sas_address)
-                       continue;
-               list_for_each_entry(phy_srch, &mpt2sas_port->phy_list,
-                   port_siblings) {
-                       if (phy_srch == mpt2sas_phy)
-                               return;
-               }
-               _transport_add_phy(ioc, mpt2sas_port, mpt2sas_phy);
-                       return;
-       }
-
-}
-
-/**
- * _transport_del_phy_from_an_existing_port - delete phy from existing port
- * @ioc: per adapter object
- * @sas_node: sas node object (either expander or sas host)
- * @mpt2sas_phy: mpt2sas per phy object
- *
- * Returns nothing.
- */
-static void
-_transport_del_phy_from_an_existing_port(struct MPT2SAS_ADAPTER *ioc,
-       struct _sas_node *sas_node, struct _sas_phy *mpt2sas_phy)
-{
-       struct _sas_port *mpt2sas_port, *next;
-       struct _sas_phy *phy_srch;
-
-       if (mpt2sas_phy->phy_belongs_to_port == 0)
-               return;
-
-       list_for_each_entry_safe(mpt2sas_port, next, &sas_node->sas_port_list,
-           port_list) {
-               list_for_each_entry(phy_srch, &mpt2sas_port->phy_list,
-                   port_siblings) {
-                       if (phy_srch != mpt2sas_phy)
-                               continue;
-                       if (mpt2sas_port->num_phys == 1)
-                               _transport_delete_port(ioc, mpt2sas_port);
-                       else
-                               _transport_delete_phy(ioc, mpt2sas_port,
-                                   mpt2sas_phy);
-                       return;
-               }
-       }
-}
-
-/**
- * _transport_sanity_check - sanity check when adding a new port
- * @ioc: per adapter object
- * @sas_node: sas node object (either expander or sas host)
- * @sas_address: sas address of device being added
- *
- * See the explanation above from _transport_delete_duplicate_port
- */
-static void
-_transport_sanity_check(struct MPT2SAS_ADAPTER *ioc, struct _sas_node *sas_node,
-     u64 sas_address)
-{
-       int i;
-
-       for (i = 0; i < sas_node->num_phys; i++) {
-               if (sas_node->phy[i].remote_identify.sas_address != sas_address)
-                       continue;
-               if (sas_node->phy[i].phy_belongs_to_port == 1)
-                       _transport_del_phy_from_an_existing_port(ioc, sas_node,
-                           &sas_node->phy[i]);
-       }
-}
-
-/**
- * mpt2sas_transport_port_add - insert port to the list
- * @ioc: per adapter object
- * @handle: handle of attached device
- * @sas_address: sas address of parent expander or sas host
- * Context: This function will acquire ioc->sas_node_lock.
- *
- * Adding new port object to the sas_node->sas_port_list.
- *
- * Returns mpt2sas_port.
- */
-struct _sas_port *
-mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, u16 handle,
-    u64 sas_address)
-{
-       struct _sas_phy *mpt2sas_phy, *next;
-       struct _sas_port *mpt2sas_port;
-       unsigned long flags;
-       struct _sas_node *sas_node;
-       struct sas_rphy *rphy;
-       int i;
-       struct sas_port *port;
-
-       mpt2sas_port = kzalloc(sizeof(struct _sas_port),
-           GFP_KERNEL);
-       if (!mpt2sas_port) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               return NULL;
-       }
-
-       INIT_LIST_HEAD(&mpt2sas_port->port_list);
-       INIT_LIST_HEAD(&mpt2sas_port->phy_list);
-       spin_lock_irqsave(&ioc->sas_node_lock, flags);
-       sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address);
-       spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
-
-       if (!sas_node) {
-               printk(MPT2SAS_ERR_FMT "%s: Could not find "
-                   "parent sas_address(0x%016llx)!\n", ioc->name,
-                   __func__, (unsigned long long)sas_address);
-               goto out_fail;
-       }
-
-       if ((_transport_set_identify(ioc, handle,
-           &mpt2sas_port->remote_identify))) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               goto out_fail;
-       }
-
-       if (mpt2sas_port->remote_identify.device_type == SAS_PHY_UNUSED) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               goto out_fail;
-       }
-
-       _transport_sanity_check(ioc, sas_node,
-           mpt2sas_port->remote_identify.sas_address);
-
-       for (i = 0; i < sas_node->num_phys; i++) {
-               if (sas_node->phy[i].remote_identify.sas_address !=
-                   mpt2sas_port->remote_identify.sas_address)
-                       continue;
-               list_add_tail(&sas_node->phy[i].port_siblings,
-                   &mpt2sas_port->phy_list);
-               mpt2sas_port->num_phys++;
-       }
-
-       if (!mpt2sas_port->num_phys) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               goto out_fail;
-       }
-
-       port = sas_port_alloc_num(sas_node->parent_dev);
-       if ((sas_port_add(port))) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               goto out_fail;
-       }
-
-       list_for_each_entry(mpt2sas_phy, &mpt2sas_port->phy_list,
-           port_siblings) {
-               if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
-                       dev_printk(KERN_INFO, &port->dev, "add: handle(0x%04x)"
-                           ", sas_addr(0x%016llx), phy(%d)\n", handle,
-                           (unsigned long long)
-                           mpt2sas_port->remote_identify.sas_address,
-                           mpt2sas_phy->phy_id);
-               sas_port_add_phy(port, mpt2sas_phy->phy);
-               mpt2sas_phy->phy_belongs_to_port = 1;
-       }
-
-       mpt2sas_port->port = port;
-       if (mpt2sas_port->remote_identify.device_type == SAS_END_DEVICE)
-               rphy = sas_end_device_alloc(port);
-       else
-               rphy = sas_expander_alloc(port,
-                   mpt2sas_port->remote_identify.device_type);
-
-       rphy->identify = mpt2sas_port->remote_identify;
-       if ((sas_rphy_add(rphy))) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-       }
-       if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
-               dev_printk(KERN_INFO, &rphy->dev, "add: handle(0x%04x), "
-                   "sas_addr(0x%016llx)\n", handle,
-                   (unsigned long long)
-                   mpt2sas_port->remote_identify.sas_address);
-       mpt2sas_port->rphy = rphy;
-       spin_lock_irqsave(&ioc->sas_node_lock, flags);
-       list_add_tail(&mpt2sas_port->port_list, &sas_node->sas_port_list);
-       spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
-
-       /* fill in report manufacture */
-       if (mpt2sas_port->remote_identify.device_type ==
-           MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER ||
-           mpt2sas_port->remote_identify.device_type ==
-           MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER)
-               _transport_expander_report_manufacture(ioc,
-                   mpt2sas_port->remote_identify.sas_address,
-                   rphy_to_expander_device(rphy));
-
-       return mpt2sas_port;
-
- out_fail:
-       list_for_each_entry_safe(mpt2sas_phy, next, &mpt2sas_port->phy_list,
-           port_siblings)
-               list_del(&mpt2sas_phy->port_siblings);
-       kfree(mpt2sas_port);
-       return NULL;
-}
-
-/**
- * mpt2sas_transport_port_remove - remove port from the list
- * @ioc: per adapter object
- * @sas_address: sas address of attached device
- * @sas_address_parent: sas address of parent expander or sas host
- * Context: This function will acquire ioc->sas_node_lock.
- *
- * Removing object and freeing associated memory from the
- * ioc->sas_port_list.
- *
- * Return nothing.
- */
-void
-mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
-    u64 sas_address_parent)
-{
-       int i;
-       unsigned long flags;
-       struct _sas_port *mpt2sas_port, *next;
-       struct _sas_node *sas_node;
-       u8 found = 0;
-       struct _sas_phy *mpt2sas_phy, *next_phy;
-
-       spin_lock_irqsave(&ioc->sas_node_lock, flags);
-       sas_node = _transport_sas_node_find_by_sas_address(ioc,
-           sas_address_parent);
-       if (!sas_node) {
-               spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
-               return;
-       }
-       list_for_each_entry_safe(mpt2sas_port, next, &sas_node->sas_port_list,
-           port_list) {
-               if (mpt2sas_port->remote_identify.sas_address != sas_address)
-                       continue;
-               found = 1;
-               list_del(&mpt2sas_port->port_list);
-               goto out;
-       }
- out:
-       if (!found) {
-               spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
-               return;
-       }
-
-       for (i = 0; i < sas_node->num_phys; i++) {
-               if (sas_node->phy[i].remote_identify.sas_address == sas_address)
-                       memset(&sas_node->phy[i].remote_identify, 0 ,
-                           sizeof(struct sas_identify));
-       }
-
-       spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
-       list_for_each_entry_safe(mpt2sas_phy, next_phy,
-           &mpt2sas_port->phy_list, port_siblings) {
-               if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
-                       dev_printk(KERN_INFO, &mpt2sas_port->port->dev,
-                           "remove: sas_addr(0x%016llx), phy(%d)\n",
-                           (unsigned long long)
-                           mpt2sas_port->remote_identify.sas_address,
-                           mpt2sas_phy->phy_id);
-               mpt2sas_phy->phy_belongs_to_port = 0;
-               sas_port_delete_phy(mpt2sas_port->port, mpt2sas_phy->phy);
-               list_del(&mpt2sas_phy->port_siblings);
-       }
-       sas_port_delete(mpt2sas_port->port);
-       kfree(mpt2sas_port);
-}
-
-/**
- * mpt2sas_transport_add_host_phy - report sas_host phy to transport
- * @ioc: per adapter object
- * @mpt2sas_phy: mpt2sas per phy object
- * @phy_pg0: sas phy page 0
- * @parent_dev: parent device class object
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_transport_add_host_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy
-    *mpt2sas_phy, Mpi2SasPhyPage0_t phy_pg0, struct device *parent_dev)
-{
-       struct sas_phy *phy;
-       int phy_index = mpt2sas_phy->phy_id;
-
-
-       INIT_LIST_HEAD(&mpt2sas_phy->port_siblings);
-       phy = sas_phy_alloc(parent_dev, phy_index);
-       if (!phy) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               return -1;
-       }
-       if ((_transport_set_identify(ioc, mpt2sas_phy->handle,
-           &mpt2sas_phy->identify))) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               return -1;
-       }
-       phy->identify = mpt2sas_phy->identify;
-       mpt2sas_phy->attached_handle = le16_to_cpu(phy_pg0.AttachedDevHandle);
-       if (mpt2sas_phy->attached_handle)
-               _transport_set_identify(ioc, mpt2sas_phy->attached_handle,
-                   &mpt2sas_phy->remote_identify);
-       phy->identify.phy_identifier = mpt2sas_phy->phy_id;
-       phy->negotiated_linkrate = _transport_convert_phy_link_rate(
-           phy_pg0.NegotiatedLinkRate & MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL);
-       phy->minimum_linkrate_hw = _transport_convert_phy_link_rate(
-           phy_pg0.HwLinkRate & MPI2_SAS_HWRATE_MIN_RATE_MASK);
-       phy->maximum_linkrate_hw = _transport_convert_phy_link_rate(
-           phy_pg0.HwLinkRate >> 4);
-       phy->minimum_linkrate = _transport_convert_phy_link_rate(
-           phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK);
-       phy->maximum_linkrate = _transport_convert_phy_link_rate(
-           phy_pg0.ProgrammedLinkRate >> 4);
-
-       if ((sas_phy_add(phy))) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               sas_phy_free(phy);
-               return -1;
-       }
-       if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
-               dev_printk(KERN_INFO, &phy->dev,
-                   "add: handle(0x%04x), sas_addr(0x%016llx)\n"
-                   "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
-                   mpt2sas_phy->handle, (unsigned long long)
-                   mpt2sas_phy->identify.sas_address,
-                   mpt2sas_phy->attached_handle,
-                   (unsigned long long)
-                   mpt2sas_phy->remote_identify.sas_address);
-       mpt2sas_phy->phy = phy;
-       return 0;
-}
-
-
-/**
- * mpt2sas_transport_add_expander_phy - report expander phy to transport
- * @ioc: per adapter object
- * @mpt2sas_phy: mpt2sas per phy object
- * @expander_pg1: expander page 1
- * @parent_dev: parent device class object
- *
- * Returns 0 for success, non-zero for failure.
- */
-int
-mpt2sas_transport_add_expander_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy
-    *mpt2sas_phy, Mpi2ExpanderPage1_t expander_pg1, struct device *parent_dev)
-{
-       struct sas_phy *phy;
-       int phy_index = mpt2sas_phy->phy_id;
-
-       INIT_LIST_HEAD(&mpt2sas_phy->port_siblings);
-       phy = sas_phy_alloc(parent_dev, phy_index);
-       if (!phy) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               return -1;
-       }
-       if ((_transport_set_identify(ioc, mpt2sas_phy->handle,
-           &mpt2sas_phy->identify))) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               return -1;
-       }
-       phy->identify = mpt2sas_phy->identify;
-       mpt2sas_phy->attached_handle =
-           le16_to_cpu(expander_pg1.AttachedDevHandle);
-       if (mpt2sas_phy->attached_handle)
-               _transport_set_identify(ioc, mpt2sas_phy->attached_handle,
-                   &mpt2sas_phy->remote_identify);
-       phy->identify.phy_identifier = mpt2sas_phy->phy_id;
-       phy->negotiated_linkrate = _transport_convert_phy_link_rate(
-           expander_pg1.NegotiatedLinkRate &
-           MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL);
-       phy->minimum_linkrate_hw = _transport_convert_phy_link_rate(
-           expander_pg1.HwLinkRate & MPI2_SAS_HWRATE_MIN_RATE_MASK);
-       phy->maximum_linkrate_hw = _transport_convert_phy_link_rate(
-           expander_pg1.HwLinkRate >> 4);
-       phy->minimum_linkrate = _transport_convert_phy_link_rate(
-           expander_pg1.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK);
-       phy->maximum_linkrate = _transport_convert_phy_link_rate(
-           expander_pg1.ProgrammedLinkRate >> 4);
-
-       if ((sas_phy_add(phy))) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               sas_phy_free(phy);
-               return -1;
-       }
-       if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
-               dev_printk(KERN_INFO, &phy->dev,
-                   "add: handle(0x%04x), sas_addr(0x%016llx)\n"
-                   "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
-                   mpt2sas_phy->handle, (unsigned long long)
-                   mpt2sas_phy->identify.sas_address,
-                   mpt2sas_phy->attached_handle,
-                   (unsigned long long)
-                   mpt2sas_phy->remote_identify.sas_address);
-       mpt2sas_phy->phy = phy;
-       return 0;
-}
-
-/**
- * mpt2sas_transport_update_links - refreshing phy link changes
- * @ioc: per adapter object
- * @sas_address: sas address of parent expander or sas host
- * @handle: attached device handle
- * @phy_numberv: phy number
- * @link_rate: new link rate
- *
- * Returns nothing.
- */
-void
-mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc,
-     u64 sas_address, u16 handle, u8 phy_number, u8 link_rate)
-{
-       unsigned long flags;
-       struct _sas_node *sas_node;
-       struct _sas_phy *mpt2sas_phy;
-
-       if (ioc->shost_recovery || ioc->pci_error_recovery)
-               return;
-
-       spin_lock_irqsave(&ioc->sas_node_lock, flags);
-       sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address);
-       if (!sas_node) {
-               spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
-               return;
-       }
-
-       mpt2sas_phy = &sas_node->phy[phy_number];
-       mpt2sas_phy->attached_handle = handle;
-       spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
-       if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)) {
-               _transport_set_identify(ioc, handle,
-                   &mpt2sas_phy->remote_identify);
-               _transport_add_phy_to_an_existing_port(ioc, sas_node,
-                   mpt2sas_phy, mpt2sas_phy->remote_identify.sas_address);
-       } else
-               memset(&mpt2sas_phy->remote_identify, 0 , sizeof(struct
-                   sas_identify));
-
-       if (mpt2sas_phy->phy)
-               mpt2sas_phy->phy->negotiated_linkrate =
-                   _transport_convert_phy_link_rate(link_rate);
-
-       if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
-               dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev,
-                   "refresh: parent sas_addr(0x%016llx),\n"
-                   "\tlink_rate(0x%02x), phy(%d)\n"
-                   "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
-                   (unsigned long long)sas_address,
-                   link_rate, phy_number, handle, (unsigned long long)
-                   mpt2sas_phy->remote_identify.sas_address);
-}
-
-static inline void *
-phy_to_ioc(struct sas_phy *phy)
-{
-       struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
-       return shost_priv(shost);
-}
-
-static inline void *
-rphy_to_ioc(struct sas_rphy *rphy)
-{
-       struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
-       return shost_priv(shost);
-}
-
-
-/* report phy error log structure */
-struct phy_error_log_request{
-       u8 smp_frame_type; /* 0x40 */
-       u8 function; /* 0x11 */
-       u8 allocated_response_length;
-       u8 request_length; /* 02 */
-       u8 reserved_1[5];
-       u8 phy_identifier;
-       u8 reserved_2[2];
-};
-
-/* report phy error log reply structure */
-struct phy_error_log_reply{
-       u8 smp_frame_type; /* 0x41 */
-       u8 function; /* 0x11 */
-       u8 function_result;
-       u8 response_length;
-       __be16 expander_change_count;
-       u8 reserved_1[3];
-       u8 phy_identifier;
-       u8 reserved_2[2];
-       __be32 invalid_dword;
-       __be32 running_disparity_error;
-       __be32 loss_of_dword_sync;
-       __be32 phy_reset_problem;
-};
-
-/**
- * _transport_get_expander_phy_error_log - return expander counters
- * @ioc: per adapter object
- * @phy: The sas phy object
- *
- * Returns 0 for success, non-zero for failure.
- *
- */
-static int
-_transport_get_expander_phy_error_log(struct MPT2SAS_ADAPTER *ioc,
-    struct sas_phy *phy)
-{
-       Mpi2SmpPassthroughRequest_t *mpi_request;
-       Mpi2SmpPassthroughReply_t *mpi_reply;
-       struct phy_error_log_request *phy_error_log_request;
-       struct phy_error_log_reply *phy_error_log_reply;
-       int rc;
-       u16 smid;
-       u32 ioc_state;
-       unsigned long timeleft;
-       void *psge;
-       u32 sgl_flags;
-       u8 issue_reset = 0;
-       void *data_out = NULL;
-       dma_addr_t data_out_dma;
-       u32 sz;
-       u16 wait_state_count;
-
-       if (ioc->shost_recovery || ioc->pci_error_recovery) {
-               printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
-                   __func__, ioc->name);
-               return -EFAULT;
-       }
-
-       mutex_lock(&ioc->transport_cmds.mutex);
-
-       if (ioc->transport_cmds.status != MPT2_CMD_NOT_USED) {
-               printk(MPT2SAS_ERR_FMT "%s: transport_cmds in use\n",
-                   ioc->name, __func__);
-               rc = -EAGAIN;
-               goto out;
-       }
-       ioc->transport_cmds.status = MPT2_CMD_PENDING;
-
-       wait_state_count = 0;
-       ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
-       while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
-               if (wait_state_count++ == 10) {
-                       printk(MPT2SAS_ERR_FMT
-                           "%s: failed due to ioc not operational\n",
-                           ioc->name, __func__);
-                       rc = -EFAULT;
-                       goto out;
-               }
-               ssleep(1);
-               ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
-               printk(MPT2SAS_INFO_FMT "%s: waiting for "
-                   "operational state(count=%d)\n", ioc->name,
-                   __func__, wait_state_count);
-       }
-       if (wait_state_count)
-               printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n",
-                   ioc->name, __func__);
-
-       smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx);
-       if (!smid) {
-               printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
-                   ioc->name, __func__);
-               rc = -EAGAIN;
-               goto out;
-       }
-
-       mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
-       ioc->transport_cmds.smid = smid;
-
-       sz = sizeof(struct phy_error_log_request) +
-           sizeof(struct phy_error_log_reply);
-       data_out = pci_alloc_consistent(ioc->pdev, sz, &data_out_dma);
-       if (!data_out) {
-               printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__,
-                   __LINE__, __func__);
-               rc = -ENOMEM;
-               mpt2sas_base_free_smid(ioc, smid);
-               goto out;
-       }
-
-       rc = -EINVAL;
-       memset(data_out, 0, sz);
-       phy_error_log_request = data_out;
-       phy_error_log_request->smp_frame_type = 0x40;
-       phy_error_log_request->function = 0x11;
-       phy_error_log_request->request_length = 2;
-       phy_error_log_request->allocated_response_length = 0;
-       phy_error_log_request->phy_identifier = phy->number;
-
-       memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
-       mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
-       mpi_request->PhysicalPort = 0xFF;
-       mpi_request->VF_ID = 0; /* TODO */
-       mpi_request->VP_ID = 0;
-       mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address);
-       mpi_request->RequestDataLength =
-           cpu_to_le16(sizeof(struct phy_error_log_request));
-       psge = &mpi_request->SGL;
-
-       /* WRITE sgel first */
-       sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
-           MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC);
-       sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
-       ioc->base_add_sg_single(psge, sgl_flags |
-           sizeof(struct phy_error_log_request), data_out_dma);
-
-       /* incr sgel */
-       psge += ioc->sge_size;
-
-       /* READ sgel last */
-       sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
-           MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER |
-           MPI2_SGE_FLAGS_END_OF_LIST);
-       sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
-       ioc->base_add_sg_single(psge, sgl_flags |
-           sizeof(struct phy_error_log_reply), data_out_dma +
-           sizeof(struct phy_error_log_request));
-
-       dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "phy_error_log - "
-           "send to sas_addr(0x%016llx), phy(%d)\n", ioc->name,
-           (unsigned long long)phy->identify.sas_address, phy->number));
-       init_completion(&ioc->transport_cmds.done);
-       mpt2sas_base_put_smid_default(ioc, smid);
-       timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done,
-           10*HZ);
-
-       if (!(ioc->transport_cmds.status & MPT2_CMD_COMPLETE)) {
-               printk(MPT2SAS_ERR_FMT "%s: timeout\n",
-                   ioc->name, __func__);
-               _debug_dump_mf(mpi_request,
-                   sizeof(Mpi2SmpPassthroughRequest_t)/4);
-               if (!(ioc->transport_cmds.status & MPT2_CMD_RESET))
-                       issue_reset = 1;
-               goto issue_host_reset;
-       }
-
-       dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "phy_error_log - "
-           "complete\n", ioc->name));
-
-       if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) {
-
-               mpi_reply = ioc->transport_cmds.reply;
-
-               dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
-                   "phy_error_log - reply data transfer size(%d)\n",
-                   ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength)));
-
-               if (le16_to_cpu(mpi_reply->ResponseDataLength) !=
-                   sizeof(struct phy_error_log_reply))
-                       goto out;
-
-               phy_error_log_reply = data_out +
-                   sizeof(struct phy_error_log_request);
-
-               dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
-                   "phy_error_log - function_result(%d)\n",
-                   ioc->name, phy_error_log_reply->function_result));
-
-               phy->invalid_dword_count =
-                   be32_to_cpu(phy_error_log_reply->invalid_dword);
-               phy->running_disparity_error_count =
-                   be32_to_cpu(phy_error_log_reply->running_disparity_error);
-               phy->loss_of_dword_sync_count =
-                   be32_to_cpu(phy_error_log_reply->loss_of_dword_sync);
-               phy->phy_reset_problem_count =
-                   be32_to_cpu(phy_error_log_reply->phy_reset_problem);
-               rc = 0;
-       } else
-               dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
-                   "phy_error_log - no reply\n", ioc->name));
-
- issue_host_reset:
-       if (issue_reset)
-               mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
-                   FORCE_BIG_HAMMER);
- out:
-       ioc->transport_cmds.status = MPT2_CMD_NOT_USED;
-       if (data_out)
-               pci_free_consistent(ioc->pdev, sz, data_out, data_out_dma);
-
-       mutex_unlock(&ioc->transport_cmds.mutex);
-       return rc;
-}
-
-/**
- * _transport_get_linkerrors - return phy counters for both hba and expanders
- * @phy: The sas phy object
- *
- * Returns 0 for success, non-zero for failure.
- *
- */
-static int
-_transport_get_linkerrors(struct sas_phy *phy)
-{
-       struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy);
-       unsigned long flags;
-       Mpi2ConfigReply_t mpi_reply;
-       Mpi2SasPhyPage1_t phy_pg1;
-
-       spin_lock_irqsave(&ioc->sas_node_lock, flags);
-       if (_transport_sas_node_find_by_sas_address(ioc,
-           phy->identify.sas_address) == NULL) {
-               spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
-               return -EINVAL;
-       }
-       spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
-
-       if (phy->identify.sas_address != ioc->sas_hba.sas_address)
-               return _transport_get_expander_phy_error_log(ioc, phy);
-
-       /* get hba phy error logs */
-       if ((mpt2sas_config_get_phy_pg1(ioc, &mpi_reply, &phy_pg1,
-                   phy->number))) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               return -ENXIO;
-       }
-
-       if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo)
-               printk(MPT2SAS_INFO_FMT "phy(%d), ioc_status"
-                   "(0x%04x), loginfo(0x%08x)\n", ioc->name,
-                   phy->number, le16_to_cpu(mpi_reply.IOCStatus),
-                   le32_to_cpu(mpi_reply.IOCLogInfo));
-
-       phy->invalid_dword_count = le32_to_cpu(phy_pg1.InvalidDwordCount);
-       phy->running_disparity_error_count =
-           le32_to_cpu(phy_pg1.RunningDisparityErrorCount);
-       phy->loss_of_dword_sync_count =
-           le32_to_cpu(phy_pg1.LossDwordSynchCount);
-       phy->phy_reset_problem_count =
-           le32_to_cpu(phy_pg1.PhyResetProblemCount);
-       return 0;
-}
-
-/**
- * _transport_get_enclosure_identifier -
- * @phy: The sas phy object
- *
- * Obtain the enclosure logical id for an expander.
- * Returns 0 for success, non-zero for failure.
- */
-static int
-_transport_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
-{
-       struct MPT2SAS_ADAPTER *ioc = rphy_to_ioc(rphy);
-       struct _sas_device *sas_device;
-       unsigned long flags;
-       int rc;
-
-       spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       sas_device = __mpt2sas_get_sdev_by_addr(ioc,
-           rphy->identify.sas_address);
-       if (sas_device) {
-               *identifier = sas_device->enclosure_logical_id;
-               rc = 0;
-               sas_device_put(sas_device);
-       } else {
-               *identifier = 0;
-               rc = -ENXIO;
-       }
-
-       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-       return rc;
-}
-
-/**
- * _transport_get_bay_identifier -
- * @phy: The sas phy object
- *
- * Returns the slot id for a device that resides inside an enclosure.
- */
-static int
-_transport_get_bay_identifier(struct sas_rphy *rphy)
-{
-       struct MPT2SAS_ADAPTER *ioc = rphy_to_ioc(rphy);
-       struct _sas_device *sas_device;
-       unsigned long flags;
-       int rc;
-
-       spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       sas_device = __mpt2sas_get_sdev_by_addr(ioc,
-           rphy->identify.sas_address);
-       if (sas_device) {
-               rc = sas_device->slot;
-               sas_device_put(sas_device);
-       } else {
-               rc = -ENXIO;
-       }
-       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-       return rc;
-}
-
-/* phy control request structure */
-struct phy_control_request{
-       u8 smp_frame_type; /* 0x40 */
-       u8 function; /* 0x91 */
-       u8 allocated_response_length;
-       u8 request_length; /* 0x09 */
-       u16 expander_change_count;
-       u8 reserved_1[3];
-       u8 phy_identifier;
-       u8 phy_operation;
-       u8 reserved_2[13];
-       u64 attached_device_name;
-       u8 programmed_min_physical_link_rate;
-       u8 programmed_max_physical_link_rate;
-       u8 reserved_3[6];
-};
-
-/* phy control reply structure */
-struct phy_control_reply{
-       u8 smp_frame_type; /* 0x41 */
-       u8 function; /* 0x11 */
-       u8 function_result;
-       u8 response_length;
-};
-
-#define SMP_PHY_CONTROL_LINK_RESET     (0x01)
-#define SMP_PHY_CONTROL_HARD_RESET     (0x02)
-#define SMP_PHY_CONTROL_DISABLE                (0x03)
-
-/**
- * _transport_expander_phy_control - expander phy control
- * @ioc: per adapter object
- * @phy: The sas phy object
- *
- * Returns 0 for success, non-zero for failure.
- *
- */
-static int
-_transport_expander_phy_control(struct MPT2SAS_ADAPTER *ioc,
-    struct sas_phy *phy, u8 phy_operation)
-{
-       Mpi2SmpPassthroughRequest_t *mpi_request;
-       Mpi2SmpPassthroughReply_t *mpi_reply;
-       struct phy_control_request *phy_control_request;
-       struct phy_control_reply *phy_control_reply;
-       int rc;
-       u16 smid;
-       u32 ioc_state;
-       unsigned long timeleft;
-       void *psge;
-       u32 sgl_flags;
-       u8 issue_reset = 0;
-       void *data_out = NULL;
-       dma_addr_t data_out_dma;
-       u32 sz;
-       u16 wait_state_count;
-
-       if (ioc->shost_recovery) {
-               printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
-                   __func__, ioc->name);
-               return -EFAULT;
-       }
-
-       mutex_lock(&ioc->transport_cmds.mutex);
-
-       if (ioc->transport_cmds.status != MPT2_CMD_NOT_USED) {
-               printk(MPT2SAS_ERR_FMT "%s: transport_cmds in use\n",
-                   ioc->name, __func__);
-               rc = -EAGAIN;
-               goto out;
-       }
-       ioc->transport_cmds.status = MPT2_CMD_PENDING;
-
-       wait_state_count = 0;
-       ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
-       while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
-               if (wait_state_count++ == 10) {
-                       printk(MPT2SAS_ERR_FMT
-                           "%s: failed due to ioc not operational\n",
-                           ioc->name, __func__);
-                       rc = -EFAULT;
-                       goto out;
-               }
-               ssleep(1);
-               ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
-               printk(MPT2SAS_INFO_FMT "%s: waiting for "
-                   "operational state(count=%d)\n", ioc->name,
-                   __func__, wait_state_count);
-       }
-       if (wait_state_count)
-               printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n",
-                   ioc->name, __func__);
-
-       smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx);
-       if (!smid) {
-               printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
-                   ioc->name, __func__);
-               rc = -EAGAIN;
-               goto out;
-       }
-
-       mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
-       ioc->transport_cmds.smid = smid;
-
-       sz = sizeof(struct phy_control_request) +
-           sizeof(struct phy_control_reply);
-       data_out = pci_alloc_consistent(ioc->pdev, sz, &data_out_dma);
-       if (!data_out) {
-               printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__,
-                   __LINE__, __func__);
-               rc = -ENOMEM;
-               mpt2sas_base_free_smid(ioc, smid);
-               goto out;
-       }
-
-       rc = -EINVAL;
-       memset(data_out, 0, sz);
-       phy_control_request = data_out;
-       phy_control_request->smp_frame_type = 0x40;
-       phy_control_request->function = 0x91;
-       phy_control_request->request_length = 9;
-       phy_control_request->allocated_response_length = 0;
-       phy_control_request->phy_identifier = phy->number;
-       phy_control_request->phy_operation = phy_operation;
-       phy_control_request->programmed_min_physical_link_rate =
-           phy->minimum_linkrate << 4;
-       phy_control_request->programmed_max_physical_link_rate =
-           phy->maximum_linkrate << 4;
-
-       memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
-       mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
-       mpi_request->PhysicalPort = 0xFF;
-       mpi_request->VF_ID = 0; /* TODO */
-       mpi_request->VP_ID = 0;
-       mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address);
-       mpi_request->RequestDataLength =
-           cpu_to_le16(sizeof(struct phy_error_log_request));
-       psge = &mpi_request->SGL;
-
-       /* WRITE sgel first */
-       sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
-           MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC);
-       sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
-       ioc->base_add_sg_single(psge, sgl_flags |
-           sizeof(struct phy_control_request), data_out_dma);
-
-       /* incr sgel */
-       psge += ioc->sge_size;
-
-       /* READ sgel last */
-       sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
-           MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER |
-           MPI2_SGE_FLAGS_END_OF_LIST);
-       sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
-       ioc->base_add_sg_single(psge, sgl_flags |
-           sizeof(struct phy_control_reply), data_out_dma +
-           sizeof(struct phy_control_request));
-
-       dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "phy_control - "
-           "send to sas_addr(0x%016llx), phy(%d), opcode(%d)\n", ioc->name,
-           (unsigned long long)phy->identify.sas_address, phy->number,
-           phy_operation));
-
-       init_completion(&ioc->transport_cmds.done);
-       mpt2sas_base_put_smid_default(ioc, smid);
-       timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done,
-           10*HZ);
-
-       if (!(ioc->transport_cmds.status & MPT2_CMD_COMPLETE)) {
-               printk(MPT2SAS_ERR_FMT "%s: timeout\n",
-                   ioc->name, __func__);
-               _debug_dump_mf(mpi_request,
-                   sizeof(Mpi2SmpPassthroughRequest_t)/4);
-               if (!(ioc->transport_cmds.status & MPT2_CMD_RESET))
-                       issue_reset = 1;
-               goto issue_host_reset;
-       }
-
-       dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "phy_control - "
-           "complete\n", ioc->name));
-
-       if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) {
-
-               mpi_reply = ioc->transport_cmds.reply;
-
-               dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
-                   "phy_control - reply data transfer size(%d)\n",
-                   ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength)));
-
-               if (le16_to_cpu(mpi_reply->ResponseDataLength) !=
-                   sizeof(struct phy_control_reply))
-                       goto out;
-
-               phy_control_reply = data_out +
-                   sizeof(struct phy_control_request);
-
-               dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
-                   "phy_control - function_result(%d)\n",
-                   ioc->name, phy_control_reply->function_result));
-
-               rc = 0;
-       } else
-               dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
-                   "phy_control - no reply\n", ioc->name));
-
- issue_host_reset:
-       if (issue_reset)
-               mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
-                   FORCE_BIG_HAMMER);
- out:
-       ioc->transport_cmds.status = MPT2_CMD_NOT_USED;
-       if (data_out)
-               pci_free_consistent(ioc->pdev, sz, data_out, data_out_dma);
-
-       mutex_unlock(&ioc->transport_cmds.mutex);
-       return rc;
-}
-
-/**
- * _transport_phy_reset -
- * @phy: The sas phy object
- * @hard_reset:
- *
- * Returns 0 for success, non-zero for failure.
- */
-static int
-_transport_phy_reset(struct sas_phy *phy, int hard_reset)
-{
-       struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy);
-       Mpi2SasIoUnitControlReply_t mpi_reply;
-       Mpi2SasIoUnitControlRequest_t mpi_request;
-       unsigned long flags;
-
-       spin_lock_irqsave(&ioc->sas_node_lock, flags);
-       if (_transport_sas_node_find_by_sas_address(ioc,
-           phy->identify.sas_address) == NULL) {
-               spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
-               return -EINVAL;
-       }
-       spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
-
-       /* handle expander phys */
-       if (phy->identify.sas_address != ioc->sas_hba.sas_address)
-               return _transport_expander_phy_control(ioc, phy,
-                   (hard_reset == 1) ? SMP_PHY_CONTROL_HARD_RESET :
-                   SMP_PHY_CONTROL_LINK_RESET);
-
-       /* handle hba phys */
-       memset(&mpi_request, 0, sizeof(Mpi2SasIoUnitControlReply_t));
-       mpi_request.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
-       mpi_request.Operation = hard_reset ?
-           MPI2_SAS_OP_PHY_HARD_RESET : MPI2_SAS_OP_PHY_LINK_RESET;
-       mpi_request.PhyNum = phy->number;
-
-       if ((mpt2sas_base_sas_iounit_control(ioc, &mpi_reply, &mpi_request))) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               return -ENXIO;
-       }
-
-       if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo)
-               printk(MPT2SAS_INFO_FMT "phy(%d), ioc_status"
-                   "(0x%04x), loginfo(0x%08x)\n", ioc->name,
-                   phy->number, le16_to_cpu(mpi_reply.IOCStatus),
-                   le32_to_cpu(mpi_reply.IOCLogInfo));
-
-       return 0;
-}
-
-/**
- * _transport_phy_enable - enable/disable phys
- * @phy: The sas phy object
- * @enable: enable phy when true
- *
- * Only support sas_host direct attached phys.
- * Returns 0 for success, non-zero for failure.
- */
-static int
-_transport_phy_enable(struct sas_phy *phy, int enable)
-{
-       struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy);
-       Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
-       Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL;
-       Mpi2ConfigReply_t mpi_reply;
-       u16 ioc_status;
-       u16 sz;
-       int rc = 0;
-       unsigned long flags;
-       int i, discovery_active;
-
-       spin_lock_irqsave(&ioc->sas_node_lock, flags);
-       if (_transport_sas_node_find_by_sas_address(ioc,
-           phy->identify.sas_address) == NULL) {
-               spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
-               return -EINVAL;
-       }
-       spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
-
-       /* handle expander phys */
-       if (phy->identify.sas_address != ioc->sas_hba.sas_address)
-               return _transport_expander_phy_control(ioc, phy,
-                   (enable == 1) ? SMP_PHY_CONTROL_LINK_RESET :
-                   SMP_PHY_CONTROL_DISABLE);
-
-       /* handle hba phys */
-
-       /* read sas_iounit page 0 */
-       sz = offsetof(Mpi2SasIOUnitPage0_t, PhyData) + (ioc->sas_hba.num_phys *
-           sizeof(Mpi2SasIOUnit0PhyData_t));
-       sas_iounit_pg0 = kzalloc(sz, GFP_KERNEL);
-       if (!sas_iounit_pg0) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               rc = -ENOMEM;
-               goto out;
-       }
-       if ((mpt2sas_config_get_sas_iounit_pg0(ioc, &mpi_reply,
-           sas_iounit_pg0, sz))) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               rc = -ENXIO;
-               goto out;
-       }
-       ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-           MPI2_IOCSTATUS_MASK;
-       if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               rc = -EIO;
-               goto out;
-       }
-
-       /* unable to enable/disable phys when when discovery is active */
-       for (i = 0, discovery_active = 0; i < ioc->sas_hba.num_phys ; i++) {
-               if (sas_iounit_pg0->PhyData[i].PortFlags &
-                   MPI2_SASIOUNIT0_PORTFLAGS_DISCOVERY_IN_PROGRESS) {
-                       printk(MPT2SAS_ERR_FMT "discovery is active on "
-                           "port = %d, phy = %d: unable to enable/disable "
-                           "phys, try again later!\n", ioc->name,
-                           sas_iounit_pg0->PhyData[i].Port, i);
-                       discovery_active = 1;
-               }
-       }
-
-       if (discovery_active) {
-               rc = -EAGAIN;
-               goto out;
-       }
-
-       /* read sas_iounit page 1 */
-       sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys *
-           sizeof(Mpi2SasIOUnit1PhyData_t));
-       sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
-       if (!sas_iounit_pg1) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               rc = -ENOMEM;
-               goto out;
-       }
-       if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply,
-           sas_iounit_pg1, sz))) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               rc = -ENXIO;
-               goto out;
-       }
-       ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-           MPI2_IOCSTATUS_MASK;
-       if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               rc = -EIO;
-               goto out;
-       }
-       /* copy Port/PortFlags/PhyFlags from page 0 */
-       for (i = 0; i < ioc->sas_hba.num_phys ; i++) {
-               sas_iounit_pg1->PhyData[i].Port =
-                   sas_iounit_pg0->PhyData[i].Port;
-               sas_iounit_pg1->PhyData[i].PortFlags =
-                   (sas_iounit_pg0->PhyData[i].PortFlags &
-                   MPI2_SASIOUNIT0_PORTFLAGS_AUTO_PORT_CONFIG);
-               sas_iounit_pg1->PhyData[i].PhyFlags =
-                   (sas_iounit_pg0->PhyData[i].PhyFlags &
-                   (MPI2_SASIOUNIT0_PHYFLAGS_ZONING_ENABLED +
-                   MPI2_SASIOUNIT0_PHYFLAGS_PHY_DISABLED));
-       }
-       if (enable)
-               sas_iounit_pg1->PhyData[phy->number].PhyFlags
-                   &= ~MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE;
-       else
-               sas_iounit_pg1->PhyData[phy->number].PhyFlags
-                   |= MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE;
-
-       mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1, sz);
-
-       /* link reset */
-       if (enable)
-               _transport_phy_reset(phy, 0);
-
- out:
-       kfree(sas_iounit_pg1);
-       kfree(sas_iounit_pg0);
-       return rc;
-}
-
-/**
- * _transport_phy_speed - set phy min/max link rates
- * @phy: The sas phy object
- * @rates: rates defined in sas_phy_linkrates
- *
- * Only support sas_host direct attached phys.
- * Returns 0 for success, non-zero for failure.
- */
-static int
-_transport_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates)
-{
-       struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy);
-       Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
-       Mpi2SasPhyPage0_t phy_pg0;
-       Mpi2ConfigReply_t mpi_reply;
-       u16 ioc_status;
-       u16 sz;
-       int i;
-       int rc = 0;
-       unsigned long flags;
-
-       spin_lock_irqsave(&ioc->sas_node_lock, flags);
-       if (_transport_sas_node_find_by_sas_address(ioc,
-           phy->identify.sas_address) == NULL) {
-               spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
-               return -EINVAL;
-       }
-       spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
-
-       if (!rates->minimum_linkrate)
-               rates->minimum_linkrate = phy->minimum_linkrate;
-       else if (rates->minimum_linkrate < phy->minimum_linkrate_hw)
-               rates->minimum_linkrate = phy->minimum_linkrate_hw;
-
-       if (!rates->maximum_linkrate)
-               rates->maximum_linkrate = phy->maximum_linkrate;
-       else if (rates->maximum_linkrate > phy->maximum_linkrate_hw)
-               rates->maximum_linkrate = phy->maximum_linkrate_hw;
-
-       /* handle expander phys */
-       if (phy->identify.sas_address != ioc->sas_hba.sas_address) {
-               phy->minimum_linkrate = rates->minimum_linkrate;
-               phy->maximum_linkrate = rates->maximum_linkrate;
-               return _transport_expander_phy_control(ioc, phy,
-                   SMP_PHY_CONTROL_LINK_RESET);
-       }
-
-       /* handle hba phys */
-
-       /* sas_iounit page 1 */
-       sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys *
-           sizeof(Mpi2SasIOUnit1PhyData_t));
-       sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
-       if (!sas_iounit_pg1) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               rc = -ENOMEM;
-               goto out;
-       }
-       if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply,
-           sas_iounit_pg1, sz))) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               rc = -ENXIO;
-               goto out;
-       }
-       ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-           MPI2_IOCSTATUS_MASK;
-       if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               rc = -EIO;
-               goto out;
-       }
-
-       for (i = 0; i < ioc->sas_hba.num_phys; i++) {
-               if (phy->number != i) {
-                       sas_iounit_pg1->PhyData[i].MaxMinLinkRate =
-                           (ioc->sas_hba.phy[i].phy->minimum_linkrate +
-                           (ioc->sas_hba.phy[i].phy->maximum_linkrate << 4));
-               } else {
-                       sas_iounit_pg1->PhyData[i].MaxMinLinkRate =
-                           (rates->minimum_linkrate +
-                           (rates->maximum_linkrate << 4));
-               }
-       }
-
-       if (mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1,
-           sz)) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               rc = -ENXIO;
-               goto out;
-       }
-
-       /* link reset */
-       _transport_phy_reset(phy, 0);
-
-       /* read phy page 0, then update the rates in the sas transport phy */
-       if (!mpt2sas_config_get_phy_pg0(ioc, &mpi_reply, &phy_pg0,
-           phy->number)) {
-               phy->minimum_linkrate = _transport_convert_phy_link_rate(
-                   phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK);
-               phy->maximum_linkrate = _transport_convert_phy_link_rate(
-                   phy_pg0.ProgrammedLinkRate >> 4);
-               phy->negotiated_linkrate = _transport_convert_phy_link_rate(
-                   phy_pg0.NegotiatedLinkRate &
-                   MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL);
-       }
-
- out:
-       kfree(sas_iounit_pg1);
-       return rc;
-}
-
-
-/**
- * _transport_smp_handler - transport portal for smp passthru
- * @shost: shost object
- * @rphy: sas transport rphy object
- * @req:
- *
- * This used primarily for smp_utils.
- * Example:
- *           smp_rep_general /sys/class/bsg/expander-5:0
- */
-static int
-_transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
-    struct request *req)
-{
-       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-       Mpi2SmpPassthroughRequest_t *mpi_request;
-       Mpi2SmpPassthroughReply_t *mpi_reply;
-       int rc;
-       u16 smid;
-       u32 ioc_state;
-       unsigned long timeleft;
-       void *psge;
-       u32 sgl_flags;
-       u8 issue_reset = 0;
-       dma_addr_t dma_addr_in = 0;
-       dma_addr_t dma_addr_out = 0;
-       dma_addr_t pci_dma_in = 0;
-       dma_addr_t pci_dma_out = 0;
-       void *pci_addr_in = NULL;
-       void *pci_addr_out = NULL;
-       u16 wait_state_count;
-       struct request *rsp = req->next_rq;
-       struct bio_vec bvec;
-       struct bvec_iter iter;
-
-       if (!rsp) {
-               printk(MPT2SAS_ERR_FMT "%s: the smp response space is "
-                   "missing\n", ioc->name, __func__);
-               return -EINVAL;
-       }
-       if (ioc->shost_recovery || ioc->pci_error_recovery) {
-               printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
-                   __func__, ioc->name);
-               return -EFAULT;
-       }
-
-       rc = mutex_lock_interruptible(&ioc->transport_cmds.mutex);
-       if (rc)
-               return rc;
-
-       if (ioc->transport_cmds.status != MPT2_CMD_NOT_USED) {
-               printk(MPT2SAS_ERR_FMT "%s: transport_cmds in use\n", ioc->name,
-                   __func__);
-               rc = -EAGAIN;
-               goto out;
-       }
-       ioc->transport_cmds.status = MPT2_CMD_PENDING;
-
-       /* Check if the request is split across multiple segments */
-       if (bio_multiple_segments(req->bio)) {
-               u32 offset = 0;
-
-               /* Allocate memory and copy the request */
-               pci_addr_out = pci_alloc_consistent(ioc->pdev,
-                   blk_rq_bytes(req), &pci_dma_out);
-               if (!pci_addr_out) {
-                       printk(MPT2SAS_INFO_FMT "%s(): PCI Addr out = NULL\n",
-                           ioc->name, __func__);
-                       rc = -ENOMEM;
-                       goto out;
-               }
-
-               bio_for_each_segment(bvec, req->bio, iter) {
-                       memcpy(pci_addr_out + offset,
-                           page_address(bvec.bv_page) + bvec.bv_offset,
-                           bvec.bv_len);
-                       offset += bvec.bv_len;
-               }
-       } else {
-               dma_addr_out = pci_map_single(ioc->pdev, bio_data(req->bio),
-                   blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL);
-               if (!dma_addr_out) {
-                       printk(MPT2SAS_INFO_FMT "%s(): DMA Addr out = NULL\n",
-                           ioc->name, __func__);
-                       rc = -ENOMEM;
-                       goto free_pci;
-               }
-       }
-
-       /* Check if the response needs to be populated across
-        * multiple segments */
-       if (bio_multiple_segments(rsp->bio)) {
-               pci_addr_in = pci_alloc_consistent(ioc->pdev, blk_rq_bytes(rsp),
-                   &pci_dma_in);
-               if (!pci_addr_in) {
-                       printk(MPT2SAS_INFO_FMT "%s(): PCI Addr in = NULL\n",
-                           ioc->name, __func__);
-                       rc = -ENOMEM;
-                       goto unmap;
-               }
-       } else {
-               dma_addr_in =  pci_map_single(ioc->pdev, bio_data(rsp->bio),
-                   blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL);
-               if (!dma_addr_in) {
-                       printk(MPT2SAS_INFO_FMT "%s(): DMA Addr in = NULL\n",
-                           ioc->name, __func__);
-                       rc = -ENOMEM;
-                       goto unmap;
-               }
-       }
-
-       wait_state_count = 0;
-       ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
-       while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
-               if (wait_state_count++ == 10) {
-                       printk(MPT2SAS_ERR_FMT
-                           "%s: failed due to ioc not operational\n",
-                           ioc->name, __func__);
-                       rc = -EFAULT;
-                       goto unmap;
-               }
-               ssleep(1);
-               ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
-               printk(MPT2SAS_INFO_FMT "%s: waiting for "
-                   "operational state(count=%d)\n", ioc->name,
-                   __func__, wait_state_count);
-       }
-       if (wait_state_count)
-               printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n",
-                   ioc->name, __func__);
-
-       smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx);
-       if (!smid) {
-               printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
-                   ioc->name, __func__);
-               rc = -EAGAIN;
-               goto unmap;
-       }
-
-       rc = 0;
-       mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
-       ioc->transport_cmds.smid = smid;
-
-       memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
-       mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
-       mpi_request->PhysicalPort = 0xFF;
-       mpi_request->VF_ID = 0; /* TODO */
-       mpi_request->VP_ID = 0;
-       mpi_request->SASAddress = (rphy) ?
-           cpu_to_le64(rphy->identify.sas_address) :
-           cpu_to_le64(ioc->sas_hba.sas_address);
-       mpi_request->RequestDataLength = cpu_to_le16(blk_rq_bytes(req) - 4);
-       psge = &mpi_request->SGL;
-
-       /* WRITE sgel first */
-       sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
-           MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC);
-       sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
-       if (bio_multiple_segments(req->bio)) {
-               ioc->base_add_sg_single(psge, sgl_flags |
-                   (blk_rq_bytes(req) - 4), pci_dma_out);
-       } else {
-               ioc->base_add_sg_single(psge, sgl_flags |
-                   (blk_rq_bytes(req) - 4), dma_addr_out);
-       }
-
-       /* incr sgel */
-       psge += ioc->sge_size;
-
-       /* READ sgel last */
-       sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
-           MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER |
-           MPI2_SGE_FLAGS_END_OF_LIST);
-       sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
-       if (bio_multiple_segments(rsp->bio)) {
-               ioc->base_add_sg_single(psge, sgl_flags |
-                   (blk_rq_bytes(rsp) + 4), pci_dma_in);
-       } else {
-               ioc->base_add_sg_single(psge, sgl_flags |
-                   (blk_rq_bytes(rsp) + 4), dma_addr_in);
-       }
-
-       dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "%s - "
-           "sending smp request\n", ioc->name, __func__));
-
-       init_completion(&ioc->transport_cmds.done);
-       mpt2sas_base_put_smid_default(ioc, smid);
-       timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done,
-           10*HZ);
-
-       if (!(ioc->transport_cmds.status & MPT2_CMD_COMPLETE)) {
-               printk(MPT2SAS_ERR_FMT "%s : timeout\n",
-                   __func__, ioc->name);
-               _debug_dump_mf(mpi_request,
-                   sizeof(Mpi2SmpPassthroughRequest_t)/4);
-               if (!(ioc->transport_cmds.status & MPT2_CMD_RESET))
-                       issue_reset = 1;
-               goto issue_host_reset;
-       }
-
-       dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "%s - "
-           "complete\n", ioc->name, __func__));
-
-       if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) {
-
-               mpi_reply = ioc->transport_cmds.reply;
-
-               dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
-                   "%s - reply data transfer size(%d)\n",
-                   ioc->name, __func__,
-                   le16_to_cpu(mpi_reply->ResponseDataLength)));
-
-               memcpy(req->sense, mpi_reply, sizeof(*mpi_reply));
-               req->sense_len = sizeof(*mpi_reply);
-               req->resid_len = 0;
-               rsp->resid_len -=
-                   le16_to_cpu(mpi_reply->ResponseDataLength);
-               /* check if the resp needs to be copied from the allocated
-                * pci mem */
-               if (bio_multiple_segments(rsp->bio)) {
-                       u32 offset = 0;
-                       u32 bytes_to_copy =
-                           le16_to_cpu(mpi_reply->ResponseDataLength);
-                       bio_for_each_segment(bvec, rsp->bio, iter) {
-                               if (bytes_to_copy <= bvec.bv_len) {
-                                       memcpy(page_address(bvec.bv_page) +
-                                           bvec.bv_offset, pci_addr_in +
-                                           offset, bytes_to_copy);
-                                       break;
-                               } else {
-                                       memcpy(page_address(bvec.bv_page) +
-                                           bvec.bv_offset, pci_addr_in +
-                                           offset, bvec.bv_len);
-                                       bytes_to_copy -= bvec.bv_len;
-                               }
-                               offset += bvec.bv_len;
-                       }
-               }
-       } else {
-               dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
-                   "%s - no reply\n", ioc->name, __func__));
-               rc = -ENXIO;
-       }
-
- issue_host_reset:
-       if (issue_reset) {
-               mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
-                   FORCE_BIG_HAMMER);
-               rc = -ETIMEDOUT;
-       }
-
- unmap:
-       if (dma_addr_out)
-               pci_unmap_single(ioc->pdev, dma_addr_out, blk_rq_bytes(req),
-                   PCI_DMA_BIDIRECTIONAL);
-       if (dma_addr_in)
-               pci_unmap_single(ioc->pdev, dma_addr_in, blk_rq_bytes(rsp),
-                   PCI_DMA_BIDIRECTIONAL);
-
- free_pci:
-       if (pci_addr_out)
-               pci_free_consistent(ioc->pdev, blk_rq_bytes(req), pci_addr_out,
-                   pci_dma_out);
-
-       if (pci_addr_in)
-               pci_free_consistent(ioc->pdev, blk_rq_bytes(rsp), pci_addr_in,
-                   pci_dma_in);
-
- out:
-       ioc->transport_cmds.status = MPT2_CMD_NOT_USED;
-       mutex_unlock(&ioc->transport_cmds.mutex);
-       return rc;
-}
-
-struct sas_function_template mpt2sas_transport_functions = {
-       .get_linkerrors         = _transport_get_linkerrors,
-       .get_enclosure_identifier = _transport_get_enclosure_identifier,
-       .get_bay_identifier     = _transport_get_bay_identifier,
-       .phy_reset              = _transport_phy_reset,
-       .phy_enable             = _transport_phy_enable,
-       .set_phy_speed          = _transport_phy_speed,
-       .smp_handler            = _transport_smp_handler,
-};
-
-struct scsi_transport_template *mpt2sas_transport_template;
index 4d235dd741bf97499d74a38820f4c85fa2031358..29061467cc174e118848dd44244ff28bb198deb3 100644 (file)
 # USA.
 
 config SCSI_MPT3SAS
-       tristate "LSI MPT Fusion SAS 3.0 Device Driver"
+       tristate "LSI MPT Fusion SAS 3.0 & SAS 2.0 Device Driver"
        depends on PCI && SCSI
        select SCSI_SAS_ATTRS
        select RAID_ATTRS
        ---help---
        This driver supports PCI-Express SAS 12Gb/s Host Adapters.
 
-config SCSI_MPT3SAS_MAX_SGE
-       int "LSI MPT Fusion Max number of SG Entries (16 - 256)"
+config SCSI_MPT2SAS_MAX_SGE
+       int "LSI MPT Fusion SAS 2.0 Max number of SG Entries (16 - 256)"
        depends on PCI && SCSI && SCSI_MPT3SAS
        default "128"
        range 16 256
@@ -60,8 +60,14 @@ config SCSI_MPT3SAS_MAX_SGE
        can be 256. However, it may decreased down to 16.  Decreasing this
        parameter will reduce memory requirements on a per controller instance.
 
-config SCSI_MPT3SAS_LOGGING
-       bool "LSI MPT Fusion logging facility"
+config SCSI_MPT3SAS_MAX_SGE
+       int "LSI MPT Fusion SAS 3.0 Max number of SG Entries (16 - 256)"
        depends on PCI && SCSI && SCSI_MPT3SAS
+       default "128"
+       range 16 256
        ---help---
-       This turns on a logging facility.
+       This option allows you to specify the maximum number of scatter-
+       gather entries per I/O. The driver default is 128, which matches
+       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.
index efb0c4c2e31000fd6f8e96777570c0d1086d1dae..b7643f596c1e67ab67e0a954ab2250577de637d8 100644 (file)
@@ -5,4 +5,5 @@ mpt3sas-y +=  mpt3sas_base.o     \
                mpt3sas_scsih.o      \
                mpt3sas_transport.o     \
                mpt3sas_ctl.o   \
-               mpt3sas_trigger_diag.o
+               mpt3sas_trigger_diag.o \
+               mpt3sas_warpdrive.o
index d4f1dcdb8361937c8b0cb75491ec45e1b4981188..11393ebf1a68ef8f14a38d58f1321d7783a84d72 100644 (file)
@@ -108,9 +108,12 @@ _scsih_set_fwfault_debug(const char *val, struct kernel_param *kp)
        if (ret)
                return ret;
 
+       /* global ioc spinlock to protect controller list on list operations */
        pr_info("setting fwfault_debug(%d)\n", mpt3sas_fwfault_debug);
+       spin_lock(&gioc_lock);
        list_for_each_entry(ioc, &mpt3sas_ioc_list, list)
                ioc->fwfault_debug = mpt3sas_fwfault_debug;
+       spin_unlock(&gioc_lock);
        return 0;
 }
 module_param_call(mpt3sas_fwfault_debug, _scsih_set_fwfault_debug,
@@ -157,7 +160,7 @@ _base_fault_reset_work(struct work_struct *work)
 
 
        spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
-       if (ioc->shost_recovery)
+       if (ioc->shost_recovery || ioc->pci_error_recovery)
                goto rearm_timer;
        spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
 
@@ -166,6 +169,20 @@ _base_fault_reset_work(struct work_struct *work)
                pr_err(MPT3SAS_FMT "SAS host is non-operational !!!!\n",
                    ioc->name);
 
+               /* It may be possible that EEH recovery can resolve some of
+                * pci bus failure issues rather removing the dead ioc function
+                * by considering controller is in a non-operational state. So
+                * here priority is given to the EEH recovery. If it doesn't
+                * not resolve this issue, mpt3sas driver will consider this
+                * controller to non-operational state and remove the dead ioc
+                * function.
+                */
+               if (ioc->non_operational_loop++ < 5) {
+                       spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock,
+                                                        flags);
+                       goto rearm_timer;
+               }
+
                /*
                 * Call _scsih_flush_pending_cmds callback so that we flush all
                 * pending commands back to OS. This call is required to aovid
@@ -181,7 +198,7 @@ _base_fault_reset_work(struct work_struct *work)
                ioc->remove_host = 1;
                /*Remove the Dead Host */
                p = kthread_run(mpt3sas_remove_dead_ioc_func, ioc,
-                   "mpt3sas_dead_ioc_%d", ioc->id);
+                   "%s_dead_ioc_%d", ioc->driver_name, ioc->id);
                if (IS_ERR(p))
                        pr_err(MPT3SAS_FMT
                        "%s: Running mpt3sas_dead_ioc thread failed !!!!\n",
@@ -193,6 +210,8 @@ _base_fault_reset_work(struct work_struct *work)
                return; /* don't rearm timer */
        }
 
+       ioc->non_operational_loop = 0;
+
        if ((doorbell & MPI2_IOC_STATE_MASK) != MPI2_IOC_STATE_OPERATIONAL) {
                rc = mpt3sas_base_hard_reset_handler(ioc, CAN_SLEEP,
                    FORCE_BIG_HAMMER);
@@ -235,7 +254,8 @@ mpt3sas_base_start_watchdog(struct MPT3SAS_ADAPTER *ioc)
 
        INIT_DELAYED_WORK(&ioc->fault_reset_work, _base_fault_reset_work);
        snprintf(ioc->fault_reset_work_q_name,
-           sizeof(ioc->fault_reset_work_q_name), "poll_%d_status", ioc->id);
+           sizeof(ioc->fault_reset_work_q_name), "poll_%s%d_status",
+           ioc->driver_name, ioc->id);
        ioc->fault_reset_work_q =
                create_singlethread_workqueue(ioc->fault_reset_work_q_name);
        if (!ioc->fault_reset_work_q) {
@@ -324,7 +344,6 @@ mpt3sas_halt_firmware(struct MPT3SAS_ADAPTER *ioc)
                panic("panic in %s\n", __func__);
 }
 
-#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
 /**
  * _base_sas_ioc_info - verbose translation of the ioc status
  * @ioc: per adapter object
@@ -578,7 +597,8 @@ _base_display_event_data(struct MPT3SAS_ADAPTER *ioc,
                desc = "Device Status Change";
                break;
        case MPI2_EVENT_IR_OPERATION_STATUS:
-               desc = "IR Operation Status";
+               if (!ioc->hide_ir_msg)
+                       desc = "IR Operation Status";
                break;
        case MPI2_EVENT_SAS_DISCOVERY:
        {
@@ -609,16 +629,20 @@ _base_display_event_data(struct MPT3SAS_ADAPTER *ioc,
                desc = "SAS Enclosure Device Status Change";
                break;
        case MPI2_EVENT_IR_VOLUME:
-               desc = "IR Volume";
+               if (!ioc->hide_ir_msg)
+                       desc = "IR Volume";
                break;
        case MPI2_EVENT_IR_PHYSICAL_DISK:
-               desc = "IR Physical Disk";
+               if (!ioc->hide_ir_msg)
+                       desc = "IR Physical Disk";
                break;
        case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
-               desc = "IR Configuration Change List";
+               if (!ioc->hide_ir_msg)
+                       desc = "IR Configuration Change List";
                break;
        case MPI2_EVENT_LOG_ENTRY_ADDED:
-               desc = "Log Entry Added";
+               if (!ioc->hide_ir_msg)
+                       desc = "Log Entry Added";
                break;
        case MPI2_EVENT_TEMP_THRESHOLD:
                desc = "Temperature Threshold";
@@ -630,7 +654,6 @@ _base_display_event_data(struct MPT3SAS_ADAPTER *ioc,
 
        pr_info(MPT3SAS_FMT "%s\n", ioc->name, desc);
 }
-#endif
 
 /**
  * _base_sas_log_info - verbose translation of firmware log info
@@ -675,7 +698,10 @@ _base_sas_log_info(struct MPT3SAS_ADAPTER *ioc , u32 log_info)
                originator_str = "PL";
                break;
        case 2:
-               originator_str = "IR";
+               if (!ioc->hide_ir_msg)
+                       originator_str = "IR";
+               else
+                       originator_str = "WarpDrive";
                break;
        }
 
@@ -710,13 +736,13 @@ _base_display_reply_info(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
                return;
        }
        ioc_status = le16_to_cpu(mpi_reply->IOCStatus);
-#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
+
        if ((ioc_status & MPI2_IOCSTATUS_MASK) &&
            (ioc->logging_level & MPT_DEBUG_REPLY)) {
                _base_sas_ioc_info(ioc , mpi_reply,
                   mpt3sas_base_get_msg_frame(ioc, smid));
        }
-#endif
+
        if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
                loginfo = le32_to_cpu(mpi_reply->IOCLogInfo);
                _base_sas_log_info(ioc, loginfo);
@@ -783,9 +809,9 @@ _base_async_event(struct MPT3SAS_ADAPTER *ioc, u8 msix_index, u32 reply)
                return 1;
        if (mpi_reply->Function != MPI2_FUNCTION_EVENT_NOTIFICATION)
                return 1;
-#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
+
        _base_display_event_data(ioc, mpi_reply);
-#endif
+
        if (!(mpi_reply->AckRequired & MPI2_EVENT_NOTIFICATION_ACK_REQUIRED))
                goto out;
        smid = mpt3sas_base_get_smid(ioc, ioc->base_cb_idx);
@@ -1009,6 +1035,12 @@ _base_interrupt(int irq, void *bus_id)
        }
 
        wmb();
+       if (ioc->is_warpdrive) {
+               writel(reply_q->reply_post_host_index,
+               ioc->reply_post_host_index[msix_index]);
+               atomic_dec(&reply_q->busy);
+               return IRQ_HANDLED;
+       }
 
        /* Update Reply Post Host Index.
         * For those HBA's which support combined reply queue feature
@@ -1319,6 +1351,149 @@ _base_build_zero_len_sge_ieee(struct MPT3SAS_ADAPTER *ioc, void *paddr)
        _base_add_sg_single_ieee(paddr, sgl_flags, 0, 0, -1);
 }
 
+/**
+ * _base_build_sg_scmd - main sg creation routine
+ * @ioc: per adapter object
+ * @scmd: scsi command
+ * @smid: system request message index
+ * Context: none.
+ *
+ * The main routine that builds scatter gather table from a given
+ * scsi request sent via the .queuecommand main handler.
+ *
+ * Returns 0 success, anything else error
+ */
+static int
+_base_build_sg_scmd(struct MPT3SAS_ADAPTER *ioc,
+               struct scsi_cmnd *scmd, u16 smid)
+{
+       Mpi2SCSIIORequest_t *mpi_request;
+       dma_addr_t chain_dma;
+       struct scatterlist *sg_scmd;
+       void *sg_local, *chain;
+       u32 chain_offset;
+       u32 chain_length;
+       u32 chain_flags;
+       int sges_left;
+       u32 sges_in_segment;
+       u32 sgl_flags;
+       u32 sgl_flags_last_element;
+       u32 sgl_flags_end_buffer;
+       struct chain_tracker *chain_req;
+
+       mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
+
+       /* init scatter gather flags */
+       sgl_flags = MPI2_SGE_FLAGS_SIMPLE_ELEMENT;
+       if (scmd->sc_data_direction == DMA_TO_DEVICE)
+               sgl_flags |= MPI2_SGE_FLAGS_HOST_TO_IOC;
+       sgl_flags_last_element = (sgl_flags | MPI2_SGE_FLAGS_LAST_ELEMENT)
+           << MPI2_SGE_FLAGS_SHIFT;
+       sgl_flags_end_buffer = (sgl_flags | MPI2_SGE_FLAGS_LAST_ELEMENT |
+           MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_END_OF_LIST)
+           << MPI2_SGE_FLAGS_SHIFT;
+       sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
+
+       sg_scmd = scsi_sglist(scmd);
+       sges_left = scsi_dma_map(scmd);
+       if (sges_left < 0) {
+               sdev_printk(KERN_ERR, scmd->device,
+                "pci_map_sg failed: request for %d bytes!\n",
+                scsi_bufflen(scmd));
+               return -ENOMEM;
+       }
+
+       sg_local = &mpi_request->SGL;
+       sges_in_segment = ioc->max_sges_in_main_message;
+       if (sges_left <= sges_in_segment)
+               goto fill_in_last_segment;
+
+       mpi_request->ChainOffset = (offsetof(Mpi2SCSIIORequest_t, SGL) +
+           (sges_in_segment * ioc->sge_size))/4;
+
+       /* fill in main message segment when there is a chain following */
+       while (sges_in_segment) {
+               if (sges_in_segment == 1)
+                       ioc->base_add_sg_single(sg_local,
+                           sgl_flags_last_element | sg_dma_len(sg_scmd),
+                           sg_dma_address(sg_scmd));
+               else
+                       ioc->base_add_sg_single(sg_local, sgl_flags |
+                           sg_dma_len(sg_scmd), sg_dma_address(sg_scmd));
+               sg_scmd = sg_next(sg_scmd);
+               sg_local += ioc->sge_size;
+               sges_left--;
+               sges_in_segment--;
+       }
+
+       /* initializing the chain flags and pointers */
+       chain_flags = MPI2_SGE_FLAGS_CHAIN_ELEMENT << MPI2_SGE_FLAGS_SHIFT;
+       chain_req = _base_get_chain_buffer_tracker(ioc, smid);
+       if (!chain_req)
+               return -1;
+       chain = chain_req->chain_buffer;
+       chain_dma = chain_req->chain_buffer_dma;
+       do {
+               sges_in_segment = (sges_left <=
+                   ioc->max_sges_in_chain_message) ? sges_left :
+                   ioc->max_sges_in_chain_message;
+               chain_offset = (sges_left == sges_in_segment) ?
+                   0 : (sges_in_segment * ioc->sge_size)/4;
+               chain_length = sges_in_segment * ioc->sge_size;
+               if (chain_offset) {
+                       chain_offset = chain_offset <<
+                           MPI2_SGE_CHAIN_OFFSET_SHIFT;
+                       chain_length += ioc->sge_size;
+               }
+               ioc->base_add_sg_single(sg_local, chain_flags | chain_offset |
+                   chain_length, chain_dma);
+               sg_local = chain;
+               if (!chain_offset)
+                       goto fill_in_last_segment;
+
+               /* fill in chain segments */
+               while (sges_in_segment) {
+                       if (sges_in_segment == 1)
+                               ioc->base_add_sg_single(sg_local,
+                                   sgl_flags_last_element |
+                                   sg_dma_len(sg_scmd),
+                                   sg_dma_address(sg_scmd));
+                       else
+                               ioc->base_add_sg_single(sg_local, sgl_flags |
+                                   sg_dma_len(sg_scmd),
+                                   sg_dma_address(sg_scmd));
+                       sg_scmd = sg_next(sg_scmd);
+                       sg_local += ioc->sge_size;
+                       sges_left--;
+                       sges_in_segment--;
+               }
+
+               chain_req = _base_get_chain_buffer_tracker(ioc, smid);
+               if (!chain_req)
+                       return -1;
+               chain = chain_req->chain_buffer;
+               chain_dma = chain_req->chain_buffer_dma;
+       } while (1);
+
+
+ fill_in_last_segment:
+
+       /* fill the last segment */
+       while (sges_left) {
+               if (sges_left == 1)
+                       ioc->base_add_sg_single(sg_local, sgl_flags_end_buffer |
+                           sg_dma_len(sg_scmd), sg_dma_address(sg_scmd));
+               else
+                       ioc->base_add_sg_single(sg_local, sgl_flags |
+                           sg_dma_len(sg_scmd), sg_dma_address(sg_scmd));
+               sg_scmd = sg_next(sg_scmd);
+               sg_local += ioc->sge_size;
+               sges_left--;
+       }
+
+       return 0;
+}
+
 /**
  * _base_build_sg_scmd_ieee - main sg creation routine for IEEE format
  * @ioc: per adapter object
@@ -1571,6 +1746,14 @@ _base_check_enable_msix(struct MPT3SAS_ADAPTER *ioc)
        int base;
        u16 message_control;
 
+       /* Check whether controller SAS2008 B0 controller,
+        * if it is SAS2008 B0 controller use IO-APIC instead of MSIX
+        */
+       if (ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2008 &&
+           ioc->pdev->revision == SAS2_PCI_DEVICE_B0_REVISION) {
+               return -EINVAL;
+       }
+
        base = pci_find_capability(ioc->pdev, PCI_CAP_ID_MSIX);
        if (!base) {
                dfailprintk(ioc, pr_info(MPT3SAS_FMT "msix not supported\n",
@@ -1579,9 +1762,19 @@ _base_check_enable_msix(struct MPT3SAS_ADAPTER *ioc)
        }
 
        /* get msix vector count */
-
-       pci_read_config_word(ioc->pdev, base + 2, &message_control);
-       ioc->msix_vector_count = (message_control & 0x3FF) + 1;
+       /* NUMA_IO not supported for older controllers */
+       if (ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2004 ||
+           ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2008 ||
+           ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2108_1 ||
+           ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2108_2 ||
+           ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2108_3 ||
+           ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2116_1 ||
+           ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2116_2)
+               ioc->msix_vector_count = 1;
+       else {
+               pci_read_config_word(ioc->pdev, base + 2, &message_control);
+               ioc->msix_vector_count = (message_control & 0x3FF) + 1;
+       }
        dinitprintk(ioc, pr_info(MPT3SAS_FMT
                "msix is supported, vector_count(%d)\n",
                ioc->name, ioc->msix_vector_count));
@@ -1643,10 +1836,10 @@ _base_request_irq(struct MPT3SAS_ADAPTER *ioc, u8 index, u32 vector)
        atomic_set(&reply_q->busy, 0);
        if (ioc->msix_enable)
                snprintf(reply_q->name, MPT_NAME_LENGTH, "%s%d-msix%d",
-                   MPT3SAS_DRIVER_NAME, ioc->id, index);
+                   ioc->driver_name, ioc->id, index);
        else
                snprintf(reply_q->name, MPT_NAME_LENGTH, "%s%d",
-                   MPT3SAS_DRIVER_NAME, ioc->id);
+                   ioc->driver_name, ioc->id);
        r = request_irq(vector, _base_interrupt, IRQF_SHARED, reply_q->name,
            reply_q);
        if (r) {
@@ -1872,7 +2065,7 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc)
 
 
        if (pci_request_selected_regions(pdev, ioc->bars,
-           MPT3SAS_DRIVER_NAME)) {
+           ioc->driver_name)) {
                pr_warn(MPT3SAS_FMT "pci_request_selected_regions: failed\n",
                        ioc->name);
                ioc->bars = 0;
@@ -2158,6 +2351,7 @@ mpt3sas_base_free_smid(struct MPT3SAS_ADAPTER *ioc, u16 smid)
                }
                ioc->scsi_lookup[i].cb_idx = 0xFF;
                ioc->scsi_lookup[i].scmd = NULL;
+               ioc->scsi_lookup[i].direct_io = 0;
                list_add(&ioc->scsi_lookup[i].tracker_list, &ioc->free_list);
                spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
 
@@ -2318,143 +2512,261 @@ mpt3sas_base_put_smid_default(struct MPT3SAS_ADAPTER *ioc, u16 smid)
 }
 
 /**
- * _base_display_intel_branding - Display branding string
+ * _base_display_OEMs_branding - Display branding string
  * @ioc: per adapter object
  *
  * Return nothing.
  */
 static void
-_base_display_intel_branding(struct MPT3SAS_ADAPTER *ioc)
+_base_display_OEMs_branding(struct MPT3SAS_ADAPTER *ioc)
 {
        if (ioc->pdev->subsystem_vendor != PCI_VENDOR_ID_INTEL)
                return;
 
-       switch (ioc->pdev->device) {
-       case MPI25_MFGPAGE_DEVID_SAS3008:
-               switch (ioc->pdev->subsystem_device) {
-               case MPT3SAS_INTEL_RMS3JC080_SSDID:
-                       pr_info(MPT3SAS_FMT "%s\n", ioc->name,
-                               MPT3SAS_INTEL_RMS3JC080_BRANDING);
-                       break;
-
-               case MPT3SAS_INTEL_RS3GC008_SSDID:
-                       pr_info(MPT3SAS_FMT "%s\n", ioc->name,
-                               MPT3SAS_INTEL_RS3GC008_BRANDING);
-                       break;
-               case MPT3SAS_INTEL_RS3FC044_SSDID:
-                       pr_info(MPT3SAS_FMT "%s\n", ioc->name,
-                               MPT3SAS_INTEL_RS3FC044_BRANDING);
-                       break;
-               case MPT3SAS_INTEL_RS3UC080_SSDID:
-                       pr_info(MPT3SAS_FMT "%s\n", ioc->name,
-                               MPT3SAS_INTEL_RS3UC080_BRANDING);
+       switch (ioc->pdev->subsystem_vendor) {
+       case PCI_VENDOR_ID_INTEL:
+               switch (ioc->pdev->device) {
+               case MPI2_MFGPAGE_DEVID_SAS2008:
+                       switch (ioc->pdev->subsystem_device) {
+                       case MPT2SAS_INTEL_RMS2LL080_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+                                   MPT2SAS_INTEL_RMS2LL080_BRANDING);
+                               break;
+                       case MPT2SAS_INTEL_RMS2LL040_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+                                   MPT2SAS_INTEL_RMS2LL040_BRANDING);
+                               break;
+                       case MPT2SAS_INTEL_SSD910_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+                                   MPT2SAS_INTEL_SSD910_BRANDING);
+                               break;
+                       default:
+                               pr_info(MPT3SAS_FMT
+                                "Intel(R) Controller: Subsystem ID: 0x%X\n",
+                                ioc->name, ioc->pdev->subsystem_device);
+                               break;
+                       }
+               case MPI2_MFGPAGE_DEVID_SAS2308_2:
+                       switch (ioc->pdev->subsystem_device) {
+                       case MPT2SAS_INTEL_RS25GB008_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+                                   MPT2SAS_INTEL_RS25GB008_BRANDING);
+                               break;
+                       case MPT2SAS_INTEL_RMS25JB080_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+                                   MPT2SAS_INTEL_RMS25JB080_BRANDING);
+                               break;
+                       case MPT2SAS_INTEL_RMS25JB040_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+                                   MPT2SAS_INTEL_RMS25JB040_BRANDING);
+                               break;
+                       case MPT2SAS_INTEL_RMS25KB080_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+                                   MPT2SAS_INTEL_RMS25KB080_BRANDING);
+                               break;
+                       case MPT2SAS_INTEL_RMS25KB040_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+                                   MPT2SAS_INTEL_RMS25KB040_BRANDING);
+                               break;
+                       case MPT2SAS_INTEL_RMS25LB040_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+                                   MPT2SAS_INTEL_RMS25LB040_BRANDING);
+                               break;
+                       case MPT2SAS_INTEL_RMS25LB080_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+                                   MPT2SAS_INTEL_RMS25LB080_BRANDING);
+                               break;
+                       default:
+                               pr_info(MPT3SAS_FMT
+                                "Intel(R) Controller: Subsystem ID: 0x%X\n",
+                                ioc->name, ioc->pdev->subsystem_device);
+                               break;
+                       }
+               case MPI25_MFGPAGE_DEVID_SAS3008:
+                       switch (ioc->pdev->subsystem_device) {
+                       case MPT3SAS_INTEL_RMS3JC080_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+                                       MPT3SAS_INTEL_RMS3JC080_BRANDING);
+                               break;
+
+                       case MPT3SAS_INTEL_RS3GC008_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+                                       MPT3SAS_INTEL_RS3GC008_BRANDING);
+                               break;
+                       case MPT3SAS_INTEL_RS3FC044_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+                                       MPT3SAS_INTEL_RS3FC044_BRANDING);
+                               break;
+                       case MPT3SAS_INTEL_RS3UC080_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+                                       MPT3SAS_INTEL_RS3UC080_BRANDING);
+                               break;
+                       default:
+                               pr_info(MPT3SAS_FMT
+                                "Intel(R) Controller: Subsystem ID: 0x%X\n",
+                                ioc->name, ioc->pdev->subsystem_device);
+                               break;
+                       }
                        break;
                default:
                        pr_info(MPT3SAS_FMT
-                               "Intel(R) Controller: Subsystem ID: 0x%X\n",
-                               ioc->name, ioc->pdev->subsystem_device);
+                        "Intel(R) Controller: Subsystem ID: 0x%X\n",
+                        ioc->name, ioc->pdev->subsystem_device);
                        break;
                }
                break;
-       default:
-               pr_info(MPT3SAS_FMT
-                       "Intel(R) Controller: Subsystem ID: 0x%X\n",
-                       ioc->name, ioc->pdev->subsystem_device);
-               break;
-       }
-}
-
-
-
-/**
- * _base_display_dell_branding - Display branding string
- * @ioc: per adapter object
- *
- * Return nothing.
- */
-static void
-_base_display_dell_branding(struct MPT3SAS_ADAPTER *ioc)
-{
-       if (ioc->pdev->subsystem_vendor != PCI_VENDOR_ID_DELL)
-               return;
-
-       switch (ioc->pdev->device) {
-       case MPI25_MFGPAGE_DEVID_SAS3008:
-               switch (ioc->pdev->subsystem_device) {
-               case MPT3SAS_DELL_12G_HBA_SSDID:
-                       pr_info(MPT3SAS_FMT "%s\n", ioc->name,
-                               MPT3SAS_DELL_12G_HBA_BRANDING);
+       case PCI_VENDOR_ID_DELL:
+               switch (ioc->pdev->device) {
+               case MPI2_MFGPAGE_DEVID_SAS2008:
+                       switch (ioc->pdev->subsystem_device) {
+                       case MPT2SAS_DELL_6GBPS_SAS_HBA_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+                                MPT2SAS_DELL_6GBPS_SAS_HBA_BRANDING);
+                               break;
+                       case MPT2SAS_DELL_PERC_H200_ADAPTER_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+                                MPT2SAS_DELL_PERC_H200_ADAPTER_BRANDING);
+                               break;
+                       case MPT2SAS_DELL_PERC_H200_INTEGRATED_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+                                MPT2SAS_DELL_PERC_H200_INTEGRATED_BRANDING);
+                               break;
+                       case MPT2SAS_DELL_PERC_H200_MODULAR_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+                                MPT2SAS_DELL_PERC_H200_MODULAR_BRANDING);
+                               break;
+                       case MPT2SAS_DELL_PERC_H200_EMBEDDED_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+                                MPT2SAS_DELL_PERC_H200_EMBEDDED_BRANDING);
+                               break;
+                       case MPT2SAS_DELL_PERC_H200_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+                                MPT2SAS_DELL_PERC_H200_BRANDING);
+                               break;
+                       case MPT2SAS_DELL_6GBPS_SAS_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+                                MPT2SAS_DELL_6GBPS_SAS_BRANDING);
+                               break;
+                       default:
+                               pr_info(MPT3SAS_FMT
+                                  "Dell 6Gbps HBA: Subsystem ID: 0x%X\n",
+                                  ioc->name, ioc->pdev->subsystem_device);
+                               break;
+                       }
+                       break;
+               case MPI25_MFGPAGE_DEVID_SAS3008:
+                       switch (ioc->pdev->subsystem_device) {
+                       case MPT3SAS_DELL_12G_HBA_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+                                       MPT3SAS_DELL_12G_HBA_BRANDING);
+                               break;
+                       default:
+                               pr_info(MPT3SAS_FMT
+                                  "Dell 12Gbps HBA: Subsystem ID: 0x%X\n",
+                                  ioc->name, ioc->pdev->subsystem_device);
+                               break;
+                       }
                        break;
                default:
                        pr_info(MPT3SAS_FMT
-                          "Dell 12Gbps HBA: Subsystem ID: 0x%X\n", ioc->name,
+                          "Dell HBA: Subsystem ID: 0x%X\n", ioc->name,
                           ioc->pdev->subsystem_device);
                        break;
                }
                break;
-       default:
-               pr_info(MPT3SAS_FMT
-                       "Dell 12Gbps HBA: Subsystem ID: 0x%X\n", ioc->name,
-                       ioc->pdev->subsystem_device);
-               break;
-       }
-}
-
-/**
- * _base_display_cisco_branding - Display branding string
- * @ioc: per adapter object
- *
- * Return nothing.
- */
-static void
-_base_display_cisco_branding(struct MPT3SAS_ADAPTER *ioc)
-{
-       if (ioc->pdev->subsystem_vendor != PCI_VENDOR_ID_CISCO)
-               return;
-
-       switch (ioc->pdev->device) {
-       case MPI25_MFGPAGE_DEVID_SAS3008:
-               switch (ioc->pdev->subsystem_device) {
-               case MPT3SAS_CISCO_12G_8E_HBA_SSDID:
-                       pr_info(MPT3SAS_FMT "%s\n", ioc->name,
-                               MPT3SAS_CISCO_12G_8E_HBA_BRANDING);
-                       break;
-               case MPT3SAS_CISCO_12G_8I_HBA_SSDID:
-                       pr_info(MPT3SAS_FMT "%s\n", ioc->name,
-                               MPT3SAS_CISCO_12G_8I_HBA_BRANDING);
+       case PCI_VENDOR_ID_CISCO:
+               switch (ioc->pdev->device) {
+               case MPI25_MFGPAGE_DEVID_SAS3008:
+                       switch (ioc->pdev->subsystem_device) {
+                       case MPT3SAS_CISCO_12G_8E_HBA_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+                                       MPT3SAS_CISCO_12G_8E_HBA_BRANDING);
+                               break;
+                       case MPT3SAS_CISCO_12G_8I_HBA_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+                                       MPT3SAS_CISCO_12G_8I_HBA_BRANDING);
+                               break;
+                       case MPT3SAS_CISCO_12G_AVILA_HBA_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+                                       MPT3SAS_CISCO_12G_AVILA_HBA_BRANDING);
+                               break;
+                       default:
+                               pr_info(MPT3SAS_FMT
+                                 "Cisco 12Gbps SAS HBA: Subsystem ID: 0x%X\n",
+                                 ioc->name, ioc->pdev->subsystem_device);
+                               break;
+                       }
                        break;
-               case MPT3SAS_CISCO_12G_AVILA_HBA_SSDID:
-                       pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+               case MPI25_MFGPAGE_DEVID_SAS3108_1:
+                       switch (ioc->pdev->subsystem_device) {
+                       case MPT3SAS_CISCO_12G_AVILA_HBA_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
                                MPT3SAS_CISCO_12G_AVILA_HBA_BRANDING);
+                               break;
+                       case MPT3SAS_CISCO_12G_COLUSA_MEZZANINE_HBA_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+                               MPT3SAS_CISCO_12G_COLUSA_MEZZANINE_HBA_BRANDING
+                               );
+                               break;
+                       default:
+                               pr_info(MPT3SAS_FMT
+                                "Cisco 12Gbps SAS HBA: Subsystem ID: 0x%X\n",
+                                ioc->name, ioc->pdev->subsystem_device);
+                               break;
+                       }
                        break;
                default:
                        pr_info(MPT3SAS_FMT
-                         "Cisco 12Gbps SAS HBA: Subsystem ID: 0x%X\n",
-                         ioc->name, ioc->pdev->subsystem_device);
+                          "Cisco SAS HBA: Subsystem ID: 0x%X\n",
+                          ioc->name, ioc->pdev->subsystem_device);
                        break;
                }
                break;
-       case MPI25_MFGPAGE_DEVID_SAS3108_1:
-               switch (ioc->pdev->subsystem_device) {
-               case MPT3SAS_CISCO_12G_AVILA_HBA_SSDID:
-                       pr_info(MPT3SAS_FMT "%s\n", ioc->name,
-                       MPT3SAS_CISCO_12G_AVILA_HBA_BRANDING);
-                       break;
-               case MPT3SAS_CISCO_12G_COLUSA_MEZZANINE_HBA_SSDID:
-                       pr_info(MPT3SAS_FMT "%s\n", ioc->name,
-                       MPT3SAS_CISCO_12G_COLUSA_MEZZANINE_HBA_BRANDING);
-                       break;
+       case MPT2SAS_HP_3PAR_SSVID:
+               switch (ioc->pdev->device) {
+               case MPI2_MFGPAGE_DEVID_SAS2004:
+                       switch (ioc->pdev->subsystem_device) {
+                       case MPT2SAS_HP_DAUGHTER_2_4_INTERNAL_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+                                   MPT2SAS_HP_DAUGHTER_2_4_INTERNAL_BRANDING);
+                               break;
+                       default:
+                               pr_info(MPT3SAS_FMT
+                                  "HP 6Gbps SAS HBA: Subsystem ID: 0x%X\n",
+                                  ioc->name, ioc->pdev->subsystem_device);
+                               break;
+                       }
+               case MPI2_MFGPAGE_DEVID_SAS2308_2:
+                       switch (ioc->pdev->subsystem_device) {
+                       case MPT2SAS_HP_2_4_INTERNAL_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+                                   MPT2SAS_HP_2_4_INTERNAL_BRANDING);
+                               break;
+                       case MPT2SAS_HP_2_4_EXTERNAL_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+                                   MPT2SAS_HP_2_4_EXTERNAL_BRANDING);
+                               break;
+                       case MPT2SAS_HP_1_4_INTERNAL_1_4_EXTERNAL_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+                                MPT2SAS_HP_1_4_INTERNAL_1_4_EXTERNAL_BRANDING);
+                               break;
+                       case MPT2SAS_HP_EMBEDDED_2_4_INTERNAL_SSDID:
+                               pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+                                   MPT2SAS_HP_EMBEDDED_2_4_INTERNAL_BRANDING);
+                               break;
+                       default:
+                               pr_info(MPT3SAS_FMT
+                                  "HP 6Gbps SAS HBA: Subsystem ID: 0x%X\n",
+                                  ioc->name, ioc->pdev->subsystem_device);
+                               break;
+                       }
                default:
                        pr_info(MPT3SAS_FMT
-                        "Cisco 12Gbps SAS HBA: Subsystem ID: 0x%X\n",
-                        ioc->name, ioc->pdev->subsystem_device);
+                          "HP SAS HBA: Subsystem ID: 0x%X\n",
+                          ioc->name, ioc->pdev->subsystem_device);
                        break;
                }
-               break;
        default:
-                pr_info(MPT3SAS_FMT
-                       "Cisco 12Gbps SAS HBA: Subsystem ID: 0x%X\n",
-                       ioc->name, ioc->pdev->subsystem_device);
                break;
        }
 }
@@ -2488,9 +2800,7 @@ _base_display_ioc_capabilities(struct MPT3SAS_ADAPTER *ioc)
           (bios_version & 0x0000FF00) >> 8,
            bios_version & 0x000000FF);
 
-       _base_display_intel_branding(ioc);
-       _base_display_dell_branding(ioc);
-       _base_display_cisco_branding(ioc);
+       _base_display_OEMs_branding(ioc);
 
        pr_info(MPT3SAS_FMT "Protocol=(", ioc->name);
 
@@ -2508,10 +2818,12 @@ _base_display_ioc_capabilities(struct MPT3SAS_ADAPTER *ioc)
        pr_info("), ");
        pr_info("Capabilities=(");
 
-       if (ioc->facts.IOCCapabilities &
+       if (!ioc->hide_ir_msg) {
+               if (ioc->facts.IOCCapabilities &
                    MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID) {
                        pr_info("Raid");
                        i++;
+               }
        }
 
        if (ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR) {
@@ -2852,18 +3164,22 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc,  int sleep_flag)
        /* command line tunables for max sgl entries */
        if (max_sgl_entries != -1)
                sg_tablesize = max_sgl_entries;
-       else
-               sg_tablesize = MPT3SAS_SG_DEPTH;
+       else {
+               if (ioc->hba_mpi_version_belonged == MPI2_VERSION)
+                       sg_tablesize = MPT2SAS_SG_DEPTH;
+               else
+                       sg_tablesize = MPT3SAS_SG_DEPTH;
+       }
 
-       if (sg_tablesize < MPT3SAS_MIN_PHYS_SEGMENTS)
-               sg_tablesize = MPT3SAS_MIN_PHYS_SEGMENTS;
-       else if (sg_tablesize > MPT3SAS_MAX_PHYS_SEGMENTS) {
+       if (sg_tablesize < MPT_MIN_PHYS_SEGMENTS)
+               sg_tablesize = MPT_MIN_PHYS_SEGMENTS;
+       else if (sg_tablesize > MPT_MAX_PHYS_SEGMENTS) {
                sg_tablesize = min_t(unsigned short, sg_tablesize,
                                      SCSI_MAX_SG_CHAIN_SEGMENTS);
                pr_warn(MPT3SAS_FMT
                 "sg_tablesize(%u) is bigger than kernel"
                 " defined SCSI_MAX_SG_SEGMENTS(%u)\n", ioc->name,
-                sg_tablesize, MPT3SAS_MAX_PHYS_SEGMENTS);
+                sg_tablesize, MPT_MAX_PHYS_SEGMENTS);
        }
        ioc->shost->sg_tablesize = sg_tablesize;
 
@@ -4021,7 +4337,7 @@ _base_send_ioc_init(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
        mpi_request.WhoInit = MPI2_WHOINIT_HOST_DRIVER;
        mpi_request.VF_ID = 0; /* TODO */
        mpi_request.VP_ID = 0;
-       mpi_request.MsgVersion = cpu_to_le16(MPI25_VERSION);
+       mpi_request.MsgVersion = cpu_to_le16(ioc->hba_mpi_version_belonged);
        mpi_request.HeaderVersion = cpu_to_le16(MPI2_HEADER_VERSION);
 
        if (_base_is_controller_msix_enabled(ioc))
@@ -4655,6 +4971,7 @@ _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
        u32 reply_address;
        u16 smid;
        struct _tr_list *delayed_tr, *delayed_tr_next;
+       u8 hide_flag;
        struct adapter_reply_queue *reply_q;
        long reply_post_free;
        u32 reply_post_free_sz, index = 0;
@@ -4685,6 +5002,7 @@ _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
                ioc->scsi_lookup[i].cb_idx = 0xFF;
                ioc->scsi_lookup[i].smid = smid;
                ioc->scsi_lookup[i].scmd = NULL;
+               ioc->scsi_lookup[i].direct_io = 0;
                list_add_tail(&ioc->scsi_lookup[i].tracker_list,
                    &ioc->free_list);
        }
@@ -4787,6 +5105,16 @@ _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
 
 
        if (ioc->is_driver_loading) {
+
+               if (ioc->is_warpdrive && ioc->manu_pg10.OEMIdentifier
+                   == 0x80) {
+                       hide_flag = (u8) (
+                           le32_to_cpu(ioc->manu_pg10.OEMSpecificFlags0) &
+                           MFG_PAGE10_HIDE_SSDS_MASK);
+                       if (hide_flag != MFG_PAGE10_HIDE_SSDS_MASK)
+                               ioc->mfg_pg10_hide_flag = hide_flag;
+               }
+
                ioc->wait_for_discovery_to_complete =
                    _base_determine_wait_on_discovery(ioc);
 
@@ -4812,6 +5140,8 @@ mpt3sas_base_free_resources(struct MPT3SAS_ADAPTER *ioc)
        dexitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name,
            __func__));
 
+       /* synchronizing freeing resource with pci_access_mutex lock */
+       mutex_lock(&ioc->pci_access_mutex);
        if (ioc->chip_phys && ioc->chip) {
                _base_mask_interrupts(ioc);
                ioc->shost_recovery = 1;
@@ -4820,6 +5150,7 @@ mpt3sas_base_free_resources(struct MPT3SAS_ADAPTER *ioc)
        }
 
        mpt3sas_base_unmap_resources(ioc);
+       mutex_unlock(&ioc->pci_access_mutex);
        return;
 }
 
@@ -4834,7 +5165,6 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
 {
        int r, i;
        int cpu_id, last_cpu_id = 0;
-       u8 revision;
 
        dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name,
            __func__));
@@ -4854,19 +5184,16 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
                goto out_free_resources;
        }
 
-       /* Check whether the controller revision is C0 or above.
-        * only C0 and above revision controllers support 96 MSI-X vectors.
-        */
-       revision = ioc->pdev->revision;
-
-       if ((ioc->pdev->device == MPI25_MFGPAGE_DEVID_SAS3004 ||
-            ioc->pdev->device == MPI25_MFGPAGE_DEVID_SAS3008 ||
-            ioc->pdev->device == MPI25_MFGPAGE_DEVID_SAS3108_1 ||
-            ioc->pdev->device == MPI25_MFGPAGE_DEVID_SAS3108_2 ||
-            ioc->pdev->device == MPI25_MFGPAGE_DEVID_SAS3108_5 ||
-            ioc->pdev->device == MPI25_MFGPAGE_DEVID_SAS3108_6) &&
-            (revision >= 0x02))
-               ioc->msix96_vector = 1;
+       if (ioc->is_warpdrive) {
+               ioc->reply_post_host_index = kcalloc(ioc->cpu_msix_table_sz,
+                   sizeof(resource_size_t *), GFP_KERNEL);
+               if (!ioc->reply_post_host_index) {
+                       dfailprintk(ioc, pr_info(MPT3SAS_FMT "allocation "
+                               "for cpu_msix_table failed!!!\n", ioc->name));
+                       r = -ENOMEM;
+                       goto out_free_resources;
+               }
+       }
 
        ioc->rdpq_array_enable_assigned = 0;
        ioc->dma_mask = 0;
@@ -4874,23 +5201,41 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
        if (r)
                goto out_free_resources;
 
+       if (ioc->is_warpdrive) {
+               ioc->reply_post_host_index[0] = (resource_size_t __iomem *)
+                   &ioc->chip->ReplyPostHostIndex;
+
+               for (i = 1; i < ioc->cpu_msix_table_sz; i++)
+                       ioc->reply_post_host_index[i] =
+                       (resource_size_t __iomem *)
+                       ((u8 __iomem *)&ioc->chip->Doorbell + (0x4000 + ((i - 1)
+                       * 4)));
+       }
 
        pci_set_drvdata(ioc->pdev, ioc->shost);
        r = _base_get_ioc_facts(ioc, CAN_SLEEP);
        if (r)
                goto out_free_resources;
 
-       /*
-        * In SAS3.0,
-        * SCSI_IO, SMP_PASSTHRU, SATA_PASSTHRU, Target Assist, and
-        * Target Status - all require the IEEE formated scatter gather
-        * elements.
-        */
-
-       ioc->build_sg_scmd = &_base_build_sg_scmd_ieee;
-       ioc->build_sg = &_base_build_sg_ieee;
-       ioc->build_zero_len_sge = &_base_build_zero_len_sge_ieee;
-       ioc->sge_size_ieee = sizeof(Mpi2IeeeSgeSimple64_t);
+       switch (ioc->hba_mpi_version_belonged) {
+       case MPI2_VERSION:
+               ioc->build_sg_scmd = &_base_build_sg_scmd;
+               ioc->build_sg = &_base_build_sg;
+               ioc->build_zero_len_sge = &_base_build_zero_len_sge;
+               break;
+       case MPI25_VERSION:
+               /*
+                * In SAS3.0,
+                * SCSI_IO, SMP_PASSTHRU, SATA_PASSTHRU, Target Assist, and
+                * Target Status - all require the IEEE formated scatter gather
+                * elements.
+                */
+               ioc->build_sg_scmd = &_base_build_sg_scmd_ieee;
+               ioc->build_sg = &_base_build_sg_ieee;
+               ioc->build_zero_len_sge = &_base_build_zero_len_sge_ieee;
+               ioc->sge_size_ieee = sizeof(Mpi2IeeeSgeSimple64_t);
+               break;
+       }
 
        /*
         * These function pointers for other requests that don't
@@ -5006,6 +5351,7 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
        if (r)
                goto out_free_resources;
 
+       ioc->non_operational_loop = 0;
        return 0;
 
  out_free_resources:
@@ -5016,6 +5362,8 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
        _base_release_memory_pools(ioc);
        pci_set_drvdata(ioc->pdev, NULL);
        kfree(ioc->cpu_msix_table);
+       if (ioc->is_warpdrive)
+               kfree(ioc->reply_post_host_index);
        kfree(ioc->pd_handles);
        kfree(ioc->blocking_handles);
        kfree(ioc->tm_cmds.reply);
@@ -5055,6 +5403,8 @@ mpt3sas_base_detach(struct MPT3SAS_ADAPTER *ioc)
        _base_release_memory_pools(ioc);
        pci_set_drvdata(ioc->pdev, NULL);
        kfree(ioc->cpu_msix_table);
+       if (ioc->is_warpdrive)
+               kfree(ioc->reply_post_host_index);
        kfree(ioc->pd_handles);
        kfree(ioc->blocking_handles);
        kfree(ioc->pfacts);
index f0e462b0880d21a645327bf60c221cc0f112c76a..5ad271efbd45e760eabd72d8218bd6cefc6a0e23 100644 (file)
@@ -63,6 +63,8 @@
 #include <scsi/scsi_transport_sas.h>
 #include <scsi/scsi_dbg.h>
 #include <scsi/scsi_eh.h>
+#include <linux/pci.h>
+#include <linux/poll.h>
 
 #include "mpt3sas_debug.h"
 #include "mpt3sas_trigger_diag.h"
 #define MPT3SAS_DRIVER_NAME            "mpt3sas"
 #define MPT3SAS_AUTHOR "Avago Technologies <MPT-FusionLinux.pdl@avagotech.com>"
 #define MPT3SAS_DESCRIPTION    "LSI MPT Fusion SAS 3.0 Device Driver"
-#define MPT3SAS_DRIVER_VERSION         "09.100.00.00"
+#define MPT3SAS_DRIVER_VERSION         "09.102.00.00"
 #define MPT3SAS_MAJOR_VERSION          9
-#define MPT3SAS_MINOR_VERSION          100
+#define MPT3SAS_MINOR_VERSION          102
 #define MPT3SAS_BUILD_VERSION          0
 #define MPT3SAS_RELEASE_VERSION        00
 
+#define MPT2SAS_DRIVER_NAME            "mpt2sas"
+#define MPT2SAS_DESCRIPTION    "LSI MPT Fusion SAS 2.0 Device Driver"
+#define MPT2SAS_DRIVER_VERSION         "20.102.00.00"
+#define MPT2SAS_MAJOR_VERSION          20
+#define MPT2SAS_MINOR_VERSION          102
+#define MPT2SAS_BUILD_VERSION          0
+#define MPT2SAS_RELEASE_VERSION        00
+
 /*
  * Set MPT3SAS_SG_DEPTH value based on user input.
  */
-#define MPT3SAS_MAX_PHYS_SEGMENTS      SCSI_MAX_SG_SEGMENTS
-#define MPT3SAS_MIN_PHYS_SEGMENTS      16
+#define MPT_MAX_PHYS_SEGMENTS  SCSI_MAX_SG_SEGMENTS
+#define MPT_MIN_PHYS_SEGMENTS  16
+
 #ifdef CONFIG_SCSI_MPT3SAS_MAX_SGE
 #define MPT3SAS_SG_DEPTH               CONFIG_SCSI_MPT3SAS_MAX_SGE
 #else
-#define MPT3SAS_SG_DEPTH               MPT3SAS_MAX_PHYS_SEGMENTS
+#define MPT3SAS_SG_DEPTH               MPT_MAX_PHYS_SEGMENTS
 #endif
 
+#ifdef CONFIG_SCSI_MPT2SAS_MAX_SGE
+#define MPT2SAS_SG_DEPTH               CONFIG_SCSI_MPT2SAS_MAX_SGE
+#else
+#define MPT2SAS_SG_DEPTH               MPT_MAX_PHYS_SEGMENTS
+#endif
 
 /*
  * Generic Defines
  */
 #define MPT3SAS_FMT                    "%s: "
 
+/*
+ *  WarpDrive Specific Log codes
+ */
+
+#define MPT2_WARPDRIVE_LOGENTRY                (0x8002)
+#define MPT2_WARPDRIVE_LC_SSDT                 (0x41)
+#define MPT2_WARPDRIVE_LC_SSDLW                (0x43)
+#define MPT2_WARPDRIVE_LC_SSDLF                (0x44)
+#define MPT2_WARPDRIVE_LC_BRMF                 (0x4D)
+
 /*
  * per target private data
  */
 #define MPT_TARGET_FLAGS_DELETED       0x04
 #define MPT_TARGET_FASTPATH_IO         0x08
 
+#define SAS2_PCI_DEVICE_B0_REVISION    (0x01)
+#define SAS3_PCI_DEVICE_C0_REVISION    (0x02)
+
 /*
  * Intel HBA branding
  */
+#define MPT2SAS_INTEL_RMS25JB080_BRANDING    \
+       "Intel(R) Integrated RAID Module RMS25JB080"
+#define MPT2SAS_INTEL_RMS25JB040_BRANDING    \
+       "Intel(R) Integrated RAID Module RMS25JB040"
+#define MPT2SAS_INTEL_RMS25KB080_BRANDING    \
+       "Intel(R) Integrated RAID Module RMS25KB080"
+#define MPT2SAS_INTEL_RMS25KB040_BRANDING    \
+       "Intel(R) Integrated RAID Module RMS25KB040"
+#define MPT2SAS_INTEL_RMS25LB040_BRANDING      \
+       "Intel(R) Integrated RAID Module RMS25LB040"
+#define MPT2SAS_INTEL_RMS25LB080_BRANDING      \
+       "Intel(R) Integrated RAID Module RMS25LB080"
+#define MPT2SAS_INTEL_RMS2LL080_BRANDING       \
+       "Intel Integrated RAID Module RMS2LL080"
+#define MPT2SAS_INTEL_RMS2LL040_BRANDING       \
+       "Intel Integrated RAID Module RMS2LL040"
+#define MPT2SAS_INTEL_RS25GB008_BRANDING       \
+       "Intel(R) RAID Controller RS25GB008"
+#define MPT2SAS_INTEL_SSD910_BRANDING          \
+       "Intel(R) SSD 910 Series"
+
 #define MPT3SAS_INTEL_RMS3JC080_BRANDING       \
        "Intel(R) Integrated RAID Module RMS3JC080"
 #define MPT3SAS_INTEL_RS3GC008_BRANDING       \
 /*
  * Intel HBA SSDIDs
  */
-#define MPT3SAS_INTEL_RMS3JC080_SSDID  0x3521
-#define MPT3SAS_INTEL_RS3GC008_SSDID   0x3522
-#define MPT3SAS_INTEL_RS3FC044_SSDID   0x3523
-#define MPT3SAS_INTEL_RS3UC080_SSDID    0x3524
+#define MPT2SAS_INTEL_RMS25JB080_SSDID         0x3516
+#define MPT2SAS_INTEL_RMS25JB040_SSDID         0x3517
+#define MPT2SAS_INTEL_RMS25KB080_SSDID         0x3518
+#define MPT2SAS_INTEL_RMS25KB040_SSDID         0x3519
+#define MPT2SAS_INTEL_RMS25LB040_SSDID         0x351A
+#define MPT2SAS_INTEL_RMS25LB080_SSDID         0x351B
+#define MPT2SAS_INTEL_RMS2LL080_SSDID          0x350E
+#define MPT2SAS_INTEL_RMS2LL040_SSDID          0x350F
+#define MPT2SAS_INTEL_RS25GB008_SSDID          0x3000
+#define MPT2SAS_INTEL_SSD910_SSDID             0x3700
+
+#define MPT3SAS_INTEL_RMS3JC080_SSDID          0x3521
+#define MPT3SAS_INTEL_RS3GC008_SSDID           0x3522
+#define MPT3SAS_INTEL_RS3FC044_SSDID           0x3523
+#define MPT3SAS_INTEL_RS3UC080_SSDID           0x3524
 
 /*
  * Dell HBA branding
  */
+#define MPT2SAS_DELL_BRANDING_SIZE                 32
+
+#define MPT2SAS_DELL_6GBPS_SAS_HBA_BRANDING        "Dell 6Gbps SAS HBA"
+#define MPT2SAS_DELL_PERC_H200_ADAPTER_BRANDING    "Dell PERC H200 Adapter"
+#define MPT2SAS_DELL_PERC_H200_INTEGRATED_BRANDING "Dell PERC H200 Integrated"
+#define MPT2SAS_DELL_PERC_H200_MODULAR_BRANDING    "Dell PERC H200 Modular"
+#define MPT2SAS_DELL_PERC_H200_EMBEDDED_BRANDING   "Dell PERC H200 Embedded"
+#define MPT2SAS_DELL_PERC_H200_BRANDING            "Dell PERC H200"
+#define MPT2SAS_DELL_6GBPS_SAS_BRANDING            "Dell 6Gbps SAS"
+
 #define MPT3SAS_DELL_12G_HBA_BRANDING       \
        "Dell 12Gbps HBA"
 
 /*
  * Dell HBA SSDIDs
  */
-#define MPT3SAS_DELL_12G_HBA_SSDID     0x1F46
+#define MPT2SAS_DELL_6GBPS_SAS_HBA_SSDID       0x1F1C
+#define MPT2SAS_DELL_PERC_H200_ADAPTER_SSDID   0x1F1D
+#define MPT2SAS_DELL_PERC_H200_INTEGRATED_SSDID        0x1F1E
+#define MPT2SAS_DELL_PERC_H200_MODULAR_SSDID   0x1F1F
+#define MPT2SAS_DELL_PERC_H200_EMBEDDED_SSDID  0x1F20
+#define MPT2SAS_DELL_PERC_H200_SSDID           0x1F21
+#define MPT2SAS_DELL_6GBPS_SAS_SSDID           0x1F22
+
+#define MPT3SAS_DELL_12G_HBA_SSDID             0x1F46
 
 /*
  * Cisco HBA branding
  */
 #define MPT3SAS_CISCO_12G_8E_HBA_BRANDING              \
-               "Cisco 9300-8E 12G SAS HBA"
+       "Cisco 9300-8E 12G SAS HBA"
 #define MPT3SAS_CISCO_12G_8I_HBA_BRANDING              \
-               "Cisco 9300-8i 12G SAS HBA"
+       "Cisco 9300-8i 12G SAS HBA"
 #define MPT3SAS_CISCO_12G_AVILA_HBA_BRANDING   \
-               "Cisco 12G Modular SAS Pass through Controller"
+       "Cisco 12G Modular SAS Pass through Controller"
 #define MPT3SAS_CISCO_12G_COLUSA_MEZZANINE_HBA_BRANDING                \
-               "UCS C3X60 12G SAS Pass through Controller"
+       "UCS C3X60 12G SAS Pass through Controller"
 /*
  * Cisco HBA SSSDIDs
  */
 #define MPT3_DIAG_BUFFER_IS_RELEASED   (0x02)
 #define MPT3_DIAG_BUFFER_IS_DIAG_RESET (0x04)
 
+/*
+ * HP HBA branding
+ */
+#define MPT2SAS_HP_3PAR_SSVID                0x1590
+
+#define MPT2SAS_HP_2_4_INTERNAL_BRANDING       \
+       "HP H220 Host Bus Adapter"
+#define MPT2SAS_HP_2_4_EXTERNAL_BRANDING       \
+       "HP H221 Host Bus Adapter"
+#define MPT2SAS_HP_1_4_INTERNAL_1_4_EXTERNAL_BRANDING  \
+       "HP H222 Host Bus Adapter"
+#define MPT2SAS_HP_EMBEDDED_2_4_INTERNAL_BRANDING      \
+       "HP H220i Host Bus Adapter"
+#define MPT2SAS_HP_DAUGHTER_2_4_INTERNAL_BRANDING      \
+       "HP H210i Host Bus Adapter"
+
+/*
+ * HO HBA SSDIDs
+ */
+#define MPT2SAS_HP_2_4_INTERNAL_SSDID                  0x0041
+#define MPT2SAS_HP_2_4_EXTERNAL_SSDID                  0x0042
+#define MPT2SAS_HP_1_4_INTERNAL_1_4_EXTERNAL_SSDID     0x0043
+#define MPT2SAS_HP_EMBEDDED_2_4_INTERNAL_SSDID         0x0044
+#define MPT2SAS_HP_DAUGHTER_2_4_INTERNAL_SSDID         0x0046
+
 /*
  * Combined Reply Queue constants,
  * There are twelve Supplemental Reply Post Host Index Registers
@@ -243,20 +347,24 @@ struct Mpi2ManufacturingPage11_t {
  * struct MPT3SAS_TARGET - starget private hostdata
  * @starget: starget object
  * @sas_address: target sas address
+ * @raid_device: raid_device pointer to access volume data
  * @handle: device handle
  * @num_luns: number luns
  * @flags: MPT_TARGET_FLAGS_XXX flags
  * @deleted: target flaged for deletion
  * @tm_busy: target is busy with TM request.
+ * @sdev: The sas_device associated with this target
  */
 struct MPT3SAS_TARGET {
        struct scsi_target *starget;
        u64     sas_address;
+       struct _raid_device *raid_device;
        u16     handle;
        int     num_luns;
        u32     flags;
        u8      deleted;
        u8      tm_busy;
+       struct _sas_device *sdev;
 };
 
 
@@ -266,6 +374,11 @@ struct MPT3SAS_TARGET {
 #define MPT_DEVICE_FLAGS_INIT          0x01
 #define MPT_DEVICE_TLR_ON              0x02
 
+#define MFG_PAGE10_HIDE_SSDS_MASK      (0x00000003)
+#define MFG_PAGE10_HIDE_ALL_DISKS      (0x00)
+#define MFG_PAGE10_EXPOSE_ALL_DISKS    (0x01)
+#define MFG_PAGE10_HIDE_IF_VOL_PRESENT (0x02)
+
 /**
  * struct MPT3SAS_DEVICE - sdev private hostdata
  * @sas_target: starget private hostdata
@@ -358,8 +471,24 @@ struct _sas_device {
        u8      pend_sas_rphy_add;
        u8      enclosure_level;
        u8      connector_name[4];
+       struct kref refcount;
 };
 
+static inline void sas_device_get(struct _sas_device *s)
+{
+       kref_get(&s->refcount);
+}
+
+static inline void sas_device_free(struct kref *r)
+{
+       kfree(container_of(r, struct _sas_device, refcount));
+}
+
+static inline void sas_device_put(struct _sas_device *s)
+{
+       kref_put(&s->refcount, sas_device_free);
+}
+
 /**
  * struct _raid_device - raid volume link list
  * @list: sas device list
@@ -367,6 +496,7 @@ struct _sas_device {
  * @sdev: scsi device struct (volumes are single lun)
  * @wwid: unique identifier for the volume
  * @handle: device handle
+ * @block_size: Block size of the volume
  * @id: target id
  * @channel: target channel
  * @volume_type: the raid level
@@ -374,6 +504,13 @@ struct _sas_device {
  * @num_pds: number of hidden raid components
  * @responding: used in _scsih_raid_device_mark_responding
  * @percent_complete: resync percent complete
+ * @direct_io_enabled: Whether direct io to PDs are allowed or not
+ * @stripe_exponent: X where 2powX is the stripe sz in blocks
+ * @block_exponent: X where 2powX is the block sz in bytes
+ * @max_lba: Maximum number of LBA in the volume
+ * @stripe_sz: Stripe Size of the volume
+ * @device_info: Device info of the volume member disk
+ * @pd_handle: Array of handles of the physical drives for direct I/O in le16
  */
 #define MPT_MAX_WARPDRIVE_PDS          8
 struct _raid_device {
@@ -382,13 +519,20 @@ struct _raid_device {
        struct scsi_device *sdev;
        u64     wwid;
        u16     handle;
+       u16     block_sz;
        int     id;
        int     channel;
        u8      volume_type;
        u8      num_pds;
        u8      responding;
        u8      percent_complete;
+       u8      direct_io_enabled;
+       u8      stripe_exponent;
+       u8      block_exponent;
+       u64     max_lba;
+       u32     stripe_sz;
        u32     device_info;
+       u16     pd_handle[MPT_MAX_WARPDRIVE_PDS];
 };
 
 /**
@@ -497,12 +641,14 @@ struct chain_tracker {
  * @smid: system message id
  * @scmd: scsi request pointer
  * @cb_idx: callback index
+ * @direct_io: To indicate whether I/O is direct (WARPDRIVE)
  * @tracker_list: list of free request (ioc->free_list)
  */
 struct scsiio_tracker {
        u16     smid;
        struct scsi_cmnd *scmd;
        u8      cb_idx;
+       u8      direct_io;
        struct list_head chain_list;
        struct list_head tracker_list;
 };
@@ -775,7 +921,13 @@ typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct MPT3SAS_ADAPTER *ioc);
  * @replyPostRegisterIndex: index of next position in Reply Desc Post Queue
  * @delayed_tr_list: target reset link list
  * @delayed_tr_volume_list: volume target reset link list
- * @@temp_sensors_count: flag to carry the number of temperature sensors
+ * @temp_sensors_count: flag to carry the number of temperature sensors
+ * @pci_access_mutex: Mutex to synchronize ioctl,sysfs show path and
+ *     pci resource handling. PCI resource freeing will lead to free
+ *     vital hardware/memory resource, which might be in use by cli/sysfs
+ *     path functions resulting in Null pointer reference followed by kernel
+ *     crash. To avoid the above race condition we use mutex syncrhonization
+ *     which ensures the syncrhonization between cli/sysfs_show path.
  */
 struct MPT3SAS_ADAPTER {
        struct list_head list;
@@ -783,6 +935,7 @@ struct MPT3SAS_ADAPTER {
        u8              id;
        int             cpu_count;
        char            name[MPT_NAME_LENGTH];
+       char            driver_name[MPT_NAME_LENGTH];
        char            tmp_string[MPT_STRING_LENGTH];
        struct pci_dev  *pdev;
        Mpi2SystemInterfaceRegs_t __iomem *chip;
@@ -829,8 +982,10 @@ struct MPT3SAS_ADAPTER {
        u16             msix_vector_count;
        u8              *cpu_msix_table;
        u16             cpu_msix_table_sz;
+       resource_size_t __iomem **reply_post_host_index;
        u32             ioc_reset_count;
        MPT3SAS_FLUSH_RUNNING_CMDS schedule_dead_ioc_flush_running_cmds;
+       u32             non_operational_loop;
 
        /* internal commands, callback index */
        u8              scsi_io_cb_idx;
@@ -859,6 +1014,7 @@ struct MPT3SAS_ADAPTER {
        MPT_BUILD_SG    build_sg;
        MPT_BUILD_ZERO_LEN_SGE build_zero_len_sge;
        u16             sge_size_ieee;
+       u16             hba_mpi_version_belonged;
 
        /* function ptr for MPI sg elements only */
        MPT_BUILD_SG    build_sg_mpi;
@@ -987,6 +1143,7 @@ struct MPT3SAS_ADAPTER {
        struct list_head delayed_tr_list;
        struct list_head delayed_tr_volume_list;
        u8              temp_sensors_count;
+       struct mutex pci_access_mutex;
 
        /* diag buffer support */
        u8              *diag_buffer[MPI2_DIAG_BUF_TYPE_COUNT];
@@ -998,6 +1155,10 @@ struct MPT3SAS_ADAPTER {
        u32             diagnostic_flags[MPI2_DIAG_BUF_TYPE_COUNT];
        u32             ring_buffer_offset;
        u32             ring_buffer_sz;
+       u8              is_warpdrive;
+       u8              hide_ir_msg;
+       u8              mfg_pg10_hide_flag;
+       u8              hide_drives;
        spinlock_t      diag_trigger_lock;
        u8              diag_trigger_active;
        struct SL_WH_MASTER_TRIGGER_T diag_trigger_master;
@@ -1012,6 +1173,19 @@ typedef u8 (*MPT_CALLBACK)(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
 
 /* base shared API */
 extern struct list_head mpt3sas_ioc_list;
+extern char    driver_name[MPT_NAME_LENGTH];
+/* spinlock on list operations over IOCs
+ * Case: when multiple warpdrive cards(IOCs) are in use
+ * Each IOC will added to the ioc list structure on initialization.
+ * Watchdog threads run at regular intervals to check IOC for any
+ * fault conditions which will trigger the dead_ioc thread to
+ * deallocate pci resource, resulting deleting the IOC netry from list,
+ * this deletion need to protected by spinlock to enusre that
+ * ioc removal is syncrhonized, if not synchronized it might lead to
+ * list_del corruption as the ioc list is traversed in cli path.
+ */
+extern spinlock_t gioc_lock;
+
 void mpt3sas_base_start_watchdog(struct MPT3SAS_ADAPTER *ioc);
 void mpt3sas_base_stop_watchdog(struct MPT3SAS_ADAPTER *ioc);
 
@@ -1090,10 +1264,14 @@ struct _sas_node *mpt3sas_scsih_expander_find_by_handle(
        struct MPT3SAS_ADAPTER *ioc, u16 handle);
 struct _sas_node *mpt3sas_scsih_expander_find_by_sas_address(
        struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
-struct _sas_device *mpt3sas_scsih_sas_device_find_by_sas_address(
-       struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
+struct _sas_device *mpt3sas_get_sdev_by_addr(
+        struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
+struct _sas_device *__mpt3sas_get_sdev_by_addr(
+        struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
 
 void mpt3sas_port_enable_complete(struct MPT3SAS_ADAPTER *ioc);
+struct _raid_device *
+mpt3sas_raid_device_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle);
 
 /* config shared API */
 u8 mpt3sas_config_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
@@ -1133,6 +1311,8 @@ int mpt3sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,
        u16 sz);
 int mpt3sas_config_get_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
        *mpi_reply, Mpi2IOUnitPage1_t *config_page);
+int mpt3sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER *ioc,
+       Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz);
 int mpt3sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
        *mpi_reply, Mpi2IOUnitPage1_t *config_page);
 int mpt3sas_config_get_iounit_pg8(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
@@ -1177,8 +1357,8 @@ int mpt3sas_config_get_volume_wwid(struct MPT3SAS_ADAPTER *ioc,
 /* ctl shared API */
 extern struct device_attribute *mpt3sas_host_attrs[];
 extern struct device_attribute *mpt3sas_dev_attrs[];
-void mpt3sas_ctl_init(void);
-void mpt3sas_ctl_exit(void);
+void mpt3sas_ctl_init(ushort hbas_to_enumerate);
+void mpt3sas_ctl_exit(ushort hbas_to_enumerate);
 u8 mpt3sas_ctl_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
        u32 reply);
 void mpt3sas_ctl_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase);
@@ -1193,6 +1373,7 @@ int mpt3sas_send_diag_release(struct MPT3SAS_ADAPTER *ioc, u8 buffer_type,
        u8 *issue_reset);
 
 /* transport shared API */
+extern struct scsi_transport_template *mpt3sas_transport_template;
 u8 mpt3sas_transport_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
        u32 reply);
 struct _sas_port *mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc,
@@ -1224,4 +1405,18 @@ void mpt3sas_trigger_scsi(struct MPT3SAS_ADAPTER *ioc, u8 sense_key,
        u8 asc, u8 ascq);
 void mpt3sas_trigger_mpi(struct MPT3SAS_ADAPTER *ioc, u16 ioc_status,
        u32 loginfo);
+
+/* warpdrive APIs */
+u8 mpt3sas_get_num_volumes(struct MPT3SAS_ADAPTER *ioc);
+void mpt3sas_init_warpdrive_properties(struct MPT3SAS_ADAPTER *ioc,
+       struct _raid_device *raid_device);
+u8
+mpt3sas_scsi_direct_io_get(struct MPT3SAS_ADAPTER *ioc, u16 smid);
+void
+mpt3sas_scsi_direct_io_set(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 direct_io);
+void
+mpt3sas_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
+       struct _raid_device *raid_device, Mpi2SCSIIORequest_t *mpi_request,
+       u16 smid);
+
 #endif /* MPT3SAS_BASE_H_INCLUDED */
index e45c4613ef0c3a4a61aca89f5e18d3ba9f4d19d6..a6914ec99cc047ecb492e107988a1f5bb9551c1e 100644 (file)
@@ -83,7 +83,6 @@ struct config_request {
        dma_addr_t              page_dma;
 };
 
-#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
 /**
  * _config_display_some_debug - debug routine
  * @ioc: per adapter object
@@ -173,7 +172,6 @@ _config_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 smid,
                    ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
                    le32_to_cpu(mpi_reply->IOCLogInfo));
 }
-#endif
 
 /**
  * _config_alloc_config_dma_memory - obtain physical memory
@@ -255,9 +253,7 @@ mpt3sas_config_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
                    mpi_reply->MsgLength*4);
        }
        ioc->config_cmds.status &= ~MPT3_CMD_PENDING;
-#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
        _config_display_some_debug(ioc, smid, "config_done", mpi_reply);
-#endif
        ioc->config_cmds.smid = USHRT_MAX;
        complete(&ioc->config_cmds.done);
        return 1;
@@ -387,9 +383,7 @@ _config_request(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
        config_request = mpt3sas_base_get_msg_frame(ioc, smid);
        ioc->config_cmds.smid = smid;
        memcpy(config_request, mpi_request, sizeof(Mpi2ConfigRequest_t));
-#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
        _config_display_some_debug(ioc, smid, "config_request", NULL);
-#endif
        init_completion(&ioc->config_cmds.done);
        mpt3sas_base_put_smid_default(ioc, smid);
        timeleft = wait_for_completion_timeout(&ioc->config_cmds.done,
@@ -871,6 +865,42 @@ mpt3sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
        return r;
 }
 
+/**
+ * mpt3sas_config_get_iounit_pg3 - obtain iounit page 3
+ * @ioc: per adapter object
+ * @mpi_reply: reply mf payload returned from firmware
+ * @config_page: contents of the config page
+ * @sz: size of buffer passed in config_page
+ * Context: sleep.
+ *
+ * Returns 0 for success, non-zero for failure.
+ */
+int
+mpt3sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER *ioc,
+       Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz)
+{
+       Mpi2ConfigRequest_t mpi_request;
+       int r;
+
+       memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
+       mpi_request.Function = MPI2_FUNCTION_CONFIG;
+       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
+       mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
+       mpi_request.Header.PageNumber = 3;
+       mpi_request.Header.PageVersion = MPI2_IOUNITPAGE3_PAGEVERSION;
+       ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
+       r = _config_request(ioc, &mpi_request, mpi_reply,
+           MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
+       if (r)
+               goto out;
+
+       mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
+       r = _config_request(ioc, &mpi_request, mpi_reply,
+           MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
+ out:
+       return r;
+}
+
 /**
  * mpt3sas_config_get_iounit_pg8 - obtain iounit page 8
  * @ioc: per adapter object
index 080c8a76d23d65c688f1a3e8fe5dbed8b90c4ac8..d8366b056b70f48c046b1fcb06637f70174914ee 100644 (file)
@@ -78,7 +78,6 @@ enum block_state {
        BLOCKING,
 };
 
-#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
 /**
  * _ctl_sas_device_find_by_handle - sas device search
  * @ioc: per adapter object
@@ -254,8 +253,6 @@ _ctl_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 smid,
        }
 }
 
-#endif
-
 /**
  * mpt3sas_ctl_done - ctl module completion routine
  * @ioc: per adapter object
@@ -302,9 +299,7 @@ mpt3sas_ctl_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
                        }
                }
        }
-#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
        _ctl_display_some_debug(ioc, smid, "ctl_done", mpi_reply);
-#endif
        ioc->ctl_cmds.status &= ~MPT3_CMD_PENDING;
        complete(&ioc->ctl_cmds.done);
        return 1;
@@ -414,20 +409,31 @@ mpt3sas_ctl_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index,
  * _ctl_verify_adapter - validates ioc_number passed from application
  * @ioc: per adapter object
  * @iocpp: The ioc pointer is returned in this.
+ * @mpi_version: will be MPI2_VERSION for mpt2ctl ioctl device &
+ *             MPI25_VERSION for mpt3ctl ioctl device.
  *
  * Return (-1) means error, else ioc_number.
  */
 static int
-_ctl_verify_adapter(int ioc_number, struct MPT3SAS_ADAPTER **iocpp)
+_ctl_verify_adapter(int ioc_number, struct MPT3SAS_ADAPTER **iocpp,
+                                                       int mpi_version)
 {
        struct MPT3SAS_ADAPTER *ioc;
-
+       /* global ioc lock to protect controller on list operations */
+       spin_lock(&gioc_lock);
        list_for_each_entry(ioc, &mpt3sas_ioc_list, list) {
                if (ioc->id != ioc_number)
                        continue;
+               /* Check whether this ioctl command is from right
+                * ioctl device or not, if not continue the search.
+                */
+               if (ioc->hba_mpi_version_belonged != mpi_version)
+                       continue;
+               spin_unlock(&gioc_lock);
                *iocpp = ioc;
                return ioc_number;
        }
+       spin_unlock(&gioc_lock);
        *iocpp = NULL;
        return -1;
 }
@@ -497,7 +503,7 @@ mpt3sas_ctl_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase)
  *
  * Called when application request fasyn callback handler.
  */
-static int
+int
 _ctl_fasync(int fd, struct file *filep, int mode)
 {
        return fasync_helper(fd, filep, mode, &async_queue);
@@ -509,17 +515,22 @@ _ctl_fasync(int fd, struct file *filep, int mode)
  * @wait -
  *
  */
-static unsigned int
+unsigned int
 _ctl_poll(struct file *filep, poll_table *wait)
 {
        struct MPT3SAS_ADAPTER *ioc;
 
        poll_wait(filep, &ctl_poll_wait, wait);
 
+       /* global ioc lock to protect controller on list operations */
+       spin_lock(&gioc_lock);
        list_for_each_entry(ioc, &mpt3sas_ioc_list, list) {
-               if (ioc->aen_event_read_flag)
+               if (ioc->aen_event_read_flag) {
+                       spin_unlock(&gioc_lock);
                        return POLLIN | POLLRDNORM;
+               }
        }
+       spin_unlock(&gioc_lock);
        return 0;
 }
 
@@ -759,9 +770,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
        psge = (void *)request + (karg.data_sge_offset*4);
 
        /* send command to firmware */
-#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
        _ctl_display_some_debug(ioc, smid, "ctl_request", NULL);
-#endif
 
        init_completion(&ioc->ctl_cmds.done);
        switch (mpi_request->Function) {
@@ -916,7 +925,6 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
        mpi_reply = ioc->ctl_cmds.reply;
        ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
 
-#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
        if (mpi_reply->Function == MPI2_FUNCTION_SCSI_TASK_MGMT &&
            (ioc->logging_level & MPT_DEBUG_TM)) {
                Mpi2SCSITaskManagementReply_t *tm_reply =
@@ -929,7 +937,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
                    le32_to_cpu(tm_reply->IOCLogInfo),
                    le32_to_cpu(tm_reply->TerminationCount));
        }
-#endif
+
        /* copy out xdata to user */
        if (data_in_sz) {
                if (copy_to_user(karg.data_in_buf_ptr, data_in,
@@ -1023,7 +1031,6 @@ _ctl_getiocinfo(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
            __func__));
 
        memset(&karg, 0 , sizeof(karg));
-       karg.adapter_type = MPT3_IOCTL_INTERFACE_SAS3;
        if (ioc->pfacts)
                karg.port_number = ioc->pfacts[0].PortNumber;
        karg.hw_rev = ioc->pdev->revision;
@@ -1035,9 +1042,21 @@ _ctl_getiocinfo(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
        karg.pci_information.u.bits.function = PCI_FUNC(ioc->pdev->devfn);
        karg.pci_information.segment_id = pci_domain_nr(ioc->pdev->bus);
        karg.firmware_version = ioc->facts.FWVersion.Word;
-       strcpy(karg.driver_version, MPT3SAS_DRIVER_NAME);
+       strcpy(karg.driver_version, ioc->driver_name);
        strcat(karg.driver_version, "-");
-       strcat(karg.driver_version, MPT3SAS_DRIVER_VERSION);
+       switch  (ioc->hba_mpi_version_belonged) {
+       case MPI2_VERSION:
+               if (ioc->is_warpdrive)
+                       karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2_SSS6200;
+               else
+                       karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2;
+               strcat(karg.driver_version, MPT2SAS_DRIVER_VERSION);
+               break;
+       case MPI25_VERSION:
+               karg.adapter_type = MPT3_IOCTL_INTERFACE_SAS3;
+               strcat(karg.driver_version, MPT3SAS_DRIVER_VERSION);
+               break;
+       }
        karg.bios_version = le32_to_cpu(ioc->bios_pg3.BiosVersion);
 
        if (copy_to_user(arg, &karg, sizeof(karg))) {
@@ -2181,12 +2200,14 @@ _ctl_compat_mpt_command(struct MPT3SAS_ADAPTER *ioc, unsigned cmd,
  * _ctl_ioctl_main - main ioctl entry point
  * @file - (struct file)
  * @cmd - ioctl opcode
- * @arg -
- * compat - handles 32 bit applications in 64bit os
+ * @arg - user space data buffer
+ * @compat - handles 32 bit applications in 64bit os
+ * @mpi_version: will be MPI2_VERSION for mpt2ctl ioctl device &
+ *             MPI25_VERSION for mpt3ctl ioctl device.
  */
 static long
 _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg,
-       u8 compat)
+       u8 compat, u16 mpi_version)
 {
        struct MPT3SAS_ADAPTER *ioc;
        struct mpt3_ioctl_header ioctl_header;
@@ -2201,19 +2222,29 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg,
                return -EFAULT;
        }
 
-       if (_ctl_verify_adapter(ioctl_header.ioc_number, &ioc) == -1 || !ioc)
+       if (_ctl_verify_adapter(ioctl_header.ioc_number,
+                               &ioc, mpi_version) == -1 || !ioc)
                return -ENODEV;
 
+       /* pci_access_mutex lock acquired by ioctl path */
+       mutex_lock(&ioc->pci_access_mutex);
+
        if (ioc->shost_recovery || ioc->pci_error_recovery ||
-           ioc->is_driver_loading)
-               return -EAGAIN;
+           ioc->is_driver_loading || ioc->remove_host) {
+               ret = -EAGAIN;
+               goto out_unlock_pciaccess;
+       }
 
        state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING : BLOCKING;
        if (state == NON_BLOCKING) {
-               if (!mutex_trylock(&ioc->ctl_cmds.mutex))
-                       return -EAGAIN;
-       } else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex))
-               return -ERESTARTSYS;
+               if (!mutex_trylock(&ioc->ctl_cmds.mutex)) {
+                       ret = -EAGAIN;
+                       goto out_unlock_pciaccess;
+               }
+       } else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex)) {
+               ret = -ERESTARTSYS;
+               goto out_unlock_pciaccess;
+       }
 
 
        switch (cmd) {
@@ -2294,39 +2325,78 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg,
        }
 
        mutex_unlock(&ioc->ctl_cmds.mutex);
+out_unlock_pciaccess:
+       mutex_unlock(&ioc->pci_access_mutex);
        return ret;
 }
 
 /**
- * _ctl_ioctl - main ioctl entry point (unlocked)
+ * _ctl_ioctl - mpt3ctl main ioctl entry point (unlocked)
  * @file - (struct file)
  * @cmd - ioctl opcode
  * @arg -
  */
-static long
+long
 _ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        long ret;
 
-       ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 0);
+       /* pass MPI25_VERSION value, to indicate that this ioctl cmd
+        * came from mpt3ctl ioctl device.
+        */
+       ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 0, MPI25_VERSION);
        return ret;
 }
 
+/**
+ * _ctl_mpt2_ioctl - mpt2ctl main ioctl entry point (unlocked)
+ * @file - (struct file)
+ * @cmd - ioctl opcode
+ * @arg -
+ */
+long
+_ctl_mpt2_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+       long ret;
+
+       /* pass MPI2_VERSION value, to indicate that this ioctl cmd
+        * came from mpt2ctl ioctl device.
+        */
+       ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 0, MPI2_VERSION);
+       return ret;
+}
 #ifdef CONFIG_COMPAT
 /**
- * _ctl_ioctl_compat - main ioctl entry point (compat)
+ *ctl_ioctl_compat - main ioctl entry point (compat)
  * @file -
  * @cmd -
  * @arg -
  *
  * This routine handles 32 bit applications in 64bit os.
  */
-static long
+long
 _ctl_ioctl_compat(struct file *file, unsigned cmd, unsigned long arg)
 {
        long ret;
 
-       ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 1);
+       ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 1, MPI25_VERSION);
+       return ret;
+}
+
+/**
+ *_ ctl_mpt2_ioctl_compat - main ioctl entry point (compat)
+ * @file -
+ * @cmd -
+ * @arg -
+ *
+ * This routine handles 32 bit applications in 64bit os.
+ */
+long
+_ctl_mpt2_ioctl_compat(struct file *file, unsigned cmd, unsigned long arg)
+{
+       long ret;
+
+       ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 1, MPI2_VERSION);
        return ret;
 }
 #endif
@@ -2713,6 +2783,82 @@ _ctl_ioc_reply_queue_count_show(struct device *cdev,
 static DEVICE_ATTR(reply_queue_count, S_IRUGO, _ctl_ioc_reply_queue_count_show,
        NULL);
 
+/**
+ * _ctl_BRM_status_show - Backup Rail Monitor Status
+ * @cdev - pointer to embedded class device
+ * @buf - the buffer returned
+ *
+ * This is number of reply queues
+ *
+ * A sysfs 'read-only' shost attribute.
+ */
+static ssize_t
+_ctl_BRM_status_show(struct device *cdev, struct device_attribute *attr,
+       char *buf)
+{
+       struct Scsi_Host *shost = class_to_shost(cdev);
+       struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
+       Mpi2IOUnitPage3_t *io_unit_pg3 = NULL;
+       Mpi2ConfigReply_t mpi_reply;
+       u16 backup_rail_monitor_status = 0;
+       u16 ioc_status;
+       int sz;
+       ssize_t rc = 0;
+
+       if (!ioc->is_warpdrive) {
+               pr_err(MPT3SAS_FMT "%s: BRM attribute is only for"
+                   " warpdrive\n", ioc->name, __func__);
+               goto out;
+       }
+       /* pci_access_mutex lock acquired by sysfs show path */
+       mutex_lock(&ioc->pci_access_mutex);
+       if (ioc->pci_error_recovery || ioc->remove_host) {
+               mutex_unlock(&ioc->pci_access_mutex);
+               return 0;
+       }
+
+       /* allocate upto GPIOVal 36 entries */
+       sz = offsetof(Mpi2IOUnitPage3_t, GPIOVal) + (sizeof(u16) * 36);
+       io_unit_pg3 = kzalloc(sz, GFP_KERNEL);
+       if (!io_unit_pg3) {
+               pr_err(MPT3SAS_FMT "%s: failed allocating memory "
+                   "for iounit_pg3: (%d) bytes\n", ioc->name, __func__, sz);
+               goto out;
+       }
+
+       if (mpt3sas_config_get_iounit_pg3(ioc, &mpi_reply, io_unit_pg3, sz) !=
+           0) {
+               pr_err(MPT3SAS_FMT
+                   "%s: failed reading iounit_pg3\n", ioc->name,
+                   __func__);
+               goto out;
+       }
+
+       ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
+       if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
+               pr_err(MPT3SAS_FMT "%s: iounit_pg3 failed with "
+                   "ioc_status(0x%04x)\n", ioc->name, __func__, ioc_status);
+               goto out;
+       }
+
+       if (io_unit_pg3->GPIOCount < 25) {
+               pr_err(MPT3SAS_FMT "%s: iounit_pg3->GPIOCount less than "
+                    "25 entries, detected (%d) entries\n", ioc->name, __func__,
+                   io_unit_pg3->GPIOCount);
+               goto out;
+       }
+
+       /* BRM status is in bit zero of GPIOVal[24] */
+       backup_rail_monitor_status = le16_to_cpu(io_unit_pg3->GPIOVal[24]);
+       rc = snprintf(buf, PAGE_SIZE, "%d\n", (backup_rail_monitor_status & 1));
+
+ out:
+       kfree(io_unit_pg3);
+       mutex_unlock(&ioc->pci_access_mutex);
+       return rc;
+}
+static DEVICE_ATTR(BRM_status, S_IRUGO, _ctl_BRM_status_show, NULL);
+
 struct DIAG_BUFFER_START {
        __le32  Size;
        __le32  DiagVersion;
@@ -3165,6 +3311,7 @@ struct device_attribute *mpt3sas_host_attrs[] = {
        &dev_attr_diag_trigger_event,
        &dev_attr_diag_trigger_scsi,
        &dev_attr_diag_trigger_mpi,
+       &dev_attr_BRM_status,
        NULL,
 };
 
@@ -3218,6 +3365,7 @@ struct device_attribute *mpt3sas_dev_attrs[] = {
        NULL,
 };
 
+/* file operations table for mpt3ctl device */
 static const struct file_operations ctl_fops = {
        .owner = THIS_MODULE,
        .unlocked_ioctl = _ctl_ioctl,
@@ -3228,23 +3376,53 @@ static const struct file_operations ctl_fops = {
 #endif
 };
 
+/* file operations table for mpt2ctl device */
+static const struct file_operations ctl_gen2_fops = {
+       .owner = THIS_MODULE,
+       .unlocked_ioctl = _ctl_mpt2_ioctl,
+       .poll = _ctl_poll,
+       .fasync = _ctl_fasync,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl = _ctl_mpt2_ioctl_compat,
+#endif
+};
+
 static struct miscdevice ctl_dev = {
        .minor  = MPT3SAS_MINOR,
        .name   = MPT3SAS_DEV_NAME,
        .fops   = &ctl_fops,
 };
 
+static struct miscdevice gen2_ctl_dev = {
+       .minor  = MPT2SAS_MINOR,
+       .name   = MPT2SAS_DEV_NAME,
+       .fops   = &ctl_gen2_fops,
+};
+
 /**
  * mpt3sas_ctl_init - main entry point for ctl.
  *
  */
 void
-mpt3sas_ctl_init(void)
+mpt3sas_ctl_init(ushort hbas_to_enumerate)
 {
        async_queue = NULL;
-       if (misc_register(&ctl_dev) < 0)
-               pr_err("%s can't register misc device [minor=%d]\n",
-                   MPT3SAS_DRIVER_NAME, MPT3SAS_MINOR);
+
+       /* Don't register mpt3ctl ioctl device if
+        * hbas_to_enumarate is one.
+        */
+       if (hbas_to_enumerate != 1)
+               if (misc_register(&ctl_dev) < 0)
+                       pr_err("%s can't register misc device [minor=%d]\n",
+                           MPT3SAS_DRIVER_NAME, MPT3SAS_MINOR);
+
+       /* Don't register mpt3ctl ioctl device if
+        * hbas_to_enumarate is two.
+        */
+       if (hbas_to_enumerate != 2)
+               if (misc_register(&gen2_ctl_dev) < 0)
+                       pr_err("%s can't register misc device [minor=%d]\n",
+                           MPT2SAS_DRIVER_NAME, MPT2SAS_MINOR);
 
        init_waitqueue_head(&ctl_poll_wait);
 }
@@ -3254,7 +3432,7 @@ mpt3sas_ctl_init(void)
  *
  */
 void
-mpt3sas_ctl_exit(void)
+mpt3sas_ctl_exit(ushort hbas_to_enumerate)
 {
        struct MPT3SAS_ADAPTER *ioc;
        int i;
@@ -3279,5 +3457,8 @@ mpt3sas_ctl_exit(void)
 
                kfree(ioc->event_log);
        }
-       misc_deregister(&ctl_dev);
+       if (hbas_to_enumerate != 1)
+               misc_deregister(&ctl_dev);
+       if (hbas_to_enumerate != 2)
+               misc_deregister(&gen2_ctl_dev);
 }
index aee99ce67e54ec8355e51eedf98039a4488d399e..89408356d252432b4d57f9ae3964ec4d1381b14a 100644 (file)
 #include <linux/miscdevice.h>
 #endif
 
-
+#ifndef MPT2SAS_MINOR
+#define MPT2SAS_MINOR          (MPT_MINOR + 1)
+#endif
 #ifndef MPT3SAS_MINOR
 #define MPT3SAS_MINOR          (MPT_MINOR + 2)
 #endif
+#define MPT2SAS_DEV_NAME       "mpt2ctl"
 #define MPT3SAS_DEV_NAME       "mpt3ctl"
 #define MPT3_MAGIC_NUMBER      'L'
 #define MPT3_IOCTL_DEFAULT_TIMEOUT (10) /* in seconds */
@@ -138,6 +141,7 @@ struct mpt3_ioctl_pci_info {
 #define MPT2_IOCTL_INTERFACE_FC_IP     (0x02)
 #define MPT2_IOCTL_INTERFACE_SAS       (0x03)
 #define MPT2_IOCTL_INTERFACE_SAS2      (0x04)
+#define MPT2_IOCTL_INTERFACE_SAS2_SSS6200      (0x05)
 #define MPT3_IOCTL_INTERFACE_SAS3      (0x06)
 #define MPT2_IOCTL_VERSION_LENGTH      (32)
 
index 4e8a63fdb304f9c2c732b95cf8e89f48d5783f31..cceeb2c16e64c6e13d1cd8ae5c163b51af972086 100644 (file)
 #define MPT_DEBUG_TRIGGER_DIAG         0x00200000
 
 
-/*
- * CONFIG_SCSI_MPT3SAS_LOGGING - enabled in Kconfig
- */
-
-#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
 #define MPT_CHECK_LOGGING(IOC, CMD, BITS)                      \
 {                                                              \
        if (IOC->logging_level & BITS)                          \
                CMD;                                            \
 }
-#else
-#define MPT_CHECK_LOGGING(IOC, CMD, BITS)
-#endif /* CONFIG_SCSI_MPT3SAS_LOGGING */
-
 
 /*
  * debug macros
 
 
 /* inline functions for dumping debug data*/
-#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
+
 /**
  * _debug_dump_mf - print message frame contents
  * @mpi_request: pointer to message frame
@@ -211,10 +202,5 @@ _debug_dump_config(void *mpi_request, int sz)
        }
        pr_info("\n");
 }
-#else
-#define _debug_dump_mf(mpi_request, sz)
-#define _debug_dump_reply(mpi_request, sz)
-#define _debug_dump_config(mpi_request, sz)
-#endif /* CONFIG_SCSI_MPT3SAS_LOGGING */
 
 #endif /* MPT3SAS_DEBUG_H_INCLUDED */
index 8ccef38523fa46c823672878978e1ab8d022018a..d95206b7e1167861531d2cd29c9ef27e7da82c25 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/aer.h>
 #include <linux/raid_class.h>
+#include <asm/unaligned.h>
 
 #include "mpt3sas_base.h"
 
-MODULE_AUTHOR(MPT3SAS_AUTHOR);
-MODULE_DESCRIPTION(MPT3SAS_DESCRIPTION);
-MODULE_LICENSE("GPL");
-MODULE_VERSION(MPT3SAS_DRIVER_VERSION);
-
 #define RAID_CHANNEL 1
 /* forward proto's */
 static void _scsih_expander_node_remove(struct MPT3SAS_ADAPTER *ioc,
@@ -75,11 +71,16 @@ static int _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle,
 
 static u8 _scsih_check_for_pending_tm(struct MPT3SAS_ADAPTER *ioc, u16 smid);
 
-static void _scsih_scan_start(struct Scsi_Host *shost);
-static int _scsih_scan_finished(struct Scsi_Host *shost, unsigned long time);
-
 /* global parameters */
 LIST_HEAD(mpt3sas_ioc_list);
+/* global ioc lock for list operations */
+DEFINE_SPINLOCK(gioc_lock);
+
+MODULE_AUTHOR(MPT3SAS_AUTHOR);
+MODULE_DESCRIPTION(MPT3SAS_DESCRIPTION);
+MODULE_LICENSE("GPL");
+MODULE_VERSION(MPT3SAS_DRIVER_VERSION);
+MODULE_ALIAS("mpt2sas");
 
 /* local parameters */
 static u8 scsi_io_cb_idx = -1;
@@ -90,7 +91,8 @@ static u8 port_enable_cb_idx = -1;
 static u8 transport_cb_idx = -1;
 static u8 scsih_cb_idx = -1;
 static u8 config_cb_idx = -1;
-static int mpt_ids;
+static int mpt2_ids;
+static int mpt3_ids;
 
 static u8 tm_tr_cb_idx = -1 ;
 static u8 tm_tr_volume_cb_idx = -1 ;
@@ -117,8 +119,12 @@ static u64 max_lun = MPT3SAS_MAX_LUN;
 module_param(max_lun, ullong, 0);
 MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
 
-
-
+static ushort hbas_to_enumerate;
+module_param(hbas_to_enumerate, ushort, 0);
+MODULE_PARM_DESC(hbas_to_enumerate,
+               " 0 - enumerates both SAS 2.0 & SAS 3.0 generation HBAs\n \
+                 1 - enumerates only SAS 2.0 generation HBAs\n \
+                 2 - enumerates only SAS 3.0 generation HBAs (default=0)");
 
 /* diag_buffer_enable is bitwise
  * bit 0 set = TRACE
@@ -143,8 +149,8 @@ MODULE_PARM_DESC(prot_mask, " host protection capabilities mask, def=7 ");
 
 
 /* raid transport support */
-
-static struct raid_template *mpt3sas_raid_template;
+struct raid_template *mpt3sas_raid_template;
+struct raid_template *mpt2sas_raid_template;
 
 
 /**
@@ -191,11 +197,36 @@ struct fw_event_work {
        u8                      VP_ID;
        u8                      ignore;
        u16                     event;
+       struct kref             refcount;
        char                    event_data[0] __aligned(4);
 };
 
-/* raid transport support */
-static struct raid_template *mpt3sas_raid_template;
+static void fw_event_work_free(struct kref *r)
+{
+       kfree(container_of(r, struct fw_event_work, refcount));
+}
+
+static void fw_event_work_get(struct fw_event_work *fw_work)
+{
+       kref_get(&fw_work->refcount);
+}
+
+static void fw_event_work_put(struct fw_event_work *fw_work)
+{
+       kref_put(&fw_work->refcount, fw_event_work_free);
+}
+
+static struct fw_event_work *alloc_fw_event_work(int len)
+{
+       struct fw_event_work *fw_event;
+
+       fw_event = kzalloc(sizeof(*fw_event) + len, GFP_ATOMIC);
+       if (!fw_event)
+               return NULL;
+
+       kref_init(&fw_event->refcount);
+       return fw_event;
+}
 
 /**
  * struct _scsi_io_transfer - scsi io transfer
@@ -245,28 +276,6 @@ struct _scsi_io_transfer {
        u32     transfer_length;
 };
 
-/*
- * The pci device ids are defined in mpi/mpi2_cnfg.h.
- */
-static const struct pci_device_id scsih_pci_table[] = {
-       /* Fury ~ 3004 and 3008 */
-       { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3004,
-               PCI_ANY_ID, PCI_ANY_ID },
-       { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3008,
-               PCI_ANY_ID, PCI_ANY_ID },
-       /* Invader ~ 3108 */
-       { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_1,
-               PCI_ANY_ID, PCI_ANY_ID },
-       { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_2,
-               PCI_ANY_ID, PCI_ANY_ID },
-       { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_5,
-               PCI_ANY_ID, PCI_ANY_ID },
-       { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_6,
-               PCI_ANY_ID, PCI_ANY_ID },
-       {0}     /* Terminating entry */
-};
-MODULE_DEVICE_TABLE(pci, scsih_pci_table);
-
 /**
  * _scsih_set_debug_level - global setting of ioc->logging_level.
  *
@@ -282,8 +291,10 @@ _scsih_set_debug_level(const char *val, struct kernel_param *kp)
                return ret;
 
        pr_info("setting logging_level(0x%08x)\n", logging_level);
+       spin_lock(&gioc_lock);
        list_for_each_entry(ioc, &mpt3sas_ioc_list, list)
                ioc->logging_level = logging_level;
+       spin_unlock(&gioc_lock);
        return 0;
 }
 module_param_call(logging_level, _scsih_set_debug_level, param_get_int,
@@ -518,8 +529,61 @@ _scsih_determine_boot_device(struct MPT3SAS_ADAPTER *ioc,
        }
 }
 
+static struct _sas_device *
+__mpt3sas_get_sdev_from_target(struct MPT3SAS_ADAPTER *ioc,
+               struct MPT3SAS_TARGET *tgt_priv)
+{
+       struct _sas_device *ret;
+
+       assert_spin_locked(&ioc->sas_device_lock);
+
+       ret = tgt_priv->sdev;
+       if (ret)
+               sas_device_get(ret);
+
+       return ret;
+}
+
+static struct _sas_device *
+mpt3sas_get_sdev_from_target(struct MPT3SAS_ADAPTER *ioc,
+               struct MPT3SAS_TARGET *tgt_priv)
+{
+       struct _sas_device *ret;
+       unsigned long flags;
+
+       spin_lock_irqsave(&ioc->sas_device_lock, flags);
+       ret = __mpt3sas_get_sdev_from_target(ioc, tgt_priv);
+       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+
+       return ret;
+}
+
+
+struct _sas_device *
+__mpt3sas_get_sdev_by_addr(struct MPT3SAS_ADAPTER *ioc,
+                                       u64 sas_address)
+{
+       struct _sas_device *sas_device;
+
+       assert_spin_locked(&ioc->sas_device_lock);
+
+       list_for_each_entry(sas_device, &ioc->sas_device_list, list)
+               if (sas_device->sas_address == sas_address)
+                       goto found_device;
+
+       list_for_each_entry(sas_device, &ioc->sas_device_init_list, list)
+               if (sas_device->sas_address == sas_address)
+                       goto found_device;
+
+       return NULL;
+
+found_device:
+       sas_device_get(sas_device);
+       return sas_device;
+}
+
 /**
- * mpt3sas_scsih_sas_device_find_by_sas_address - sas device search
+ * mpt3sas_get_sdev_by_addr - sas device search
  * @ioc: per adapter object
  * @sas_address: sas address
  * Context: Calling function should acquire ioc->sas_device_lock
@@ -528,24 +592,44 @@ _scsih_determine_boot_device(struct MPT3SAS_ADAPTER *ioc,
  * object.
  */
 struct _sas_device *
-mpt3sas_scsih_sas_device_find_by_sas_address(struct MPT3SAS_ADAPTER *ioc,
+mpt3sas_get_sdev_by_addr(struct MPT3SAS_ADAPTER *ioc,
        u64 sas_address)
+{
+       struct _sas_device *sas_device;
+       unsigned long flags;
+
+       spin_lock_irqsave(&ioc->sas_device_lock, flags);
+       sas_device = __mpt3sas_get_sdev_by_addr(ioc,
+                       sas_address);
+       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+
+       return sas_device;
+}
+
+static struct _sas_device *
+__mpt3sas_get_sdev_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 {
        struct _sas_device *sas_device;
 
+       assert_spin_locked(&ioc->sas_device_lock);
+
        list_for_each_entry(sas_device, &ioc->sas_device_list, list)
-               if (sas_device->sas_address == sas_address)
-                       return sas_device;
+               if (sas_device->handle == handle)
+                       goto found_device;
 
        list_for_each_entry(sas_device, &ioc->sas_device_init_list, list)
-               if (sas_device->sas_address == sas_address)
-                       return sas_device;
+               if (sas_device->handle == handle)
+                       goto found_device;
 
        return NULL;
+
+found_device:
+       sas_device_get(sas_device);
+       return sas_device;
 }
 
 /**
- * _scsih_sas_device_find_by_handle - sas device search
+ * mpt3sas_get_sdev_by_handle - sas device search
  * @ioc: per adapter object
  * @handle: sas device handle (assigned by firmware)
  * Context: Calling function should acquire ioc->sas_device_lock
@@ -554,19 +638,16 @@ mpt3sas_scsih_sas_device_find_by_sas_address(struct MPT3SAS_ADAPTER *ioc,
  * object.
  */
 static struct _sas_device *
-_scsih_sas_device_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
+mpt3sas_get_sdev_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 {
        struct _sas_device *sas_device;
+       unsigned long flags;
 
-       list_for_each_entry(sas_device, &ioc->sas_device_list, list)
-               if (sas_device->handle == handle)
-                       return sas_device;
-
-       list_for_each_entry(sas_device, &ioc->sas_device_init_list, list)
-               if (sas_device->handle == handle)
-                       return sas_device;
+       spin_lock_irqsave(&ioc->sas_device_lock, flags);
+       sas_device = __mpt3sas_get_sdev_by_handle(ioc, handle);
+       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
-       return NULL;
+       return sas_device;
 }
 
 /**
@@ -575,7 +656,7 @@ _scsih_sas_device_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
  * @sas_device: the sas_device object
  * Context: This function will acquire ioc->sas_device_lock.
  *
- * Removing object and freeing associated memory from the ioc->sas_device_list.
+ * If sas_device is on the list, remove it and decrement its reference count.
  */
 static void
 _scsih_sas_device_remove(struct MPT3SAS_ADAPTER *ioc,
@@ -602,9 +683,15 @@ _scsih_sas_device_remove(struct MPT3SAS_ADAPTER *ioc,
                   ioc->name, sas_device->enclosure_level,
                   sas_device->connector_name);
 
+       /*
+        * The lock serializes access to the list, but we still need to verify
+        * that nobody removed the entry while we were waiting on the lock.
+        */
        spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       list_del(&sas_device->list);
-       kfree(sas_device);
+       if (!list_empty(&sas_device->list)) {
+               list_del_init(&sas_device->list);
+               sas_device_put(sas_device);
+       }
        spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 }
 
@@ -625,12 +712,16 @@ _scsih_device_remove_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
                return;
 
        spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
-       if (sas_device)
-               list_del(&sas_device->list);
+       sas_device = __mpt3sas_get_sdev_by_handle(ioc, handle);
+       if (sas_device) {
+               list_del_init(&sas_device->list);
+               sas_device_put(sas_device);
+       }
        spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-       if (sas_device)
+       if (sas_device) {
                _scsih_remove_device(ioc, sas_device);
+               sas_device_put(sas_device);
+       }
 }
 
 /**
@@ -651,13 +742,16 @@ mpt3sas_device_remove_by_sas_address(struct MPT3SAS_ADAPTER *ioc,
                return;
 
        spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
-           sas_address);
-       if (sas_device)
-               list_del(&sas_device->list);
+       sas_device = __mpt3sas_get_sdev_by_addr(ioc, sas_address);
+       if (sas_device) {
+               list_del_init(&sas_device->list);
+               sas_device_put(sas_device);
+       }
        spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-       if (sas_device)
+       if (sas_device) {
                _scsih_remove_device(ioc, sas_device);
+               sas_device_put(sas_device);
+       }
 }
 
 /**
@@ -692,6 +786,7 @@ _scsih_sas_device_add(struct MPT3SAS_ADAPTER *ioc,
                    sas_device->enclosure_level, sas_device->connector_name));
 
        spin_lock_irqsave(&ioc->sas_device_lock, flags);
+       sas_device_get(sas_device);
        list_add_tail(&sas_device->list, &ioc->sas_device_list);
        spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
@@ -745,6 +840,7 @@ _scsih_sas_device_init_add(struct MPT3SAS_ADAPTER *ioc,
                    sas_device->connector_name));
 
        spin_lock_irqsave(&ioc->sas_device_lock, flags);
+       sas_device_get(sas_device);
        list_add_tail(&sas_device->list, &ioc->sas_device_init_list);
        _scsih_determine_boot_device(ioc, sas_device, 0);
        spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
@@ -778,7 +874,7 @@ _scsih_raid_device_find_by_id(struct MPT3SAS_ADAPTER *ioc, int id, int channel)
 }
 
 /**
- * _scsih_raid_device_find_by_handle - raid device search
+ * mpt3sas_raid_device_find_by_handle - raid device search
  * @ioc: per adapter object
  * @handle: sas device handle (assigned by firmware)
  * Context: Calling function should acquire ioc->raid_device_lock
@@ -786,8 +882,8 @@ _scsih_raid_device_find_by_id(struct MPT3SAS_ADAPTER *ioc, int id, int channel)
  * This searches for raid_device based on handle, then return raid_device
  * object.
  */
-static struct _raid_device *
-_scsih_raid_device_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
+struct _raid_device *
+mpt3sas_raid_device_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 {
        struct _raid_device *raid_device, *r;
 
@@ -1095,14 +1191,14 @@ _scsih_scsi_lookup_find_by_lun(struct MPT3SAS_ADAPTER *ioc, int id,
 }
 
 /**
- * _scsih_change_queue_depth - setting device queue depth
+ * scsih_change_queue_depth - setting device queue depth
  * @sdev: scsi device struct
  * @qdepth: requested queue depth
  *
  * Returns queue depth.
  */
-static int
-_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
+int
+scsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
 {
        struct Scsi_Host *shost = sdev->host;
        int max_depth;
@@ -1123,12 +1219,15 @@ _scsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
                goto not_sata;
        if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME))
                goto not_sata;
+
        spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
-          sas_device_priv_data->sas_target->sas_address);
-       if (sas_device && sas_device->device_info &
-           MPI2_SAS_DEVICE_INFO_SATA_DEVICE)
-               max_depth = MPT3SAS_SATA_QUEUE_DEPTH;
+       sas_device = __mpt3sas_get_sdev_from_target(ioc, sas_target_priv_data);
+       if (sas_device) {
+               if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE)
+                       max_depth = MPT3SAS_SATA_QUEUE_DEPTH;
+
+               sas_device_put(sas_device);
+       }
        spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
  not_sata:
@@ -1141,14 +1240,14 @@ _scsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
 }
 
 /**
- * _scsih_target_alloc - target add routine
+ * scsih_target_alloc - target add routine
  * @starget: scsi target struct
  *
  * Returns 0 if ok. Any other return is assumed to be an error and
  * the device is ignored.
  */
-static int
-_scsih_target_alloc(struct scsi_target *starget)
+int
+scsih_target_alloc(struct scsi_target *starget)
 {
        struct Scsi_Host *shost = dev_to_shost(&starget->dev);
        struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
@@ -1176,7 +1275,9 @@ _scsih_target_alloc(struct scsi_target *starget)
                        sas_target_priv_data->handle = raid_device->handle;
                        sas_target_priv_data->sas_address = raid_device->wwid;
                        sas_target_priv_data->flags |= MPT_TARGET_FLAGS_VOLUME;
-                       raid_device->starget = starget;
+                       sas_target_priv_data->raid_device = raid_device;
+                       if (ioc->is_warpdrive)
+                               raid_device->starget = starget;
                }
                spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
                return 0;
@@ -1185,12 +1286,13 @@ _scsih_target_alloc(struct scsi_target *starget)
        /* sas/sata devices */
        spin_lock_irqsave(&ioc->sas_device_lock, flags);
        rphy = dev_to_rphy(starget->dev.parent);
-       sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
+       sas_device = __mpt3sas_get_sdev_by_addr(ioc,
           rphy->identify.sas_address);
 
        if (sas_device) {
                sas_target_priv_data->handle = sas_device->handle;
                sas_target_priv_data->sas_address = sas_device->sas_address;
+               sas_target_priv_data->sdev = sas_device;
                sas_device->starget = starget;
                sas_device->id = starget->id;
                sas_device->channel = starget->channel;
@@ -1206,13 +1308,13 @@ _scsih_target_alloc(struct scsi_target *starget)
 }
 
 /**
- * _scsih_target_destroy - target destroy routine
+ * scsih_target_destroy - target destroy routine
  * @starget: scsi target struct
  *
  * Returns nothing.
  */
-static void
-_scsih_target_destroy(struct scsi_target *starget)
+void
+scsih_target_destroy(struct scsi_target *starget)
 {
        struct Scsi_Host *shost = dev_to_shost(&starget->dev);
        struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
@@ -1240,13 +1342,21 @@ _scsih_target_destroy(struct scsi_target *starget)
 
        spin_lock_irqsave(&ioc->sas_device_lock, flags);
        rphy = dev_to_rphy(starget->dev.parent);
-       sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
-          rphy->identify.sas_address);
+       sas_device = __mpt3sas_get_sdev_from_target(ioc, sas_target_priv_data);
        if (sas_device && (sas_device->starget == starget) &&
            (sas_device->id == starget->id) &&
            (sas_device->channel == starget->channel))
                sas_device->starget = NULL;
 
+       if (sas_device) {
+               /*
+                * Corresponding get() is in _scsih_target_alloc()
+                */
+               sas_target_priv_data->sdev = NULL;
+               sas_device_put(sas_device);
+
+               sas_device_put(sas_device);
+       }
        spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
  out:
@@ -1255,14 +1365,14 @@ _scsih_target_destroy(struct scsi_target *starget)
 }
 
 /**
- * _scsih_slave_alloc - device add routine
+ * scsih_slave_alloc - device add routine
  * @sdev: scsi device struct
  *
  * Returns 0 if ok. Any other return is assumed to be an error and
  * the device is ignored.
  */
-static int
-_scsih_slave_alloc(struct scsi_device *sdev)
+int
+scsih_slave_alloc(struct scsi_device *sdev)
 {
        struct Scsi_Host *shost;
        struct MPT3SAS_ADAPTER *ioc;
@@ -1302,14 +1412,18 @@ _scsih_slave_alloc(struct scsi_device *sdev)
 
        if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) {
                spin_lock_irqsave(&ioc->sas_device_lock, flags);
-               sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
+               sas_device = __mpt3sas_get_sdev_by_addr(ioc,
                                        sas_target_priv_data->sas_address);
                if (sas_device && (sas_device->starget == NULL)) {
                        sdev_printk(KERN_INFO, sdev,
                        "%s : sas_device->starget set to starget @ %d\n",
-                               __func__, __LINE__);
+                            __func__, __LINE__);
                        sas_device->starget = starget;
                }
+
+               if (sas_device)
+                       sas_device_put(sas_device);
+
                spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
        }
 
@@ -1317,13 +1431,13 @@ _scsih_slave_alloc(struct scsi_device *sdev)
 }
 
 /**
- * _scsih_slave_destroy - device destroy routine
+ * scsih_slave_destroy - device destroy routine
  * @sdev: scsi device struct
  *
  * Returns nothing.
  */
-static void
-_scsih_slave_destroy(struct scsi_device *sdev)
+void
+scsih_slave_destroy(struct scsi_device *sdev)
 {
        struct MPT3SAS_TARGET *sas_target_priv_data;
        struct scsi_target *starget;
@@ -1344,10 +1458,13 @@ _scsih_slave_destroy(struct scsi_device *sdev)
 
        if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) {
                spin_lock_irqsave(&ioc->sas_device_lock, flags);
-               sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
-                  sas_target_priv_data->sas_address);
+               sas_device = __mpt3sas_get_sdev_from_target(ioc,
+                               sas_target_priv_data);
                if (sas_device && !sas_target_priv_data->num_luns)
                        sas_device->starget = NULL;
+
+               if (sas_device)
+                       sas_device_put(sas_device);
                spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
        }
 
@@ -1409,23 +1526,26 @@ _scsih_display_sata_capabilities(struct MPT3SAS_ADAPTER *ioc,
  */
 
 /**
- * _scsih_is_raid - return boolean indicating device is raid volume
+ * scsih_is_raid - return boolean indicating device is raid volume
  * @dev the device struct object
  */
-static int
-_scsih_is_raid(struct device *dev)
+int
+scsih_is_raid(struct device *dev)
 {
        struct scsi_device *sdev = to_scsi_device(dev);
+       struct MPT3SAS_ADAPTER *ioc = shost_priv(sdev->host);
 
+       if (ioc->is_warpdrive)
+               return 0;
        return (sdev->channel == RAID_CHANNEL) ? 1 : 0;
 }
 
 /**
- * _scsih_get_resync - get raid volume resync percent complete
+ * scsih_get_resync - get raid volume resync percent complete
  * @dev the device struct object
  */
-static void
-_scsih_get_resync(struct device *dev)
+void
+scsih_get_resync(struct device *dev)
 {
        struct scsi_device *sdev = to_scsi_device(dev);
        struct MPT3SAS_ADAPTER *ioc = shost_priv(sdev->host);
@@ -1439,6 +1559,9 @@ _scsih_get_resync(struct device *dev)
 
        percent_complete = 0;
        handle = 0;
+       if (ioc->is_warpdrive)
+               goto out;
+
        spin_lock_irqsave(&ioc->raid_device_lock, flags);
        raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id,
            sdev->channel);
@@ -1466,15 +1589,18 @@ _scsih_get_resync(struct device *dev)
                percent_complete = 0;
 
  out:
-       raid_set_resync(mpt3sas_raid_template, dev, percent_complete);
+       if (ioc->hba_mpi_version_belonged == MPI2_VERSION)
+               raid_set_resync(mpt2sas_raid_template, dev, percent_complete);
+       if (ioc->hba_mpi_version_belonged == MPI25_VERSION)
+               raid_set_resync(mpt3sas_raid_template, dev, percent_complete);
 }
 
 /**
- * _scsih_get_state - get raid volume level
+ * scsih_get_state - get raid volume level
  * @dev the device struct object
  */
-static void
-_scsih_get_state(struct device *dev)
+void
+scsih_get_state(struct device *dev)
 {
        struct scsi_device *sdev = to_scsi_device(dev);
        struct MPT3SAS_ADAPTER *ioc = shost_priv(sdev->host);
@@ -1524,7 +1650,10 @@ _scsih_get_state(struct device *dev)
                break;
        }
  out:
-       raid_set_state(mpt3sas_raid_template, dev, state);
+       if (ioc->hba_mpi_version_belonged == MPI2_VERSION)
+               raid_set_state(mpt2sas_raid_template, dev, state);
+       if (ioc->hba_mpi_version_belonged == MPI25_VERSION)
+               raid_set_state(mpt3sas_raid_template, dev, state);
 }
 
 /**
@@ -1533,7 +1662,8 @@ _scsih_get_state(struct device *dev)
  * @volume_type: volume type
  */
 static void
-_scsih_set_level(struct scsi_device *sdev, u8 volume_type)
+_scsih_set_level(struct MPT3SAS_ADAPTER *ioc,
+       struct scsi_device *sdev, u8 volume_type)
 {
        enum raid_level level = RAID_LEVEL_UNKNOWN;
 
@@ -1552,7 +1682,12 @@ _scsih_set_level(struct scsi_device *sdev, u8 volume_type)
                break;
        }
 
-       raid_set_level(mpt3sas_raid_template, &sdev->sdev_gendev, level);
+       if (ioc->hba_mpi_version_belonged == MPI2_VERSION)
+               raid_set_level(mpt2sas_raid_template,
+                              &sdev->sdev_gendev, level);
+       if (ioc->hba_mpi_version_belonged == MPI25_VERSION)
+               raid_set_level(mpt3sas_raid_template,
+                              &sdev->sdev_gendev, level);
 }
 
 
@@ -1622,8 +1757,6 @@ _scsih_get_volume_capabilities(struct MPT3SAS_ADAPTER *ioc,
        return 0;
 }
 
-
-
 /**
  * _scsih_enable_tlr - setting TLR flags
  * @ioc: per adapter object
@@ -1652,14 +1785,14 @@ _scsih_enable_tlr(struct MPT3SAS_ADAPTER *ioc, struct scsi_device *sdev)
 }
 
 /**
- * _scsih_slave_configure - device configure routine.
+ * scsih_slave_configure - device configure routine.
  * @sdev: scsi device struct
  *
  * Returns 0 if ok. Any other return is assumed to be an error and
  * the device is ignored.
  */
-static int
-_scsih_slave_configure(struct scsi_device *sdev)
+int
+scsih_slave_configure(struct scsi_device *sdev)
 {
        struct Scsi_Host *shost = sdev->host;
        struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
@@ -1686,7 +1819,7 @@ _scsih_slave_configure(struct scsi_device *sdev)
        if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME) {
 
                spin_lock_irqsave(&ioc->raid_device_lock, flags);
-               raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
+               raid_device = mpt3sas_raid_device_find_by_handle(ioc, handle);
                spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
                if (!raid_device) {
                        dfailprintk(ioc, pr_warn(MPT3SAS_FMT
@@ -1702,6 +1835,10 @@ _scsih_slave_configure(struct scsi_device *sdev)
                        return 1;
                }
 
+               /*
+                * WARPDRIVE: Initialize the required data for Direct IO
+                */
+               mpt3sas_init_warpdrive_properties(ioc, raid_device);
 
                /* RAID Queue Depth Support
                 * IS volume = underlying qdepth of drive type, either
@@ -1750,17 +1887,19 @@ _scsih_slave_configure(struct scsi_device *sdev)
                        break;
                }
 
-               sdev_printk(KERN_INFO, sdev,
-                       "%s: handle(0x%04x), wwid(0x%016llx), pd_count(%d), type(%s)\n",
-                        r_level, raid_device->handle,
-                        (unsigned long long)raid_device->wwid,
-                        raid_device->num_pds, ds);
-
+               if (!ioc->hide_ir_msg)
+                       sdev_printk(KERN_INFO, sdev,
+                          "%s: handle(0x%04x), wwid(0x%016llx),"
+                           " pd_count(%d), type(%s)\n",
+                           r_level, raid_device->handle,
+                           (unsigned long long)raid_device->wwid,
+                           raid_device->num_pds, ds);
 
-               _scsih_change_queue_depth(sdev, qdepth);
+               scsih_change_queue_depth(sdev, qdepth);
 
-/* raid transport support */
-               _scsih_set_level(sdev, raid_device->volume_type);
+               /* raid transport support */
+               if (!ioc->is_warpdrive)
+                       _scsih_set_level(ioc, sdev, raid_device->volume_type);
                return 0;
        }
 
@@ -1783,7 +1922,7 @@ _scsih_slave_configure(struct scsi_device *sdev)
        }
 
        spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
+       sas_device = __mpt3sas_get_sdev_by_addr(ioc,
           sas_device_priv_data->sas_target->sas_address);
        if (!sas_device) {
                spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
@@ -1823,13 +1962,14 @@ _scsih_slave_configure(struct scsi_device *sdev)
                     ds, sas_device->enclosure_level,
                     sas_device->connector_name);
 
+       sas_device_put(sas_device);
        spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
        if (!ssp_target)
                _scsih_display_sata_capabilities(ioc, handle, sdev);
 
 
-       _scsih_change_queue_depth(sdev, qdepth);
+       scsih_change_queue_depth(sdev, qdepth);
 
        if (ssp_target) {
                sas_read_port_mode_page(sdev);
@@ -1840,7 +1980,7 @@ _scsih_slave_configure(struct scsi_device *sdev)
 }
 
 /**
- * _scsih_bios_param - fetch head, sector, cylinder info for a disk
+ * scsih_bios_param - fetch head, sector, cylinder info for a disk
  * @sdev: scsi device struct
  * @bdev: pointer to block device context
  * @capacity: device size (in 512 byte sectors)
@@ -1851,8 +1991,8 @@ _scsih_slave_configure(struct scsi_device *sdev)
  *
  * Return nothing.
  */
-static int
-_scsih_bios_param(struct scsi_device *sdev, struct block_device *bdev,
+int
+scsih_bios_param(struct scsi_device *sdev, struct block_device *bdev,
        sector_t capacity, int params[])
 {
        int             heads;
@@ -2209,7 +2349,10 @@ _scsih_tm_display_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd)
 
        if (!priv_target)
                return;
-       device_str = "volume";
+       if (ioc->hide_ir_msg)
+               device_str = "WarpDrive";
+       else
+               device_str = "volume";
 
        scsi_print_command(scmd);
        if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) {
@@ -2219,8 +2362,7 @@ _scsih_tm_display_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd)
                    device_str, (unsigned long long)priv_target->sas_address);
        } else {
                spin_lock_irqsave(&ioc->sas_device_lock, flags);
-               sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
-                   priv_target->sas_address);
+               sas_device = __mpt3sas_get_sdev_from_target(ioc, priv_target);
                if (sas_device) {
                        if (priv_target->flags &
                            MPT_TARGET_FLAGS_RAID_COMPONENT) {
@@ -2246,19 +2388,21 @@ _scsih_tm_display_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd)
                                "enclosure level(0x%04x),connector name(%s)\n",
                                 sas_device->enclosure_level,
                                 sas_device->connector_name);
+
+                       sas_device_put(sas_device);
                }
                spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
        }
 }
 
 /**
- * _scsih_abort - eh threads main abort routine
+ * scsih_abort - eh threads main abort routine
  * @scmd: pointer to scsi command object
  *
  * Returns SUCCESS if command aborted else FAILED
  */
-static int
-_scsih_abort(struct scsi_cmnd *scmd)
+int
+scsih_abort(struct scsi_cmnd *scmd)
 {
        struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
        struct MPT3SAS_DEVICE *sas_device_priv_data;
@@ -2311,21 +2455,23 @@ _scsih_abort(struct scsi_cmnd *scmd)
 }
 
 /**
- * _scsih_dev_reset - eh threads main device reset routine
+ * scsih_dev_reset - eh threads main device reset routine
  * @scmd: pointer to scsi command object
  *
  * Returns SUCCESS if command aborted else FAILED
  */
-static int
-_scsih_dev_reset(struct scsi_cmnd *scmd)
+int
+scsih_dev_reset(struct scsi_cmnd *scmd)
 {
        struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
        struct MPT3SAS_DEVICE *sas_device_priv_data;
-       struct _sas_device *sas_device;
-       unsigned long flags;
+       struct _sas_device *sas_device = NULL;
        u16     handle;
        int r;
 
+       struct scsi_target *starget = scmd->device->sdev_target;
+       struct MPT3SAS_TARGET *target_priv_data = starget->hostdata;
+
        sdev_printk(KERN_INFO, scmd->device,
                "attempting device reset! scmd(%p)\n", scmd);
        _scsih_tm_display_info(ioc, scmd);
@@ -2344,12 +2490,10 @@ _scsih_dev_reset(struct scsi_cmnd *scmd)
        handle = 0;
        if (sas_device_priv_data->sas_target->flags &
            MPT_TARGET_FLAGS_RAID_COMPONENT) {
-               spin_lock_irqsave(&ioc->sas_device_lock, flags);
-               sas_device = _scsih_sas_device_find_by_handle(ioc,
-                  sas_device_priv_data->sas_target->handle);
+               sas_device = mpt3sas_get_sdev_from_target(ioc,
+                               target_priv_data);
                if (sas_device)
                        handle = sas_device->volume_handle;
-               spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
        } else
                handle = sas_device_priv_data->sas_target->handle;
 
@@ -2366,25 +2510,29 @@ _scsih_dev_reset(struct scsi_cmnd *scmd)
  out:
        sdev_printk(KERN_INFO, scmd->device, "device reset: %s scmd(%p)\n",
            ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
+
+       if (sas_device)
+               sas_device_put(sas_device);
+
        return r;
 }
 
 /**
- * _scsih_target_reset - eh threads main target reset routine
+ * scsih_target_reset - eh threads main target reset routine
  * @scmd: pointer to scsi command object
  *
  * Returns SUCCESS if command aborted else FAILED
  */
-static int
-_scsih_target_reset(struct scsi_cmnd *scmd)
+int
+scsih_target_reset(struct scsi_cmnd *scmd)
 {
        struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
        struct MPT3SAS_DEVICE *sas_device_priv_data;
-       struct _sas_device *sas_device;
-       unsigned long flags;
+       struct _sas_device *sas_device = NULL;
        u16     handle;
        int r;
        struct scsi_target *starget = scmd->device->sdev_target;
+       struct MPT3SAS_TARGET *target_priv_data = starget->hostdata;
 
        starget_printk(KERN_INFO, starget, "attempting target reset! scmd(%p)\n",
                scmd);
@@ -2404,12 +2552,10 @@ _scsih_target_reset(struct scsi_cmnd *scmd)
        handle = 0;
        if (sas_device_priv_data->sas_target->flags &
            MPT_TARGET_FLAGS_RAID_COMPONENT) {
-               spin_lock_irqsave(&ioc->sas_device_lock, flags);
-               sas_device = _scsih_sas_device_find_by_handle(ioc,
-                  sas_device_priv_data->sas_target->handle);
+               sas_device = mpt3sas_get_sdev_from_target(ioc,
+                               target_priv_data);
                if (sas_device)
                        handle = sas_device->volume_handle;
-               spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
        } else
                handle = sas_device_priv_data->sas_target->handle;
 
@@ -2426,18 +2572,22 @@ _scsih_target_reset(struct scsi_cmnd *scmd)
  out:
        starget_printk(KERN_INFO, starget, "target reset: %s scmd(%p)\n",
            ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
+
+       if (sas_device)
+               sas_device_put(sas_device);
+
        return r;
 }
 
 
 /**
- * _scsih_host_reset - eh threads main host reset routine
+ * scsih_host_reset - eh threads main host reset routine
  * @scmd: pointer to scsi command object
  *
  * Returns SUCCESS if command aborted else FAILED
  */
-static int
-_scsih_host_reset(struct scsi_cmnd *scmd)
+int
+scsih_host_reset(struct scsi_cmnd *scmd)
 {
        struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
        int r, retval;
@@ -2483,32 +2633,36 @@ _scsih_fw_event_add(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event)
                return;
 
        spin_lock_irqsave(&ioc->fw_event_lock, flags);
+       fw_event_work_get(fw_event);
        INIT_LIST_HEAD(&fw_event->list);
        list_add_tail(&fw_event->list, &ioc->fw_event_list);
        INIT_WORK(&fw_event->work, _firmware_event_work);
+       fw_event_work_get(fw_event);
        queue_work(ioc->firmware_event_thread, &fw_event->work);
        spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
 }
 
 /**
- * _scsih_fw_event_free - delete fw_event
+ * _scsih_fw_event_del_from_list - delete fw_event from the list
  * @ioc: per adapter object
  * @fw_event: object describing the event
  * Context: This function will acquire ioc->fw_event_lock.
  *
- * This removes firmware event object from link list, frees associated memory.
+ * If the fw_event is on the fw_event_list, remove it and do a put.
  *
  * Return nothing.
  */
 static void
-_scsih_fw_event_free(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work
+_scsih_fw_event_del_from_list(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work
        *fw_event)
 {
        unsigned long flags;
 
        spin_lock_irqsave(&ioc->fw_event_lock, flags);
-       list_del(&fw_event->list);
-       kfree(fw_event);
+       if (!list_empty(&fw_event->list)) {
+               list_del_init(&fw_event->list);
+               fw_event_work_put(fw_event);
+       }
        spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
 }
 
@@ -2525,17 +2679,19 @@ mpt3sas_send_trigger_data_event(struct MPT3SAS_ADAPTER *ioc,
        struct SL_WH_TRIGGERS_EVENT_DATA_T *event_data)
 {
        struct fw_event_work *fw_event;
+       u16 sz;
 
        if (ioc->is_driver_loading)
                return;
-       fw_event = kzalloc(sizeof(*fw_event) + sizeof(*event_data),
-                          GFP_ATOMIC);
+       sz = sizeof(*event_data);
+       fw_event = alloc_fw_event_work(sz);
        if (!fw_event)
                return;
        fw_event->event = MPT3SAS_PROCESS_TRIGGER_DIAG;
        fw_event->ioc = ioc;
        memcpy(fw_event->event_data, event_data, sizeof(*event_data));
        _scsih_fw_event_add(ioc, fw_event);
+       fw_event_work_put(fw_event);
 }
 
 /**
@@ -2551,12 +2707,13 @@ _scsih_error_recovery_delete_devices(struct MPT3SAS_ADAPTER *ioc)
 
        if (ioc->is_driver_loading)
                return;
-       fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
+       fw_event = alloc_fw_event_work(0);
        if (!fw_event)
                return;
        fw_event->event = MPT3SAS_REMOVE_UNRESPONDING_DEVICES;
        fw_event->ioc = ioc;
        _scsih_fw_event_add(ioc, fw_event);
+       fw_event_work_put(fw_event);
 }
 
 /**
@@ -2570,12 +2727,29 @@ mpt3sas_port_enable_complete(struct MPT3SAS_ADAPTER *ioc)
 {
        struct fw_event_work *fw_event;
 
-       fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
+       fw_event = alloc_fw_event_work(0);
        if (!fw_event)
                return;
        fw_event->event = MPT3SAS_PORT_ENABLE_COMPLETE;
        fw_event->ioc = ioc;
        _scsih_fw_event_add(ioc, fw_event);
+       fw_event_work_put(fw_event);
+}
+
+static struct fw_event_work *dequeue_next_fw_event(struct MPT3SAS_ADAPTER *ioc)
+{
+       unsigned long flags;
+       struct fw_event_work *fw_event = NULL;
+
+       spin_lock_irqsave(&ioc->fw_event_lock, flags);
+       if (!list_empty(&ioc->fw_event_list)) {
+               fw_event = list_first_entry(&ioc->fw_event_list,
+                               struct fw_event_work, list);
+               list_del_init(&fw_event->list);
+       }
+       spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
+
+       return fw_event;
 }
 
 /**
@@ -2590,17 +2764,25 @@ mpt3sas_port_enable_complete(struct MPT3SAS_ADAPTER *ioc)
 static void
 _scsih_fw_event_cleanup_queue(struct MPT3SAS_ADAPTER *ioc)
 {
-       struct fw_event_work *fw_event, *next;
+       struct fw_event_work *fw_event;
 
        if (list_empty(&ioc->fw_event_list) ||
             !ioc->firmware_event_thread || in_interrupt())
                return;
 
-       list_for_each_entry_safe(fw_event, next, &ioc->fw_event_list, list) {
-               if (cancel_delayed_work_sync(&fw_event->delayed_work)) {
-                       _scsih_fw_event_free(ioc, fw_event);
-                       continue;
-               }
+       while ((fw_event = dequeue_next_fw_event(ioc))) {
+               /*
+                * Wait on the fw_event to complete. If this returns 1, then
+                * the event was never executed, and we need a put for the
+                * reference the delayed_work had on the fw_event.
+                *
+                * If it did execute, we wait for it to finish, and the put will
+                * happen from _firmware_event_work()
+                */
+               if (cancel_delayed_work_sync(&fw_event->delayed_work))
+                       fw_event_work_put(fw_event);
+
+               fw_event_work_put(fw_event);
        }
 }
 
@@ -2763,7 +2945,7 @@ _scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 handle)
        struct scsi_device *sdev;
        struct _sas_device *sas_device;
 
-       sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
+       sas_device = mpt3sas_get_sdev_by_handle(ioc, handle);
        if (!sas_device)
                return;
 
@@ -2779,6 +2961,8 @@ _scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 handle)
                        continue;
                _scsih_internal_device_block(sdev, sas_device_priv_data);
        }
+
+       sas_device_put(sas_device);
 }
 
 /**
@@ -2807,12 +2991,13 @@ _scsih_block_io_to_children_attached_to_ex(struct MPT3SAS_ADAPTER *ioc,
                if (mpt3sas_port->remote_identify.device_type ==
                    SAS_END_DEVICE) {
                        spin_lock_irqsave(&ioc->sas_device_lock, flags);
-                       sas_device =
-                           mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
-                          mpt3sas_port->remote_identify.sas_address);
-                       if (sas_device)
+                       sas_device = __mpt3sas_get_sdev_by_addr(ioc,
+                           mpt3sas_port->remote_identify.sas_address);
+                       if (sas_device) {
                                set_bit(sas_device->handle,
-                                   ioc->blocking_handles);
+                                               ioc->blocking_handles);
+                               sas_device_put(sas_device);
+                       }
                        spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
                }
        }
@@ -2880,7 +3065,7 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 {
        Mpi2SCSITaskManagementRequest_t *mpi_request;
        u16 smid;
-       struct _sas_device *sas_device;
+       struct _sas_device *sas_device = NULL;
        struct MPT3SAS_TARGET *sas_target_priv_data = NULL;
        u64 sas_address = 0;
        unsigned long flags;
@@ -2913,7 +3098,7 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle)
                return;
 
        spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
+       sas_device = __mpt3sas_get_sdev_by_handle(ioc, handle);
        if (sas_device && sas_device->starget &&
            sas_device->starget->hostdata) {
                sas_target_priv_data = sas_device->starget->hostdata;
@@ -2947,14 +3132,14 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle)
        if (!smid) {
                delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC);
                if (!delayed_tr)
-                       return;
+                       goto out;
                INIT_LIST_HEAD(&delayed_tr->list);
                delayed_tr->handle = handle;
                list_add_tail(&delayed_tr->list, &ioc->delayed_tr_list);
                dewtprintk(ioc, pr_info(MPT3SAS_FMT
                    "DELAYED:tr:handle(0x%04x), (open)\n",
                    ioc->name, handle));
-               return;
+               goto out;
        }
 
        dewtprintk(ioc, pr_info(MPT3SAS_FMT
@@ -2968,6 +3153,10 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle)
        mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
        mpt3sas_base_put_smid_hi_priority(ioc, smid);
        mpt3sas_trigger_master(ioc, MASTER_TRIGGER_DEVICE_REMOVAL);
+
+out:
+       if (sas_device)
+               sas_device_put(sas_device);
 }
 
 /**
@@ -3337,7 +3526,7 @@ _scsih_set_volume_delete_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle)
        unsigned long flags;
 
        spin_lock_irqsave(&ioc->raid_device_lock, flags);
-       raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
+       raid_device = mpt3sas_raid_device_find_by_handle(ioc, handle);
        if (raid_device && raid_device->starget &&
            raid_device->starget->hostdata) {
                sas_target_priv_data =
@@ -3398,6 +3587,9 @@ _scsih_check_ir_config_unhide_events(struct MPT3SAS_ADAPTER *ioc,
        a = 0;
        b = 0;
 
+       if (ioc->is_warpdrive)
+               return;
+
        /* Volume Resets for Deleted or Removed */
        element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
        for (i = 0; i < event_data->NumElements; i++, element++) {
@@ -3634,8 +3826,9 @@ _scsih_eedp_error_handling(struct scsi_cmnd *scmd, u16 ioc_status)
 }
 
 
+
 /**
- * _scsih_qcmd - main scsi request entry point
+ * scsih_qcmd - main scsi request entry point
  * @scmd: pointer to scsi command object
  * @done: function pointer to be invoked on completion
  *
@@ -3645,21 +3838,20 @@ _scsih_eedp_error_handling(struct scsi_cmnd *scmd, u16 ioc_status)
  * SCSI_MLQUEUE_DEVICE_BUSY if the device queue is full, or
  * SCSI_MLQUEUE_HOST_BUSY if the entire host queue is full
  */
-static int
-_scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
+int
+scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
 {
        struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
        struct MPT3SAS_DEVICE *sas_device_priv_data;
        struct MPT3SAS_TARGET *sas_target_priv_data;
+       struct _raid_device *raid_device;
        Mpi2SCSIIORequest_t *mpi_request;
        u32 mpi_control;
        u16 smid;
        u16 handle;
 
-#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
        if (ioc->logging_level & MPT_DEBUG_SCSI)
                scsi_print_command(scmd);
-#endif
 
        sas_device_priv_data = scmd->device->hostdata;
        if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
@@ -3709,7 +3901,11 @@ _scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
        /* set tags */
        mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
 
-       if ((sas_device_priv_data->flags & MPT_DEVICE_TLR_ON) &&
+       /* Make sure Device is not raid volume.
+        * 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)
                mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON;
 
@@ -3752,13 +3948,19 @@ _scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
        } else
                ioc->build_zero_len_sge(ioc, &mpi_request->SGL);
 
+       raid_device = sas_target_priv_data->raid_device;
+       if (raid_device && raid_device->direct_io_enabled)
+               mpt3sas_setup_direct_io(ioc, scmd, raid_device, mpi_request,
+                   smid);
+
        if (likely(mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST)) {
                if (sas_target_priv_data->flags & MPT_TARGET_FASTPATH_IO) {
                        mpi_request->IoFlags = cpu_to_le16(scmd->cmd_len |
                            MPI25_SCSIIO_IOFLAGS_FAST_PATH);
                        mpt3sas_base_put_smid_fast_path(ioc, smid, handle);
                } else
-                       mpt3sas_base_put_smid_scsi_io(ioc, smid, handle);
+                       mpt3sas_base_put_smid_scsi_io(ioc, smid,
+                           le16_to_cpu(mpi_request->DevHandle));
        } else
                mpt3sas_base_put_smid_default(ioc, smid);
        return 0;
@@ -3790,7 +3992,6 @@ _scsih_normalize_sense(char *sense_buffer, struct sense_info *data)
        }
 }
 
-#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
 /**
  * _scsih_scsi_ioc_info - translated non-succesfull SCSI_IO request
  * @ioc: per adapter object
@@ -3818,14 +4019,16 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
        char *desc_scsi_state = ioc->tmp_string;
        u32 log_info = le32_to_cpu(mpi_reply->IOCLogInfo);
        struct _sas_device *sas_device = NULL;
-       unsigned long flags;
        struct scsi_target *starget = scmd->device->sdev_target;
        struct MPT3SAS_TARGET *priv_target = starget->hostdata;
        char *device_str = NULL;
 
        if (!priv_target)
                return;
-       device_str = "volume";
+       if (ioc->hide_ir_msg)
+               device_str = "WarpDrive";
+       else
+               device_str = "volume";
 
        if (log_info == 0x31170000)
                return;
@@ -3946,9 +4149,7 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
                pr_warn(MPT3SAS_FMT "\t%s wwid(0x%016llx)\n", ioc->name,
                    device_str, (unsigned long long)priv_target->sas_address);
        } else {
-               spin_lock_irqsave(&ioc->sas_device_lock, flags);
-               sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
-                   priv_target->sas_address);
+               sas_device = mpt3sas_get_sdev_from_target(ioc, priv_target);
                if (sas_device) {
                        pr_warn(MPT3SAS_FMT
                                "\tsas_address(0x%016llx), phy(%d)\n",
@@ -3967,8 +4168,9 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
                                  " connector name( %s)\n", ioc->name,
                                  sas_device->enclosure_level,
                                  sas_device->connector_name);
+
+                       sas_device_put(sas_device);
                }
-               spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
        }
 
        pr_warn(MPT3SAS_FMT
@@ -4003,7 +4205,6 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
                _scsih_response_code(ioc, response_bytes[0]);
        }
 }
-#endif
 
 /**
  * _scsih_turn_on_pfa_led - illuminate PFA LED
@@ -4020,7 +4221,7 @@ _scsih_turn_on_pfa_led(struct MPT3SAS_ADAPTER *ioc, u16 handle)
        Mpi2SepRequest_t mpi_request;
        struct _sas_device *sas_device;
 
-       sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
+       sas_device = mpt3sas_get_sdev_by_handle(ioc, handle);
        if (!sas_device)
                return;
 
@@ -4035,7 +4236,7 @@ _scsih_turn_on_pfa_led(struct MPT3SAS_ADAPTER *ioc, u16 handle)
            &mpi_request)) != 0) {
                pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ioc->name,
                __FILE__, __LINE__, __func__);
-               return;
+               goto out;
        }
        sas_device->pfa_led_on = 1;
 
@@ -4044,9 +4245,12 @@ _scsih_turn_on_pfa_led(struct MPT3SAS_ADAPTER *ioc, u16 handle)
                        "enclosure_processor: ioc_status (0x%04x), loginfo(0x%08x)\n",
                        ioc->name, le16_to_cpu(mpi_reply.IOCStatus),
                    le32_to_cpu(mpi_reply.IOCLogInfo)));
-               return;
+               goto out;
        }
+out:
+       sas_device_put(sas_device);
 }
+
 /**
  * _scsih_turn_off_pfa_led - turn off Fault LED
  * @ioc: per adapter object
@@ -4085,6 +4289,7 @@ _scsih_turn_off_pfa_led(struct MPT3SAS_ADAPTER *ioc,
                return;
        }
 }
+
 /**
  * _scsih_send_event_to_turn_on_pfa_led - fire delayed event
  * @ioc: per adapter object
@@ -4098,13 +4303,14 @@ _scsih_send_event_to_turn_on_pfa_led(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 {
        struct fw_event_work *fw_event;
 
-       fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
+       fw_event = alloc_fw_event_work(0);
        if (!fw_event)
                return;
        fw_event->event = MPT3SAS_TURN_ON_PFA_LED;
        fw_event->device_handle = handle;
        fw_event->ioc = ioc;
        _scsih_fw_event_add(ioc, fw_event);
+       fw_event_work_put(fw_event);
 }
 
 /**
@@ -4128,19 +4334,17 @@ _scsih_smart_predicted_fault(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 
        /* only handle non-raid devices */
        spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
-       if (!sas_device) {
-               spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-               return;
-       }
+       sas_device = __mpt3sas_get_sdev_by_handle(ioc, handle);
+       if (!sas_device)
+               goto out_unlock;
+
        starget = sas_device->starget;
        sas_target_priv_data = starget->hostdata;
 
        if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_RAID_COMPONENT) ||
-          ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME))) {
-               spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-               return;
-       }
+          ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)))
+               goto out_unlock;
+
        if (sas_device->enclosure_handle != 0)
                starget_printk(KERN_INFO, starget, "predicted fault, "
                        "enclosure logical id(0x%016llx), slot(%d)\n",
@@ -4163,7 +4367,7 @@ _scsih_smart_predicted_fault(struct MPT3SAS_ADAPTER *ioc, u16 handle)
        if (!event_reply) {
                pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
                    ioc->name, __FILE__, __LINE__, __func__);
-               return;
+               goto out;
        }
 
        event_reply->Function = MPI2_FUNCTION_EVENT_NOTIFICATION;
@@ -4180,6 +4384,14 @@ _scsih_smart_predicted_fault(struct MPT3SAS_ADAPTER *ioc, u16 handle)
        event_data->SASAddress = cpu_to_le64(sas_target_priv_data->sas_address);
        mpt3sas_ctl_add_to_event_log(ioc, event_reply);
        kfree(event_reply);
+out:
+       if (sas_device)
+               sas_device_put(sas_device);
+       return;
+
+out_unlock:
+       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+       goto out;
 }
 
 /**
@@ -4207,6 +4419,7 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
        u32 log_info;
        struct MPT3SAS_DEVICE *sas_device_priv_data;
        u32 response_code = 0;
+       unsigned long flags;
 
        mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply);
        scmd = _scsih_scsi_lookup_get_clear(ioc, smid);
@@ -4228,6 +4441,24 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
        }
        ioc_status = le16_to_cpu(mpi_reply->IOCStatus);
 
+       /*
+        * WARPDRIVE: If direct_io is set then it is directIO,
+        * the failed direct I/O should be redirected to volume
+        */
+       if (mpt3sas_scsi_direct_io_get(ioc, smid) &&
+            ((ioc_status & MPI2_IOCSTATUS_MASK)
+             != MPI2_IOCSTATUS_SCSI_TASK_TERMINATED)) {
+               spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
+               ioc->scsi_lookup[smid - 1].scmd = scmd;
+               spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
+               mpt3sas_scsi_direct_io_set(ioc, smid, 0);
+               memcpy(mpi_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len);
+               mpi_request->DevHandle =
+                   cpu_to_le16(sas_device_priv_data->sas_target->handle);
+               mpt3sas_base_put_smid_scsi_io(ioc, smid,
+                   sas_device_priv_data->sas_target->handle);
+               return 0;
+       }
        /* turning off TLR */
        scsi_state = mpi_reply->SCSIState;
        if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID)
@@ -4235,10 +4466,13 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
                    le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF;
        if (!sas_device_priv_data->tlr_snoop_check) {
                sas_device_priv_data->tlr_snoop_check++;
-               if ((sas_device_priv_data->flags & MPT_DEVICE_TLR_ON) &&
-                   response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME)
-                       sas_device_priv_data->flags &=
-                           ~MPT_DEVICE_TLR_ON;
+               if (!ioc->is_warpdrive &&
+                   !scsih_is_raid(&scmd->device->sdev_gendev) &&
+                   sas_is_tlr_enabled(scmd->device) &&
+                   response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) {
+                       sas_disable_tlr(scmd->device);
+                       sdev_printk(KERN_INFO, scmd->device, "TLR disabled\n");
+               }
        }
 
        xfer_cnt = le32_to_cpu(mpi_reply->TransferCount);
@@ -4271,13 +4505,11 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
                            le16_to_cpu(mpi_reply->DevHandle));
                mpt3sas_trigger_scsi(ioc, data.skey, data.asc, data.ascq);
 
-#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
                if (!(ioc->logging_level & MPT_DEBUG_REPLY) &&
                     ((scmd->sense_buffer[2] == UNIT_ATTENTION) ||
                     (scmd->sense_buffer[2] == MEDIUM_ERROR) ||
                     (scmd->sense_buffer[2] == HARDWARE_ERROR)))
                        _scsih_scsi_ioc_info(ioc, scmd, mpi_reply, smid);
-#endif
        }
        switch (ioc_status) {
        case MPI2_IOCSTATUS_BUSY:
@@ -4384,10 +4616,8 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
 
        }
 
-#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
        if (scmd->result && (ioc->logging_level & MPT_DEBUG_REPLY))
                _scsih_scsi_ioc_info(ioc , scmd, mpi_reply, smid);
-#endif
 
  out:
 
@@ -4933,13 +5163,11 @@ _scsih_check_device(struct MPT3SAS_ADAPTER *ioc,
 
        spin_lock_irqsave(&ioc->sas_device_lock, flags);
        sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
-       sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
+       sas_device = __mpt3sas_get_sdev_by_addr(ioc,
            sas_address);
 
-       if (!sas_device) {
-               spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-               return;
-       }
+       if (!sas_device)
+               goto out_unlock;
 
        if (unlikely(sas_device->handle != handle)) {
                starget = sas_device->starget;
@@ -4967,20 +5195,25 @@ _scsih_check_device(struct MPT3SAS_ADAPTER *ioc,
                pr_err(MPT3SAS_FMT
                        "device is not present handle(0x%04x), flags!!!\n",
                        ioc->name, handle);
-               spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-               return;
+               goto out_unlock;
        }
 
        /* check if there were any issues with discovery */
        if (_scsih_check_access_status(ioc, sas_address, handle,
-           sas_device_pg0.AccessStatus)) {
-               spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-               return;
-       }
+           sas_device_pg0.AccessStatus))
+               goto out_unlock;
 
        spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
        _scsih_ublock_io_device(ioc, sas_address);
 
+       if (sas_device)
+               sas_device_put(sas_device);
+       return;
+
+out_unlock:
+       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+       if (sas_device)
+               sas_device_put(sas_device);
 }
 
 /**
@@ -5005,7 +5238,6 @@ _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phy_num,
        u32 ioc_status;
        u64 sas_address;
        u32 device_info;
-       unsigned long flags;
 
        if ((mpt3sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
            MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
@@ -5041,13 +5273,12 @@ _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phy_num,
            sas_device_pg0.AccessStatus))
                return -1;
 
-       spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
-           sas_address);
-       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-
-       if (sas_device)
+       sas_device = mpt3sas_get_sdev_by_addr(ioc,
+                                       sas_address);
+       if (sas_device) {
+               sas_device_put(sas_device);
                return -1;
+       }
 
        sas_device = kzalloc(sizeof(struct _sas_device),
            GFP_KERNEL);
@@ -5057,6 +5288,7 @@ _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phy_num,
                return 0;
        }
 
+       kref_init(&sas_device->refcount);
        sas_device->handle = handle;
        if (_scsih_get_sas_address(ioc,
            le16_to_cpu(sas_device_pg0.ParentDevHandle),
@@ -5098,6 +5330,7 @@ _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phy_num,
        else
                _scsih_sas_device_add(ioc, sas_device);
 
+       sas_device_put(sas_device);
        return 0;
 }
 
@@ -5144,7 +5377,9 @@ _scsih_remove_device(struct MPT3SAS_ADAPTER *ioc,
                sas_target_priv_data->handle =
                     MPT3SAS_INVALID_DEVICE_HANDLE;
        }
-       mpt3sas_transport_port_remove(ioc,
+
+       if (!ioc->hide_drives)
+               mpt3sas_transport_port_remove(ioc,
                    sas_device->sas_address,
                    sas_device->sas_address_parent);
 
@@ -5180,11 +5415,8 @@ _scsih_remove_device(struct MPT3SAS_ADAPTER *ioc,
                    "%s: exit: enclosure level(0x%04x), connector name(%s)\n",
                    ioc->name, __func__, sas_device->enclosure_level,
                    sas_device->connector_name));
-
-       kfree(sas_device);
 }
 
-#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
 /**
  * _scsih_sas_topology_change_event_debug - debug for topology event
  * @ioc: per adapter object
@@ -5262,7 +5494,6 @@ _scsih_sas_topology_change_event_debug(struct MPT3SAS_ADAPTER *ioc,
 
        }
 }
-#endif
 
 /**
  * _scsih_sas_topology_change_event - handle topology changes
@@ -5287,10 +5518,8 @@ _scsih_sas_topology_change_event(struct MPT3SAS_ADAPTER *ioc,
                (Mpi2EventDataSasTopologyChangeList_t *)
                fw_event->event_data;
 
-#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
        if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
                _scsih_sas_topology_change_event_debug(ioc, event_data);
-#endif
 
        if (ioc->shost_recovery || ioc->remove_host || ioc->pci_error_recovery)
                return 0;
@@ -5396,7 +5625,6 @@ _scsih_sas_topology_change_event(struct MPT3SAS_ADAPTER *ioc,
        return 0;
 }
 
-#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
 /**
  * _scsih_sas_device_status_change_event_debug - debug for device event
  * @event_data: event data payload
@@ -5464,7 +5692,6 @@ _scsih_sas_device_status_change_event_debug(struct MPT3SAS_ADAPTER *ioc,
                    event_data->ASC, event_data->ASCQ);
        pr_info("\n");
 }
-#endif
 
 /**
  * _scsih_sas_device_status_change_event - handle device status change
@@ -5486,11 +5713,9 @@ _scsih_sas_device_status_change_event(struct MPT3SAS_ADAPTER *ioc,
                (Mpi2EventDataSasDeviceStatusChange_t *)
                fw_event->event_data;
 
-#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
        if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
                _scsih_sas_device_status_change_event_debug(ioc,
                     event_data);
-#endif
 
        /* In MPI Revision K (0xC), the internal device reset complete was
         * implemented, so avoid setting tm_busy flag for older firmware.
@@ -5506,29 +5731,30 @@ _scsih_sas_device_status_change_event(struct MPT3SAS_ADAPTER *ioc,
 
        spin_lock_irqsave(&ioc->sas_device_lock, flags);
        sas_address = le64_to_cpu(event_data->SASAddress);
-       sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
+       sas_device = __mpt3sas_get_sdev_by_addr(ioc,
            sas_address);
 
-       if (!sas_device || !sas_device->starget) {
-               spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-               return;
-       }
+       if (!sas_device || !sas_device->starget)
+               goto out;
 
        target_priv_data = sas_device->starget->hostdata;
-       if (!target_priv_data) {
-               spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-               return;
-       }
+       if (!target_priv_data)
+               goto out;
 
        if (event_data->ReasonCode ==
            MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET)
                target_priv_data->tm_busy = 1;
        else
                target_priv_data->tm_busy = 0;
+
+out:
+       if (sas_device)
+               sas_device_put(sas_device);
+
        spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+
 }
 
-#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
 /**
  * _scsih_sas_enclosure_dev_status_change_event_debug - debug for enclosure
  * event
@@ -5563,7 +5789,6 @@ _scsih_sas_enclosure_dev_status_change_event_debug(struct MPT3SAS_ADAPTER *ioc,
            (unsigned long long)le64_to_cpu(event_data->EnclosureLogicalID),
            le16_to_cpu(event_data->StartSlot));
 }
-#endif
 
 /**
  * _scsih_sas_enclosure_dev_status_change_event - handle enclosure events
@@ -5577,12 +5802,10 @@ static void
 _scsih_sas_enclosure_dev_status_change_event(struct MPT3SAS_ADAPTER *ioc,
        struct fw_event_work *fw_event)
 {
-#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
        if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
                _scsih_sas_enclosure_dev_status_change_event_debug(ioc,
                     (Mpi2EventDataSasEnclDevStatusChange_t *)
                     fw_event->event_data);
-#endif
 }
 
 /**
@@ -5762,17 +5985,15 @@ _scsih_sas_discovery_event(struct MPT3SAS_ADAPTER *ioc,
        Mpi2EventDataSasDiscovery_t *event_data =
                (Mpi2EventDataSasDiscovery_t *) fw_event->event_data;
 
-#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
        if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) {
                pr_info(MPT3SAS_FMT "discovery event: (%s)", ioc->name,
                    (event_data->ReasonCode == MPI2_EVENT_SAS_DISC_RC_STARTED) ?
                    "start" : "stop");
-       if (event_data->DiscoveryStatus)
-               pr_info("discovery_status(0x%08x)",
-                   le32_to_cpu(event_data->DiscoveryStatus));
-       pr_info("\n");
+               if (event_data->DiscoveryStatus)
+                       pr_info("discovery_status(0x%08x)",
+                           le32_to_cpu(event_data->DiscoveryStatus));
+               pr_info("\n");
        }
-#endif
 
        if (event_data->ReasonCode == MPI2_EVENT_SAS_DISC_RC_STARTED &&
            !ioc->sas_hba.num_phys) {
@@ -5804,6 +6025,8 @@ _scsih_ir_fastpath(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phys_disk_num)
        u16 ioc_status;
        u32 log_info;
 
+       if (ioc->hba_mpi_version_belonged == MPI2_VERSION)
+               return rc;
 
        mutex_lock(&ioc->scsih_cmds.mutex);
 
@@ -5971,7 +6194,7 @@ _scsih_sas_volume_delete(struct MPT3SAS_ADAPTER *ioc, u16 handle)
        struct scsi_target *starget = NULL;
 
        spin_lock_irqsave(&ioc->raid_device_lock, flags);
-       raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
+       raid_device = mpt3sas_raid_device_find_by_handle(ioc, handle);
        if (raid_device) {
                if (raid_device->starget) {
                        starget = raid_device->starget;
@@ -6008,7 +6231,7 @@ _scsih_sas_pd_expose(struct MPT3SAS_ADAPTER *ioc,
        u16 handle = le16_to_cpu(element->PhysDiskDevHandle);
 
        spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
+       sas_device = __mpt3sas_get_sdev_by_handle(ioc, handle);
        if (sas_device) {
                sas_device->volume_handle = 0;
                sas_device->volume_wwid = 0;
@@ -6027,6 +6250,8 @@ _scsih_sas_pd_expose(struct MPT3SAS_ADAPTER *ioc,
        /* exposing raid component */
        if (starget)
                starget_for_each_device(starget, NULL, _scsih_reprobe_lun);
+
+       sas_device_put(sas_device);
 }
 
 /**
@@ -6055,7 +6280,7 @@ _scsih_sas_pd_hide(struct MPT3SAS_ADAPTER *ioc,
                    &volume_wwid);
 
        spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
+       sas_device = __mpt3sas_get_sdev_by_handle(ioc, handle);
        if (sas_device) {
                set_bit(handle, ioc->pd_handles);
                if (sas_device->starget && sas_device->starget->hostdata) {
@@ -6073,8 +6298,11 @@ _scsih_sas_pd_hide(struct MPT3SAS_ADAPTER *ioc,
 
        /* hiding raid component */
        _scsih_ir_fastpath(ioc, handle, element->PhysDiskNum);
+
        if (starget)
                starget_for_each_device(starget, (void *)1, _scsih_reprobe_lun);
+
+       sas_device_put(sas_device);
 }
 
 /**
@@ -6107,7 +6335,6 @@ _scsih_sas_pd_add(struct MPT3SAS_ADAPTER *ioc,
        Mpi2EventIrConfigElement_t *element)
 {
        struct _sas_device *sas_device;
-       unsigned long flags;
        u16 handle = le16_to_cpu(element->PhysDiskDevHandle);
        Mpi2ConfigReply_t mpi_reply;
        Mpi2SasDevicePage0_t sas_device_pg0;
@@ -6117,11 +6344,10 @@ _scsih_sas_pd_add(struct MPT3SAS_ADAPTER *ioc,
 
        set_bit(handle, ioc->pd_handles);
 
-       spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
-       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+       sas_device = mpt3sas_get_sdev_by_handle(ioc, handle);
        if (sas_device) {
                _scsih_ir_fastpath(ioc, handle, element->PhysDiskNum);
+               sas_device_put(sas_device);
                return;
        }
 
@@ -6149,7 +6375,6 @@ _scsih_sas_pd_add(struct MPT3SAS_ADAPTER *ioc,
        _scsih_add_device(ioc, handle, 0, 1);
 }
 
-#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
 /**
  * _scsih_sas_ir_config_change_event_debug - debug for IR Config Change events
  * @ioc: per adapter object
@@ -6229,7 +6454,6 @@ _scsih_sas_ir_config_change_event_debug(struct MPT3SAS_ADAPTER *ioc,
                    element->PhysDiskNum);
        }
 }
-#endif
 
 /**
  * _scsih_sas_ir_config_change_event - handle ir configuration change events
@@ -6250,18 +6474,16 @@ _scsih_sas_ir_config_change_event(struct MPT3SAS_ADAPTER *ioc,
                (Mpi2EventDataIrConfigChangeList_t *)
                fw_event->event_data;
 
-#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
-       if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
+       if ((ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) &&
+            (!ioc->hide_ir_msg))
                _scsih_sas_ir_config_change_event_debug(ioc, event_data);
 
-#endif
-
        foreign_config = (le32_to_cpu(event_data->Flags) &
            MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ? 1 : 0;
 
        element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
-       if (ioc->shost_recovery) {
-
+       if (ioc->shost_recovery &&
+           ioc->hba_mpi_version_belonged != MPI2_VERSION) {
                for (i = 0; i < event_data->NumElements; i++, element++) {
                        if (element->ReasonCode == MPI2_EVENT_IR_CHANGE_RC_HIDE)
                                _scsih_ir_fastpath(ioc,
@@ -6270,6 +6492,7 @@ _scsih_sas_ir_config_change_event(struct MPT3SAS_ADAPTER *ioc,
                }
                return;
        }
+
        for (i = 0; i < event_data->NumElements; i++, element++) {
 
                switch (element->ReasonCode) {
@@ -6285,16 +6508,20 @@ _scsih_sas_ir_config_change_event(struct MPT3SAS_ADAPTER *ioc,
                                    le16_to_cpu(element->VolDevHandle));
                        break;
                case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED:
-                       _scsih_sas_pd_hide(ioc, element);
+                       if (!ioc->is_warpdrive)
+                               _scsih_sas_pd_hide(ioc, element);
                        break;
                case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED:
-                       _scsih_sas_pd_expose(ioc, element);
+                       if (!ioc->is_warpdrive)
+                               _scsih_sas_pd_expose(ioc, element);
                        break;
                case MPI2_EVENT_IR_CHANGE_RC_HIDE:
-                       _scsih_sas_pd_add(ioc, element);
+                       if (!ioc->is_warpdrive)
+                               _scsih_sas_pd_add(ioc, element);
                        break;
                case MPI2_EVENT_IR_CHANGE_RC_UNHIDE:
-                       _scsih_sas_pd_delete(ioc, element);
+                       if (!ioc->is_warpdrive)
+                               _scsih_sas_pd_delete(ioc, element);
                        break;
                }
        }
@@ -6329,10 +6556,11 @@ _scsih_sas_ir_volume_event(struct MPT3SAS_ADAPTER *ioc,
 
        handle = le16_to_cpu(event_data->VolDevHandle);
        state = le32_to_cpu(event_data->NewValue);
-       dewtprintk(ioc, pr_info(MPT3SAS_FMT
-               "%s: handle(0x%04x), old(0x%08x), new(0x%08x)\n",
-               ioc->name, __func__,  handle,
-           le32_to_cpu(event_data->PreviousValue), state));
+       if (!ioc->hide_ir_msg)
+               dewtprintk(ioc, pr_info(MPT3SAS_FMT
+                   "%s: handle(0x%04x), old(0x%08x), new(0x%08x)\n",
+                   ioc->name, __func__,  handle,
+                   le32_to_cpu(event_data->PreviousValue), state));
        switch (state) {
        case MPI2_RAID_VOL_STATE_MISSING:
        case MPI2_RAID_VOL_STATE_FAILED:
@@ -6344,7 +6572,7 @@ _scsih_sas_ir_volume_event(struct MPT3SAS_ADAPTER *ioc,
        case MPI2_RAID_VOL_STATE_OPTIMAL:
 
                spin_lock_irqsave(&ioc->raid_device_lock, flags);
-               raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
+               raid_device = mpt3sas_raid_device_find_by_handle(ioc, handle);
                spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
 
                if (raid_device)
@@ -6398,7 +6626,6 @@ _scsih_sas_ir_physical_disk_event(struct MPT3SAS_ADAPTER *ioc,
        u16 handle, parent_handle;
        u32 state;
        struct _sas_device *sas_device;
-       unsigned long flags;
        Mpi2ConfigReply_t mpi_reply;
        Mpi2SasDevicePage0_t sas_device_pg0;
        u32 ioc_status;
@@ -6415,10 +6642,12 @@ _scsih_sas_ir_physical_disk_event(struct MPT3SAS_ADAPTER *ioc,
        handle = le16_to_cpu(event_data->PhysDiskDevHandle);
        state = le32_to_cpu(event_data->NewValue);
 
-       dewtprintk(ioc, pr_info(MPT3SAS_FMT
-               "%s: handle(0x%04x), old(0x%08x), new(0x%08x)\n",
-               ioc->name, __func__,  handle,
+       if (!ioc->hide_ir_msg)
+               dewtprintk(ioc, pr_info(MPT3SAS_FMT
+                   "%s: handle(0x%04x), old(0x%08x), new(0x%08x)\n",
+                   ioc->name, __func__,  handle,
                    le32_to_cpu(event_data->PreviousValue), state));
+
        switch (state) {
        case MPI2_RAID_PD_STATE_ONLINE:
        case MPI2_RAID_PD_STATE_DEGRADED:
@@ -6426,13 +6655,14 @@ _scsih_sas_ir_physical_disk_event(struct MPT3SAS_ADAPTER *ioc,
        case MPI2_RAID_PD_STATE_OPTIMAL:
        case MPI2_RAID_PD_STATE_HOT_SPARE:
 
-               set_bit(handle, ioc->pd_handles);
-               spin_lock_irqsave(&ioc->sas_device_lock, flags);
-               sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
-               spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+               if (!ioc->is_warpdrive)
+                       set_bit(handle, ioc->pd_handles);
 
-               if (sas_device)
+               sas_device = mpt3sas_get_sdev_by_handle(ioc, handle);
+               if (sas_device) {
+                       sas_device_put(sas_device);
                        return;
+               }
 
                if ((mpt3sas_config_get_sas_device_pg0(ioc, &mpi_reply,
                    &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE,
@@ -6467,7 +6697,6 @@ _scsih_sas_ir_physical_disk_event(struct MPT3SAS_ADAPTER *ioc,
        }
 }
 
-#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
 /**
  * _scsih_sas_ir_operation_status_event_debug - debug for IR op event
  * @ioc: per adapter object
@@ -6509,7 +6738,6 @@ _scsih_sas_ir_operation_status_event_debug(struct MPT3SAS_ADAPTER *ioc,
            le16_to_cpu(event_data->VolDevHandle),
            event_data->PercentComplete);
 }
-#endif
 
 /**
  * _scsih_sas_ir_operation_status_event - handle RAID operation events
@@ -6530,18 +6758,17 @@ _scsih_sas_ir_operation_status_event(struct MPT3SAS_ADAPTER *ioc,
        unsigned long flags;
        u16 handle;
 
-#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
-       if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
+       if ((ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) &&
+           (!ioc->hide_ir_msg))
                _scsih_sas_ir_operation_status_event_debug(ioc,
                     event_data);
-#endif
 
        /* code added for raid transport support */
        if (event_data->RAIDOperation == MPI2_EVENT_IR_RAIDOP_RESYNC) {
 
                spin_lock_irqsave(&ioc->raid_device_lock, flags);
                handle = le16_to_cpu(event_data->VolDevHandle);
-               raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
+               raid_device = mpt3sas_raid_device_find_by_handle(ioc, handle);
                if (raid_device)
                        raid_device->percent_complete =
                            event_data->PercentComplete;
@@ -6703,7 +6930,7 @@ static void
 _scsih_mark_responding_raid_device(struct MPT3SAS_ADAPTER *ioc, u64 wwid,
        u16 handle)
 {
-       struct MPT3SAS_TARGET *sas_target_priv_data;
+       struct MPT3SAS_TARGET *sas_target_priv_data = NULL;
        struct scsi_target *starget;
        struct _raid_device *raid_device;
        unsigned long flags;
@@ -6722,6 +6949,13 @@ _scsih_mark_responding_raid_device(struct MPT3SAS_ADAPTER *ioc, u64 wwid,
                        starget_printk(KERN_INFO, raid_device->starget,
                            "handle(0x%04x), wwid(0x%016llx)\n", handle,
                            (unsigned long long)raid_device->wwid);
+
+                       /*
+                        * WARPDRIVE: The handles of the PDs might have changed
+                        * across the host reset so re-initialize the
+                        * required data for Direct IO
+                        */
+                       mpt3sas_init_warpdrive_properties(ioc, raid_device);
                        spin_lock_irqsave(&ioc->raid_device_lock, flags);
                        if (raid_device->handle == handle) {
                                spin_unlock_irqrestore(&ioc->raid_device_lock,
@@ -6791,6 +7025,7 @@ _scsih_search_responding_raid_devices(struct MPT3SAS_ADAPTER *ioc)
        }
 
        /* refresh the pd_handles */
+       if (!ioc->is_warpdrive) {
                phys_disk_num = 0xFF;
                memset(ioc->pd_handles, 0, ioc->pd_handles_sz);
                while (!(mpt3sas_config_get_phys_disk_pg0(ioc, &mpi_reply,
@@ -6804,6 +7039,7 @@ _scsih_search_responding_raid_devices(struct MPT3SAS_ADAPTER *ioc)
                        handle = le16_to_cpu(pd_pg0.DevHandle);
                        set_bit(handle, ioc->pd_handles);
                }
+       }
  out:
        pr_info(MPT3SAS_FMT "search for responding raid volumes: complete\n",
                ioc->name);
@@ -6906,6 +7142,7 @@ _scsih_remove_unresponding_sas_devices(struct MPT3SAS_ADAPTER *ioc)
        struct _raid_device *raid_device, *raid_device_next;
        struct list_head tmp_list;
        unsigned long flags;
+       LIST_HEAD(head);
 
        pr_info(MPT3SAS_FMT "removing unresponding devices: start\n",
            ioc->name);
@@ -6913,14 +7150,28 @@ _scsih_remove_unresponding_sas_devices(struct MPT3SAS_ADAPTER *ioc)
        /* removing unresponding end devices */
        pr_info(MPT3SAS_FMT "removing unresponding devices: end-devices\n",
            ioc->name);
+       /*
+        * Iterate, pulling off devices marked as non-responding. We become the
+        * owner for the reference the list had on any object we prune.
+        */
+       spin_lock_irqsave(&ioc->sas_device_lock, flags);
        list_for_each_entry_safe(sas_device, sas_device_next,
            &ioc->sas_device_list, list) {
                if (!sas_device->responding)
-                       mpt3sas_device_remove_by_sas_address(ioc,
-                           sas_device->sas_address);
+                       list_move_tail(&sas_device->list, &head);
                else
                        sas_device->responding = 0;
        }
+       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+
+       /*
+        * Now, uninitialize and remove the unresponding devices we pruned.
+        */
+       list_for_each_entry_safe(sas_device, sas_device_next, &head, list) {
+               _scsih_remove_device(ioc, sas_device);
+               list_del_init(&sas_device->list);
+               sas_device_put(sas_device);
+       }
 
        /* removing unresponding volumes */
        if (ioc->ir_firmware) {
@@ -7074,11 +7325,11 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc)
                }
                phys_disk_num = pd_pg0.PhysDiskNum;
                handle = le16_to_cpu(pd_pg0.DevHandle);
-               spin_lock_irqsave(&ioc->sas_device_lock, flags);
-               sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
-               spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-               if (sas_device)
+               sas_device = mpt3sas_get_sdev_by_handle(ioc, handle);
+               if (sas_device) {
+                       sas_device_put(sas_device);
                        continue;
+               }
                if (mpt3sas_config_get_sas_device_pg0(ioc, &mpi_reply,
                    &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE,
                    handle) != 0)
@@ -7199,12 +7450,12 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc)
                if (!(_scsih_is_end_device(
                    le32_to_cpu(sas_device_pg0.DeviceInfo))))
                        continue;
-               spin_lock_irqsave(&ioc->sas_device_lock, flags);
-               sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
+               sas_device = mpt3sas_get_sdev_by_addr(ioc,
                    le64_to_cpu(sas_device_pg0.SASAddress));
-               spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-               if (sas_device)
+               if (sas_device) {
+                       sas_device_put(sas_device);
                        continue;
+               }
                parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
                if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) {
                        pr_info(MPT3SAS_FMT "\tBEFORE adding end device: " \
@@ -7296,10 +7547,11 @@ mpt3sas_scsih_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase)
 static void
 _mpt3sas_fw_work(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event)
 {
+       _scsih_fw_event_del_from_list(ioc, fw_event);
+
        /* the queue is being flushed so ignore this event */
-       if (ioc->remove_host ||
-           ioc->pci_error_recovery) {
-               _scsih_fw_event_free(ioc, fw_event);
+       if (ioc->remove_host || ioc->pci_error_recovery) {
+               fw_event_work_put(fw_event);
                return;
        }
 
@@ -7310,8 +7562,16 @@ _mpt3sas_fw_work(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event)
                        fw_event->event_data);
                break;
        case MPT3SAS_REMOVE_UNRESPONDING_DEVICES:
-               while (scsi_host_in_recovery(ioc->shost) || ioc->shost_recovery)
+               while (scsi_host_in_recovery(ioc->shost) ||
+                                        ioc->shost_recovery) {
+                       /*
+                        * If we're unloading, bail. Otherwise, this can become
+                        * an infinite loop.
+                        */
+                       if (ioc->remove_host)
+                               goto out;
                        ssleep(1);
+               }
                _scsih_remove_unresponding_sas_devices(ioc);
                _scsih_scan_for_devices_after_reset(ioc);
                break;
@@ -7356,7 +7616,8 @@ _mpt3sas_fw_work(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event)
                _scsih_sas_ir_operation_status_event(ioc, fw_event);
                break;
        }
-       _scsih_fw_event_free(ioc, fw_event);
+out:
+       fw_event_work_put(fw_event);
 }
 
 /**
@@ -7453,7 +7714,53 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index,
                    (Mpi2EventDataIrVolume_t *)
                    mpi_reply->EventData);
                break;
+       case MPI2_EVENT_LOG_ENTRY_ADDED:
+       {
+               Mpi2EventDataLogEntryAdded_t *log_entry;
+               u32 *log_code;
+
+               if (!ioc->is_warpdrive)
+                       break;
+
+               log_entry = (Mpi2EventDataLogEntryAdded_t *)
+                   mpi_reply->EventData;
+               log_code = (u32 *)log_entry->LogData;
 
+               if (le16_to_cpu(log_entry->LogEntryQualifier)
+                   != MPT2_WARPDRIVE_LOGENTRY)
+                       break;
+
+               switch (le32_to_cpu(*log_code)) {
+               case MPT2_WARPDRIVE_LC_SSDT:
+                       pr_warn(MPT3SAS_FMT "WarpDrive Warning: "
+                           "IO Throttling has occurred in the WarpDrive "
+                           "subsystem. Check WarpDrive documentation for "
+                           "additional details.\n", ioc->name);
+                       break;
+               case MPT2_WARPDRIVE_LC_SSDLW:
+                       pr_warn(MPT3SAS_FMT "WarpDrive Warning: "
+                           "Program/Erase Cycles for the WarpDrive subsystem "
+                           "in degraded range. Check WarpDrive documentation "
+                           "for additional details.\n", ioc->name);
+                       break;
+               case MPT2_WARPDRIVE_LC_SSDLF:
+                       pr_err(MPT3SAS_FMT "WarpDrive Fatal Error: "
+                           "There are no Program/Erase Cycles for the "
+                           "WarpDrive subsystem. The storage device will be "
+                           "in read-only mode. Check WarpDrive documentation "
+                           "for additional details.\n", ioc->name);
+                       break;
+               case MPT2_WARPDRIVE_LC_BRMF:
+                       pr_err(MPT3SAS_FMT "WarpDrive Fatal Error: "
+                           "The Backup Rail Monitor has failed on the "
+                           "WarpDrive subsystem. Check WarpDrive "
+                           "documentation for additional details.\n",
+                           ioc->name);
+                       break;
+               }
+
+               break;
+       }
        case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
        case MPI2_EVENT_IR_OPERATION_STATUS:
        case MPI2_EVENT_SAS_DISCOVERY:
@@ -7472,7 +7779,7 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index,
        }
 
        sz = le16_to_cpu(mpi_reply->EventDataLength) * 4;
-       fw_event = kzalloc(sizeof(*fw_event) + sz, GFP_ATOMIC);
+       fw_event = alloc_fw_event_work(sz);
        if (!fw_event) {
                pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
                    ioc->name, __FILE__, __LINE__, __func__);
@@ -7485,39 +7792,10 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index,
        fw_event->VP_ID = mpi_reply->VP_ID;
        fw_event->event = event;
        _scsih_fw_event_add(ioc, fw_event);
+       fw_event_work_put(fw_event);
        return 1;
 }
 
-/* shost template */
-static struct scsi_host_template scsih_driver_template = {
-       .module                         = THIS_MODULE,
-       .name                           = "Fusion MPT SAS Host",
-       .proc_name                      = MPT3SAS_DRIVER_NAME,
-       .queuecommand                   = _scsih_qcmd,
-       .target_alloc                   = _scsih_target_alloc,
-       .slave_alloc                    = _scsih_slave_alloc,
-       .slave_configure                = _scsih_slave_configure,
-       .target_destroy                 = _scsih_target_destroy,
-       .slave_destroy                  = _scsih_slave_destroy,
-       .scan_finished                  = _scsih_scan_finished,
-       .scan_start                     = _scsih_scan_start,
-       .change_queue_depth             = _scsih_change_queue_depth,
-       .eh_abort_handler               = _scsih_abort,
-       .eh_device_reset_handler        = _scsih_dev_reset,
-       .eh_target_reset_handler        = _scsih_target_reset,
-       .eh_host_reset_handler          = _scsih_host_reset,
-       .bios_param                     = _scsih_bios_param,
-       .can_queue                      = 1,
-       .this_id                        = -1,
-       .sg_tablesize                   = MPT3SAS_SG_DEPTH,
-       .max_sectors                    = 32767,
-       .cmd_per_lun                    = 7,
-       .use_clustering                 = ENABLE_CLUSTERING,
-       .shost_attrs                    = mpt3sas_host_attrs,
-       .sdev_attrs                     = mpt3sas_dev_attrs,
-       .track_queue_depth              = 1,
-};
-
 /**
  * _scsih_expander_node_remove - removing expander device from list.
  * @ioc: per adapter object
@@ -7613,7 +7891,8 @@ _scsih_ir_shutdown(struct MPT3SAS_ADAPTER *ioc)
        mpi_request->Function = MPI2_FUNCTION_RAID_ACTION;
        mpi_request->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED;
 
-       pr_info(MPT3SAS_FMT "IR shutdown (sending)\n", ioc->name);
+       if (!ioc->hide_ir_msg)
+               pr_info(MPT3SAS_FMT "IR shutdown (sending)\n", ioc->name);
        init_completion(&ioc->scsih_cmds.done);
        mpt3sas_base_put_smid_default(ioc, smid);
        wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ);
@@ -7626,10 +7905,11 @@ _scsih_ir_shutdown(struct MPT3SAS_ADAPTER *ioc)
 
        if (ioc->scsih_cmds.status & MPT3_CMD_REPLY_VALID) {
                mpi_reply = ioc->scsih_cmds.reply;
-               pr_info(MPT3SAS_FMT
-                       "IR shutdown (complete): ioc_status(0x%04x), loginfo(0x%08x)\n",
-                   ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
-                   le32_to_cpu(mpi_reply->IOCLogInfo));
+               if (!ioc->hide_ir_msg)
+                       pr_info(MPT3SAS_FMT "IR shutdown "
+                          "(complete): ioc_status(0x%04x), loginfo(0x%08x)\n",
+                           ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
+                           le32_to_cpu(mpi_reply->IOCLogInfo));
        }
 
  out:
@@ -7638,13 +7918,13 @@ _scsih_ir_shutdown(struct MPT3SAS_ADAPTER *ioc)
 }
 
 /**
- * _scsih_remove - detach and remove add host
+ * scsih_remove - detach and remove add host
  * @pdev: PCI device struct
  *
  * Routine called when unloading the driver.
  * Return nothing.
  */
-static void _scsih_remove(struct pci_dev *pdev)
+void scsih_remove(struct pci_dev *pdev)
 {
        struct Scsi_Host *shost = pci_get_drvdata(pdev);
        struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
@@ -7705,18 +7985,20 @@ static void _scsih_remove(struct pci_dev *pdev)
        sas_remove_host(shost);
        scsi_remove_host(shost);
        mpt3sas_base_detach(ioc);
+       spin_lock(&gioc_lock);
        list_del(&ioc->list);
+       spin_unlock(&gioc_lock);
        scsi_host_put(shost);
 }
 
 /**
- * _scsih_shutdown - routine call during system shutdown
+ * scsih_shutdown - routine call during system shutdown
  * @pdev: PCI device struct
  *
  * Return nothing.
  */
-static void
-_scsih_shutdown(struct pci_dev *pdev)
+void
+scsih_shutdown(struct pci_dev *pdev)
 {
        struct Scsi_Host *shost = pci_get_drvdata(pdev);
        struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
@@ -7794,6 +8076,8 @@ _scsih_probe_boot_devices(struct MPT3SAS_ADAPTER *ioc)
                list_move_tail(&sas_device->list, &ioc->sas_device_list);
                spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
+               if (ioc->hide_drives)
+                       return;
                if (!mpt3sas_transport_port_add(ioc, handle,
                    sas_address_parent)) {
                        _scsih_sas_device_remove(ioc, sas_device);
@@ -7831,6 +8115,48 @@ _scsih_probe_raid(struct MPT3SAS_ADAPTER *ioc)
        }
 }
 
+static struct _sas_device *get_next_sas_device(struct MPT3SAS_ADAPTER *ioc)
+{
+       struct _sas_device *sas_device = NULL;
+       unsigned long flags;
+
+       spin_lock_irqsave(&ioc->sas_device_lock, flags);
+       if (!list_empty(&ioc->sas_device_init_list)) {
+               sas_device = list_first_entry(&ioc->sas_device_init_list,
+                               struct _sas_device, list);
+               sas_device_get(sas_device);
+       }
+       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+
+       return sas_device;
+}
+
+static void sas_device_make_active(struct MPT3SAS_ADAPTER *ioc,
+               struct _sas_device *sas_device)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&ioc->sas_device_lock, flags);
+
+       /*
+        * Since we dropped the lock during the call to port_add(), we need to
+        * be careful here that somebody else didn't move or delete this item
+        * while we were busy with other things.
+        *
+        * If it was on the list, we need a put() for the reference the list
+        * had. Either way, we need a get() for the destination list.
+        */
+       if (!list_empty(&sas_device->list)) {
+               list_del_init(&sas_device->list);
+               sas_device_put(sas_device);
+       }
+
+       sas_device_get(sas_device);
+       list_add_tail(&sas_device->list, &ioc->sas_device_list);
+
+       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+}
+
 /**
  * _scsih_probe_sas - reporting sas devices to sas transport
  * @ioc: per adapter object
@@ -7840,17 +8166,16 @@ _scsih_probe_raid(struct MPT3SAS_ADAPTER *ioc)
 static void
 _scsih_probe_sas(struct MPT3SAS_ADAPTER *ioc)
 {
-       struct _sas_device *sas_device, *next;
-       unsigned long flags;
+       struct _sas_device *sas_device;
 
-       /* SAS Device List */
-       list_for_each_entry_safe(sas_device, next, &ioc->sas_device_init_list,
-           list) {
+       if (ioc->hide_drives)
+               return;
 
+       while ((sas_device = get_next_sas_device(ioc))) {
                if (!mpt3sas_transport_port_add(ioc, sas_device->handle,
                    sas_device->sas_address_parent)) {
-                       list_del(&sas_device->list);
-                       kfree(sas_device);
+                       _scsih_sas_device_remove(ioc, sas_device);
+                       sas_device_put(sas_device);
                        continue;
                } else if (!sas_device->starget) {
                        /*
@@ -7863,15 +8188,13 @@ _scsih_probe_sas(struct MPT3SAS_ADAPTER *ioc)
                                mpt3sas_transport_port_remove(ioc,
                                    sas_device->sas_address,
                                    sas_device->sas_address_parent);
-                               list_del(&sas_device->list);
-                               kfree(sas_device);
+                               _scsih_sas_device_remove(ioc, sas_device);
+                               sas_device_put(sas_device);
                                continue;
                        }
                }
-
-               spin_lock_irqsave(&ioc->sas_device_lock, flags);
-               list_move_tail(&sas_device->list, &ioc->sas_device_list);
-               spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+               sas_device_make_active(ioc, sas_device);
+               sas_device_put(sas_device);
        }
 }
 
@@ -7908,15 +8231,15 @@ _scsih_probe_devices(struct MPT3SAS_ADAPTER *ioc)
 }
 
 /**
- * _scsih_scan_start - scsi lld callback for .scan_start
+ * scsih_scan_start - scsi lld callback for .scan_start
  * @shost: SCSI host pointer
  *
  * The shost has the ability to discover targets on its own instead
  * of scanning the entire bus.  In our implemention, we will kick off
  * firmware discovery.
  */
-static void
-_scsih_scan_start(struct Scsi_Host *shost)
+void
+scsih_scan_start(struct Scsi_Host *shost)
 {
        struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
        int rc;
@@ -7934,7 +8257,7 @@ _scsih_scan_start(struct Scsi_Host *shost)
 }
 
 /**
- * _scsih_scan_finished - scsi lld callback for .scan_finished
+ * scsih_scan_finished - scsi lld callback for .scan_finished
  * @shost: SCSI host pointer
  * @time: elapsed time of the scan in jiffies
  *
@@ -7942,8 +8265,8 @@ _scsih_scan_start(struct Scsi_Host *shost)
  * scsi_host and the elapsed time of the scan in jiffies. In our implemention,
  * we wait for firmware discovery to complete, then return 1.
  */
-static int
-_scsih_scan_finished(struct Scsi_Host *shost, unsigned long time)
+int
+scsih_scan_finished(struct Scsi_Host *shost, unsigned long time)
 {
        struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
 
@@ -7987,6 +8310,124 @@ _scsih_scan_finished(struct Scsi_Host *shost, unsigned long time)
        return 1;
 }
 
+/* shost template for SAS 2.0 HBA devices */
+static struct scsi_host_template mpt2sas_driver_template = {
+       .module                         = THIS_MODULE,
+       .name                           = "Fusion MPT SAS Host",
+       .proc_name                      = MPT2SAS_DRIVER_NAME,
+       .queuecommand                   = scsih_qcmd,
+       .target_alloc                   = scsih_target_alloc,
+       .slave_alloc                    = scsih_slave_alloc,
+       .slave_configure                = scsih_slave_configure,
+       .target_destroy                 = scsih_target_destroy,
+       .slave_destroy                  = scsih_slave_destroy,
+       .scan_finished                  = scsih_scan_finished,
+       .scan_start                     = scsih_scan_start,
+       .change_queue_depth             = scsih_change_queue_depth,
+       .eh_abort_handler               = scsih_abort,
+       .eh_device_reset_handler        = scsih_dev_reset,
+       .eh_target_reset_handler        = scsih_target_reset,
+       .eh_host_reset_handler          = scsih_host_reset,
+       .bios_param                     = scsih_bios_param,
+       .can_queue                      = 1,
+       .this_id                        = -1,
+       .sg_tablesize                   = MPT2SAS_SG_DEPTH,
+       .max_sectors                    = 32767,
+       .cmd_per_lun                    = 7,
+       .use_clustering                 = ENABLE_CLUSTERING,
+       .shost_attrs                    = mpt3sas_host_attrs,
+       .sdev_attrs                     = mpt3sas_dev_attrs,
+       .track_queue_depth              = 1,
+};
+
+/* raid transport support for SAS 2.0 HBA devices */
+static struct raid_function_template mpt2sas_raid_functions = {
+       .cookie         = &mpt2sas_driver_template,
+       .is_raid        = scsih_is_raid,
+       .get_resync     = scsih_get_resync,
+       .get_state      = scsih_get_state,
+};
+
+/* shost template for SAS 3.0 HBA devices */
+static struct scsi_host_template mpt3sas_driver_template = {
+       .module                         = THIS_MODULE,
+       .name                           = "Fusion MPT SAS Host",
+       .proc_name                      = MPT3SAS_DRIVER_NAME,
+       .queuecommand                   = scsih_qcmd,
+       .target_alloc                   = scsih_target_alloc,
+       .slave_alloc                    = scsih_slave_alloc,
+       .slave_configure                = scsih_slave_configure,
+       .target_destroy                 = scsih_target_destroy,
+       .slave_destroy                  = scsih_slave_destroy,
+       .scan_finished                  = scsih_scan_finished,
+       .scan_start                     = scsih_scan_start,
+       .change_queue_depth             = scsih_change_queue_depth,
+       .eh_abort_handler               = scsih_abort,
+       .eh_device_reset_handler        = scsih_dev_reset,
+       .eh_target_reset_handler        = scsih_target_reset,
+       .eh_host_reset_handler          = scsih_host_reset,
+       .bios_param                     = scsih_bios_param,
+       .can_queue                      = 1,
+       .this_id                        = -1,
+       .sg_tablesize                   = MPT3SAS_SG_DEPTH,
+       .max_sectors                    = 32767,
+       .cmd_per_lun                    = 7,
+       .use_clustering                 = ENABLE_CLUSTERING,
+       .shost_attrs                    = mpt3sas_host_attrs,
+       .sdev_attrs                     = mpt3sas_dev_attrs,
+       .track_queue_depth              = 1,
+};
+
+/* raid transport support for SAS 3.0 HBA devices */
+static struct raid_function_template mpt3sas_raid_functions = {
+       .cookie         = &mpt3sas_driver_template,
+       .is_raid        = scsih_is_raid,
+       .get_resync     = scsih_get_resync,
+       .get_state      = scsih_get_state,
+};
+
+/**
+ * _scsih_determine_hba_mpi_version - determine in which MPI version class
+ *                                     this device belongs to.
+ * @pdev: PCI device struct
+ *
+ * return MPI2_VERSION for SAS 2.0 HBA devices,
+ *     MPI25_VERSION for SAS 3.0 HBA devices.
+ */
+u16
+_scsih_determine_hba_mpi_version(struct pci_dev *pdev)
+{
+
+       switch (pdev->device) {
+       case MPI2_MFGPAGE_DEVID_SSS6200:
+       case MPI2_MFGPAGE_DEVID_SAS2004:
+       case MPI2_MFGPAGE_DEVID_SAS2008:
+       case MPI2_MFGPAGE_DEVID_SAS2108_1:
+       case MPI2_MFGPAGE_DEVID_SAS2108_2:
+       case MPI2_MFGPAGE_DEVID_SAS2108_3:
+       case MPI2_MFGPAGE_DEVID_SAS2116_1:
+       case MPI2_MFGPAGE_DEVID_SAS2116_2:
+       case MPI2_MFGPAGE_DEVID_SAS2208_1:
+       case MPI2_MFGPAGE_DEVID_SAS2208_2:
+       case MPI2_MFGPAGE_DEVID_SAS2208_3:
+       case MPI2_MFGPAGE_DEVID_SAS2208_4:
+       case MPI2_MFGPAGE_DEVID_SAS2208_5:
+       case MPI2_MFGPAGE_DEVID_SAS2208_6:
+       case MPI2_MFGPAGE_DEVID_SAS2308_1:
+       case MPI2_MFGPAGE_DEVID_SAS2308_2:
+       case MPI2_MFGPAGE_DEVID_SAS2308_3:
+               return MPI2_VERSION;
+       case MPI25_MFGPAGE_DEVID_SAS3004:
+       case MPI25_MFGPAGE_DEVID_SAS3008:
+       case MPI25_MFGPAGE_DEVID_SAS3108_1:
+       case MPI25_MFGPAGE_DEVID_SAS3108_2:
+       case MPI25_MFGPAGE_DEVID_SAS3108_5:
+       case MPI25_MFGPAGE_DEVID_SAS3108_6:
+               return MPI25_VERSION;
+       }
+       return 0;
+}
+
 /**
  * _scsih_probe - attach and add scsi host
  * @pdev: PCI device struct
@@ -7994,26 +8435,72 @@ _scsih_scan_finished(struct Scsi_Host *shost, unsigned long time)
  *
  * Returns 0 success, anything else error.
  */
-static int
+int
 _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
        struct MPT3SAS_ADAPTER *ioc;
-       struct Scsi_Host *shost;
+       struct Scsi_Host *shost = NULL;
        int rv;
+       u16 hba_mpi_version;
 
-       shost = scsi_host_alloc(&scsih_driver_template,
-           sizeof(struct MPT3SAS_ADAPTER));
-       if (!shost)
+       /* Determine in which MPI version class this pci device belongs */
+       hba_mpi_version = _scsih_determine_hba_mpi_version(pdev);
+       if (hba_mpi_version == 0)
                return -ENODEV;
 
-       /* init local params */
-       ioc = shost_priv(shost);
-       memset(ioc, 0, sizeof(struct MPT3SAS_ADAPTER));
+       /* Enumerate only SAS 2.0 HBA's if hbas_to_enumerate is one,
+        * for other generation HBA's return with -ENODEV
+        */
+       if ((hbas_to_enumerate == 1) && (hba_mpi_version !=  MPI2_VERSION))
+               return -ENODEV;
+
+       /* Enumerate only SAS 3.0 HBA's if hbas_to_enumerate is two,
+        * for other generation HBA's return with -ENODEV
+        */
+       if ((hbas_to_enumerate == 2) && (hba_mpi_version !=  MPI25_VERSION))
+               return -ENODEV;
+
+       switch (hba_mpi_version) {
+       case MPI2_VERSION:
+               /* Use mpt2sas driver host template for SAS 2.0 HBA's */
+               shost = scsi_host_alloc(&mpt2sas_driver_template,
+                 sizeof(struct MPT3SAS_ADAPTER));
+               if (!shost)
+                       return -ENODEV;
+               ioc = shost_priv(shost);
+               memset(ioc, 0, sizeof(struct MPT3SAS_ADAPTER));
+               ioc->hba_mpi_version_belonged = hba_mpi_version;
+               ioc->id = mpt2_ids++;
+               sprintf(ioc->driver_name, "%s", MPT2SAS_DRIVER_NAME);
+               if (pdev->device == MPI2_MFGPAGE_DEVID_SSS6200) {
+                       ioc->is_warpdrive = 1;
+                       ioc->hide_ir_msg = 1;
+               } else
+                       ioc->mfg_pg10_hide_flag = MFG_PAGE10_EXPOSE_ALL_DISKS;
+               break;
+       case MPI25_VERSION:
+               /* Use mpt3sas driver host template for SAS 3.0 HBA's */
+               shost = scsi_host_alloc(&mpt3sas_driver_template,
+                 sizeof(struct MPT3SAS_ADAPTER));
+               if (!shost)
+                       return -ENODEV;
+               ioc = shost_priv(shost);
+               memset(ioc, 0, sizeof(struct MPT3SAS_ADAPTER));
+               ioc->hba_mpi_version_belonged = hba_mpi_version;
+               ioc->id = mpt3_ids++;
+               sprintf(ioc->driver_name, "%s", MPT3SAS_DRIVER_NAME);
+               if (pdev->revision >= SAS3_PCI_DEVICE_C0_REVISION)
+                       ioc->msix96_vector = 1;
+               break;
+       default:
+               return -ENODEV;
+       }
+
        INIT_LIST_HEAD(&ioc->list);
+       spin_lock(&gioc_lock);
        list_add_tail(&ioc->list, &mpt3sas_ioc_list);
+       spin_unlock(&gioc_lock);
        ioc->shost = shost;
-       ioc->id = mpt_ids++;
-       sprintf(ioc->name, "%s%d", MPT3SAS_DRIVER_NAME, ioc->id);
        ioc->pdev = pdev;
        ioc->scsi_io_cb_idx = scsi_io_cb_idx;
        ioc->tm_cb_idx = tm_cb_idx;
@@ -8030,6 +8517,8 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        ioc->schedule_dead_ioc_flush_running_cmds = &_scsih_flush_running_cmds;
        /* misc semaphores and spin locks */
        mutex_init(&ioc->reset_in_progress_mutex);
+       /* initializing pci_access_mutex lock */
+       mutex_init(&ioc->pci_access_mutex);
        spin_lock_init(&ioc->ioc_reset_in_progress_lock);
        spin_lock_init(&ioc->scsi_lookup_lock);
        spin_lock_init(&ioc->sas_device_lock);
@@ -8048,6 +8537,8 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        INIT_LIST_HEAD(&ioc->delayed_tr_volume_list);
        INIT_LIST_HEAD(&ioc->reply_queue_list);
 
+       sprintf(ioc->name, "%s_cm%d", ioc->driver_name, ioc->id);
+
        /* init shost parameters */
        shost->max_cmd_len = 32;
        shost->max_lun = max_lun;
@@ -8086,7 +8577,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
        /* event thread */
        snprintf(ioc->firmware_event_name, sizeof(ioc->firmware_event_name),
-           "fw_event%d", ioc->id);
+           "fw_event_%s%d", ioc->driver_name, ioc->id);
        ioc->firmware_event_thread = alloc_ordered_workqueue(
            ioc->firmware_event_name, WQ_MEM_RECLAIM);
        if (!ioc->firmware_event_thread) {
@@ -8103,6 +8594,21 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                rv = -ENODEV;
                goto out_attach_fail;
        }
+
+       if (ioc->is_warpdrive) {
+               if (ioc->mfg_pg10_hide_flag ==  MFG_PAGE10_EXPOSE_ALL_DISKS)
+                       ioc->hide_drives = 0;
+               else if (ioc->mfg_pg10_hide_flag ==  MFG_PAGE10_HIDE_ALL_DISKS)
+                       ioc->hide_drives = 1;
+               else {
+                       if (mpt3sas_get_num_volumes(ioc))
+                               ioc->hide_drives = 1;
+                       else
+                               ioc->hide_drives = 0;
+               }
+       } else
+               ioc->hide_drives = 0;
+
        rv = scsi_add_host(shost, &pdev->dev);
        if (rv) {
                pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
@@ -8117,21 +8623,23 @@ out_add_shost_fail:
  out_attach_fail:
        destroy_workqueue(ioc->firmware_event_thread);
  out_thread_fail:
+       spin_lock(&gioc_lock);
        list_del(&ioc->list);
+       spin_unlock(&gioc_lock);
        scsi_host_put(shost);
        return rv;
 }
 
 #ifdef CONFIG_PM
 /**
- * _scsih_suspend - power management suspend main entry point
+ * scsih_suspend - power management suspend main entry point
  * @pdev: PCI device struct
  * @state: PM state change to (usually PCI_D3)
  *
  * Returns 0 success, anything else error.
  */
-static int
-_scsih_suspend(struct pci_dev *pdev, pm_message_t state)
+int
+scsih_suspend(struct pci_dev *pdev, pm_message_t state)
 {
        struct Scsi_Host *shost = pci_get_drvdata(pdev);
        struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
@@ -8152,13 +8660,13 @@ _scsih_suspend(struct pci_dev *pdev, pm_message_t state)
 }
 
 /**
- * _scsih_resume - power management resume main entry point
+ * scsih_resume - power management resume main entry point
  * @pdev: PCI device struct
  *
  * Returns 0 success, anything else error.
  */
-static int
-_scsih_resume(struct pci_dev *pdev)
+int
+scsih_resume(struct pci_dev *pdev)
 {
        struct Scsi_Host *shost = pci_get_drvdata(pdev);
        struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
@@ -8185,7 +8693,7 @@ _scsih_resume(struct pci_dev *pdev)
 #endif /* CONFIG_PM */
 
 /**
- * _scsih_pci_error_detected - Called when a PCI error is detected.
+ * scsih_pci_error_detected - Called when a PCI error is detected.
  * @pdev: PCI device struct
  * @state: PCI channel state
  *
@@ -8194,8 +8702,8 @@ _scsih_resume(struct pci_dev *pdev)
  * Return value:
  *      PCI_ERS_RESULT_NEED_RESET or PCI_ERS_RESULT_DISCONNECT
  */
-static pci_ers_result_t
-_scsih_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
+pci_ers_result_t
+scsih_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
 {
        struct Scsi_Host *shost = pci_get_drvdata(pdev);
        struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
@@ -8224,15 +8732,15 @@ _scsih_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
 }
 
 /**
- * _scsih_pci_slot_reset - Called when PCI slot has been reset.
+ * scsih_pci_slot_reset - Called when PCI slot has been reset.
  * @pdev: PCI device struct
  *
  * Description: This routine is called by the pci error recovery
  * code after the PCI slot has been reset, just before we
  * should resume normal operations.
  */
-static pci_ers_result_t
-_scsih_pci_slot_reset(struct pci_dev *pdev)
+pci_ers_result_t
+scsih_pci_slot_reset(struct pci_dev *pdev)
 {
        struct Scsi_Host *shost = pci_get_drvdata(pdev);
        struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
@@ -8261,15 +8769,15 @@ _scsih_pci_slot_reset(struct pci_dev *pdev)
 }
 
 /**
- * _scsih_pci_resume() - resume normal ops after PCI reset
+ * scsih_pci_resume() - resume normal ops after PCI reset
  * @pdev: pointer to PCI device
  *
  * Called when the error recovery driver tells us that its
  * OK to resume normal operation. Use completion to allow
  * halted scsi ops to resume.
  */
-static void
-_scsih_pci_resume(struct pci_dev *pdev)
+void
+scsih_pci_resume(struct pci_dev *pdev)
 {
        struct Scsi_Host *shost = pci_get_drvdata(pdev);
        struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
@@ -8282,11 +8790,11 @@ _scsih_pci_resume(struct pci_dev *pdev)
 }
 
 /**
- * _scsih_pci_mmio_enabled - Enable MMIO and dump debug registers
+ * scsih_pci_mmio_enabled - Enable MMIO and dump debug registers
  * @pdev: pointer to PCI device
  */
-static pci_ers_result_t
-_scsih_pci_mmio_enabled(struct pci_dev *pdev)
+pci_ers_result_t
+scsih_pci_mmio_enabled(struct pci_dev *pdev)
 {
        struct Scsi_Host *shost = pci_get_drvdata(pdev);
        struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
@@ -8300,61 +8808,99 @@ _scsih_pci_mmio_enabled(struct pci_dev *pdev)
        return PCI_ERS_RESULT_NEED_RESET;
 }
 
-/* raid transport support */
-static struct raid_function_template mpt3sas_raid_functions = {
-       .cookie         = &scsih_driver_template,
-       .is_raid        = _scsih_is_raid,
-       .get_resync     = _scsih_get_resync,
-       .get_state      = _scsih_get_state,
+/*
+ * The pci device ids are defined in mpi/mpi2_cnfg.h.
+ */
+static const struct pci_device_id mpt3sas_pci_table[] = {
+       /* Spitfire ~ 2004 */
+       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2004,
+               PCI_ANY_ID, PCI_ANY_ID },
+       /* Falcon ~ 2008 */
+       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2008,
+               PCI_ANY_ID, PCI_ANY_ID },
+       /* Liberator ~ 2108 */
+       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_1,
+               PCI_ANY_ID, PCI_ANY_ID },
+       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_2,
+               PCI_ANY_ID, PCI_ANY_ID },
+       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_3,
+               PCI_ANY_ID, PCI_ANY_ID },
+       /* Meteor ~ 2116 */
+       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_1,
+               PCI_ANY_ID, PCI_ANY_ID },
+       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_2,
+               PCI_ANY_ID, PCI_ANY_ID },
+       /* Thunderbolt ~ 2208 */
+       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_1,
+               PCI_ANY_ID, PCI_ANY_ID },
+       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_2,
+               PCI_ANY_ID, PCI_ANY_ID },
+       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_3,
+               PCI_ANY_ID, PCI_ANY_ID },
+       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_4,
+               PCI_ANY_ID, PCI_ANY_ID },
+       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_5,
+               PCI_ANY_ID, PCI_ANY_ID },
+       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_6,
+               PCI_ANY_ID, PCI_ANY_ID },
+       /* Mustang ~ 2308 */
+       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_1,
+               PCI_ANY_ID, PCI_ANY_ID },
+       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_2,
+               PCI_ANY_ID, PCI_ANY_ID },
+       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_3,
+               PCI_ANY_ID, PCI_ANY_ID },
+       /* SSS6200 */
+       { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SSS6200,
+               PCI_ANY_ID, PCI_ANY_ID },
+       /* Fury ~ 3004 and 3008 */
+       { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3004,
+               PCI_ANY_ID, PCI_ANY_ID },
+       { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3008,
+               PCI_ANY_ID, PCI_ANY_ID },
+       /* Invader ~ 3108 */
+       { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_1,
+               PCI_ANY_ID, PCI_ANY_ID },
+       { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_2,
+               PCI_ANY_ID, PCI_ANY_ID },
+       { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_5,
+               PCI_ANY_ID, PCI_ANY_ID },
+       { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_6,
+               PCI_ANY_ID, PCI_ANY_ID },
+       {0}     /* Terminating entry */
 };
+MODULE_DEVICE_TABLE(pci, mpt3sas_pci_table);
 
-static struct pci_error_handlers _scsih_err_handler = {
-       .error_detected = _scsih_pci_error_detected,
-       .mmio_enabled = _scsih_pci_mmio_enabled,
-       .slot_reset =   _scsih_pci_slot_reset,
-       .resume =       _scsih_pci_resume,
+static struct pci_error_handlers _mpt3sas_err_handler = {
+       .error_detected = scsih_pci_error_detected,
+       .mmio_enabled   = scsih_pci_mmio_enabled,
+       .slot_reset     = scsih_pci_slot_reset,
+       .resume         = scsih_pci_resume,
 };
 
-static struct pci_driver scsih_driver = {
+static struct pci_driver mpt3sas_driver = {
        .name           = MPT3SAS_DRIVER_NAME,
-       .id_table       = scsih_pci_table,
+       .id_table       = mpt3sas_pci_table,
        .probe          = _scsih_probe,
-       .remove         = _scsih_remove,
-       .shutdown       = _scsih_shutdown,
-       .err_handler    = &_scsih_err_handler,
+       .remove         = scsih_remove,
+       .shutdown       = scsih_shutdown,
+       .err_handler    = &_mpt3sas_err_handler,
 #ifdef CONFIG_PM
-       .suspend        = _scsih_suspend,
-       .resume         = _scsih_resume,
+       .suspend        = scsih_suspend,
+       .resume         = scsih_resume,
 #endif
 };
 
-
 /**
- * _scsih_init - main entry point for this driver.
+ * scsih_init - main entry point for this driver.
  *
  * Returns 0 success, anything else error.
  */
-static int __init
-_scsih_init(void)
+int
+scsih_init(void)
 {
-       int error;
-
-       mpt_ids = 0;
-
-       pr_info("%s version %s loaded\n", MPT3SAS_DRIVER_NAME,
-           MPT3SAS_DRIVER_VERSION);
-
-       mpt3sas_transport_template =
-           sas_attach_transport(&mpt3sas_transport_functions);
-       if (!mpt3sas_transport_template)
-               return -ENODEV;
-
-/* raid transport support */
-       mpt3sas_raid_template = raid_class_attach(&mpt3sas_raid_functions);
-       if (!mpt3sas_raid_template) {
-               sas_release_transport(mpt3sas_transport_template);
-               return -ENODEV;
-       }
+       mpt2_ids = 0;
+       mpt3_ids = 0;
 
        mpt3sas_base_initialize_callback_handler();
 
@@ -8392,33 +8938,17 @@ _scsih_init(void)
        tm_sas_control_cb_idx = mpt3sas_base_register_callback_handler(
            _scsih_sas_control_complete);
 
-       mpt3sas_ctl_init();
-
-       error = pci_register_driver(&scsih_driver);
-       if (error) {
-               /* raid transport support */
-               raid_class_release(mpt3sas_raid_template);
-               sas_release_transport(mpt3sas_transport_template);
-       }
-
-       return error;
+       return 0;
 }
 
 /**
- * _scsih_exit - exit point for this driver (when it is a module).
+ * scsih_exit - exit point for this driver (when it is a module).
  *
  * Returns 0 success, anything else error.
  */
-static void __exit
-_scsih_exit(void)
+void
+scsih_exit(void)
 {
-       pr_info("mpt3sas version %s unloading\n",
-           MPT3SAS_DRIVER_VERSION);
-
-       mpt3sas_ctl_exit();
-
-       pci_unregister_driver(&scsih_driver);
-
 
        mpt3sas_base_release_callback_handler(scsi_io_cb_idx);
        mpt3sas_base_release_callback_handler(tm_cb_idx);
@@ -8434,9 +8964,86 @@ _scsih_exit(void)
        mpt3sas_base_release_callback_handler(tm_sas_control_cb_idx);
 
 /* raid transport support */
-       raid_class_release(mpt3sas_raid_template);
+       if (hbas_to_enumerate != 1)
+               raid_class_release(mpt3sas_raid_template);
+       if (hbas_to_enumerate != 2)
+               raid_class_release(mpt2sas_raid_template);
        sas_release_transport(mpt3sas_transport_template);
 }
 
-module_init(_scsih_init);
-module_exit(_scsih_exit);
+/**
+ * _mpt3sas_init - main entry point for this driver.
+ *
+ * Returns 0 success, anything else error.
+ */
+static int __init
+_mpt3sas_init(void)
+{
+       int error;
+
+       pr_info("%s version %s loaded\n", MPT3SAS_DRIVER_NAME,
+                                       MPT3SAS_DRIVER_VERSION);
+
+       mpt3sas_transport_template =
+           sas_attach_transport(&mpt3sas_transport_functions);
+       if (!mpt3sas_transport_template)
+               return -ENODEV;
+
+       /* No need attach mpt3sas raid functions template
+        * if hbas_to_enumarate value is one.
+        */
+       if (hbas_to_enumerate != 1) {
+               mpt3sas_raid_template =
+                               raid_class_attach(&mpt3sas_raid_functions);
+               if (!mpt3sas_raid_template) {
+                       sas_release_transport(mpt3sas_transport_template);
+                       return -ENODEV;
+               }
+       }
+
+       /* No need to attach mpt2sas raid functions template
+        * if hbas_to_enumarate value is two
+        */
+       if (hbas_to_enumerate != 2) {
+               mpt2sas_raid_template =
+                               raid_class_attach(&mpt2sas_raid_functions);
+               if (!mpt2sas_raid_template) {
+                       sas_release_transport(mpt3sas_transport_template);
+                       return -ENODEV;
+               }
+       }
+
+       error = scsih_init();
+       if (error) {
+               scsih_exit();
+               return error;
+       }
+
+       mpt3sas_ctl_init(hbas_to_enumerate);
+
+       error = pci_register_driver(&mpt3sas_driver);
+       if (error)
+               scsih_exit();
+
+       return error;
+}
+
+/**
+ * _mpt3sas_exit - exit point for this driver (when it is a module).
+ *
+ */
+static void __exit
+_mpt3sas_exit(void)
+{
+       pr_info("mpt3sas version %s unloading\n",
+                               MPT3SAS_DRIVER_VERSION);
+
+       pci_unregister_driver(&mpt3sas_driver);
+
+       mpt3sas_ctl_exit(hbas_to_enumerate);
+
+       scsih_exit();
+}
+
+module_init(_mpt3sas_init);
+module_exit(_mpt3sas_exit);
index 70fd019e7ee585c14deea0e4ec1ffcff66709f8e..ca36d7ea096495f6f6f659af4a92076dbf0bf485 100644 (file)
@@ -734,7 +734,7 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle,
        rphy->identify = mpt3sas_port->remote_identify;
 
        if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) {
-               sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
+               sas_device = mpt3sas_get_sdev_by_addr(ioc,
                                    mpt3sas_port->remote_identify.sas_address);
                if (!sas_device) {
                        dfailprintk(ioc, printk(MPT3SAS_FMT
@@ -750,8 +750,10 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle,
                    ioc->name, __FILE__, __LINE__, __func__);
        }
 
-       if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE)
+       if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) {
                sas_device->pend_sas_rphy_add = 0;
+               sas_device_put(sas_device);
+       }
 
        if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
                dev_printk(KERN_INFO, &rphy->dev,
@@ -1324,15 +1326,17 @@ _transport_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
        int rc;
 
        spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
+       sas_device = __mpt3sas_get_sdev_by_addr(ioc,
            rphy->identify.sas_address);
        if (sas_device) {
                *identifier = sas_device->enclosure_logical_id;
                rc = 0;
+               sas_device_put(sas_device);
        } else {
                *identifier = 0;
                rc = -ENXIO;
        }
+
        spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
        return rc;
 }
@@ -1352,12 +1356,14 @@ _transport_get_bay_identifier(struct sas_rphy *rphy)
        int rc;
 
        spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
+       sas_device = __mpt3sas_get_sdev_by_addr(ioc,
            rphy->identify.sas_address);
-       if (sas_device)
+       if (sas_device) {
                rc = sas_device->slot;
-       else
+               sas_device_put(sas_device);
+       } else {
                rc = -ENXIO;
+       }
        spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
        return rc;
 }
diff --git a/drivers/scsi/mpt3sas/mpt3sas_warpdrive.c b/drivers/scsi/mpt3sas/mpt3sas_warpdrive.c
new file mode 100644 (file)
index 0000000..540bd50
--- /dev/null
@@ -0,0 +1,344 @@
+/*
+ * Scsi Host Layer for MPT (Message Passing Technology) based controllers
+ *
+ * Copyright (C) 2012-2014  LSI Corporation
+ * Copyright (C) 2013-2015 Avago Technologies
+ *  (mailto: MPT-FusionLinux.pdl@avagotech.com)
+ *
+ * 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.
+ *
+ * NO WARRANTY
+ * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
+ * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
+ * solely responsible for determining the appropriateness of using and
+ * distributing the Program and assumes all risks associated with its
+ * exercise of rights under this Agreement, including but not limited to
+ * the risks and costs of program errors, damage to or loss of data,
+ * programs or equipment, and unavailability or interruption of operations.
+
+ * DISCLAIMER OF LIABILITY
+ * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+ * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <asm/unaligned.h>
+
+#include "mpt3sas_base.h"
+
+/**
+ * _warpdrive_disable_ddio - Disable direct I/O for all the volumes
+ * @ioc: per adapter object
+ */
+static void
+_warpdrive_disable_ddio(struct MPT3SAS_ADAPTER *ioc)
+{
+       Mpi2RaidVolPage1_t vol_pg1;
+       Mpi2ConfigReply_t mpi_reply;
+       struct _raid_device *raid_device;
+       u16 handle;
+       u16 ioc_status;
+       unsigned long flags;
+
+       handle = 0xFFFF;
+       while (!(mpt3sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
+           &vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
+               ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+                   MPI2_IOCSTATUS_MASK;
+               if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
+                       break;
+               handle = le16_to_cpu(vol_pg1.DevHandle);
+               spin_lock_irqsave(&ioc->raid_device_lock, flags);
+               raid_device = mpt3sas_raid_device_find_by_handle(ioc, handle);
+               if (raid_device)
+                       raid_device->direct_io_enabled = 0;
+               spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
+       }
+       return;
+}
+
+
+/**
+ * mpt3sas_get_num_volumes - Get number of volumes in the ioc
+ * @ioc: per adapter object
+ */
+u8
+mpt3sas_get_num_volumes(struct MPT3SAS_ADAPTER *ioc)
+{
+       Mpi2RaidVolPage1_t vol_pg1;
+       Mpi2ConfigReply_t mpi_reply;
+       u16 handle;
+       u8 vol_cnt = 0;
+       u16 ioc_status;
+
+       handle = 0xFFFF;
+       while (!(mpt3sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
+           &vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
+               ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+                   MPI2_IOCSTATUS_MASK;
+               if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
+                       break;
+               vol_cnt++;
+               handle = le16_to_cpu(vol_pg1.DevHandle);
+       }
+       return vol_cnt;
+}
+
+
+/**
+ * mpt3sas_init_warpdrive_properties - Set properties for warpdrive direct I/O.
+ * @ioc: per adapter object
+ * @raid_device: the raid_device object
+ */
+void
+mpt3sas_init_warpdrive_properties(struct MPT3SAS_ADAPTER *ioc,
+       struct _raid_device *raid_device)
+{
+       Mpi2RaidVolPage0_t *vol_pg0;
+       Mpi2RaidPhysDiskPage0_t pd_pg0;
+       Mpi2ConfigReply_t mpi_reply;
+       u16 sz;
+       u8 num_pds, count;
+       unsigned long stripe_sz, block_sz;
+       u8 stripe_exp, block_exp;
+       u64 dev_max_lba;
+
+       if (!ioc->is_warpdrive)
+               return;
+
+       if (ioc->mfg_pg10_hide_flag ==  MFG_PAGE10_EXPOSE_ALL_DISKS) {
+               pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled "
+                   "globally as drives are exposed\n", ioc->name);
+               return;
+       }
+       if (mpt3sas_get_num_volumes(ioc) > 1) {
+               _warpdrive_disable_ddio(ioc);
+               pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled "
+                   "globally as number of drives > 1\n", ioc->name);
+               return;
+       }
+       if ((mpt3sas_config_get_number_pds(ioc, raid_device->handle,
+           &num_pds)) || !num_pds) {
+               pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled "
+                   "Failure in computing number of drives\n", ioc->name);
+               return;
+       }
+
+       sz = offsetof(Mpi2RaidVolPage0_t, PhysDisk) + (num_pds *
+           sizeof(Mpi2RaidVol0PhysDisk_t));
+       vol_pg0 = kzalloc(sz, GFP_KERNEL);
+       if (!vol_pg0) {
+               pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled "
+                   "Memory allocation failure for RVPG0\n", ioc->name);
+               return;
+       }
+
+       if ((mpt3sas_config_get_raid_volume_pg0(ioc, &mpi_reply, vol_pg0,
+            MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, sz))) {
+               pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled "
+                   "Failure in retrieving RVPG0\n", ioc->name);
+               kfree(vol_pg0);
+               return;
+       }
+
+       /*
+        * WARPDRIVE:If number of physical disks in a volume exceeds the max pds
+        * assumed for WARPDRIVE, disable direct I/O
+        */
+       if (num_pds > MPT_MAX_WARPDRIVE_PDS) {
+               pr_warn(MPT3SAS_FMT "WarpDrive : Direct IO is disabled "
+                   "for the drive with handle(0x%04x): num_mem=%d, "
+                   "max_mem_allowed=%d\n", ioc->name, raid_device->handle,
+                   num_pds, MPT_MAX_WARPDRIVE_PDS);
+               kfree(vol_pg0);
+               return;
+       }
+       for (count = 0; count < num_pds; count++) {
+               if (mpt3sas_config_get_phys_disk_pg0(ioc, &mpi_reply,
+                   &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_PHYSDISKNUM,
+                   vol_pg0->PhysDisk[count].PhysDiskNum) ||
+                   pd_pg0.DevHandle == MPT3SAS_INVALID_DEVICE_HANDLE) {
+                       pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is "
+                           "disabled for the drive with handle(0x%04x) member"
+                           "handle retrieval failed for member number=%d\n",
+                           ioc->name, raid_device->handle,
+                           vol_pg0->PhysDisk[count].PhysDiskNum);
+                       goto out_error;
+               }
+               /* Disable direct I/O if member drive lba exceeds 4 bytes */
+               dev_max_lba = le64_to_cpu(pd_pg0.DeviceMaxLBA);
+               if (dev_max_lba >> 32) {
+                       pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is "
+                           "disabled for the drive with handle(0x%04x) member"
+                           " handle (0x%04x) unsupported max lba 0x%016llx\n",
+                           ioc->name, raid_device->handle,
+                           le16_to_cpu(pd_pg0.DevHandle),
+                           (unsigned long long)dev_max_lba);
+                       goto out_error;
+               }
+
+               raid_device->pd_handle[count] = le16_to_cpu(pd_pg0.DevHandle);
+       }
+
+       /*
+        * Assumption for WD: Direct I/O is not supported if the volume is
+        * not RAID0
+        */
+       if (raid_device->volume_type != MPI2_RAID_VOL_TYPE_RAID0) {
+               pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled "
+                   "for the drive with handle(0x%04x): type=%d, "
+                   "s_sz=%uK, blk_size=%u\n", ioc->name,
+                   raid_device->handle, raid_device->volume_type,
+                   (le32_to_cpu(vol_pg0->StripeSize) *
+                   le16_to_cpu(vol_pg0->BlockSize)) / 1024,
+                   le16_to_cpu(vol_pg0->BlockSize));
+               goto out_error;
+       }
+
+       stripe_sz = le32_to_cpu(vol_pg0->StripeSize);
+       stripe_exp = find_first_bit(&stripe_sz, 32);
+       if (stripe_exp == 32) {
+               pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled "
+               "for the drive with handle(0x%04x) invalid stripe sz %uK\n",
+                   ioc->name, raid_device->handle,
+                   (le32_to_cpu(vol_pg0->StripeSize) *
+                   le16_to_cpu(vol_pg0->BlockSize)) / 1024);
+               goto out_error;
+       }
+       raid_device->stripe_exponent = stripe_exp;
+       block_sz = le16_to_cpu(vol_pg0->BlockSize);
+       block_exp = find_first_bit(&block_sz, 16);
+       if (block_exp == 16) {
+               pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled "
+                   "for the drive with handle(0x%04x) invalid block sz %u\n",
+                   ioc->name, raid_device->handle,
+                   le16_to_cpu(vol_pg0->BlockSize));
+               goto out_error;
+       }
+       raid_device->block_exponent = block_exp;
+       raid_device->direct_io_enabled = 1;
+
+       pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is Enabled for the drive"
+           " with handle(0x%04x)\n", ioc->name, raid_device->handle);
+       /*
+        * WARPDRIVE: Though the following fields are not used for direct IO,
+        * stored for future purpose:
+        */
+       raid_device->max_lba = le64_to_cpu(vol_pg0->MaxLBA);
+       raid_device->stripe_sz = le32_to_cpu(vol_pg0->StripeSize);
+       raid_device->block_sz = le16_to_cpu(vol_pg0->BlockSize);
+
+
+       kfree(vol_pg0);
+       return;
+
+out_error:
+       raid_device->direct_io_enabled = 0;
+       for (count = 0; count < num_pds; count++)
+               raid_device->pd_handle[count] = 0;
+       kfree(vol_pg0);
+       return;
+}
+
+/**
+ * mpt3sas_scsi_direct_io_get - returns direct io flag
+ * @ioc: per adapter object
+ * @smid: system request message index
+ *
+ * Returns the smid stored scmd pointer.
+ */
+inline u8
+mpt3sas_scsi_direct_io_get(struct MPT3SAS_ADAPTER *ioc, u16 smid)
+{
+       return ioc->scsi_lookup[smid - 1].direct_io;
+}
+
+/**
+ * mpt3sas_scsi_direct_io_set - sets direct io flag
+ * @ioc: per adapter object
+ * @smid: system request message index
+ * @direct_io: Zero or non-zero value to set in the direct_io flag
+ *
+ * Returns Nothing.
+ */
+inline void
+mpt3sas_scsi_direct_io_set(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 direct_io)
+{
+       ioc->scsi_lookup[smid - 1].direct_io = direct_io;
+}
+
+/**
+ * mpt3sas_setup_direct_io - setup MPI request for WARPDRIVE Direct I/O
+ * @ioc: per adapter object
+ * @scmd: pointer to scsi command object
+ * @raid_device: pointer to raid device data structure
+ * @mpi_request: pointer to the SCSI_IO reqest message frame
+ * @smid: system request message index
+ *
+ * Returns nothing
+ */
+void
+mpt3sas_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
+       struct _raid_device *raid_device, Mpi2SCSIIORequest_t *mpi_request,
+       u16 smid)
+{
+       sector_t v_lba, p_lba, stripe_off, column, io_size;
+       u32 stripe_sz, stripe_exp;
+       u8 num_pds, cmd = scmd->cmnd[0];
+
+       if (cmd != READ_10 && cmd != WRITE_10 &&
+           cmd != READ_16 && cmd != WRITE_16)
+               return;
+
+       if (cmd == READ_10 || cmd == WRITE_10)
+               v_lba = get_unaligned_be32(&mpi_request->CDB.CDB32[2]);
+       else
+               v_lba = get_unaligned_be64(&mpi_request->CDB.CDB32[2]);
+
+       io_size = scsi_bufflen(scmd) >> raid_device->block_exponent;
+
+       if (v_lba + io_size - 1 > raid_device->max_lba)
+               return;
+
+       stripe_sz = raid_device->stripe_sz;
+       stripe_exp = raid_device->stripe_exponent;
+       stripe_off = v_lba & (stripe_sz - 1);
+
+       /* Return unless IO falls within a stripe */
+       if (stripe_off + io_size > stripe_sz)
+               return;
+
+       num_pds = raid_device->num_pds;
+       p_lba = v_lba >> stripe_exp;
+       column = sector_div(p_lba, num_pds);
+       p_lba = (p_lba << stripe_exp) + stripe_off;
+       mpi_request->DevHandle = cpu_to_le16(raid_device->pd_handle[column]);
+
+       if (cmd == READ_10 || cmd == WRITE_10)
+               put_unaligned_be32(lower_32_bits(p_lba),
+                                  &mpi_request->CDB.CDB32[2]);
+       else
+               put_unaligned_be64(p_lba, &mpi_request->CDB.CDB32[2]);
+
+       mpt3sas_scsi_direct_io_set(ioc, smid, 1);
+}
index e2d555c1bffc16f94a87ed6b009d868cc3784a3e..90fdf0e859e31fd9e72352d2ed19a889061e6ed4 100644 (file)
@@ -65,7 +65,6 @@ static struct scsi_host_template mvs_sht = {
        .target_destroy         = sas_target_destroy,
        .ioctl                  = sas_ioctl,
        .shost_attrs            = mvst_host_attrs,
-       .use_blk_tags           = 1,
        .track_queue_depth      = 1,
 };
 
@@ -641,9 +640,9 @@ static void mvs_pci_remove(struct pci_dev *pdev)
        tasklet_kill(&((struct mvs_prv_info *)sha->lldd_ha)->mv_tasklet);
 #endif
 
+       scsi_remove_host(mvi->shost);
        sas_unregister_ha(sha);
        sas_remove_host(mvi->shost);
-       scsi_remove_host(mvi->shost);
 
        MVS_CHIP_DISP->interrupt_disable(mvi);
        free_irq(mvi->pdev->irq, sha);
index 3e6b866759fef68dd80eac70ea4e35e56f955f92..02360de6b7e0dd8bd59bf7fe40e3e173d1fe7d0f 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/ktime.h>
 #include <linux/blkdev.h>
 #include <linux/io.h>
 #include <scsi/scsi.h>
@@ -858,8 +859,8 @@ static void mvumi_hs_build_page(struct mvumi_hba *mhba,
        struct mvumi_hs_page2 *hs_page2;
        struct mvumi_hs_page4 *hs_page4;
        struct mvumi_hs_page3 *hs_page3;
-       struct timeval time;
-       unsigned int local_time;
+       u64 time;
+       u64 local_time;
 
        switch (hs_header->page_code) {
        case HS_PAGE_HOST_INFO:
@@ -877,9 +878,8 @@ static void mvumi_hs_build_page(struct mvumi_hba *mhba,
                hs_page2->slot_number = 0;
                hs_page2->intr_level = 0;
                hs_page2->intr_vector = 0;
-               do_gettimeofday(&time);
-               local_time = (unsigned int) (time.tv_sec -
-                                               (sys_tz.tz_minuteswest * 60));
+               time = ktime_get_real_seconds();
+               local_time = (time - (sys_tz.tz_minuteswest * 60));
                hs_page2->seconds_since1970 = local_time;
                hs_header->checksum = mvumi_calculate_checksum(hs_header,
                                                hs_header->frame_length);
index f14ec6e042b9ae240b9c5984688325b746496347..199527dbaaa14fa84c48deb122c9b71d1c1b171c 100644 (file)
@@ -51,6 +51,8 @@ enum chip_flavors {
        chip_8076,
        chip_8077,
        chip_8006,
+       chip_8070,
+       chip_8072
 };
 
 enum phy_speed {
index 5c0356fb6310ecfeb5c39cafe9bc75c7cb354002..062ab34b86f8bcab08d24b8cfe1e4dffa938939d 100644 (file)
@@ -58,6 +58,8 @@ static const struct pm8001_chip_info pm8001_chips[] = {
        [chip_8076] = {0,  16, &pm8001_80xx_dispatch,},
        [chip_8077] = {0,  16, &pm8001_80xx_dispatch,},
        [chip_8006] = {0,  16, &pm8001_80xx_dispatch,},
+       [chip_8070] = {0,  8, &pm8001_80xx_dispatch,},
+       [chip_8072] = {0,  16, &pm8001_80xx_dispatch,},
 };
 static int pm8001_id;
 
@@ -88,7 +90,6 @@ static struct scsi_host_template pm8001_sht = {
        .target_destroy         = sas_target_destroy,
        .ioctl                  = sas_ioctl,
        .shost_attrs            = pm8001_host_attrs,
-       .use_blk_tags           = 1,
        .track_queue_depth      = 1,
 };
 
@@ -480,7 +481,8 @@ static struct pm8001_hba_info *pm8001_pci_alloc(struct pci_dev *pdev,
 
 #ifdef PM8001_USE_TASKLET
        /* Tasklet for non msi-x interrupt handler */
-       if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001))
+       if ((!pdev->msix_cap || !pci_msi_enabled())
+           || (pm8001_ha->chip_id == chip_8001))
                tasklet_init(&pm8001_ha->tasklet[0], pm8001_tasklet,
                        (unsigned long)&(pm8001_ha->irq_vector[0]));
        else
@@ -634,6 +636,11 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha)
                        payload.minor_function = 0;
                        payload.length = 128;
                }
+       } else if ((pm8001_ha->chip_id == chip_8070 ||
+                       pm8001_ha->chip_id == chip_8072) &&
+                       pm8001_ha->pdev->subsystem_vendor == PCI_VENDOR_ID_ATTO) {
+               payload.minor_function = 4;
+               payload.length = 4096;
        } else {
                payload.minor_function = 1;
                payload.length = 4096;
@@ -660,6 +667,11 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha)
                        else if (deviceid == 0x0042)
                                pm8001_ha->sas_addr[j] =
                                        payload.func_specific[0x010 + i];
+               } else if ((pm8001_ha->chip_id == chip_8070 ||
+                               pm8001_ha->chip_id == chip_8072) &&
+                               pm8001_ha->pdev->subsystem_vendor == PCI_VENDOR_ID_ATTO) {
+                       pm8001_ha->sas_addr[j] =
+                                       payload.func_specific[0x010 + i];
                } else
                        pm8001_ha->sas_addr[j] =
                                        payload.func_specific[0x804 + i];
@@ -720,6 +732,153 @@ static int pm8001_get_phy_settings_info(struct pm8001_hba_info *pm8001_ha)
        return 0;
 }
 
+struct pm8001_mpi3_phy_pg_trx_config {
+       u32 LaneLosCfg;
+       u32 LanePgaCfg1;
+       u32 LanePisoCfg1;
+       u32 LanePisoCfg2;
+       u32 LanePisoCfg3;
+       u32 LanePisoCfg4;
+       u32 LanePisoCfg5;
+       u32 LanePisoCfg6;
+       u32 LaneBctCtrl;
+};
+
+/**
+ * pm8001_get_internal_phy_settings : Retrieves the internal PHY settings
+ * @pm8001_ha : our adapter
+ * @phycfg : PHY config page to populate
+ */
+static
+void pm8001_get_internal_phy_settings(struct pm8001_hba_info *pm8001_ha,
+               struct pm8001_mpi3_phy_pg_trx_config *phycfg)
+{
+       phycfg->LaneLosCfg   = 0x00000132;
+       phycfg->LanePgaCfg1  = 0x00203949;
+       phycfg->LanePisoCfg1 = 0x000000FF;
+       phycfg->LanePisoCfg2 = 0xFF000001;
+       phycfg->LanePisoCfg3 = 0xE7011300;
+       phycfg->LanePisoCfg4 = 0x631C40C0;
+       phycfg->LanePisoCfg5 = 0xF8102036;
+       phycfg->LanePisoCfg6 = 0xF74A1000;
+       phycfg->LaneBctCtrl  = 0x00FB33F8;
+}
+
+/**
+ * pm8001_get_external_phy_settings : Retrieves the external PHY settings
+ * @pm8001_ha : our adapter
+ * @phycfg : PHY config page to populate
+ */
+static
+void pm8001_get_external_phy_settings(struct pm8001_hba_info *pm8001_ha,
+               struct pm8001_mpi3_phy_pg_trx_config *phycfg)
+{
+       phycfg->LaneLosCfg   = 0x00000132;
+       phycfg->LanePgaCfg1  = 0x00203949;
+       phycfg->LanePisoCfg1 = 0x000000FF;
+       phycfg->LanePisoCfg2 = 0xFF000001;
+       phycfg->LanePisoCfg3 = 0xE7011300;
+       phycfg->LanePisoCfg4 = 0x63349140;
+       phycfg->LanePisoCfg5 = 0xF8102036;
+       phycfg->LanePisoCfg6 = 0xF80D9300;
+       phycfg->LaneBctCtrl  = 0x00FB33F8;
+}
+
+/**
+ * pm8001_get_phy_mask : Retrieves the mask that denotes if a PHY is int/ext
+ * @pm8001_ha : our adapter
+ * @phymask : The PHY mask
+ */
+static
+void pm8001_get_phy_mask(struct pm8001_hba_info *pm8001_ha, int *phymask)
+{
+       switch (pm8001_ha->pdev->subsystem_device) {
+       case 0x0070: /* H1280 - 8 external 0 internal */
+       case 0x0072: /* H12F0 - 16 external 0 internal */
+               *phymask = 0x0000;
+               break;
+
+       case 0x0071: /* H1208 - 0 external 8 internal */
+       case 0x0073: /* H120F - 0 external 16 internal */
+               *phymask = 0xFFFF;
+               break;
+
+       case 0x0080: /* H1244 - 4 external 4 internal */
+               *phymask = 0x00F0;
+               break;
+
+       case 0x0081: /* H1248 - 4 external 8 internal */
+               *phymask = 0x0FF0;
+               break;
+
+       case 0x0082: /* H1288 - 8 external 8 internal */
+               *phymask = 0xFF00;
+               break;
+
+       default:
+               PM8001_INIT_DBG(pm8001_ha,
+                       pm8001_printk("Unknown subsystem device=0x%.04x",
+                               pm8001_ha->pdev->subsystem_device));
+       }
+}
+
+/**
+ * pm8001_set_phy_settings_ven_117c_12Gb : Configure ATTO 12Gb PHY settings
+ * @pm8001_ha : our adapter
+ */
+static
+int pm8001_set_phy_settings_ven_117c_12G(struct pm8001_hba_info *pm8001_ha)
+{
+       struct pm8001_mpi3_phy_pg_trx_config phycfg_int;
+       struct pm8001_mpi3_phy_pg_trx_config phycfg_ext;
+       int phymask = 0;
+       int i = 0;
+
+       memset(&phycfg_int, 0, sizeof(phycfg_int));
+       memset(&phycfg_ext, 0, sizeof(phycfg_ext));
+
+       pm8001_get_internal_phy_settings(pm8001_ha, &phycfg_int);
+       pm8001_get_external_phy_settings(pm8001_ha, &phycfg_ext);
+       pm8001_get_phy_mask(pm8001_ha, &phymask);
+
+       for (i = 0; i < pm8001_ha->chip->n_phy; i++) {
+               if (phymask & (1 << i)) {/* Internal PHY */
+                       pm8001_set_phy_profile_single(pm8001_ha, i,
+                                       sizeof(phycfg_int) / sizeof(u32),
+                                       (u32 *)&phycfg_int);
+
+               } else { /* External PHY */
+                       pm8001_set_phy_profile_single(pm8001_ha, i,
+                                       sizeof(phycfg_ext) / sizeof(u32),
+                                       (u32 *)&phycfg_ext);
+               }
+       }
+
+       return 0;
+}
+
+/**
+ * pm8001_configure_phy_settings : Configures PHY settings based on vendor ID.
+ * @pm8001_ha : our hba.
+ */
+static int pm8001_configure_phy_settings(struct pm8001_hba_info *pm8001_ha)
+{
+       switch (pm8001_ha->pdev->subsystem_vendor) {
+       case PCI_VENDOR_ID_ATTO:
+               if (pm8001_ha->pdev->device == 0x0042) /* 6Gb */
+                       return 0;
+               else
+                       return pm8001_set_phy_settings_ven_117c_12G(pm8001_ha);
+
+       case PCI_VENDOR_ID_ADAPTEC2:
+       case 0:
+               return 0;
+
+       default:
+               return pm8001_get_phy_settings_info(pm8001_ha);
+       }
+}
+
 #ifdef PM8001_USE_MSIX
 /**
  * pm8001_setup_msix - enable MSI-X interrupt
@@ -792,7 +951,7 @@ static u32 pm8001_request_irq(struct pm8001_hba_info *pm8001_ha)
        pdev = pm8001_ha->pdev;
 
 #ifdef PM8001_USE_MSIX
-       if (pdev->msix_cap)
+       if (pdev->msix_cap && pci_msi_enabled())
                return pm8001_setup_msix(pm8001_ha);
        else {
                PM8001_INIT_DBG(pm8001_ha,
@@ -803,6 +962,8 @@ static u32 pm8001_request_irq(struct pm8001_hba_info *pm8001_ha)
 
 intx:
        /* initialize the INT-X interrupt */
+       pm8001_ha->irq_vector[0].irq_id = 0;
+       pm8001_ha->irq_vector[0].drv_inst = pm8001_ha;
        rc = request_irq(pdev->irq, pm8001_interrupt_handler_intx, IRQF_SHARED,
                DRV_NAME, SHOST_TO_SAS_HA(pm8001_ha->shost));
        return rc;
@@ -902,12 +1063,9 @@ static int pm8001_pci_probe(struct pci_dev *pdev,
 
        pm8001_init_sas_add(pm8001_ha);
        /* phy setting support for motherboard controller */
-       if (pdev->subsystem_vendor != PCI_VENDOR_ID_ADAPTEC2 &&
-               pdev->subsystem_vendor != 0) {
-               rc = pm8001_get_phy_settings_info(pm8001_ha);
-               if (rc)
-                       goto err_out_shost;
-       }
+       if (pm8001_configure_phy_settings(pm8001_ha))
+               goto err_out_shost;
+
        pm8001_post_sas_ha_init(shost, chip);
        rc = sas_register_ha(SHOST_TO_SAS_HA(shost));
        if (rc)
@@ -937,10 +1095,10 @@ static void pm8001_pci_remove(struct pci_dev *pdev)
        struct pm8001_hba_info *pm8001_ha;
        int i, j;
        pm8001_ha = sha->lldd_ha;
+       scsi_remove_host(pm8001_ha->shost);
        sas_unregister_ha(sha);
        sas_remove_host(pm8001_ha->shost);
        list_del(&pm8001_ha->list);
-       scsi_remove_host(pm8001_ha->shost);
        PM8001_CHIP_DISP->interrupt_disable(pm8001_ha, 0xFF);
        PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha);
 
@@ -956,7 +1114,8 @@ static void pm8001_pci_remove(struct pci_dev *pdev)
 #endif
 #ifdef PM8001_USE_TASKLET
        /* For non-msix and msix interrupts */
-       if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001))
+       if ((!pdev->msix_cap || !pci_msi_enabled()) ||
+           (pm8001_ha->chip_id == chip_8001))
                tasklet_kill(&pm8001_ha->tasklet[0]);
        else
                for (j = 0; j < PM8001_MAX_MSIX_VEC; j++)
@@ -1005,7 +1164,8 @@ static int pm8001_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 #endif
 #ifdef PM8001_USE_TASKLET
        /* For non-msix and msix interrupts */
-       if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001))
+       if ((!pdev->msix_cap || !pci_msi_enabled()) ||
+           (pm8001_ha->chip_id == chip_8001))
                tasklet_kill(&pm8001_ha->tasklet[0]);
        else
                for (j = 0; j < PM8001_MAX_MSIX_VEC; j++)
@@ -1074,7 +1234,8 @@ static int pm8001_pci_resume(struct pci_dev *pdev)
                goto err_out_disable;
 #ifdef PM8001_USE_TASKLET
        /*  Tasklet for non msi-x interrupt handler */
-       if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001))
+       if ((!pdev->msix_cap || !pci_msi_enabled()) ||
+           (pm8001_ha->chip_id == chip_8001))
                tasklet_init(&pm8001_ha->tasklet[0], pm8001_tasklet,
                        (unsigned long)&(pm8001_ha->irq_vector[0]));
        else
@@ -1087,6 +1248,19 @@ static int pm8001_pci_resume(struct pci_dev *pdev)
                for (i = 1; i < pm8001_ha->number_of_intr; i++)
                        PM8001_CHIP_DISP->interrupt_enable(pm8001_ha, i);
        }
+
+       /* Chip documentation for the 8070 and 8072 SPCv    */
+       /* states that a 500ms minimum delay is required    */
+       /* before issuing commands.  Otherwise, the firmare */
+       /* will enter an unrecoverable state.               */
+
+       if (pm8001_ha->chip_id == chip_8070 ||
+               pm8001_ha->chip_id == chip_8072) {
+               mdelay(500);
+       }
+
+       /* Spin up the PHYs */
+
        pm8001_ha->flags = PM8001F_RUN_TIME;
        for (i = 0; i < pm8001_ha->chip->n_phy; i++) {
                pm8001_ha->phy[i].enable_completion = &completion;
@@ -1165,6 +1339,20 @@ static struct pci_device_id pm8001_pci_table[] = {
                PCI_VENDOR_ID_ADAPTEC2, 0x0808, 0, 0, chip_8077 },
        { PCI_VENDOR_ID_ADAPTEC2, 0x8074,
                PCI_VENDOR_ID_ADAPTEC2, 0x0404, 0, 0, chip_8074 },
+       { PCI_VENDOR_ID_ATTO, 0x8070,
+               PCI_VENDOR_ID_ATTO, 0x0070, 0, 0, chip_8070 },
+       { PCI_VENDOR_ID_ATTO, 0x8070,
+               PCI_VENDOR_ID_ATTO, 0x0071, 0, 0, chip_8070 },
+       { PCI_VENDOR_ID_ATTO, 0x8072,
+               PCI_VENDOR_ID_ATTO, 0x0072, 0, 0, chip_8072 },
+       { PCI_VENDOR_ID_ATTO, 0x8072,
+               PCI_VENDOR_ID_ATTO, 0x0073, 0, 0, chip_8072 },
+       { PCI_VENDOR_ID_ATTO, 0x8070,
+               PCI_VENDOR_ID_ATTO, 0x0080, 0, 0, chip_8070 },
+       { PCI_VENDOR_ID_ATTO, 0x8072,
+               PCI_VENDOR_ID_ATTO, 0x0081, 0, 0, chip_8072 },
+       { PCI_VENDOR_ID_ATTO, 0x8072,
+               PCI_VENDOR_ID_ATTO, 0x0082, 0, 0, chip_8072 },
        {} /* terminate list */
 };
 
@@ -1220,7 +1408,7 @@ MODULE_AUTHOR("Anand Kumar Santhanam <AnandKumar.Santhanam@pmcs.com>");
 MODULE_AUTHOR("Sangeetha Gnanasekaran <Sangeetha.Gnanasekaran@pmcs.com>");
 MODULE_AUTHOR("Nikith Ganigarakoppal <Nikith.Ganigarakoppal@pmcs.com>");
 MODULE_DESCRIPTION(
-               "PMC-Sierra PM8001/8006/8081/8088/8089/8074/8076/8077 "
+               "PMC-Sierra PM8001/8006/8081/8088/8089/8074/8076/8077/8070/8072 "
                "SAS/SATA controller driver");
 MODULE_VERSION(DRV_VERSION);
 MODULE_LICENSE("GPL");
index e2e97db38ae8c73e0c8f2064cb7cd5bc28932060..6628cc38316c2ef5871ef81db4d9fe772e402fee 100644 (file)
@@ -106,7 +106,9 @@ do {                                                \
 #define DEV_IS_EXPANDER(type)  ((type == SAS_EDGE_EXPANDER_DEVICE) || (type == SAS_FANOUT_EXPANDER_DEVICE))
 #define IS_SPCV_12G(dev)       ((dev->device == 0X8074)                \
                                || (dev->device == 0X8076)              \
-                               || (dev->device == 0X8077))
+                               || (dev->device == 0X8077)              \
+                               || (dev->device == 0X8070)              \
+                               || (dev->device == 0X8072))
 
 #define PM8001_NAME_LENGTH             32/* generic length of strings */
 extern struct list_head hba_list;
@@ -708,6 +710,8 @@ int pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha);
 int pm8001_bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shiftValue);
 void pm8001_set_phy_profile(struct pm8001_hba_info *pm8001_ha,
        u32 length, u8 *buf);
+void pm8001_set_phy_profile_single(struct pm8001_hba_info *pm8001_ha,
+               u32 phy, u32 length, u32 *buf);
 int pm80xx_bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shiftValue);
 ssize_t pm80xx_get_fatal_dump(struct device *cdev,
                struct device_attribute *attr, char *buf);
index 9a389f1508de8518cf08b0b62dee1c42251a2907..eb4fee61df729f700c8db790a632b9fe3b146324 100644 (file)
@@ -1267,6 +1267,8 @@ pm80xx_chip_soft_rst(struct pm8001_hba_info *pm8001_ha)
                /* check iButton feature support for motherboard controller */
                if (pm8001_ha->pdev->subsystem_vendor !=
                        PCI_VENDOR_ID_ADAPTEC2 &&
+                       pm8001_ha->pdev->subsystem_vendor !=
+                       PCI_VENDOR_ID_ATTO &&
                        pm8001_ha->pdev->subsystem_vendor != 0) {
                        ibutton0 = pm8001_cr32(pm8001_ha, 0,
                                        MSGU_HOST_SCRATCH_PAD_6);
@@ -4576,6 +4578,38 @@ void pm8001_set_phy_profile(struct pm8001_hba_info *pm8001_ha,
        }
        PM8001_INIT_DBG(pm8001_ha, pm8001_printk("phy settings completed\n"));
 }
+
+void pm8001_set_phy_profile_single(struct pm8001_hba_info *pm8001_ha,
+               u32 phy, u32 length, u32 *buf)
+{
+       u32 tag, opc;
+       int rc, i;
+       struct set_phy_profile_req payload;
+       struct inbound_queue_table *circularQ;
+
+       memset(&payload, 0, sizeof(payload));
+
+       rc = pm8001_tag_alloc(pm8001_ha, &tag);
+       if (rc)
+               PM8001_INIT_DBG(pm8001_ha, pm8001_printk("Invalid tag"));
+
+       circularQ = &pm8001_ha->inbnd_q_tbl[0];
+       opc = OPC_INB_SET_PHY_PROFILE;
+
+       payload.tag = cpu_to_le32(tag);
+       payload.ppc_phyid = (((SAS_PHY_ANALOG_SETTINGS_PAGE & 0xF) << 8)
+                               | (phy & 0xFF));
+
+       for (i = 0; i < length; i++)
+               payload.reserved[i] = cpu_to_le32(*(buf + i));
+
+       rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0);
+       if (rc)
+               pm8001_tag_free(pm8001_ha, tag);
+
+       PM8001_INIT_DBG(pm8001_ha,
+               pm8001_printk("PHY %d settings applied", phy));
+}
 const struct pm8001_dispatch pm8001_80xx_dispatch = {
        .name                   = "pmc80xx",
        .chip_init              = pm80xx_chip_init,
index ed31d8cc62665cf919d6b31d3bad01c275104362..b2a88200fe546b2243574b90422cb52da73b10fb 100644 (file)
@@ -45,6 +45,7 @@
 #include <asm/processor.h>
 #include <linux/libata.h>
 #include <linux/mutex.h>
+#include <linux/ktime.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_device.h>
@@ -4254,7 +4255,6 @@ static struct scsi_host_template pmcraid_host_template = {
        .use_clustering = ENABLE_CLUSTERING,
        .shost_attrs = pmcraid_host_attrs,
        .proc_name = PMCRAID_DRIVER_NAME,
-       .use_blk_tags = 1,
 };
 
 /*
@@ -5563,11 +5563,9 @@ static void pmcraid_set_timestamp(struct pmcraid_cmd *cmd)
        __be32 time_stamp_len = cpu_to_be32(PMCRAID_TIMESTAMP_LEN);
        struct pmcraid_ioadl_desc *ioadl = ioarcb->add_data.u.ioadl;
 
-       struct timeval tv;
        __le64 timestamp;
 
-       do_gettimeofday(&tv);
-       timestamp = tv.tv_sec * 1000;
+       timestamp = ktime_get_real_seconds() * 1000;
 
        pinstance->timestamp_data->timestamp[0] = (__u8)(timestamp);
        pinstance->timestamp_data->timestamp[1] = (__u8)((timestamp) >> 8);
index c2dd17b1d26fa6b275268256623a167a8682019d..bfa9a64c316b6ca2eec9a1b2277608f68101d92d 100644 (file)
@@ -267,7 +267,6 @@ struct scsi_host_template qla2xxx_driver_template = {
        .shost_attrs            = qla2x00_host_attrs,
 
        .supported_mode         = MODE_INITIATOR,
-       .use_blk_tags           = 1,
        .track_queue_depth      = 1,
 };
 
index ac65cb7b48861b81dc1daa0ea531e506cb5752fa..3ba2e9564b9a78f000c234fa1be7bb05e24eaebd 100644 (file)
@@ -43,8 +43,6 @@
 #include <scsi/scsi_cmnd.h>
 #include <target/target_core_base.h>
 #include <target/target_core_fabric.h>
-#include <target/target_core_fabric_configfs.h>
-#include <target/configfs_macros.h>
 
 #include "qla_def.h"
 #include "qla_target.h"
@@ -729,23 +727,23 @@ static int tcm_qla2xxx_init_nodeacl(struct se_node_acl *se_nacl,
 
 #define DEF_QLA_TPG_ATTRIB(name)                                       \
                                                                        \
-static ssize_t tcm_qla2xxx_tpg_attrib_show_##name(                     \
-       struct se_portal_group *se_tpg,                                 \
-       char *page)                                                     \
+static ssize_t tcm_qla2xxx_tpg_attrib_##name##_show(                   \
+               struct config_item *item, char *page)                   \
 {                                                                      \
+       struct se_portal_group *se_tpg = attrib_to_tpg(item);           \
        struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,              \
                        struct tcm_qla2xxx_tpg, se_tpg);                \
                                                                        \
        return sprintf(page, "%u\n", tpg->tpg_attrib.name);     \
 }                                                                      \
                                                                        \
-static ssize_t tcm_qla2xxx_tpg_attrib_store_##name(                    \
-       struct se_portal_group *se_tpg,                                 \
-       const char *page,                                               \
-       size_t count)                                                   \
+static ssize_t tcm_qla2xxx_tpg_attrib_##name##_store(                  \
+               struct config_item *item, const char *page, size_t count) \
 {                                                                      \
+       struct se_portal_group *se_tpg = attrib_to_tpg(item);           \
        struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,              \
                        struct tcm_qla2xxx_tpg, se_tpg);                \
+       struct tcm_qla2xxx_tpg_attrib *a = &tpg->tpg_attrib;            \
        unsigned long val;                                              \
        int ret;                                                        \
                                                                        \
@@ -755,81 +753,39 @@ static ssize_t tcm_qla2xxx_tpg_attrib_store_##name(                       \
                                " ret: %d\n", ret);                     \
                return -EINVAL;                                         \
        }                                                               \
-       ret = tcm_qla2xxx_set_attrib_##name(tpg, val);                  \
-                                                                       \
-       return (!ret) ? count : -EINVAL;                                \
-}
-
-#define DEF_QLA_TPG_ATTR_BOOL(_name)                                   \
-                                                                       \
-static int tcm_qla2xxx_set_attrib_##_name(                             \
-       struct tcm_qla2xxx_tpg *tpg,                                    \
-       unsigned long val)                                              \
-{                                                                      \
-       struct tcm_qla2xxx_tpg_attrib *a = &tpg->tpg_attrib;            \
                                                                        \
        if ((val != 0) && (val != 1)) {                                 \
                pr_err("Illegal boolean value %lu\n", val);             \
                return -EINVAL;                                         \
        }                                                               \
                                                                        \
-       a->_name = val;                                                 \
-       return 0;                                                       \
-}
-
-#define QLA_TPG_ATTR(_name, _mode) \
-       TF_TPG_ATTRIB_ATTR(tcm_qla2xxx, _name, _mode);
+       a->name = val;                                                  \
+                                                                       \
+       return count;                                                   \
+}                                                                      \
+CONFIGFS_ATTR(tcm_qla2xxx_tpg_attrib_, name)
 
-/*
- * Define tcm_qla2xxx_tpg_attrib_s_generate_node_acls
- */
-DEF_QLA_TPG_ATTR_BOOL(generate_node_acls);
 DEF_QLA_TPG_ATTRIB(generate_node_acls);
-QLA_TPG_ATTR(generate_node_acls, S_IRUGO | S_IWUSR);
-
-/*
- Define tcm_qla2xxx_attrib_s_cache_dynamic_acls
- */
-DEF_QLA_TPG_ATTR_BOOL(cache_dynamic_acls);
 DEF_QLA_TPG_ATTRIB(cache_dynamic_acls);
-QLA_TPG_ATTR(cache_dynamic_acls, S_IRUGO | S_IWUSR);
-
-/*
- * Define tcm_qla2xxx_tpg_attrib_s_demo_mode_write_protect
- */
-DEF_QLA_TPG_ATTR_BOOL(demo_mode_write_protect);
 DEF_QLA_TPG_ATTRIB(demo_mode_write_protect);
-QLA_TPG_ATTR(demo_mode_write_protect, S_IRUGO | S_IWUSR);
-
-/*
- * Define tcm_qla2xxx_tpg_attrib_s_prod_mode_write_protect
- */
-DEF_QLA_TPG_ATTR_BOOL(prod_mode_write_protect);
 DEF_QLA_TPG_ATTRIB(prod_mode_write_protect);
-QLA_TPG_ATTR(prod_mode_write_protect, S_IRUGO | S_IWUSR);
-
-/*
- * Define tcm_qla2xxx_tpg_attrib_s_demo_mode_login_only
- */
-DEF_QLA_TPG_ATTR_BOOL(demo_mode_login_only);
 DEF_QLA_TPG_ATTRIB(demo_mode_login_only);
-QLA_TPG_ATTR(demo_mode_login_only, S_IRUGO | S_IWUSR);
 
 static struct configfs_attribute *tcm_qla2xxx_tpg_attrib_attrs[] = {
-       &tcm_qla2xxx_tpg_attrib_generate_node_acls.attr,
-       &tcm_qla2xxx_tpg_attrib_cache_dynamic_acls.attr,
-       &tcm_qla2xxx_tpg_attrib_demo_mode_write_protect.attr,
-       &tcm_qla2xxx_tpg_attrib_prod_mode_write_protect.attr,
-       &tcm_qla2xxx_tpg_attrib_demo_mode_login_only.attr,
+       &tcm_qla2xxx_tpg_attrib_attr_generate_node_acls,
+       &tcm_qla2xxx_tpg_attrib_attr_cache_dynamic_acls,
+       &tcm_qla2xxx_tpg_attrib_attr_demo_mode_write_protect,
+       &tcm_qla2xxx_tpg_attrib_attr_prod_mode_write_protect,
+       &tcm_qla2xxx_tpg_attrib_attr_demo_mode_login_only,
        NULL,
 };
 
 /* End items for tcm_qla2xxx_tpg_attrib_cit */
 
-static ssize_t tcm_qla2xxx_tpg_show_enable(
-       struct se_portal_group *se_tpg,
-       char *page)
+static ssize_t tcm_qla2xxx_tpg_enable_show(struct config_item *item,
+               char *page)
 {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
                        struct tcm_qla2xxx_tpg, se_tpg);
 
@@ -865,11 +821,10 @@ static void tcm_qla2xxx_undepend_tpg(struct work_struct *work)
        complete(&base_tpg->tpg_base_comp);
 }
 
-static ssize_t tcm_qla2xxx_tpg_store_enable(
-       struct se_portal_group *se_tpg,
-       const char *page,
-       size_t count)
+static ssize_t tcm_qla2xxx_tpg_enable_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
                        struct tcm_qla2xxx_tpg, se_tpg);
        unsigned long op;
@@ -909,22 +864,16 @@ static ssize_t tcm_qla2xxx_tpg_store_enable(
        return count;
 }
 
-TF_TPG_BASE_ATTR(tcm_qla2xxx, enable, S_IRUGO | S_IWUSR);
-
-static ssize_t tcm_qla2xxx_tpg_show_dynamic_sessions(
-       struct se_portal_group *se_tpg,
-       char *page)
+static ssize_t tcm_qla2xxx_tpg_dynamic_sessions_show(struct config_item *item,
+               char *page)
 {
-       return target_show_dynamic_sessions(se_tpg, page);
+       return target_show_dynamic_sessions(to_tpg(item), page);
 }
 
-TF_TPG_BASE_ATTR_RO(tcm_qla2xxx, dynamic_sessions);
-
-static ssize_t tcm_qla2xxx_tpg_store_fabric_prot_type(
-       struct se_portal_group *se_tpg,
-       const char *page,
-       size_t count)
+static ssize_t tcm_qla2xxx_tpg_fabric_prot_type_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
                                struct tcm_qla2xxx_tpg, se_tpg);
        unsigned long val;
@@ -943,21 +892,24 @@ static ssize_t tcm_qla2xxx_tpg_store_fabric_prot_type(
        return count;
 }
 
-static ssize_t tcm_qla2xxx_tpg_show_fabric_prot_type(
-       struct se_portal_group *se_tpg,
-       char *page)
+static ssize_t tcm_qla2xxx_tpg_fabric_prot_type_show(struct config_item *item,
+               char *page)
 {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
                                struct tcm_qla2xxx_tpg, se_tpg);
 
        return sprintf(page, "%d\n", tpg->tpg_attrib.fabric_prot_type);
 }
-TF_TPG_BASE_ATTR(tcm_qla2xxx, fabric_prot_type, S_IRUGO | S_IWUSR);
+
+CONFIGFS_ATTR_WO(tcm_qla2xxx_tpg_, enable);
+CONFIGFS_ATTR_RO(tcm_qla2xxx_tpg_, dynamic_sessions);
+CONFIGFS_ATTR(tcm_qla2xxx_tpg_, fabric_prot_type);
 
 static struct configfs_attribute *tcm_qla2xxx_tpg_attrs[] = {
-       &tcm_qla2xxx_tpg_enable.attr,
-       &tcm_qla2xxx_tpg_dynamic_sessions.attr,
-       &tcm_qla2xxx_tpg_fabric_prot_type.attr,
+       &tcm_qla2xxx_tpg_attr_enable,
+       &tcm_qla2xxx_tpg_attr_dynamic_sessions,
+       &tcm_qla2xxx_tpg_attr_fabric_prot_type,
        NULL,
 };
 
@@ -1030,18 +982,16 @@ static void tcm_qla2xxx_drop_tpg(struct se_portal_group *se_tpg)
        kfree(tpg);
 }
 
-static ssize_t tcm_qla2xxx_npiv_tpg_show_enable(
-       struct se_portal_group *se_tpg,
-       char *page)
+static ssize_t tcm_qla2xxx_npiv_tpg_enable_show(struct config_item *item,
+               char *page)
 {
-       return tcm_qla2xxx_tpg_show_enable(se_tpg, page);
+       return tcm_qla2xxx_tpg_enable_show(item, page);
 }
 
-static ssize_t tcm_qla2xxx_npiv_tpg_store_enable(
-       struct se_portal_group *se_tpg,
-       const char *page,
-       size_t count)
+static ssize_t tcm_qla2xxx_npiv_tpg_enable_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct se_wwn *se_wwn = se_tpg->se_tpg_wwn;
        struct tcm_qla2xxx_lport *lport = container_of(se_wwn,
                        struct tcm_qla2xxx_lport, lport_wwn);
@@ -1077,10 +1027,10 @@ static ssize_t tcm_qla2xxx_npiv_tpg_store_enable(
        return count;
 }
 
-TF_TPG_BASE_ATTR(tcm_qla2xxx_npiv, enable, S_IRUGO | S_IWUSR);
+CONFIGFS_ATTR(tcm_qla2xxx_npiv_tpg_, enable);
 
 static struct configfs_attribute *tcm_qla2xxx_npiv_tpg_attrs[] = {
-        &tcm_qla2xxx_npiv_tpg_enable.attr,
+        &tcm_qla2xxx_npiv_tpg_attr_enable,
         NULL,
 };
 
@@ -1783,9 +1733,8 @@ static void tcm_qla2xxx_npiv_drop_lport(struct se_wwn *wwn)
 }
 
 
-static ssize_t tcm_qla2xxx_wwn_show_attr_version(
-       struct target_fabric_configfs *tf,
-       char *page)
+static ssize_t tcm_qla2xxx_wwn_version_show(struct config_item *item,
+               char *page)
 {
        return sprintf(page,
            "TCM QLOGIC QLA2XXX NPIV capable fabric module %s on %s/%s on "
@@ -1793,10 +1742,10 @@ static ssize_t tcm_qla2xxx_wwn_show_attr_version(
            utsname()->machine);
 }
 
-TF_WWN_ATTR_RO(tcm_qla2xxx, version);
+CONFIGFS_ATTR_RO(tcm_qla2xxx_wwn_, version);
 
 static struct configfs_attribute *tcm_qla2xxx_wwn_attrs[] = {
-       &tcm_qla2xxx_wwn_version.attr,
+       &tcm_qla2xxx_wwn_attr_version,
        NULL,
 };
 
index 6d25879d87c8550893cdd8671db68d542cde64cb..01c3610a60cf0b767f7566fc97967158f5eeb618 100644 (file)
@@ -212,7 +212,6 @@ static struct scsi_host_template qla4xxx_driver_template = {
        .shost_attrs            = qla4xxx_host_attrs,
        .host_reset             = qla4xxx_host_reset,
        .vendor_id              = SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_QLOGIC,
-       .use_blk_tags           = 1,
 };
 
 static struct iscsi_transport qla4xxx_iscsi_transport = {
@@ -8697,13 +8696,6 @@ static int qla4xxx_probe_adapter(struct pci_dev *pdev,
        host->can_queue = MAX_SRBS ;
        host->transportt = qla4xxx_scsi_transport;
 
-       ret = scsi_init_shared_tag_map(host, MAX_SRBS);
-       if (ret) {
-               ql4_printk(KERN_WARNING, ha,
-                          "%s: scsi_init_shared_tag_map failed\n", __func__);
-               goto probe_failed;
-       }
-
        pci_set_drvdata(pdev, ha);
 
        ret = scsi_add_host(host, &pdev->dev);
index 207d6a7a1bd0bce29ca748c8f3a4cd2aee6ad97a..d07fb653f5dc3348c41bbc68597489d2c4b25180 100644 (file)
@@ -616,32 +616,11 @@ void scsi_finish_command(struct scsi_cmnd *cmd)
  */
 int scsi_change_queue_depth(struct scsi_device *sdev, int depth)
 {
-       unsigned long flags;
-
-       if (depth <= 0)
-               goto out;
-
-       spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
-
-       /*
-        * Check to see if the queue is managed by the block layer.
-        * If it is, and we fail to adjust the depth, exit.
-        *
-        * Do not resize the tag map if it is a host wide share bqt,
-        * because the size should be the hosts's can_queue. If there
-        * is more IO than the LLD's can_queue (so there are not enuogh
-        * tags) request_fn's host queue ready check will handle it.
-        */
-       if (!shost_use_blk_mq(sdev->host) && !sdev->host->bqt) {
-               if (blk_queue_tagged(sdev->request_queue) &&
-                   blk_queue_resize_tags(sdev->request_queue, depth) != 0)
-                       goto out_unlock;
+       if (depth > 0) {
+               sdev->queue_depth = depth;
+               wmb();
        }
 
-       sdev->queue_depth = depth;
-out_unlock:
-       spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);
-out:
        return sdev->queue_depth;
 }
 EXPORT_SYMBOL(scsi_change_queue_depth);
index f9f3f8203d42709d9957aa27b1be471acb612046..83245391e956bc6f351a668473debeba6121b71b 100644 (file)
@@ -55,6 +55,7 @@
  * Default timeout
  */
 #define SCSI_TIMEOUT (2*HZ)
+#define SCSI_REPORT_LUNS_TIMEOUT (30*HZ)
 
 /*
  * Prefix values for the SCSI id's (stored in sysfs name field)
@@ -274,8 +275,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
        WARN_ON_ONCE(!blk_get_queue(sdev->request_queue));
        sdev->request_queue->queuedata = sdev;
 
-       if (!shost_use_blk_mq(sdev->host) &&
-           (shost->bqt || shost->hostt->use_blk_tags)) {
+       if (!shost_use_blk_mq(sdev->host)) {
                blk_queue_init_tags(sdev->request_queue,
                                    sdev->host->cmd_per_lun, shost->bqt,
                                    shost->hostt->tag_alloc_policy);
@@ -1383,7 +1383,7 @@ retry:
 
                result = scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE,
                                          lun_data, length, &sshdr,
-                                         SCSI_TIMEOUT + 4 * HZ, 3, NULL);
+                                         SCSI_REPORT_LUNS_TIMEOUT, 3, NULL);
 
                SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev,
                                "scsi scan: REPORT LUNS"
@@ -1712,8 +1712,7 @@ static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost)
                return NULL;
 
        if (shost->async_scan) {
-               shost_printk(KERN_INFO, shost, "%s called twice\n", __func__);
-               dump_stack();
+               shost_printk(KERN_DEBUG, shost, "%s called twice\n", __func__);
                return NULL;
        }
 
index dff8fafb741c1bff625131e73e7fe4425375ced2..8d2312239ae0cda01238ae549f0ae8007de233ea 100644 (file)
@@ -775,6 +775,29 @@ static struct bin_attribute dev_attr_vpd_##_page = {               \
 sdev_vpd_pg_attr(pg83);
 sdev_vpd_pg_attr(pg80);
 
+static ssize_t show_inquiry(struct file *filep, struct kobject *kobj,
+                           struct bin_attribute *bin_attr,
+                           char *buf, loff_t off, size_t count)
+{
+       struct device *dev = container_of(kobj, struct device, kobj);
+       struct scsi_device *sdev = to_scsi_device(dev);
+
+       if (!sdev->inquiry)
+               return -EINVAL;
+
+       return memory_read_from_buffer(buf, count, &off, sdev->inquiry,
+                                      sdev->inquiry_len);
+}
+
+static struct bin_attribute dev_attr_inquiry = {
+       .attr = {
+               .name = "inquiry",
+               .mode = S_IRUGO,
+       },
+       .size = 0,
+       .read = show_inquiry,
+};
+
 static ssize_t
 show_iostat_counterbits(struct device *dev, struct device_attribute *attr,
                        char *buf)
@@ -900,7 +923,7 @@ sdev_store_queue_ramp_up_period(struct device *dev,
                return -EINVAL;
 
        sdev->queue_ramp_up_period = msecs_to_jiffies(period);
-       return period;
+       return count;
 }
 
 static DEVICE_ATTR(queue_ramp_up_period, S_IRUGO | S_IWUSR,
@@ -959,6 +982,7 @@ static struct attribute *scsi_sdev_attrs[] = {
 static struct bin_attribute *scsi_sdev_bin_attrs[] = {
        &dev_attr_vpd_pg83,
        &dev_attr_vpd_pg80,
+       &dev_attr_inquiry,
        NULL
 };
 static struct attribute_group scsi_sdev_attr_group = {
@@ -1086,9 +1110,7 @@ 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
@@ -1099,6 +1121,16 @@ 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);
@@ -1160,31 +1192,23 @@ static void __scsi_remove_target(struct scsi_target *starget)
 void scsi_remove_target(struct device *dev)
 {
        struct Scsi_Host *shost = dev_to_shost(dev->parent);
-       struct scsi_target *starget, *last = NULL;
+       struct scsi_target *starget;
        unsigned long flags;
 
-       /* remove targets being careful to lookup next entry before
-        * deleting the last
-        */
+restart:
        spin_lock_irqsave(shost->host_lock, flags);
        list_for_each_entry(starget, &shost->__targets, siblings) {
                if (starget->state == STARGET_DEL)
                        continue;
                if (starget->dev.parent == dev || &starget->dev == dev) {
-                       /* assuming new targets arrive at the end */
                        kref_get(&starget->reap_ref);
                        spin_unlock_irqrestore(shost->host_lock, flags);
-                       if (last)
-                               scsi_target_reap(last);
-                       last = starget;
                        __scsi_remove_target(starget);
-                       spin_lock_irqsave(shost->host_lock, flags);
+                       scsi_target_reap(starget);
+                       goto restart;
                }
        }
        spin_unlock_irqrestore(shost->host_lock, flags);
-
-       if (last)
-               scsi_target_reap(last);
 }
 EXPORT_SYMBOL(scsi_remove_target);
 
index 5e170a6809fde2fe3c8c6ff51d382c2a570485ea..54519804c46a57b99ce680ee665b4fe28dd91148 100644 (file)
@@ -205,6 +205,7 @@ cache_type_store(struct device *dev, struct device_attribute *attr,
        buffer_data[2] &= ~0x05;
        buffer_data[2] |= wce << 2 | rcd;
        sp = buffer_data[0] & 0x80 ? 1 : 0;
+       buffer_data[0] &= ~0x80;
 
        if (scsi_mode_select(sdp, 1, sp, 8, buffer_data, len, SD_TIMEOUT,
                             SD_MAX_RETRIES, &data, &sshdr)) {
index 9d7b7db75e4b96b6fbb33bf24b91c205add07d79..503ab8b46c0b4e8a73d7e826ba1aaf3be1abd6b0 100644 (file)
@@ -787,8 +787,14 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp,
                return k;       /* probably out of space --> ENOMEM */
        }
        if (atomic_read(&sdp->detaching)) {
-               if (srp->bio)
+               if (srp->bio) {
+                       if (srp->rq->cmd != srp->rq->__cmd)
+                               kfree(srp->rq->cmd);
+
                        blk_end_request_all(srp->rq, -EIO);
+                       srp->rq = NULL;
+               }
+
                sg_finish_rem_req(srp);
                return -ENODEV;
        }
index b2b87cef00fcce3c2f765a71cd7020f7c5790e32..2b3c25371d769e4626c6c91898a848c1f995def4 100644 (file)
@@ -124,7 +124,6 @@ static struct scsi_host_template snic_host_template = {
        .sg_tablesize = SNIC_MAX_SG_DESC_CNT,
        .max_sectors = 0x800,
        .shost_attrs = snic_attrs,
-       .use_blk_tags = 1,
        .track_queue_depth = 1,
        .cmd_size = sizeof(struct snic_internal_io_state),
        .proc_name = "snic_scsi",
@@ -533,15 +532,6 @@ snic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        snic->max_tag_id = shost->can_queue;
 
-       ret = scsi_init_shared_tag_map(shost, snic->max_tag_id);
-       if (ret) {
-               SNIC_HOST_ERR(shost,
-                             "Unable to alloc shared tag map. %d\n",
-                             ret);
-
-               goto err_dev_close;
-       }
-
        shost->max_lun = snic->config.luns_per_tgt;
        shost->max_id = SNIC_MAX_TARGET;
 
index b37b9b00c4b460ca97b44720d5aee1405c2d89ef..e0a1e52a04e736b35dc2b03371a72fc0590b85b1 100644 (file)
@@ -4452,11 +4452,41 @@ static ssize_t version_show(struct device_driver *ddd, char *buf)
 }
 static DRIVER_ATTR_RO(version);
 
+#if DEBUG
+static ssize_t debug_flag_store(struct device_driver *ddp,
+       const char *buf, size_t count)
+{
+/* We only care what the first byte of the data is the rest is unused.
+ * if it's a '1' we turn on debug and if it's a '0' we disable it. All
+ * other values have -EINVAL returned if they are passed in.
+ */
+       if (count > 0) {
+               if (buf[0] == '0') {
+                       debugging = NO_DEBUG;
+                       return count;
+               } else if (buf[0] == '1') {
+                       debugging = 1;
+                       return count;
+               }
+       }
+       return -EINVAL;
+}
+
+static ssize_t debug_flag_show(struct device_driver *ddp, char *buf)
+{
+       return scnprintf(buf, PAGE_SIZE, "%d\n", debugging);
+}
+static DRIVER_ATTR_RW(debug_flag);
+#endif
+
 static struct attribute *st_drv_attrs[] = {
        &driver_attr_try_direct_io.attr,
        &driver_attr_fixed_buffer_size.attr,
        &driver_attr_max_sg_segs.attr,
        &driver_attr_version.attr,
+#if DEBUG
+       &driver_attr_debug_flag.attr,
+#endif
        NULL,
 };
 ATTRIBUTE_GROUPS(st_drv);
index 98a62bc15069773ba2de93dd9d4164e8655919f0..2de28d7a0b045e6e88a7256f1ac3e0a5324c4541 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/types.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
+#include <linux/ktime.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/byteorder.h>
@@ -362,14 +363,6 @@ MODULE_DESCRIPTION("Promise Technology SuperTrak EX Controllers");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(ST_DRIVER_VERSION);
 
-static void stex_gettime(__le64 *time)
-{
-       struct timeval tv;
-
-       do_gettimeofday(&tv);
-       *time = cpu_to_le64(tv.tv_sec);
-}
-
 static struct status_msg *stex_get_status(struct st_hba *hba)
 {
        struct status_msg *status = hba->status_buffer + hba->status_tail;
@@ -1002,7 +995,7 @@ static int stex_common_handshake(struct st_hba *hba)
        h->req_cnt = cpu_to_le16(hba->rq_count+1);
        h->status_sz = cpu_to_le16(sizeof(struct status_msg));
        h->status_cnt = cpu_to_le16(hba->sts_count+1);
-       stex_gettime(&h->hosttime);
+       h->hosttime = cpu_to_le64(ktime_get_real_seconds());
        h->partner_type = HMU_PARTNER_TYPE;
        if (hba->extra_offset) {
                h->extra_offset = cpu_to_le32(hba->extra_offset);
@@ -1076,7 +1069,7 @@ static int stex_ss_handshake(struct st_hba *hba)
        h->req_cnt = cpu_to_le16(hba->rq_count+1);
        h->status_sz = cpu_to_le16(sizeof(struct status_msg));
        h->status_cnt = cpu_to_le16(hba->sts_count+1);
-       stex_gettime(&h->hosttime);
+       h->hosttime = cpu_to_le64(ktime_get_real_seconds());
        h->partner_type = HMU_PARTNER_TYPE;
        h->extra_offset = h->extra_size = 0;
        scratch_size = (hba->sts_count+1)*sizeof(u32);
@@ -1374,7 +1367,6 @@ static struct scsi_host_template driver_template = {
        .eh_abort_handler               = stex_abort,
        .eh_host_reset_handler          = stex_reset,
        .this_id                        = -1,
-       .use_blk_tags                   = 1,
 };
 
 static struct pci_device_id stex_pci_tbl[] = {
@@ -1659,13 +1651,6 @@ static int stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        if (err)
                goto out_free_irq;
 
-       err = scsi_init_shared_tag_map(host, host->can_queue);
-       if (err) {
-               printk(KERN_ERR DRV_NAME "(%s): init shared queue failed\n",
-                       pci_name(pdev));
-               goto out_free_irq;
-       }
-
        pci_set_drvdata(pdev, hba);
 
        err = scsi_add_host(host, &pdev->dev);
index 40c43aeb4ff364898f160d7528d93ea4ef46a00a..3fba42ad9fb8aee55d5015167a9cb9ad601fb1a7 100644 (file)
@@ -349,11 +349,14 @@ enum storvsc_request_type {
  */
 
 #define SRB_STATUS_AUTOSENSE_VALID     0x80
+#define SRB_STATUS_QUEUE_FROZEN                0x40
 #define SRB_STATUS_INVALID_LUN 0x20
 #define SRB_STATUS_SUCCESS     0x01
 #define SRB_STATUS_ABORTED     0x02
 #define SRB_STATUS_ERROR       0x04
 
+#define SRB_STATUS(status) \
+       (status & ~(SRB_STATUS_AUTOSENSE_VALID | SRB_STATUS_QUEUE_FROZEN))
 /*
  * This is the end of Protocol specific defines.
  */
@@ -393,9 +396,6 @@ static void storvsc_on_channel_callback(void *context);
 struct storvsc_cmd_request {
        struct scsi_cmnd *cmd;
 
-       unsigned int bounce_sgl_count;
-       struct scatterlist *bounce_sgl;
-
        struct hv_device *device;
 
        /* Synchronize the request/response if needed */
@@ -586,241 +586,6 @@ get_in_err:
 
 }
 
-static void destroy_bounce_buffer(struct scatterlist *sgl,
-                                 unsigned int sg_count)
-{
-       int i;
-       struct page *page_buf;
-
-       for (i = 0; i < sg_count; i++) {
-               page_buf = sg_page((&sgl[i]));
-               if (page_buf != NULL)
-                       __free_page(page_buf);
-       }
-
-       kfree(sgl);
-}
-
-static int do_bounce_buffer(struct scatterlist *sgl, unsigned int sg_count)
-{
-       int i;
-
-       /* No need to check */
-       if (sg_count < 2)
-               return -1;
-
-       /* We have at least 2 sg entries */
-       for (i = 0; i < sg_count; i++) {
-               if (i == 0) {
-                       /* make sure 1st one does not have hole */
-                       if (sgl[i].offset + sgl[i].length != PAGE_SIZE)
-                               return i;
-               } else if (i == sg_count - 1) {
-                       /* make sure last one does not have hole */
-                       if (sgl[i].offset != 0)
-                               return i;
-               } else {
-                       /* make sure no hole in the middle */
-                       if (sgl[i].length != PAGE_SIZE || sgl[i].offset != 0)
-                               return i;
-               }
-       }
-       return -1;
-}
-
-static struct scatterlist *create_bounce_buffer(struct scatterlist *sgl,
-                                               unsigned int sg_count,
-                                               unsigned int len,
-                                               int write)
-{
-       int i;
-       int num_pages;
-       struct scatterlist *bounce_sgl;
-       struct page *page_buf;
-       unsigned int buf_len = ((write == WRITE_TYPE) ? 0 : PAGE_SIZE);
-
-       num_pages = ALIGN(len, PAGE_SIZE) >> PAGE_SHIFT;
-
-       bounce_sgl = kcalloc(num_pages, sizeof(struct scatterlist), GFP_ATOMIC);
-       if (!bounce_sgl)
-               return NULL;
-
-       sg_init_table(bounce_sgl, num_pages);
-       for (i = 0; i < num_pages; i++) {
-               page_buf = alloc_page(GFP_ATOMIC);
-               if (!page_buf)
-                       goto cleanup;
-               sg_set_page(&bounce_sgl[i], page_buf, buf_len, 0);
-       }
-
-       return bounce_sgl;
-
-cleanup:
-       destroy_bounce_buffer(bounce_sgl, num_pages);
-       return NULL;
-}
-
-/* Assume the original sgl has enough room */
-static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl,
-                                           struct scatterlist *bounce_sgl,
-                                           unsigned int orig_sgl_count,
-                                           unsigned int bounce_sgl_count)
-{
-       int i;
-       int j = 0;
-       unsigned long src, dest;
-       unsigned int srclen, destlen, copylen;
-       unsigned int total_copied = 0;
-       unsigned long bounce_addr = 0;
-       unsigned long dest_addr = 0;
-       unsigned long flags;
-       struct scatterlist *cur_dest_sgl;
-       struct scatterlist *cur_src_sgl;
-
-       local_irq_save(flags);
-       cur_dest_sgl = orig_sgl;
-       cur_src_sgl = bounce_sgl;
-       for (i = 0; i < orig_sgl_count; i++) {
-               dest_addr = (unsigned long)
-                               kmap_atomic(sg_page(cur_dest_sgl)) +
-                               cur_dest_sgl->offset;
-               dest = dest_addr;
-               destlen = cur_dest_sgl->length;
-
-               if (bounce_addr == 0)
-                       bounce_addr = (unsigned long)kmap_atomic(
-                                                       sg_page(cur_src_sgl));
-
-               while (destlen) {
-                       src = bounce_addr + cur_src_sgl->offset;
-                       srclen = cur_src_sgl->length - cur_src_sgl->offset;
-
-                       copylen = min(srclen, destlen);
-                       memcpy((void *)dest, (void *)src, copylen);
-
-                       total_copied += copylen;
-                       cur_src_sgl->offset += copylen;
-                       destlen -= copylen;
-                       dest += copylen;
-
-                       if (cur_src_sgl->offset == cur_src_sgl->length) {
-                               /* full */
-                               kunmap_atomic((void *)bounce_addr);
-                               j++;
-
-                               /*
-                                * It is possible that the number of elements
-                                * in the bounce buffer may not be equal to
-                                * the number of elements in the original
-                                * scatter list. Handle this correctly.
-                                */
-
-                               if (j == bounce_sgl_count) {
-                                       /*
-                                        * We are done; cleanup and return.
-                                        */
-                                       kunmap_atomic((void *)(dest_addr -
-                                               cur_dest_sgl->offset));
-                                       local_irq_restore(flags);
-                                       return total_copied;
-                               }
-
-                               /* if we need to use another bounce buffer */
-                               if (destlen || i != orig_sgl_count - 1) {
-                                       cur_src_sgl = sg_next(cur_src_sgl);
-                                       bounce_addr = (unsigned long)
-                                                       kmap_atomic(
-                                                       sg_page(cur_src_sgl));
-                               }
-                       } else if (destlen == 0 && i == orig_sgl_count - 1) {
-                               /* unmap the last bounce that is < PAGE_SIZE */
-                               kunmap_atomic((void *)bounce_addr);
-                       }
-               }
-
-               kunmap_atomic((void *)(dest_addr - cur_dest_sgl->offset));
-               cur_dest_sgl = sg_next(cur_dest_sgl);
-       }
-
-       local_irq_restore(flags);
-
-       return total_copied;
-}
-
-/* Assume the bounce_sgl has enough room ie using the create_bounce_buffer() */
-static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl,
-                                         struct scatterlist *bounce_sgl,
-                                         unsigned int orig_sgl_count)
-{
-       int i;
-       int j = 0;
-       unsigned long src, dest;
-       unsigned int srclen, destlen, copylen;
-       unsigned int total_copied = 0;
-       unsigned long bounce_addr = 0;
-       unsigned long src_addr = 0;
-       unsigned long flags;
-       struct scatterlist *cur_src_sgl;
-       struct scatterlist *cur_dest_sgl;
-
-       local_irq_save(flags);
-
-       cur_src_sgl = orig_sgl;
-       cur_dest_sgl = bounce_sgl;
-
-       for (i = 0; i < orig_sgl_count; i++) {
-               src_addr = (unsigned long)
-                               kmap_atomic(sg_page(cur_src_sgl)) +
-                               cur_src_sgl->offset;
-               src = src_addr;
-               srclen = cur_src_sgl->length;
-
-               if (bounce_addr == 0)
-                       bounce_addr = (unsigned long)
-                                       kmap_atomic(sg_page(cur_dest_sgl));
-
-               while (srclen) {
-                       /* assume bounce offset always == 0 */
-                       dest = bounce_addr + cur_dest_sgl->length;
-                       destlen = PAGE_SIZE - cur_dest_sgl->length;
-
-                       copylen = min(srclen, destlen);
-                       memcpy((void *)dest, (void *)src, copylen);
-
-                       total_copied += copylen;
-                       cur_dest_sgl->length += copylen;
-                       srclen -= copylen;
-                       src += copylen;
-
-                       if (cur_dest_sgl->length == PAGE_SIZE) {
-                               /* full..move to next entry */
-                               kunmap_atomic((void *)bounce_addr);
-                               bounce_addr = 0;
-                               j++;
-                       }
-
-                       /* if we need to use another bounce buffer */
-                       if (srclen && bounce_addr == 0) {
-                               cur_dest_sgl = sg_next(cur_dest_sgl);
-                               bounce_addr = (unsigned long)
-                                               kmap_atomic(
-                                               sg_page(cur_dest_sgl));
-                       }
-
-               }
-
-               kunmap_atomic((void *)(src_addr - cur_src_sgl->offset));
-               cur_src_sgl = sg_next(cur_src_sgl);
-       }
-
-       if (bounce_addr)
-               kunmap_atomic((void *)bounce_addr);
-
-       local_irq_restore(flags);
-
-       return total_copied;
-}
-
 static void handle_sc_creation(struct vmbus_channel *new_sc)
 {
        struct hv_device *device = new_sc->primary_channel->device_obj;
@@ -1096,7 +861,7 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb,
        void (*process_err_fn)(struct work_struct *work);
        bool do_work = false;
 
-       switch (vm_srb->srb_status) {
+       switch (SRB_STATUS(vm_srb->srb_status)) {
        case SRB_STATUS_ERROR:
                /*
                 * If there is an error; offline the device since all
@@ -1171,15 +936,6 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request)
        host = stor_dev->host;
 
        vm_srb = &cmd_request->vstor_packet.vm_srb;
-       if (cmd_request->bounce_sgl_count) {
-               if (vm_srb->data_in == READ_TYPE)
-                       copy_from_bounce_buffer(scsi_sglist(scmnd),
-                                       cmd_request->bounce_sgl,
-                                       scsi_sg_count(scmnd),
-                                       cmd_request->bounce_sgl_count);
-               destroy_bounce_buffer(cmd_request->bounce_sgl,
-                                       cmd_request->bounce_sgl_count);
-       }
 
        scmnd->result = vm_srb->scsi_status;
 
@@ -1474,6 +1230,9 @@ static int storvsc_device_configure(struct scsi_device *sdevice)
 
        blk_queue_rq_timeout(sdevice->request_queue, (storvsc_timeout * HZ));
 
+       /* Ensure there are no gaps in presented sgls */
+       blk_queue_virt_boundary(sdevice->request_queue, PAGE_SIZE - 1);
+
        sdevice->no_write_same = 1;
 
        /*
@@ -1647,8 +1406,7 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
        vm_srb->win8_extension.time_out_value = 60;
 
        vm_srb->win8_extension.srb_flags |=
-               (SRB_FLAGS_QUEUE_ACTION_ENABLE |
-               SRB_FLAGS_DISABLE_SYNCH_TRANSFER);
+               SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
 
        /* Build the SRB */
        switch (scmnd->sc_data_direction) {
@@ -1692,40 +1450,13 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
        payload_sz = sizeof(cmd_request->mpb);
 
        if (sg_count) {
-               /* check if we need to bounce the sgl */
-               if (do_bounce_buffer(sgl, scsi_sg_count(scmnd)) != -1) {
-                       cmd_request->bounce_sgl =
-                               create_bounce_buffer(sgl, sg_count,
-                                                    length,
-                                                    vm_srb->data_in);
-                       if (!cmd_request->bounce_sgl)
-                               return SCSI_MLQUEUE_HOST_BUSY;
-
-                       cmd_request->bounce_sgl_count =
-                               ALIGN(length, PAGE_SIZE) >> PAGE_SHIFT;
-
-                       if (vm_srb->data_in == WRITE_TYPE)
-                               copy_to_bounce_buffer(sgl,
-                                       cmd_request->bounce_sgl, sg_count);
-
-                       sgl = cmd_request->bounce_sgl;
-                       sg_count = cmd_request->bounce_sgl_count;
-               }
-
-
                if (sg_count > MAX_PAGE_BUFFER_COUNT) {
 
                        payload_sz = (sg_count * sizeof(void *) +
                                      sizeof(struct vmbus_packet_mpb_array));
                        payload = kmalloc(payload_sz, GFP_ATOMIC);
-                       if (!payload) {
-                               if (cmd_request->bounce_sgl_count)
-                                       destroy_bounce_buffer(
-                                       cmd_request->bounce_sgl,
-                                       cmd_request->bounce_sgl_count);
-
-                                       return SCSI_MLQUEUE_DEVICE_BUSY;
-                       }
+                       if (!payload)
+                               return SCSI_MLQUEUE_DEVICE_BUSY;
                }
 
                payload->range.len = length;
@@ -1754,11 +1485,6 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
 
        if (ret == -EAGAIN) {
                /* no more space */
-
-               if (cmd_request->bounce_sgl_count)
-                       destroy_bounce_buffer(cmd_request->bounce_sgl,
-                                       cmd_request->bounce_sgl_count);
-
                return SCSI_MLQUEUE_DEVICE_BUSY;
        }
 
index e94538362536e4234b180201c7a70ae21bde7af1..5f4530744e0af7bd1ea8e4ca76fffe3a87d11d56 100644 (file)
@@ -72,7 +72,7 @@ config SCSI_UFSHCD_PLATFORM
          If unsure, say N.
 
 config SCSI_UFS_QCOM
-       bool "QCOM specific hooks to UFS controller platform driver"
+       tristate "QCOM specific hooks to UFS controller platform driver"
        depends on SCSI_UFSHCD_PLATFORM && ARCH_QCOM
        select PHY_QCOM_UFS
        help
index 4cdffa46d401a5ea6120ba5d350e453158166a31..4f38d008bfb401d9eeeb359472e643bdf3e85c9b 100644 (file)
 
 #include <linux/phy/phy-qcom-ufs.h>
 #include "ufshcd.h"
+#include "ufshcd-pltfrm.h"
 #include "unipro.h"
 #include "ufs-qcom.h"
 #include "ufshci.h"
+#define UFS_QCOM_DEFAULT_DBG_PRINT_EN  \
+       (UFS_QCOM_DBG_PRINT_REGS_EN | UFS_QCOM_DBG_PRINT_TEST_BUS_EN)
+
+enum {
+       TSTBUS_UAWM,
+       TSTBUS_UARM,
+       TSTBUS_TXUC,
+       TSTBUS_RXUC,
+       TSTBUS_DFC,
+       TSTBUS_TRLUT,
+       TSTBUS_TMRLUT,
+       TSTBUS_OCSC,
+       TSTBUS_UTP_HCI,
+       TSTBUS_COMBINED,
+       TSTBUS_WRAPPER,
+       TSTBUS_UNIPRO,
+       TSTBUS_MAX,
+};
 
 static struct ufs_qcom_host *ufs_qcom_hosts[MAX_UFS_QCOM_HOSTS];
 
-static void ufs_qcom_get_speed_mode(struct ufs_pa_layer_attr *p, char *result);
-static int ufs_qcom_get_bus_vote(struct ufs_qcom_host *host,
-               const char *speed_mode);
 static int ufs_qcom_set_bus_vote(struct ufs_qcom_host *host, int vote);
+static void ufs_qcom_get_default_testbus_cfg(struct ufs_qcom_host *host);
+static int ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(struct ufs_hba *hba,
+                                                      u32 clk_cycles);
+
+static void ufs_qcom_dump_regs(struct ufs_hba *hba, int offset, int len,
+               char *prefix)
+{
+       print_hex_dump(KERN_ERR, prefix,
+                       len > 4 ? DUMP_PREFIX_OFFSET : DUMP_PREFIX_NONE,
+                       16, 4, (void __force *)hba->mmio_base + offset,
+                       len * 4, false);
+}
 
 static int ufs_qcom_get_connected_tx_lanes(struct ufs_hba *hba, u32 *tx_lanes)
 {
@@ -149,13 +177,14 @@ static int ufs_qcom_init_lane_clks(struct ufs_qcom_host *host)
 
        err = ufs_qcom_host_clk_get(dev, "tx_lane1_sync_clk",
                &host->tx_l1_sync_clk);
+
 out:
        return err;
 }
 
 static int ufs_qcom_link_startup_post_change(struct ufs_hba *hba)
 {
-       struct ufs_qcom_host *host = hba->priv;
+       struct ufs_qcom_host *host = ufshcd_get_variant(hba);
        struct phy *phy = host->generic_phy;
        u32 tx_lanes;
        int err = 0;
@@ -181,7 +210,9 @@ static int ufs_qcom_check_hibern8(struct ufs_hba *hba)
 
        do {
                err = ufshcd_dme_get(hba,
-                       UIC_ARG_MIB(MPHY_TX_FSM_STATE), &tx_fsm_val);
+                               UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE,
+                                       UIC_ARG_MPHY_TX_GEN_SEL_INDEX(0)),
+                               &tx_fsm_val);
                if (err || tx_fsm_val == TX_FSM_HIBERN8)
                        break;
 
@@ -195,7 +226,9 @@ static int ufs_qcom_check_hibern8(struct ufs_hba *hba)
         */
        if (time_after(jiffies, timeout))
                err = ufshcd_dme_get(hba,
-                               UIC_ARG_MIB(MPHY_TX_FSM_STATE), &tx_fsm_val);
+                               UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE,
+                                       UIC_ARG_MPHY_TX_GEN_SEL_INDEX(0)),
+                               &tx_fsm_val);
 
        if (err) {
                dev_err(hba->dev, "%s: unable to get TX_FSM_STATE, err %d\n",
@@ -209,9 +242,18 @@ static int ufs_qcom_check_hibern8(struct ufs_hba *hba)
        return err;
 }
 
+static void ufs_qcom_select_unipro_mode(struct ufs_qcom_host *host)
+{
+       ufshcd_rmwl(host->hba, QUNIPRO_SEL,
+                  ufs_qcom_cap_qunipro(host) ? QUNIPRO_SEL : 0,
+                  REG_UFS_CFG1);
+       /* make sure above configuration is applied before we return */
+       mb();
+}
+
 static int ufs_qcom_power_up_sequence(struct ufs_hba *hba)
 {
-       struct ufs_qcom_host *host = hba->priv;
+       struct ufs_qcom_host *host = ufshcd_get_variant(hba);
        struct phy *phy = host->generic_phy;
        int ret = 0;
        bool is_rate_B = (UFS_QCOM_LIMIT_HS_RATE == PA_HS_MODE_B)
@@ -223,9 +265,11 @@ static int ufs_qcom_power_up_sequence(struct ufs_hba *hba)
        usleep_range(1000, 1100);
 
        ret = ufs_qcom_phy_calibrate_phy(phy, is_rate_B);
+
        if (ret) {
-               dev_err(hba->dev, "%s: ufs_qcom_phy_calibrate_phy() failed, ret = %d\n",
-                       __func__, ret);
+               dev_err(hba->dev,
+               "%s: ufs_qcom_phy_calibrate_phy()failed, ret = %d\n",
+               __func__, ret);
                goto out;
        }
 
@@ -246,9 +290,12 @@ static int ufs_qcom_power_up_sequence(struct ufs_hba *hba)
 
        ret = ufs_qcom_phy_is_pcs_ready(phy);
        if (ret)
-               dev_err(hba->dev, "%s: is_physical_coding_sublayer_ready() failed, ret = %d\n",
+               dev_err(hba->dev,
+                       "%s: is_physical_coding_sublayer_ready() failed, ret = %d\n",
                        __func__, ret);
 
+       ufs_qcom_select_unipro_mode(host);
+
 out:
        return ret;
 }
@@ -271,9 +318,10 @@ static void ufs_qcom_enable_hw_clk_gating(struct ufs_hba *hba)
        mb();
 }
 
-static int ufs_qcom_hce_enable_notify(struct ufs_hba *hba, bool status)
+static int ufs_qcom_hce_enable_notify(struct ufs_hba *hba,
+                                     enum ufs_notify_change_status status)
 {
-       struct ufs_qcom_host *host = hba->priv;
+       struct ufs_qcom_host *host = ufshcd_get_variant(hba);
        int err = 0;
 
        switch (status) {
@@ -301,13 +349,13 @@ static int ufs_qcom_hce_enable_notify(struct ufs_hba *hba, bool status)
 }
 
 /**
- * Returns non-zero for success (which rate of core_clk) and 0
- * in case of a failure
+ * Returns zero for success and non-zero in case of a failure
  */
-static unsigned long
-ufs_qcom_cfg_timers(struct ufs_hba *hba, u32 gear, u32 hs, u32 rate)
+static int ufs_qcom_cfg_timers(struct ufs_hba *hba, u32 gear,
+                              u32 hs, u32 rate, bool update_link_startup_timer)
 {
-       struct ufs_qcom_host *host = hba->priv;
+       int ret = 0;
+       struct ufs_qcom_host *host = ufshcd_get_variant(hba);
        struct ufs_clk_info *clki;
        u32 core_clk_period_in_ns;
        u32 tx_clk_cycles_per_us = 0;
@@ -324,11 +372,13 @@ ufs_qcom_cfg_timers(struct ufs_hba *hba, u32 gear, u32 hs, u32 rate)
        static u32 hs_fr_table_rA[][2] = {
                {UFS_HS_G1, 0x1F},
                {UFS_HS_G2, 0x3e},
+               {UFS_HS_G3, 0x7D},
        };
 
        static u32 hs_fr_table_rB[][2] = {
                {UFS_HS_G1, 0x24},
                {UFS_HS_G2, 0x49},
+               {UFS_HS_G3, 0x92},
        };
 
        /*
@@ -356,7 +406,17 @@ ufs_qcom_cfg_timers(struct ufs_hba *hba, u32 gear, u32 hs, u32 rate)
                core_clk_rate = DEFAULT_CLK_RATE_HZ;
 
        core_clk_cycles_per_us = core_clk_rate / USEC_PER_SEC;
-       ufshcd_writel(hba, core_clk_cycles_per_us, REG_UFS_SYS1CLK_1US);
+       if (ufshcd_readl(hba, REG_UFS_SYS1CLK_1US) != core_clk_cycles_per_us) {
+               ufshcd_writel(hba, core_clk_cycles_per_us, REG_UFS_SYS1CLK_1US);
+               /*
+                * make sure above write gets applied before we return from
+                * this function.
+                */
+               mb();
+       }
+
+       if (ufs_qcom_cap_qunipro(host))
+               goto out;
 
        core_clk_period_in_ns = NSEC_PER_SEC / core_clk_rate;
        core_clk_period_in_ns <<= OFFSET_CLK_NS_REG;
@@ -406,35 +466,59 @@ ufs_qcom_cfg_timers(struct ufs_hba *hba, u32 gear, u32 hs, u32 rate)
                goto out_error;
        }
 
-       /* this register 2 fields shall be written at once */
-       ufshcd_writel(hba, core_clk_period_in_ns | tx_clk_cycles_per_us,
-                                               REG_UFS_TX_SYMBOL_CLK_NS_US);
+       if (ufshcd_readl(hba, REG_UFS_TX_SYMBOL_CLK_NS_US) !=
+           (core_clk_period_in_ns | tx_clk_cycles_per_us)) {
+               /* this register 2 fields shall be written at once */
+               ufshcd_writel(hba, core_clk_period_in_ns | tx_clk_cycles_per_us,
+                             REG_UFS_TX_SYMBOL_CLK_NS_US);
+               /*
+                * make sure above write gets applied before we return from
+                * this function.
+                */
+               mb();
+       }
+
+       if (update_link_startup_timer) {
+               ufshcd_writel(hba, ((core_clk_rate / MSEC_PER_SEC) * 100),
+                             REG_UFS_PA_LINK_STARTUP_TIMER);
+               /*
+                * make sure that this configuration is applied before
+                * we return
+                */
+               mb();
+       }
        goto out;
 
 out_error:
-       core_clk_rate = 0;
+       ret = -EINVAL;
 out:
-       return core_clk_rate;
+       return ret;
 }
 
-static int ufs_qcom_link_startup_notify(struct ufs_hba *hba, bool status)
+static int ufs_qcom_link_startup_notify(struct ufs_hba *hba,
+                                       enum ufs_notify_change_status status)
 {
-       unsigned long core_clk_rate = 0;
-       u32 core_clk_cycles_per_100ms;
+       int err = 0;
+       struct ufs_qcom_host *host = ufshcd_get_variant(hba);
 
        switch (status) {
        case PRE_CHANGE:
-               core_clk_rate = ufs_qcom_cfg_timers(hba, UFS_PWM_G1,
-                                                   SLOWAUTO_MODE, 0);
-               if (!core_clk_rate) {
+               if (ufs_qcom_cfg_timers(hba, UFS_PWM_G1, SLOWAUTO_MODE,
+                                       0, true)) {
                        dev_err(hba->dev, "%s: ufs_qcom_cfg_timers() failed\n",
                                __func__);
-                       return -EINVAL;
+                       err = -EINVAL;
+                       goto out;
                }
-               core_clk_cycles_per_100ms =
-                       (core_clk_rate / MSEC_PER_SEC) * 100;
-               ufshcd_writel(hba, core_clk_cycles_per_100ms,
-                                       REG_UFS_PA_LINK_STARTUP_TIMER);
+
+               if (ufs_qcom_cap_qunipro(host))
+                       /*
+                        * set unipro core clock cycles to 150 & clear clock
+                        * divider
+                        */
+                       err = ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(hba,
+                                                                         150);
+
                break;
        case POST_CHANGE:
                ufs_qcom_link_startup_post_change(hba);
@@ -443,12 +527,13 @@ static int ufs_qcom_link_startup_notify(struct ufs_hba *hba, bool status)
                break;
        }
 
-       return 0;
+out:
+       return err;
 }
 
 static int ufs_qcom_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
 {
-       struct ufs_qcom_host *host = hba->priv;
+       struct ufs_qcom_host *host = ufshcd_get_variant(hba);
        struct phy *phy = host->generic_phy;
        int ret = 0;
 
@@ -470,8 +555,10 @@ static int ufs_qcom_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
         * If UniPro link is not active, PHY ref_clk, main PHY analog power
         * rail and low noise analog power rail for PLL can be switched off.
         */
-       if (!ufs_qcom_is_link_active(hba))
+       if (!ufs_qcom_is_link_active(hba)) {
+               ufs_qcom_disable_lane_clks(host);
                phy_power_off(phy);
+       }
 
 out:
        return ret;
@@ -479,7 +566,7 @@ out:
 
 static int ufs_qcom_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
 {
-       struct ufs_qcom_host *host = hba->priv;
+       struct ufs_qcom_host *host = ufshcd_get_variant(hba);
        struct phy *phy = host->generic_phy;
        int err;
 
@@ -490,6 +577,10 @@ static int ufs_qcom_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
                goto out;
        }
 
+       err = ufs_qcom_enable_lane_clks(host);
+       if (err)
+               goto out;
+
        hba->is_sys_suspended = false;
 
 out:
@@ -594,6 +685,81 @@ static int ufs_qcom_get_pwr_dev_param(struct ufs_qcom_dev_params *qcom_param,
        return 0;
 }
 
+#ifdef CONFIG_MSM_BUS_SCALING
+static int ufs_qcom_get_bus_vote(struct ufs_qcom_host *host,
+               const char *speed_mode)
+{
+       struct device *dev = host->hba->dev;
+       struct device_node *np = dev->of_node;
+       int err;
+       const char *key = "qcom,bus-vector-names";
+
+       if (!speed_mode) {
+               err = -EINVAL;
+               goto out;
+       }
+
+       if (host->bus_vote.is_max_bw_needed && !!strcmp(speed_mode, "MIN"))
+               err = of_property_match_string(np, key, "MAX");
+       else
+               err = of_property_match_string(np, key, speed_mode);
+
+out:
+       if (err < 0)
+               dev_err(dev, "%s: Invalid %s mode %d\n",
+                               __func__, speed_mode, err);
+       return err;
+}
+
+static void ufs_qcom_get_speed_mode(struct ufs_pa_layer_attr *p, char *result)
+{
+       int gear = max_t(u32, p->gear_rx, p->gear_tx);
+       int lanes = max_t(u32, p->lane_rx, p->lane_tx);
+       int pwr;
+
+       /* default to PWM Gear 1, Lane 1 if power mode is not initialized */
+       if (!gear)
+               gear = 1;
+
+       if (!lanes)
+               lanes = 1;
+
+       if (!p->pwr_rx && !p->pwr_tx) {
+               pwr = SLOWAUTO_MODE;
+               snprintf(result, BUS_VECTOR_NAME_LEN, "MIN");
+       } else if (p->pwr_rx == FAST_MODE || p->pwr_rx == FASTAUTO_MODE ||
+                p->pwr_tx == FAST_MODE || p->pwr_tx == FASTAUTO_MODE) {
+               pwr = FAST_MODE;
+               snprintf(result, BUS_VECTOR_NAME_LEN, "%s_R%s_G%d_L%d", "HS",
+                        p->hs_rate == PA_HS_MODE_B ? "B" : "A", gear, lanes);
+       } else {
+               pwr = SLOW_MODE;
+               snprintf(result, BUS_VECTOR_NAME_LEN, "%s_G%d_L%d",
+                        "PWM", gear, lanes);
+       }
+}
+
+static int ufs_qcom_set_bus_vote(struct ufs_qcom_host *host, int vote)
+{
+       int err = 0;
+
+       if (vote != host->bus_vote.curr_vote) {
+               err = msm_bus_scale_client_update_request(
+                               host->bus_vote.client_handle, vote);
+               if (err) {
+                       dev_err(host->hba->dev,
+                               "%s: msm_bus_scale_client_update_request() failed: bus_client_handle=0x%x, vote=%d, err=%d\n",
+                               __func__, host->bus_vote.client_handle,
+                               vote, err);
+                       goto out;
+               }
+
+               host->bus_vote.curr_vote = vote;
+       }
+out:
+       return err;
+}
+
 static int ufs_qcom_update_bus_bw_vote(struct ufs_qcom_host *host)
 {
        int vote;
@@ -615,13 +781,137 @@ static int ufs_qcom_update_bus_bw_vote(struct ufs_qcom_host *host)
        return err;
 }
 
+static ssize_t
+show_ufs_to_mem_max_bus_bw(struct device *dev, struct device_attribute *attr,
+                       char *buf)
+{
+       struct ufs_hba *hba = dev_get_drvdata(dev);
+       struct ufs_qcom_host *host = ufshcd_get_variant(hba);
+
+       return snprintf(buf, PAGE_SIZE, "%u\n",
+                       host->bus_vote.is_max_bw_needed);
+}
+
+static ssize_t
+store_ufs_to_mem_max_bus_bw(struct device *dev, struct device_attribute *attr,
+               const char *buf, size_t count)
+{
+       struct ufs_hba *hba = dev_get_drvdata(dev);
+       struct ufs_qcom_host *host = ufshcd_get_variant(hba);
+       uint32_t value;
+
+       if (!kstrtou32(buf, 0, &value)) {
+               host->bus_vote.is_max_bw_needed = !!value;
+               ufs_qcom_update_bus_bw_vote(host);
+       }
+
+       return count;
+}
+
+static int ufs_qcom_bus_register(struct ufs_qcom_host *host)
+{
+       int err;
+       struct msm_bus_scale_pdata *bus_pdata;
+       struct device *dev = host->hba->dev;
+       struct platform_device *pdev = to_platform_device(dev);
+       struct device_node *np = dev->of_node;
+
+       bus_pdata = msm_bus_cl_get_pdata(pdev);
+       if (!bus_pdata) {
+               dev_err(dev, "%s: failed to get bus vectors\n", __func__);
+               err = -ENODATA;
+               goto out;
+       }
+
+       err = of_property_count_strings(np, "qcom,bus-vector-names");
+       if (err < 0 || err != bus_pdata->num_usecases) {
+               dev_err(dev, "%s: qcom,bus-vector-names not specified correctly %d\n",
+                               __func__, err);
+               goto out;
+       }
+
+       host->bus_vote.client_handle = msm_bus_scale_register_client(bus_pdata);
+       if (!host->bus_vote.client_handle) {
+               dev_err(dev, "%s: msm_bus_scale_register_client failed\n",
+                               __func__);
+               err = -EFAULT;
+               goto out;
+       }
+
+       /* cache the vote index for minimum and maximum bandwidth */
+       host->bus_vote.min_bw_vote = ufs_qcom_get_bus_vote(host, "MIN");
+       host->bus_vote.max_bw_vote = ufs_qcom_get_bus_vote(host, "MAX");
+
+       host->bus_vote.max_bus_bw.show = show_ufs_to_mem_max_bus_bw;
+       host->bus_vote.max_bus_bw.store = store_ufs_to_mem_max_bus_bw;
+       sysfs_attr_init(&host->bus_vote.max_bus_bw.attr);
+       host->bus_vote.max_bus_bw.attr.name = "max_bus_bw";
+       host->bus_vote.max_bus_bw.attr.mode = S_IRUGO | S_IWUSR;
+       err = device_create_file(dev, &host->bus_vote.max_bus_bw);
+out:
+       return err;
+}
+#else /* CONFIG_MSM_BUS_SCALING */
+static int ufs_qcom_update_bus_bw_vote(struct ufs_qcom_host *host)
+{
+       return 0;
+}
+
+static int ufs_qcom_set_bus_vote(struct ufs_qcom_host *host, int vote)
+{
+       return 0;
+}
+
+static int ufs_qcom_bus_register(struct ufs_qcom_host *host)
+{
+       return 0;
+}
+#endif /* CONFIG_MSM_BUS_SCALING */
+
+static void ufs_qcom_dev_ref_clk_ctrl(struct ufs_qcom_host *host, bool enable)
+{
+       if (host->dev_ref_clk_ctrl_mmio &&
+           (enable ^ host->is_dev_ref_clk_enabled)) {
+               u32 temp = readl_relaxed(host->dev_ref_clk_ctrl_mmio);
+
+               if (enable)
+                       temp |= host->dev_ref_clk_en_mask;
+               else
+                       temp &= ~host->dev_ref_clk_en_mask;
+
+               /*
+                * If we are here to disable this clock it might be immediately
+                * after entering into hibern8 in which case we need to make
+                * sure that device ref_clk is active at least 1us after the
+                * hibern8 enter.
+                */
+               if (!enable)
+                       udelay(1);
+
+               writel_relaxed(temp, host->dev_ref_clk_ctrl_mmio);
+
+               /* ensure that ref_clk is enabled/disabled before we return */
+               wmb();
+
+               /*
+                * If we call hibern8 exit after this, we need to make sure that
+                * device ref_clk is stable for at least 1us before the hibern8
+                * exit command.
+                */
+               if (enable)
+                       udelay(1);
+
+               host->is_dev_ref_clk_enabled = enable;
+       }
+}
+
 static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba,
-                               bool status,
+                               enum ufs_notify_change_status status,
                                struct ufs_pa_layer_attr *dev_max_params,
                                struct ufs_pa_layer_attr *dev_req_params)
 {
        u32 val;
-       struct ufs_qcom_host *host = hba->priv;
+       struct ufs_qcom_host *host = ufshcd_get_variant(hba);
        struct phy *phy = host->generic_phy;
        struct ufs_qcom_dev_params ufs_qcom_cap;
        int ret = 0;
@@ -649,6 +939,20 @@ static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba,
                ufs_qcom_cap.desired_working_mode =
                                        UFS_QCOM_LIMIT_DESIRED_MODE;
 
+               if (host->hw_ver.major == 0x1) {
+                       /*
+                        * HS-G3 operations may not reliably work on legacy QCOM
+                        * UFS host controller hardware even though capability
+                        * exchange during link startup phase may end up
+                        * negotiating maximum supported gear as G3.
+                        * Hence downgrade the maximum supported gear to HS-G2.
+                        */
+                       if (ufs_qcom_cap.hs_tx_gear > UFS_HS_G2)
+                               ufs_qcom_cap.hs_tx_gear = UFS_HS_G2;
+                       if (ufs_qcom_cap.hs_rx_gear > UFS_HS_G2)
+                               ufs_qcom_cap.hs_rx_gear = UFS_HS_G2;
+               }
+
                ret = ufs_qcom_get_pwr_dev_param(&ufs_qcom_cap,
                                                 dev_max_params,
                                                 dev_req_params);
@@ -660,9 +964,9 @@ static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba,
 
                break;
        case POST_CHANGE:
-               if (!ufs_qcom_cfg_timers(hba, dev_req_params->gear_rx,
+               if (ufs_qcom_cfg_timers(hba, dev_req_params->gear_rx,
                                        dev_req_params->pwr_rx,
-                                       dev_req_params->hs_rate)) {
+                                       dev_req_params->hs_rate, false)) {
                        dev_err(hba->dev, "%s: ufs_qcom_cfg_timers() failed\n",
                                __func__);
                        /*
@@ -696,7 +1000,7 @@ out:
 
 static u32 ufs_qcom_get_ufs_hci_version(struct ufs_hba *hba)
 {
-       struct ufs_qcom_host *host = hba->priv;
+       struct ufs_qcom_host *host = ufshcd_get_variant(hba);
 
        if (host->hw_ver.major == 0x1)
                return UFSHCI_VERSION_11;
@@ -715,7 +1019,7 @@ static u32 ufs_qcom_get_ufs_hci_version(struct ufs_hba *hba)
  */
 static void ufs_qcom_advertise_quirks(struct ufs_hba *hba)
 {
-       struct ufs_qcom_host *host = hba->priv;
+       struct ufs_qcom_host *host = ufshcd_get_variant(hba);
 
        if (host->hw_ver.major == 0x01) {
                hba->quirks |= UFSHCD_QUIRK_DELAY_BEFORE_DME_CMDS
@@ -724,10 +1028,11 @@ static void ufs_qcom_advertise_quirks(struct ufs_hba *hba)
 
                if (host->hw_ver.minor == 0x0001 && host->hw_ver.step == 0x0001)
                        hba->quirks |= UFSHCD_QUIRK_BROKEN_INTR_AGGR;
+
+               hba->quirks |= UFSHCD_QUIRK_BROKEN_LCC;
        }
 
        if (host->hw_ver.major >= 0x2) {
-               hba->quirks |= UFSHCD_QUIRK_BROKEN_LCC;
                hba->quirks |= UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION;
 
                if (!ufs_qcom_cap_qunipro(host))
@@ -740,79 +1045,29 @@ static void ufs_qcom_advertise_quirks(struct ufs_hba *hba)
 
 static void ufs_qcom_set_caps(struct ufs_hba *hba)
 {
-       struct ufs_qcom_host *host = hba->priv;
+       struct ufs_qcom_host *host = ufshcd_get_variant(hba);
 
-       if (host->hw_ver.major >= 0x2)
-               host->caps = UFS_QCOM_CAP_QUNIPRO;
-}
-
-static int ufs_qcom_get_bus_vote(struct ufs_qcom_host *host,
-               const char *speed_mode)
-{
-       struct device *dev = host->hba->dev;
-       struct device_node *np = dev->of_node;
-       int err;
-       const char *key = "qcom,bus-vector-names";
-
-       if (!speed_mode) {
-               err = -EINVAL;
-               goto out;
-       }
-
-       if (host->bus_vote.is_max_bw_needed && !!strcmp(speed_mode, "MIN"))
-               err = of_property_match_string(np, key, "MAX");
-       else
-               err = of_property_match_string(np, key, speed_mode);
-
-out:
-       if (err < 0)
-               dev_err(dev, "%s: Invalid %s mode %d\n",
-                               __func__, speed_mode, err);
-       return err;
-}
-
-static int ufs_qcom_set_bus_vote(struct ufs_qcom_host *host, int vote)
-{
-       int err = 0;
-
-       if (vote != host->bus_vote.curr_vote)
-               host->bus_vote.curr_vote = vote;
-
-       return err;
-}
-
-static void ufs_qcom_get_speed_mode(struct ufs_pa_layer_attr *p, char *result)
-{
-       int gear = max_t(u32, p->gear_rx, p->gear_tx);
-       int lanes = max_t(u32, p->lane_rx, p->lane_tx);
-       int pwr;
-
-       /* default to PWM Gear 1, Lane 1 if power mode is not initialized */
-       if (!gear)
-               gear = 1;
-
-       if (!lanes)
-               lanes = 1;
+       hba->caps |= UFSHCD_CAP_CLK_GATING | UFSHCD_CAP_HIBERN8_WITH_CLK_GATING;
+       hba->caps |= UFSHCD_CAP_CLK_SCALING;
+       hba->caps |= UFSHCD_CAP_AUTO_BKOPS_SUSPEND;
 
-       if (!p->pwr_rx && !p->pwr_tx) {
-               pwr = SLOWAUTO_MODE;
-               snprintf(result, BUS_VECTOR_NAME_LEN, "MIN");
-       } else if (p->pwr_rx == FAST_MODE || p->pwr_rx == FASTAUTO_MODE ||
-                p->pwr_tx == FAST_MODE || p->pwr_tx == FASTAUTO_MODE) {
-               pwr = FAST_MODE;
-               snprintf(result, BUS_VECTOR_NAME_LEN, "%s_R%s_G%d_L%d", "HS",
-                        p->hs_rate == PA_HS_MODE_B ? "B" : "A", gear, lanes);
-       } else {
-               pwr = SLOW_MODE;
-               snprintf(result, BUS_VECTOR_NAME_LEN, "%s_G%d_L%d",
-                        "PWM", gear, lanes);
+       if (host->hw_ver.major >= 0x2) {
+               host->caps = UFS_QCOM_CAP_QUNIPRO |
+                            UFS_QCOM_CAP_RETAIN_SEC_CFG_AFTER_PWR_COLLAPSE;
        }
 }
 
+/**
+ * ufs_qcom_setup_clocks - enables/disable clocks
+ * @hba: host controller instance
+ * @on: If true, enable clocks else disable them.
+ *
+ * Returns 0 on success, non-zero on failure.
+ */
 static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on)
 {
-       struct ufs_qcom_host *host = hba->priv;
-       int err = 0;
+       struct ufs_qcom_host *host = ufshcd_get_variant(hba);
+       int err;
        int vote = 0;
 
        /*
@@ -835,20 +1090,18 @@ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on)
                        ufs_qcom_phy_disable_iface_clk(host->generic_phy);
                        goto out;
                }
-               /* enable the device ref clock */
-               ufs_qcom_phy_enable_dev_ref_clk(host->generic_phy);
                vote = host->bus_vote.saved_vote;
                if (vote == host->bus_vote.min_bw_vote)
                        ufs_qcom_update_bus_bw_vote(host);
+
        } else {
+
                /* M-PHY RMMI interface clocks can be turned off */
                ufs_qcom_phy_disable_iface_clk(host->generic_phy);
-               if (!ufs_qcom_is_link_active(hba)) {
-                       /* turn off UFS local PHY ref_clk */
-                       ufs_qcom_phy_disable_ref_clk(host->generic_phy);
+               if (!ufs_qcom_is_link_active(hba))
                        /* disable device ref_clk */
-                       ufs_qcom_phy_disable_dev_ref_clk(host->generic_phy);
-               }
+                       ufs_qcom_dev_ref_clk_ctrl(host, false);
+
                vote = host->bus_vote.min_bw_vote;
        }
 
@@ -861,68 +1114,17 @@ out:
        return err;
 }
 
-static ssize_t
-show_ufs_to_mem_max_bus_bw(struct device *dev, struct device_attribute *attr,
-                       char *buf)
-{
-       struct ufs_hba *hba = dev_get_drvdata(dev);
-       struct ufs_qcom_host *host = hba->priv;
-
-       return snprintf(buf, PAGE_SIZE, "%u\n",
-                       host->bus_vote.is_max_bw_needed);
-}
-
-static ssize_t
-store_ufs_to_mem_max_bus_bw(struct device *dev, struct device_attribute *attr,
-               const char *buf, size_t count)
-{
-       struct ufs_hba *hba = dev_get_drvdata(dev);
-       struct ufs_qcom_host *host = hba->priv;
-       uint32_t value;
-
-       if (!kstrtou32(buf, 0, &value)) {
-               host->bus_vote.is_max_bw_needed = !!value;
-               ufs_qcom_update_bus_bw_vote(host);
-       }
-
-       return count;
-}
-
-static int ufs_qcom_bus_register(struct ufs_qcom_host *host)
-{
-       int err;
-       struct device *dev = host->hba->dev;
-       struct device_node *np = dev->of_node;
-
-       err = of_property_count_strings(np, "qcom,bus-vector-names");
-       if (err < 0 ) {
-               dev_err(dev, "%s: qcom,bus-vector-names not specified correctly %d\n",
-                               __func__, err);
-               goto out;
-       }
-
-       /* cache the vote index for minimum and maximum bandwidth */
-       host->bus_vote.min_bw_vote = ufs_qcom_get_bus_vote(host, "MIN");
-       host->bus_vote.max_bw_vote = ufs_qcom_get_bus_vote(host, "MAX");
-
-       host->bus_vote.max_bus_bw.show = show_ufs_to_mem_max_bus_bw;
-       host->bus_vote.max_bus_bw.store = store_ufs_to_mem_max_bus_bw;
-       sysfs_attr_init(&host->bus_vote.max_bus_bw.attr);
-       host->bus_vote.max_bus_bw.attr.name = "max_bus_bw";
-       host->bus_vote.max_bus_bw.attr.mode = S_IRUGO | S_IWUSR;
-       err = device_create_file(dev, &host->bus_vote.max_bus_bw);
-out:
-       return err;
-}
-
 #define        ANDROID_BOOT_DEV_MAX    30
 static char android_boot_dev[ANDROID_BOOT_DEV_MAX];
-static int get_android_boot_dev(char *str)
+
+#ifndef MODULE
+static int __init get_android_boot_dev(char *str)
 {
        strlcpy(android_boot_dev, str, ANDROID_BOOT_DEV_MAX);
        return 1;
 }
 __setup("androidboot.bootdevice=", get_android_boot_dev);
+#endif
 
 /**
  * ufs_qcom_init - bind phy with controller
@@ -938,7 +1140,9 @@ static int ufs_qcom_init(struct ufs_hba *hba)
 {
        int err;
        struct device *dev = hba->dev;
+       struct platform_device *pdev = to_platform_device(dev);
        struct ufs_qcom_host *host;
+       struct resource *res;
 
        if (strlen(android_boot_dev) && strcmp(android_boot_dev, dev_name(dev)))
                return -ENODEV;
@@ -950,9 +1154,15 @@ static int ufs_qcom_init(struct ufs_hba *hba)
                goto out;
        }
 
+       /* Make a two way bind between the qcom host and the hba */
        host->hba = hba;
-       hba->priv = (void *)host;
+       ufshcd_set_variant(hba, host);
 
+       /*
+        * voting/devoting device ref_clk source is time consuming hence
+        * skip devoting it during aggressive clock gating. This clock
+        * will still be gated off during runtime suspend.
+        */
        host->generic_phy = devm_phy_get(dev, "ufsphy");
 
        if (IS_ERR(host->generic_phy)) {
@@ -968,6 +1178,30 @@ static int ufs_qcom_init(struct ufs_hba *hba)
        ufs_qcom_get_controller_revision(hba, &host->hw_ver.major,
                &host->hw_ver.minor, &host->hw_ver.step);
 
+       /*
+        * for newer controllers, device reference clock control bit has
+        * moved inside UFS controller register address space itself.
+        */
+       if (host->hw_ver.major >= 0x02) {
+               host->dev_ref_clk_ctrl_mmio = hba->mmio_base + REG_UFS_CFG1;
+               host->dev_ref_clk_en_mask = BIT(26);
+       } else {
+               /* "dev_ref_clk_ctrl_mem" is optional resource */
+               res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+               if (res) {
+                       host->dev_ref_clk_ctrl_mmio =
+                                       devm_ioremap_resource(dev, res);
+                       if (IS_ERR(host->dev_ref_clk_ctrl_mmio)) {
+                               dev_warn(dev,
+                                       "%s: could not map dev_ref_clk_ctrl_mmio, err %ld\n",
+                                       __func__,
+                                       PTR_ERR(host->dev_ref_clk_ctrl_mmio));
+                               host->dev_ref_clk_ctrl_mmio = NULL;
+                       }
+                       host->dev_ref_clk_en_mask = BIT(5);
+               }
+       }
+
        /* update phy revision information before calling phy_init() */
        ufs_qcom_phy_save_controller_version(host->generic_phy,
                host->hw_ver.major, host->hw_ver.minor, host->hw_ver.step);
@@ -984,14 +1218,20 @@ static int ufs_qcom_init(struct ufs_hba *hba)
        ufs_qcom_set_caps(hba);
        ufs_qcom_advertise_quirks(hba);
 
-       hba->caps |= UFSHCD_CAP_CLK_GATING | UFSHCD_CAP_CLK_SCALING;
-       hba->caps |= UFSHCD_CAP_AUTO_BKOPS_SUSPEND;
-
        ufs_qcom_setup_clocks(hba, true);
 
        if (hba->dev->id < MAX_UFS_QCOM_HOSTS)
                ufs_qcom_hosts[hba->dev->id] = host;
 
+       host->dbg_print_en |= UFS_QCOM_DEFAULT_DBG_PRINT_EN;
+       ufs_qcom_get_default_testbus_cfg(host);
+       err = ufs_qcom_testbus_config(host);
+       if (err) {
+               dev_warn(dev, "%s: failed to configure the testbus %d\n",
+                               __func__, err);
+               err = 0;
+       }
+
        goto out;
 
 out_disable_phy:
@@ -1000,40 +1240,266 @@ out_unregister_bus:
        phy_exit(host->generic_phy);
 out_host_free:
        devm_kfree(dev, host);
-       hba->priv = NULL;
+       ufshcd_set_variant(hba, NULL);
 out:
        return err;
 }
 
 static void ufs_qcom_exit(struct ufs_hba *hba)
 {
-       struct ufs_qcom_host *host = hba->priv;
+       struct ufs_qcom_host *host = ufshcd_get_variant(hba);
 
        ufs_qcom_disable_lane_clks(host);
        phy_power_off(host->generic_phy);
 }
 
-static
-void ufs_qcom_clk_scale_notify(struct ufs_hba *hba)
+static int ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(struct ufs_hba *hba,
+                                                      u32 clk_cycles)
+{
+       int err;
+       u32 core_clk_ctrl_reg;
+
+       if (clk_cycles > DME_VS_CORE_CLK_CTRL_MAX_CORE_CLK_1US_CYCLES_MASK)
+               return -EINVAL;
+
+       err = ufshcd_dme_get(hba,
+                           UIC_ARG_MIB(DME_VS_CORE_CLK_CTRL),
+                           &core_clk_ctrl_reg);
+       if (err)
+               goto out;
+
+       core_clk_ctrl_reg &= ~DME_VS_CORE_CLK_CTRL_MAX_CORE_CLK_1US_CYCLES_MASK;
+       core_clk_ctrl_reg |= clk_cycles;
+
+       /* Clear CORE_CLK_DIV_EN */
+       core_clk_ctrl_reg &= ~DME_VS_CORE_CLK_CTRL_CORE_CLK_DIV_EN_BIT;
+
+       err = ufshcd_dme_set(hba,
+                           UIC_ARG_MIB(DME_VS_CORE_CLK_CTRL),
+                           core_clk_ctrl_reg);
+out:
+       return err;
+}
+
+static int ufs_qcom_clk_scale_up_pre_change(struct ufs_hba *hba)
+{
+       /* nothing to do as of now */
+       return 0;
+}
+
+static int ufs_qcom_clk_scale_up_post_change(struct ufs_hba *hba)
+{
+       struct ufs_qcom_host *host = ufshcd_get_variant(hba);
+
+       if (!ufs_qcom_cap_qunipro(host))
+               return 0;
+
+       /* set unipro core clock cycles to 150 and clear clock divider */
+       return ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(hba, 150);
+}
+
+static int ufs_qcom_clk_scale_down_pre_change(struct ufs_hba *hba)
+{
+       struct ufs_qcom_host *host = ufshcd_get_variant(hba);
+       int err;
+       u32 core_clk_ctrl_reg;
+
+       if (!ufs_qcom_cap_qunipro(host))
+               return 0;
+
+       err = ufshcd_dme_get(hba,
+                           UIC_ARG_MIB(DME_VS_CORE_CLK_CTRL),
+                           &core_clk_ctrl_reg);
+
+       /* make sure CORE_CLK_DIV_EN is cleared */
+       if (!err &&
+           (core_clk_ctrl_reg & DME_VS_CORE_CLK_CTRL_CORE_CLK_DIV_EN_BIT)) {
+               core_clk_ctrl_reg &= ~DME_VS_CORE_CLK_CTRL_CORE_CLK_DIV_EN_BIT;
+               err = ufshcd_dme_set(hba,
+                                   UIC_ARG_MIB(DME_VS_CORE_CLK_CTRL),
+                                   core_clk_ctrl_reg);
+       }
+
+       return err;
+}
+
+static int ufs_qcom_clk_scale_down_post_change(struct ufs_hba *hba)
+{
+       struct ufs_qcom_host *host = ufshcd_get_variant(hba);
+
+       if (!ufs_qcom_cap_qunipro(host))
+               return 0;
+
+       /* set unipro core clock cycles to 75 and clear clock divider */
+       return ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(hba, 75);
+}
+
+static int ufs_qcom_clk_scale_notify(struct ufs_hba *hba,
+               bool scale_up, enum ufs_notify_change_status status)
 {
-       struct ufs_qcom_host *host = hba->priv;
+       struct ufs_qcom_host *host = ufshcd_get_variant(hba);
        struct ufs_pa_layer_attr *dev_req_params = &host->dev_req_params;
+       int err = 0;
 
-       if (!dev_req_params)
-               return;
+       if (status == PRE_CHANGE) {
+               if (scale_up)
+                       err = ufs_qcom_clk_scale_up_pre_change(hba);
+               else
+                       err = ufs_qcom_clk_scale_down_pre_change(hba);
+       } else {
+               if (scale_up)
+                       err = ufs_qcom_clk_scale_up_post_change(hba);
+               else
+                       err = ufs_qcom_clk_scale_down_post_change(hba);
 
-       ufs_qcom_cfg_timers(hba, dev_req_params->gear_rx,
-                               dev_req_params->pwr_rx,
-                               dev_req_params->hs_rate);
+               if (err || !dev_req_params)
+                       goto out;
+
+               ufs_qcom_cfg_timers(hba,
+                                   dev_req_params->gear_rx,
+                                   dev_req_params->pwr_rx,
+                                   dev_req_params->hs_rate,
+                                   false);
+               ufs_qcom_update_bus_bw_vote(host);
+       }
+
+out:
+       return err;
 }
 
+static void ufs_qcom_get_default_testbus_cfg(struct ufs_qcom_host *host)
+{
+       /* provide a legal default configuration */
+       host->testbus.select_major = TSTBUS_UAWM;
+       host->testbus.select_minor = 1;
+}
+
+static bool ufs_qcom_testbus_cfg_is_ok(struct ufs_qcom_host *host)
+{
+       if (host->testbus.select_major >= TSTBUS_MAX) {
+               dev_err(host->hba->dev,
+                       "%s: UFS_CFG1[TEST_BUS_SEL} may not equal 0x%05X\n",
+                       __func__, host->testbus.select_major);
+               return false;
+       }
+
+       /*
+        * Not performing check for each individual select_major
+        * mappings of select_minor, since there is no harm in
+        * configuring a non-existent select_minor
+        */
+       if (host->testbus.select_minor > 0x1F) {
+               dev_err(host->hba->dev,
+                       "%s: 0x%05X is not a legal testbus option\n",
+                       __func__, host->testbus.select_minor);
+               return false;
+       }
+
+       return true;
+}
+
+int ufs_qcom_testbus_config(struct ufs_qcom_host *host)
+{
+       int reg;
+       int offset;
+       u32 mask = TEST_BUS_SUB_SEL_MASK;
+
+       if (!host)
+               return -EINVAL;
+
+       if (!ufs_qcom_testbus_cfg_is_ok(host))
+               return -EPERM;
+
+       switch (host->testbus.select_major) {
+       case TSTBUS_UAWM:
+               reg = UFS_TEST_BUS_CTRL_0;
+               offset = 24;
+               break;
+       case TSTBUS_UARM:
+               reg = UFS_TEST_BUS_CTRL_0;
+               offset = 16;
+               break;
+       case TSTBUS_TXUC:
+               reg = UFS_TEST_BUS_CTRL_0;
+               offset = 8;
+               break;
+       case TSTBUS_RXUC:
+               reg = UFS_TEST_BUS_CTRL_0;
+               offset = 0;
+               break;
+       case TSTBUS_DFC:
+               reg = UFS_TEST_BUS_CTRL_1;
+               offset = 24;
+               break;
+       case TSTBUS_TRLUT:
+               reg = UFS_TEST_BUS_CTRL_1;
+               offset = 16;
+               break;
+       case TSTBUS_TMRLUT:
+               reg = UFS_TEST_BUS_CTRL_1;
+               offset = 8;
+               break;
+       case TSTBUS_OCSC:
+               reg = UFS_TEST_BUS_CTRL_1;
+               offset = 0;
+               break;
+       case TSTBUS_WRAPPER:
+               reg = UFS_TEST_BUS_CTRL_2;
+               offset = 16;
+               break;
+       case TSTBUS_COMBINED:
+               reg = UFS_TEST_BUS_CTRL_2;
+               offset = 8;
+               break;
+       case TSTBUS_UTP_HCI:
+               reg = UFS_TEST_BUS_CTRL_2;
+               offset = 0;
+               break;
+       case TSTBUS_UNIPRO:
+               reg = UFS_UNIPRO_CFG;
+               offset = 1;
+               break;
+       /*
+        * No need for a default case, since
+        * ufs_qcom_testbus_cfg_is_ok() checks that the configuration
+        * is legal
+        */
+       }
+       mask <<= offset;
+
+       pm_runtime_get_sync(host->hba->dev);
+       ufshcd_hold(host->hba, false);
+       ufshcd_rmwl(host->hba, TEST_BUS_SEL,
+                   (u32)host->testbus.select_major << 19,
+                   REG_UFS_CFG1);
+       ufshcd_rmwl(host->hba, mask,
+                   (u32)host->testbus.select_minor << offset,
+                   reg);
+       ufshcd_release(host->hba);
+       pm_runtime_put_sync(host->hba->dev);
+
+       return 0;
+}
+
+static void ufs_qcom_testbus_read(struct ufs_hba *hba)
+{
+       ufs_qcom_dump_regs(hba, UFS_TEST_BUS, 1, "UFS_TEST_BUS ");
+}
+
+static void ufs_qcom_dump_dbg_regs(struct ufs_hba *hba)
+{
+       ufs_qcom_dump_regs(hba, REG_UFS_SYS1CLK_1US, 16,
+                       "HCI Vendor Specific Registers ");
+
+       ufs_qcom_testbus_read(hba);
+}
 /**
  * struct ufs_hba_qcom_vops - UFS QCOM specific variant operations
  *
  * The variant operations configure the necessary controller and PHY
  * handshake during initialization.
  */
-static const struct ufs_hba_variant_ops ufs_hba_qcom_vops = {
+static struct ufs_hba_variant_ops ufs_hba_qcom_vops = {
        .name                   = "qcom",
        .init                   = ufs_qcom_init,
        .exit                   = ufs_qcom_exit,
@@ -1045,5 +1511,66 @@ static const struct ufs_hba_variant_ops ufs_hba_qcom_vops = {
        .pwr_change_notify      = ufs_qcom_pwr_change_notify,
        .suspend                = ufs_qcom_suspend,
        .resume                 = ufs_qcom_resume,
+       .dbg_register_dump      = ufs_qcom_dump_dbg_regs,
+};
+
+/**
+ * ufs_qcom_probe - probe routine of the driver
+ * @pdev: pointer to Platform device handle
+ *
+ * Return zero for success and non-zero for failure
+ */
+static int ufs_qcom_probe(struct platform_device *pdev)
+{
+       int err;
+       struct device *dev = &pdev->dev;
+
+       /* Perform generic probe */
+       err = ufshcd_pltfrm_init(pdev, &ufs_hba_qcom_vops);
+       if (err)
+               dev_err(dev, "ufshcd_pltfrm_init() failed %d\n", err);
+
+       return err;
+}
+
+/**
+ * ufs_qcom_remove - set driver_data of the device to NULL
+ * @pdev: pointer to platform device handle
+ *
+ * Always return 0
+ */
+static int ufs_qcom_remove(struct platform_device *pdev)
+{
+       struct ufs_hba *hba =  platform_get_drvdata(pdev);
+
+       pm_runtime_get_sync(&(pdev)->dev);
+       ufshcd_remove(hba);
+       return 0;
+}
+
+static const struct of_device_id ufs_qcom_of_match[] = {
+       { .compatible = "qcom,ufshc"},
+       {},
+};
+
+static const struct dev_pm_ops ufs_qcom_pm_ops = {
+       .suspend        = ufshcd_pltfrm_suspend,
+       .resume         = ufshcd_pltfrm_resume,
+       .runtime_suspend = ufshcd_pltfrm_runtime_suspend,
+       .runtime_resume  = ufshcd_pltfrm_runtime_resume,
+       .runtime_idle    = ufshcd_pltfrm_runtime_idle,
 };
-EXPORT_SYMBOL(ufs_hba_qcom_vops);
+
+static struct platform_driver ufs_qcom_pltform = {
+       .probe  = ufs_qcom_probe,
+       .remove = ufs_qcom_remove,
+       .shutdown = ufshcd_pltfrm_shutdown,
+       .driver = {
+               .name   = "ufshcd-qcom",
+               .pm     = &ufs_qcom_pm_ops,
+               .of_match_table = of_match_ptr(ufs_qcom_of_match),
+       },
+};
+module_platform_driver(ufs_qcom_pltform);
+
+MODULE_LICENSE("GPL v2");
index db2c0a00e846282b37688e850a994e584ecb46d7..36249b35f8584939c74501068e0a730192dff94a 100644 (file)
@@ -35,8 +35,8 @@
 
 #define UFS_QCOM_LIMIT_NUM_LANES_RX    2
 #define UFS_QCOM_LIMIT_NUM_LANES_TX    2
-#define UFS_QCOM_LIMIT_HSGEAR_RX       UFS_HS_G2
-#define UFS_QCOM_LIMIT_HSGEAR_TX       UFS_HS_G2
+#define UFS_QCOM_LIMIT_HSGEAR_RX       UFS_HS_G3
+#define UFS_QCOM_LIMIT_HSGEAR_TX       UFS_HS_G3
 #define UFS_QCOM_LIMIT_PWMGEAR_RX      UFS_PWM_G4
 #define UFS_QCOM_LIMIT_PWMGEAR_TX      UFS_PWM_G4
 #define UFS_QCOM_LIMIT_RX_PWR_PWM      SLOW_MODE
@@ -58,6 +58,21 @@ enum {
        REG_UFS_CFG2                        = 0xE0,
        REG_UFS_HW_VERSION                  = 0xE4,
 
+       UFS_TEST_BUS                            = 0xE8,
+       UFS_TEST_BUS_CTRL_0                     = 0xEC,
+       UFS_TEST_BUS_CTRL_1                     = 0xF0,
+       UFS_TEST_BUS_CTRL_2                     = 0xF4,
+       UFS_UNIPRO_CFG                          = 0xF8,
+
+       /*
+        * QCOM UFS host controller vendor specific registers
+        * added in HW Version 3.0.0
+        */
+       UFS_AH8_CFG                             = 0xFC,
+};
+
+/* QCOM UFS host controller vendor specific debug registers */
+enum {
        UFS_DBG_RD_REG_UAWM                     = 0x100,
        UFS_DBG_RD_REG_UARM                     = 0x200,
        UFS_DBG_RD_REG_TXUC                     = 0x300,
@@ -73,6 +88,14 @@ enum {
        UFS_UFS_DBG_RD_EDTL_RAM                 = 0x1900,
 };
 
+#define UFS_CNTLR_2_x_x_VEN_REGS_OFFSET(x)     (0x000 + x)
+#define UFS_CNTLR_3_x_x_VEN_REGS_OFFSET(x)     (0x400 + x)
+
+/* bit definitions for REG_UFS_CFG1 register */
+#define QUNIPRO_SEL    UFS_BIT(0)
+#define TEST_BUS_EN            BIT(18)
+#define TEST_BUS_SEL           GENMASK(22, 19)
+
 /* bit definitions for REG_UFS_CFG2 register */
 #define UAWM_HW_CGC_EN         (1 << 0)
 #define UARM_HW_CGC_EN         (1 << 1)
@@ -83,6 +106,9 @@ enum {
 #define TMRLUT_HW_CGC_EN       (1 << 6)
 #define OCSC_HW_CGC_EN         (1 << 7)
 
+/* bit definition for UFS_UFS_TEST_BUS_CTRL_n */
+#define TEST_BUS_SUB_SEL_MASK  0x1F  /* All XXX_SEL fields are 5 bits wide */
+
 #define REG_UFS_CFG2_CGC_EN_ALL (UAWM_HW_CGC_EN | UARM_HW_CGC_EN |\
                                 TXUC_HW_CGC_EN | RXUC_HW_CGC_EN |\
                                 DFC_HW_CGC_EN | TRLUT_HW_CGC_EN |\
@@ -106,6 +132,21 @@ enum ufs_qcom_phy_init_type {
        UFS_PHY_INIT_CFG_RESTORE,
 };
 
+/* QCOM UFS debug print bit mask */
+#define UFS_QCOM_DBG_PRINT_REGS_EN     BIT(0)
+#define UFS_QCOM_DBG_PRINT_ICE_REGS_EN BIT(1)
+#define UFS_QCOM_DBG_PRINT_TEST_BUS_EN BIT(2)
+
+#define UFS_QCOM_DBG_PRINT_ALL \
+       (UFS_QCOM_DBG_PRINT_REGS_EN | UFS_QCOM_DBG_PRINT_ICE_REGS_EN | \
+        UFS_QCOM_DBG_PRINT_TEST_BUS_EN)
+
+/* QUniPro Vendor specific attributes */
+#define DME_VS_CORE_CLK_CTRL   0xD002
+/* bit and mask definitions for DME_VS_CORE_CLK_CTRL attribute */
+#define DME_VS_CORE_CLK_CTRL_CORE_CLK_DIV_EN_BIT               BIT(8)
+#define DME_VS_CORE_CLK_CTRL_MAX_CORE_CLK_1US_CYCLES_MASK      0xFF
+
 static inline void
 ufs_qcom_get_controller_revision(struct ufs_hba *hba,
                                 u8 *major, u16 *minor, u16 *step)
@@ -157,8 +198,13 @@ struct ufs_hw_version {
        u16 minor;
        u8 major;
 };
-struct ufs_qcom_host {
 
+struct ufs_qcom_testbus {
+       u8 select_major;
+       u8 select_minor;
+};
+
+struct ufs_qcom_host {
        /*
         * Set this capability if host controller supports the QUniPro mode
         * and if driver wants the Host controller to operate in QUniPro mode.
@@ -166,6 +212,12 @@ struct ufs_qcom_host {
         * controller supports the QUniPro mode.
         */
        #define UFS_QCOM_CAP_QUNIPRO    UFS_BIT(0)
+
+       /*
+        * Set this capability if host controller can retain the secure
+        * configuration even after UFS controller core power collapse.
+        */
+       #define UFS_QCOM_CAP_RETAIN_SEC_CFG_AFTER_PWR_COLLAPSE  UFS_BIT(1)
        u32 caps;
 
        struct phy *generic_phy;
@@ -178,13 +230,23 @@ struct ufs_qcom_host {
        struct clk *tx_l1_sync_clk;
        bool is_lane_clks_enabled;
 
+       void __iomem *dev_ref_clk_ctrl_mmio;
+       bool is_dev_ref_clk_enabled;
        struct ufs_hw_version hw_ver;
+
+       u32 dev_ref_clk_en_mask;
+
+       /* Bitmask for enabling debug prints */
+       u32 dbg_print_en;
+       struct ufs_qcom_testbus testbus;
 };
 
 #define ufs_qcom_is_link_off(hba) ufshcd_is_link_off(hba)
 #define ufs_qcom_is_link_active(hba) ufshcd_is_link_active(hba)
 #define ufs_qcom_is_link_hibern8(hba) ufshcd_is_link_hibern8(hba)
 
+int ufs_qcom_testbus_config(struct ufs_qcom_host *host);
+
 static inline bool ufs_qcom_cap_qunipro(struct ufs_qcom_host *host)
 {
        if (host->caps & UFS_QCOM_CAP_QUNIPRO)
index 7db9564f507df27d7ddcfce6369a05e6622f7e41..9714f2a8b32977d7394838c888bda8b64c1210ef 100644 (file)
 #include <linux/of.h>
 
 #include "ufshcd.h"
-
-static const struct of_device_id ufs_of_match[];
-static struct ufs_hba_variant_ops *get_variant_ops(struct device *dev)
-{
-       if (dev->of_node) {
-               const struct of_device_id *match;
-
-               match = of_match_node(ufs_of_match, dev->of_node);
-               if (match)
-                       return (struct ufs_hba_variant_ops *)match->data;
-       }
-
-       return NULL;
-}
+#include "ufshcd-pltfrm.h"
 
 static int ufshcd_parse_clock_info(struct ufs_hba *hba)
 {
@@ -245,10 +232,11 @@ out:
  * Returns 0 if successful
  * Returns non-zero otherwise
  */
-static int ufshcd_pltfrm_suspend(struct device *dev)
+int ufshcd_pltfrm_suspend(struct device *dev)
 {
        return ufshcd_system_suspend(dev_get_drvdata(dev));
 }
+EXPORT_SYMBOL_GPL(ufshcd_pltfrm_suspend);
 
 /**
  * ufshcd_pltfrm_resume - resume power management function
@@ -257,43 +245,47 @@ static int ufshcd_pltfrm_suspend(struct device *dev)
  * Returns 0 if successful
  * Returns non-zero otherwise
  */
-static int ufshcd_pltfrm_resume(struct device *dev)
+int ufshcd_pltfrm_resume(struct device *dev)
 {
        return ufshcd_system_resume(dev_get_drvdata(dev));
 }
+EXPORT_SYMBOL_GPL(ufshcd_pltfrm_resume);
 
-static int ufshcd_pltfrm_runtime_suspend(struct device *dev)
+int ufshcd_pltfrm_runtime_suspend(struct device *dev)
 {
        return ufshcd_runtime_suspend(dev_get_drvdata(dev));
 }
-static int ufshcd_pltfrm_runtime_resume(struct device *dev)
+EXPORT_SYMBOL_GPL(ufshcd_pltfrm_runtime_suspend);
+
+int ufshcd_pltfrm_runtime_resume(struct device *dev)
 {
        return ufshcd_runtime_resume(dev_get_drvdata(dev));
 }
-static int ufshcd_pltfrm_runtime_idle(struct device *dev)
+EXPORT_SYMBOL_GPL(ufshcd_pltfrm_runtime_resume);
+
+int ufshcd_pltfrm_runtime_idle(struct device *dev)
 {
        return ufshcd_runtime_idle(dev_get_drvdata(dev));
 }
-#else /* !CONFIG_PM */
-#define ufshcd_pltfrm_suspend  NULL
-#define ufshcd_pltfrm_resume   NULL
-#define ufshcd_pltfrm_runtime_suspend  NULL
-#define ufshcd_pltfrm_runtime_resume   NULL
-#define ufshcd_pltfrm_runtime_idle     NULL
+EXPORT_SYMBOL_GPL(ufshcd_pltfrm_runtime_idle);
+
 #endif /* CONFIG_PM */
 
-static void ufshcd_pltfrm_shutdown(struct platform_device *pdev)
+void ufshcd_pltfrm_shutdown(struct platform_device *pdev)
 {
        ufshcd_shutdown((struct ufs_hba *)platform_get_drvdata(pdev));
 }
+EXPORT_SYMBOL_GPL(ufshcd_pltfrm_shutdown);
 
 /**
- * ufshcd_pltfrm_probe - probe routine of the driver
+ * ufshcd_pltfrm_init - probe routine of the driver
  * @pdev: pointer to Platform device handle
+ * @vops: pointer to variant ops
  *
  * Returns 0 on success, non-zero value on failure
  */
-static int ufshcd_pltfrm_probe(struct platform_device *pdev)
+int ufshcd_pltfrm_init(struct platform_device *pdev,
+                      struct ufs_hba_variant_ops *vops)
 {
        struct ufs_hba *hba;
        void __iomem *mmio_base;
@@ -321,19 +313,19 @@ static int ufshcd_pltfrm_probe(struct platform_device *pdev)
                goto out;
        }
 
-       hba->vops = get_variant_ops(&pdev->dev);
+       hba->vops = vops;
 
        err = ufshcd_parse_clock_info(hba);
        if (err) {
                dev_err(&pdev->dev, "%s: clock parse failed %d\n",
                                __func__, err);
-               goto out;
+               goto dealloc_host;
        }
        err = ufshcd_parse_regulator_info(hba);
        if (err) {
                dev_err(&pdev->dev, "%s: regulator init failed %d\n",
                                __func__, err);
-               goto out;
+               goto dealloc_host;
        }
 
        pm_runtime_set_active(&pdev->dev);
@@ -352,50 +344,12 @@ static int ufshcd_pltfrm_probe(struct platform_device *pdev)
 out_disable_rpm:
        pm_runtime_disable(&pdev->dev);
        pm_runtime_set_suspended(&pdev->dev);
+dealloc_host:
+       ufshcd_dealloc_host(hba);
 out:
        return err;
 }
-
-/**
- * ufshcd_pltfrm_remove - remove platform driver routine
- * @pdev: pointer to platform device handle
- *
- * Returns 0 on success, non-zero value on failure
- */
-static int ufshcd_pltfrm_remove(struct platform_device *pdev)
-{
-       struct ufs_hba *hba =  platform_get_drvdata(pdev);
-
-       pm_runtime_get_sync(&(pdev)->dev);
-       ufshcd_remove(hba);
-       return 0;
-}
-
-static const struct of_device_id ufs_of_match[] = {
-       { .compatible = "jedec,ufs-1.1"},
-       {},
-};
-
-static const struct dev_pm_ops ufshcd_dev_pm_ops = {
-       .suspend        = ufshcd_pltfrm_suspend,
-       .resume         = ufshcd_pltfrm_resume,
-       .runtime_suspend = ufshcd_pltfrm_runtime_suspend,
-       .runtime_resume  = ufshcd_pltfrm_runtime_resume,
-       .runtime_idle    = ufshcd_pltfrm_runtime_idle,
-};
-
-static struct platform_driver ufshcd_pltfrm_driver = {
-       .probe  = ufshcd_pltfrm_probe,
-       .remove = ufshcd_pltfrm_remove,
-       .shutdown = ufshcd_pltfrm_shutdown,
-       .driver = {
-               .name   = "ufshcd",
-               .pm     = &ufshcd_dev_pm_ops,
-               .of_match_table = ufs_of_match,
-       },
-};
-
-module_platform_driver(ufshcd_pltfrm_driver);
+EXPORT_SYMBOL_GPL(ufshcd_pltfrm_init);
 
 MODULE_AUTHOR("Santosh Yaragnavi <santosh.sy@samsung.com>");
 MODULE_AUTHOR("Vinayak Holikatti <h.vinayak@samsung.com>");
diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.h b/drivers/scsi/ufs/ufshcd-pltfrm.h
new file mode 100644 (file)
index 0000000..df64c41
--- /dev/null
@@ -0,0 +1,41 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef UFSHCD_PLTFRM_H_
+#define UFSHCD_PLTFRM_H_
+
+#include "ufshcd.h"
+
+int ufshcd_pltfrm_init(struct platform_device *pdev,
+                      struct ufs_hba_variant_ops *vops);
+void ufshcd_pltfrm_shutdown(struct platform_device *pdev);
+
+#ifdef CONFIG_PM
+
+int ufshcd_pltfrm_suspend(struct device *dev);
+int ufshcd_pltfrm_resume(struct device *dev);
+int ufshcd_pltfrm_runtime_suspend(struct device *dev);
+int ufshcd_pltfrm_runtime_resume(struct device *dev);
+int ufshcd_pltfrm_runtime_idle(struct device *dev);
+
+#else /* !CONFIG_PM */
+
+#define ufshcd_pltfrm_suspend  NULL
+#define ufshcd_pltfrm_resume   NULL
+#define ufshcd_pltfrm_runtime_suspend  NULL
+#define ufshcd_pltfrm_runtime_resume   NULL
+#define ufshcd_pltfrm_runtime_idle     NULL
+
+#endif /* CONFIG_PM */
+
+#endif /* UFSHCD_PLTFRM_H_ */
index b0ade73f8c6a66a6a5f4d32fcbc4ac266b43d7eb..85cd2564c15773f728e8bd6ae6fcde28867ab2bb 100644 (file)
@@ -271,10 +271,8 @@ static inline u32 ufshcd_get_intr_mask(struct ufs_hba *hba)
  */
 static inline u32 ufshcd_get_ufs_version(struct ufs_hba *hba)
 {
-       if (hba->quirks & UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION) {
-               if (hba->vops && hba->vops->get_ufs_hci_version)
-                       return hba->vops->get_ufs_hci_version(hba);
-       }
+       if (hba->quirks & UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION)
+               return ufshcd_vops_get_ufs_hci_version(hba);
 
        return ufshcd_readl(hba, REG_UFS_VERSION);
 }
@@ -627,6 +625,7 @@ start:
 out:
        return rc;
 }
+EXPORT_SYMBOL_GPL(ufshcd_hold);
 
 static void ufshcd_gate_work(struct work_struct *work)
 {
@@ -714,6 +713,7 @@ void ufshcd_release(struct ufs_hba *hba)
        __ufshcd_release(hba);
        spin_unlock_irqrestore(hba->host->host_lock, flags);
 }
+EXPORT_SYMBOL_GPL(ufshcd_release);
 
 static ssize_t ufshcd_clkgate_delay_show(struct device *dev,
                struct device_attribute *attr, char *buf)
@@ -2473,9 +2473,8 @@ static int ufshcd_change_power_mode(struct ufs_hba *hba,
                dev_err(hba->dev,
                        "%s: power mode change failed %d\n", __func__, ret);
        } else {
-               if (hba->vops && hba->vops->pwr_change_notify)
-                       hba->vops->pwr_change_notify(hba,
-                               POST_CHANGE, NULL, pwr_mode);
+               ufshcd_vops_pwr_change_notify(hba, POST_CHANGE, NULL,
+                                                               pwr_mode);
 
                memcpy(&hba->pwr_info, pwr_mode,
                        sizeof(struct ufs_pa_layer_attr));
@@ -2495,10 +2494,10 @@ static int ufshcd_config_pwr_mode(struct ufs_hba *hba,
        struct ufs_pa_layer_attr final_params = { 0 };
        int ret;
 
-       if (hba->vops && hba->vops->pwr_change_notify)
-               hba->vops->pwr_change_notify(hba,
-                    PRE_CHANGE, desired_pwr_mode, &final_params);
-       else
+       ret = ufshcd_vops_pwr_change_notify(hba, PRE_CHANGE,
+                                       desired_pwr_mode, &final_params);
+
+       if (ret)
                memcpy(&final_params, desired_pwr_mode, sizeof(final_params));
 
        ret = ufshcd_change_power_mode(hba, &final_params);
@@ -2647,8 +2646,7 @@ static int ufshcd_hba_enable(struct ufs_hba *hba)
        /* UniPro link is disabled at this point */
        ufshcd_set_link_off(hba);
 
-       if (hba->vops && hba->vops->hce_enable_notify)
-               hba->vops->hce_enable_notify(hba, PRE_CHANGE);
+       ufshcd_vops_hce_enable_notify(hba, PRE_CHANGE);
 
        /* start controller initialization sequence */
        ufshcd_hba_start(hba);
@@ -2681,8 +2679,7 @@ static int ufshcd_hba_enable(struct ufs_hba *hba)
        /* enable UIC related interrupts */
        ufshcd_enable_intr(hba, UFSHCD_UIC_MASK);
 
-       if (hba->vops && hba->vops->hce_enable_notify)
-               hba->vops->hce_enable_notify(hba, POST_CHANGE);
+       ufshcd_vops_hce_enable_notify(hba, POST_CHANGE);
 
        return 0;
 }
@@ -2735,8 +2732,7 @@ static int ufshcd_link_startup(struct ufs_hba *hba)
        int retries = DME_LINKSTARTUP_RETRIES;
 
        do {
-               if (hba->vops && hba->vops->link_startup_notify)
-                       hba->vops->link_startup_notify(hba, PRE_CHANGE);
+               ufshcd_vops_link_startup_notify(hba, PRE_CHANGE);
 
                ret = ufshcd_dme_link_startup(hba);
 
@@ -2767,11 +2763,9 @@ static int ufshcd_link_startup(struct ufs_hba *hba)
        }
 
        /* Include any host controller configuration via UIC commands */
-       if (hba->vops && hba->vops->link_startup_notify) {
-               ret = hba->vops->link_startup_notify(hba, POST_CHANGE);
-               if (ret)
-                       goto out;
-       }
+       ret = ufshcd_vops_link_startup_notify(hba, POST_CHANGE);
+       if (ret)
+               goto out;
 
        ret = ufshcd_make_hba_operational(hba);
 out:
@@ -4355,7 +4349,6 @@ static struct scsi_host_template ufshcd_driver_template = {
        .cmd_per_lun            = UFSHCD_CMD_PER_LUN,
        .can_queue              = UFSHCD_CAN_QUEUE,
        .max_host_blocked       = 1,
-       .use_blk_tags           = 1,
        .track_queue_depth      = 1,
 };
 
@@ -4578,8 +4571,7 @@ static int __ufshcd_setup_clocks(struct ufs_hba *hba, bool on,
                }
        }
 
-       if (hba->vops && hba->vops->setup_clocks)
-               ret = hba->vops->setup_clocks(hba, on);
+       ret = ufshcd_vops_setup_clocks(hba, on);
 out:
        if (ret) {
                list_for_each_entry(clki, head, list) {
@@ -4645,27 +4637,22 @@ static int ufshcd_variant_hba_init(struct ufs_hba *hba)
        if (!hba->vops)
                goto out;
 
-       if (hba->vops->init) {
-               err = hba->vops->init(hba);
-               if (err)
-                       goto out;
-       }
+       err = ufshcd_vops_init(hba);
+       if (err)
+               goto out;
 
-       if (hba->vops->setup_regulators) {
-               err = hba->vops->setup_regulators(hba, true);
-               if (err)
-                       goto out_exit;
-       }
+       err = ufshcd_vops_setup_regulators(hba, true);
+       if (err)
+               goto out_exit;
 
        goto out;
 
 out_exit:
-       if (hba->vops->exit)
-               hba->vops->exit(hba);
+       ufshcd_vops_exit(hba);
 out:
        if (err)
                dev_err(hba->dev, "%s: variant %s init failed err %d\n",
-                       __func__, hba->vops ? hba->vops->name : "", err);
+                       __func__, ufshcd_get_var_name(hba), err);
        return err;
 }
 
@@ -4674,14 +4661,11 @@ static void ufshcd_variant_hba_exit(struct ufs_hba *hba)
        if (!hba->vops)
                return;
 
-       if (hba->vops->setup_clocks)
-               hba->vops->setup_clocks(hba, false);
+       ufshcd_vops_setup_clocks(hba, false);
 
-       if (hba->vops->setup_regulators)
-               hba->vops->setup_regulators(hba, false);
+       ufshcd_vops_setup_regulators(hba, false);
 
-       if (hba->vops->exit)
-               hba->vops->exit(hba);
+       ufshcd_vops_exit(hba);
 }
 
 static int ufshcd_hba_init(struct ufs_hba *hba)
@@ -5058,17 +5042,13 @@ disable_clks:
         * vendor specific host controller register space call them before the
         * host clocks are ON.
         */
-       if (hba->vops && hba->vops->suspend) {
-               ret = hba->vops->suspend(hba, pm_op);
-               if (ret)
-                       goto set_link_active;
-       }
+       ret = ufshcd_vops_suspend(hba, pm_op);
+       if (ret)
+               goto set_link_active;
 
-       if (hba->vops && hba->vops->setup_clocks) {
-               ret = hba->vops->setup_clocks(hba, false);
-               if (ret)
-                       goto vops_resume;
-       }
+       ret = ufshcd_vops_setup_clocks(hba, false);
+       if (ret)
+               goto vops_resume;
 
        if (!ufshcd_is_link_active(hba))
                ufshcd_setup_clocks(hba, false);
@@ -5079,7 +5059,7 @@ disable_clks:
        hba->clk_gating.state = CLKS_OFF;
        /*
         * Disable the host irq as host controller as there won't be any
-        * host controller trasanction expected till resume.
+        * host controller transaction expected till resume.
         */
        ufshcd_disable_irq(hba);
        /* Put the host controller in low power mode if possible */
@@ -5087,8 +5067,7 @@ disable_clks:
        goto out;
 
 vops_resume:
-       if (hba->vops && hba->vops->resume)
-               hba->vops->resume(hba, pm_op);
+       ufshcd_vops_resume(hba, pm_op);
 set_link_active:
        ufshcd_vreg_set_hpm(hba);
        if (ufshcd_is_link_hibern8(hba) && !ufshcd_uic_hibern8_exit(hba))
@@ -5144,11 +5123,9 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
         * vendor specific host controller register space call them when the
         * host clocks are ON.
         */
-       if (hba->vops && hba->vops->resume) {
-               ret = hba->vops->resume(hba, pm_op);
-               if (ret)
-                       goto disable_vreg;
-       }
+       ret = ufshcd_vops_resume(hba, pm_op);
+       if (ret)
+               goto disable_vreg;
 
        if (ufshcd_is_link_hibern8(hba)) {
                ret = ufshcd_uic_hibern8_exit(hba);
@@ -5189,8 +5166,7 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
 set_old_link_state:
        ufshcd_link_state_transition(hba, old_link_state, 0);
 vendor_suspend:
-       if (hba->vops && hba->vops->suspend)
-               hba->vops->suspend(hba, pm_op);
+       ufshcd_vops_suspend(hba, pm_op);
 disable_vreg:
        ufshcd_vreg_set_lpm(hba);
 disable_irq_and_vops_clks:
@@ -5372,6 +5348,16 @@ void ufshcd_remove(struct ufs_hba *hba)
 }
 EXPORT_SYMBOL_GPL(ufshcd_remove);
 
+/**
+ * ufshcd_dealloc_host - deallocate Host Bus Adapter (HBA)
+ * @hba: pointer to Host Bus Adapter (HBA)
+ */
+void ufshcd_dealloc_host(struct ufs_hba *hba)
+{
+       scsi_host_put(hba->host);
+}
+EXPORT_SYMBOL_GPL(ufshcd_dealloc_host);
+
 /**
  * ufshcd_set_dma_mask - Set dma mask based on the controller
  *                      addressing capability
@@ -5433,6 +5419,10 @@ static int ufshcd_scale_clks(struct ufs_hba *hba, bool scale_up)
        if (!head || list_empty(head))
                goto out;
 
+       ret = ufshcd_vops_clk_scale_notify(hba, scale_up, PRE_CHANGE);
+       if (ret)
+               return ret;
+
        list_for_each_entry(clki, head, list) {
                if (!IS_ERR_OR_NULL(clki->clk)) {
                        if (scale_up && clki->max_freq) {
@@ -5463,8 +5453,9 @@ static int ufshcd_scale_clks(struct ufs_hba *hba, bool scale_up)
                dev_dbg(hba->dev, "%s: clk: %s, rate: %lu\n", __func__,
                                clki->name, clk_get_rate(clki->clk));
        }
-       if (hba->vops->clk_scale_notify)
-               hba->vops->clk_scale_notify(hba);
+
+       ret = ufshcd_vops_clk_scale_notify(hba, scale_up, POST_CHANGE);
+
 out:
        return ret;
 }
@@ -5619,13 +5610,6 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
                hba->is_irq_enabled = true;
        }
 
-       /* Enable SCSI tag mapping */
-       err = scsi_init_shared_tag_map(host, host->can_queue);
-       if (err) {
-               dev_err(hba->dev, "init shared queue failed\n");
-               goto exit_gating;
-       }
-
        err = scsi_add_host(host, hba->dev);
        if (err) {
                dev_err(hba->dev, "scsi_add_host failed\n");
index c40a0e78a6c4298cf437dc312f0a136dd78abfa9..2570d9477b3778c9505e616f72c22e0b30fad8be 100644 (file)
@@ -223,8 +223,10 @@ struct ufs_clk_info {
        bool enabled;
 };
 
-#define PRE_CHANGE      0
-#define POST_CHANGE     1
+enum ufs_notify_change_status {
+       PRE_CHANGE,
+       POST_CHANGE,
+};
 
 struct ufs_pa_layer_attr {
        u32 gear_rx;
@@ -259,22 +261,28 @@ struct ufs_pwr_mode_info {
  *                     to be set.
  * @suspend: called during host controller PM callback
  * @resume: called during host controller PM callback
+ * @dbg_register_dump: used to dump controller debug information
  */
 struct ufs_hba_variant_ops {
        const char *name;
        int     (*init)(struct ufs_hba *);
        void    (*exit)(struct ufs_hba *);
        u32     (*get_ufs_hci_version)(struct ufs_hba *);
-       void    (*clk_scale_notify)(struct ufs_hba *);
-       int     (*setup_clocks)(struct ufs_hba *, bool);
+       int     (*clk_scale_notify)(struct ufs_hba *, bool,
+                                   enum ufs_notify_change_status);
+       int     (*setup_clocks)(struct ufs_hba *, bool);
        int     (*setup_regulators)(struct ufs_hba *, bool);
-       int     (*hce_enable_notify)(struct ufs_hba *, bool);
-       int     (*link_startup_notify)(struct ufs_hba *, bool);
+       int     (*hce_enable_notify)(struct ufs_hba *,
+                                    enum ufs_notify_change_status);
+       int     (*link_startup_notify)(struct ufs_hba *,
+                                      enum ufs_notify_change_status);
        int     (*pwr_change_notify)(struct ufs_hba *,
-                                       bool, struct ufs_pa_layer_attr *,
+                                       enum ufs_notify_change_status status,
+                                       struct ufs_pa_layer_attr *,
                                        struct ufs_pa_layer_attr *);
        int     (*suspend)(struct ufs_hba *, enum ufs_pm_op);
        int     (*resume)(struct ufs_hba *, enum ufs_pm_op);
+       void    (*dbg_register_dump)(struct ufs_hba *hba);
 };
 
 /* clock gating state  */
@@ -576,6 +584,7 @@ static inline void ufshcd_rmwl(struct ufs_hba *hba, u32 mask, u32 val, u32 reg)
 }
 
 int ufshcd_alloc_host(struct device *, struct ufs_hba **);
+void ufshcd_dealloc_host(struct ufs_hba *);
 int ufshcd_init(struct ufs_hba * , void __iomem * , unsigned int);
 void ufshcd_remove(struct ufs_hba *);
 
@@ -594,6 +603,27 @@ static inline void check_upiu_size(void)
                GENERAL_UPIU_REQUEST_SIZE + QUERY_DESC_MAX_SIZE);
 }
 
+/**
+ * ufshcd_set_variant - set variant specific data to the hba
+ * @hba - per adapter instance
+ * @variant - pointer to variant specific data
+ */
+static inline void ufshcd_set_variant(struct ufs_hba *hba, void *variant)
+{
+       BUG_ON(!hba);
+       hba->priv = variant;
+}
+
+/**
+ * ufshcd_get_variant - get variant specific data from the hba
+ * @hba - per adapter instance
+ */
+static inline void *ufshcd_get_variant(struct ufs_hba *hba)
+{
+       BUG_ON(!hba);
+       return hba->priv;
+}
+
 extern int ufshcd_runtime_suspend(struct ufs_hba *hba);
 extern int ufshcd_runtime_resume(struct ufs_hba *hba);
 extern int ufshcd_runtime_idle(struct ufs_hba *hba);
@@ -653,4 +683,109 @@ static inline int ufshcd_dme_peer_get(struct ufs_hba *hba,
 
 int ufshcd_hold(struct ufs_hba *hba, bool async);
 void ufshcd_release(struct ufs_hba *hba);
+
+/* Wrapper functions for safely calling variant operations */
+static inline const char *ufshcd_get_var_name(struct ufs_hba *hba)
+{
+       if (hba->vops)
+               return hba->vops->name;
+       return "";
+}
+
+static inline int ufshcd_vops_init(struct ufs_hba *hba)
+{
+       if (hba->vops && hba->vops->init)
+               return hba->vops->init(hba);
+
+       return 0;
+}
+
+static inline void ufshcd_vops_exit(struct ufs_hba *hba)
+{
+       if (hba->vops && hba->vops->exit)
+               return hba->vops->exit(hba);
+}
+
+static inline u32 ufshcd_vops_get_ufs_hci_version(struct ufs_hba *hba)
+{
+       if (hba->vops && hba->vops->get_ufs_hci_version)
+               return hba->vops->get_ufs_hci_version(hba);
+
+       return ufshcd_readl(hba, REG_UFS_VERSION);
+}
+
+static inline int ufshcd_vops_clk_scale_notify(struct ufs_hba *hba,
+                       bool up, enum ufs_notify_change_status status)
+{
+       if (hba->vops && hba->vops->clk_scale_notify)
+               return hba->vops->clk_scale_notify(hba, up, status);
+       return 0;
+}
+
+static inline int ufshcd_vops_setup_clocks(struct ufs_hba *hba, bool on)
+{
+       if (hba->vops && hba->vops->setup_clocks)
+               return hba->vops->setup_clocks(hba, on);
+       return 0;
+}
+
+static inline int ufshcd_vops_setup_regulators(struct ufs_hba *hba, bool status)
+{
+       if (hba->vops && hba->vops->setup_regulators)
+               return hba->vops->setup_regulators(hba, status);
+
+       return 0;
+}
+
+static inline int ufshcd_vops_hce_enable_notify(struct ufs_hba *hba,
+                                               bool status)
+{
+       if (hba->vops && hba->vops->hce_enable_notify)
+               return hba->vops->hce_enable_notify(hba, status);
+
+       return 0;
+}
+static inline int ufshcd_vops_link_startup_notify(struct ufs_hba *hba,
+                                               bool status)
+{
+       if (hba->vops && hba->vops->link_startup_notify)
+               return hba->vops->link_startup_notify(hba, status);
+
+       return 0;
+}
+
+static inline int ufshcd_vops_pwr_change_notify(struct ufs_hba *hba,
+                                 bool status,
+                                 struct ufs_pa_layer_attr *dev_max_params,
+                                 struct ufs_pa_layer_attr *dev_req_params)
+{
+       if (hba->vops && hba->vops->pwr_change_notify)
+               return hba->vops->pwr_change_notify(hba, status,
+                                       dev_max_params, dev_req_params);
+
+       return -ENOTSUPP;
+}
+
+static inline int ufshcd_vops_suspend(struct ufs_hba *hba, enum ufs_pm_op op)
+{
+       if (hba->vops && hba->vops->suspend)
+               return hba->vops->suspend(hba, op);
+
+       return 0;
+}
+
+static inline int ufshcd_vops_resume(struct ufs_hba *hba, enum ufs_pm_op op)
+{
+       if (hba->vops && hba->vops->resume)
+               return hba->vops->resume(hba, op);
+
+       return 0;
+}
+
+static inline void ufshcd_vops_dbg_register_dump(struct ufs_hba *hba)
+{
+       if (hba->vops && hba->vops->dbg_register_dump)
+               hba->vops->dbg_register_dump(hba);
+}
+
 #endif /* End of Header */
index c7461d770d3a8bff4ba0d4c64067654cf53512ca..255204cc43e6218ff7caa6725d7430f300a4d571 100644 (file)
@@ -23,8 +23,6 @@
 #include <linux/inet.h>
 #include <target/target_core_base.h>
 #include <target/target_core_fabric.h>
-#include <target/target_core_fabric_configfs.h>
-#include <target/configfs_macros.h>
 #include <target/iscsi/iscsi_transport.h>
 
 #include <target/iscsi/iscsi_target_core.h>
 #include "iscsi_target.h"
 #include <target/iscsi/iscsi_target_stat.h>
 
-struct lio_target_configfs_attribute {
-       struct configfs_attribute attr;
-       ssize_t (*show)(void *, char *);
-       ssize_t (*store)(void *, const char *, size_t);
-};
 
 /* Start items for lio_target_portal_cit */
 
-static ssize_t lio_target_np_show_sctp(
-       struct se_tpg_np *se_tpg_np,
-       char *page)
+static inline struct iscsi_tpg_np *to_iscsi_tpg_np(struct config_item *item)
+{
+       return container_of(to_tpg_np(item), struct iscsi_tpg_np, se_tpg_np);
+}
+
+static ssize_t lio_target_np_sctp_show(struct config_item *item, char *page)
 {
-       struct iscsi_tpg_np *tpg_np = container_of(se_tpg_np,
-                               struct iscsi_tpg_np, se_tpg_np);
+       struct iscsi_tpg_np *tpg_np = to_iscsi_tpg_np(item);
        struct iscsi_tpg_np *tpg_np_sctp;
        ssize_t rb;
 
@@ -63,15 +58,12 @@ static ssize_t lio_target_np_show_sctp(
        return rb;
 }
 
-static ssize_t lio_target_np_store_sctp(
-       struct se_tpg_np *se_tpg_np,
-       const char *page,
-       size_t count)
+static ssize_t lio_target_np_sctp_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct iscsi_tpg_np *tpg_np = to_iscsi_tpg_np(item);
        struct iscsi_np *np;
        struct iscsi_portal_group *tpg;
-       struct iscsi_tpg_np *tpg_np = container_of(se_tpg_np,
-                               struct iscsi_tpg_np, se_tpg_np);
        struct iscsi_tpg_np *tpg_np_sctp = NULL;
        u32 op;
        int ret;
@@ -119,14 +111,9 @@ out:
        return -EINVAL;
 }
 
-TF_NP_BASE_ATTR(lio_target, sctp, S_IRUGO | S_IWUSR);
-
-static ssize_t lio_target_np_show_iser(
-       struct se_tpg_np *se_tpg_np,
-       char *page)
+static ssize_t lio_target_np_iser_show(struct config_item *item, char *page)
 {
-       struct iscsi_tpg_np *tpg_np = container_of(se_tpg_np,
-                               struct iscsi_tpg_np, se_tpg_np);
+       struct iscsi_tpg_np *tpg_np = to_iscsi_tpg_np(item);
        struct iscsi_tpg_np *tpg_np_iser;
        ssize_t rb;
 
@@ -139,15 +126,12 @@ static ssize_t lio_target_np_show_iser(
        return rb;
 }
 
-static ssize_t lio_target_np_store_iser(
-       struct se_tpg_np *se_tpg_np,
-       const char *page,
-       size_t count)
+static ssize_t lio_target_np_iser_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct iscsi_tpg_np *tpg_np = to_iscsi_tpg_np(item);
        struct iscsi_np *np;
        struct iscsi_portal_group *tpg;
-       struct iscsi_tpg_np *tpg_np = container_of(se_tpg_np,
-                               struct iscsi_tpg_np, se_tpg_np);
        struct iscsi_tpg_np *tpg_np_iser = NULL;
        char *endptr;
        u32 op;
@@ -198,11 +182,12 @@ out:
        return rc;
 }
 
-TF_NP_BASE_ATTR(lio_target, iser, S_IRUGO | S_IWUSR);
+CONFIGFS_ATTR(lio_target_np_, sctp);
+CONFIGFS_ATTR(lio_target_np_, iser);
 
 static struct configfs_attribute *lio_target_portal_attrs[] = {
-       &lio_target_np_sctp.attr,
-       &lio_target_np_iser.attr,
+       &lio_target_np_attr_sctp,
+       &lio_target_np_attr_iser,
        NULL,
 };
 
@@ -360,22 +345,21 @@ out:
 
 /* Start items for lio_target_nacl_attrib_cit */
 
-#define DEF_NACL_ATTRIB(name)                                          \
-static ssize_t iscsi_nacl_attrib_show_##name(                          \
-       struct se_node_acl *se_nacl,                                    \
-       char *page)                                                     \
+#define ISCSI_NACL_ATTR(name)                                          \
+static ssize_t iscsi_nacl_attrib_##name##_show(struct config_item *item,\
+               char *page)                                             \
 {                                                                      \
+       struct se_node_acl *se_nacl = attrib_to_nacl(item);             \
        struct iscsi_node_acl *nacl = container_of(se_nacl, struct iscsi_node_acl, \
                                        se_node_acl);                   \
                                                                        \
        return sprintf(page, "%u\n", nacl->node_attrib.name);           \
 }                                                                      \
                                                                        \
-static ssize_t iscsi_nacl_attrib_store_##name(                         \
-       struct se_node_acl *se_nacl,                                    \
-       const char *page,                                               \
-       size_t count)                                                   \
+static ssize_t iscsi_nacl_attrib_##name##_store(struct config_item *item,\
+               const char *page, size_t count)                         \
 {                                                                      \
+       struct se_node_acl *se_nacl = attrib_to_nacl(item);             \
        struct iscsi_node_acl *nacl = container_of(se_nacl, struct iscsi_node_acl, \
                                        se_node_acl);                   \
        u32 val;                                                        \
@@ -389,59 +373,28 @@ static ssize_t iscsi_nacl_attrib_store_##name(                            \
                return ret;                                             \
                                                                        \
        return count;                                                   \
-}
+}                                                                      \
+                                                                       \
+CONFIGFS_ATTR(iscsi_nacl_attrib_, name)
 
-#define NACL_ATTR(_name, _mode) TF_NACL_ATTRIB_ATTR(iscsi, _name, _mode);
-/*
- * Define iscsi_node_attrib_s_dataout_timeout
- */
-DEF_NACL_ATTRIB(dataout_timeout);
-NACL_ATTR(dataout_timeout, S_IRUGO | S_IWUSR);
-/*
- * Define iscsi_node_attrib_s_dataout_timeout_retries
- */
-DEF_NACL_ATTRIB(dataout_timeout_retries);
-NACL_ATTR(dataout_timeout_retries, S_IRUGO | S_IWUSR);
-/*
- * Define iscsi_node_attrib_s_default_erl
- */
-DEF_NACL_ATTRIB(default_erl);
-NACL_ATTR(default_erl, S_IRUGO | S_IWUSR);
-/*
- * Define iscsi_node_attrib_s_nopin_timeout
- */
-DEF_NACL_ATTRIB(nopin_timeout);
-NACL_ATTR(nopin_timeout, S_IRUGO | S_IWUSR);
-/*
- * Define iscsi_node_attrib_s_nopin_response_timeout
- */
-DEF_NACL_ATTRIB(nopin_response_timeout);
-NACL_ATTR(nopin_response_timeout, S_IRUGO | S_IWUSR);
-/*
- * Define iscsi_node_attrib_s_random_datain_pdu_offsets
- */
-DEF_NACL_ATTRIB(random_datain_pdu_offsets);
-NACL_ATTR(random_datain_pdu_offsets, S_IRUGO | S_IWUSR);
-/*
- * Define iscsi_node_attrib_s_random_datain_seq_offsets
- */
-DEF_NACL_ATTRIB(random_datain_seq_offsets);
-NACL_ATTR(random_datain_seq_offsets, S_IRUGO | S_IWUSR);
-/*
- * Define iscsi_node_attrib_s_random_r2t_offsets
- */
-DEF_NACL_ATTRIB(random_r2t_offsets);
-NACL_ATTR(random_r2t_offsets, S_IRUGO | S_IWUSR);
+ISCSI_NACL_ATTR(dataout_timeout);
+ISCSI_NACL_ATTR(dataout_timeout_retries);
+ISCSI_NACL_ATTR(default_erl);
+ISCSI_NACL_ATTR(nopin_timeout);
+ISCSI_NACL_ATTR(nopin_response_timeout);
+ISCSI_NACL_ATTR(random_datain_pdu_offsets);
+ISCSI_NACL_ATTR(random_datain_seq_offsets);
+ISCSI_NACL_ATTR(random_r2t_offsets);
 
 static struct configfs_attribute *lio_target_nacl_attrib_attrs[] = {
-       &iscsi_nacl_attrib_dataout_timeout.attr,
-       &iscsi_nacl_attrib_dataout_timeout_retries.attr,
-       &iscsi_nacl_attrib_default_erl.attr,
-       &iscsi_nacl_attrib_nopin_timeout.attr,
-       &iscsi_nacl_attrib_nopin_response_timeout.attr,
-       &iscsi_nacl_attrib_random_datain_pdu_offsets.attr,
-       &iscsi_nacl_attrib_random_datain_seq_offsets.attr,
-       &iscsi_nacl_attrib_random_r2t_offsets.attr,
+       &iscsi_nacl_attrib_attr_dataout_timeout,
+       &iscsi_nacl_attrib_attr_dataout_timeout_retries,
+       &iscsi_nacl_attrib_attr_default_erl,
+       &iscsi_nacl_attrib_attr_nopin_timeout,
+       &iscsi_nacl_attrib_attr_nopin_response_timeout,
+       &iscsi_nacl_attrib_attr_random_datain_pdu_offsets,
+       &iscsi_nacl_attrib_attr_random_datain_seq_offsets,
+       &iscsi_nacl_attrib_attr_random_r2t_offsets,
        NULL,
 };
 
@@ -450,7 +403,7 @@ static struct configfs_attribute *lio_target_nacl_attrib_attrs[] = {
 /* Start items for lio_target_nacl_auth_cit */
 
 #define __DEF_NACL_AUTH_STR(prefix, name, flags)                       \
-static ssize_t __iscsi_##prefix##_show_##name(                         \
+static ssize_t __iscsi_##prefix##_##name##_show(                       \
        struct iscsi_node_acl *nacl,                                    \
        char *page)                                                     \
 {                                                                      \
@@ -461,7 +414,7 @@ static ssize_t __iscsi_##prefix##_show_##name(                              \
        return snprintf(page, PAGE_SIZE, "%s\n", auth->name);           \
 }                                                                      \
                                                                        \
-static ssize_t __iscsi_##prefix##_store_##name(                                \
+static ssize_t __iscsi_##prefix##_##name##_store(                      \
        struct iscsi_node_acl *nacl,                                    \
        const char *page,                                               \
        size_t count)                                                   \
@@ -487,8 +440,35 @@ static ssize_t __iscsi_##prefix##_store_##name(                            \
        return count;                                                   \
 }
 
+#define DEF_NACL_AUTH_STR(name, flags)                                 \
+       __DEF_NACL_AUTH_STR(nacl_auth, name, flags)                     \
+static ssize_t iscsi_nacl_auth_##name##_show(struct config_item *item, \
+               char *page)                                             \
+{                                                                      \
+       struct se_node_acl *nacl = auth_to_nacl(item);                  \
+       return __iscsi_nacl_auth_##name##_show(container_of(nacl,       \
+                       struct iscsi_node_acl, se_node_acl), page);     \
+}                                                                      \
+static ssize_t iscsi_nacl_auth_##name##_store(struct config_item *item,        \
+               const char *page, size_t count)                         \
+{                                                                      \
+       struct se_node_acl *nacl = auth_to_nacl(item);                  \
+       return __iscsi_nacl_auth_##name##_store(container_of(nacl,      \
+                       struct iscsi_node_acl, se_node_acl), page, count); \
+}                                                                      \
+                                                                       \
+CONFIGFS_ATTR(iscsi_nacl_auth_, name)
+
+/*
+ * One-way authentication userid
+ */
+DEF_NACL_AUTH_STR(userid, NAF_USERID_SET);
+DEF_NACL_AUTH_STR(password, NAF_PASSWORD_SET);
+DEF_NACL_AUTH_STR(userid_mutual, NAF_USERID_IN_SET);
+DEF_NACL_AUTH_STR(password_mutual, NAF_PASSWORD_IN_SET);
+
 #define __DEF_NACL_AUTH_INT(prefix, name)                              \
-static ssize_t __iscsi_##prefix##_show_##name(                         \
+static ssize_t __iscsi_##prefix##_##name##_show(                               \
        struct iscsi_node_acl *nacl,                                    \
        char *page)                                                     \
 {                                                                      \
@@ -500,69 +480,26 @@ static ssize_t __iscsi_##prefix##_show_##name(                            \
        return snprintf(page, PAGE_SIZE, "%d\n", auth->name);           \
 }
 
-#define DEF_NACL_AUTH_STR(name, flags)                                 \
-       __DEF_NACL_AUTH_STR(nacl_auth, name, flags)                     \
-static ssize_t iscsi_nacl_auth_show_##name(                            \
-       struct se_node_acl *nacl,                                       \
-       char *page)                                                     \
-{                                                                      \
-       return __iscsi_nacl_auth_show_##name(container_of(nacl,         \
-                       struct iscsi_node_acl, se_node_acl), page);             \
-}                                                                      \
-static ssize_t iscsi_nacl_auth_store_##name(                           \
-       struct se_node_acl *nacl,                                       \
-       const char *page,                                               \
-       size_t count)                                                   \
-{                                                                      \
-       return __iscsi_nacl_auth_store_##name(container_of(nacl,        \
-                       struct iscsi_node_acl, se_node_acl), page, count);      \
-}
-
 #define DEF_NACL_AUTH_INT(name)                                                \
        __DEF_NACL_AUTH_INT(nacl_auth, name)                            \
-static ssize_t iscsi_nacl_auth_show_##name(                            \
-       struct se_node_acl *nacl,                                       \
-       char *page)                                                     \
+static ssize_t iscsi_nacl_auth_##name##_show(struct config_item *item, \
+               char *page)                                             \
 {                                                                      \
-       return __iscsi_nacl_auth_show_##name(container_of(nacl,         \
-                       struct iscsi_node_acl, se_node_acl), page);             \
-}
-
-#define AUTH_ATTR(_name, _mode)        TF_NACL_AUTH_ATTR(iscsi, _name, _mode);
-#define AUTH_ATTR_RO(_name) TF_NACL_AUTH_ATTR_RO(iscsi, _name);
+       struct se_node_acl *nacl = auth_to_nacl(item);                  \
+       return __iscsi_nacl_auth_##name##_show(container_of(nacl,       \
+                       struct iscsi_node_acl, se_node_acl), page);     \
+}                                                                      \
+                                                                       \
+CONFIGFS_ATTR_RO(iscsi_nacl_auth_, name)
 
-/*
- * One-way authentication userid
- */
-DEF_NACL_AUTH_STR(userid, NAF_USERID_SET);
-AUTH_ATTR(userid, S_IRUGO | S_IWUSR);
-/*
- * One-way authentication password
- */
-DEF_NACL_AUTH_STR(password, NAF_PASSWORD_SET);
-AUTH_ATTR(password, S_IRUGO | S_IWUSR);
-/*
- * Enforce mutual authentication
- */
 DEF_NACL_AUTH_INT(authenticate_target);
-AUTH_ATTR_RO(authenticate_target);
-/*
- * Mutual authentication userid
- */
-DEF_NACL_AUTH_STR(userid_mutual, NAF_USERID_IN_SET);
-AUTH_ATTR(userid_mutual, S_IRUGO | S_IWUSR);
-/*
- * Mutual authentication password
- */
-DEF_NACL_AUTH_STR(password_mutual, NAF_PASSWORD_IN_SET);
-AUTH_ATTR(password_mutual, S_IRUGO | S_IWUSR);
 
 static struct configfs_attribute *lio_target_nacl_auth_attrs[] = {
-       &iscsi_nacl_auth_userid.attr,
-       &iscsi_nacl_auth_password.attr,
-       &iscsi_nacl_auth_authenticate_target.attr,
-       &iscsi_nacl_auth_userid_mutual.attr,
-       &iscsi_nacl_auth_password_mutual.attr,
+       &iscsi_nacl_auth_attr_userid,
+       &iscsi_nacl_auth_attr_password,
+       &iscsi_nacl_auth_attr_authenticate_target,
+       &iscsi_nacl_auth_attr_userid_mutual,
+       &iscsi_nacl_auth_attr_password_mutual,
        NULL,
 };
 
@@ -570,11 +507,11 @@ static struct configfs_attribute *lio_target_nacl_auth_attrs[] = {
 
 /* Start items for lio_target_nacl_param_cit */
 
-#define DEF_NACL_PARAM(name)                                           \
-static ssize_t iscsi_nacl_param_show_##name(                           \
-       struct se_node_acl *se_nacl,                                    \
-       char *page)                                                     \
+#define ISCSI_NACL_PARAM(name)                                         \
+static ssize_t iscsi_nacl_param_##name##_show(struct config_item *item,        \
+               char *page)                                             \
 {                                                                      \
+       struct se_node_acl *se_nacl = param_to_nacl(item);              \
        struct iscsi_session *sess;                                     \
        struct se_session *se_sess;                                     \
        ssize_t rb;                                                     \
@@ -592,55 +529,34 @@ static ssize_t iscsi_nacl_param_show_##name(                              \
        spin_unlock_bh(&se_nacl->nacl_sess_lock);                       \
                                                                        \
        return rb;                                                      \
-}
-
-#define NACL_PARAM_ATTR(_name) TF_NACL_PARAM_ATTR_RO(iscsi, _name);
-
-DEF_NACL_PARAM(MaxConnections);
-NACL_PARAM_ATTR(MaxConnections);
-
-DEF_NACL_PARAM(InitialR2T);
-NACL_PARAM_ATTR(InitialR2T);
-
-DEF_NACL_PARAM(ImmediateData);
-NACL_PARAM_ATTR(ImmediateData);
-
-DEF_NACL_PARAM(MaxBurstLength);
-NACL_PARAM_ATTR(MaxBurstLength);
-
-DEF_NACL_PARAM(FirstBurstLength);
-NACL_PARAM_ATTR(FirstBurstLength);
-
-DEF_NACL_PARAM(DefaultTime2Wait);
-NACL_PARAM_ATTR(DefaultTime2Wait);
-
-DEF_NACL_PARAM(DefaultTime2Retain);
-NACL_PARAM_ATTR(DefaultTime2Retain);
-
-DEF_NACL_PARAM(MaxOutstandingR2T);
-NACL_PARAM_ATTR(MaxOutstandingR2T);
-
-DEF_NACL_PARAM(DataPDUInOrder);
-NACL_PARAM_ATTR(DataPDUInOrder);
-
-DEF_NACL_PARAM(DataSequenceInOrder);
-NACL_PARAM_ATTR(DataSequenceInOrder);
-
-DEF_NACL_PARAM(ErrorRecoveryLevel);
-NACL_PARAM_ATTR(ErrorRecoveryLevel);
+}                                                                      \
+                                                                       \
+CONFIGFS_ATTR_RO(iscsi_nacl_param_, name)
+
+ISCSI_NACL_PARAM(MaxConnections);
+ISCSI_NACL_PARAM(InitialR2T);
+ISCSI_NACL_PARAM(ImmediateData);
+ISCSI_NACL_PARAM(MaxBurstLength);
+ISCSI_NACL_PARAM(FirstBurstLength);
+ISCSI_NACL_PARAM(DefaultTime2Wait);
+ISCSI_NACL_PARAM(DefaultTime2Retain);
+ISCSI_NACL_PARAM(MaxOutstandingR2T);
+ISCSI_NACL_PARAM(DataPDUInOrder);
+ISCSI_NACL_PARAM(DataSequenceInOrder);
+ISCSI_NACL_PARAM(ErrorRecoveryLevel);
 
 static struct configfs_attribute *lio_target_nacl_param_attrs[] = {
-       &iscsi_nacl_param_MaxConnections.attr,
-       &iscsi_nacl_param_InitialR2T.attr,
-       &iscsi_nacl_param_ImmediateData.attr,
-       &iscsi_nacl_param_MaxBurstLength.attr,
-       &iscsi_nacl_param_FirstBurstLength.attr,
-       &iscsi_nacl_param_DefaultTime2Wait.attr,
-       &iscsi_nacl_param_DefaultTime2Retain.attr,
-       &iscsi_nacl_param_MaxOutstandingR2T.attr,
-       &iscsi_nacl_param_DataPDUInOrder.attr,
-       &iscsi_nacl_param_DataSequenceInOrder.attr,
-       &iscsi_nacl_param_ErrorRecoveryLevel.attr,
+       &iscsi_nacl_param_attr_MaxConnections,
+       &iscsi_nacl_param_attr_InitialR2T,
+       &iscsi_nacl_param_attr_ImmediateData,
+       &iscsi_nacl_param_attr_MaxBurstLength,
+       &iscsi_nacl_param_attr_FirstBurstLength,
+       &iscsi_nacl_param_attr_DefaultTime2Wait,
+       &iscsi_nacl_param_attr_DefaultTime2Retain,
+       &iscsi_nacl_param_attr_MaxOutstandingR2T,
+       &iscsi_nacl_param_attr_DataPDUInOrder,
+       &iscsi_nacl_param_attr_DataSequenceInOrder,
+       &iscsi_nacl_param_attr_ErrorRecoveryLevel,
        NULL,
 };
 
@@ -648,10 +564,9 @@ static struct configfs_attribute *lio_target_nacl_param_attrs[] = {
 
 /* Start items for lio_target_acl_cit */
 
-static ssize_t lio_target_nacl_show_info(
-       struct se_node_acl *se_nacl,
-       char *page)
+static ssize_t lio_target_nacl_info_show(struct config_item *item, char *page)
 {
+       struct se_node_acl *se_nacl = acl_to_nacl(item);
        struct iscsi_session *sess;
        struct iscsi_conn *conn;
        struct se_session *se_sess;
@@ -766,20 +681,16 @@ static ssize_t lio_target_nacl_show_info(
        return rb;
 }
 
-TF_NACL_BASE_ATTR_RO(lio_target, info);
-
-static ssize_t lio_target_nacl_show_cmdsn_depth(
-       struct se_node_acl *se_nacl,
-       char *page)
+static ssize_t lio_target_nacl_cmdsn_depth_show(struct config_item *item,
+               char *page)
 {
-       return sprintf(page, "%u\n", se_nacl->queue_depth);
+       return sprintf(page, "%u\n", acl_to_nacl(item)->queue_depth);
 }
 
-static ssize_t lio_target_nacl_store_cmdsn_depth(
-       struct se_node_acl *se_nacl,
-       const char *page,
-       size_t count)
+static ssize_t lio_target_nacl_cmdsn_depth_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct se_node_acl *se_nacl = acl_to_nacl(item);
        struct se_portal_group *se_tpg = se_nacl->se_tpg;
        struct iscsi_portal_group *tpg = container_of(se_tpg,
                        struct iscsi_portal_group, tpg_se_tpg);
@@ -829,20 +740,15 @@ static ssize_t lio_target_nacl_store_cmdsn_depth(
        return (!ret) ? count : (ssize_t)ret;
 }
 
-TF_NACL_BASE_ATTR(lio_target, cmdsn_depth, S_IRUGO | S_IWUSR);
-
-static ssize_t lio_target_nacl_show_tag(
-       struct se_node_acl *se_nacl,
-       char *page)
+static ssize_t lio_target_nacl_tag_show(struct config_item *item, char *page)
 {
-       return snprintf(page, PAGE_SIZE, "%s", se_nacl->acl_tag);
+       return snprintf(page, PAGE_SIZE, "%s", acl_to_nacl(item)->acl_tag);
 }
 
-static ssize_t lio_target_nacl_store_tag(
-       struct se_node_acl *se_nacl,
-       const char *page,
-       size_t count)
+static ssize_t lio_target_nacl_tag_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct se_node_acl *se_nacl = acl_to_nacl(item);
        int ret;
 
        ret = core_tpg_set_initiator_node_tag(se_nacl->se_tpg, se_nacl, page);
@@ -852,12 +758,14 @@ static ssize_t lio_target_nacl_store_tag(
        return count;
 }
 
-TF_NACL_BASE_ATTR(lio_target, tag, S_IRUGO | S_IWUSR);
+CONFIGFS_ATTR_RO(lio_target_nacl_, info);
+CONFIGFS_ATTR(lio_target_nacl_, cmdsn_depth);
+CONFIGFS_ATTR(lio_target_nacl_, tag);
 
 static struct configfs_attribute *lio_target_initiator_attrs[] = {
-       &lio_target_nacl_info.attr,
-       &lio_target_nacl_cmdsn_depth.attr,
-       &lio_target_nacl_tag.attr,
+       &lio_target_nacl_attr_info,
+       &lio_target_nacl_attr_cmdsn_depth,
+       &lio_target_nacl_attr_tag,
        NULL,
 };
 
@@ -907,10 +815,10 @@ static void lio_target_cleanup_nodeacl( struct se_node_acl *se_nacl)
 
 #define DEF_TPG_ATTRIB(name)                                           \
                                                                        \
-static ssize_t iscsi_tpg_attrib_show_##name(                           \
-       struct se_portal_group *se_tpg,                         \
-       char *page)                                                     \
+static ssize_t iscsi_tpg_attrib_##name##_show(struct config_item *item,        \
+               char *page)                                             \
 {                                                                      \
+       struct se_portal_group *se_tpg = attrib_to_tpg(item);           \
        struct iscsi_portal_group *tpg = container_of(se_tpg,           \
                        struct iscsi_portal_group, tpg_se_tpg); \
        ssize_t rb;                                                     \
@@ -923,11 +831,10 @@ static ssize_t iscsi_tpg_attrib_show_##name(                              \
        return rb;                                                      \
 }                                                                      \
                                                                        \
-static ssize_t iscsi_tpg_attrib_store_##name(                          \
-       struct se_portal_group *se_tpg,                         \
-       const char *page,                                               \
-       size_t count)                                                   \
+static ssize_t iscsi_tpg_attrib_##name##_store(struct config_item *item,\
+               const char *page, size_t count)                         \
 {                                                                      \
+       struct se_portal_group *se_tpg = attrib_to_tpg(item);           \
        struct iscsi_portal_group *tpg = container_of(se_tpg,           \
                        struct iscsi_portal_group, tpg_se_tpg); \
        u32 val;                                                        \
@@ -948,90 +855,37 @@ static ssize_t iscsi_tpg_attrib_store_##name(                             \
 out:                                                                   \
        iscsit_put_tpg(tpg);                                            \
        return ret;                                                     \
-}
-
-#define TPG_ATTR(_name, _mode) TF_TPG_ATTRIB_ATTR(iscsi, _name, _mode);
+}                                                                      \
+CONFIGFS_ATTR(iscsi_tpg_attrib_, name)
 
-/*
- * Define iscsi_tpg_attrib_s_authentication
- */
 DEF_TPG_ATTRIB(authentication);
-TPG_ATTR(authentication, S_IRUGO | S_IWUSR);
-/*
- * Define iscsi_tpg_attrib_s_login_timeout
- */
 DEF_TPG_ATTRIB(login_timeout);
-TPG_ATTR(login_timeout, S_IRUGO | S_IWUSR);
-/*
- * Define iscsi_tpg_attrib_s_netif_timeout
- */
 DEF_TPG_ATTRIB(netif_timeout);
-TPG_ATTR(netif_timeout, S_IRUGO | S_IWUSR);
-/*
- * Define iscsi_tpg_attrib_s_generate_node_acls
- */
 DEF_TPG_ATTRIB(generate_node_acls);
-TPG_ATTR(generate_node_acls, S_IRUGO | S_IWUSR);
-/*
- * Define iscsi_tpg_attrib_s_default_cmdsn_depth
- */
 DEF_TPG_ATTRIB(default_cmdsn_depth);
-TPG_ATTR(default_cmdsn_depth, S_IRUGO | S_IWUSR);
-/*
- Define iscsi_tpg_attrib_s_cache_dynamic_acls
- */
 DEF_TPG_ATTRIB(cache_dynamic_acls);
-TPG_ATTR(cache_dynamic_acls, S_IRUGO | S_IWUSR);
-/*
- * Define iscsi_tpg_attrib_s_demo_mode_write_protect
- */
 DEF_TPG_ATTRIB(demo_mode_write_protect);
-TPG_ATTR(demo_mode_write_protect, S_IRUGO | S_IWUSR);
-/*
- * Define iscsi_tpg_attrib_s_prod_mode_write_protect
- */
 DEF_TPG_ATTRIB(prod_mode_write_protect);
-TPG_ATTR(prod_mode_write_protect, S_IRUGO | S_IWUSR);
-/*
- * Define iscsi_tpg_attrib_s_demo_mode_discovery,
- */
 DEF_TPG_ATTRIB(demo_mode_discovery);
-TPG_ATTR(demo_mode_discovery, S_IRUGO | S_IWUSR);
-/*
- * Define iscsi_tpg_attrib_s_default_erl
- */
 DEF_TPG_ATTRIB(default_erl);
-TPG_ATTR(default_erl, S_IRUGO | S_IWUSR);
-/*
- * Define iscsi_tpg_attrib_s_t10_pi
- */
 DEF_TPG_ATTRIB(t10_pi);
-TPG_ATTR(t10_pi, S_IRUGO | S_IWUSR);
-/*
- * Define iscsi_tpg_attrib_s_fabric_prot_type
- */
 DEF_TPG_ATTRIB(fabric_prot_type);
-TPG_ATTR(fabric_prot_type, S_IRUGO | S_IWUSR);
-/*
- * Define iscsi_tpg_attrib_s_tpg_enabled_sendtargets
- */
 DEF_TPG_ATTRIB(tpg_enabled_sendtargets);
-TPG_ATTR(tpg_enabled_sendtargets, S_IRUGO | S_IWUSR);
 
 static struct configfs_attribute *lio_target_tpg_attrib_attrs[] = {
-       &iscsi_tpg_attrib_authentication.attr,
-       &iscsi_tpg_attrib_login_timeout.attr,
-       &iscsi_tpg_attrib_netif_timeout.attr,
-       &iscsi_tpg_attrib_generate_node_acls.attr,
-       &iscsi_tpg_attrib_default_cmdsn_depth.attr,
-       &iscsi_tpg_attrib_cache_dynamic_acls.attr,
-       &iscsi_tpg_attrib_demo_mode_write_protect.attr,
-       &iscsi_tpg_attrib_prod_mode_write_protect.attr,
-       &iscsi_tpg_attrib_demo_mode_discovery.attr,
-       &iscsi_tpg_attrib_default_erl.attr,
-       &iscsi_tpg_attrib_t10_pi.attr,
-       &iscsi_tpg_attrib_fabric_prot_type.attr,
-       &iscsi_tpg_attrib_tpg_enabled_sendtargets.attr,
+       &iscsi_tpg_attrib_attr_authentication,
+       &iscsi_tpg_attrib_attr_login_timeout,
+       &iscsi_tpg_attrib_attr_netif_timeout,
+       &iscsi_tpg_attrib_attr_generate_node_acls,
+       &iscsi_tpg_attrib_attr_default_cmdsn_depth,
+       &iscsi_tpg_attrib_attr_cache_dynamic_acls,
+       &iscsi_tpg_attrib_attr_demo_mode_write_protect,
+       &iscsi_tpg_attrib_attr_prod_mode_write_protect,
+       &iscsi_tpg_attrib_attr_demo_mode_discovery,
+       &iscsi_tpg_attrib_attr_default_erl,
+       &iscsi_tpg_attrib_attr_t10_pi,
+       &iscsi_tpg_attrib_attr_fabric_prot_type,
+       &iscsi_tpg_attrib_attr_tpg_enabled_sendtargets,
        NULL,
 };
 
@@ -1040,9 +894,8 @@ static struct configfs_attribute *lio_target_tpg_attrib_attrs[] = {
 /* Start items for lio_target_tpg_auth_cit */
 
 #define __DEF_TPG_AUTH_STR(prefix, name, flags)                                        \
-static ssize_t __iscsi_##prefix##_show_##name(                                 \
-       struct se_portal_group *se_tpg,                                         \
-       char *page)                                                             \
+static ssize_t __iscsi_##prefix##_##name##_show(struct se_portal_group *se_tpg,        \
+               char *page)                                                     \
 {                                                                              \
        struct iscsi_portal_group *tpg = container_of(se_tpg,                   \
                                struct iscsi_portal_group, tpg_se_tpg);         \
@@ -1054,10 +907,8 @@ static ssize_t __iscsi_##prefix##_show_##name(                                    \
        return snprintf(page, PAGE_SIZE, "%s\n", auth->name);                   \
 }                                                                              \
                                                                                \
-static ssize_t __iscsi_##prefix##_store_##name(                                        \
-       struct se_portal_group *se_tpg,                                         \
-       const char *page,                                                       \
-       size_t count)                                                           \
+static ssize_t __iscsi_##prefix##_##name##_store(struct se_portal_group *se_tpg,\
+               const char *page, size_t count)                                 \
 {                                                                              \
        struct iscsi_portal_group *tpg = container_of(se_tpg,                   \
                                struct iscsi_portal_group, tpg_se_tpg);         \
@@ -1081,10 +932,31 @@ static ssize_t __iscsi_##prefix##_store_##name(                                  \
        return count;                                                           \
 }
 
+#define DEF_TPG_AUTH_STR(name, flags)                                          \
+       __DEF_TPG_AUTH_STR(tpg_auth, name, flags)                               \
+static ssize_t iscsi_tpg_auth_##name##_show(struct config_item *item,          \
+               char *page)                                                     \
+{                                                                              \
+       return __iscsi_tpg_auth_##name##_show(auth_to_tpg(item), page);         \
+}                                                                              \
+                                                                               \
+static ssize_t iscsi_tpg_auth_##name##_store(struct config_item *item,         \
+               const char *page, size_t count)                                 \
+{                                                                              \
+       return __iscsi_tpg_auth_##name##_store(auth_to_tpg(item), page, count); \
+}                                                                              \
+                                                                               \
+CONFIGFS_ATTR(iscsi_tpg_auth_, name);
+
+
+DEF_TPG_AUTH_STR(userid, NAF_USERID_SET);
+DEF_TPG_AUTH_STR(password, NAF_PASSWORD_SET);
+DEF_TPG_AUTH_STR(userid_mutual, NAF_USERID_IN_SET);
+DEF_TPG_AUTH_STR(password_mutual, NAF_PASSWORD_IN_SET);
+
 #define __DEF_TPG_AUTH_INT(prefix, name)                                       \
-static ssize_t __iscsi_##prefix##_show_##name(                                 \
-       struct se_portal_group *se_tpg,                                         \
-       char *page)                                                             \
+static ssize_t __iscsi_##prefix##_##name##_show(struct se_portal_group *se_tpg,        \
+               char *page)                                                             \
 {                                                                              \
        struct iscsi_portal_group *tpg = container_of(se_tpg,                   \
                                struct iscsi_portal_group, tpg_se_tpg);         \
@@ -1096,67 +968,23 @@ static ssize_t __iscsi_##prefix##_show_##name(                                   \
        return snprintf(page, PAGE_SIZE, "%d\n", auth->name);                   \
 }
 
-#define DEF_TPG_AUTH_STR(name, flags)                                          \
-       __DEF_TPG_AUTH_STR(tpg_auth, name, flags)                               \
-static ssize_t iscsi_tpg_auth_show_##name(                                     \
-       struct se_portal_group *se_tpg,                                         \
-       char *page)                                                             \
-{                                                                              \
-       return __iscsi_tpg_auth_show_##name(se_tpg, page);                      \
-}                                                                              \
-                                                                               \
-static ssize_t iscsi_tpg_auth_store_##name(                                    \
-       struct se_portal_group *se_tpg,                                         \
-       const char *page,                                                       \
-       size_t count)                                                           \
-{                                                                              \
-       return __iscsi_tpg_auth_store_##name(se_tpg, page, count);              \
-}
-
 #define DEF_TPG_AUTH_INT(name)                                                 \
        __DEF_TPG_AUTH_INT(tpg_auth, name)                                      \
-static ssize_t iscsi_tpg_auth_show_##name(                                     \
-       struct se_portal_group *se_tpg,                                         \
-       char *page)                                                             \
+static ssize_t iscsi_tpg_auth_##name##_show(struct config_item *item,          \
+               char *page) \
 {                                                                              \
-       return __iscsi_tpg_auth_show_##name(se_tpg, page);                      \
-}
-
-#define TPG_AUTH_ATTR(_name, _mode) TF_TPG_AUTH_ATTR(iscsi, _name, _mode);
-#define TPG_AUTH_ATTR_RO(_name) TF_TPG_AUTH_ATTR_RO(iscsi, _name);
+       return __iscsi_tpg_auth_##name##_show(auth_to_tpg(item), page);         \
+}                                                                              \
+CONFIGFS_ATTR_RO(iscsi_tpg_auth_, name);
 
-/*
- *  * One-way authentication userid
- *   */
-DEF_TPG_AUTH_STR(userid, NAF_USERID_SET);
-TPG_AUTH_ATTR(userid, S_IRUGO | S_IWUSR);
-/*
- *  * One-way authentication password
- *   */
-DEF_TPG_AUTH_STR(password, NAF_PASSWORD_SET);
-TPG_AUTH_ATTR(password, S_IRUGO | S_IWUSR);
-/*
- *  * Enforce mutual authentication
- *   */
 DEF_TPG_AUTH_INT(authenticate_target);
-TPG_AUTH_ATTR_RO(authenticate_target);
-/*
- *  * Mutual authentication userid
- *   */
-DEF_TPG_AUTH_STR(userid_mutual, NAF_USERID_IN_SET);
-TPG_AUTH_ATTR(userid_mutual, S_IRUGO | S_IWUSR);
-/*
- *  * Mutual authentication password
- *   */
-DEF_TPG_AUTH_STR(password_mutual, NAF_PASSWORD_IN_SET);
-TPG_AUTH_ATTR(password_mutual, S_IRUGO | S_IWUSR);
 
 static struct configfs_attribute *lio_target_tpg_auth_attrs[] = {
-       &iscsi_tpg_auth_userid.attr,
-       &iscsi_tpg_auth_password.attr,
-       &iscsi_tpg_auth_authenticate_target.attr,
-       &iscsi_tpg_auth_userid_mutual.attr,
-       &iscsi_tpg_auth_password_mutual.attr,
+       &iscsi_tpg_auth_attr_userid,
+       &iscsi_tpg_auth_attr_password,
+       &iscsi_tpg_auth_attr_authenticate_target,
+       &iscsi_tpg_auth_attr_userid_mutual,
+       &iscsi_tpg_auth_attr_password_mutual,
        NULL,
 };
 
@@ -1165,10 +993,10 @@ static struct configfs_attribute *lio_target_tpg_auth_attrs[] = {
 /* Start items for lio_target_tpg_param_cit */
 
 #define DEF_TPG_PARAM(name)                                            \
-static ssize_t iscsi_tpg_param_show_##name(                            \
-       struct se_portal_group *se_tpg,                                 \
-       char *page)                                                     \
+static ssize_t iscsi_tpg_param_##name##_show(struct config_item *item, \
+               char *page)                                             \
 {                                                                      \
+       struct se_portal_group *se_tpg = param_to_tpg(item);            \
        struct iscsi_portal_group *tpg = container_of(se_tpg,           \
                        struct iscsi_portal_group, tpg_se_tpg);         \
        struct iscsi_param *param;                                      \
@@ -1188,11 +1016,10 @@ static ssize_t iscsi_tpg_param_show_##name(                             \
        iscsit_put_tpg(tpg);                                            \
        return rb;                                                      \
 }                                                                      \
-static ssize_t iscsi_tpg_param_store_##name(                           \
-       struct se_portal_group *se_tpg,                         \
-       const char *page,                                               \
-       size_t count)                                                   \
+static ssize_t iscsi_tpg_param_##name##_store(struct config_item *item, \
+               const char *page, size_t count)                         \
 {                                                                      \
+       struct se_portal_group *se_tpg = param_to_tpg(item);            \
        struct iscsi_portal_group *tpg = container_of(se_tpg,           \
                        struct iscsi_portal_group, tpg_se_tpg);         \
        char *buf;                                                      \
@@ -1220,96 +1047,54 @@ static ssize_t iscsi_tpg_param_store_##name(                            \
 out:                                                                   \
        kfree(buf);                                                     \
        iscsit_put_tpg(tpg);                                            \
-       return -EINVAL;                                         \
-}
-
-#define TPG_PARAM_ATTR(_name, _mode) TF_TPG_PARAM_ATTR(iscsi, _name, _mode);
+       return -EINVAL;                                                 \
+}                                                                      \
+CONFIGFS_ATTR(iscsi_tpg_param_, name)
 
 DEF_TPG_PARAM(AuthMethod);
-TPG_PARAM_ATTR(AuthMethod, S_IRUGO | S_IWUSR);
-
 DEF_TPG_PARAM(HeaderDigest);
-TPG_PARAM_ATTR(HeaderDigest, S_IRUGO | S_IWUSR);
-
 DEF_TPG_PARAM(DataDigest);
-TPG_PARAM_ATTR(DataDigest, S_IRUGO | S_IWUSR);
-
 DEF_TPG_PARAM(MaxConnections);
-TPG_PARAM_ATTR(MaxConnections, S_IRUGO | S_IWUSR);
-
 DEF_TPG_PARAM(TargetAlias);
-TPG_PARAM_ATTR(TargetAlias, S_IRUGO | S_IWUSR);
-
 DEF_TPG_PARAM(InitialR2T);
-TPG_PARAM_ATTR(InitialR2T, S_IRUGO | S_IWUSR);
-
 DEF_TPG_PARAM(ImmediateData);
-TPG_PARAM_ATTR(ImmediateData, S_IRUGO | S_IWUSR);
-
 DEF_TPG_PARAM(MaxRecvDataSegmentLength);
-TPG_PARAM_ATTR(MaxRecvDataSegmentLength, S_IRUGO | S_IWUSR);
-
 DEF_TPG_PARAM(MaxXmitDataSegmentLength);
-TPG_PARAM_ATTR(MaxXmitDataSegmentLength, S_IRUGO | S_IWUSR);
-
 DEF_TPG_PARAM(MaxBurstLength);
-TPG_PARAM_ATTR(MaxBurstLength, S_IRUGO | S_IWUSR);
-
 DEF_TPG_PARAM(FirstBurstLength);
-TPG_PARAM_ATTR(FirstBurstLength, S_IRUGO | S_IWUSR);
-
 DEF_TPG_PARAM(DefaultTime2Wait);
-TPG_PARAM_ATTR(DefaultTime2Wait, S_IRUGO | S_IWUSR);
-
 DEF_TPG_PARAM(DefaultTime2Retain);
-TPG_PARAM_ATTR(DefaultTime2Retain, S_IRUGO | S_IWUSR);
-
 DEF_TPG_PARAM(MaxOutstandingR2T);
-TPG_PARAM_ATTR(MaxOutstandingR2T, S_IRUGO | S_IWUSR);
-
 DEF_TPG_PARAM(DataPDUInOrder);
-TPG_PARAM_ATTR(DataPDUInOrder, S_IRUGO | S_IWUSR);
-
 DEF_TPG_PARAM(DataSequenceInOrder);
-TPG_PARAM_ATTR(DataSequenceInOrder, S_IRUGO | S_IWUSR);
-
 DEF_TPG_PARAM(ErrorRecoveryLevel);
-TPG_PARAM_ATTR(ErrorRecoveryLevel, S_IRUGO | S_IWUSR);
-
 DEF_TPG_PARAM(IFMarker);
-TPG_PARAM_ATTR(IFMarker, S_IRUGO | S_IWUSR);
-
 DEF_TPG_PARAM(OFMarker);
-TPG_PARAM_ATTR(OFMarker, S_IRUGO | S_IWUSR);
-
 DEF_TPG_PARAM(IFMarkInt);
-TPG_PARAM_ATTR(IFMarkInt, S_IRUGO | S_IWUSR);
-
 DEF_TPG_PARAM(OFMarkInt);
-TPG_PARAM_ATTR(OFMarkInt, S_IRUGO | S_IWUSR);
 
 static struct configfs_attribute *lio_target_tpg_param_attrs[] = {
-       &iscsi_tpg_param_AuthMethod.attr,
-       &iscsi_tpg_param_HeaderDigest.attr,
-       &iscsi_tpg_param_DataDigest.attr,
-       &iscsi_tpg_param_MaxConnections.attr,
-       &iscsi_tpg_param_TargetAlias.attr,
-       &iscsi_tpg_param_InitialR2T.attr,
-       &iscsi_tpg_param_ImmediateData.attr,
-       &iscsi_tpg_param_MaxRecvDataSegmentLength.attr,
-       &iscsi_tpg_param_MaxXmitDataSegmentLength.attr,
-       &iscsi_tpg_param_MaxBurstLength.attr,
-       &iscsi_tpg_param_FirstBurstLength.attr,
-       &iscsi_tpg_param_DefaultTime2Wait.attr,
-       &iscsi_tpg_param_DefaultTime2Retain.attr,
-       &iscsi_tpg_param_MaxOutstandingR2T.attr,
-       &iscsi_tpg_param_DataPDUInOrder.attr,
-       &iscsi_tpg_param_DataSequenceInOrder.attr,
-       &iscsi_tpg_param_ErrorRecoveryLevel.attr,
-       &iscsi_tpg_param_IFMarker.attr,
-       &iscsi_tpg_param_OFMarker.attr,
-       &iscsi_tpg_param_IFMarkInt.attr,
-       &iscsi_tpg_param_OFMarkInt.attr,
+       &iscsi_tpg_param_attr_AuthMethod,
+       &iscsi_tpg_param_attr_HeaderDigest,
+       &iscsi_tpg_param_attr_DataDigest,
+       &iscsi_tpg_param_attr_MaxConnections,
+       &iscsi_tpg_param_attr_TargetAlias,
+       &iscsi_tpg_param_attr_InitialR2T,
+       &iscsi_tpg_param_attr_ImmediateData,
+       &iscsi_tpg_param_attr_MaxRecvDataSegmentLength,
+       &iscsi_tpg_param_attr_MaxXmitDataSegmentLength,
+       &iscsi_tpg_param_attr_MaxBurstLength,
+       &iscsi_tpg_param_attr_FirstBurstLength,
+       &iscsi_tpg_param_attr_DefaultTime2Wait,
+       &iscsi_tpg_param_attr_DefaultTime2Retain,
+       &iscsi_tpg_param_attr_MaxOutstandingR2T,
+       &iscsi_tpg_param_attr_DataPDUInOrder,
+       &iscsi_tpg_param_attr_DataSequenceInOrder,
+       &iscsi_tpg_param_attr_ErrorRecoveryLevel,
+       &iscsi_tpg_param_attr_IFMarker,
+       &iscsi_tpg_param_attr_OFMarker,
+       &iscsi_tpg_param_attr_IFMarkInt,
+       &iscsi_tpg_param_attr_OFMarkInt,
        NULL,
 };
 
@@ -1317,10 +1102,9 @@ static struct configfs_attribute *lio_target_tpg_param_attrs[] = {
 
 /* Start items for lio_target_tpg_cit */
 
-static ssize_t lio_target_tpg_show_enable(
-       struct se_portal_group *se_tpg,
-       char *page)
+static ssize_t lio_target_tpg_enable_show(struct config_item *item, char *page)
 {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct iscsi_portal_group *tpg = container_of(se_tpg,
                        struct iscsi_portal_group, tpg_se_tpg);
        ssize_t len;
@@ -1333,11 +1117,10 @@ static ssize_t lio_target_tpg_show_enable(
        return len;
 }
 
-static ssize_t lio_target_tpg_store_enable(
-       struct se_portal_group *se_tpg,
-       const char *page,
-       size_t count)
+static ssize_t lio_target_tpg_enable_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct iscsi_portal_group *tpg = container_of(se_tpg,
                        struct iscsi_portal_group, tpg_se_tpg);
        u32 op;
@@ -1375,20 +1158,19 @@ out:
        return -EINVAL;
 }
 
-TF_TPG_BASE_ATTR(lio_target, enable, S_IRUGO | S_IWUSR);
 
-static ssize_t lio_target_tpg_show_dynamic_sessions(
-       struct se_portal_group *se_tpg,
-       char *page)
+static ssize_t lio_target_tpg_dynamic_sessions_show(struct config_item *item,
+               char *page)
 {
-       return target_show_dynamic_sessions(se_tpg, page);
+       return target_show_dynamic_sessions(to_tpg(item), page);
 }
 
-TF_TPG_BASE_ATTR_RO(lio_target, dynamic_sessions);
+CONFIGFS_ATTR(lio_target_tpg_, enable);
+CONFIGFS_ATTR_RO(lio_target_tpg_, dynamic_sessions);
 
 static struct configfs_attribute *lio_target_tpg_attrs[] = {
-       &lio_target_tpg_enable.attr,
-       &lio_target_tpg_dynamic_sessions.attr,
+       &lio_target_tpg_attr_enable,
+       &lio_target_tpg_attr_dynamic_sessions,
        NULL,
 };
 
@@ -1463,17 +1245,16 @@ static void lio_target_tiqn_deltpg(struct se_portal_group *se_tpg)
 
 /* Start LIO-Target TIQN struct contig_item lio_target_cit */
 
-static ssize_t lio_target_wwn_show_attr_lio_version(
-       struct target_fabric_configfs *tf,
-       char *page)
+static ssize_t lio_target_wwn_lio_version_show(struct config_item *item,
+               char *page)
 {
        return sprintf(page, "Datera Inc. iSCSI Target "ISCSIT_VERSION"\n");
 }
 
-TF_WWN_ATTR_RO(lio_target, lio_version);
+CONFIGFS_ATTR_RO(lio_target_wwn_, lio_version);
 
 static struct configfs_attribute *lio_target_wwn_attrs[] = {
-       &lio_target_wwn_lio_version.attr,
+       &lio_target_wwn_attr_lio_version,
        NULL,
 };
 
@@ -1552,77 +1333,47 @@ static void lio_target_call_coredeltiqn(
 
 #define DEF_DISC_AUTH_STR(name, flags)                                 \
        __DEF_NACL_AUTH_STR(disc, name, flags)                          \
-static ssize_t iscsi_disc_show_##name(                                 \
-       struct target_fabric_configfs *tf,                              \
-       char *page)                                                     \
+static ssize_t iscsi_disc_##name##_show(struct config_item *item, char *page) \
 {                                                                      \
-       return __iscsi_disc_show_##name(&iscsit_global->discovery_acl,  \
+       return __iscsi_disc_##name##_show(&iscsit_global->discovery_acl,\
                page);                                                  \
 }                                                                      \
-static ssize_t iscsi_disc_store_##name(                                        \
-       struct target_fabric_configfs *tf,                              \
-       const char *page,                                               \
-       size_t count)                                                   \
+static ssize_t iscsi_disc_##name##_store(struct config_item *item,     \
+               const char *page, size_t count)                         \
 {                                                                      \
-       return __iscsi_disc_store_##name(&iscsit_global->discovery_acl, \
+       return __iscsi_disc_##name##_store(&iscsit_global->discovery_acl,       \
                page, count);                                           \
-}
+                                                                       \
+}                                                                      \
+CONFIGFS_ATTR(iscsi_disc_, name)
+
+DEF_DISC_AUTH_STR(userid, NAF_USERID_SET);
+DEF_DISC_AUTH_STR(password, NAF_PASSWORD_SET);
+DEF_DISC_AUTH_STR(userid_mutual, NAF_USERID_IN_SET);
+DEF_DISC_AUTH_STR(password_mutual, NAF_PASSWORD_IN_SET);
 
 #define DEF_DISC_AUTH_INT(name)                                                \
        __DEF_NACL_AUTH_INT(disc, name)                                 \
-static ssize_t iscsi_disc_show_##name(                                 \
-       struct target_fabric_configfs *tf,                              \
-       char *page)                                                     \
+static ssize_t iscsi_disc_##name##_show(struct config_item *item, char *page) \
 {                                                                      \
-       return __iscsi_disc_show_##name(&iscsit_global->discovery_acl,  \
+       return __iscsi_disc_##name##_show(&iscsit_global->discovery_acl, \
                        page);                                          \
-}
-
-#define DISC_AUTH_ATTR(_name, _mode) TF_DISC_ATTR(iscsi, _name, _mode)
-#define DISC_AUTH_ATTR_RO(_name) TF_DISC_ATTR_RO(iscsi, _name)
+}                                                                      \
+CONFIGFS_ATTR_RO(iscsi_disc_, name)
 
-/*
- * One-way authentication userid
- */
-DEF_DISC_AUTH_STR(userid, NAF_USERID_SET);
-DISC_AUTH_ATTR(userid, S_IRUGO | S_IWUSR);
-/*
- * One-way authentication password
- */
-DEF_DISC_AUTH_STR(password, NAF_PASSWORD_SET);
-DISC_AUTH_ATTR(password, S_IRUGO | S_IWUSR);
-/*
- * Enforce mutual authentication
- */
 DEF_DISC_AUTH_INT(authenticate_target);
-DISC_AUTH_ATTR_RO(authenticate_target);
-/*
- * Mutual authentication userid
- */
-DEF_DISC_AUTH_STR(userid_mutual, NAF_USERID_IN_SET);
-DISC_AUTH_ATTR(userid_mutual, S_IRUGO | S_IWUSR);
-/*
- * Mutual authentication password
- */
-DEF_DISC_AUTH_STR(password_mutual, NAF_PASSWORD_IN_SET);
-DISC_AUTH_ATTR(password_mutual, S_IRUGO | S_IWUSR);
 
-/*
- * enforce_discovery_auth
- */
-static ssize_t iscsi_disc_show_enforce_discovery_auth(
-       struct target_fabric_configfs *tf,
-       char *page)
+
+static ssize_t iscsi_disc_enforce_discovery_auth_show(struct config_item *item,
+               char *page)
 {
        struct iscsi_node_auth *discovery_auth = &iscsit_global->discovery_acl.node_auth;
 
        return sprintf(page, "%d\n", discovery_auth->enforce_discovery_auth);
 }
 
-static ssize_t iscsi_disc_store_enforce_discovery_auth(
-       struct target_fabric_configfs *tf,
-       const char *page,
-       size_t count)
+static ssize_t iscsi_disc_enforce_discovery_auth_store(struct config_item *item,
+               const char *page, size_t count)
 {
        struct iscsi_param *param;
        struct iscsi_portal_group *discovery_tpg = iscsit_global->discovery_tpg;
@@ -1677,15 +1428,15 @@ static ssize_t iscsi_disc_store_enforce_discovery_auth(
        return count;
 }
 
-DISC_AUTH_ATTR(enforce_discovery_auth, S_IRUGO | S_IWUSR);
+CONFIGFS_ATTR(iscsi_disc_, enforce_discovery_auth);
 
 static struct configfs_attribute *lio_target_discovery_auth_attrs[] = {
-       &iscsi_disc_userid.attr,
-       &iscsi_disc_password.attr,
-       &iscsi_disc_authenticate_target.attr,
-       &iscsi_disc_userid_mutual.attr,
-       &iscsi_disc_password_mutual.attr,
-       &iscsi_disc_enforce_discovery_auth.attr,
+       &iscsi_disc_attr_userid,
+       &iscsi_disc_attr_password,
+       &iscsi_disc_attr_authenticate_target,
+       &iscsi_disc_attr_userid_mutual,
+       &iscsi_disc_attr_password_mutual,
+       &iscsi_disc_attr_enforce_discovery_auth,
        NULL,
 };
 
index 9dd94ff0b62c0e53e39dbd3685ce1e3dc272cb1b..411cb266a47d5c39bd7df5ec4b705bce68ef0ca2 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/export.h>
 #include <scsi/iscsi_proto.h>
 #include <target/target_core_base.h>
-#include <target/configfs_macros.h>
 
 #include <target/iscsi/iscsi_target_core.h>
 #include "iscsi_target_parameters.h"
 /*
  * Instance Attributes Table
  */
-CONFIGFS_EATTR_STRUCT(iscsi_stat_instance, iscsi_wwn_stat_grps);
-#define ISCSI_STAT_INSTANCE_ATTR(_name, _mode)                 \
-static struct iscsi_stat_instance_attribute                    \
-                       iscsi_stat_instance_##_name =           \
-       __CONFIGFS_EATTR(_name, _mode,                          \
-       iscsi_stat_instance_show_attr_##_name,                  \
-       iscsi_stat_instance_store_attr_##_name);
-
-#define ISCSI_STAT_INSTANCE_ATTR_RO(_name)                     \
-static struct iscsi_stat_instance_attribute                    \
-                       iscsi_stat_instance_##_name =           \
-       __CONFIGFS_EATTR_RO(_name,                              \
-       iscsi_stat_instance_show_attr_##_name);
-
-static ssize_t iscsi_stat_instance_show_attr_inst(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
-{
-       struct iscsi_tiqn *tiqn = container_of(igrps,
-                               struct iscsi_tiqn, tiqn_stat_grps);
+static struct iscsi_tiqn *iscsi_instance_tiqn(struct config_item *item)
+{
+       struct iscsi_wwn_stat_grps *igrps = container_of(to_config_group(item),
+                       struct iscsi_wwn_stat_grps, iscsi_instance_group);
+       return container_of(igrps, struct iscsi_tiqn, tiqn_stat_grps);
+}
 
-       return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_index);
+static ssize_t iscsi_stat_instance_inst_show(struct config_item *item,
+               char *page)
+{
+       return snprintf(page, PAGE_SIZE, "%u\n",
+                       iscsi_instance_tiqn(item)->tiqn_index);
 }
-ISCSI_STAT_INSTANCE_ATTR_RO(inst);
 
-static ssize_t iscsi_stat_instance_show_attr_min_ver(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_instance_min_ver_show(struct config_item *item,
+               char *page)
 {
        return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_DRAFT20_VERSION);
 }
-ISCSI_STAT_INSTANCE_ATTR_RO(min_ver);
 
-static ssize_t iscsi_stat_instance_show_attr_max_ver(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_instance_max_ver_show(struct config_item *item,
+               char *page)
 {
        return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_DRAFT20_VERSION);
 }
-ISCSI_STAT_INSTANCE_ATTR_RO(max_ver);
 
-static ssize_t iscsi_stat_instance_show_attr_portals(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_instance_portals_show(struct config_item *item,
+               char *page)
 {
-       struct iscsi_tiqn *tiqn = container_of(igrps,
-                               struct iscsi_tiqn, tiqn_stat_grps);
-
-       return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_num_tpg_nps);
+       return snprintf(page, PAGE_SIZE, "%u\n",
+                       iscsi_instance_tiqn(item)->tiqn_num_tpg_nps);
 }
-ISCSI_STAT_INSTANCE_ATTR_RO(portals);
 
-static ssize_t iscsi_stat_instance_show_attr_nodes(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_instance_nodes_show(struct config_item *item,
+               char *page)
 {
        return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_INST_NUM_NODES);
 }
-ISCSI_STAT_INSTANCE_ATTR_RO(nodes);
 
-static ssize_t iscsi_stat_instance_show_attr_sessions(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_instance_sessions_show(struct config_item *item,
+               char *page)
 {
-       struct iscsi_tiqn *tiqn = container_of(igrps,
-                               struct iscsi_tiqn, tiqn_stat_grps);
-
-       return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_nsessions);
+       return snprintf(page, PAGE_SIZE, "%u\n",
+               iscsi_instance_tiqn(item)->tiqn_nsessions);
 }
-ISCSI_STAT_INSTANCE_ATTR_RO(sessions);
 
-static ssize_t iscsi_stat_instance_show_attr_fail_sess(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_instance_fail_sess_show(struct config_item *item,
+               char *page)
 {
-       struct iscsi_tiqn *tiqn = container_of(igrps,
-                               struct iscsi_tiqn, tiqn_stat_grps);
+       struct iscsi_tiqn *tiqn = iscsi_instance_tiqn(item);
        struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats;
        u32 sess_err_count;
 
@@ -131,88 +110,84 @@ static ssize_t iscsi_stat_instance_show_attr_fail_sess(
 
        return snprintf(page, PAGE_SIZE, "%u\n", sess_err_count);
 }
-ISCSI_STAT_INSTANCE_ATTR_RO(fail_sess);
 
-static ssize_t iscsi_stat_instance_show_attr_fail_type(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_instance_fail_type_show(struct config_item *item,
+               char *page)
 {
-       struct iscsi_tiqn *tiqn = container_of(igrps,
-                               struct iscsi_tiqn, tiqn_stat_grps);
+       struct iscsi_tiqn *tiqn = iscsi_instance_tiqn(item);
        struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats;
 
        return snprintf(page, PAGE_SIZE, "%u\n",
                        sess_err->last_sess_failure_type);
 }
-ISCSI_STAT_INSTANCE_ATTR_RO(fail_type);
 
-static ssize_t iscsi_stat_instance_show_attr_fail_rem_name(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_instance_fail_rem_name_show(struct config_item *item,
+               char *page)
 {
-       struct iscsi_tiqn *tiqn = container_of(igrps,
-                               struct iscsi_tiqn, tiqn_stat_grps);
+       struct iscsi_tiqn *tiqn = iscsi_instance_tiqn(item);
        struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats;
 
        return snprintf(page, PAGE_SIZE, "%s\n",
                        sess_err->last_sess_fail_rem_name[0] ?
                        sess_err->last_sess_fail_rem_name : NONE);
 }
-ISCSI_STAT_INSTANCE_ATTR_RO(fail_rem_name);
 
-static ssize_t iscsi_stat_instance_show_attr_disc_time(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_instance_disc_time_show(struct config_item *item,
+               char *page)
 {
        return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_DISCONTINUITY_TIME);
 }
-ISCSI_STAT_INSTANCE_ATTR_RO(disc_time);
 
-static ssize_t iscsi_stat_instance_show_attr_description(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_instance_description_show(struct config_item *item,
+               char *page)
 {
        return snprintf(page, PAGE_SIZE, "%s\n", ISCSI_INST_DESCR);
 }
-ISCSI_STAT_INSTANCE_ATTR_RO(description);
 
-static ssize_t iscsi_stat_instance_show_attr_vendor(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_instance_vendor_show(struct config_item *item,
+               char *page)
 {
        return snprintf(page, PAGE_SIZE, "Datera, Inc. iSCSI-Target\n");
 }
-ISCSI_STAT_INSTANCE_ATTR_RO(vendor);
 
-static ssize_t iscsi_stat_instance_show_attr_version(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_instance_version_show(struct config_item *item,
+               char *page)
 {
        return snprintf(page, PAGE_SIZE, "%s\n", ISCSIT_VERSION);
 }
-ISCSI_STAT_INSTANCE_ATTR_RO(version);
 
-CONFIGFS_EATTR_OPS(iscsi_stat_instance, iscsi_wwn_stat_grps,
-               iscsi_instance_group);
+CONFIGFS_ATTR_RO(iscsi_stat_instance_, inst);
+CONFIGFS_ATTR_RO(iscsi_stat_instance_, min_ver);
+CONFIGFS_ATTR_RO(iscsi_stat_instance_, max_ver);
+CONFIGFS_ATTR_RO(iscsi_stat_instance_, portals);
+CONFIGFS_ATTR_RO(iscsi_stat_instance_, nodes);
+CONFIGFS_ATTR_RO(iscsi_stat_instance_, sessions);
+CONFIGFS_ATTR_RO(iscsi_stat_instance_, fail_sess);
+CONFIGFS_ATTR_RO(iscsi_stat_instance_, fail_type);
+CONFIGFS_ATTR_RO(iscsi_stat_instance_, fail_rem_name);
+CONFIGFS_ATTR_RO(iscsi_stat_instance_, disc_time);
+CONFIGFS_ATTR_RO(iscsi_stat_instance_, description);
+CONFIGFS_ATTR_RO(iscsi_stat_instance_, vendor);
+CONFIGFS_ATTR_RO(iscsi_stat_instance_, version);
 
 static struct configfs_attribute *iscsi_stat_instance_attrs[] = {
-       &iscsi_stat_instance_inst.attr,
-       &iscsi_stat_instance_min_ver.attr,
-       &iscsi_stat_instance_max_ver.attr,
-       &iscsi_stat_instance_portals.attr,
-       &iscsi_stat_instance_nodes.attr,
-       &iscsi_stat_instance_sessions.attr,
-       &iscsi_stat_instance_fail_sess.attr,
-       &iscsi_stat_instance_fail_type.attr,
-       &iscsi_stat_instance_fail_rem_name.attr,
-       &iscsi_stat_instance_disc_time.attr,
-       &iscsi_stat_instance_description.attr,
-       &iscsi_stat_instance_vendor.attr,
-       &iscsi_stat_instance_version.attr,
+       &iscsi_stat_instance_attr_inst,
+       &iscsi_stat_instance_attr_min_ver,
+       &iscsi_stat_instance_attr_max_ver,
+       &iscsi_stat_instance_attr_portals,
+       &iscsi_stat_instance_attr_nodes,
+       &iscsi_stat_instance_attr_sessions,
+       &iscsi_stat_instance_attr_fail_sess,
+       &iscsi_stat_instance_attr_fail_type,
+       &iscsi_stat_instance_attr_fail_rem_name,
+       &iscsi_stat_instance_attr_disc_time,
+       &iscsi_stat_instance_attr_description,
+       &iscsi_stat_instance_attr_vendor,
+       &iscsi_stat_instance_attr_version,
        NULL,
 };
 
-static struct configfs_item_operations iscsi_stat_instance_item_ops = {
-       .show_attribute         = iscsi_stat_instance_attr_show,
-       .store_attribute        = iscsi_stat_instance_attr_store,
-};
-
 struct config_item_type iscsi_stat_instance_cit = {
-       .ct_item_ops            = &iscsi_stat_instance_item_ops,
        .ct_attrs               = iscsi_stat_instance_attrs,
        .ct_owner               = THIS_MODULE,
 };
@@ -220,81 +195,61 @@ struct config_item_type iscsi_stat_instance_cit = {
 /*
  * Instance Session Failure Stats Table
  */
-CONFIGFS_EATTR_STRUCT(iscsi_stat_sess_err, iscsi_wwn_stat_grps);
-#define ISCSI_STAT_SESS_ERR_ATTR(_name, _mode)                 \
-static struct iscsi_stat_sess_err_attribute                    \
-                       iscsi_stat_sess_err_##_name =           \
-       __CONFIGFS_EATTR(_name, _mode,                          \
-       iscsi_stat_sess_err_show_attr_##_name,                  \
-       iscsi_stat_sess_err_store_attr_##_name);
-
-#define ISCSI_STAT_SESS_ERR_ATTR_RO(_name)                     \
-static struct iscsi_stat_sess_err_attribute                    \
-                       iscsi_stat_sess_err_##_name =           \
-       __CONFIGFS_EATTR_RO(_name,                              \
-       iscsi_stat_sess_err_show_attr_##_name);
-
-static ssize_t iscsi_stat_sess_err_show_attr_inst(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
-{
-       struct iscsi_tiqn *tiqn = container_of(igrps,
-                               struct iscsi_tiqn, tiqn_stat_grps);
+static struct iscsi_tiqn *iscsi_sess_err_tiqn(struct config_item *item)
+{
+       struct iscsi_wwn_stat_grps *igrps = container_of(to_config_group(item),
+                       struct iscsi_wwn_stat_grps, iscsi_sess_err_group);
+       return container_of(igrps, struct iscsi_tiqn, tiqn_stat_grps);
+}
 
-       return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_index);
+static ssize_t iscsi_stat_sess_err_inst_show(struct config_item *item,
+               char *page)
+{
+       return snprintf(page, PAGE_SIZE, "%u\n",
+               iscsi_sess_err_tiqn(item)->tiqn_index);
 }
-ISCSI_STAT_SESS_ERR_ATTR_RO(inst);
 
-static ssize_t iscsi_stat_sess_err_show_attr_digest_errors(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_sess_err_digest_errors_show(struct config_item *item,
+               char *page)
 {
-       struct iscsi_tiqn *tiqn = container_of(igrps,
-                               struct iscsi_tiqn, tiqn_stat_grps);
+       struct iscsi_tiqn *tiqn = iscsi_sess_err_tiqn(item);
        struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats;
 
        return snprintf(page, PAGE_SIZE, "%u\n", sess_err->digest_errors);
 }
-ISCSI_STAT_SESS_ERR_ATTR_RO(digest_errors);
 
-static ssize_t iscsi_stat_sess_err_show_attr_cxn_errors(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_sess_err_cxn_errors_show(struct config_item *item,
+               char *page)
 {
-       struct iscsi_tiqn *tiqn = container_of(igrps,
-                               struct iscsi_tiqn, tiqn_stat_grps);
+       struct iscsi_tiqn *tiqn = iscsi_sess_err_tiqn(item);
        struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats;
 
        return snprintf(page, PAGE_SIZE, "%u\n", sess_err->cxn_timeout_errors);
 }
-ISCSI_STAT_SESS_ERR_ATTR_RO(cxn_errors);
 
-static ssize_t iscsi_stat_sess_err_show_attr_format_errors(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_sess_err_format_errors_show(struct config_item *item,
+               char *page)
 {
-       struct iscsi_tiqn *tiqn = container_of(igrps,
-                               struct iscsi_tiqn, tiqn_stat_grps);
+       struct iscsi_tiqn *tiqn = iscsi_sess_err_tiqn(item);
        struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats;
 
        return snprintf(page, PAGE_SIZE, "%u\n", sess_err->pdu_format_errors);
 }
-ISCSI_STAT_SESS_ERR_ATTR_RO(format_errors);
 
-CONFIGFS_EATTR_OPS(iscsi_stat_sess_err, iscsi_wwn_stat_grps,
-               iscsi_sess_err_group);
+CONFIGFS_ATTR_RO(iscsi_stat_sess_err_, inst);
+CONFIGFS_ATTR_RO(iscsi_stat_sess_err_, digest_errors);
+CONFIGFS_ATTR_RO(iscsi_stat_sess_err_, cxn_errors);
+CONFIGFS_ATTR_RO(iscsi_stat_sess_err_, format_errors);
 
 static struct configfs_attribute *iscsi_stat_sess_err_attrs[] = {
-       &iscsi_stat_sess_err_inst.attr,
-       &iscsi_stat_sess_err_digest_errors.attr,
-       &iscsi_stat_sess_err_cxn_errors.attr,
-       &iscsi_stat_sess_err_format_errors.attr,
+       &iscsi_stat_sess_err_attr_inst,
+       &iscsi_stat_sess_err_attr_digest_errors,
+       &iscsi_stat_sess_err_attr_cxn_errors,
+       &iscsi_stat_sess_err_attr_format_errors,
        NULL,
 };
 
-static struct configfs_item_operations iscsi_stat_sess_err_item_ops = {
-       .show_attribute         = iscsi_stat_sess_err_attr_show,
-       .store_attribute        = iscsi_stat_sess_err_attr_store,
-};
-
 struct config_item_type iscsi_stat_sess_err_cit = {
-       .ct_item_ops            = &iscsi_stat_sess_err_item_ops,
        .ct_attrs               = iscsi_stat_sess_err_attrs,
        .ct_owner               = THIS_MODULE,
 };
@@ -302,42 +257,30 @@ struct config_item_type iscsi_stat_sess_err_cit = {
 /*
  * Target Attributes Table
  */
-CONFIGFS_EATTR_STRUCT(iscsi_stat_tgt_attr, iscsi_wwn_stat_grps);
-#define ISCSI_STAT_TGT_ATTR(_name, _mode)                      \
-static struct iscsi_stat_tgt_attr_attribute                    \
-                       iscsi_stat_tgt_attr_##_name =           \
-       __CONFIGFS_EATTR(_name, _mode,                          \
-       iscsi_stat_tgt-attr_show_attr_##_name,                  \
-       iscsi_stat_tgt_attr_store_attr_##_name);
-
-#define ISCSI_STAT_TGT_ATTR_RO(_name)                          \
-static struct iscsi_stat_tgt_attr_attribute                    \
-                       iscsi_stat_tgt_attr_##_name =           \
-       __CONFIGFS_EATTR_RO(_name,                              \
-       iscsi_stat_tgt_attr_show_attr_##_name);
-
-static ssize_t iscsi_stat_tgt_attr_show_attr_inst(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
-{
-       struct iscsi_tiqn *tiqn = container_of(igrps,
-                               struct iscsi_tiqn, tiqn_stat_grps);
+static struct iscsi_tiqn *iscsi_tgt_attr_tiqn(struct config_item *item)
+{
+       struct iscsi_wwn_stat_grps *igrps = container_of(to_config_group(item),
+                       struct iscsi_wwn_stat_grps, iscsi_tgt_attr_group);
+       return container_of(igrps, struct iscsi_tiqn, tiqn_stat_grps);
+}
 
-       return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_index);
+static ssize_t iscsi_stat_tgt_attr_inst_show(struct config_item *item,
+               char *page)
+{
+       return snprintf(page, PAGE_SIZE, "%u\n",
+                       iscsi_tgt_attr_tiqn(item)->tiqn_index);
 }
-ISCSI_STAT_TGT_ATTR_RO(inst);
 
-static ssize_t iscsi_stat_tgt_attr_show_attr_indx(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_tgt_attr_indx_show(struct config_item *item,
+               char *page)
 {
        return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_NODE_INDEX);
 }
-ISCSI_STAT_TGT_ATTR_RO(indx);
 
-static ssize_t iscsi_stat_tgt_attr_show_attr_login_fails(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_tgt_attr_login_fails_show(struct config_item *item,
+               char *page)
 {
-       struct iscsi_tiqn *tiqn = container_of(igrps,
-                               struct iscsi_tiqn, tiqn_stat_grps);
+       struct iscsi_tiqn *tiqn = iscsi_tgt_attr_tiqn(item);
        struct iscsi_login_stats *lstat = &tiqn->login_stats;
        u32 fail_count;
 
@@ -349,13 +292,11 @@ static ssize_t iscsi_stat_tgt_attr_show_attr_login_fails(
 
        return snprintf(page, PAGE_SIZE, "%u\n", fail_count);
 }
-ISCSI_STAT_TGT_ATTR_RO(login_fails);
 
-static ssize_t iscsi_stat_tgt_attr_show_attr_last_fail_time(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_tgt_attr_last_fail_time_show(struct config_item *item,
+               char *page)
 {
-       struct iscsi_tiqn *tiqn = container_of(igrps,
-                               struct iscsi_tiqn, tiqn_stat_grps);
+       struct iscsi_tiqn *tiqn = iscsi_tgt_attr_tiqn(item);
        struct iscsi_login_stats *lstat = &tiqn->login_stats;
        u32 last_fail_time;
 
@@ -367,13 +308,11 @@ static ssize_t iscsi_stat_tgt_attr_show_attr_last_fail_time(
 
        return snprintf(page, PAGE_SIZE, "%u\n", last_fail_time);
 }
-ISCSI_STAT_TGT_ATTR_RO(last_fail_time);
 
-static ssize_t iscsi_stat_tgt_attr_show_attr_last_fail_type(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_tgt_attr_last_fail_type_show(struct config_item *item,
+               char *page)
 {
-       struct iscsi_tiqn *tiqn = container_of(igrps,
-                               struct iscsi_tiqn, tiqn_stat_grps);
+       struct iscsi_tiqn *tiqn = iscsi_tgt_attr_tiqn(item);
        struct iscsi_login_stats *lstat = &tiqn->login_stats;
        u32 last_fail_type;
 
@@ -383,13 +322,11 @@ static ssize_t iscsi_stat_tgt_attr_show_attr_last_fail_type(
 
        return snprintf(page, PAGE_SIZE, "%u\n", last_fail_type);
 }
-ISCSI_STAT_TGT_ATTR_RO(last_fail_type);
 
-static ssize_t iscsi_stat_tgt_attr_show_attr_fail_intr_name(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_tgt_attr_fail_intr_name_show(struct config_item *item,
+               char *page)
 {
-       struct iscsi_tiqn *tiqn = container_of(igrps,
-                               struct iscsi_tiqn, tiqn_stat_grps);
+       struct iscsi_tiqn *tiqn = iscsi_tgt_attr_tiqn(item);
        struct iscsi_login_stats *lstat = &tiqn->login_stats;
        unsigned char buf[224];
 
@@ -400,13 +337,11 @@ static ssize_t iscsi_stat_tgt_attr_show_attr_fail_intr_name(
 
        return snprintf(page, PAGE_SIZE, "%s\n", buf);
 }
-ISCSI_STAT_TGT_ATTR_RO(fail_intr_name);
 
-static ssize_t iscsi_stat_tgt_attr_show_attr_fail_intr_addr_type(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_tgt_attr_fail_intr_addr_type_show(struct config_item *item,
+               char *page)
 {
-       struct iscsi_tiqn *tiqn = container_of(igrps,
-                       struct iscsi_tiqn, tiqn_stat_grps);
+       struct iscsi_tiqn *tiqn = iscsi_tgt_attr_tiqn(item);
        struct iscsi_login_stats *lstat = &tiqn->login_stats;
        int ret;
 
@@ -419,13 +354,11 @@ static ssize_t iscsi_stat_tgt_attr_show_attr_fail_intr_addr_type(
 
        return ret;
 }
-ISCSI_STAT_TGT_ATTR_RO(fail_intr_addr_type);
 
-static ssize_t iscsi_stat_tgt_attr_show_attr_fail_intr_addr(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_tgt_attr_fail_intr_addr_show(struct config_item *item,
+               char *page)
 {
-       struct iscsi_tiqn *tiqn = container_of(igrps,
-                       struct iscsi_tiqn, tiqn_stat_grps);
+       struct iscsi_tiqn *tiqn = iscsi_tgt_attr_tiqn(item);
        struct iscsi_login_stats *lstat = &tiqn->login_stats;
        int ret;
 
@@ -435,30 +368,29 @@ static ssize_t iscsi_stat_tgt_attr_show_attr_fail_intr_addr(
 
        return ret;
 }
-ISCSI_STAT_TGT_ATTR_RO(fail_intr_addr);
 
-CONFIGFS_EATTR_OPS(iscsi_stat_tgt_attr, iscsi_wwn_stat_grps,
-               iscsi_tgt_attr_group);
+CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, inst);
+CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, indx);
+CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, login_fails);
+CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, last_fail_time);
+CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, last_fail_type);
+CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, fail_intr_name);
+CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, fail_intr_addr_type);
+CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, fail_intr_addr);
 
 static struct configfs_attribute *iscsi_stat_tgt_attr_attrs[] = {
-       &iscsi_stat_tgt_attr_inst.attr,
-       &iscsi_stat_tgt_attr_indx.attr,
-       &iscsi_stat_tgt_attr_login_fails.attr,
-       &iscsi_stat_tgt_attr_last_fail_time.attr,
-       &iscsi_stat_tgt_attr_last_fail_type.attr,
-       &iscsi_stat_tgt_attr_fail_intr_name.attr,
-       &iscsi_stat_tgt_attr_fail_intr_addr_type.attr,
-       &iscsi_stat_tgt_attr_fail_intr_addr.attr,
+       &iscsi_stat_tgt_attr_attr_inst,
+       &iscsi_stat_tgt_attr_attr_indx,
+       &iscsi_stat_tgt_attr_attr_login_fails,
+       &iscsi_stat_tgt_attr_attr_last_fail_time,
+       &iscsi_stat_tgt_attr_attr_last_fail_type,
+       &iscsi_stat_tgt_attr_attr_fail_intr_name,
+       &iscsi_stat_tgt_attr_attr_fail_intr_addr_type,
+       &iscsi_stat_tgt_attr_attr_fail_intr_addr,
        NULL,
 };
 
-static struct configfs_item_operations iscsi_stat_tgt_attr_item_ops = {
-       .show_attribute         = iscsi_stat_tgt_attr_attr_show,
-       .store_attribute        = iscsi_stat_tgt_attr_attr_store,
-};
-
 struct config_item_type iscsi_stat_tgt_attr_cit = {
-       .ct_item_ops            = &iscsi_stat_tgt_attr_item_ops,
        .ct_attrs               = iscsi_stat_tgt_attr_attrs,
        .ct_owner               = THIS_MODULE,
 };
@@ -466,42 +398,29 @@ struct config_item_type iscsi_stat_tgt_attr_cit = {
 /*
  * Target Login Stats Table
  */
-CONFIGFS_EATTR_STRUCT(iscsi_stat_login, iscsi_wwn_stat_grps);
-#define ISCSI_STAT_LOGIN(_name, _mode)                         \
-static struct iscsi_stat_login_attribute                       \
-                       iscsi_stat_login_##_name =              \
-       __CONFIGFS_EATTR(_name, _mode,                          \
-       iscsi_stat_login_show_attr_##_name,                     \
-       iscsi_stat_login_store_attr_##_name);
-
-#define ISCSI_STAT_LOGIN_RO(_name)                             \
-static struct iscsi_stat_login_attribute                       \
-                       iscsi_stat_login_##_name =              \
-       __CONFIGFS_EATTR_RO(_name,                              \
-       iscsi_stat_login_show_attr_##_name);
-
-static ssize_t iscsi_stat_login_show_attr_inst(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
-{
-       struct iscsi_tiqn *tiqn = container_of(igrps,
-                               struct iscsi_tiqn, tiqn_stat_grps);
+static struct iscsi_tiqn *iscsi_login_stat_tiqn(struct config_item *item)
+{
+       struct iscsi_wwn_stat_grps *igrps = container_of(to_config_group(item),
+                       struct iscsi_wwn_stat_grps, iscsi_login_stats_group);
+       return container_of(igrps, struct iscsi_tiqn, tiqn_stat_grps);
+}
 
-       return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_index);
+static ssize_t iscsi_stat_login_inst_show(struct config_item *item, char *page)
+{
+       return snprintf(page, PAGE_SIZE, "%u\n",
+               iscsi_login_stat_tiqn(item)->tiqn_index);
 }
-ISCSI_STAT_LOGIN_RO(inst);
 
-static ssize_t iscsi_stat_login_show_attr_indx(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_login_indx_show(struct config_item *item,
+               char *page)
 {
        return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_NODE_INDEX);
 }
-ISCSI_STAT_LOGIN_RO(indx);
 
-static ssize_t iscsi_stat_login_show_attr_accepts(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_login_accepts_show(struct config_item *item,
+               char *page)
 {
-       struct iscsi_tiqn *tiqn = container_of(igrps,
-                               struct iscsi_tiqn, tiqn_stat_grps);
+       struct iscsi_tiqn *tiqn = iscsi_login_stat_tiqn(item);
        struct iscsi_login_stats *lstat = &tiqn->login_stats;
        ssize_t ret;
 
@@ -511,13 +430,11 @@ static ssize_t iscsi_stat_login_show_attr_accepts(
 
        return ret;
 }
-ISCSI_STAT_LOGIN_RO(accepts);
 
-static ssize_t iscsi_stat_login_show_attr_other_fails(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_login_other_fails_show(struct config_item *item,
+               char *page)
 {
-       struct iscsi_tiqn *tiqn = container_of(igrps,
-                               struct iscsi_tiqn, tiqn_stat_grps);
+       struct iscsi_tiqn *tiqn = iscsi_login_stat_tiqn(item);
        struct iscsi_login_stats *lstat = &tiqn->login_stats;
        ssize_t ret;
 
@@ -527,13 +444,11 @@ static ssize_t iscsi_stat_login_show_attr_other_fails(
 
        return ret;
 }
-ISCSI_STAT_LOGIN_RO(other_fails);
 
-static ssize_t iscsi_stat_login_show_attr_redirects(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_login_redirects_show(struct config_item *item,
+               char *page)
 {
-       struct iscsi_tiqn *tiqn = container_of(igrps,
-                               struct iscsi_tiqn, tiqn_stat_grps);
+       struct iscsi_tiqn *tiqn = iscsi_login_stat_tiqn(item);
        struct iscsi_login_stats *lstat = &tiqn->login_stats;
        ssize_t ret;
 
@@ -543,13 +458,11 @@ static ssize_t iscsi_stat_login_show_attr_redirects(
 
        return ret;
 }
-ISCSI_STAT_LOGIN_RO(redirects);
 
-static ssize_t iscsi_stat_login_show_attr_authorize_fails(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_login_authorize_fails_show(struct config_item *item,
+               char *page)
 {
-       struct iscsi_tiqn *tiqn = container_of(igrps,
-                               struct iscsi_tiqn, tiqn_stat_grps);
+       struct iscsi_tiqn *tiqn = iscsi_login_stat_tiqn(item);
        struct iscsi_login_stats *lstat = &tiqn->login_stats;
        ssize_t ret;
 
@@ -559,13 +472,11 @@ static ssize_t iscsi_stat_login_show_attr_authorize_fails(
 
        return ret;
 }
-ISCSI_STAT_LOGIN_RO(authorize_fails);
 
-static ssize_t iscsi_stat_login_show_attr_authenticate_fails(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_login_authenticate_fails_show(
+               struct config_item *item, char *page)
 {
-       struct iscsi_tiqn *tiqn = container_of(igrps,
-                               struct iscsi_tiqn, tiqn_stat_grps);
+       struct iscsi_tiqn *tiqn = iscsi_login_stat_tiqn(item);
        struct iscsi_login_stats *lstat = &tiqn->login_stats;
        ssize_t ret;
 
@@ -575,13 +486,11 @@ static ssize_t iscsi_stat_login_show_attr_authenticate_fails(
 
        return ret;
 }
-ISCSI_STAT_LOGIN_RO(authenticate_fails);
 
-static ssize_t iscsi_stat_login_show_attr_negotiate_fails(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_login_negotiate_fails_show(struct config_item *item,
+               char *page)
 {
-       struct iscsi_tiqn *tiqn = container_of(igrps,
-                               struct iscsi_tiqn, tiqn_stat_grps);
+       struct iscsi_tiqn *tiqn = iscsi_login_stat_tiqn(item);
        struct iscsi_login_stats *lstat = &tiqn->login_stats;
        ssize_t ret;
 
@@ -591,30 +500,29 @@ static ssize_t iscsi_stat_login_show_attr_negotiate_fails(
 
        return ret;
 }
-ISCSI_STAT_LOGIN_RO(negotiate_fails);
 
-CONFIGFS_EATTR_OPS(iscsi_stat_login, iscsi_wwn_stat_grps,
-               iscsi_login_stats_group);
+CONFIGFS_ATTR_RO(iscsi_stat_login_, inst);
+CONFIGFS_ATTR_RO(iscsi_stat_login_, indx);
+CONFIGFS_ATTR_RO(iscsi_stat_login_, accepts);
+CONFIGFS_ATTR_RO(iscsi_stat_login_, other_fails);
+CONFIGFS_ATTR_RO(iscsi_stat_login_, redirects);
+CONFIGFS_ATTR_RO(iscsi_stat_login_, authorize_fails);
+CONFIGFS_ATTR_RO(iscsi_stat_login_, authenticate_fails);
+CONFIGFS_ATTR_RO(iscsi_stat_login_, negotiate_fails);
 
 static struct configfs_attribute *iscsi_stat_login_stats_attrs[] = {
-       &iscsi_stat_login_inst.attr,
-       &iscsi_stat_login_indx.attr,
-       &iscsi_stat_login_accepts.attr,
-       &iscsi_stat_login_other_fails.attr,
-       &iscsi_stat_login_redirects.attr,
-       &iscsi_stat_login_authorize_fails.attr,
-       &iscsi_stat_login_authenticate_fails.attr,
-       &iscsi_stat_login_negotiate_fails.attr,
+       &iscsi_stat_login_attr_inst,
+       &iscsi_stat_login_attr_indx,
+       &iscsi_stat_login_attr_accepts,
+       &iscsi_stat_login_attr_other_fails,
+       &iscsi_stat_login_attr_redirects,
+       &iscsi_stat_login_attr_authorize_fails,
+       &iscsi_stat_login_attr_authenticate_fails,
+       &iscsi_stat_login_attr_negotiate_fails,
        NULL,
 };
 
-static struct configfs_item_operations iscsi_stat_login_stats_item_ops = {
-       .show_attribute         = iscsi_stat_login_attr_show,
-       .store_attribute        = iscsi_stat_login_attr_store,
-};
-
 struct config_item_type iscsi_stat_login_cit = {
-       .ct_item_ops            = &iscsi_stat_login_stats_item_ops,
        .ct_attrs               = iscsi_stat_login_stats_attrs,
        .ct_owner               = THIS_MODULE,
 };
@@ -622,78 +530,56 @@ struct config_item_type iscsi_stat_login_cit = {
 /*
  * Target Logout Stats Table
  */
-
-CONFIGFS_EATTR_STRUCT(iscsi_stat_logout, iscsi_wwn_stat_grps);
-#define ISCSI_STAT_LOGOUT(_name, _mode)                                \
-static struct iscsi_stat_logout_attribute                      \
-                       iscsi_stat_logout_##_name =             \
-       __CONFIGFS_EATTR(_name, _mode,                          \
-       iscsi_stat_logout_show_attr_##_name,                    \
-       iscsi_stat_logout_store_attr_##_name);
-
-#define ISCSI_STAT_LOGOUT_RO(_name)                            \
-static struct iscsi_stat_logout_attribute                      \
-                       iscsi_stat_logout_##_name =             \
-       __CONFIGFS_EATTR_RO(_name,                              \
-       iscsi_stat_logout_show_attr_##_name);
-
-static ssize_t iscsi_stat_logout_show_attr_inst(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static struct iscsi_tiqn *iscsi_logout_stat_tiqn(struct config_item *item)
 {
-       struct iscsi_tiqn *tiqn = container_of(igrps,
-                       struct iscsi_tiqn, tiqn_stat_grps);
+       struct iscsi_wwn_stat_grps *igrps = container_of(to_config_group(item),
+                       struct iscsi_wwn_stat_grps, iscsi_logout_stats_group);
+       return container_of(igrps, struct iscsi_tiqn, tiqn_stat_grps);
+}
 
-       return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_index);
+static ssize_t iscsi_stat_logout_inst_show(struct config_item *item, char *page)
+{
+       return snprintf(page, PAGE_SIZE, "%u\n",
+               iscsi_logout_stat_tiqn(item)->tiqn_index);
 }
-ISCSI_STAT_LOGOUT_RO(inst);
 
-static ssize_t iscsi_stat_logout_show_attr_indx(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_logout_indx_show(struct config_item *item, char *page)
 {
        return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_NODE_INDEX);
 }
-ISCSI_STAT_LOGOUT_RO(indx);
 
-static ssize_t iscsi_stat_logout_show_attr_normal_logouts(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_logout_normal_logouts_show(struct config_item *item,
+               char *page)
 {
-       struct iscsi_tiqn *tiqn = container_of(igrps,
-                       struct iscsi_tiqn, tiqn_stat_grps);
+       struct iscsi_tiqn *tiqn = iscsi_logout_stat_tiqn(item);
        struct iscsi_logout_stats *lstats = &tiqn->logout_stats;
 
        return snprintf(page, PAGE_SIZE, "%u\n", lstats->normal_logouts);
 }
-ISCSI_STAT_LOGOUT_RO(normal_logouts);
 
-static ssize_t iscsi_stat_logout_show_attr_abnormal_logouts(
-       struct iscsi_wwn_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_logout_abnormal_logouts_show(struct config_item *item,
+               char *page)
 {
-       struct iscsi_tiqn *tiqn = container_of(igrps,
-                       struct iscsi_tiqn, tiqn_stat_grps);
+       struct iscsi_tiqn *tiqn = iscsi_logout_stat_tiqn(item);
        struct iscsi_logout_stats *lstats = &tiqn->logout_stats;
 
        return snprintf(page, PAGE_SIZE, "%u\n", lstats->abnormal_logouts);
 }
-ISCSI_STAT_LOGOUT_RO(abnormal_logouts);
 
-CONFIGFS_EATTR_OPS(iscsi_stat_logout, iscsi_wwn_stat_grps,
-               iscsi_logout_stats_group);
+CONFIGFS_ATTR_RO(iscsi_stat_logout_, inst);
+CONFIGFS_ATTR_RO(iscsi_stat_logout_, indx);
+CONFIGFS_ATTR_RO(iscsi_stat_logout_, normal_logouts);
+CONFIGFS_ATTR_RO(iscsi_stat_logout_, abnormal_logouts);
 
 static struct configfs_attribute *iscsi_stat_logout_stats_attrs[] = {
-       &iscsi_stat_logout_inst.attr,
-       &iscsi_stat_logout_indx.attr,
-       &iscsi_stat_logout_normal_logouts.attr,
-       &iscsi_stat_logout_abnormal_logouts.attr,
+       &iscsi_stat_logout_attr_inst,
+       &iscsi_stat_logout_attr_indx,
+       &iscsi_stat_logout_attr_normal_logouts,
+       &iscsi_stat_logout_attr_abnormal_logouts,
        NULL,
 };
 
-static struct configfs_item_operations iscsi_stat_logout_stats_item_ops = {
-       .show_attribute         = iscsi_stat_logout_attr_show,
-       .store_attribute        = iscsi_stat_logout_attr_store,
-};
-
 struct config_item_type iscsi_stat_logout_cit = {
-       .ct_item_ops            = &iscsi_stat_logout_stats_item_ops,
        .ct_attrs               = iscsi_stat_logout_stats_attrs,
        .ct_owner               = THIS_MODULE,
 };
@@ -701,39 +587,26 @@ struct config_item_type iscsi_stat_logout_cit = {
 /*
  * Session Stats Table
  */
+static struct iscsi_node_acl *iscsi_stat_nacl(struct config_item *item)
+{
+       struct iscsi_node_stat_grps *igrps = container_of(to_config_group(item),
+                       struct iscsi_node_stat_grps, iscsi_sess_stats_group);
+       return container_of(igrps, struct iscsi_node_acl, node_stat_grps);
+}
 
-CONFIGFS_EATTR_STRUCT(iscsi_stat_sess, iscsi_node_stat_grps);
-#define ISCSI_STAT_SESS(_name, _mode)                          \
-static struct iscsi_stat_sess_attribute                                \
-                       iscsi_stat_sess_##_name =               \
-       __CONFIGFS_EATTR(_name, _mode,                          \
-       iscsi_stat_sess_show_attr_##_name,                      \
-       iscsi_stat_sess_store_attr_##_name);
-
-#define ISCSI_STAT_SESS_RO(_name)                              \
-static struct iscsi_stat_sess_attribute                                \
-                       iscsi_stat_sess_##_name =               \
-       __CONFIGFS_EATTR_RO(_name,                              \
-       iscsi_stat_sess_show_attr_##_name);
-
-static ssize_t iscsi_stat_sess_show_attr_inst(
-       struct iscsi_node_stat_grps *igrps, char *page)
-{
-       struct iscsi_node_acl *acl = container_of(igrps,
-                       struct iscsi_node_acl, node_stat_grps);
+static ssize_t iscsi_stat_sess_inst_show(struct config_item *item, char *page)
+{
+       struct iscsi_node_acl *acl = iscsi_stat_nacl(item);
        struct se_wwn *wwn = acl->se_node_acl.se_tpg->se_tpg_wwn;
        struct iscsi_tiqn *tiqn = container_of(wwn,
                        struct iscsi_tiqn, tiqn_wwn);
 
        return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_index);
 }
-ISCSI_STAT_SESS_RO(inst);
 
-static ssize_t iscsi_stat_sess_show_attr_node(
-       struct iscsi_node_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_sess_node_show(struct config_item *item, char *page)
 {
-       struct iscsi_node_acl *acl = container_of(igrps,
-                       struct iscsi_node_acl, node_stat_grps);
+       struct iscsi_node_acl *acl = iscsi_stat_nacl(item);
        struct se_node_acl *se_nacl = &acl->se_node_acl;
        struct iscsi_session *sess;
        struct se_session *se_sess;
@@ -751,13 +624,10 @@ static ssize_t iscsi_stat_sess_show_attr_node(
 
        return ret;
 }
-ISCSI_STAT_SESS_RO(node);
 
-static ssize_t iscsi_stat_sess_show_attr_indx(
-       struct iscsi_node_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_sess_indx_show(struct config_item *item, char *page)
 {
-       struct iscsi_node_acl *acl = container_of(igrps,
-                       struct iscsi_node_acl, node_stat_grps);
+       struct iscsi_node_acl *acl = iscsi_stat_nacl(item);
        struct se_node_acl *se_nacl = &acl->se_node_acl;
        struct iscsi_session *sess;
        struct se_session *se_sess;
@@ -775,13 +645,11 @@ static ssize_t iscsi_stat_sess_show_attr_indx(
 
        return ret;
 }
-ISCSI_STAT_SESS_RO(indx);
 
-static ssize_t iscsi_stat_sess_show_attr_cmd_pdus(
-       struct iscsi_node_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_sess_cmd_pdus_show(struct config_item *item,
+               char *page)
 {
-       struct iscsi_node_acl *acl = container_of(igrps,
-                       struct iscsi_node_acl, node_stat_grps);
+       struct iscsi_node_acl *acl = iscsi_stat_nacl(item);
        struct se_node_acl *se_nacl = &acl->se_node_acl;
        struct iscsi_session *sess;
        struct se_session *se_sess;
@@ -799,13 +667,11 @@ static ssize_t iscsi_stat_sess_show_attr_cmd_pdus(
 
        return ret;
 }
-ISCSI_STAT_SESS_RO(cmd_pdus);
 
-static ssize_t iscsi_stat_sess_show_attr_rsp_pdus(
-       struct iscsi_node_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_sess_rsp_pdus_show(struct config_item *item,
+               char *page)
 {
-       struct iscsi_node_acl *acl = container_of(igrps,
-                       struct iscsi_node_acl, node_stat_grps);
+       struct iscsi_node_acl *acl = iscsi_stat_nacl(item);
        struct se_node_acl *se_nacl = &acl->se_node_acl;
        struct iscsi_session *sess;
        struct se_session *se_sess;
@@ -823,13 +689,11 @@ static ssize_t iscsi_stat_sess_show_attr_rsp_pdus(
 
        return ret;
 }
-ISCSI_STAT_SESS_RO(rsp_pdus);
 
-static ssize_t iscsi_stat_sess_show_attr_txdata_octs(
-       struct iscsi_node_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_sess_txdata_octs_show(struct config_item *item,
+               char *page)
 {
-       struct iscsi_node_acl *acl = container_of(igrps,
-                       struct iscsi_node_acl, node_stat_grps);
+       struct iscsi_node_acl *acl = iscsi_stat_nacl(item);
        struct se_node_acl *se_nacl = &acl->se_node_acl;
        struct iscsi_session *sess;
        struct se_session *se_sess;
@@ -847,13 +711,11 @@ static ssize_t iscsi_stat_sess_show_attr_txdata_octs(
 
        return ret;
 }
-ISCSI_STAT_SESS_RO(txdata_octs);
 
-static ssize_t iscsi_stat_sess_show_attr_rxdata_octs(
-       struct iscsi_node_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_sess_rxdata_octs_show(struct config_item *item,
+               char *page)
 {
-       struct iscsi_node_acl *acl = container_of(igrps,
-                       struct iscsi_node_acl, node_stat_grps);
+       struct iscsi_node_acl *acl = iscsi_stat_nacl(item);
        struct se_node_acl *se_nacl = &acl->se_node_acl;
        struct iscsi_session *sess;
        struct se_session *se_sess;
@@ -871,13 +733,11 @@ static ssize_t iscsi_stat_sess_show_attr_rxdata_octs(
 
        return ret;
 }
-ISCSI_STAT_SESS_RO(rxdata_octs);
 
-static ssize_t iscsi_stat_sess_show_attr_conn_digest_errors(
-       struct iscsi_node_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_sess_conn_digest_errors_show(struct config_item *item,
+               char *page)
 {
-       struct iscsi_node_acl *acl = container_of(igrps,
-                       struct iscsi_node_acl, node_stat_grps);
+       struct iscsi_node_acl *acl = iscsi_stat_nacl(item);
        struct se_node_acl *se_nacl = &acl->se_node_acl;
        struct iscsi_session *sess;
        struct se_session *se_sess;
@@ -895,13 +755,11 @@ static ssize_t iscsi_stat_sess_show_attr_conn_digest_errors(
 
        return ret;
 }
-ISCSI_STAT_SESS_RO(conn_digest_errors);
 
-static ssize_t iscsi_stat_sess_show_attr_conn_timeout_errors(
-       struct iscsi_node_stat_grps *igrps, char *page)
+static ssize_t iscsi_stat_sess_conn_timeout_errors_show(
+               struct config_item *item, char *page)
 {
-       struct iscsi_node_acl *acl = container_of(igrps,
-                       struct iscsi_node_acl, node_stat_grps);
+       struct iscsi_node_acl *acl = iscsi_stat_nacl(item);
        struct se_node_acl *se_nacl = &acl->se_node_acl;
        struct iscsi_session *sess;
        struct se_session *se_sess;
@@ -919,31 +777,31 @@ static ssize_t iscsi_stat_sess_show_attr_conn_timeout_errors(
 
        return ret;
 }
-ISCSI_STAT_SESS_RO(conn_timeout_errors);
 
-CONFIGFS_EATTR_OPS(iscsi_stat_sess, iscsi_node_stat_grps,
-               iscsi_sess_stats_group);
+CONFIGFS_ATTR_RO(iscsi_stat_sess_, inst);
+CONFIGFS_ATTR_RO(iscsi_stat_sess_, node);
+CONFIGFS_ATTR_RO(iscsi_stat_sess_, indx);
+CONFIGFS_ATTR_RO(iscsi_stat_sess_, cmd_pdus);
+CONFIGFS_ATTR_RO(iscsi_stat_sess_, rsp_pdus);
+CONFIGFS_ATTR_RO(iscsi_stat_sess_, txdata_octs);
+CONFIGFS_ATTR_RO(iscsi_stat_sess_, rxdata_octs);
+CONFIGFS_ATTR_RO(iscsi_stat_sess_, conn_digest_errors);
+CONFIGFS_ATTR_RO(iscsi_stat_sess_, conn_timeout_errors);
 
 static struct configfs_attribute *iscsi_stat_sess_stats_attrs[] = {
-       &iscsi_stat_sess_inst.attr,
-       &iscsi_stat_sess_node.attr,
-       &iscsi_stat_sess_indx.attr,
-       &iscsi_stat_sess_cmd_pdus.attr,
-       &iscsi_stat_sess_rsp_pdus.attr,
-       &iscsi_stat_sess_txdata_octs.attr,
-       &iscsi_stat_sess_rxdata_octs.attr,
-       &iscsi_stat_sess_conn_digest_errors.attr,
-       &iscsi_stat_sess_conn_timeout_errors.attr,
+       &iscsi_stat_sess_attr_inst,
+       &iscsi_stat_sess_attr_node,
+       &iscsi_stat_sess_attr_indx,
+       &iscsi_stat_sess_attr_cmd_pdus,
+       &iscsi_stat_sess_attr_rsp_pdus,
+       &iscsi_stat_sess_attr_txdata_octs,
+       &iscsi_stat_sess_attr_rxdata_octs,
+       &iscsi_stat_sess_attr_conn_digest_errors,
+       &iscsi_stat_sess_attr_conn_timeout_errors,
        NULL,
 };
 
-static struct configfs_item_operations iscsi_stat_sess_stats_item_ops = {
-       .show_attribute         = iscsi_stat_sess_attr_show,
-       .store_attribute        = iscsi_stat_sess_attr_store,
-};
-
 struct config_item_type iscsi_stat_sess_cit = {
-       .ct_item_ops            = &iscsi_stat_sess_stats_item_ops,
        .ct_attrs               = iscsi_stat_sess_stats_attrs,
        .ct_owner               = THIS_MODULE,
 };
index 5bc85ffed7204f21871a31d7346b93885b437cf8..4fb0eca86857e2f3229603397138d4c793b57eff 100644 (file)
@@ -34,7 +34,6 @@
 
 #include <target/target_core_base.h>
 #include <target/target_core_fabric.h>
-#include <target/target_core_fabric_configfs.h>
 
 #include "tcm_loop.h"
 
@@ -377,7 +376,6 @@ static struct scsi_host_template tcm_loop_driver_template = {
        .use_clustering         = DISABLE_CLUSTERING,
        .slave_alloc            = tcm_loop_slave_alloc,
        .module                 = THIS_MODULE,
-       .use_blk_tags           = 1,
        .track_queue_depth      = 1,
 };
 
@@ -763,21 +761,20 @@ static void tcm_loop_port_unlink(
 
 /* End items for tcm_loop_port_cit */
 
-static ssize_t tcm_loop_tpg_attrib_show_fabric_prot_type(
-       struct se_portal_group *se_tpg,
-       char *page)
+static ssize_t tcm_loop_tpg_attrib_fabric_prot_type_show(
+               struct config_item *item, char *page)
 {
+       struct se_portal_group *se_tpg = attrib_to_tpg(item);
        struct tcm_loop_tpg *tl_tpg = container_of(se_tpg, struct tcm_loop_tpg,
                                                   tl_se_tpg);
 
        return sprintf(page, "%d\n", tl_tpg->tl_fabric_prot_type);
 }
 
-static ssize_t tcm_loop_tpg_attrib_store_fabric_prot_type(
-       struct se_portal_group *se_tpg,
-       const char *page,
-       size_t count)
+static ssize_t tcm_loop_tpg_attrib_fabric_prot_type_store(
+               struct config_item *item, const char *page, size_t count)
 {
+       struct se_portal_group *se_tpg = attrib_to_tpg(item);
        struct tcm_loop_tpg *tl_tpg = container_of(se_tpg, struct tcm_loop_tpg,
                                                   tl_se_tpg);
        unsigned long val;
@@ -796,10 +793,10 @@ static ssize_t tcm_loop_tpg_attrib_store_fabric_prot_type(
        return count;
 }
 
-TF_TPG_ATTRIB_ATTR(tcm_loop, fabric_prot_type, S_IRUGO | S_IWUSR);
+CONFIGFS_ATTR(tcm_loop_tpg_attrib_, fabric_prot_type);
 
 static struct configfs_attribute *tcm_loop_tpg_attrib_attrs[] = {
-       &tcm_loop_tpg_attrib_fabric_prot_type.attr,
+       &tcm_loop_tpg_attrib_attr_fabric_prot_type,
        NULL,
 };
 
@@ -894,10 +891,9 @@ static int tcm_loop_drop_nexus(
 
 /* End items for tcm_loop_nexus_cit */
 
-static ssize_t tcm_loop_tpg_show_nexus(
-       struct se_portal_group *se_tpg,
-       char *page)
+static ssize_t tcm_loop_tpg_nexus_show(struct config_item *item, char *page)
 {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
                        struct tcm_loop_tpg, tl_se_tpg);
        struct tcm_loop_nexus *tl_nexus;
@@ -913,11 +909,10 @@ static ssize_t tcm_loop_tpg_show_nexus(
        return ret;
 }
 
-static ssize_t tcm_loop_tpg_store_nexus(
-       struct se_portal_group *se_tpg,
-       const char *page,
-       size_t count)
+static ssize_t tcm_loop_tpg_nexus_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
                        struct tcm_loop_tpg, tl_se_tpg);
        struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
@@ -992,12 +987,10 @@ check_newline:
        return count;
 }
 
-TF_TPG_BASE_ATTR(tcm_loop, nexus, S_IRUGO | S_IWUSR);
-
-static ssize_t tcm_loop_tpg_show_transport_status(
-       struct se_portal_group *se_tpg,
-       char *page)
+static ssize_t tcm_loop_tpg_transport_status_show(struct config_item *item,
+               char *page)
 {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
                        struct tcm_loop_tpg, tl_se_tpg);
        const char *status = NULL;
@@ -1020,11 +1013,10 @@ static ssize_t tcm_loop_tpg_show_transport_status(
        return ret;
 }
 
-static ssize_t tcm_loop_tpg_store_transport_status(
-       struct se_portal_group *se_tpg,
-       const char *page,
-       size_t count)
+static ssize_t tcm_loop_tpg_transport_status_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
                        struct tcm_loop_tpg, tl_se_tpg);
 
@@ -1044,11 +1036,12 @@ static ssize_t tcm_loop_tpg_store_transport_status(
        return -EINVAL;
 }
 
-TF_TPG_BASE_ATTR(tcm_loop, transport_status, S_IRUGO | S_IWUSR);
+CONFIGFS_ATTR(tcm_loop_tpg_, nexus);
+CONFIGFS_ATTR(tcm_loop_tpg_, transport_status);
 
 static struct configfs_attribute *tcm_loop_tpg_attrs[] = {
-       &tcm_loop_tpg_nexus.attr,
-       &tcm_loop_tpg_transport_status.attr,
+       &tcm_loop_tpg_attr_nexus,
+       &tcm_loop_tpg_attr_transport_status,
        NULL,
 };
 
@@ -1216,17 +1209,15 @@ static void tcm_loop_drop_scsi_hba(
 }
 
 /* Start items for tcm_loop_cit */
-static ssize_t tcm_loop_wwn_show_attr_version(
-       struct target_fabric_configfs *tf,
-       char *page)
+static ssize_t tcm_loop_wwn_version_show(struct config_item *item, char *page)
 {
        return sprintf(page, "TCM Loopback Fabric module %s\n", TCM_LOOP_VERSION);
 }
 
-TF_WWN_ATTR_RO(tcm_loop, version);
+CONFIGFS_ATTR_RO(tcm_loop_wwn_, version);
 
 static struct configfs_attribute *tcm_loop_wwn_attrs[] = {
-       &tcm_loop_wwn_version.attr,
+       &tcm_loop_wwn_attr_version,
        NULL,
 };
 
index 0edf320fb68547a4f4c6d0b8d46687727d47c557..35f7d31b29d2eb05c13985e4ab45df0df41669e6 100644 (file)
@@ -35,8 +35,6 @@
 #include <target/target_core_base.h>
 #include <target/target_core_backend.h>
 #include <target/target_core_fabric.h>
-#include <target/target_core_fabric_configfs.h>
-#include <target/configfs_macros.h>
 #include <asm/unaligned.h>
 
 #include "sbp_target.h"
@@ -2111,24 +2109,21 @@ static void sbp_drop_tport(struct se_wwn *wwn)
        kfree(tport);
 }
 
-static ssize_t sbp_wwn_show_attr_version(
-               struct target_fabric_configfs *tf,
-               char *page)
+static ssize_t sbp_wwn_version_show(struct config_item *item, char *page)
 {
        return sprintf(page, "FireWire SBP fabric module %s\n", SBP_VERSION);
 }
 
-TF_WWN_ATTR_RO(sbp, version);
+CONFIGFS_ATTR_RO(sbp_wwn_, version);
 
 static struct configfs_attribute *sbp_wwn_attrs[] = {
-       &sbp_wwn_version.attr,
+       &sbp_wwn_attr_version,
        NULL,
 };
 
-static ssize_t sbp_tpg_show_directory_id(
-               struct se_portal_group *se_tpg,
-               char *page)
+static ssize_t sbp_tpg_directory_id_show(struct config_item *item, char *page)
 {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);
        struct sbp_tport *tport = tpg->tport;
 
@@ -2138,11 +2133,10 @@ static ssize_t sbp_tpg_show_directory_id(
                return sprintf(page, "%06x\n", tport->directory_id);
 }
 
-static ssize_t sbp_tpg_store_directory_id(
-               struct se_portal_group *se_tpg,
-               const char *page,
-               size_t count)
+static ssize_t sbp_tpg_directory_id_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);
        struct sbp_tport *tport = tpg->tport;
        unsigned long val;
@@ -2166,20 +2160,18 @@ static ssize_t sbp_tpg_store_directory_id(
        return count;
 }
 
-static ssize_t sbp_tpg_show_enable(
-               struct se_portal_group *se_tpg,
-               char *page)
+static ssize_t sbp_tpg_enable_show(struct config_item *item, char *page)
 {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);
        struct sbp_tport *tport = tpg->tport;
        return sprintf(page, "%d\n", tport->enable);
 }
 
-static ssize_t sbp_tpg_store_enable(
-               struct se_portal_group *se_tpg,
-               const char *page,
-               size_t count)
+static ssize_t sbp_tpg_enable_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);
        struct sbp_tport *tport = tpg->tport;
        unsigned long val;
@@ -2219,29 +2211,28 @@ static ssize_t sbp_tpg_store_enable(
        return count;
 }
 
-TF_TPG_BASE_ATTR(sbp, directory_id, S_IRUGO | S_IWUSR);
-TF_TPG_BASE_ATTR(sbp, enable, S_IRUGO | S_IWUSR);
+CONFIGFS_ATTR(sbp_tpg_, directory_id);
+CONFIGFS_ATTR(sbp_tpg_, enable);
 
 static struct configfs_attribute *sbp_tpg_base_attrs[] = {
-       &sbp_tpg_directory_id.attr,
-       &sbp_tpg_enable.attr,
+       &sbp_tpg_attr_directory_id,
+       &sbp_tpg_attr_enable,
        NULL,
 };
 
-static ssize_t sbp_tpg_attrib_show_mgt_orb_timeout(
-               struct se_portal_group *se_tpg,
+static ssize_t sbp_tpg_attrib_mgt_orb_timeout_show(struct config_item *item,
                char *page)
 {
+       struct se_portal_group *se_tpg = attrib_to_tpg(item);
        struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);
        struct sbp_tport *tport = tpg->tport;
        return sprintf(page, "%d\n", tport->mgt_orb_timeout);
 }
 
-static ssize_t sbp_tpg_attrib_store_mgt_orb_timeout(
-               struct se_portal_group *se_tpg,
-               const char *page,
-               size_t count)
+static ssize_t sbp_tpg_attrib_mgt_orb_timeout_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct se_portal_group *se_tpg = attrib_to_tpg(item);
        struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);
        struct sbp_tport *tport = tpg->tport;
        unsigned long val;
@@ -2264,20 +2255,19 @@ static ssize_t sbp_tpg_attrib_store_mgt_orb_timeout(
        return count;
 }
 
-static ssize_t sbp_tpg_attrib_show_max_reconnect_timeout(
-               struct se_portal_group *se_tpg,
+static ssize_t sbp_tpg_attrib_max_reconnect_timeout_show(struct config_item *item,
                char *page)
 {
+       struct se_portal_group *se_tpg = attrib_to_tpg(item);
        struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);
        struct sbp_tport *tport = tpg->tport;
        return sprintf(page, "%d\n", tport->max_reconnect_timeout);
 }
 
-static ssize_t sbp_tpg_attrib_store_max_reconnect_timeout(
-               struct se_portal_group *se_tpg,
-               const char *page,
-               size_t count)
+static ssize_t sbp_tpg_attrib_max_reconnect_timeout_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct se_portal_group *se_tpg = attrib_to_tpg(item);
        struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);
        struct sbp_tport *tport = tpg->tport;
        unsigned long val;
@@ -2300,20 +2290,19 @@ static ssize_t sbp_tpg_attrib_store_max_reconnect_timeout(
        return count;
 }
 
-static ssize_t sbp_tpg_attrib_show_max_logins_per_lun(
-               struct se_portal_group *se_tpg,
+static ssize_t sbp_tpg_attrib_max_logins_per_lun_show(struct config_item *item,
                char *page)
 {
+       struct se_portal_group *se_tpg = attrib_to_tpg(item);
        struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);
        struct sbp_tport *tport = tpg->tport;
        return sprintf(page, "%d\n", tport->max_logins_per_lun);
 }
 
-static ssize_t sbp_tpg_attrib_store_max_logins_per_lun(
-               struct se_portal_group *se_tpg,
-               const char *page,
-               size_t count)
+static ssize_t sbp_tpg_attrib_max_logins_per_lun_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct se_portal_group *se_tpg = attrib_to_tpg(item);
        struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);
        struct sbp_tport *tport = tpg->tport;
        unsigned long val;
@@ -2330,14 +2319,14 @@ static ssize_t sbp_tpg_attrib_store_max_logins_per_lun(
        return count;
 }
 
-TF_TPG_ATTRIB_ATTR(sbp, mgt_orb_timeout, S_IRUGO | S_IWUSR);
-TF_TPG_ATTRIB_ATTR(sbp, max_reconnect_timeout, S_IRUGO | S_IWUSR);
-TF_TPG_ATTRIB_ATTR(sbp, max_logins_per_lun, S_IRUGO | S_IWUSR);
+CONFIGFS_ATTR(sbp_tpg_attrib_, mgt_orb_timeout);
+CONFIGFS_ATTR(sbp_tpg_attrib_, max_reconnect_timeout);
+CONFIGFS_ATTR(sbp_tpg_attrib_, max_logins_per_lun);
 
 static struct configfs_attribute *sbp_tpg_attrib_attrs[] = {
-       &sbp_tpg_attrib_mgt_orb_timeout.attr,
-       &sbp_tpg_attrib_max_reconnect_timeout.attr,
-       &sbp_tpg_attrib_max_logins_per_lun.attr,
+       &sbp_tpg_attrib_attr_mgt_orb_timeout,
+       &sbp_tpg_attrib_attr_max_reconnect_timeout,
+       &sbp_tpg_attrib_attr_max_logins_per_lun,
        NULL,
 };
 
index 860e840461778271191ba4ee8f1a4011dba5e78c..b9b9ffde4c7a870e32a623ad5aacbf289c07ebef 100644 (file)
@@ -40,8 +40,6 @@
 #include <target/target_core_base.h>
 #include <target/target_core_backend.h>
 #include <target/target_core_fabric.h>
-#include <target/target_core_fabric_configfs.h>
-#include <target/configfs_macros.h>
 
 #include "target_core_internal.h"
 #include "target_core_alua.h"
@@ -78,12 +76,6 @@ extern struct t10_alua_lu_gp *default_lu_gp;
 static LIST_HEAD(g_tf_list);
 static DEFINE_MUTEX(g_tf_lock);
 
-struct target_core_configfs_attribute {
-       struct configfs_attribute attr;
-       ssize_t (*show)(void *, char *);
-       ssize_t (*store)(void *, const char *, size_t);
-};
-
 static struct config_group target_core_hbagroup;
 static struct config_group alua_group;
 static struct config_group alua_lu_gps_group;
@@ -97,24 +89,15 @@ item_to_hba(struct config_item *item)
 /*
  * Attributes for /sys/kernel/config/target/
  */
-static ssize_t target_core_attr_show(struct config_item *item,
-                                     struct configfs_attribute *attr,
-                                     char *page)
+static ssize_t target_core_item_version_show(struct config_item *item,
+               char *page)
 {
        return sprintf(page, "Target Engine Core ConfigFS Infrastructure %s"
                " on %s/%s on "UTS_RELEASE"\n", TARGET_CORE_VERSION,
                utsname()->sysname, utsname()->machine);
 }
 
-static struct configfs_item_operations target_core_fabric_item_ops = {
-       .show_attribute = target_core_attr_show,
-};
-
-static struct configfs_attribute target_core_item_attr_version = {
-       .ca_owner       = THIS_MODULE,
-       .ca_name        = "version",
-       .ca_mode        = S_IRUGO,
-};
+CONFIGFS_ATTR_RO(target_core_item_, version);
 
 static struct target_fabric_configfs *target_core_get_fabric(
        const char *name)
@@ -273,7 +256,6 @@ static struct configfs_attribute *target_core_fabric_item_attrs[] = {
  * Provides Fabrics Groups and Item Attributes for /sys/kernel/config/target/
  */
 static struct config_item_type target_core_fabrics_item = {
-       .ct_item_ops    = &target_core_fabric_item_ops,
        .ct_group_ops   = &target_core_fabric_group_ops,
        .ct_attrs       = target_core_fabric_item_attrs,
        .ct_owner       = THIS_MODULE,
@@ -476,47 +458,54 @@ EXPORT_SYMBOL(target_unregister_template);
 // Stop functions called by external Target Fabrics Modules
 //############################################################################*/
 
+static inline struct se_dev_attrib *to_attrib(struct config_item *item)
+{
+       return container_of(to_config_group(item), struct se_dev_attrib,
+                       da_group);
+}
+
 /* Start functions for struct config_item_type tb_dev_attrib_cit */
-#define DEF_TB_DEV_ATTRIB_SHOW(_name)                                  \
-static ssize_t show_##_name(struct se_dev_attrib *da, char *page)      \
+#define DEF_CONFIGFS_ATTRIB_SHOW(_name)                                        \
+static ssize_t _name##_show(struct config_item *item, char *page)      \
 {                                                                      \
-       return snprintf(page, PAGE_SIZE, "%u\n", da->_name);            \
-}
-
-DEF_TB_DEV_ATTRIB_SHOW(emulate_model_alias);
-DEF_TB_DEV_ATTRIB_SHOW(emulate_dpo);
-DEF_TB_DEV_ATTRIB_SHOW(emulate_fua_write);
-DEF_TB_DEV_ATTRIB_SHOW(emulate_fua_read);
-DEF_TB_DEV_ATTRIB_SHOW(emulate_write_cache);
-DEF_TB_DEV_ATTRIB_SHOW(emulate_ua_intlck_ctrl);
-DEF_TB_DEV_ATTRIB_SHOW(emulate_tas);
-DEF_TB_DEV_ATTRIB_SHOW(emulate_tpu);
-DEF_TB_DEV_ATTRIB_SHOW(emulate_tpws);
-DEF_TB_DEV_ATTRIB_SHOW(emulate_caw);
-DEF_TB_DEV_ATTRIB_SHOW(emulate_3pc);
-DEF_TB_DEV_ATTRIB_SHOW(pi_prot_type);
-DEF_TB_DEV_ATTRIB_SHOW(hw_pi_prot_type);
-DEF_TB_DEV_ATTRIB_SHOW(pi_prot_format);
-DEF_TB_DEV_ATTRIB_SHOW(enforce_pr_isids);
-DEF_TB_DEV_ATTRIB_SHOW(is_nonrot);
-DEF_TB_DEV_ATTRIB_SHOW(emulate_rest_reord);
-DEF_TB_DEV_ATTRIB_SHOW(force_pr_aptpl);
-DEF_TB_DEV_ATTRIB_SHOW(hw_block_size);
-DEF_TB_DEV_ATTRIB_SHOW(block_size);
-DEF_TB_DEV_ATTRIB_SHOW(hw_max_sectors);
-DEF_TB_DEV_ATTRIB_SHOW(optimal_sectors);
-DEF_TB_DEV_ATTRIB_SHOW(hw_queue_depth);
-DEF_TB_DEV_ATTRIB_SHOW(queue_depth);
-DEF_TB_DEV_ATTRIB_SHOW(max_unmap_lba_count);
-DEF_TB_DEV_ATTRIB_SHOW(max_unmap_block_desc_count);
-DEF_TB_DEV_ATTRIB_SHOW(unmap_granularity);
-DEF_TB_DEV_ATTRIB_SHOW(unmap_granularity_alignment);
-DEF_TB_DEV_ATTRIB_SHOW(max_write_same_len);
-
-#define DEF_TB_DEV_ATTRIB_STORE_U32(_name)                             \
-static ssize_t store_##_name(struct se_dev_attrib *da, const char *page,\
+       return snprintf(page, PAGE_SIZE, "%u\n", to_attrib(item)->_name); \
+}
+
+DEF_CONFIGFS_ATTRIB_SHOW(emulate_model_alias);
+DEF_CONFIGFS_ATTRIB_SHOW(emulate_dpo);
+DEF_CONFIGFS_ATTRIB_SHOW(emulate_fua_write);
+DEF_CONFIGFS_ATTRIB_SHOW(emulate_fua_read);
+DEF_CONFIGFS_ATTRIB_SHOW(emulate_write_cache);
+DEF_CONFIGFS_ATTRIB_SHOW(emulate_ua_intlck_ctrl);
+DEF_CONFIGFS_ATTRIB_SHOW(emulate_tas);
+DEF_CONFIGFS_ATTRIB_SHOW(emulate_tpu);
+DEF_CONFIGFS_ATTRIB_SHOW(emulate_tpws);
+DEF_CONFIGFS_ATTRIB_SHOW(emulate_caw);
+DEF_CONFIGFS_ATTRIB_SHOW(emulate_3pc);
+DEF_CONFIGFS_ATTRIB_SHOW(pi_prot_type);
+DEF_CONFIGFS_ATTRIB_SHOW(hw_pi_prot_type);
+DEF_CONFIGFS_ATTRIB_SHOW(pi_prot_format);
+DEF_CONFIGFS_ATTRIB_SHOW(enforce_pr_isids);
+DEF_CONFIGFS_ATTRIB_SHOW(is_nonrot);
+DEF_CONFIGFS_ATTRIB_SHOW(emulate_rest_reord);
+DEF_CONFIGFS_ATTRIB_SHOW(force_pr_aptpl);
+DEF_CONFIGFS_ATTRIB_SHOW(hw_block_size);
+DEF_CONFIGFS_ATTRIB_SHOW(block_size);
+DEF_CONFIGFS_ATTRIB_SHOW(hw_max_sectors);
+DEF_CONFIGFS_ATTRIB_SHOW(optimal_sectors);
+DEF_CONFIGFS_ATTRIB_SHOW(hw_queue_depth);
+DEF_CONFIGFS_ATTRIB_SHOW(queue_depth);
+DEF_CONFIGFS_ATTRIB_SHOW(max_unmap_lba_count);
+DEF_CONFIGFS_ATTRIB_SHOW(max_unmap_block_desc_count);
+DEF_CONFIGFS_ATTRIB_SHOW(unmap_granularity);
+DEF_CONFIGFS_ATTRIB_SHOW(unmap_granularity_alignment);
+DEF_CONFIGFS_ATTRIB_SHOW(max_write_same_len);
+
+#define DEF_CONFIGFS_ATTRIB_STORE_U32(_name)                           \
+static ssize_t _name##_store(struct config_item *item, const char *page,\
                size_t count)                                           \
 {                                                                      \
+       struct se_dev_attrib *da = to_attrib(item);                     \
        u32 val;                                                        \
        int ret;                                                        \
                                                                        \
@@ -527,16 +516,17 @@ static ssize_t store_##_name(struct se_dev_attrib *da, const char *page,\
        return count;                                                   \
 }
 
-DEF_TB_DEV_ATTRIB_STORE_U32(max_unmap_lba_count);
-DEF_TB_DEV_ATTRIB_STORE_U32(max_unmap_block_desc_count);
-DEF_TB_DEV_ATTRIB_STORE_U32(unmap_granularity);
-DEF_TB_DEV_ATTRIB_STORE_U32(unmap_granularity_alignment);
-DEF_TB_DEV_ATTRIB_STORE_U32(max_write_same_len);
+DEF_CONFIGFS_ATTRIB_STORE_U32(max_unmap_lba_count);
+DEF_CONFIGFS_ATTRIB_STORE_U32(max_unmap_block_desc_count);
+DEF_CONFIGFS_ATTRIB_STORE_U32(unmap_granularity);
+DEF_CONFIGFS_ATTRIB_STORE_U32(unmap_granularity_alignment);
+DEF_CONFIGFS_ATTRIB_STORE_U32(max_write_same_len);
 
-#define DEF_TB_DEV_ATTRIB_STORE_BOOL(_name)                            \
-static ssize_t store_##_name(struct se_dev_attrib *da, const char *page,\
+#define DEF_CONFIGFS_ATTRIB_STORE_BOOL(_name)                          \
+static ssize_t _name##_store(struct config_item *item, const char *page,       \
                size_t count)                                           \
 {                                                                      \
+       struct se_dev_attrib *da = to_attrib(item);                     \
        bool flag;                                                      \
        int ret;                                                        \
                                                                        \
@@ -547,14 +537,14 @@ static ssize_t store_##_name(struct se_dev_attrib *da, const char *page,\
        return count;                                                   \
 }
 
-DEF_TB_DEV_ATTRIB_STORE_BOOL(emulate_fua_write);
-DEF_TB_DEV_ATTRIB_STORE_BOOL(emulate_caw);
-DEF_TB_DEV_ATTRIB_STORE_BOOL(emulate_3pc);
-DEF_TB_DEV_ATTRIB_STORE_BOOL(enforce_pr_isids);
-DEF_TB_DEV_ATTRIB_STORE_BOOL(is_nonrot);
+DEF_CONFIGFS_ATTRIB_STORE_BOOL(emulate_fua_write);
+DEF_CONFIGFS_ATTRIB_STORE_BOOL(emulate_caw);
+DEF_CONFIGFS_ATTRIB_STORE_BOOL(emulate_3pc);
+DEF_CONFIGFS_ATTRIB_STORE_BOOL(enforce_pr_isids);
+DEF_CONFIGFS_ATTRIB_STORE_BOOL(is_nonrot);
 
-#define DEF_TB_DEV_ATTRIB_STORE_STUB(_name)                            \
-static ssize_t store_##_name(struct se_dev_attrib *da, const char *page,\
+#define DEF_CONFIGFS_ATTRIB_STORE_STUB(_name)                          \
+static ssize_t _name##_store(struct config_item *item, const char *page,\
                size_t count)                                           \
 {                                                                      \
        printk_once(KERN_WARNING                                        \
@@ -562,8 +552,8 @@ static ssize_t store_##_name(struct se_dev_attrib *da, const char *page,\
        return count;                                                   \
 }
 
-DEF_TB_DEV_ATTRIB_STORE_STUB(emulate_dpo);
-DEF_TB_DEV_ATTRIB_STORE_STUB(emulate_fua_read);
+DEF_CONFIGFS_ATTRIB_STORE_STUB(emulate_dpo);
+DEF_CONFIGFS_ATTRIB_STORE_STUB(emulate_fua_read);
 
 static void dev_set_t10_wwn_model_alias(struct se_device *dev)
 {
@@ -578,9 +568,10 @@ static void dev_set_t10_wwn_model_alias(struct se_device *dev)
        snprintf(&dev->t10_wwn.model[0], 16, "%s", configname);
 }
 
-static ssize_t store_emulate_model_alias(struct se_dev_attrib *da,
+static ssize_t emulate_model_alias_store(struct config_item *item,
                const char *page, size_t count)
 {
+       struct se_dev_attrib *da = to_attrib(item);
        struct se_device *dev = da->da_dev;
        bool flag;
        int ret;
@@ -606,9 +597,10 @@ static ssize_t store_emulate_model_alias(struct se_dev_attrib *da,
        return count;
 }
 
-static ssize_t store_emulate_write_cache(struct se_dev_attrib *da,
+static ssize_t emulate_write_cache_store(struct config_item *item,
                const char *page, size_t count)
 {
+       struct se_dev_attrib *da = to_attrib(item);
        bool flag;
        int ret;
 
@@ -627,9 +619,10 @@ static ssize_t store_emulate_write_cache(struct se_dev_attrib *da,
        return count;
 }
 
-static ssize_t store_emulate_ua_intlck_ctrl(struct se_dev_attrib *da,
+static ssize_t emulate_ua_intlck_ctrl_store(struct config_item *item,
                const char *page, size_t count)
 {
+       struct se_dev_attrib *da = to_attrib(item);
        u32 val;
        int ret;
 
@@ -654,9 +647,10 @@ static ssize_t store_emulate_ua_intlck_ctrl(struct se_dev_attrib *da,
        return count;
 }
 
-static ssize_t store_emulate_tas(struct se_dev_attrib *da,
+static ssize_t emulate_tas_store(struct config_item *item,
                const char *page, size_t count)
 {
+       struct se_dev_attrib *da = to_attrib(item);
        bool flag;
        int ret;
 
@@ -677,9 +671,10 @@ static ssize_t store_emulate_tas(struct se_dev_attrib *da,
        return count;
 }
 
-static ssize_t store_emulate_tpu(struct se_dev_attrib *da,
+static ssize_t emulate_tpu_store(struct config_item *item,
                const char *page, size_t count)
 {
+       struct se_dev_attrib *da = to_attrib(item);
        bool flag;
        int ret;
 
@@ -702,9 +697,10 @@ static ssize_t store_emulate_tpu(struct se_dev_attrib *da,
        return count;
 }
 
-static ssize_t store_emulate_tpws(struct se_dev_attrib *da,
+static ssize_t emulate_tpws_store(struct config_item *item,
                const char *page, size_t count)
 {
+       struct se_dev_attrib *da = to_attrib(item);
        bool flag;
        int ret;
 
@@ -727,9 +723,10 @@ static ssize_t store_emulate_tpws(struct se_dev_attrib *da,
        return count;
 }
 
-static ssize_t store_pi_prot_type(struct se_dev_attrib *da,
+static ssize_t pi_prot_type_store(struct config_item *item,
                const char *page, size_t count)
 {
+       struct se_dev_attrib *da = to_attrib(item);
        int old_prot = da->pi_prot_type, ret;
        struct se_device *dev = da->da_dev;
        u32 flag;
@@ -787,9 +784,10 @@ static ssize_t store_pi_prot_type(struct se_dev_attrib *da,
        return count;
 }
 
-static ssize_t store_pi_prot_format(struct se_dev_attrib *da,
+static ssize_t pi_prot_format_store(struct config_item *item,
                const char *page, size_t count)
 {
+       struct se_dev_attrib *da = to_attrib(item);
        struct se_device *dev = da->da_dev;
        bool flag;
        int ret;
@@ -824,9 +822,10 @@ static ssize_t store_pi_prot_format(struct se_dev_attrib *da,
        return count;
 }
 
-static ssize_t store_force_pr_aptpl(struct se_dev_attrib *da,
+static ssize_t force_pr_aptpl_store(struct config_item *item,
                const char *page, size_t count)
 {
+       struct se_dev_attrib *da = to_attrib(item);
        bool flag;
        int ret;
 
@@ -845,9 +844,10 @@ static ssize_t store_force_pr_aptpl(struct se_dev_attrib *da,
        return count;
 }
 
-static ssize_t store_emulate_rest_reord(struct se_dev_attrib *da,
+static ssize_t emulate_rest_reord_store(struct config_item *item,
                const char *page, size_t count)
 {
+       struct se_dev_attrib *da = to_attrib(item);
        bool flag;
        int ret;
 
@@ -869,9 +869,10 @@ static ssize_t store_emulate_rest_reord(struct se_dev_attrib *da,
 /*
  * Note, this can only be called on unexported SE Device Object.
  */
-static ssize_t store_queue_depth(struct se_dev_attrib *da,
+static ssize_t queue_depth_store(struct config_item *item,
                const char *page, size_t count)
 {
+       struct se_dev_attrib *da = to_attrib(item);
        struct se_device *dev = da->da_dev;
        u32 val;
        int ret;
@@ -905,9 +906,10 @@ static ssize_t store_queue_depth(struct se_dev_attrib *da,
        return count;
 }
 
-static ssize_t store_optimal_sectors(struct se_dev_attrib *da,
+static ssize_t optimal_sectors_store(struct config_item *item,
                const char *page, size_t count)
 {
+       struct se_dev_attrib *da = to_attrib(item);
        u32 val;
        int ret;
 
@@ -934,9 +936,10 @@ static ssize_t store_optimal_sectors(struct se_dev_attrib *da,
        return count;
 }
 
-static ssize_t store_block_size(struct se_dev_attrib *da,
+static ssize_t block_size_store(struct config_item *item,
                const char *page, size_t count)
 {
+       struct se_dev_attrib *da = to_attrib(item);
        u32 val;
        int ret;
 
@@ -967,50 +970,35 @@ static ssize_t store_block_size(struct se_dev_attrib *da,
        return count;
 }
 
-CONFIGFS_EATTR_STRUCT(target_backend_dev_attrib, se_dev_attrib);
-#define TB_DEV_ATTR(_backend, _name, _mode)                            \
-static struct target_backend_dev_attrib_attribute _backend##_dev_attrib_##_name = \
-       __CONFIGFS_EATTR(_name, _mode,                                  \
-       show_##_name,                                                   \
-       store_##_name);
-
-#define TB_DEV_ATTR_RO(_backend, _name)                                        \
-static struct target_backend_dev_attrib_attribute _backend##_dev_attrib_##_name = \
-       __CONFIGFS_EATTR_RO(_name,                                      \
-       show_##_name);
-
-TB_DEV_ATTR(target_core, emulate_model_alias, S_IRUGO | S_IWUSR);
-TB_DEV_ATTR(target_core, emulate_dpo, S_IRUGO | S_IWUSR);
-TB_DEV_ATTR(target_core, emulate_fua_write, S_IRUGO | S_IWUSR);
-TB_DEV_ATTR(target_core, emulate_fua_read, S_IRUGO | S_IWUSR);
-TB_DEV_ATTR(target_core, emulate_write_cache, S_IRUGO | S_IWUSR);
-TB_DEV_ATTR(target_core, emulate_ua_intlck_ctrl, S_IRUGO | S_IWUSR);
-TB_DEV_ATTR(target_core, emulate_tas, S_IRUGO | S_IWUSR);
-TB_DEV_ATTR(target_core, emulate_tpu, S_IRUGO | S_IWUSR);
-TB_DEV_ATTR(target_core, emulate_tpws, S_IRUGO | S_IWUSR);
-TB_DEV_ATTR(target_core, emulate_caw, S_IRUGO | S_IWUSR);
-TB_DEV_ATTR(target_core, emulate_3pc, S_IRUGO | S_IWUSR);
-TB_DEV_ATTR(target_core, pi_prot_type, S_IRUGO | S_IWUSR);
-TB_DEV_ATTR_RO(target_core, hw_pi_prot_type);
-TB_DEV_ATTR(target_core, pi_prot_format, S_IRUGO | S_IWUSR);
-TB_DEV_ATTR(target_core, enforce_pr_isids, S_IRUGO | S_IWUSR);
-TB_DEV_ATTR(target_core, is_nonrot, S_IRUGO | S_IWUSR);
-TB_DEV_ATTR(target_core, emulate_rest_reord, S_IRUGO | S_IWUSR);
-TB_DEV_ATTR(target_core, force_pr_aptpl, S_IRUGO | S_IWUSR)
-TB_DEV_ATTR_RO(target_core, hw_block_size);
-TB_DEV_ATTR(target_core, block_size, S_IRUGO | S_IWUSR)
-TB_DEV_ATTR_RO(target_core, hw_max_sectors);
-TB_DEV_ATTR(target_core, optimal_sectors, S_IRUGO | S_IWUSR);
-TB_DEV_ATTR_RO(target_core, hw_queue_depth);
-TB_DEV_ATTR(target_core, queue_depth, S_IRUGO | S_IWUSR);
-TB_DEV_ATTR(target_core, max_unmap_lba_count, S_IRUGO | S_IWUSR);
-TB_DEV_ATTR(target_core, max_unmap_block_desc_count, S_IRUGO | S_IWUSR);
-TB_DEV_ATTR(target_core, unmap_granularity, S_IRUGO | S_IWUSR);
-TB_DEV_ATTR(target_core, unmap_granularity_alignment, S_IRUGO | S_IWUSR);
-TB_DEV_ATTR(target_core, max_write_same_len, S_IRUGO | S_IWUSR);
-
-CONFIGFS_EATTR_STRUCT(target_core_dev_attrib, se_dev_attrib);
-CONFIGFS_EATTR_OPS(target_core_dev_attrib, se_dev_attrib, da_group);
+CONFIGFS_ATTR(, emulate_model_alias);
+CONFIGFS_ATTR(, emulate_dpo);
+CONFIGFS_ATTR(, emulate_fua_write);
+CONFIGFS_ATTR(, emulate_fua_read);
+CONFIGFS_ATTR(, emulate_write_cache);
+CONFIGFS_ATTR(, emulate_ua_intlck_ctrl);
+CONFIGFS_ATTR(, emulate_tas);
+CONFIGFS_ATTR(, emulate_tpu);
+CONFIGFS_ATTR(, emulate_tpws);
+CONFIGFS_ATTR(, emulate_caw);
+CONFIGFS_ATTR(, emulate_3pc);
+CONFIGFS_ATTR(, pi_prot_type);
+CONFIGFS_ATTR_RO(, hw_pi_prot_type);
+CONFIGFS_ATTR(, pi_prot_format);
+CONFIGFS_ATTR(, enforce_pr_isids);
+CONFIGFS_ATTR(, is_nonrot);
+CONFIGFS_ATTR(, emulate_rest_reord);
+CONFIGFS_ATTR(, force_pr_aptpl);
+CONFIGFS_ATTR_RO(, hw_block_size);
+CONFIGFS_ATTR(, block_size);
+CONFIGFS_ATTR_RO(, hw_max_sectors);
+CONFIGFS_ATTR(, optimal_sectors);
+CONFIGFS_ATTR_RO(, hw_queue_depth);
+CONFIGFS_ATTR(, queue_depth);
+CONFIGFS_ATTR(, max_unmap_lba_count);
+CONFIGFS_ATTR(, max_unmap_block_desc_count);
+CONFIGFS_ATTR(, unmap_granularity);
+CONFIGFS_ATTR(, unmap_granularity_alignment);
+CONFIGFS_ATTR(, max_write_same_len);
 
 /*
  * dev_attrib attributes for devices using the target core SBC/SPC
@@ -1018,100 +1006,78 @@ CONFIGFS_EATTR_OPS(target_core_dev_attrib, se_dev_attrib, da_group);
  * these.
  */
 struct configfs_attribute *sbc_attrib_attrs[] = {
-       &target_core_dev_attrib_emulate_model_alias.attr,
-       &target_core_dev_attrib_emulate_dpo.attr,
-       &target_core_dev_attrib_emulate_fua_write.attr,
-       &target_core_dev_attrib_emulate_fua_read.attr,
-       &target_core_dev_attrib_emulate_write_cache.attr,
-       &target_core_dev_attrib_emulate_ua_intlck_ctrl.attr,
-       &target_core_dev_attrib_emulate_tas.attr,
-       &target_core_dev_attrib_emulate_tpu.attr,
-       &target_core_dev_attrib_emulate_tpws.attr,
-       &target_core_dev_attrib_emulate_caw.attr,
-       &target_core_dev_attrib_emulate_3pc.attr,
-       &target_core_dev_attrib_pi_prot_type.attr,
-       &target_core_dev_attrib_hw_pi_prot_type.attr,
-       &target_core_dev_attrib_pi_prot_format.attr,
-       &target_core_dev_attrib_enforce_pr_isids.attr,
-       &target_core_dev_attrib_is_nonrot.attr,
-       &target_core_dev_attrib_emulate_rest_reord.attr,
-       &target_core_dev_attrib_force_pr_aptpl.attr,
-       &target_core_dev_attrib_hw_block_size.attr,
-       &target_core_dev_attrib_block_size.attr,
-       &target_core_dev_attrib_hw_max_sectors.attr,
-       &target_core_dev_attrib_optimal_sectors.attr,
-       &target_core_dev_attrib_hw_queue_depth.attr,
-       &target_core_dev_attrib_queue_depth.attr,
-       &target_core_dev_attrib_max_unmap_lba_count.attr,
-       &target_core_dev_attrib_max_unmap_block_desc_count.attr,
-       &target_core_dev_attrib_unmap_granularity.attr,
-       &target_core_dev_attrib_unmap_granularity_alignment.attr,
-       &target_core_dev_attrib_max_write_same_len.attr,
+       &attr_emulate_model_alias,
+       &attr_emulate_dpo,
+       &attr_emulate_fua_write,
+       &attr_emulate_fua_read,
+       &attr_emulate_write_cache,
+       &attr_emulate_ua_intlck_ctrl,
+       &attr_emulate_tas,
+       &attr_emulate_tpu,
+       &attr_emulate_tpws,
+       &attr_emulate_caw,
+       &attr_emulate_3pc,
+       &attr_pi_prot_type,
+       &attr_hw_pi_prot_type,
+       &attr_pi_prot_format,
+       &attr_enforce_pr_isids,
+       &attr_is_nonrot,
+       &attr_emulate_rest_reord,
+       &attr_force_pr_aptpl,
+       &attr_hw_block_size,
+       &attr_block_size,
+       &attr_hw_max_sectors,
+       &attr_optimal_sectors,
+       &attr_hw_queue_depth,
+       &attr_queue_depth,
+       &attr_max_unmap_lba_count,
+       &attr_max_unmap_block_desc_count,
+       &attr_unmap_granularity,
+       &attr_unmap_granularity_alignment,
+       &attr_max_write_same_len,
        NULL,
 };
 EXPORT_SYMBOL(sbc_attrib_attrs);
 
-TB_DEV_ATTR_RO(target_pt, hw_pi_prot_type);
-TB_DEV_ATTR_RO(target_pt, hw_block_size);
-TB_DEV_ATTR_RO(target_pt, hw_max_sectors);
-TB_DEV_ATTR_RO(target_pt, hw_queue_depth);
-
 /*
  * Minimal dev_attrib attributes for devices passing through CDBs.
  * In this case we only provide a few read-only attributes for
  * backwards compatibility.
  */
 struct configfs_attribute *passthrough_attrib_attrs[] = {
-       &target_pt_dev_attrib_hw_pi_prot_type.attr,
-       &target_pt_dev_attrib_hw_block_size.attr,
-       &target_pt_dev_attrib_hw_max_sectors.attr,
-       &target_pt_dev_attrib_hw_queue_depth.attr,
+       &attr_hw_pi_prot_type,
+       &attr_hw_block_size,
+       &attr_hw_max_sectors,
+       &attr_hw_queue_depth,
        NULL,
 };
 EXPORT_SYMBOL(passthrough_attrib_attrs);
 
-static struct configfs_item_operations target_core_dev_attrib_ops = {
-       .show_attribute         = target_core_dev_attrib_attr_show,
-       .store_attribute        = target_core_dev_attrib_attr_store,
-};
-
-TB_CIT_SETUP_DRV(dev_attrib, &target_core_dev_attrib_ops, NULL);
+TB_CIT_SETUP_DRV(dev_attrib, NULL, NULL);
 
 /* End functions for struct config_item_type tb_dev_attrib_cit */
 
 /*  Start functions for struct config_item_type tb_dev_wwn_cit */
 
-CONFIGFS_EATTR_STRUCT(target_core_dev_wwn, t10_wwn);
-#define SE_DEV_WWN_ATTR(_name, _mode)                                  \
-static struct target_core_dev_wwn_attribute target_core_dev_wwn_##_name = \
-               __CONFIGFS_EATTR(_name, _mode,                          \
-               target_core_dev_wwn_show_attr_##_name,                  \
-               target_core_dev_wwn_store_attr_##_name);
-
-#define SE_DEV_WWN_ATTR_RO(_name);                                     \
-do {                                                                   \
-       static struct target_core_dev_wwn_attribute                     \
-                       target_core_dev_wwn_##_name =                   \
-               __CONFIGFS_EATTR_RO(_name,                              \
-               target_core_dev_wwn_show_attr_##_name);                 \
-} while (0);
+static struct t10_wwn *to_t10_wwn(struct config_item *item)
+{
+       return container_of(to_config_group(item), struct t10_wwn, t10_wwn_group);
+}
 
 /*
  * VPD page 0x80 Unit serial
  */
-static ssize_t target_core_dev_wwn_show_attr_vpd_unit_serial(
-       struct t10_wwn *t10_wwn,
-       char *page)
+static ssize_t target_wwn_vpd_unit_serial_show(struct config_item *item,
+               char *page)
 {
        return sprintf(page, "T10 VPD Unit Serial Number: %s\n",
-               &t10_wwn->unit_serial[0]);
+               &to_t10_wwn(item)->unit_serial[0]);
 }
 
-static ssize_t target_core_dev_wwn_store_attr_vpd_unit_serial(
-       struct t10_wwn *t10_wwn,
-       const char *page,
-       size_t count)
+static ssize_t target_wwn_vpd_unit_serial_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct t10_wwn *t10_wwn = to_t10_wwn(item);
        struct se_device *dev = t10_wwn->t10_dev;
        unsigned char buf[INQUIRY_VPD_SERIAL_LEN];
 
@@ -1167,15 +1133,13 @@ static ssize_t target_core_dev_wwn_store_attr_vpd_unit_serial(
        return count;
 }
 
-SE_DEV_WWN_ATTR(vpd_unit_serial, S_IRUGO | S_IWUSR);
-
 /*
  * VPD page 0x83 Protocol Identifier
  */
-static ssize_t target_core_dev_wwn_show_attr_vpd_protocol_identifier(
-       struct t10_wwn *t10_wwn,
-       char *page)
+static ssize_t target_wwn_vpd_protocol_identifier_show(struct config_item *item,
+               char *page)
 {
+       struct t10_wwn *t10_wwn = to_t10_wwn(item);
        struct t10_vpd *vpd;
        unsigned char buf[VPD_TMP_BUF_SIZE];
        ssize_t len = 0;
@@ -1199,25 +1163,15 @@ static ssize_t target_core_dev_wwn_show_attr_vpd_protocol_identifier(
        return len;
 }
 
-static ssize_t target_core_dev_wwn_store_attr_vpd_protocol_identifier(
-       struct t10_wwn *t10_wwn,
-       const char *page,
-       size_t count)
-{
-       return -ENOSYS;
-}
-
-SE_DEV_WWN_ATTR(vpd_protocol_identifier, S_IRUGO | S_IWUSR);
-
 /*
  * Generic wrapper for dumping VPD identifiers by association.
  */
 #define DEF_DEV_WWN_ASSOC_SHOW(_name, _assoc)                          \
-static ssize_t target_core_dev_wwn_show_attr_##_name(                  \
-       struct t10_wwn *t10_wwn,                                        \
-       char *page)                                                     \
+static ssize_t target_wwn_##_name##_show(struct config_item *item,     \
+               char *page)                                             \
 {                                                                      \
-       struct t10_vpd *vpd;                                                    \
+       struct t10_wwn *t10_wwn = to_t10_wwn(item);                     \
+       struct t10_vpd *vpd;                                            \
        unsigned char buf[VPD_TMP_BUF_SIZE];                            \
        ssize_t len = 0;                                                \
                                                                        \
@@ -1249,84 +1203,39 @@ static ssize_t target_core_dev_wwn_show_attr_##_name(                   \
        return len;                                                     \
 }
 
-/*
- * VPD page 0x83 Association: Logical Unit
- */
+/* VPD page 0x83 Association: Logical Unit */
 DEF_DEV_WWN_ASSOC_SHOW(vpd_assoc_logical_unit, 0x00);
-
-static ssize_t target_core_dev_wwn_store_attr_vpd_assoc_logical_unit(
-       struct t10_wwn *t10_wwn,
-       const char *page,
-       size_t count)
-{
-       return -ENOSYS;
-}
-
-SE_DEV_WWN_ATTR(vpd_assoc_logical_unit, S_IRUGO | S_IWUSR);
-
-/*
- * VPD page 0x83 Association: Target Port
- */
+/* VPD page 0x83 Association: Target Port */
 DEF_DEV_WWN_ASSOC_SHOW(vpd_assoc_target_port, 0x10);
-
-static ssize_t target_core_dev_wwn_store_attr_vpd_assoc_target_port(
-       struct t10_wwn *t10_wwn,
-       const char *page,
-       size_t count)
-{
-       return -ENOSYS;
-}
-
-SE_DEV_WWN_ATTR(vpd_assoc_target_port, S_IRUGO | S_IWUSR);
-
-/*
- * VPD page 0x83 Association: SCSI Target Device
- */
+/* VPD page 0x83 Association: SCSI Target Device */
 DEF_DEV_WWN_ASSOC_SHOW(vpd_assoc_scsi_target_device, 0x20);
 
-static ssize_t target_core_dev_wwn_store_attr_vpd_assoc_scsi_target_device(
-       struct t10_wwn *t10_wwn,
-       const char *page,
-       size_t count)
-{
-       return -ENOSYS;
-}
-
-SE_DEV_WWN_ATTR(vpd_assoc_scsi_target_device, S_IRUGO | S_IWUSR);
-
-CONFIGFS_EATTR_OPS(target_core_dev_wwn, t10_wwn, t10_wwn_group);
+CONFIGFS_ATTR(target_wwn_, vpd_unit_serial);
+CONFIGFS_ATTR_RO(target_wwn_, vpd_protocol_identifier);
+CONFIGFS_ATTR_RO(target_wwn_, vpd_assoc_logical_unit);
+CONFIGFS_ATTR_RO(target_wwn_, vpd_assoc_target_port);
+CONFIGFS_ATTR_RO(target_wwn_, vpd_assoc_scsi_target_device);
 
 static struct configfs_attribute *target_core_dev_wwn_attrs[] = {
-       &target_core_dev_wwn_vpd_unit_serial.attr,
-       &target_core_dev_wwn_vpd_protocol_identifier.attr,
-       &target_core_dev_wwn_vpd_assoc_logical_unit.attr,
-       &target_core_dev_wwn_vpd_assoc_target_port.attr,
-       &target_core_dev_wwn_vpd_assoc_scsi_target_device.attr,
+       &target_wwn_attr_vpd_unit_serial,
+       &target_wwn_attr_vpd_protocol_identifier,
+       &target_wwn_attr_vpd_assoc_logical_unit,
+       &target_wwn_attr_vpd_assoc_target_port,
+       &target_wwn_attr_vpd_assoc_scsi_target_device,
        NULL,
 };
 
-static struct configfs_item_operations target_core_dev_wwn_ops = {
-       .show_attribute         = target_core_dev_wwn_attr_show,
-       .store_attribute        = target_core_dev_wwn_attr_store,
-};
-
-TB_CIT_SETUP(dev_wwn, &target_core_dev_wwn_ops, NULL, target_core_dev_wwn_attrs);
+TB_CIT_SETUP(dev_wwn, NULL, NULL, target_core_dev_wwn_attrs);
 
 /*  End functions for struct config_item_type tb_dev_wwn_cit */
 
 /*  Start functions for struct config_item_type tb_dev_pr_cit */
 
-CONFIGFS_EATTR_STRUCT(target_core_dev_pr, se_device);
-#define SE_DEV_PR_ATTR(_name, _mode)                                   \
-static struct target_core_dev_pr_attribute target_core_dev_pr_##_name = \
-       __CONFIGFS_EATTR(_name, _mode,                                  \
-       target_core_dev_pr_show_attr_##_name,                           \
-       target_core_dev_pr_store_attr_##_name);
-
-#define SE_DEV_PR_ATTR_RO(_name);                                      \
-static struct target_core_dev_pr_attribute target_core_dev_pr_##_name =        \
-       __CONFIGFS_EATTR_RO(_name,                                      \
-       target_core_dev_pr_show_attr_##_name);
+static struct se_device *pr_to_dev(struct config_item *item)
+{
+       return container_of(to_config_group(item), struct se_device,
+                       dev_pr_group);
+}
 
 static ssize_t target_core_dev_pr_show_spc3_res(struct se_device *dev,
                char *page)
@@ -1367,9 +1276,9 @@ static ssize_t target_core_dev_pr_show_spc2_res(struct se_device *dev,
        return len;
 }
 
-static ssize_t target_core_dev_pr_show_attr_res_holder(struct se_device *dev,
-               char *page)
+static ssize_t target_pr_res_holder_show(struct config_item *item, char *page)
 {
+       struct se_device *dev = pr_to_dev(item);
        int ret;
 
        if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH)
@@ -1384,11 +1293,10 @@ static ssize_t target_core_dev_pr_show_attr_res_holder(struct se_device *dev,
        return ret;
 }
 
-SE_DEV_PR_ATTR_RO(res_holder);
-
-static ssize_t target_core_dev_pr_show_attr_res_pr_all_tgt_pts(
-               struct se_device *dev, char *page)
+static ssize_t target_pr_res_pr_all_tgt_pts_show(struct config_item *item,
+               char *page)
 {
+       struct se_device *dev = pr_to_dev(item);
        ssize_t len = 0;
 
        spin_lock(&dev->dev_reservation_lock);
@@ -1406,22 +1314,17 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_all_tgt_pts(
        return len;
 }
 
-SE_DEV_PR_ATTR_RO(res_pr_all_tgt_pts);
-
-static ssize_t target_core_dev_pr_show_attr_res_pr_generation(
-               struct se_device *dev, char *page)
+static ssize_t target_pr_res_pr_generation_show(struct config_item *item,
+               char *page)
 {
-       return sprintf(page, "0x%08x\n", dev->t10_pr.pr_generation);
+       return sprintf(page, "0x%08x\n", pr_to_dev(item)->t10_pr.pr_generation);
 }
 
-SE_DEV_PR_ATTR_RO(res_pr_generation);
 
-/*
- * res_pr_holder_tg_port
- */
-static ssize_t target_core_dev_pr_show_attr_res_pr_holder_tg_port(
-               struct se_device *dev, char *page)
+static ssize_t target_pr_res_pr_holder_tg_port_show(struct config_item *item,
+               char *page)
 {
+       struct se_device *dev = pr_to_dev(item);
        struct se_node_acl *se_nacl;
        struct se_portal_group *se_tpg;
        struct t10_pr_registration *pr_reg;
@@ -1453,11 +1356,11 @@ out_unlock:
        return len;
 }
 
-SE_DEV_PR_ATTR_RO(res_pr_holder_tg_port);
 
-static ssize_t target_core_dev_pr_show_attr_res_pr_registered_i_pts(
-               struct se_device *dev, char *page)
+static ssize_t target_pr_res_pr_registered_i_pts_show(struct config_item *item,
+               char *page)
 {
+       struct se_device *dev = pr_to_dev(item);
        const struct target_core_fabric_ops *tfo;
        struct t10_pr_registration *pr_reg;
        unsigned char buf[384];
@@ -1495,11 +1398,9 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_registered_i_pts(
        return len;
 }
 
-SE_DEV_PR_ATTR_RO(res_pr_registered_i_pts);
-
-static ssize_t target_core_dev_pr_show_attr_res_pr_type(
-               struct se_device *dev, char *page)
+static ssize_t target_pr_res_pr_type_show(struct config_item *item, char *page)
 {
+       struct se_device *dev = pr_to_dev(item);
        struct t10_pr_registration *pr_reg;
        ssize_t len = 0;
 
@@ -1516,11 +1417,10 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_type(
        return len;
 }
 
-SE_DEV_PR_ATTR_RO(res_pr_type);
-
-static ssize_t target_core_dev_pr_show_attr_res_type(
-               struct se_device *dev, char *page)
+static ssize_t target_pr_res_type_show(struct config_item *item, char *page)
 {
+       struct se_device *dev = pr_to_dev(item);
+
        if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH)
                return sprintf(page, "SPC_PASSTHROUGH\n");
        else if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS)
@@ -1529,11 +1429,11 @@ static ssize_t target_core_dev_pr_show_attr_res_type(
                return sprintf(page, "SPC3_PERSISTENT_RESERVATIONS\n");
 }
 
-SE_DEV_PR_ATTR_RO(res_type);
-
-static ssize_t target_core_dev_pr_show_attr_res_aptpl_active(
-               struct se_device *dev, char *page)
+static ssize_t target_pr_res_aptpl_active_show(struct config_item *item,
+               char *page)
 {
+       struct se_device *dev = pr_to_dev(item);
+
        if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH)
                return 0;
 
@@ -1541,14 +1441,11 @@ static ssize_t target_core_dev_pr_show_attr_res_aptpl_active(
                (dev->t10_pr.pr_aptpl_active) ? "Activated" : "Disabled");
 }
 
-SE_DEV_PR_ATTR_RO(res_aptpl_active);
-
-/*
- * res_aptpl_metadata
- */
-static ssize_t target_core_dev_pr_show_attr_res_aptpl_metadata(
-               struct se_device *dev, char *page)
+static ssize_t target_pr_res_aptpl_metadata_show(struct config_item *item,
+               char *page)
 {
+       struct se_device *dev = pr_to_dev(item);
+
        if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH)
                return 0;
 
@@ -1580,11 +1477,10 @@ static match_table_t tokens = {
        {Opt_err, NULL}
 };
 
-static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
-       struct se_device *dev,
-       const char *page,
-       size_t count)
+static ssize_t target_pr_res_aptpl_metadata_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct se_device *dev = pr_to_dev(item);
        unsigned char *i_fabric = NULL, *i_port = NULL, *isid = NULL;
        unsigned char *t_fabric = NULL, *t_port = NULL;
        char *orig, *ptr, *opts;
@@ -1765,37 +1661,44 @@ out:
        return (ret == 0) ? count : ret;
 }
 
-SE_DEV_PR_ATTR(res_aptpl_metadata, S_IRUGO | S_IWUSR);
 
-CONFIGFS_EATTR_OPS(target_core_dev_pr, se_device, dev_pr_group);
+CONFIGFS_ATTR_RO(target_pr_, res_holder);
+CONFIGFS_ATTR_RO(target_pr_, res_pr_all_tgt_pts);
+CONFIGFS_ATTR_RO(target_pr_, res_pr_generation);
+CONFIGFS_ATTR_RO(target_pr_, res_pr_holder_tg_port);
+CONFIGFS_ATTR_RO(target_pr_, res_pr_registered_i_pts);
+CONFIGFS_ATTR_RO(target_pr_, res_pr_type);
+CONFIGFS_ATTR_RO(target_pr_, res_type);
+CONFIGFS_ATTR_RO(target_pr_, res_aptpl_active);
+CONFIGFS_ATTR(target_pr_, res_aptpl_metadata);
 
 static struct configfs_attribute *target_core_dev_pr_attrs[] = {
-       &target_core_dev_pr_res_holder.attr,
-       &target_core_dev_pr_res_pr_all_tgt_pts.attr,
-       &target_core_dev_pr_res_pr_generation.attr,
-       &target_core_dev_pr_res_pr_holder_tg_port.attr,
-       &target_core_dev_pr_res_pr_registered_i_pts.attr,
-       &target_core_dev_pr_res_pr_type.attr,
-       &target_core_dev_pr_res_type.attr,
-       &target_core_dev_pr_res_aptpl_active.attr,
-       &target_core_dev_pr_res_aptpl_metadata.attr,
+       &target_pr_attr_res_holder,
+       &target_pr_attr_res_pr_all_tgt_pts,
+       &target_pr_attr_res_pr_generation,
+       &target_pr_attr_res_pr_holder_tg_port,
+       &target_pr_attr_res_pr_registered_i_pts,
+       &target_pr_attr_res_pr_type,
+       &target_pr_attr_res_type,
+       &target_pr_attr_res_aptpl_active,
+       &target_pr_attr_res_aptpl_metadata,
        NULL,
 };
 
-static struct configfs_item_operations target_core_dev_pr_ops = {
-       .show_attribute         = target_core_dev_pr_attr_show,
-       .store_attribute        = target_core_dev_pr_attr_store,
-};
-
-TB_CIT_SETUP(dev_pr, &target_core_dev_pr_ops, NULL, target_core_dev_pr_attrs);
+TB_CIT_SETUP(dev_pr, NULL, NULL, target_core_dev_pr_attrs);
 
 /*  End functions for struct config_item_type tb_dev_pr_cit */
 
 /*  Start functions for struct config_item_type tb_dev_cit */
 
-static ssize_t target_core_show_dev_info(void *p, char *page)
+static inline struct se_device *to_device(struct config_item *item)
+{
+       return container_of(to_config_group(item), struct se_device, dev_group);
+}
+
+static ssize_t target_dev_info_show(struct config_item *item, char *page)
 {
-       struct se_device *dev = p;
+       struct se_device *dev = to_device(item);
        int bl = 0;
        ssize_t read_bytes = 0;
 
@@ -1806,35 +1709,17 @@ static ssize_t target_core_show_dev_info(void *p, char *page)
        return read_bytes;
 }
 
-static struct target_core_configfs_attribute target_core_attr_dev_info = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                   .ca_name = "info",
-                   .ca_mode = S_IRUGO },
-       .show   = target_core_show_dev_info,
-       .store  = NULL,
-};
-
-static ssize_t target_core_store_dev_control(
-       void *p,
-       const char *page,
-       size_t count)
+static ssize_t target_dev_control_store(struct config_item *item,
+               const char *page, size_t count)
 {
-       struct se_device *dev = p;
+       struct se_device *dev = to_device(item);
 
        return dev->transport->set_configfs_dev_params(dev, page, count);
 }
 
-static struct target_core_configfs_attribute target_core_attr_dev_control = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                   .ca_name = "control",
-                   .ca_mode = S_IWUSR },
-       .show   = NULL,
-       .store  = target_core_store_dev_control,
-};
-
-static ssize_t target_core_show_dev_alias(void *p, char *page)
+static ssize_t target_dev_alias_show(struct config_item *item, char *page)
 {
-       struct se_device *dev = p;
+       struct se_device *dev = to_device(item);
 
        if (!(dev->dev_flags & DF_USING_ALIAS))
                return 0;
@@ -1842,12 +1727,10 @@ static ssize_t target_core_show_dev_alias(void *p, char *page)
        return snprintf(page, PAGE_SIZE, "%s\n", dev->dev_alias);
 }
 
-static ssize_t target_core_store_dev_alias(
-       void *p,
-       const char *page,
-       size_t count)
+static ssize_t target_dev_alias_store(struct config_item *item,
+               const char *page, size_t count)
 {
-       struct se_device *dev = p;
+       struct se_device *dev = to_device(item);
        struct se_hba *hba = dev->se_hba;
        ssize_t read_bytes;
 
@@ -1874,17 +1757,9 @@ static ssize_t target_core_store_dev_alias(
        return read_bytes;
 }
 
-static struct target_core_configfs_attribute target_core_attr_dev_alias = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                   .ca_name = "alias",
-                   .ca_mode =  S_IRUGO | S_IWUSR },
-       .show   = target_core_show_dev_alias,
-       .store  = target_core_store_dev_alias,
-};
-
-static ssize_t target_core_show_dev_udev_path(void *p, char *page)
+static ssize_t target_dev_udev_path_show(struct config_item *item, char *page)
 {
-       struct se_device *dev = p;
+       struct se_device *dev = to_device(item);
 
        if (!(dev->dev_flags & DF_USING_UDEV_PATH))
                return 0;
@@ -1892,12 +1767,10 @@ static ssize_t target_core_show_dev_udev_path(void *p, char *page)
        return snprintf(page, PAGE_SIZE, "%s\n", dev->udev_path);
 }
 
-static ssize_t target_core_store_dev_udev_path(
-       void *p,
-       const char *page,
-       size_t count)
+static ssize_t target_dev_udev_path_store(struct config_item *item,
+               const char *page, size_t count)
 {
-       struct se_device *dev = p;
+       struct se_device *dev = to_device(item);
        struct se_hba *hba = dev->se_hba;
        ssize_t read_bytes;
 
@@ -1925,27 +1798,17 @@ static ssize_t target_core_store_dev_udev_path(
        return read_bytes;
 }
 
-static struct target_core_configfs_attribute target_core_attr_dev_udev_path = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                   .ca_name = "udev_path",
-                   .ca_mode =  S_IRUGO | S_IWUSR },
-       .show   = target_core_show_dev_udev_path,
-       .store  = target_core_store_dev_udev_path,
-};
-
-static ssize_t target_core_show_dev_enable(void *p, char *page)
+static ssize_t target_dev_enable_show(struct config_item *item, char *page)
 {
-       struct se_device *dev = p;
+       struct se_device *dev = to_device(item);
 
        return snprintf(page, PAGE_SIZE, "%d\n", !!(dev->dev_flags & DF_CONFIGURED));
 }
 
-static ssize_t target_core_store_dev_enable(
-       void *p,
-       const char *page,
-       size_t count)
+static ssize_t target_dev_enable_store(struct config_item *item,
+               const char *page, size_t count)
 {
-       struct se_device *dev = p;
+       struct se_device *dev = to_device(item);
        char *ptr;
        int ret;
 
@@ -1962,17 +1825,9 @@ static ssize_t target_core_store_dev_enable(
        return count;
 }
 
-static struct target_core_configfs_attribute target_core_attr_dev_enable = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                   .ca_name = "enable",
-                   .ca_mode =  S_IRUGO | S_IWUSR },
-       .show   = target_core_show_dev_enable,
-       .store  = target_core_store_dev_enable,
-};
-
-static ssize_t target_core_show_alua_lu_gp(void *p, char *page)
+static ssize_t target_dev_alua_lu_gp_show(struct config_item *item, char *page)
 {
-       struct se_device *dev = p;
+       struct se_device *dev = to_device(item);
        struct config_item *lu_ci;
        struct t10_alua_lu_gp *lu_gp;
        struct t10_alua_lu_gp_member *lu_gp_mem;
@@ -1994,12 +1849,10 @@ static ssize_t target_core_show_alua_lu_gp(void *p, char *page)
        return len;
 }
 
-static ssize_t target_core_store_alua_lu_gp(
-       void *p,
-       const char *page,
-       size_t count)
+static ssize_t target_dev_alua_lu_gp_store(struct config_item *item,
+               const char *page, size_t count)
 {
-       struct se_device *dev = p;
+       struct se_device *dev = to_device(item);
        struct se_hba *hba = dev->se_hba;
        struct t10_alua_lu_gp *lu_gp = NULL, *lu_gp_new = NULL;
        struct t10_alua_lu_gp_member *lu_gp_mem;
@@ -2076,17 +1929,9 @@ static ssize_t target_core_store_alua_lu_gp(
        return count;
 }
 
-static struct target_core_configfs_attribute target_core_attr_dev_alua_lu_gp = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                   .ca_name = "alua_lu_gp",
-                   .ca_mode = S_IRUGO | S_IWUSR },
-       .show   = target_core_show_alua_lu_gp,
-       .store  = target_core_store_alua_lu_gp,
-};
-
-static ssize_t target_core_show_dev_lba_map(void *p, char *page)
+static ssize_t target_dev_lba_map_show(struct config_item *item, char *page)
 {
-       struct se_device *dev = p;
+       struct se_device *dev = to_device(item);
        struct t10_alua_lba_map *map;
        struct t10_alua_lba_map_member *mem;
        char *b = page;
@@ -2129,12 +1974,10 @@ static ssize_t target_core_show_dev_lba_map(void *p, char *page)
        return bl;
 }
 
-static ssize_t target_core_store_dev_lba_map(
-       void *p,
-       const char *page,
-       size_t count)
+static ssize_t target_dev_lba_map_store(struct config_item *item,
+               const char *page, size_t count)
 {
-       struct se_device *dev = p;
+       struct se_device *dev = to_device(item);
        struct t10_alua_lba_map *lba_map = NULL;
        struct list_head lba_list;
        char *map_entries, *ptr;
@@ -2246,22 +2089,22 @@ out:
        return count;
 }
 
-static struct target_core_configfs_attribute target_core_attr_dev_lba_map = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                   .ca_name = "lba_map",
-                   .ca_mode = S_IRUGO | S_IWUSR },
-       .show   = target_core_show_dev_lba_map,
-       .store  = target_core_store_dev_lba_map,
-};
+CONFIGFS_ATTR_RO(target_dev_, info);
+CONFIGFS_ATTR_WO(target_dev_, control);
+CONFIGFS_ATTR(target_dev_, alias);
+CONFIGFS_ATTR(target_dev_, udev_path);
+CONFIGFS_ATTR(target_dev_, enable);
+CONFIGFS_ATTR(target_dev_, alua_lu_gp);
+CONFIGFS_ATTR(target_dev_, lba_map);
 
 static struct configfs_attribute *target_core_dev_attrs[] = {
-       &target_core_attr_dev_info.attr,
-       &target_core_attr_dev_control.attr,
-       &target_core_attr_dev_alias.attr,
-       &target_core_attr_dev_udev_path.attr,
-       &target_core_attr_dev_enable.attr,
-       &target_core_attr_dev_alua_lu_gp.attr,
-       &target_core_attr_dev_lba_map.attr,
+       &target_dev_attr_info,
+       &target_dev_attr_control,
+       &target_dev_attr_alias,
+       &target_dev_attr_udev_path,
+       &target_dev_attr_enable,
+       &target_dev_attr_alua_lu_gp,
+       &target_dev_attr_lba_map,
        NULL,
 };
 
@@ -2275,42 +2118,8 @@ static void target_core_dev_release(struct config_item *item)
        target_free_device(dev);
 }
 
-static ssize_t target_core_dev_show(struct config_item *item,
-                                    struct configfs_attribute *attr,
-                                    char *page)
-{
-       struct config_group *dev_cg = to_config_group(item);
-       struct se_device *dev =
-               container_of(dev_cg, struct se_device, dev_group);
-       struct target_core_configfs_attribute *tc_attr = container_of(
-                       attr, struct target_core_configfs_attribute, attr);
-
-       if (!tc_attr->show)
-               return -EINVAL;
-
-       return tc_attr->show(dev, page);
-}
-
-static ssize_t target_core_dev_store(struct config_item *item,
-                                     struct configfs_attribute *attr,
-                                     const char *page, size_t count)
-{
-       struct config_group *dev_cg = to_config_group(item);
-       struct se_device *dev =
-               container_of(dev_cg, struct se_device, dev_group);
-       struct target_core_configfs_attribute *tc_attr = container_of(
-                       attr, struct target_core_configfs_attribute, attr);
-
-       if (!tc_attr->store)
-               return -EINVAL;
-
-       return tc_attr->store(dev, page, count);
-}
-
 static struct configfs_item_operations target_core_dev_item_ops = {
        .release                = target_core_dev_release,
-       .show_attribute         = target_core_dev_show,
-       .store_attribute        = target_core_dev_store,
 };
 
 TB_CIT_SETUP(dev, &target_core_dev_item_ops, NULL, target_core_dev_attrs);
@@ -2319,38 +2128,25 @@ TB_CIT_SETUP(dev, &target_core_dev_item_ops, NULL, target_core_dev_attrs);
 
 /* Start functions for struct config_item_type target_core_alua_lu_gp_cit */
 
-CONFIGFS_EATTR_STRUCT(target_core_alua_lu_gp, t10_alua_lu_gp);
-#define SE_DEV_ALUA_LU_ATTR(_name, _mode)                              \
-static struct target_core_alua_lu_gp_attribute                         \
-                       target_core_alua_lu_gp_##_name =                \
-       __CONFIGFS_EATTR(_name, _mode,                                  \
-       target_core_alua_lu_gp_show_attr_##_name,                       \
-       target_core_alua_lu_gp_store_attr_##_name);
-
-#define SE_DEV_ALUA_LU_ATTR_RO(_name)                                  \
-static struct target_core_alua_lu_gp_attribute                         \
-                       target_core_alua_lu_gp_##_name =                \
-       __CONFIGFS_EATTR_RO(_name,                                      \
-       target_core_alua_lu_gp_show_attr_##_name);
+static inline struct t10_alua_lu_gp *to_lu_gp(struct config_item *item)
+{
+       return container_of(to_config_group(item), struct t10_alua_lu_gp,
+                       lu_gp_group);
+}
 
-/*
- * lu_gp_id
- */
-static ssize_t target_core_alua_lu_gp_show_attr_lu_gp_id(
-       struct t10_alua_lu_gp *lu_gp,
-       char *page)
+static ssize_t target_lu_gp_lu_gp_id_show(struct config_item *item, char *page)
 {
+       struct t10_alua_lu_gp *lu_gp = to_lu_gp(item);
+
        if (!lu_gp->lu_gp_valid_id)
                return 0;
-
        return sprintf(page, "%hu\n", lu_gp->lu_gp_id);
 }
 
-static ssize_t target_core_alua_lu_gp_store_attr_lu_gp_id(
-       struct t10_alua_lu_gp *lu_gp,
-       const char *page,
-       size_t count)
+static ssize_t target_lu_gp_lu_gp_id_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct t10_alua_lu_gp *lu_gp = to_lu_gp(item);
        struct config_group *alua_lu_gp_cg = &lu_gp->lu_gp_group;
        unsigned long lu_gp_id;
        int ret;
@@ -2379,15 +2175,9 @@ static ssize_t target_core_alua_lu_gp_store_attr_lu_gp_id(
        return count;
 }
 
-SE_DEV_ALUA_LU_ATTR(lu_gp_id, S_IRUGO | S_IWUSR);
-
-/*
- * members
- */
-static ssize_t target_core_alua_lu_gp_show_attr_members(
-       struct t10_alua_lu_gp *lu_gp,
-       char *page)
+static ssize_t target_lu_gp_members_show(struct config_item *item, char *page)
 {
+       struct t10_alua_lu_gp *lu_gp = to_lu_gp(item);
        struct se_device *dev;
        struct se_hba *hba;
        struct t10_alua_lu_gp_member *lu_gp_mem;
@@ -2419,13 +2209,12 @@ static ssize_t target_core_alua_lu_gp_show_attr_members(
        return len;
 }
 
-SE_DEV_ALUA_LU_ATTR_RO(members);
-
-CONFIGFS_EATTR_OPS(target_core_alua_lu_gp, t10_alua_lu_gp, lu_gp_group);
+CONFIGFS_ATTR(target_lu_gp_, lu_gp_id);
+CONFIGFS_ATTR_RO(target_lu_gp_, members);
 
 static struct configfs_attribute *target_core_alua_lu_gp_attrs[] = {
-       &target_core_alua_lu_gp_lu_gp_id.attr,
-       &target_core_alua_lu_gp_members.attr,
+       &target_lu_gp_attr_lu_gp_id,
+       &target_lu_gp_attr_members,
        NULL,
 };
 
@@ -2439,8 +2228,6 @@ static void target_core_alua_lu_gp_release(struct config_item *item)
 
 static struct configfs_item_operations target_core_alua_lu_gp_ops = {
        .release                = target_core_alua_lu_gp_release,
-       .show_attribute         = target_core_alua_lu_gp_attr_show,
-       .store_attribute        = target_core_alua_lu_gp_attr_store,
 };
 
 static struct config_item_type target_core_alua_lu_gp_cit = {
@@ -2511,36 +2298,23 @@ static struct config_item_type target_core_alua_lu_gps_cit = {
 
 /* Start functions for struct config_item_type target_core_alua_tg_pt_gp_cit */
 
-CONFIGFS_EATTR_STRUCT(target_core_alua_tg_pt_gp, t10_alua_tg_pt_gp);
-#define SE_DEV_ALUA_TG_PT_ATTR(_name, _mode)                           \
-static struct target_core_alua_tg_pt_gp_attribute                      \
-                       target_core_alua_tg_pt_gp_##_name =             \
-       __CONFIGFS_EATTR(_name, _mode,                                  \
-       target_core_alua_tg_pt_gp_show_attr_##_name,                    \
-       target_core_alua_tg_pt_gp_store_attr_##_name);
-
-#define SE_DEV_ALUA_TG_PT_ATTR_RO(_name)                               \
-static struct target_core_alua_tg_pt_gp_attribute                      \
-                       target_core_alua_tg_pt_gp_##_name =             \
-       __CONFIGFS_EATTR_RO(_name,                                      \
-       target_core_alua_tg_pt_gp_show_attr_##_name);
+static inline struct t10_alua_tg_pt_gp *to_tg_pt_gp(struct config_item *item)
+{
+       return container_of(to_config_group(item), struct t10_alua_tg_pt_gp,
+                       tg_pt_gp_group);
+}
 
-/*
- * alua_access_state
- */
-static ssize_t target_core_alua_tg_pt_gp_show_attr_alua_access_state(
-       struct t10_alua_tg_pt_gp *tg_pt_gp,
-       char *page)
+static ssize_t target_tg_pt_gp_alua_access_state_show(struct config_item *item,
+               char *page)
 {
        return sprintf(page, "%d\n",
-               atomic_read(&tg_pt_gp->tg_pt_gp_alua_access_state));
+               atomic_read(&to_tg_pt_gp(item)->tg_pt_gp_alua_access_state));
 }
 
-static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_state(
-       struct t10_alua_tg_pt_gp *tg_pt_gp,
-       const char *page,
-       size_t count)
+static ssize_t target_tg_pt_gp_alua_access_state_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct t10_alua_tg_pt_gp *tg_pt_gp = to_tg_pt_gp(item);
        struct se_device *dev = tg_pt_gp->tg_pt_gp_dev;
        unsigned long tmp;
        int new_state, ret;
@@ -2582,24 +2356,18 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_state(
        return (!ret) ? count : -EINVAL;
 }
 
-SE_DEV_ALUA_TG_PT_ATTR(alua_access_state, S_IRUGO | S_IWUSR);
-
-/*
- * alua_access_status
- */
-static ssize_t target_core_alua_tg_pt_gp_show_attr_alua_access_status(
-       struct t10_alua_tg_pt_gp *tg_pt_gp,
-       char *page)
+static ssize_t target_tg_pt_gp_alua_access_status_show(struct config_item *item,
+               char *page)
 {
+       struct t10_alua_tg_pt_gp *tg_pt_gp = to_tg_pt_gp(item);
        return sprintf(page, "%s\n",
                core_alua_dump_status(tg_pt_gp->tg_pt_gp_alua_access_status));
 }
 
-static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_status(
-       struct t10_alua_tg_pt_gp *tg_pt_gp,
-       const char *page,
-       size_t count)
+static ssize_t target_tg_pt_gp_alua_access_status_store(
+               struct config_item *item, const char *page, size_t count)
 {
+       struct t10_alua_tg_pt_gp *tg_pt_gp = to_tg_pt_gp(item);
        unsigned long tmp;
        int new_status, ret;
 
@@ -2630,43 +2398,31 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_status(
        return count;
 }
 
-SE_DEV_ALUA_TG_PT_ATTR(alua_access_status, S_IRUGO | S_IWUSR);
-
-/*
- * alua_access_type
- */
-static ssize_t target_core_alua_tg_pt_gp_show_attr_alua_access_type(
-       struct t10_alua_tg_pt_gp *tg_pt_gp,
-       char *page)
+static ssize_t target_tg_pt_gp_alua_access_type_show(struct config_item *item,
+               char *page)
 {
-       return core_alua_show_access_type(tg_pt_gp, page);
+       return core_alua_show_access_type(to_tg_pt_gp(item), page);
 }
 
-static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_type(
-       struct t10_alua_tg_pt_gp *tg_pt_gp,
-       const char *page,
-       size_t count)
+static ssize_t target_tg_pt_gp_alua_access_type_store(struct config_item *item,
+               const char *page, size_t count)
 {
-       return core_alua_store_access_type(tg_pt_gp, page, count);
+       return core_alua_store_access_type(to_tg_pt_gp(item), page, count);
 }
 
-SE_DEV_ALUA_TG_PT_ATTR(alua_access_type, S_IRUGO | S_IWUSR);
-
-/*
- * alua_supported_states
- */
-
-#define SE_DEV_ALUA_SUPPORT_STATE_SHOW(_name, _var, _bit)              \
-static ssize_t target_core_alua_tg_pt_gp_show_attr_alua_support_##_name( \
-       struct t10_alua_tg_pt_gp *t, char *p)                           \
+#define ALUA_SUPPORTED_STATE_ATTR(_name, _bit)                         \
+static ssize_t target_tg_pt_gp_alua_support_##_name##_show(            \
+               struct config_item *item, char *p)                      \
 {                                                                      \
-       return sprintf(p, "%d\n", !!(t->_var & _bit));                  \
-}
-
-#define SE_DEV_ALUA_SUPPORT_STATE_STORE(_name, _var, _bit)             \
-static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_support_##_name(\
-       struct t10_alua_tg_pt_gp *t, const char *p, size_t c)           \
+       struct t10_alua_tg_pt_gp *t = to_tg_pt_gp(item);                \
+       return sprintf(p, "%d\n",                                       \
+               !!(t->tg_pt_gp_alua_supported_states & _bit));          \
+}                                                                      \
+                                                                       \
+static ssize_t target_tg_pt_gp_alua_support_##_name##_store(           \
+               struct config_item *item, const char *p, size_t c)      \
 {                                                                      \
+       struct t10_alua_tg_pt_gp *t = to_tg_pt_gp(item);                \
        unsigned long tmp;                                              \
        int ret;                                                        \
                                                                        \
@@ -2687,70 +2443,32 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_support_##_name(\
                return -EINVAL;                                         \
        }                                                               \
        if (tmp)                                                        \
-               t->_var |= _bit;                                        \
+               t->tg_pt_gp_alua_supported_states |= _bit;              \
        else                                                            \
-               t->_var &= ~_bit;                                       \
+               t->tg_pt_gp_alua_supported_states &= ~_bit;             \
                                                                        \
        return c;                                                       \
 }
 
-SE_DEV_ALUA_SUPPORT_STATE_SHOW(transitioning,
-                              tg_pt_gp_alua_supported_states, ALUA_T_SUP);
-SE_DEV_ALUA_SUPPORT_STATE_STORE(transitioning,
-                               tg_pt_gp_alua_supported_states, ALUA_T_SUP);
-SE_DEV_ALUA_TG_PT_ATTR(alua_support_transitioning, S_IRUGO | S_IWUSR);
-
-SE_DEV_ALUA_SUPPORT_STATE_SHOW(offline,
-                              tg_pt_gp_alua_supported_states, ALUA_O_SUP);
-SE_DEV_ALUA_SUPPORT_STATE_STORE(offline,
-                               tg_pt_gp_alua_supported_states, ALUA_O_SUP);
-SE_DEV_ALUA_TG_PT_ATTR(alua_support_offline, S_IRUGO | S_IWUSR);
-
-SE_DEV_ALUA_SUPPORT_STATE_SHOW(lba_dependent,
-                              tg_pt_gp_alua_supported_states, ALUA_LBD_SUP);
-SE_DEV_ALUA_SUPPORT_STATE_STORE(lba_dependent,
-                               tg_pt_gp_alua_supported_states, ALUA_LBD_SUP);
-SE_DEV_ALUA_TG_PT_ATTR(alua_support_lba_dependent, S_IRUGO);
-
-SE_DEV_ALUA_SUPPORT_STATE_SHOW(unavailable,
-                              tg_pt_gp_alua_supported_states, ALUA_U_SUP);
-SE_DEV_ALUA_SUPPORT_STATE_STORE(unavailable,
-                               tg_pt_gp_alua_supported_states, ALUA_U_SUP);
-SE_DEV_ALUA_TG_PT_ATTR(alua_support_unavailable, S_IRUGO | S_IWUSR);
-
-SE_DEV_ALUA_SUPPORT_STATE_SHOW(standby,
-                              tg_pt_gp_alua_supported_states, ALUA_S_SUP);
-SE_DEV_ALUA_SUPPORT_STATE_STORE(standby,
-                               tg_pt_gp_alua_supported_states, ALUA_S_SUP);
-SE_DEV_ALUA_TG_PT_ATTR(alua_support_standby, S_IRUGO | S_IWUSR);
-
-SE_DEV_ALUA_SUPPORT_STATE_SHOW(active_optimized,
-                              tg_pt_gp_alua_supported_states, ALUA_AO_SUP);
-SE_DEV_ALUA_SUPPORT_STATE_STORE(active_optimized,
-                               tg_pt_gp_alua_supported_states, ALUA_AO_SUP);
-SE_DEV_ALUA_TG_PT_ATTR(alua_support_active_optimized, S_IRUGO | S_IWUSR);
-
-SE_DEV_ALUA_SUPPORT_STATE_SHOW(active_nonoptimized,
-                              tg_pt_gp_alua_supported_states, ALUA_AN_SUP);
-SE_DEV_ALUA_SUPPORT_STATE_STORE(active_nonoptimized,
-                               tg_pt_gp_alua_supported_states, ALUA_AN_SUP);
-SE_DEV_ALUA_TG_PT_ATTR(alua_support_active_nonoptimized, S_IRUGO | S_IWUSR);
+ALUA_SUPPORTED_STATE_ATTR(transitioning, ALUA_T_SUP);
+ALUA_SUPPORTED_STATE_ATTR(offline, ALUA_O_SUP);
+ALUA_SUPPORTED_STATE_ATTR(lba_dependent, ALUA_LBD_SUP);
+ALUA_SUPPORTED_STATE_ATTR(unavailable, ALUA_U_SUP);
+ALUA_SUPPORTED_STATE_ATTR(standby, ALUA_S_SUP);
+ALUA_SUPPORTED_STATE_ATTR(active_optimized, ALUA_AO_SUP);
+ALUA_SUPPORTED_STATE_ATTR(active_nonoptimized, ALUA_AN_SUP);
 
-/*
- * alua_write_metadata
- */
-static ssize_t target_core_alua_tg_pt_gp_show_attr_alua_write_metadata(
-       struct t10_alua_tg_pt_gp *tg_pt_gp,
-       char *page)
+static ssize_t target_tg_pt_gp_alua_write_metadata_show(
+               struct config_item *item, char *page)
 {
-       return sprintf(page, "%d\n", tg_pt_gp->tg_pt_gp_write_metadata);
+       return sprintf(page, "%d\n",
+               to_tg_pt_gp(item)->tg_pt_gp_write_metadata);
 }
 
-static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_write_metadata(
-       struct t10_alua_tg_pt_gp *tg_pt_gp,
-       const char *page,
-       size_t count)
+static ssize_t target_tg_pt_gp_alua_write_metadata_store(
+               struct config_item *item, const char *page, size_t count)
 {
+       struct t10_alua_tg_pt_gp *tg_pt_gp = to_tg_pt_gp(item);
        unsigned long tmp;
        int ret;
 
@@ -2770,110 +2488,71 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_write_metadata(
        return count;
 }
 
-SE_DEV_ALUA_TG_PT_ATTR(alua_write_metadata, S_IRUGO | S_IWUSR);
-
-
-
-/*
- * nonop_delay_msecs
- */
-static ssize_t target_core_alua_tg_pt_gp_show_attr_nonop_delay_msecs(
-       struct t10_alua_tg_pt_gp *tg_pt_gp,
-       char *page)
+static ssize_t target_tg_pt_gp_nonop_delay_msecs_show(struct config_item *item,
+               char *page)
 {
-       return core_alua_show_nonop_delay_msecs(tg_pt_gp, page);
-
+       return core_alua_show_nonop_delay_msecs(to_tg_pt_gp(item), page);
 }
 
-static ssize_t target_core_alua_tg_pt_gp_store_attr_nonop_delay_msecs(
-       struct t10_alua_tg_pt_gp *tg_pt_gp,
-       const char *page,
-       size_t count)
+static ssize_t target_tg_pt_gp_nonop_delay_msecs_store(struct config_item *item,
+               const char *page, size_t count)
 {
-       return core_alua_store_nonop_delay_msecs(tg_pt_gp, page, count);
+       return core_alua_store_nonop_delay_msecs(to_tg_pt_gp(item), page,
+                       count);
 }
 
-SE_DEV_ALUA_TG_PT_ATTR(nonop_delay_msecs, S_IRUGO | S_IWUSR);
-
-/*
- * trans_delay_msecs
- */
-static ssize_t target_core_alua_tg_pt_gp_show_attr_trans_delay_msecs(
-       struct t10_alua_tg_pt_gp *tg_pt_gp,
-       char *page)
+static ssize_t target_tg_pt_gp_trans_delay_msecs_show(struct config_item *item,
+               char *page)
 {
-       return core_alua_show_trans_delay_msecs(tg_pt_gp, page);
+       return core_alua_show_trans_delay_msecs(to_tg_pt_gp(item), page);
 }
 
-static ssize_t target_core_alua_tg_pt_gp_store_attr_trans_delay_msecs(
-       struct t10_alua_tg_pt_gp *tg_pt_gp,
-       const char *page,
-       size_t count)
+static ssize_t target_tg_pt_gp_trans_delay_msecs_store(struct config_item *item,
+               const char *page, size_t count)
 {
-       return core_alua_store_trans_delay_msecs(tg_pt_gp, page, count);
+       return core_alua_store_trans_delay_msecs(to_tg_pt_gp(item), page,
+                       count);
 }
 
-SE_DEV_ALUA_TG_PT_ATTR(trans_delay_msecs, S_IRUGO | S_IWUSR);
-
-/*
- * implicit_trans_secs
- */
-static ssize_t target_core_alua_tg_pt_gp_show_attr_implicit_trans_secs(
-       struct t10_alua_tg_pt_gp *tg_pt_gp,
-       char *page)
+static ssize_t target_tg_pt_gp_implicit_trans_secs_show(
+               struct config_item *item, char *page)
 {
-       return core_alua_show_implicit_trans_secs(tg_pt_gp, page);
+       return core_alua_show_implicit_trans_secs(to_tg_pt_gp(item), page);
 }
 
-static ssize_t target_core_alua_tg_pt_gp_store_attr_implicit_trans_secs(
-       struct t10_alua_tg_pt_gp *tg_pt_gp,
-       const char *page,
-       size_t count)
+static ssize_t target_tg_pt_gp_implicit_trans_secs_store(
+               struct config_item *item, const char *page, size_t count)
 {
-       return core_alua_store_implicit_trans_secs(tg_pt_gp, page, count);
+       return core_alua_store_implicit_trans_secs(to_tg_pt_gp(item), page,
+                       count);
 }
 
-SE_DEV_ALUA_TG_PT_ATTR(implicit_trans_secs, S_IRUGO | S_IWUSR);
-
-/*
- * preferred
- */
-
-static ssize_t target_core_alua_tg_pt_gp_show_attr_preferred(
-       struct t10_alua_tg_pt_gp *tg_pt_gp,
-       char *page)
+static ssize_t target_tg_pt_gp_preferred_show(struct config_item *item,
+               char *page)
 {
-       return core_alua_show_preferred_bit(tg_pt_gp, page);
+       return core_alua_show_preferred_bit(to_tg_pt_gp(item), page);
 }
 
-static ssize_t target_core_alua_tg_pt_gp_store_attr_preferred(
-       struct t10_alua_tg_pt_gp *tg_pt_gp,
-       const char *page,
-       size_t count)
+static ssize_t target_tg_pt_gp_preferred_store(struct config_item *item,
+               const char *page, size_t count)
 {
-       return core_alua_store_preferred_bit(tg_pt_gp, page, count);
+       return core_alua_store_preferred_bit(to_tg_pt_gp(item), page, count);
 }
 
-SE_DEV_ALUA_TG_PT_ATTR(preferred, S_IRUGO | S_IWUSR);
-
-/*
- * tg_pt_gp_id
- */
-static ssize_t target_core_alua_tg_pt_gp_show_attr_tg_pt_gp_id(
-       struct t10_alua_tg_pt_gp *tg_pt_gp,
-       char *page)
+static ssize_t target_tg_pt_gp_tg_pt_gp_id_show(struct config_item *item,
+               char *page)
 {
+       struct t10_alua_tg_pt_gp *tg_pt_gp = to_tg_pt_gp(item);
+
        if (!tg_pt_gp->tg_pt_gp_valid_id)
                return 0;
-
        return sprintf(page, "%hu\n", tg_pt_gp->tg_pt_gp_id);
 }
 
-static ssize_t target_core_alua_tg_pt_gp_store_attr_tg_pt_gp_id(
-       struct t10_alua_tg_pt_gp *tg_pt_gp,
-       const char *page,
-       size_t count)
+static ssize_t target_tg_pt_gp_tg_pt_gp_id_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct t10_alua_tg_pt_gp *tg_pt_gp = to_tg_pt_gp(item);
        struct config_group *alua_tg_pt_gp_cg = &tg_pt_gp->tg_pt_gp_group;
        unsigned long tg_pt_gp_id;
        int ret;
@@ -2902,15 +2581,10 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_tg_pt_gp_id(
        return count;
 }
 
-SE_DEV_ALUA_TG_PT_ATTR(tg_pt_gp_id, S_IRUGO | S_IWUSR);
-
-/*
- * members
- */
-static ssize_t target_core_alua_tg_pt_gp_show_attr_members(
-       struct t10_alua_tg_pt_gp *tg_pt_gp,
-       char *page)
+static ssize_t target_tg_pt_gp_members_show(struct config_item *item,
+               char *page)
 {
+       struct t10_alua_tg_pt_gp *tg_pt_gp = to_tg_pt_gp(item);
        struct se_lun *lun;
        ssize_t len = 0, cur_len;
        unsigned char buf[TG_PT_GROUP_NAME_BUF];
@@ -2942,29 +2616,42 @@ static ssize_t target_core_alua_tg_pt_gp_show_attr_members(
        return len;
 }
 
-SE_DEV_ALUA_TG_PT_ATTR_RO(members);
-
-CONFIGFS_EATTR_OPS(target_core_alua_tg_pt_gp, t10_alua_tg_pt_gp,
-                       tg_pt_gp_group);
+CONFIGFS_ATTR(target_tg_pt_gp_, alua_access_state);
+CONFIGFS_ATTR(target_tg_pt_gp_, alua_access_status);
+CONFIGFS_ATTR(target_tg_pt_gp_, alua_access_type);
+CONFIGFS_ATTR(target_tg_pt_gp_, alua_support_transitioning);
+CONFIGFS_ATTR(target_tg_pt_gp_, alua_support_offline);
+CONFIGFS_ATTR(target_tg_pt_gp_, alua_support_lba_dependent);
+CONFIGFS_ATTR(target_tg_pt_gp_, alua_support_unavailable);
+CONFIGFS_ATTR(target_tg_pt_gp_, alua_support_standby);
+CONFIGFS_ATTR(target_tg_pt_gp_, alua_support_active_optimized);
+CONFIGFS_ATTR(target_tg_pt_gp_, alua_support_active_nonoptimized);
+CONFIGFS_ATTR(target_tg_pt_gp_, alua_write_metadata);
+CONFIGFS_ATTR(target_tg_pt_gp_, nonop_delay_msecs);
+CONFIGFS_ATTR(target_tg_pt_gp_, trans_delay_msecs);
+CONFIGFS_ATTR(target_tg_pt_gp_, implicit_trans_secs);
+CONFIGFS_ATTR(target_tg_pt_gp_, preferred);
+CONFIGFS_ATTR(target_tg_pt_gp_, tg_pt_gp_id);
+CONFIGFS_ATTR_RO(target_tg_pt_gp_, members);
 
 static struct configfs_attribute *target_core_alua_tg_pt_gp_attrs[] = {
-       &target_core_alua_tg_pt_gp_alua_access_state.attr,
-       &target_core_alua_tg_pt_gp_alua_access_status.attr,
-       &target_core_alua_tg_pt_gp_alua_access_type.attr,
-       &target_core_alua_tg_pt_gp_alua_support_transitioning.attr,
-       &target_core_alua_tg_pt_gp_alua_support_offline.attr,
-       &target_core_alua_tg_pt_gp_alua_support_lba_dependent.attr,
-       &target_core_alua_tg_pt_gp_alua_support_unavailable.attr,
-       &target_core_alua_tg_pt_gp_alua_support_standby.attr,
-       &target_core_alua_tg_pt_gp_alua_support_active_nonoptimized.attr,
-       &target_core_alua_tg_pt_gp_alua_support_active_optimized.attr,
-       &target_core_alua_tg_pt_gp_alua_write_metadata.attr,
-       &target_core_alua_tg_pt_gp_nonop_delay_msecs.attr,
-       &target_core_alua_tg_pt_gp_trans_delay_msecs.attr,
-       &target_core_alua_tg_pt_gp_implicit_trans_secs.attr,
-       &target_core_alua_tg_pt_gp_preferred.attr,
-       &target_core_alua_tg_pt_gp_tg_pt_gp_id.attr,
-       &target_core_alua_tg_pt_gp_members.attr,
+       &target_tg_pt_gp_attr_alua_access_state,
+       &target_tg_pt_gp_attr_alua_access_status,
+       &target_tg_pt_gp_attr_alua_access_type,
+       &target_tg_pt_gp_attr_alua_support_transitioning,
+       &target_tg_pt_gp_attr_alua_support_offline,
+       &target_tg_pt_gp_attr_alua_support_lba_dependent,
+       &target_tg_pt_gp_attr_alua_support_unavailable,
+       &target_tg_pt_gp_attr_alua_support_standby,
+       &target_tg_pt_gp_attr_alua_support_active_nonoptimized,
+       &target_tg_pt_gp_attr_alua_support_active_optimized,
+       &target_tg_pt_gp_attr_alua_write_metadata,
+       &target_tg_pt_gp_attr_nonop_delay_msecs,
+       &target_tg_pt_gp_attr_trans_delay_msecs,
+       &target_tg_pt_gp_attr_implicit_trans_secs,
+       &target_tg_pt_gp_attr_preferred,
+       &target_tg_pt_gp_attr_tg_pt_gp_id,
+       &target_tg_pt_gp_attr_members,
        NULL,
 };
 
@@ -2978,8 +2665,6 @@ static void target_core_alua_tg_pt_gp_release(struct config_item *item)
 
 static struct configfs_item_operations target_core_alua_tg_pt_gp_ops = {
        .release                = target_core_alua_tg_pt_gp_release,
-       .show_attribute         = target_core_alua_tg_pt_gp_attr_show,
-       .store_attribute        = target_core_alua_tg_pt_gp_attr_store,
 };
 
 static struct config_item_type target_core_alua_tg_pt_gp_cit = {
@@ -3237,34 +2922,24 @@ static struct configfs_group_operations target_core_hba_group_ops = {
        .drop_item              = target_core_drop_subdev,
 };
 
-CONFIGFS_EATTR_STRUCT(target_core_hba, se_hba);
-#define SE_HBA_ATTR(_name, _mode)                              \
-static struct target_core_hba_attribute                                \
-               target_core_hba_##_name =                       \
-               __CONFIGFS_EATTR(_name, _mode,                  \
-               target_core_hba_show_attr_##_name,              \
-               target_core_hba_store_attr_##_name);
 
-#define SE_HBA_ATTR_RO(_name)                                  \
-static struct target_core_hba_attribute                                \
-               target_core_hba_##_name =                       \
-               __CONFIGFS_EATTR_RO(_name,                      \
-               target_core_hba_show_attr_##_name);
+static inline struct se_hba *to_hba(struct config_item *item)
+{
+       return container_of(to_config_group(item), struct se_hba, hba_group);
+}
 
-static ssize_t target_core_hba_show_attr_hba_info(
-       struct se_hba *hba,
-       char *page)
+static ssize_t target_hba_info_show(struct config_item *item, char *page)
 {
+       struct se_hba *hba = to_hba(item);
+
        return sprintf(page, "HBA Index: %d plugin: %s version: %s\n",
                        hba->hba_id, hba->backend->ops->name,
                        TARGET_CORE_VERSION);
 }
 
-SE_HBA_ATTR_RO(hba_info);
-
-static ssize_t target_core_hba_show_attr_hba_mode(struct se_hba *hba,
-                               char *page)
+static ssize_t target_hba_mode_show(struct config_item *item, char *page)
 {
+       struct se_hba *hba = to_hba(item);
        int hba_mode = 0;
 
        if (hba->hba_flags & HBA_FLAGS_PSCSI_MODE)
@@ -3273,9 +2948,10 @@ static ssize_t target_core_hba_show_attr_hba_mode(struct se_hba *hba,
        return sprintf(page, "%d\n", hba_mode);
 }
 
-static ssize_t target_core_hba_store_attr_hba_mode(struct se_hba *hba,
-                               const char *page, size_t count)
+static ssize_t target_hba_mode_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct se_hba *hba = to_hba(item);
        unsigned long mode_flag;
        int ret;
 
@@ -3304,9 +2980,8 @@ static ssize_t target_core_hba_store_attr_hba_mode(struct se_hba *hba,
        return count;
 }
 
-SE_HBA_ATTR(hba_mode, S_IRUGO | S_IWUSR);
-
-CONFIGFS_EATTR_OPS(target_core_hba, se_hba, hba_group);
+CONFIGFS_ATTR_RO(target_, hba_info);
+CONFIGFS_ATTR(target_, hba_mode);
 
 static void target_core_hba_release(struct config_item *item)
 {
@@ -3316,15 +2991,13 @@ static void target_core_hba_release(struct config_item *item)
 }
 
 static struct configfs_attribute *target_core_hba_attrs[] = {
-       &target_core_hba_hba_info.attr,
-       &target_core_hba_hba_mode.attr,
+       &target_attr_hba_info,
+       &target_attr_hba_mode,
        NULL,
 };
 
 static struct configfs_item_operations target_core_hba_item_ops = {
        .release                = target_core_hba_release,
-       .show_attribute         = target_core_hba_attr_show,
-       .store_attribute        = target_core_hba_attr_store,
 };
 
 static struct config_item_type target_core_hba_cit = {
index be42429468e2505833f0578eea2cf5a81a4f9ee0..f916d18ccb487c0910ec79ec3f0d8dda232a7b30 100644 (file)
@@ -35,8 +35,6 @@
 
 #include <target/target_core_base.h>
 #include <target/target_core_fabric.h>
-#include <target/target_core_fabric_configfs.h>
-#include <target/configfs_macros.h>
 
 #include "target_core_internal.h"
 #include "target_core_alua.h"
@@ -152,17 +150,16 @@ static int target_fabric_mappedlun_unlink(
        return core_dev_del_initiator_node_lun_acl(lun, lacl);
 }
 
-CONFIGFS_EATTR_STRUCT(target_fabric_mappedlun, se_lun_acl);
-#define TCM_MAPPEDLUN_ATTR(_name, _mode)                               \
-static struct target_fabric_mappedlun_attribute target_fabric_mappedlun_##_name = \
-       __CONFIGFS_EATTR(_name, _mode,                                  \
-       target_fabric_mappedlun_show_##_name,                           \
-       target_fabric_mappedlun_store_##_name);
+static struct se_lun_acl *item_to_lun_acl(struct config_item *item)
+{
+       return container_of(to_config_group(item), struct se_lun_acl,
+                       se_lun_group);
+}
 
-static ssize_t target_fabric_mappedlun_show_write_protect(
-       struct se_lun_acl *lacl,
-       char *page)
+static ssize_t target_fabric_mappedlun_write_protect_show(
+               struct config_item *item, char *page)
 {
+       struct se_lun_acl *lacl = item_to_lun_acl(item);
        struct se_node_acl *se_nacl = lacl->se_lun_nacl;
        struct se_dev_entry *deve;
        ssize_t len = 0;
@@ -178,11 +175,10 @@ static ssize_t target_fabric_mappedlun_show_write_protect(
        return len;
 }
 
-static ssize_t target_fabric_mappedlun_store_write_protect(
-       struct se_lun_acl *lacl,
-       const char *page,
-       size_t count)
+static ssize_t target_fabric_mappedlun_write_protect_store(
+               struct config_item *item, const char *page, size_t count)
 {
+       struct se_lun_acl *lacl = item_to_lun_acl(item);
        struct se_node_acl *se_nacl = lacl->se_lun_nacl;
        struct se_portal_group *se_tpg = se_nacl->se_tpg;
        unsigned long op;
@@ -209,9 +205,12 @@ static ssize_t target_fabric_mappedlun_store_write_protect(
 
 }
 
-TCM_MAPPEDLUN_ATTR(write_protect, S_IRUGO | S_IWUSR);
+CONFIGFS_ATTR(target_fabric_mappedlun_, write_protect);
 
-CONFIGFS_EATTR_OPS(target_fabric_mappedlun, se_lun_acl, se_lun_group);
+static struct configfs_attribute *target_fabric_mappedlun_attrs[] = {
+       &target_fabric_mappedlun_attr_write_protect,
+       NULL,
+};
 
 static void target_fabric_mappedlun_release(struct config_item *item)
 {
@@ -222,15 +221,8 @@ static void target_fabric_mappedlun_release(struct config_item *item)
        core_dev_free_initiator_node_lun_acl(se_tpg, lacl);
 }
 
-static struct configfs_attribute *target_fabric_mappedlun_attrs[] = {
-       &target_fabric_mappedlun_write_protect.attr,
-       NULL,
-};
-
 static struct configfs_item_operations target_fabric_mappedlun_item_ops = {
        .release                = target_fabric_mappedlun_release,
-       .show_attribute         = target_fabric_mappedlun_attr_show,
-       .store_attribute        = target_fabric_mappedlun_attr_store,
        .allow_link             = target_fabric_mappedlun_link,
        .drop_link              = target_fabric_mappedlun_unlink,
 };
@@ -266,49 +258,12 @@ TF_CIT_SETUP(tpg_mappedlun_stat, NULL, &target_fabric_mappedlun_stat_group_ops,
 
 /* End of tfc_tpg_mappedlun_port_cit */
 
-/* Start of tfc_tpg_nacl_attrib_cit */
-
-CONFIGFS_EATTR_OPS(target_fabric_nacl_attrib, se_node_acl, acl_attrib_group);
-
-static struct configfs_item_operations target_fabric_nacl_attrib_item_ops = {
-       .show_attribute         = target_fabric_nacl_attrib_attr_show,
-       .store_attribute        = target_fabric_nacl_attrib_attr_store,
-};
-
-TF_CIT_SETUP_DRV(tpg_nacl_attrib, &target_fabric_nacl_attrib_item_ops, NULL);
-
-/* End of tfc_tpg_nacl_attrib_cit */
-
-/* Start of tfc_tpg_nacl_auth_cit */
-
-CONFIGFS_EATTR_OPS(target_fabric_nacl_auth, se_node_acl, acl_auth_group);
-
-static struct configfs_item_operations target_fabric_nacl_auth_item_ops = {
-       .show_attribute         = target_fabric_nacl_auth_attr_show,
-       .store_attribute        = target_fabric_nacl_auth_attr_store,
-};
-
-TF_CIT_SETUP_DRV(tpg_nacl_auth, &target_fabric_nacl_auth_item_ops, NULL);
-
-/* End of tfc_tpg_nacl_auth_cit */
-
-/* Start of tfc_tpg_nacl_param_cit */
-
-CONFIGFS_EATTR_OPS(target_fabric_nacl_param, se_node_acl, acl_param_group);
-
-static struct configfs_item_operations target_fabric_nacl_param_item_ops = {
-       .show_attribute         = target_fabric_nacl_param_attr_show,
-       .store_attribute        = target_fabric_nacl_param_attr_store,
-};
-
-TF_CIT_SETUP_DRV(tpg_nacl_param, &target_fabric_nacl_param_item_ops, NULL);
-
-/* End of tfc_tpg_nacl_param_cit */
+TF_CIT_SETUP_DRV(tpg_nacl_attrib, NULL, NULL);
+TF_CIT_SETUP_DRV(tpg_nacl_auth, NULL, NULL);
+TF_CIT_SETUP_DRV(tpg_nacl_param, NULL, NULL);
 
 /* Start of tfc_tpg_nacl_base_cit */
 
-CONFIGFS_EATTR_OPS(target_fabric_nacl_base, se_node_acl, acl_group);
-
 static struct config_group *target_fabric_make_mappedlun(
        struct config_group *group,
        const char *name)
@@ -438,8 +393,6 @@ static void target_fabric_nacl_base_release(struct config_item *item)
 
 static struct configfs_item_operations target_fabric_nacl_base_item_ops = {
        .release                = target_fabric_nacl_base_release,
-       .show_attribute         = target_fabric_nacl_base_attr_show,
-       .store_attribute        = target_fabric_nacl_base_attr_store,
 };
 
 static struct configfs_group_operations target_fabric_nacl_base_group_ops = {
@@ -540,8 +493,6 @@ TF_CIT_SETUP(tpg_nacl, NULL, &target_fabric_nacl_group_ops, NULL);
 
 /* Start of tfc_tpg_np_base_cit */
 
-CONFIGFS_EATTR_OPS(target_fabric_np_base, se_tpg_np, tpg_np_group);
-
 static void target_fabric_np_base_release(struct config_item *item)
 {
        struct se_tpg_np *se_tpg_np = container_of(to_config_group(item),
@@ -554,8 +505,6 @@ static void target_fabric_np_base_release(struct config_item *item)
 
 static struct configfs_item_operations target_fabric_np_base_item_ops = {
        .release                = target_fabric_np_base_release,
-       .show_attribute         = target_fabric_np_base_attr_show,
-       .store_attribute        = target_fabric_np_base_attr_store,
 };
 
 TF_CIT_SETUP_DRV(tpg_np_base, &target_fabric_np_base_item_ops, NULL);
@@ -610,132 +559,113 @@ TF_CIT_SETUP(tpg_np, NULL, &target_fabric_np_group_ops, NULL);
 
 /* Start of tfc_tpg_port_cit */
 
-CONFIGFS_EATTR_STRUCT(target_fabric_port, se_lun);
-#define TCM_PORT_ATTR(_name, _mode)                                    \
-static struct target_fabric_port_attribute target_fabric_port_##_name =        \
-       __CONFIGFS_EATTR(_name, _mode,                                  \
-       target_fabric_port_show_attr_##_name,                           \
-       target_fabric_port_store_attr_##_name);
-
-#define TCM_PORT_ATTOR_RO(_name)                                       \
-       __CONFIGFS_EATTR_RO(_name,                                      \
-       target_fabric_port_show_attr_##_name);
+static struct se_lun *item_to_lun(struct config_item *item)
+{
+       return container_of(to_config_group(item), struct se_lun,
+                       lun_group);
+}
 
-/*
- * alua_tg_pt_gp
- */
-static ssize_t target_fabric_port_show_attr_alua_tg_pt_gp(
-       struct se_lun *lun,
-       char *page)
+static ssize_t target_fabric_port_alua_tg_pt_gp_show(struct config_item *item,
+               char *page)
 {
+       struct se_lun *lun = item_to_lun(item);
+
        if (!lun || !lun->lun_se_dev)
                return -ENODEV;
 
        return core_alua_show_tg_pt_gp_info(lun, page);
 }
 
-static ssize_t target_fabric_port_store_attr_alua_tg_pt_gp(
-       struct se_lun *lun,
-       const char *page,
-       size_t count)
+static ssize_t target_fabric_port_alua_tg_pt_gp_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct se_lun *lun = item_to_lun(item);
+
        if (!lun || !lun->lun_se_dev)
                return -ENODEV;
 
        return core_alua_store_tg_pt_gp_info(lun, page, count);
 }
 
-TCM_PORT_ATTR(alua_tg_pt_gp, S_IRUGO | S_IWUSR);
-
-/*
- * alua_tg_pt_offline
- */
-static ssize_t target_fabric_port_show_attr_alua_tg_pt_offline(
-       struct se_lun *lun,
-       char *page)
+static ssize_t target_fabric_port_alua_tg_pt_offline_show(
+               struct config_item *item, char *page)
 {
+       struct se_lun *lun = item_to_lun(item);
+
        if (!lun || !lun->lun_se_dev)
                return -ENODEV;
 
        return core_alua_show_offline_bit(lun, page);
 }
 
-static ssize_t target_fabric_port_store_attr_alua_tg_pt_offline(
-       struct se_lun *lun,
-       const char *page,
-       size_t count)
+static ssize_t target_fabric_port_alua_tg_pt_offline_store(
+               struct config_item *item, const char *page, size_t count)
 {
+       struct se_lun *lun = item_to_lun(item);
+
        if (!lun || !lun->lun_se_dev)
                return -ENODEV;
 
        return core_alua_store_offline_bit(lun, page, count);
 }
 
-TCM_PORT_ATTR(alua_tg_pt_offline, S_IRUGO | S_IWUSR);
-
-/*
- * alua_tg_pt_status
- */
-static ssize_t target_fabric_port_show_attr_alua_tg_pt_status(
-       struct se_lun *lun,
-       char *page)
+static ssize_t target_fabric_port_alua_tg_pt_status_show(
+               struct config_item *item, char *page)
 {
+       struct se_lun *lun = item_to_lun(item);
+
        if (!lun || !lun->lun_se_dev)
                return -ENODEV;
 
        return core_alua_show_secondary_status(lun, page);
 }
 
-static ssize_t target_fabric_port_store_attr_alua_tg_pt_status(
-       struct se_lun *lun,
-       const char *page,
-       size_t count)
+static ssize_t target_fabric_port_alua_tg_pt_status_store(
+               struct config_item *item, const char *page, size_t count)
 {
+       struct se_lun *lun = item_to_lun(item);
+
        if (!lun || !lun->lun_se_dev)
                return -ENODEV;
 
        return core_alua_store_secondary_status(lun, page, count);
 }
 
-TCM_PORT_ATTR(alua_tg_pt_status, S_IRUGO | S_IWUSR);
-
-/*
- * alua_tg_pt_write_md
- */
-static ssize_t target_fabric_port_show_attr_alua_tg_pt_write_md(
-       struct se_lun *lun,
-       char *page)
+static ssize_t target_fabric_port_alua_tg_pt_write_md_show(
+               struct config_item *item, char *page)
 {
+       struct se_lun *lun = item_to_lun(item);
+
        if (!lun || !lun->lun_se_dev)
                return -ENODEV;
 
        return core_alua_show_secondary_write_metadata(lun, page);
 }
 
-static ssize_t target_fabric_port_store_attr_alua_tg_pt_write_md(
-       struct se_lun *lun,
-       const char *page,
-       size_t count)
+static ssize_t target_fabric_port_alua_tg_pt_write_md_store(
+               struct config_item *item, const char *page, size_t count)
 {
+       struct se_lun *lun = item_to_lun(item);
+
        if (!lun || !lun->lun_se_dev)
                return -ENODEV;
 
        return core_alua_store_secondary_write_metadata(lun, page, count);
 }
 
-TCM_PORT_ATTR(alua_tg_pt_write_md, S_IRUGO | S_IWUSR);
-
+CONFIGFS_ATTR(target_fabric_port_, alua_tg_pt_gp);
+CONFIGFS_ATTR(target_fabric_port_, alua_tg_pt_offline);
+CONFIGFS_ATTR(target_fabric_port_, alua_tg_pt_status);
+CONFIGFS_ATTR(target_fabric_port_, alua_tg_pt_write_md);
 
 static struct configfs_attribute *target_fabric_port_attrs[] = {
-       &target_fabric_port_alua_tg_pt_gp.attr,
-       &target_fabric_port_alua_tg_pt_offline.attr,
-       &target_fabric_port_alua_tg_pt_status.attr,
-       &target_fabric_port_alua_tg_pt_write_md.attr,
+       &target_fabric_port_attr_alua_tg_pt_gp,
+       &target_fabric_port_attr_alua_tg_pt_offline,
+       &target_fabric_port_attr_alua_tg_pt_status,
+       &target_fabric_port_attr_alua_tg_pt_write_md,
        NULL,
 };
 
-CONFIGFS_EATTR_OPS(target_fabric_port, se_lun, lun_group);
-
 static int target_fabric_port_link(
        struct config_item *lun_ci,
        struct config_item *se_dev_ci)
@@ -821,8 +751,6 @@ static void target_fabric_port_release(struct config_item *item)
 }
 
 static struct configfs_item_operations target_fabric_port_item_ops = {
-       .show_attribute         = target_fabric_port_attr_show,
-       .store_attribute        = target_fabric_port_attr_store,
        .release                = target_fabric_port_release,
        .allow_link             = target_fabric_port_link,
        .drop_link              = target_fabric_port_unlink,
@@ -952,50 +880,11 @@ TF_CIT_SETUP(tpg_lun, NULL, &target_fabric_lun_group_ops, NULL);
 
 /* End of tfc_tpg_lun_cit */
 
-/* Start of tfc_tpg_attrib_cit */
-
-CONFIGFS_EATTR_OPS(target_fabric_tpg_attrib, se_portal_group, tpg_attrib_group);
-
-static struct configfs_item_operations target_fabric_tpg_attrib_item_ops = {
-       .show_attribute         = target_fabric_tpg_attrib_attr_show,
-       .store_attribute        = target_fabric_tpg_attrib_attr_store,
-};
-
-TF_CIT_SETUP_DRV(tpg_attrib, &target_fabric_tpg_attrib_item_ops, NULL);
-
-/* End of tfc_tpg_attrib_cit */
-
-/* Start of tfc_tpg_auth_cit */
-
-CONFIGFS_EATTR_OPS(target_fabric_tpg_auth, se_portal_group, tpg_auth_group);
-
-static struct configfs_item_operations target_fabric_tpg_auth_item_ops = {
-       .show_attribute         = target_fabric_tpg_auth_attr_show,
-       .store_attribute        = target_fabric_tpg_auth_attr_store,
-};
-
-TF_CIT_SETUP_DRV(tpg_auth, &target_fabric_tpg_auth_item_ops, NULL);
-
-/* End of tfc_tpg_attrib_cit */
-
-/* Start of tfc_tpg_param_cit */
-
-CONFIGFS_EATTR_OPS(target_fabric_tpg_param, se_portal_group, tpg_param_group);
-
-static struct configfs_item_operations target_fabric_tpg_param_item_ops = {
-       .show_attribute         = target_fabric_tpg_param_attr_show,
-       .store_attribute        = target_fabric_tpg_param_attr_store,
-};
-
-TF_CIT_SETUP_DRV(tpg_param, &target_fabric_tpg_param_item_ops, NULL);
-
-/* End of tfc_tpg_param_cit */
+TF_CIT_SETUP_DRV(tpg_attrib, NULL, NULL);
+TF_CIT_SETUP_DRV(tpg_auth, NULL, NULL);
+TF_CIT_SETUP_DRV(tpg_param, NULL, NULL);
 
 /* Start of tfc_tpg_base_cit */
-/*
- * For use with TF_TPG_ATTR() and TF_TPG_ATTR_RO()
- */
-CONFIGFS_EATTR_OPS(target_fabric_tpg, se_portal_group, tpg_group);
 
 static void target_fabric_tpg_release(struct config_item *item)
 {
@@ -1009,8 +898,6 @@ static void target_fabric_tpg_release(struct config_item *item)
 
 static struct configfs_item_operations target_fabric_tpg_base_item_ops = {
        .release                = target_fabric_tpg_release,
-       .show_attribute         = target_fabric_tpg_attr_show,
-       .store_attribute        = target_fabric_tpg_attr_store,
 };
 
 TF_CIT_SETUP_DRV(tpg_base, &target_fabric_tpg_base_item_ops, NULL);
@@ -1176,33 +1063,9 @@ static struct configfs_group_operations target_fabric_wwn_group_ops = {
        .make_group     = target_fabric_make_wwn,
        .drop_item      = target_fabric_drop_wwn,
 };
-/*
- * For use with TF_WWN_ATTR() and TF_WWN_ATTR_RO()
- */
-CONFIGFS_EATTR_OPS(target_fabric_wwn, target_fabric_configfs, tf_group);
-
-static struct configfs_item_operations target_fabric_wwn_item_ops = {
-       .show_attribute         = target_fabric_wwn_attr_show,
-       .store_attribute        = target_fabric_wwn_attr_store,
-};
-
-TF_CIT_SETUP_DRV(wwn, &target_fabric_wwn_item_ops, &target_fabric_wwn_group_ops);
-
-/* End of tfc_wwn_cit */
-
-/* Start of tfc_discovery_cit */
-
-CONFIGFS_EATTR_OPS(target_fabric_discovery, target_fabric_configfs,
-               tf_disc_group);
-
-static struct configfs_item_operations target_fabric_discovery_item_ops = {
-       .show_attribute         = target_fabric_discovery_attr_show,
-       .store_attribute        = target_fabric_discovery_attr_store,
-};
-
-TF_CIT_SETUP_DRV(discovery, &target_fabric_discovery_item_ops, NULL);
 
-/* End of tfc_discovery_cit */
+TF_CIT_SETUP_DRV(wwn, NULL, &target_fabric_wwn_group_ops);
+TF_CIT_SETUP_DRV(discovery, NULL, NULL);
 
 int target_fabric_setup_cits(struct target_fabric_configfs *tf)
 {
index 99c24acfe6761797fc9788f4f233d1c8c94a0e1d..dae0750c2032bd87430ab99609d475a615e691db 100644 (file)
@@ -87,6 +87,9 @@ void  target_free_device(struct se_device *);
 /* target_core_configfs.c */
 void   target_setup_backend_cits(struct target_backend *);
 
+/* target_core_fabric_configfs.c */
+int    target_fabric_setup_cits(struct target_fabric_configfs *);
+
 /* target_core_fabric_lib.c */
 int    target_get_pr_transport_id_len(struct se_node_acl *nacl,
                struct t10_pr_registration *pr_reg, int *format_code);
index 20ed5d2e151a6f50211273967e2cc107ba2b5bce..273c72b2b83dc016b2a317b778a8c391eebcb9c8 100644 (file)
@@ -37,7 +37,6 @@
 #include <target/target_core_base.h>
 #include <target/target_core_backend.h>
 #include <target/target_core_fabric.h>
-#include <target/configfs_macros.h>
 
 #include "target_core_internal.h"
 
  * SCSI Device Table
  */
 
-CONFIGFS_EATTR_STRUCT(target_stat_scsi_dev, se_dev_stat_grps);
-#define DEV_STAT_SCSI_DEV_ATTR(_name, _mode)                           \
-static struct target_stat_scsi_dev_attribute                           \
-                       target_stat_scsi_dev_##_name =                  \
-       __CONFIGFS_EATTR(_name, _mode,                                  \
-       target_stat_scsi_dev_show_attr_##_name,                         \
-       target_stat_scsi_dev_store_attr_##_name);
-
-#define DEV_STAT_SCSI_DEV_ATTR_RO(_name)                               \
-static struct target_stat_scsi_dev_attribute                           \
-                       target_stat_scsi_dev_##_name =                  \
-       __CONFIGFS_EATTR_RO(_name,                                      \
-       target_stat_scsi_dev_show_attr_##_name);
+static struct se_device *to_stat_dev(struct config_item *item)
+{
+       struct se_dev_stat_grps *sgrps = container_of(to_config_group(item),
+                       struct se_dev_stat_grps, scsi_dev_group);
+       return container_of(sgrps, struct se_device, dev_stat_grps);
+}
 
-static ssize_t target_stat_scsi_dev_show_attr_inst(
-       struct se_dev_stat_grps *sgrps, char *page)
+static ssize_t target_stat_inst_show(struct config_item *item, char *page)
 {
-       struct se_device *dev =
-               container_of(sgrps, struct se_device, dev_stat_grps);
-       struct se_hba *hba = dev->se_hba;
+       struct se_hba *hba = to_stat_dev(item)->se_hba;
 
        return snprintf(page, PAGE_SIZE, "%u\n", hba->hba_index);
 }
-DEV_STAT_SCSI_DEV_ATTR_RO(inst);
 
-static ssize_t target_stat_scsi_dev_show_attr_indx(
-       struct se_dev_stat_grps *sgrps, char *page)
+static ssize_t target_stat_indx_show(struct config_item *item, char *page)
 {
-       struct se_device *dev =
-               container_of(sgrps, struct se_device, dev_stat_grps);
-
-       return snprintf(page, PAGE_SIZE, "%u\n", dev->dev_index);
+       return snprintf(page, PAGE_SIZE, "%u\n", to_stat_dev(item)->dev_index);
 }
-DEV_STAT_SCSI_DEV_ATTR_RO(indx);
 
-static ssize_t target_stat_scsi_dev_show_attr_role(
-       struct se_dev_stat_grps *sgrps, char *page)
+static ssize_t target_stat_role_show(struct config_item *item, char *page)
 {
        return snprintf(page, PAGE_SIZE, "Target\n");
 }
-DEV_STAT_SCSI_DEV_ATTR_RO(role);
 
-static ssize_t target_stat_scsi_dev_show_attr_ports(
-       struct se_dev_stat_grps *sgrps, char *page)
+static ssize_t target_stat_ports_show(struct config_item *item, char *page)
 {
-       struct se_device *dev =
-               container_of(sgrps, struct se_device, dev_stat_grps);
-
-       return snprintf(page, PAGE_SIZE, "%u\n", dev->export_count);
+       return snprintf(page, PAGE_SIZE, "%u\n", to_stat_dev(item)->export_count);
 }
-DEV_STAT_SCSI_DEV_ATTR_RO(ports);
 
-CONFIGFS_EATTR_OPS(target_stat_scsi_dev, se_dev_stat_grps, scsi_dev_group);
+CONFIGFS_ATTR_RO(target_stat_, inst);
+CONFIGFS_ATTR_RO(target_stat_, indx);
+CONFIGFS_ATTR_RO(target_stat_, role);
+CONFIGFS_ATTR_RO(target_stat_, ports);
 
 static struct configfs_attribute *target_stat_scsi_dev_attrs[] = {
-       &target_stat_scsi_dev_inst.attr,
-       &target_stat_scsi_dev_indx.attr,
-       &target_stat_scsi_dev_role.attr,
-       &target_stat_scsi_dev_ports.attr,
+       &target_stat_attr_inst,
+       &target_stat_attr_indx,
+       &target_stat_attr_role,
+       &target_stat_attr_ports,
        NULL,
 };
 
-static struct configfs_item_operations target_stat_scsi_dev_attrib_ops = {
-       .show_attribute         = target_stat_scsi_dev_attr_show,
-       .store_attribute        = target_stat_scsi_dev_attr_store,
-};
-
 static struct config_item_type target_stat_scsi_dev_cit = {
-       .ct_item_ops            = &target_stat_scsi_dev_attrib_ops,
        .ct_attrs               = target_stat_scsi_dev_attrs,
        .ct_owner               = THIS_MODULE,
 };
@@ -131,109 +104,78 @@ static struct config_item_type target_stat_scsi_dev_cit = {
 /*
  * SCSI Target Device Table
  */
+static struct se_device *to_stat_tgt_dev(struct config_item *item)
+{
+       struct se_dev_stat_grps *sgrps = container_of(to_config_group(item),
+                       struct se_dev_stat_grps, scsi_tgt_dev_group);
+       return container_of(sgrps, struct se_device, dev_stat_grps);
+}
 
-CONFIGFS_EATTR_STRUCT(target_stat_scsi_tgt_dev, se_dev_stat_grps);
-#define DEV_STAT_SCSI_TGT_DEV_ATTR(_name, _mode)                       \
-static struct target_stat_scsi_tgt_dev_attribute                       \
-                       target_stat_scsi_tgt_dev_##_name =              \
-       __CONFIGFS_EATTR(_name, _mode,                                  \
-       target_stat_scsi_tgt_dev_show_attr_##_name,                     \
-       target_stat_scsi_tgt_dev_store_attr_##_name);
-
-#define DEV_STAT_SCSI_TGT_DEV_ATTR_RO(_name)                           \
-static struct target_stat_scsi_tgt_dev_attribute                       \
-                       target_stat_scsi_tgt_dev_##_name =              \
-       __CONFIGFS_EATTR_RO(_name,                                      \
-       target_stat_scsi_tgt_dev_show_attr_##_name);
-
-static ssize_t target_stat_scsi_tgt_dev_show_attr_inst(
-       struct se_dev_stat_grps *sgrps, char *page)
+static ssize_t target_stat_tgt_inst_show(struct config_item *item, char *page)
 {
-       struct se_device *dev =
-               container_of(sgrps, struct se_device, dev_stat_grps);
-       struct se_hba *hba = dev->se_hba;
+       struct se_hba *hba = to_stat_tgt_dev(item)->se_hba;
 
        return snprintf(page, PAGE_SIZE, "%u\n", hba->hba_index);
 }
-DEV_STAT_SCSI_TGT_DEV_ATTR_RO(inst);
 
-static ssize_t target_stat_scsi_tgt_dev_show_attr_indx(
-       struct se_dev_stat_grps *sgrps, char *page)
+static ssize_t target_stat_tgt_indx_show(struct config_item *item, char *page)
 {
-       struct se_device *dev =
-               container_of(sgrps, struct se_device, dev_stat_grps);
-
-       return snprintf(page, PAGE_SIZE, "%u\n", dev->dev_index);
+       return snprintf(page, PAGE_SIZE, "%u\n", to_stat_tgt_dev(item)->dev_index);
 }
-DEV_STAT_SCSI_TGT_DEV_ATTR_RO(indx);
 
-static ssize_t target_stat_scsi_tgt_dev_show_attr_num_lus(
-       struct se_dev_stat_grps *sgrps, char *page)
+static ssize_t target_stat_tgt_num_lus_show(struct config_item *item,
+               char *page)
 {
        return snprintf(page, PAGE_SIZE, "%u\n", LU_COUNT);
 }
-DEV_STAT_SCSI_TGT_DEV_ATTR_RO(num_lus);
 
-static ssize_t target_stat_scsi_tgt_dev_show_attr_status(
-       struct se_dev_stat_grps *sgrps, char *page)
+static ssize_t target_stat_tgt_status_show(struct config_item *item,
+               char *page)
 {
-       struct se_device *dev =
-               container_of(sgrps, struct se_device, dev_stat_grps);
-
-       if (dev->export_count)
+       if (to_stat_tgt_dev(item)->export_count)
                return snprintf(page, PAGE_SIZE, "activated");
        else
                return snprintf(page, PAGE_SIZE, "deactivated");
 }
-DEV_STAT_SCSI_TGT_DEV_ATTR_RO(status);
 
-static ssize_t target_stat_scsi_tgt_dev_show_attr_non_access_lus(
-       struct se_dev_stat_grps *sgrps, char *page)
+static ssize_t target_stat_tgt_non_access_lus_show(struct config_item *item,
+               char *page)
 {
-       struct se_device *dev =
-               container_of(sgrps, struct se_device, dev_stat_grps);
        int non_accessible_lus;
 
-       if (dev->export_count)
+       if (to_stat_tgt_dev(item)->export_count)
                non_accessible_lus = 0;
        else
                non_accessible_lus = 1;
 
        return snprintf(page, PAGE_SIZE, "%u\n", non_accessible_lus);
 }
-DEV_STAT_SCSI_TGT_DEV_ATTR_RO(non_access_lus);
 
-static ssize_t target_stat_scsi_tgt_dev_show_attr_resets(
-       struct se_dev_stat_grps *sgrps, char *page)
+static ssize_t target_stat_tgt_resets_show(struct config_item *item,
+               char *page)
 {
-       struct se_device *dev =
-               container_of(sgrps, struct se_device, dev_stat_grps);
-
        return snprintf(page, PAGE_SIZE, "%lu\n",
-                       atomic_long_read(&dev->num_resets));
+                       atomic_long_read(&to_stat_tgt_dev(item)->num_resets));
 }
-DEV_STAT_SCSI_TGT_DEV_ATTR_RO(resets);
 
-
-CONFIGFS_EATTR_OPS(target_stat_scsi_tgt_dev, se_dev_stat_grps, scsi_tgt_dev_group);
+CONFIGFS_ATTR_RO(target_stat_tgt_, inst);
+CONFIGFS_ATTR_RO(target_stat_tgt_, indx);
+CONFIGFS_ATTR_RO(target_stat_tgt_, num_lus);
+CONFIGFS_ATTR_RO(target_stat_tgt_, status);
+CONFIGFS_ATTR_RO(target_stat_tgt_, non_access_lus);
+CONFIGFS_ATTR_RO(target_stat_tgt_, resets);
 
 static struct configfs_attribute *target_stat_scsi_tgt_dev_attrs[] = {
-       &target_stat_scsi_tgt_dev_inst.attr,
-       &target_stat_scsi_tgt_dev_indx.attr,
-       &target_stat_scsi_tgt_dev_num_lus.attr,
-       &target_stat_scsi_tgt_dev_status.attr,
-       &target_stat_scsi_tgt_dev_non_access_lus.attr,
-       &target_stat_scsi_tgt_dev_resets.attr,
+       &target_stat_tgt_attr_inst,
+       &target_stat_tgt_attr_indx,
+       &target_stat_tgt_attr_num_lus,
+       &target_stat_tgt_attr_status,
+       &target_stat_tgt_attr_non_access_lus,
+       &target_stat_tgt_attr_resets,
        NULL,
 };
 
-static struct configfs_item_operations target_stat_scsi_tgt_dev_attrib_ops = {
-       .show_attribute         = target_stat_scsi_tgt_dev_attr_show,
-       .store_attribute        = target_stat_scsi_tgt_dev_attr_store,
-};
-
 static struct config_item_type target_stat_scsi_tgt_dev_cit = {
-       .ct_item_ops            = &target_stat_scsi_tgt_dev_attrib_ops,
        .ct_attrs               = target_stat_scsi_tgt_dev_attrs,
        .ct_owner               = THIS_MODULE,
 };
@@ -242,72 +184,50 @@ static struct config_item_type target_stat_scsi_tgt_dev_cit = {
  * SCSI Logical Unit Table
  */
 
-CONFIGFS_EATTR_STRUCT(target_stat_scsi_lu, se_dev_stat_grps);
-#define DEV_STAT_SCSI_LU_ATTR(_name, _mode)                            \
-static struct target_stat_scsi_lu_attribute target_stat_scsi_lu_##_name = \
-       __CONFIGFS_EATTR(_name, _mode,                                  \
-       target_stat_scsi_lu_show_attr_##_name,                          \
-       target_stat_scsi_lu_store_attr_##_name);
-
-#define DEV_STAT_SCSI_LU_ATTR_RO(_name)                                        \
-static struct target_stat_scsi_lu_attribute target_stat_scsi_lu_##_name = \
-       __CONFIGFS_EATTR_RO(_name,                                      \
-       target_stat_scsi_lu_show_attr_##_name);
+static struct se_device *to_stat_lu_dev(struct config_item *item)
+{
+       struct se_dev_stat_grps *sgrps = container_of(to_config_group(item),
+                       struct se_dev_stat_grps, scsi_lu_group);
+       return container_of(sgrps, struct se_device, dev_stat_grps);
+}
 
-static ssize_t target_stat_scsi_lu_show_attr_inst(
-       struct se_dev_stat_grps *sgrps, char *page)
+static ssize_t target_stat_lu_inst_show(struct config_item *item, char *page)
 {
-       struct se_device *dev =
-               container_of(sgrps, struct se_device, dev_stat_grps);
-       struct se_hba *hba = dev->se_hba;
+       struct se_hba *hba = to_stat_lu_dev(item)->se_hba;
 
        return snprintf(page, PAGE_SIZE, "%u\n", hba->hba_index);
 }
-DEV_STAT_SCSI_LU_ATTR_RO(inst);
 
-static ssize_t target_stat_scsi_lu_show_attr_dev(
-       struct se_dev_stat_grps *sgrps, char *page)
+static ssize_t target_stat_lu_dev_show(struct config_item *item, char *page)
 {
-       struct se_device *dev =
-               container_of(sgrps, struct se_device, dev_stat_grps);
-
-       return snprintf(page, PAGE_SIZE, "%u\n", dev->dev_index);
+       return snprintf(page, PAGE_SIZE, "%u\n",
+                       to_stat_lu_dev(item)->dev_index);
 }
-DEV_STAT_SCSI_LU_ATTR_RO(dev);
 
-static ssize_t target_stat_scsi_lu_show_attr_indx(
-       struct se_dev_stat_grps *sgrps, char *page)
+static ssize_t target_stat_lu_indx_show(struct config_item *item, char *page)
 {
        return snprintf(page, PAGE_SIZE, "%u\n", SCSI_LU_INDEX);
 }
-DEV_STAT_SCSI_LU_ATTR_RO(indx);
 
-static ssize_t target_stat_scsi_lu_show_attr_lun(
-       struct se_dev_stat_grps *sgrps, char *page)
+static ssize_t target_stat_lu_lun_show(struct config_item *item, char *page)
 {
        /* FIXME: scsiLuDefaultLun */
        return snprintf(page, PAGE_SIZE, "%llu\n", (unsigned long long)0);
 }
-DEV_STAT_SCSI_LU_ATTR_RO(lun);
 
-static ssize_t target_stat_scsi_lu_show_attr_lu_name(
-       struct se_dev_stat_grps *sgrps, char *page)
+static ssize_t target_stat_lu_lu_name_show(struct config_item *item, char *page)
 {
-       struct se_device *dev =
-               container_of(sgrps, struct se_device, dev_stat_grps);
+       struct se_device *dev = to_stat_lu_dev(item);
 
        /* scsiLuWwnName */
        return snprintf(page, PAGE_SIZE, "%s\n",
                        (strlen(dev->t10_wwn.unit_serial)) ?
                        dev->t10_wwn.unit_serial : "None");
 }
-DEV_STAT_SCSI_LU_ATTR_RO(lu_name);
 
-static ssize_t target_stat_scsi_lu_show_attr_vend(
-       struct se_dev_stat_grps *sgrps, char *page)
+static ssize_t target_stat_lu_vend_show(struct config_item *item, char *page)
 {
-       struct se_device *dev =
-               container_of(sgrps, struct se_device, dev_stat_grps);
+       struct se_device *dev = to_stat_lu_dev(item);
        int i;
        char str[sizeof(dev->t10_wwn.vendor)+1];
 
@@ -318,13 +238,10 @@ static ssize_t target_stat_scsi_lu_show_attr_vend(
        str[i] = '\0';
        return snprintf(page, PAGE_SIZE, "%s\n", str);
 }
-DEV_STAT_SCSI_LU_ATTR_RO(vend);
 
-static ssize_t target_stat_scsi_lu_show_attr_prod(
-       struct se_dev_stat_grps *sgrps, char *page)
+static ssize_t target_stat_lu_prod_show(struct config_item *item, char *page)
 {
-       struct se_device *dev =
-               container_of(sgrps, struct se_device, dev_stat_grps);
+       struct se_device *dev = to_stat_lu_dev(item);
        int i;
        char str[sizeof(dev->t10_wwn.model)+1];
 
@@ -335,13 +252,10 @@ static ssize_t target_stat_scsi_lu_show_attr_prod(
        str[i] = '\0';
        return snprintf(page, PAGE_SIZE, "%s\n", str);
 }
-DEV_STAT_SCSI_LU_ATTR_RO(prod);
 
-static ssize_t target_stat_scsi_lu_show_attr_rev(
-       struct se_dev_stat_grps *sgrps, char *page)
+static ssize_t target_stat_lu_rev_show(struct config_item *item, char *page)
 {
-       struct se_device *dev =
-               container_of(sgrps, struct se_device, dev_stat_grps);
+       struct se_device *dev = to_stat_lu_dev(item);
        int i;
        char str[sizeof(dev->t10_wwn.revision)+1];
 
@@ -352,146 +266,137 @@ static ssize_t target_stat_scsi_lu_show_attr_rev(
        str[i] = '\0';
        return snprintf(page, PAGE_SIZE, "%s\n", str);
 }
-DEV_STAT_SCSI_LU_ATTR_RO(rev);
 
-static ssize_t target_stat_scsi_lu_show_attr_dev_type(
-       struct se_dev_stat_grps *sgrps, char *page)
+static ssize_t target_stat_lu_dev_type_show(struct config_item *item, char *page)
 {
-       struct se_device *dev =
-               container_of(sgrps, struct se_device, dev_stat_grps);
+       struct se_device *dev = to_stat_lu_dev(item);
 
        /* scsiLuPeripheralType */
        return snprintf(page, PAGE_SIZE, "%u\n",
                        dev->transport->get_device_type(dev));
 }
-DEV_STAT_SCSI_LU_ATTR_RO(dev_type);
 
-static ssize_t target_stat_scsi_lu_show_attr_status(
-       struct se_dev_stat_grps *sgrps, char *page)
+static ssize_t target_stat_lu_status_show(struct config_item *item, char *page)
 {
-       struct se_device *dev =
-               container_of(sgrps, struct se_device, dev_stat_grps);
+       struct se_device *dev = to_stat_lu_dev(item);
 
        /* scsiLuStatus */
        return snprintf(page, PAGE_SIZE, "%s\n",
                (dev->export_count) ? "available" : "notavailable");
 }
-DEV_STAT_SCSI_LU_ATTR_RO(status);
 
-static ssize_t target_stat_scsi_lu_show_attr_state_bit(
-       struct se_dev_stat_grps *sgrps, char *page)
+static ssize_t target_stat_lu_state_bit_show(struct config_item *item,
+               char *page)
 {
        /* scsiLuState */
        return snprintf(page, PAGE_SIZE, "exposed\n");
 }
-DEV_STAT_SCSI_LU_ATTR_RO(state_bit);
 
-static ssize_t target_stat_scsi_lu_show_attr_num_cmds(
-       struct se_dev_stat_grps *sgrps, char *page)
+static ssize_t target_stat_lu_num_cmds_show(struct config_item *item,
+               char *page)
 {
-       struct se_device *dev =
-               container_of(sgrps, struct se_device, dev_stat_grps);
+       struct se_device *dev = to_stat_lu_dev(item);
 
        /* scsiLuNumCommands */
        return snprintf(page, PAGE_SIZE, "%lu\n",
                        atomic_long_read(&dev->num_cmds));
 }
-DEV_STAT_SCSI_LU_ATTR_RO(num_cmds);
 
-static ssize_t target_stat_scsi_lu_show_attr_read_mbytes(
-       struct se_dev_stat_grps *sgrps, char *page)
+static ssize_t target_stat_lu_read_mbytes_show(struct config_item *item,
+               char *page)
 {
-       struct se_device *dev =
-               container_of(sgrps, struct se_device, dev_stat_grps);
+       struct se_device *dev = to_stat_lu_dev(item);
 
        /* scsiLuReadMegaBytes */
        return snprintf(page, PAGE_SIZE, "%lu\n",
                        atomic_long_read(&dev->read_bytes) >> 20);
 }
-DEV_STAT_SCSI_LU_ATTR_RO(read_mbytes);
 
-static ssize_t target_stat_scsi_lu_show_attr_write_mbytes(
-       struct se_dev_stat_grps *sgrps, char *page)
+static ssize_t target_stat_lu_write_mbytes_show(struct config_item *item,
+               char *page)
 {
-       struct se_device *dev =
-               container_of(sgrps, struct se_device, dev_stat_grps);
+       struct se_device *dev = to_stat_lu_dev(item);
 
        /* scsiLuWrittenMegaBytes */
        return snprintf(page, PAGE_SIZE, "%lu\n",
                        atomic_long_read(&dev->write_bytes) >> 20);
 }
-DEV_STAT_SCSI_LU_ATTR_RO(write_mbytes);
 
-static ssize_t target_stat_scsi_lu_show_attr_resets(
-       struct se_dev_stat_grps *sgrps, char *page)
+static ssize_t target_stat_lu_resets_show(struct config_item *item, char *page)
 {
-       struct se_device *dev =
-               container_of(sgrps, struct se_device, dev_stat_grps);
+       struct se_device *dev = to_stat_lu_dev(item);
 
        /* scsiLuInResets */
-       return snprintf(page, PAGE_SIZE, "%lu\n", atomic_long_read(&dev->num_resets));
+       return snprintf(page, PAGE_SIZE, "%lu\n",
+               atomic_long_read(&dev->num_resets));
 }
-DEV_STAT_SCSI_LU_ATTR_RO(resets);
 
-static ssize_t target_stat_scsi_lu_show_attr_full_stat(
-       struct se_dev_stat_grps *sgrps, char *page)
+static ssize_t target_stat_lu_full_stat_show(struct config_item *item,
+               char *page)
 {
        /* FIXME: scsiLuOutTaskSetFullStatus */
        return snprintf(page, PAGE_SIZE, "%u\n", 0);
 }
-DEV_STAT_SCSI_LU_ATTR_RO(full_stat);
 
-static ssize_t target_stat_scsi_lu_show_attr_hs_num_cmds(
-       struct se_dev_stat_grps *sgrps, char *page)
+static ssize_t target_stat_lu_hs_num_cmds_show(struct config_item *item,
+               char *page)
 {
        /* FIXME: scsiLuHSInCommands */
        return snprintf(page, PAGE_SIZE, "%u\n", 0);
 }
-DEV_STAT_SCSI_LU_ATTR_RO(hs_num_cmds);
 
-static ssize_t target_stat_scsi_lu_show_attr_creation_time(
-       struct se_dev_stat_grps *sgrps, char *page)
+static ssize_t target_stat_lu_creation_time_show(struct config_item *item,
+               char *page)
 {
-       struct se_device *dev =
-               container_of(sgrps, struct se_device, dev_stat_grps);
+       struct se_device *dev = to_stat_lu_dev(item);
 
        /* scsiLuCreationTime */
        return snprintf(page, PAGE_SIZE, "%u\n", (u32)(((u32)dev->creation_time -
                                INITIAL_JIFFIES) * 100 / HZ));
 }
-DEV_STAT_SCSI_LU_ATTR_RO(creation_time);
 
-CONFIGFS_EATTR_OPS(target_stat_scsi_lu, se_dev_stat_grps, scsi_lu_group);
+CONFIGFS_ATTR_RO(target_stat_lu_, inst);
+CONFIGFS_ATTR_RO(target_stat_lu_, dev);
+CONFIGFS_ATTR_RO(target_stat_lu_, indx);
+CONFIGFS_ATTR_RO(target_stat_lu_, lun);
+CONFIGFS_ATTR_RO(target_stat_lu_, lu_name);
+CONFIGFS_ATTR_RO(target_stat_lu_, vend);
+CONFIGFS_ATTR_RO(target_stat_lu_, prod);
+CONFIGFS_ATTR_RO(target_stat_lu_, rev);
+CONFIGFS_ATTR_RO(target_stat_lu_, dev_type);
+CONFIGFS_ATTR_RO(target_stat_lu_, status);
+CONFIGFS_ATTR_RO(target_stat_lu_, state_bit);
+CONFIGFS_ATTR_RO(target_stat_lu_, num_cmds);
+CONFIGFS_ATTR_RO(target_stat_lu_, read_mbytes);
+CONFIGFS_ATTR_RO(target_stat_lu_, write_mbytes);
+CONFIGFS_ATTR_RO(target_stat_lu_, resets);
+CONFIGFS_ATTR_RO(target_stat_lu_, full_stat);
+CONFIGFS_ATTR_RO(target_stat_lu_, hs_num_cmds);
+CONFIGFS_ATTR_RO(target_stat_lu_, creation_time);
 
 static struct configfs_attribute *target_stat_scsi_lu_attrs[] = {
-       &target_stat_scsi_lu_inst.attr,
-       &target_stat_scsi_lu_dev.attr,
-       &target_stat_scsi_lu_indx.attr,
-       &target_stat_scsi_lu_lun.attr,
-       &target_stat_scsi_lu_lu_name.attr,
-       &target_stat_scsi_lu_vend.attr,
-       &target_stat_scsi_lu_prod.attr,
-       &target_stat_scsi_lu_rev.attr,
-       &target_stat_scsi_lu_dev_type.attr,
-       &target_stat_scsi_lu_status.attr,
-       &target_stat_scsi_lu_state_bit.attr,
-       &target_stat_scsi_lu_num_cmds.attr,
-       &target_stat_scsi_lu_read_mbytes.attr,
-       &target_stat_scsi_lu_write_mbytes.attr,
-       &target_stat_scsi_lu_resets.attr,
-       &target_stat_scsi_lu_full_stat.attr,
-       &target_stat_scsi_lu_hs_num_cmds.attr,
-       &target_stat_scsi_lu_creation_time.attr,
+       &target_stat_lu_attr_inst,
+       &target_stat_lu_attr_dev,
+       &target_stat_lu_attr_indx,
+       &target_stat_lu_attr_lun,
+       &target_stat_lu_attr_lu_name,
+       &target_stat_lu_attr_vend,
+       &target_stat_lu_attr_prod,
+       &target_stat_lu_attr_rev,
+       &target_stat_lu_attr_dev_type,
+       &target_stat_lu_attr_status,
+       &target_stat_lu_attr_state_bit,
+       &target_stat_lu_attr_num_cmds,
+       &target_stat_lu_attr_read_mbytes,
+       &target_stat_lu_attr_write_mbytes,
+       &target_stat_lu_attr_resets,
+       &target_stat_lu_attr_full_stat,
+       &target_stat_lu_attr_hs_num_cmds,
+       &target_stat_lu_attr_creation_time,
        NULL,
 };
 
-static struct configfs_item_operations target_stat_scsi_lu_attrib_ops = {
-       .show_attribute         = target_stat_scsi_lu_attr_show,
-       .store_attribute        = target_stat_scsi_lu_attr_store,
-};
-
 static struct config_item_type target_stat_scsi_lu_cit = {
-       .ct_item_ops            = &target_stat_scsi_lu_attrib_ops,
        .ct_attrs               = target_stat_scsi_lu_attrs,
        .ct_owner               = THIS_MODULE,
 };
@@ -521,24 +426,16 @@ void target_stat_setup_dev_default_groups(struct se_device *dev)
  * SCSI Port Table
  */
 
-CONFIGFS_EATTR_STRUCT(target_stat_scsi_port, se_port_stat_grps);
-#define DEV_STAT_SCSI_PORT_ATTR(_name, _mode)                          \
-static struct target_stat_scsi_port_attribute                          \
-                       target_stat_scsi_port_##_name =                 \
-       __CONFIGFS_EATTR(_name, _mode,                                  \
-       target_stat_scsi_port_show_attr_##_name,                        \
-       target_stat_scsi_port_store_attr_##_name);
-
-#define DEV_STAT_SCSI_PORT_ATTR_RO(_name)                              \
-static struct target_stat_scsi_port_attribute                          \
-                       target_stat_scsi_port_##_name =                 \
-       __CONFIGFS_EATTR_RO(_name,                                      \
-       target_stat_scsi_port_show_attr_##_name);
+static struct se_lun *to_stat_port(struct config_item *item)
+{
+       struct se_port_stat_grps *pgrps = container_of(to_config_group(item),
+                       struct se_port_stat_grps, scsi_port_group);
+       return container_of(pgrps, struct se_lun, port_stat_grps);
+}
 
-static ssize_t target_stat_scsi_port_show_attr_inst(
-       struct se_port_stat_grps *pgrps, char *page)
+static ssize_t target_stat_port_inst_show(struct config_item *item, char *page)
 {
-       struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
+       struct se_lun *lun = to_stat_port(item);
        struct se_device *dev;
        ssize_t ret = -ENODEV;
 
@@ -549,12 +446,10 @@ static ssize_t target_stat_scsi_port_show_attr_inst(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_PORT_ATTR_RO(inst);
 
-static ssize_t target_stat_scsi_port_show_attr_dev(
-       struct se_port_stat_grps *pgrps, char *page)
+static ssize_t target_stat_port_dev_show(struct config_item *item, char *page)
 {
-       struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
+       struct se_lun *lun = to_stat_port(item);
        struct se_device *dev;
        ssize_t ret = -ENODEV;
 
@@ -565,12 +460,10 @@ static ssize_t target_stat_scsi_port_show_attr_dev(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_PORT_ATTR_RO(dev);
 
-static ssize_t target_stat_scsi_port_show_attr_indx(
-       struct se_port_stat_grps *pgrps, char *page)
+static ssize_t target_stat_port_indx_show(struct config_item *item, char *page)
 {
-       struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
+       struct se_lun *lun = to_stat_port(item);
        struct se_device *dev;
        ssize_t ret = -ENODEV;
 
@@ -581,12 +474,10 @@ static ssize_t target_stat_scsi_port_show_attr_indx(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_PORT_ATTR_RO(indx);
 
-static ssize_t target_stat_scsi_port_show_attr_role(
-       struct se_port_stat_grps *pgrps, char *page)
+static ssize_t target_stat_port_role_show(struct config_item *item, char *page)
 {
-       struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
+       struct se_lun *lun = to_stat_port(item);
        struct se_device *dev;
        ssize_t ret = -ENODEV;
 
@@ -597,12 +488,11 @@ static ssize_t target_stat_scsi_port_show_attr_role(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_PORT_ATTR_RO(role);
 
-static ssize_t target_stat_scsi_port_show_attr_busy_count(
-       struct se_port_stat_grps *pgrps, char *page)
+static ssize_t target_stat_port_busy_count_show(struct config_item *item,
+               char *page)
 {
-       struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
+       struct se_lun *lun = to_stat_port(item);
        struct se_device *dev;
        ssize_t ret = -ENODEV;
 
@@ -615,26 +505,23 @@ static ssize_t target_stat_scsi_port_show_attr_busy_count(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_PORT_ATTR_RO(busy_count);
 
-CONFIGFS_EATTR_OPS(target_stat_scsi_port, se_port_stat_grps, scsi_port_group);
+CONFIGFS_ATTR_RO(target_stat_port_, inst);
+CONFIGFS_ATTR_RO(target_stat_port_, dev);
+CONFIGFS_ATTR_RO(target_stat_port_, indx);
+CONFIGFS_ATTR_RO(target_stat_port_, role);
+CONFIGFS_ATTR_RO(target_stat_port_, busy_count);
 
 static struct configfs_attribute *target_stat_scsi_port_attrs[] = {
-       &target_stat_scsi_port_inst.attr,
-       &target_stat_scsi_port_dev.attr,
-       &target_stat_scsi_port_indx.attr,
-       &target_stat_scsi_port_role.attr,
-       &target_stat_scsi_port_busy_count.attr,
+       &target_stat_port_attr_inst,
+       &target_stat_port_attr_dev,
+       &target_stat_port_attr_indx,
+       &target_stat_port_attr_role,
+       &target_stat_port_attr_busy_count,
        NULL,
 };
 
-static struct configfs_item_operations target_stat_scsi_port_attrib_ops = {
-       .show_attribute         = target_stat_scsi_port_attr_show,
-       .store_attribute        = target_stat_scsi_port_attr_store,
-};
-
 static struct config_item_type target_stat_scsi_port_cit = {
-       .ct_item_ops            = &target_stat_scsi_port_attrib_ops,
        .ct_attrs               = target_stat_scsi_port_attrs,
        .ct_owner               = THIS_MODULE,
 };
@@ -642,24 +529,17 @@ static struct config_item_type target_stat_scsi_port_cit = {
 /*
  * SCSI Target Port Table
  */
-CONFIGFS_EATTR_STRUCT(target_stat_scsi_tgt_port, se_port_stat_grps);
-#define DEV_STAT_SCSI_TGT_PORT_ATTR(_name, _mode)                      \
-static struct target_stat_scsi_tgt_port_attribute                      \
-                       target_stat_scsi_tgt_port_##_name =             \
-       __CONFIGFS_EATTR(_name, _mode,                                  \
-       target_stat_scsi_tgt_port_show_attr_##_name,                    \
-       target_stat_scsi_tgt_port_store_attr_##_name);
-
-#define DEV_STAT_SCSI_TGT_PORT_ATTR_RO(_name)                          \
-static struct target_stat_scsi_tgt_port_attribute                      \
-                       target_stat_scsi_tgt_port_##_name =             \
-       __CONFIGFS_EATTR_RO(_name,                                      \
-       target_stat_scsi_tgt_port_show_attr_##_name);
-
-static ssize_t target_stat_scsi_tgt_port_show_attr_inst(
-       struct se_port_stat_grps *pgrps, char *page)
-{
-       struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
+static struct se_lun *to_stat_tgt_port(struct config_item *item)
+{
+       struct se_port_stat_grps *pgrps = container_of(to_config_group(item),
+                       struct se_port_stat_grps, scsi_tgt_port_group);
+       return container_of(pgrps, struct se_lun, port_stat_grps);
+}
+
+static ssize_t target_stat_tgt_port_inst_show(struct config_item *item,
+               char *page)
+{
+       struct se_lun *lun = to_stat_tgt_port(item);
        struct se_device *dev;
        ssize_t ret = -ENODEV;
 
@@ -670,12 +550,11 @@ static ssize_t target_stat_scsi_tgt_port_show_attr_inst(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_TGT_PORT_ATTR_RO(inst);
 
-static ssize_t target_stat_scsi_tgt_port_show_attr_dev(
-       struct se_port_stat_grps *pgrps, char *page)
+static ssize_t target_stat_tgt_port_dev_show(struct config_item *item,
+               char *page)
 {
-       struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
+       struct se_lun *lun = to_stat_tgt_port(item);
        struct se_device *dev;
        ssize_t ret = -ENODEV;
 
@@ -686,12 +565,11 @@ static ssize_t target_stat_scsi_tgt_port_show_attr_dev(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_TGT_PORT_ATTR_RO(dev);
 
-static ssize_t target_stat_scsi_tgt_port_show_attr_indx(
-       struct se_port_stat_grps *pgrps, char *page)
+static ssize_t target_stat_tgt_port_indx_show(struct config_item *item,
+               char *page)
 {
-       struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
+       struct se_lun *lun = to_stat_tgt_port(item);
        struct se_device *dev;
        ssize_t ret = -ENODEV;
 
@@ -702,12 +580,11 @@ static ssize_t target_stat_scsi_tgt_port_show_attr_indx(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_TGT_PORT_ATTR_RO(indx);
 
-static ssize_t target_stat_scsi_tgt_port_show_attr_name(
-       struct se_port_stat_grps *pgrps, char *page)
+static ssize_t target_stat_tgt_port_name_show(struct config_item *item,
+               char *page)
 {
-       struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
+       struct se_lun *lun = to_stat_tgt_port(item);
        struct se_portal_group *tpg = lun->lun_tpg;
        struct se_device *dev;
        ssize_t ret = -ENODEV;
@@ -721,12 +598,11 @@ static ssize_t target_stat_scsi_tgt_port_show_attr_name(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_TGT_PORT_ATTR_RO(name);
 
-static ssize_t target_stat_scsi_tgt_port_show_attr_port_index(
-       struct se_port_stat_grps *pgrps, char *page)
+static ssize_t target_stat_tgt_port_port_index_show(struct config_item *item,
+               char *page)
 {
-       struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
+       struct se_lun *lun = to_stat_tgt_port(item);
        struct se_portal_group *tpg = lun->lun_tpg;
        struct se_device *dev;
        ssize_t ret = -ENODEV;
@@ -740,12 +616,11 @@ static ssize_t target_stat_scsi_tgt_port_show_attr_port_index(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_TGT_PORT_ATTR_RO(port_index);
 
-static ssize_t target_stat_scsi_tgt_port_show_attr_in_cmds(
-       struct se_port_stat_grps *pgrps, char *page)
+static ssize_t target_stat_tgt_port_in_cmds_show(struct config_item *item,
+               char *page)
 {
-       struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
+       struct se_lun *lun = to_stat_tgt_port(item);
        struct se_device *dev;
        ssize_t ret = -ENODEV;
 
@@ -757,12 +632,11 @@ static ssize_t target_stat_scsi_tgt_port_show_attr_in_cmds(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_TGT_PORT_ATTR_RO(in_cmds);
 
-static ssize_t target_stat_scsi_tgt_port_show_attr_write_mbytes(
-       struct se_port_stat_grps *pgrps, char *page)
+static ssize_t target_stat_tgt_port_write_mbytes_show(struct config_item *item,
+               char *page)
 {
-       struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
+       struct se_lun *lun = to_stat_tgt_port(item);
        struct se_device *dev;
        ssize_t ret = -ENODEV;
 
@@ -774,12 +648,11 @@ static ssize_t target_stat_scsi_tgt_port_show_attr_write_mbytes(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_TGT_PORT_ATTR_RO(write_mbytes);
 
-static ssize_t target_stat_scsi_tgt_port_show_attr_read_mbytes(
-       struct se_port_stat_grps *pgrps, char *page)
+static ssize_t target_stat_tgt_port_read_mbytes_show(struct config_item *item,
+               char *page)
 {
-       struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
+       struct se_lun *lun = to_stat_tgt_port(item);
        struct se_device *dev;
        ssize_t ret = -ENODEV;
 
@@ -791,12 +664,11 @@ static ssize_t target_stat_scsi_tgt_port_show_attr_read_mbytes(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_TGT_PORT_ATTR_RO(read_mbytes);
 
-static ssize_t target_stat_scsi_tgt_port_show_attr_hs_in_cmds(
-       struct se_port_stat_grps *pgrps, char *page)
+static ssize_t target_stat_tgt_port_hs_in_cmds_show(struct config_item *item,
+               char *page)
 {
-       struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
+       struct se_lun *lun = to_stat_tgt_port(item);
        struct se_device *dev;
        ssize_t ret = -ENODEV;
 
@@ -809,57 +681,49 @@ static ssize_t target_stat_scsi_tgt_port_show_attr_hs_in_cmds(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_TGT_PORT_ATTR_RO(hs_in_cmds);
 
-CONFIGFS_EATTR_OPS(target_stat_scsi_tgt_port, se_port_stat_grps,
-               scsi_tgt_port_group);
+CONFIGFS_ATTR_RO(target_stat_tgt_port_, inst);
+CONFIGFS_ATTR_RO(target_stat_tgt_port_, dev);
+CONFIGFS_ATTR_RO(target_stat_tgt_port_, indx);
+CONFIGFS_ATTR_RO(target_stat_tgt_port_, name);
+CONFIGFS_ATTR_RO(target_stat_tgt_port_, port_index);
+CONFIGFS_ATTR_RO(target_stat_tgt_port_, in_cmds);
+CONFIGFS_ATTR_RO(target_stat_tgt_port_, write_mbytes);
+CONFIGFS_ATTR_RO(target_stat_tgt_port_, read_mbytes);
+CONFIGFS_ATTR_RO(target_stat_tgt_port_, hs_in_cmds);
 
 static struct configfs_attribute *target_stat_scsi_tgt_port_attrs[] = {
-       &target_stat_scsi_tgt_port_inst.attr,
-       &target_stat_scsi_tgt_port_dev.attr,
-       &target_stat_scsi_tgt_port_indx.attr,
-       &target_stat_scsi_tgt_port_name.attr,
-       &target_stat_scsi_tgt_port_port_index.attr,
-       &target_stat_scsi_tgt_port_in_cmds.attr,
-       &target_stat_scsi_tgt_port_write_mbytes.attr,
-       &target_stat_scsi_tgt_port_read_mbytes.attr,
-       &target_stat_scsi_tgt_port_hs_in_cmds.attr,
+       &target_stat_tgt_port_attr_inst,
+       &target_stat_tgt_port_attr_dev,
+       &target_stat_tgt_port_attr_indx,
+       &target_stat_tgt_port_attr_name,
+       &target_stat_tgt_port_attr_port_index,
+       &target_stat_tgt_port_attr_in_cmds,
+       &target_stat_tgt_port_attr_write_mbytes,
+       &target_stat_tgt_port_attr_read_mbytes,
+       &target_stat_tgt_port_attr_hs_in_cmds,
        NULL,
 };
 
-static struct configfs_item_operations target_stat_scsi_tgt_port_attrib_ops = {
-       .show_attribute         = target_stat_scsi_tgt_port_attr_show,
-       .store_attribute        = target_stat_scsi_tgt_port_attr_store,
-};
-
 static struct config_item_type target_stat_scsi_tgt_port_cit = {
-       .ct_item_ops            = &target_stat_scsi_tgt_port_attrib_ops,
        .ct_attrs               = target_stat_scsi_tgt_port_attrs,
        .ct_owner               = THIS_MODULE,
 };
 
 /*
  * SCSI Transport Table
-o */
-
-CONFIGFS_EATTR_STRUCT(target_stat_scsi_transport, se_port_stat_grps);
-#define DEV_STAT_SCSI_TRANSPORT_ATTR(_name, _mode)                     \
-static struct target_stat_scsi_transport_attribute                     \
-                       target_stat_scsi_transport_##_name =            \
-       __CONFIGFS_EATTR(_name, _mode,                                  \
-       target_stat_scsi_transport_show_attr_##_name,                   \
-       target_stat_scsi_transport_store_attr_##_name);
-
-#define DEV_STAT_SCSI_TRANSPORT_ATTR_RO(_name)                         \
-static struct target_stat_scsi_transport_attribute                     \
-                       target_stat_scsi_transport_##_name =            \
-       __CONFIGFS_EATTR_RO(_name,                                      \
-       target_stat_scsi_transport_show_attr_##_name);
-
-static ssize_t target_stat_scsi_transport_show_attr_inst(
-       struct se_port_stat_grps *pgrps, char *page)
-{
-       struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
+ */
+static struct se_lun *to_transport_stat(struct config_item *item)
+{
+       struct se_port_stat_grps *pgrps = container_of(to_config_group(item),
+                       struct se_port_stat_grps, scsi_transport_group);
+       return container_of(pgrps, struct se_lun, port_stat_grps);
+}
+
+static ssize_t target_stat_transport_inst_show(struct config_item *item,
+               char *page)
+{
+       struct se_lun *lun = to_transport_stat(item);
        struct se_device *dev;
        ssize_t ret = -ENODEV;
 
@@ -870,12 +734,11 @@ static ssize_t target_stat_scsi_transport_show_attr_inst(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_TRANSPORT_ATTR_RO(inst);
 
-static ssize_t target_stat_scsi_transport_show_attr_device(
-       struct se_port_stat_grps *pgrps, char *page)
+static ssize_t target_stat_transport_device_show(struct config_item *item,
+               char *page)
 {
-       struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
+       struct se_lun *lun = to_transport_stat(item);
        struct se_device *dev;
        struct se_portal_group *tpg = lun->lun_tpg;
        ssize_t ret = -ENODEV;
@@ -890,12 +753,11 @@ static ssize_t target_stat_scsi_transport_show_attr_device(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_TRANSPORT_ATTR_RO(device);
 
-static ssize_t target_stat_scsi_transport_show_attr_indx(
-       struct se_port_stat_grps *pgrps, char *page)
+static ssize_t target_stat_transport_indx_show(struct config_item *item,
+               char *page)
 {
-       struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
+       struct se_lun *lun = to_transport_stat(item);
        struct se_device *dev;
        struct se_portal_group *tpg = lun->lun_tpg;
        ssize_t ret = -ENODEV;
@@ -908,12 +770,11 @@ static ssize_t target_stat_scsi_transport_show_attr_indx(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_TRANSPORT_ATTR_RO(indx);
 
-static ssize_t target_stat_scsi_transport_show_attr_dev_name(
-       struct se_port_stat_grps *pgrps, char *page)
+static ssize_t target_stat_transport_dev_name_show(struct config_item *item,
+               char *page)
 {
-       struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
+       struct se_lun *lun = to_transport_stat(item);
        struct se_device *dev;
        struct se_portal_group *tpg = lun->lun_tpg;
        struct t10_wwn *wwn;
@@ -932,26 +793,21 @@ static ssize_t target_stat_scsi_transport_show_attr_dev_name(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_TRANSPORT_ATTR_RO(dev_name);
 
-CONFIGFS_EATTR_OPS(target_stat_scsi_transport, se_port_stat_grps,
-               scsi_transport_group);
+CONFIGFS_ATTR_RO(target_stat_transport_, inst);
+CONFIGFS_ATTR_RO(target_stat_transport_, device);
+CONFIGFS_ATTR_RO(target_stat_transport_, indx);
+CONFIGFS_ATTR_RO(target_stat_transport_, dev_name);
 
 static struct configfs_attribute *target_stat_scsi_transport_attrs[] = {
-       &target_stat_scsi_transport_inst.attr,
-       &target_stat_scsi_transport_device.attr,
-       &target_stat_scsi_transport_indx.attr,
-       &target_stat_scsi_transport_dev_name.attr,
+       &target_stat_transport_attr_inst,
+       &target_stat_transport_attr_device,
+       &target_stat_transport_attr_indx,
+       &target_stat_transport_attr_dev_name,
        NULL,
 };
 
-static struct configfs_item_operations target_stat_scsi_transport_attrib_ops = {
-       .show_attribute         = target_stat_scsi_transport_attr_show,
-       .store_attribute        = target_stat_scsi_transport_attr_store,
-};
-
 static struct config_item_type target_stat_scsi_transport_cit = {
-       .ct_item_ops            = &target_stat_scsi_transport_attrib_ops,
        .ct_attrs               = target_stat_scsi_transport_attrs,
        .ct_owner               = THIS_MODULE,
 };
@@ -981,25 +837,17 @@ void target_stat_setup_port_default_groups(struct se_lun *lun)
  * SCSI Authorized Initiator Table
  */
 
-CONFIGFS_EATTR_STRUCT(target_stat_scsi_auth_intr, se_ml_stat_grps);
-#define DEV_STAT_SCSI_AUTH_INTR_ATTR(_name, _mode)                     \
-static struct target_stat_scsi_auth_intr_attribute                     \
-                       target_stat_scsi_auth_intr_##_name =            \
-       __CONFIGFS_EATTR(_name, _mode,                                  \
-       target_stat_scsi_auth_intr_show_attr_##_name,                   \
-       target_stat_scsi_auth_intr_store_attr_##_name);
-
-#define DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(_name)                         \
-static struct target_stat_scsi_auth_intr_attribute                     \
-                       target_stat_scsi_auth_intr_##_name =            \
-       __CONFIGFS_EATTR_RO(_name,                                      \
-       target_stat_scsi_auth_intr_show_attr_##_name);
-
-static ssize_t target_stat_scsi_auth_intr_show_attr_inst(
-       struct se_ml_stat_grps *lgrps, char *page)
-{
-       struct se_lun_acl *lacl = container_of(lgrps,
-                       struct se_lun_acl, ml_stat_grps);
+static struct se_lun_acl *auth_to_lacl(struct config_item *item)
+{
+       struct se_ml_stat_grps *lgrps = container_of(to_config_group(item),
+                       struct se_ml_stat_grps, scsi_auth_intr_group);
+       return container_of(lgrps, struct se_lun_acl, ml_stat_grps);
+}
+
+static ssize_t target_stat_auth_inst_show(struct config_item *item,
+               char *page)
+{
+       struct se_lun_acl *lacl = auth_to_lacl(item);
        struct se_node_acl *nacl = lacl->se_lun_nacl;
        struct se_dev_entry *deve;
        struct se_portal_group *tpg;
@@ -1018,13 +866,11 @@ static ssize_t target_stat_scsi_auth_intr_show_attr_inst(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(inst);
 
-static ssize_t target_stat_scsi_auth_intr_show_attr_dev(
-       struct se_ml_stat_grps *lgrps, char *page)
+static ssize_t target_stat_auth_dev_show(struct config_item *item,
+               char *page)
 {
-       struct se_lun_acl *lacl = container_of(lgrps,
-                       struct se_lun_acl, ml_stat_grps);
+       struct se_lun_acl *lacl = auth_to_lacl(item);
        struct se_node_acl *nacl = lacl->se_lun_nacl;
        struct se_dev_entry *deve;
        struct se_lun *lun;
@@ -1042,13 +888,11 @@ static ssize_t target_stat_scsi_auth_intr_show_attr_dev(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(dev);
 
-static ssize_t target_stat_scsi_auth_intr_show_attr_port(
-       struct se_ml_stat_grps *lgrps, char *page)
+static ssize_t target_stat_auth_port_show(struct config_item *item,
+               char *page)
 {
-       struct se_lun_acl *lacl = container_of(lgrps,
-                       struct se_lun_acl, ml_stat_grps);
+       struct se_lun_acl *lacl = auth_to_lacl(item);
        struct se_node_acl *nacl = lacl->se_lun_nacl;
        struct se_dev_entry *deve;
        struct se_portal_group *tpg;
@@ -1066,13 +910,11 @@ static ssize_t target_stat_scsi_auth_intr_show_attr_port(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(port);
 
-static ssize_t target_stat_scsi_auth_intr_show_attr_indx(
-       struct se_ml_stat_grps *lgrps, char *page)
+static ssize_t target_stat_auth_indx_show(struct config_item *item,
+               char *page)
 {
-       struct se_lun_acl *lacl = container_of(lgrps,
-                       struct se_lun_acl, ml_stat_grps);
+       struct se_lun_acl *lacl = auth_to_lacl(item);
        struct se_node_acl *nacl = lacl->se_lun_nacl;
        struct se_dev_entry *deve;
        ssize_t ret;
@@ -1088,13 +930,11 @@ static ssize_t target_stat_scsi_auth_intr_show_attr_indx(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(indx);
 
-static ssize_t target_stat_scsi_auth_intr_show_attr_dev_or_port(
-       struct se_ml_stat_grps *lgrps, char *page)
+static ssize_t target_stat_auth_dev_or_port_show(struct config_item *item,
+               char *page)
 {
-       struct se_lun_acl *lacl = container_of(lgrps,
-                       struct se_lun_acl, ml_stat_grps);
+       struct se_lun_acl *lacl = auth_to_lacl(item);
        struct se_node_acl *nacl = lacl->se_lun_nacl;
        struct se_dev_entry *deve;
        ssize_t ret;
@@ -1110,13 +950,11 @@ static ssize_t target_stat_scsi_auth_intr_show_attr_dev_or_port(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(dev_or_port);
 
-static ssize_t target_stat_scsi_auth_intr_show_attr_intr_name(
-       struct se_ml_stat_grps *lgrps, char *page)
+static ssize_t target_stat_auth_intr_name_show(struct config_item *item,
+               char *page)
 {
-       struct se_lun_acl *lacl = container_of(lgrps,
-                       struct se_lun_acl, ml_stat_grps);
+       struct se_lun_acl *lacl = auth_to_lacl(item);
        struct se_node_acl *nacl = lacl->se_lun_nacl;
        struct se_dev_entry *deve;
        ssize_t ret;
@@ -1132,13 +970,11 @@ static ssize_t target_stat_scsi_auth_intr_show_attr_intr_name(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(intr_name);
 
-static ssize_t target_stat_scsi_auth_intr_show_attr_map_indx(
-       struct se_ml_stat_grps *lgrps, char *page)
+static ssize_t target_stat_auth_map_indx_show(struct config_item *item,
+               char *page)
 {
-       struct se_lun_acl *lacl = container_of(lgrps,
-                       struct se_lun_acl, ml_stat_grps);
+       struct se_lun_acl *lacl = auth_to_lacl(item);
        struct se_node_acl *nacl = lacl->se_lun_nacl;
        struct se_dev_entry *deve;
        ssize_t ret;
@@ -1154,13 +990,11 @@ static ssize_t target_stat_scsi_auth_intr_show_attr_map_indx(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(map_indx);
 
-static ssize_t target_stat_scsi_auth_intr_show_attr_att_count(
-       struct se_ml_stat_grps *lgrps, char *page)
+static ssize_t target_stat_auth_att_count_show(struct config_item *item,
+               char *page)
 {
-       struct se_lun_acl *lacl = container_of(lgrps,
-                       struct se_lun_acl, ml_stat_grps);
+       struct se_lun_acl *lacl = auth_to_lacl(item);
        struct se_node_acl *nacl = lacl->se_lun_nacl;
        struct se_dev_entry *deve;
        ssize_t ret;
@@ -1176,13 +1010,11 @@ static ssize_t target_stat_scsi_auth_intr_show_attr_att_count(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(att_count);
 
-static ssize_t target_stat_scsi_auth_intr_show_attr_num_cmds(
-       struct se_ml_stat_grps *lgrps, char *page)
+static ssize_t target_stat_auth_num_cmds_show(struct config_item *item,
+               char *page)
 {
-       struct se_lun_acl *lacl = container_of(lgrps,
-                       struct se_lun_acl, ml_stat_grps);
+       struct se_lun_acl *lacl = auth_to_lacl(item);
        struct se_node_acl *nacl = lacl->se_lun_nacl;
        struct se_dev_entry *deve;
        ssize_t ret;
@@ -1199,13 +1031,11 @@ static ssize_t target_stat_scsi_auth_intr_show_attr_num_cmds(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(num_cmds);
 
-static ssize_t target_stat_scsi_auth_intr_show_attr_read_mbytes(
-       struct se_ml_stat_grps *lgrps, char *page)
+static ssize_t target_stat_auth_read_mbytes_show(struct config_item *item,
+               char *page)
 {
-       struct se_lun_acl *lacl = container_of(lgrps,
-                       struct se_lun_acl, ml_stat_grps);
+       struct se_lun_acl *lacl = auth_to_lacl(item);
        struct se_node_acl *nacl = lacl->se_lun_nacl;
        struct se_dev_entry *deve;
        ssize_t ret;
@@ -1222,13 +1052,11 @@ static ssize_t target_stat_scsi_auth_intr_show_attr_read_mbytes(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(read_mbytes);
 
-static ssize_t target_stat_scsi_auth_intr_show_attr_write_mbytes(
-       struct se_ml_stat_grps *lgrps, char *page)
+static ssize_t target_stat_auth_write_mbytes_show(struct config_item *item,
+               char *page)
 {
-       struct se_lun_acl *lacl = container_of(lgrps,
-                       struct se_lun_acl, ml_stat_grps);
+       struct se_lun_acl *lacl = auth_to_lacl(item);
        struct se_node_acl *nacl = lacl->se_lun_nacl;
        struct se_dev_entry *deve;
        ssize_t ret;
@@ -1245,13 +1073,11 @@ static ssize_t target_stat_scsi_auth_intr_show_attr_write_mbytes(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(write_mbytes);
 
-static ssize_t target_stat_scsi_auth_intr_show_attr_hs_num_cmds(
-       struct se_ml_stat_grps *lgrps, char *page)
+static ssize_t target_stat_auth_hs_num_cmds_show(struct config_item *item,
+               char *page)
 {
-       struct se_lun_acl *lacl = container_of(lgrps,
-                       struct se_lun_acl, ml_stat_grps);
+       struct se_lun_acl *lacl = auth_to_lacl(item);
        struct se_node_acl *nacl = lacl->se_lun_nacl;
        struct se_dev_entry *deve;
        ssize_t ret;
@@ -1267,13 +1093,11 @@ static ssize_t target_stat_scsi_auth_intr_show_attr_hs_num_cmds(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(hs_num_cmds);
 
-static ssize_t target_stat_scsi_auth_intr_show_attr_creation_time(
-       struct se_ml_stat_grps *lgrps, char *page)
+static ssize_t target_stat_auth_creation_time_show(struct config_item *item,
+               char *page)
 {
-       struct se_lun_acl *lacl = container_of(lgrps,
-                       struct se_lun_acl, ml_stat_grps);
+       struct se_lun_acl *lacl = auth_to_lacl(item);
        struct se_node_acl *nacl = lacl->se_lun_nacl;
        struct se_dev_entry *deve;
        ssize_t ret;
@@ -1290,13 +1114,11 @@ static ssize_t target_stat_scsi_auth_intr_show_attr_creation_time(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(creation_time);
 
-static ssize_t target_stat_scsi_auth_intr_show_attr_row_status(
-       struct se_ml_stat_grps *lgrps, char *page)
+static ssize_t target_stat_auth_row_status_show(struct config_item *item,
+               char *page)
 {
-       struct se_lun_acl *lacl = container_of(lgrps,
-                       struct se_lun_acl, ml_stat_grps);
+       struct se_lun_acl *lacl = auth_to_lacl(item);
        struct se_node_acl *nacl = lacl->se_lun_nacl;
        struct se_dev_entry *deve;
        ssize_t ret;
@@ -1312,36 +1134,41 @@ static ssize_t target_stat_scsi_auth_intr_show_attr_row_status(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(row_status);
 
-CONFIGFS_EATTR_OPS(target_stat_scsi_auth_intr, se_ml_stat_grps,
-               scsi_auth_intr_group);
+CONFIGFS_ATTR_RO(target_stat_auth_, inst);
+CONFIGFS_ATTR_RO(target_stat_auth_, dev);
+CONFIGFS_ATTR_RO(target_stat_auth_, port);
+CONFIGFS_ATTR_RO(target_stat_auth_, indx);
+CONFIGFS_ATTR_RO(target_stat_auth_, dev_or_port);
+CONFIGFS_ATTR_RO(target_stat_auth_, intr_name);
+CONFIGFS_ATTR_RO(target_stat_auth_, map_indx);
+CONFIGFS_ATTR_RO(target_stat_auth_, att_count);
+CONFIGFS_ATTR_RO(target_stat_auth_, num_cmds);
+CONFIGFS_ATTR_RO(target_stat_auth_, read_mbytes);
+CONFIGFS_ATTR_RO(target_stat_auth_, write_mbytes);
+CONFIGFS_ATTR_RO(target_stat_auth_, hs_num_cmds);
+CONFIGFS_ATTR_RO(target_stat_auth_, creation_time);
+CONFIGFS_ATTR_RO(target_stat_auth_, row_status);
 
 static struct configfs_attribute *target_stat_scsi_auth_intr_attrs[] = {
-       &target_stat_scsi_auth_intr_inst.attr,
-       &target_stat_scsi_auth_intr_dev.attr,
-       &target_stat_scsi_auth_intr_port.attr,
-       &target_stat_scsi_auth_intr_indx.attr,
-       &target_stat_scsi_auth_intr_dev_or_port.attr,
-       &target_stat_scsi_auth_intr_intr_name.attr,
-       &target_stat_scsi_auth_intr_map_indx.attr,
-       &target_stat_scsi_auth_intr_att_count.attr,
-       &target_stat_scsi_auth_intr_num_cmds.attr,
-       &target_stat_scsi_auth_intr_read_mbytes.attr,
-       &target_stat_scsi_auth_intr_write_mbytes.attr,
-       &target_stat_scsi_auth_intr_hs_num_cmds.attr,
-       &target_stat_scsi_auth_intr_creation_time.attr,
-       &target_stat_scsi_auth_intr_row_status.attr,
+       &target_stat_auth_attr_inst,
+       &target_stat_auth_attr_dev,
+       &target_stat_auth_attr_port,
+       &target_stat_auth_attr_indx,
+       &target_stat_auth_attr_dev_or_port,
+       &target_stat_auth_attr_intr_name,
+       &target_stat_auth_attr_map_indx,
+       &target_stat_auth_attr_att_count,
+       &target_stat_auth_attr_num_cmds,
+       &target_stat_auth_attr_read_mbytes,
+       &target_stat_auth_attr_write_mbytes,
+       &target_stat_auth_attr_hs_num_cmds,
+       &target_stat_auth_attr_creation_time,
+       &target_stat_auth_attr_row_status,
        NULL,
 };
 
-static struct configfs_item_operations target_stat_scsi_auth_intr_attrib_ops = {
-       .show_attribute         = target_stat_scsi_auth_intr_attr_show,
-       .store_attribute        = target_stat_scsi_auth_intr_attr_store,
-};
-
 static struct config_item_type target_stat_scsi_auth_intr_cit = {
-       .ct_item_ops            = &target_stat_scsi_auth_intr_attrib_ops,
        .ct_attrs               = target_stat_scsi_auth_intr_attrs,
        .ct_owner               = THIS_MODULE,
 };
@@ -1350,25 +1177,17 @@ static struct config_item_type target_stat_scsi_auth_intr_cit = {
  * SCSI Attached Initiator Port Table
  */
 
-CONFIGFS_EATTR_STRUCT(target_stat_scsi_att_intr_port, se_ml_stat_grps);
-#define DEV_STAT_SCSI_ATTR_INTR_PORT_ATTR(_name, _mode)                        \
-static struct target_stat_scsi_att_intr_port_attribute                 \
-               target_stat_scsi_att_intr_port_##_name =                \
-       __CONFIGFS_EATTR(_name, _mode,                                  \
-       target_stat_scsi_att_intr_port_show_attr_##_name,               \
-       target_stat_scsi_att_intr_port_store_attr_##_name);
-
-#define DEV_STAT_SCSI_ATTR_INTR_PORT_ATTR_RO(_name)                    \
-static struct target_stat_scsi_att_intr_port_attribute                 \
-               target_stat_scsi_att_intr_port_##_name =                \
-       __CONFIGFS_EATTR_RO(_name,                                      \
-       target_stat_scsi_att_intr_port_show_attr_##_name);
-
-static ssize_t target_stat_scsi_att_intr_port_show_attr_inst(
-       struct se_ml_stat_grps *lgrps, char *page)
-{
-       struct se_lun_acl *lacl = container_of(lgrps,
-                       struct se_lun_acl, ml_stat_grps);
+static struct se_lun_acl *iport_to_lacl(struct config_item *item)
+{
+       struct se_ml_stat_grps *lgrps = container_of(to_config_group(item),
+                       struct se_ml_stat_grps, scsi_att_intr_port_group);
+       return container_of(lgrps, struct se_lun_acl, ml_stat_grps);
+}
+
+static ssize_t target_stat_iport_inst_show(struct config_item *item,
+               char *page)
+{
+       struct se_lun_acl *lacl = iport_to_lacl(item);
        struct se_node_acl *nacl = lacl->se_lun_nacl;
        struct se_dev_entry *deve;
        struct se_portal_group *tpg;
@@ -1387,13 +1206,11 @@ static ssize_t target_stat_scsi_att_intr_port_show_attr_inst(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_ATTR_INTR_PORT_ATTR_RO(inst);
 
-static ssize_t target_stat_scsi_att_intr_port_show_attr_dev(
-       struct se_ml_stat_grps *lgrps, char *page)
+static ssize_t target_stat_iport_dev_show(struct config_item *item,
+               char *page)
 {
-       struct se_lun_acl *lacl = container_of(lgrps,
-                       struct se_lun_acl, ml_stat_grps);
+       struct se_lun_acl *lacl = iport_to_lacl(item);
        struct se_node_acl *nacl = lacl->se_lun_nacl;
        struct se_dev_entry *deve;
        struct se_lun *lun;
@@ -1411,13 +1228,11 @@ static ssize_t target_stat_scsi_att_intr_port_show_attr_dev(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_ATTR_INTR_PORT_ATTR_RO(dev);
 
-static ssize_t target_stat_scsi_att_intr_port_show_attr_port(
-       struct se_ml_stat_grps *lgrps, char *page)
+static ssize_t target_stat_iport_port_show(struct config_item *item,
+               char *page)
 {
-       struct se_lun_acl *lacl = container_of(lgrps,
-                       struct se_lun_acl, ml_stat_grps);
+       struct se_lun_acl *lacl = iport_to_lacl(item);
        struct se_node_acl *nacl = lacl->se_lun_nacl;
        struct se_dev_entry *deve;
        struct se_portal_group *tpg;
@@ -1435,13 +1250,11 @@ static ssize_t target_stat_scsi_att_intr_port_show_attr_port(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_ATTR_INTR_PORT_ATTR_RO(port);
 
-static ssize_t target_stat_scsi_att_intr_port_show_attr_indx(
-       struct se_ml_stat_grps *lgrps, char *page)
+static ssize_t target_stat_iport_indx_show(struct config_item *item,
+               char *page)
 {
-       struct se_lun_acl *lacl = container_of(lgrps,
-                       struct se_lun_acl, ml_stat_grps);
+       struct se_lun_acl *lacl = iport_to_lacl(item);
        struct se_node_acl *nacl = lacl->se_lun_nacl;
        struct se_session *se_sess;
        struct se_portal_group *tpg;
@@ -1461,13 +1274,11 @@ static ssize_t target_stat_scsi_att_intr_port_show_attr_indx(
        spin_unlock_irq(&nacl->nacl_sess_lock);
        return ret;
 }
-DEV_STAT_SCSI_ATTR_INTR_PORT_ATTR_RO(indx);
 
-static ssize_t target_stat_scsi_att_intr_port_show_attr_port_auth_indx(
-       struct se_ml_stat_grps *lgrps, char *page)
+static ssize_t target_stat_iport_port_auth_indx_show(struct config_item *item,
+               char *page)
 {
-       struct se_lun_acl *lacl = container_of(lgrps,
-                       struct se_lun_acl, ml_stat_grps);
+       struct se_lun_acl *lacl = iport_to_lacl(item);
        struct se_node_acl *nacl = lacl->se_lun_nacl;
        struct se_dev_entry *deve;
        ssize_t ret;
@@ -1483,13 +1294,11 @@ static ssize_t target_stat_scsi_att_intr_port_show_attr_port_auth_indx(
        rcu_read_unlock();
        return ret;
 }
-DEV_STAT_SCSI_ATTR_INTR_PORT_ATTR_RO(port_auth_indx);
 
-static ssize_t target_stat_scsi_att_intr_port_show_attr_port_ident(
-       struct se_ml_stat_grps *lgrps, char *page)
+static ssize_t target_stat_iport_port_ident_show(struct config_item *item,
+               char *page)
 {
-       struct se_lun_acl *lacl = container_of(lgrps,
-                       struct se_lun_acl, ml_stat_grps);
+       struct se_lun_acl *lacl = iport_to_lacl(item);
        struct se_node_acl *nacl = lacl->se_lun_nacl;
        struct se_session *se_sess;
        struct se_portal_group *tpg;
@@ -1513,28 +1322,25 @@ static ssize_t target_stat_scsi_att_intr_port_show_attr_port_ident(
        spin_unlock_irq(&nacl->nacl_sess_lock);
        return ret;
 }
-DEV_STAT_SCSI_ATTR_INTR_PORT_ATTR_RO(port_ident);
 
-CONFIGFS_EATTR_OPS(target_stat_scsi_att_intr_port, se_ml_stat_grps,
-               scsi_att_intr_port_group);
+CONFIGFS_ATTR_RO(target_stat_iport_, inst);
+CONFIGFS_ATTR_RO(target_stat_iport_, dev);
+CONFIGFS_ATTR_RO(target_stat_iport_, port);
+CONFIGFS_ATTR_RO(target_stat_iport_, indx);
+CONFIGFS_ATTR_RO(target_stat_iport_, port_auth_indx);
+CONFIGFS_ATTR_RO(target_stat_iport_, port_ident);
 
 static struct configfs_attribute *target_stat_scsi_ath_intr_port_attrs[] = {
-       &target_stat_scsi_att_intr_port_inst.attr,
-       &target_stat_scsi_att_intr_port_dev.attr,
-       &target_stat_scsi_att_intr_port_port.attr,
-       &target_stat_scsi_att_intr_port_indx.attr,
-       &target_stat_scsi_att_intr_port_port_auth_indx.attr,
-       &target_stat_scsi_att_intr_port_port_ident.attr,
+       &target_stat_iport_attr_inst,
+       &target_stat_iport_attr_dev,
+       &target_stat_iport_attr_port,
+       &target_stat_iport_attr_indx,
+       &target_stat_iport_attr_port_auth_indx,
+       &target_stat_iport_attr_port_ident,
        NULL,
 };
 
-static struct configfs_item_operations target_stat_scsi_att_intr_port_attrib_ops = {
-       .show_attribute         = target_stat_scsi_att_intr_port_attr_show,
-       .store_attribute        = target_stat_scsi_att_intr_port_attr_store,
-};
-
 static struct config_item_type target_stat_scsi_att_intr_port_cit = {
-       .ct_item_ops            = &target_stat_scsi_att_intr_port_attrib_ops,
        .ct_attrs               = target_stat_scsi_ath_intr_port_attrs,
        .ct_owner               = THIS_MODULE,
 };
index aa3caca8bace13dc29a8cd9cb01d5b252b5c8a6c..064d6dfb5b6d9391bdd96f55ec4ae3f7d238655b 100644 (file)
@@ -36,7 +36,6 @@
 
 #include <target/target_core_base.h>
 #include <target/target_core_fabric.h>
-#include <target/configfs_macros.h>
 
 #include "tcm_fc.h"
 
index 16670933013bf6b7d803471a73de3c87b79459a1..85aeaa0ad303b9cff6e33234c2fe685b964ca53b 100644 (file)
@@ -38,8 +38,6 @@
 
 #include <target/target_core_base.h>
 #include <target/target_core_fabric.h>
-#include <target/target_core_fabric_configfs.h>
-#include <target/configfs_macros.h>
 
 #include "tcm_fc.h"
 
@@ -131,55 +129,51 @@ static ssize_t ft_wwn_store(void *arg, const char *buf, size_t len)
  * ACL auth ops.
  */
 
-static ssize_t ft_nacl_show_port_name(
-       struct se_node_acl *se_nacl,
-       char *page)
+static ssize_t ft_nacl_port_name_show(struct config_item *item, char *page)
 {
+       struct se_node_acl *se_nacl = acl_to_nacl(item);
        struct ft_node_acl *acl = container_of(se_nacl,
                        struct ft_node_acl, se_node_acl);
 
        return ft_wwn_show(&acl->node_auth.port_name, page);
 }
 
-static ssize_t ft_nacl_store_port_name(
-       struct se_node_acl *se_nacl,
-       const char *page,
-       size_t count)
+static ssize_t ft_nacl_port_name_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct se_node_acl *se_nacl = acl_to_nacl(item);
        struct ft_node_acl *acl = container_of(se_nacl,
                        struct ft_node_acl, se_node_acl);
 
        return ft_wwn_store(&acl->node_auth.port_name, page, count);
 }
 
-TF_NACL_BASE_ATTR(ft, port_name, S_IRUGO | S_IWUSR);
-
-static ssize_t ft_nacl_show_node_name(
-       struct se_node_acl *se_nacl,
-       char *page)
+static ssize_t ft_nacl_node_name_show(struct config_item *item,
+               char *page)
 {
+       struct se_node_acl *se_nacl = acl_to_nacl(item);
        struct ft_node_acl *acl = container_of(se_nacl,
                        struct ft_node_acl, se_node_acl);
 
        return ft_wwn_show(&acl->node_auth.node_name, page);
 }
 
-static ssize_t ft_nacl_store_node_name(
-       struct se_node_acl *se_nacl,
-       const char *page,
-       size_t count)
+static ssize_t ft_nacl_node_name_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct se_node_acl *se_nacl = acl_to_nacl(item);
        struct ft_node_acl *acl = container_of(se_nacl,
                        struct ft_node_acl, se_node_acl);
 
        return ft_wwn_store(&acl->node_auth.node_name, page, count);
 }
 
-TF_NACL_BASE_ATTR(ft, node_name, S_IRUGO | S_IWUSR);
+CONFIGFS_ATTR(ft_nacl_, node_name);
+CONFIGFS_ATTR(ft_nacl_, port_name);
 
 static struct configfs_attribute *ft_nacl_base_attrs[] = {
-       &ft_nacl_port_name.attr,
-       &ft_nacl_node_name.attr,
+       &ft_nacl_attr_port_name,
+       &ft_nacl_attr_node_name,
        NULL,
 };
 
@@ -386,18 +380,16 @@ static void ft_del_wwn(struct se_wwn *wwn)
        kfree(ft_wwn);
 }
 
-static ssize_t ft_wwn_show_attr_version(
-       struct target_fabric_configfs *tf,
-       char *page)
+static ssize_t ft_wwn_version_show(struct config_item *item, char *page)
 {
        return sprintf(page, "TCM FC " FT_VERSION " on %s/%s on "
                ""UTS_RELEASE"\n",  utsname()->sysname, utsname()->machine);
 }
 
-TF_WWN_ATTR_RO(ft, version);
+CONFIGFS_ATTR_RO(ft_wwn_, version);
 
 static struct configfs_attribute *ft_wwn_attrs[] = {
-       &ft_wwn_version.attr,
+       &ft_wwn_attr_version,
        NULL,
 };
 
index 4b0fedd6bd4be2236f2beb636e05251345687c60..847c1aa6fbf4d037bb385041719b39f1ef2c37b6 100644 (file)
@@ -44,7 +44,6 @@
 
 #include <target/target_core_base.h>
 #include <target/target_core_fabric.h>
-#include <target/configfs_macros.h>
 
 #include "tcm_fc.h"
 
index 31a9e3fb98c5321de2e6b774c875845638c81862..7b934eac995df68aaf764bceaaa4f14472db3314 100644 (file)
@@ -36,7 +36,6 @@
 
 #include <target/target_core_base.h>
 #include <target/target_core_fabric.h>
-#include <target/configfs_macros.h>
 
 #include "tcm_fc.h"
 
index 5aabc4bc0d757fb0d7f423663867c8b634797a97..c463c89b90efd89c9cf1a29b8472b25e41bf6c17 100644 (file)
@@ -147,6 +147,20 @@ config CLOCK_THERMAL
          device that is configured to use this cooling mechanism will be
          controlled to reduce clock frequency whenever temperature is high.
 
+config DEVFREQ_THERMAL
+       bool "Generic device cooling support"
+       depends on PM_DEVFREQ
+       depends on PM_OPP
+       help
+         This implements the generic devfreq cooling mechanism through
+         frequency reduction for devices using devfreq.
+
+         This will throttle the device by limiting the maximum allowed DVFS
+         frequency corresponding to the cooling level.
+
+         In order to use the power extensions of the cooling device,
+         devfreq should use the simple_ondemand governor.
+
          If you want this support, you should say Y here.
 
 config THERMAL_EMULATION
@@ -275,6 +289,7 @@ config X86_PKG_TEMP_THERMAL
        tristate "X86 package temperature thermal driver"
        depends on X86_THERMAL_VECTOR
        select THERMAL_GOV_USER_SPACE
+       select THERMAL_WRITABLE_TRIPS
        default m
        help
          Enable this to register CPU digital sensor for package temperature as
@@ -296,6 +311,7 @@ config INTEL_SOC_DTS_THERMAL
        tristate "Intel SoCs DTS thermal driver"
        depends on X86
        select INTEL_SOC_DTS_IOSF_CORE
+       select THERMAL_WRITABLE_TRIPS
        help
          Enable this to register Intel SoCs (e.g. Bay Trail) platform digital
          temperature sensor (DTS). These SoCs have two additional DTSs in
@@ -322,6 +338,7 @@ config INT340X_THERMAL
        select ACPI_THERMAL_REL
        select ACPI_FAN
        select INTEL_SOC_DTS_IOSF_CORE
+       select THERMAL_WRITABLE_TRIPS
        help
          Newer laptops and tablets that use ACPI may have thermal sensors and
          other devices with thermal control capabilities outside the core
index 26f160809959248e682544f3adc976599336690e..cfae6a654793bbc0ad28bf96ea5784aa8330f6d7 100644 (file)
@@ -22,6 +22,9 @@ thermal_sys-$(CONFIG_CPU_THERMAL)     += cpu_cooling.o
 # clock cooling
 thermal_sys-$(CONFIG_CLOCK_THERMAL)    += clock_cooling.o
 
+# devfreq cooling
+thermal_sys-$(CONFIG_DEVFREQ_THERMAL) += devfreq_cooling.o
+
 # platform thermal drivers
 obj-$(CONFIG_QCOM_SPMI_TEMP_ALARM)     += qcom-spmi-temp-alarm.o
 obj-$(CONFIG_SPEAR_THERMAL)    += spear_thermal.o
index 26b8d326546a804d2c4f954258c0cc9839113d09..ae75328945f7b6e1818397d71b53f2c82e8473f9 100644 (file)
@@ -224,9 +224,9 @@ static const struct armada_thermal_data armada380_data = {
        .is_valid_shift = 10,
        .temp_shift = 0,
        .temp_mask = 0x3ff,
-       .coef_b = 2931108200UL,
-       .coef_m = 5000000UL,
-       .coef_div = 10502,
+       .coef_b = 1172499100UL,
+       .coef_m = 2000096UL,
+       .coef_div = 4201,
        .inverted = true,
 };
 
index 42c6f71bdcc16e96d956ebed4ed808c5701d8afd..e3fbc5a5d88f166930e8633e671348614d00dd4d 100644 (file)
@@ -591,8 +591,7 @@ static int cpufreq_get_requested_power(struct thermal_cooling_device *cdev,
        if (trace_thermal_power_cpu_get_power_enabled()) {
                u32 ncpus = cpumask_weight(&cpufreq_device->allowed_cpus);
 
-               load_cpu = devm_kcalloc(&cdev->device, ncpus, sizeof(*load_cpu),
-                                       GFP_KERNEL);
+               load_cpu = kcalloc(ncpus, sizeof(*load_cpu), GFP_KERNEL);
        }
 
        for_each_cpu(cpu, &cpufreq_device->allowed_cpus) {
@@ -615,8 +614,7 @@ static int cpufreq_get_requested_power(struct thermal_cooling_device *cdev,
        dynamic_power = get_dynamic_power(cpufreq_device, freq);
        ret = get_static_power(cpufreq_device, tz, freq, &static_power);
        if (ret) {
-               if (load_cpu)
-                       devm_kfree(&cdev->device, load_cpu);
+               kfree(load_cpu);
                return ret;
        }
 
@@ -625,7 +623,7 @@ static int cpufreq_get_requested_power(struct thermal_cooling_device *cdev,
                        &cpufreq_device->allowed_cpus,
                        freq, load_cpu, i, dynamic_power, static_power);
 
-               devm_kfree(&cdev->device, load_cpu);
+               kfree(load_cpu);
        }
 
        *power = static_power + dynamic_power;
diff --git a/drivers/thermal/devfreq_cooling.c b/drivers/thermal/devfreq_cooling.c
new file mode 100644 (file)
index 0000000..01f0015
--- /dev/null
@@ -0,0 +1,573 @@
+/*
+ * devfreq_cooling: Thermal cooling device implementation for devices using
+ *                  devfreq
+ *
+ * Copyright (C) 2014-2015 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * TODO:
+ *    - If OPPs are added or removed after devfreq cooling has
+ *      registered, the devfreq cooling won't react to it.
+ */
+
+#include <linux/devfreq.h>
+#include <linux/devfreq_cooling.h>
+#include <linux/export.h>
+#include <linux/slab.h>
+#include <linux/pm_opp.h>
+#include <linux/thermal.h>
+
+#include <trace/events/thermal.h>
+
+static DEFINE_MUTEX(devfreq_lock);
+static DEFINE_IDR(devfreq_idr);
+
+/**
+ * struct devfreq_cooling_device - Devfreq cooling device
+ * @id:                unique integer value corresponding to each
+ *             devfreq_cooling_device registered.
+ * @cdev:      Pointer to associated thermal cooling device.
+ * @devfreq:   Pointer to associated devfreq device.
+ * @cooling_state:     Current cooling state.
+ * @power_table:       Pointer to table with maximum power draw for each
+ *                     cooling state. State is the index into the table, and
+ *                     the power is in mW.
+ * @freq_table:        Pointer to a table with the frequencies sorted in descending
+ *             order.  You can index the table by cooling device state
+ * @freq_table_size:   Size of the @freq_table and @power_table
+ * @power_ops: Pointer to devfreq_cooling_power, used to generate the
+ *             @power_table.
+ */
+struct devfreq_cooling_device {
+       int id;
+       struct thermal_cooling_device *cdev;
+       struct devfreq *devfreq;
+       unsigned long cooling_state;
+       u32 *power_table;
+       u32 *freq_table;
+       size_t freq_table_size;
+       struct devfreq_cooling_power *power_ops;
+};
+
+/**
+ * get_idr - function to get a unique id.
+ * @idr: struct idr * handle used to create a id.
+ * @id: int * value generated by this function.
+ *
+ * This function will populate @id with an unique
+ * id, using the idr API.
+ *
+ * Return: 0 on success, an error code on failure.
+ */
+static int get_idr(struct idr *idr, int *id)
+{
+       int ret;
+
+       mutex_lock(&devfreq_lock);
+       ret = idr_alloc(idr, NULL, 0, 0, GFP_KERNEL);
+       mutex_unlock(&devfreq_lock);
+       if (unlikely(ret < 0))
+               return ret;
+       *id = ret;
+
+       return 0;
+}
+
+/**
+ * release_idr - function to free the unique id.
+ * @idr: struct idr * handle used for creating the id.
+ * @id: int value representing the unique id.
+ */
+static void release_idr(struct idr *idr, int id)
+{
+       mutex_lock(&devfreq_lock);
+       idr_remove(idr, id);
+       mutex_unlock(&devfreq_lock);
+}
+
+/**
+ * partition_enable_opps() - disable all opps above a given state
+ * @dfc:       Pointer to devfreq we are operating on
+ * @cdev_state:        cooling device state we're setting
+ *
+ * Go through the OPPs of the device, enabling all OPPs until
+ * @cdev_state and disabling those frequencies above it.
+ */
+static int partition_enable_opps(struct devfreq_cooling_device *dfc,
+                                unsigned long cdev_state)
+{
+       int i;
+       struct device *dev = dfc->devfreq->dev.parent;
+
+       for (i = 0; i < dfc->freq_table_size; i++) {
+               struct dev_pm_opp *opp;
+               int ret = 0;
+               unsigned int freq = dfc->freq_table[i];
+               bool want_enable = i >= cdev_state ? true : false;
+
+               rcu_read_lock();
+               opp = dev_pm_opp_find_freq_exact(dev, freq, !want_enable);
+               rcu_read_unlock();
+
+               if (PTR_ERR(opp) == -ERANGE)
+                       continue;
+               else if (IS_ERR(opp))
+                       return PTR_ERR(opp);
+
+               if (want_enable)
+                       ret = dev_pm_opp_enable(dev, freq);
+               else
+                       ret = dev_pm_opp_disable(dev, freq);
+
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static int devfreq_cooling_get_max_state(struct thermal_cooling_device *cdev,
+                                        unsigned long *state)
+{
+       struct devfreq_cooling_device *dfc = cdev->devdata;
+
+       *state = dfc->freq_table_size - 1;
+
+       return 0;
+}
+
+static int devfreq_cooling_get_cur_state(struct thermal_cooling_device *cdev,
+                                        unsigned long *state)
+{
+       struct devfreq_cooling_device *dfc = cdev->devdata;
+
+       *state = dfc->cooling_state;
+
+       return 0;
+}
+
+static int devfreq_cooling_set_cur_state(struct thermal_cooling_device *cdev,
+                                        unsigned long state)
+{
+       struct devfreq_cooling_device *dfc = cdev->devdata;
+       struct devfreq *df = dfc->devfreq;
+       struct device *dev = df->dev.parent;
+       int ret;
+
+       if (state == dfc->cooling_state)
+               return 0;
+
+       dev_dbg(dev, "Setting cooling state %lu\n", state);
+
+       if (state >= dfc->freq_table_size)
+               return -EINVAL;
+
+       ret = partition_enable_opps(dfc, state);
+       if (ret)
+               return ret;
+
+       dfc->cooling_state = state;
+
+       return 0;
+}
+
+/**
+ * freq_get_state() - get the cooling state corresponding to a frequency
+ * @dfc:       Pointer to devfreq cooling device
+ * @freq:      frequency in Hz
+ *
+ * Return: the cooling state associated with the @freq, or
+ * THERMAL_CSTATE_INVALID if it wasn't found.
+ */
+static unsigned long
+freq_get_state(struct devfreq_cooling_device *dfc, unsigned long freq)
+{
+       int i;
+
+       for (i = 0; i < dfc->freq_table_size; i++) {
+               if (dfc->freq_table[i] == freq)
+                       return i;
+       }
+
+       return THERMAL_CSTATE_INVALID;
+}
+
+/**
+ * get_static_power() - calculate the static power
+ * @dfc:       Pointer to devfreq cooling device
+ * @freq:      Frequency in Hz
+ *
+ * Calculate the static power in milliwatts using the supplied
+ * get_static_power().  The current voltage is calculated using the
+ * OPP library.  If no get_static_power() was supplied, assume the
+ * static power is negligible.
+ */
+static unsigned long
+get_static_power(struct devfreq_cooling_device *dfc, unsigned long freq)
+{
+       struct devfreq *df = dfc->devfreq;
+       struct device *dev = df->dev.parent;
+       unsigned long voltage;
+       struct dev_pm_opp *opp;
+
+       if (!dfc->power_ops->get_static_power)
+               return 0;
+
+       rcu_read_lock();
+
+       opp = dev_pm_opp_find_freq_exact(dev, freq, true);
+       if (IS_ERR(opp) && (PTR_ERR(opp) == -ERANGE))
+               opp = dev_pm_opp_find_freq_exact(dev, freq, false);
+
+       voltage = dev_pm_opp_get_voltage(opp) / 1000; /* mV */
+
+       rcu_read_unlock();
+
+       if (voltage == 0) {
+               dev_warn_ratelimited(dev,
+                                    "Failed to get voltage for frequency %lu: %ld\n",
+                                    freq, IS_ERR(opp) ? PTR_ERR(opp) : 0);
+               return 0;
+       }
+
+       return dfc->power_ops->get_static_power(voltage);
+}
+
+/**
+ * get_dynamic_power - calculate the dynamic power
+ * @dfc:       Pointer to devfreq cooling device
+ * @freq:      Frequency in Hz
+ * @voltage:   Voltage in millivolts
+ *
+ * Calculate the dynamic power in milliwatts consumed by the device at
+ * frequency @freq and voltage @voltage.  If the get_dynamic_power()
+ * was supplied as part of the devfreq_cooling_power struct, then that
+ * function is used.  Otherwise, a simple power model (Pdyn = Coeff *
+ * Voltage^2 * Frequency) is used.
+ */
+static unsigned long
+get_dynamic_power(struct devfreq_cooling_device *dfc, unsigned long freq,
+                 unsigned long voltage)
+{
+       u64 power;
+       u32 freq_mhz;
+       struct devfreq_cooling_power *dfc_power = dfc->power_ops;
+
+       if (dfc_power->get_dynamic_power)
+               return dfc_power->get_dynamic_power(freq, voltage);
+
+       freq_mhz = freq / 1000000;
+       power = (u64)dfc_power->dyn_power_coeff * freq_mhz * voltage * voltage;
+       do_div(power, 1000000000);
+
+       return power;
+}
+
+static int devfreq_cooling_get_requested_power(struct thermal_cooling_device *cdev,
+                                              struct thermal_zone_device *tz,
+                                              u32 *power)
+{
+       struct devfreq_cooling_device *dfc = cdev->devdata;
+       struct devfreq *df = dfc->devfreq;
+       struct devfreq_dev_status *status = &df->last_status;
+       unsigned long state;
+       unsigned long freq = status->current_frequency;
+       u32 dyn_power, static_power;
+
+       /* Get dynamic power for state */
+       state = freq_get_state(dfc, freq);
+       if (state == THERMAL_CSTATE_INVALID)
+               return -EAGAIN;
+
+       dyn_power = dfc->power_table[state];
+
+       /* Scale dynamic power for utilization */
+       dyn_power = (dyn_power * status->busy_time) / status->total_time;
+
+       /* Get static power */
+       static_power = get_static_power(dfc, freq);
+
+       trace_thermal_power_devfreq_get_power(cdev, status, freq, dyn_power,
+                                             static_power);
+
+       *power = dyn_power + static_power;
+
+       return 0;
+}
+
+static int devfreq_cooling_state2power(struct thermal_cooling_device *cdev,
+                                      struct thermal_zone_device *tz,
+                                      unsigned long state,
+                                      u32 *power)
+{
+       struct devfreq_cooling_device *dfc = cdev->devdata;
+       unsigned long freq;
+       u32 static_power;
+
+       if (state < 0 || state >= dfc->freq_table_size)
+               return -EINVAL;
+
+       freq = dfc->freq_table[state];
+       static_power = get_static_power(dfc, freq);
+
+       *power = dfc->power_table[state] + static_power;
+       return 0;
+}
+
+static int devfreq_cooling_power2state(struct thermal_cooling_device *cdev,
+                                      struct thermal_zone_device *tz,
+                                      u32 power, unsigned long *state)
+{
+       struct devfreq_cooling_device *dfc = cdev->devdata;
+       struct devfreq *df = dfc->devfreq;
+       struct devfreq_dev_status *status = &df->last_status;
+       unsigned long freq = status->current_frequency;
+       unsigned long busy_time;
+       s32 dyn_power;
+       u32 static_power;
+       int i;
+
+       static_power = get_static_power(dfc, freq);
+
+       dyn_power = power - static_power;
+       dyn_power = dyn_power > 0 ? dyn_power : 0;
+
+       /* Scale dynamic power for utilization */
+       busy_time = status->busy_time ?: 1;
+       dyn_power = (dyn_power * status->total_time) / busy_time;
+
+       /*
+        * Find the first cooling state that is within the power
+        * budget for dynamic power.
+        */
+       for (i = 0; i < dfc->freq_table_size - 1; i++)
+               if (dyn_power >= dfc->power_table[i])
+                       break;
+
+       *state = i;
+       trace_thermal_power_devfreq_limit(cdev, freq, *state, power);
+       return 0;
+}
+
+static struct thermal_cooling_device_ops devfreq_cooling_ops = {
+       .get_max_state = devfreq_cooling_get_max_state,
+       .get_cur_state = devfreq_cooling_get_cur_state,
+       .set_cur_state = devfreq_cooling_set_cur_state,
+};
+
+/**
+ * devfreq_cooling_gen_tables() - Generate power and freq tables.
+ * @dfc: Pointer to devfreq cooling device.
+ *
+ * Generate power and frequency tables: the power table hold the
+ * device's maximum power usage at each cooling state (OPP).  The
+ * static and dynamic power using the appropriate voltage and
+ * frequency for the state, is acquired from the struct
+ * devfreq_cooling_power, and summed to make the maximum power draw.
+ *
+ * The frequency table holds the frequencies in descending order.
+ * That way its indexed by cooling device state.
+ *
+ * The tables are malloced, and pointers put in dfc.  They must be
+ * freed when unregistering the devfreq cooling device.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+static int devfreq_cooling_gen_tables(struct devfreq_cooling_device *dfc)
+{
+       struct devfreq *df = dfc->devfreq;
+       struct device *dev = df->dev.parent;
+       int ret, num_opps;
+       unsigned long freq;
+       u32 *power_table = NULL;
+       u32 *freq_table;
+       int i;
+
+       num_opps = dev_pm_opp_get_opp_count(dev);
+
+       if (dfc->power_ops) {
+               power_table = kcalloc(num_opps, sizeof(*power_table),
+                                     GFP_KERNEL);
+               if (!power_table)
+                       return -ENOMEM;
+       }
+
+       freq_table = kcalloc(num_opps, sizeof(*freq_table),
+                            GFP_KERNEL);
+       if (!freq_table) {
+               ret = -ENOMEM;
+               goto free_power_table;
+       }
+
+       for (i = 0, freq = ULONG_MAX; i < num_opps; i++, freq--) {
+               unsigned long power_dyn, voltage;
+               struct dev_pm_opp *opp;
+
+               rcu_read_lock();
+
+               opp = dev_pm_opp_find_freq_floor(dev, &freq);
+               if (IS_ERR(opp)) {
+                       rcu_read_unlock();
+                       ret = PTR_ERR(opp);
+                       goto free_tables;
+               }
+
+               voltage = dev_pm_opp_get_voltage(opp) / 1000; /* mV */
+
+               rcu_read_unlock();
+
+               if (dfc->power_ops) {
+                       power_dyn = get_dynamic_power(dfc, freq, voltage);
+
+                       dev_dbg(dev, "Dynamic power table: %lu MHz @ %lu mV: %lu = %lu mW\n",
+                               freq / 1000000, voltage, power_dyn, power_dyn);
+
+                       power_table[i] = power_dyn;
+               }
+
+               freq_table[i] = freq;
+       }
+
+       if (dfc->power_ops)
+               dfc->power_table = power_table;
+
+       dfc->freq_table = freq_table;
+       dfc->freq_table_size = num_opps;
+
+       return 0;
+
+free_tables:
+       kfree(freq_table);
+free_power_table:
+       kfree(power_table);
+
+       return ret;
+}
+
+/**
+ * of_devfreq_cooling_register_power() - Register devfreq cooling device,
+ *                                      with OF and power information.
+ * @np:        Pointer to OF device_node.
+ * @df:        Pointer to devfreq device.
+ * @dfc_power: Pointer to devfreq_cooling_power.
+ *
+ * Register a devfreq cooling device.  The available OPPs must be
+ * registered on the device.
+ *
+ * If @dfc_power is provided, the cooling device is registered with the
+ * power extensions.  For the power extensions to work correctly,
+ * devfreq should use the simple_ondemand governor, other governors
+ * are not currently supported.
+ */
+struct thermal_cooling_device *
+of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df,
+                                 struct devfreq_cooling_power *dfc_power)
+{
+       struct thermal_cooling_device *cdev;
+       struct devfreq_cooling_device *dfc;
+       char dev_name[THERMAL_NAME_LENGTH];
+       int err;
+
+       dfc = kzalloc(sizeof(*dfc), GFP_KERNEL);
+       if (!dfc)
+               return ERR_PTR(-ENOMEM);
+
+       dfc->devfreq = df;
+
+       if (dfc_power) {
+               dfc->power_ops = dfc_power;
+
+               devfreq_cooling_ops.get_requested_power =
+                       devfreq_cooling_get_requested_power;
+               devfreq_cooling_ops.state2power = devfreq_cooling_state2power;
+               devfreq_cooling_ops.power2state = devfreq_cooling_power2state;
+       }
+
+       err = devfreq_cooling_gen_tables(dfc);
+       if (err)
+               goto free_dfc;
+
+       err = get_idr(&devfreq_idr, &dfc->id);
+       if (err)
+               goto free_tables;
+
+       snprintf(dev_name, sizeof(dev_name), "thermal-devfreq-%d", dfc->id);
+
+       cdev = thermal_of_cooling_device_register(np, dev_name, dfc,
+                                                 &devfreq_cooling_ops);
+       if (IS_ERR(cdev)) {
+               err = PTR_ERR(cdev);
+               dev_err(df->dev.parent,
+                       "Failed to register devfreq cooling device (%d)\n",
+                       err);
+               goto release_idr;
+       }
+
+       dfc->cdev = cdev;
+
+       return cdev;
+
+release_idr:
+       release_idr(&devfreq_idr, dfc->id);
+free_tables:
+       kfree(dfc->power_table);
+       kfree(dfc->freq_table);
+free_dfc:
+       kfree(dfc);
+
+       return ERR_PTR(err);
+}
+EXPORT_SYMBOL_GPL(of_devfreq_cooling_register_power);
+
+/**
+ * of_devfreq_cooling_register() - Register devfreq cooling device,
+ *                                with OF information.
+ * @np: Pointer to OF device_node.
+ * @df: Pointer to devfreq device.
+ */
+struct thermal_cooling_device *
+of_devfreq_cooling_register(struct device_node *np, struct devfreq *df)
+{
+       return of_devfreq_cooling_register_power(np, df, NULL);
+}
+EXPORT_SYMBOL_GPL(of_devfreq_cooling_register);
+
+/**
+ * devfreq_cooling_register() - Register devfreq cooling device.
+ * @df: Pointer to devfreq device.
+ */
+struct thermal_cooling_device *devfreq_cooling_register(struct devfreq *df)
+{
+       return of_devfreq_cooling_register(NULL, df);
+}
+EXPORT_SYMBOL_GPL(devfreq_cooling_register);
+
+/**
+ * devfreq_cooling_unregister() - Unregister devfreq cooling device.
+ * @dfc: Pointer to devfreq cooling device to unregister.
+ */
+void devfreq_cooling_unregister(struct thermal_cooling_device *cdev)
+{
+       struct devfreq_cooling_device *dfc;
+
+       if (!cdev)
+               return;
+
+       dfc = cdev->devdata;
+
+       thermal_cooling_device_unregister(dfc->cdev);
+       release_idr(&devfreq_idr, dfc->id);
+       kfree(dfc->power_table);
+       kfree(dfc->freq_table);
+
+       kfree(dfc);
+}
+EXPORT_SYMBOL_GPL(devfreq_cooling_unregister);
index 4bec1d3c3d27bba4438ea37f26c9ffdf2e749fe5..c8fe3cac2e0e04d8196694f264b6d9f4fcd5cc5d 100644 (file)
@@ -288,7 +288,7 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip,
        if (trip == IMX_TRIP_CRITICAL)
                return -EPERM;
 
-       if (temp > IMX_TEMP_PASSIVE)
+       if (temp < 0 || temp > IMX_TEMP_PASSIVE)
                return -EINVAL;
 
        data->temp_passive = temp;
@@ -487,14 +487,6 @@ static int imx_thermal_probe(struct platform_device *pdev)
        if (data->irq < 0)
                return data->irq;
 
-       ret = devm_request_threaded_irq(&pdev->dev, data->irq,
-                       imx_thermal_alarm_irq, imx_thermal_alarm_irq_thread,
-                       0, "imx_thermal", data);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "failed to request alarm irq: %d\n", ret);
-               return ret;
-       }
-
        platform_set_drvdata(pdev, data);
 
        ret = imx_get_sensor_data(pdev);
@@ -571,6 +563,17 @@ static int imx_thermal_probe(struct platform_device *pdev)
        regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN);
        regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP);
 
+       ret = devm_request_threaded_irq(&pdev->dev, data->irq,
+                       imx_thermal_alarm_irq, imx_thermal_alarm_irq_thread,
+                       0, "imx_thermal", data);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "failed to request alarm irq: %d\n", ret);
+               clk_disable_unprepare(data->thermal_clk);
+               thermal_zone_device_unregister(data->tz);
+               cpufreq_cooling_unregister(data->cdev);
+               return ret;
+       }
+
        data->irq_enabled = true;
        data->mode = THERMAL_DEVICE_ENABLED;
 
index c89ffb26a35434e67f38c7dfef3a6800cb29b83b..9787e8aa509fc406ab4fe5c8ff46811bac19b2de 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/platform_device.h>
 #include <linux/reset.h>
 #include <linux/thermal.h>
+#include <linux/pinctrl/consumer.h>
 
 /**
  * If the temperature over a period of time High,
@@ -106,16 +107,14 @@ struct rockchip_thermal_data {
 #define TSADCV2_AUTO_PERIOD_HT                 0x6c
 
 #define TSADCV2_AUTO_EN                                BIT(0)
-#define TSADCV2_AUTO_DISABLE                   ~BIT(0)
 #define TSADCV2_AUTO_SRC_EN(chn)               BIT(4 + (chn))
 #define TSADCV2_AUTO_TSHUT_POLARITY_HIGH       BIT(8)
-#define TSADCV2_AUTO_TSHUT_POLARITY_LOW                ~BIT(8)
 
 #define TSADCV2_INT_SRC_EN(chn)                        BIT(chn)
 #define TSADCV2_SHUT_2GPIO_SRC_EN(chn)         BIT(4 + (chn))
 #define TSADCV2_SHUT_2CRU_SRC_EN(chn)          BIT(8 + (chn))
 
-#define TSADCV2_INT_PD_CLEAR                   ~BIT(8)
+#define TSADCV2_INT_PD_CLEAR_MASK              ~BIT(8)
 
 #define TSADCV2_DATA_MASK                      0xfff
 #define TSADCV2_HIGHT_INT_DEBOUNCE_COUNT       4
@@ -124,7 +123,7 @@ struct rockchip_thermal_data {
 #define TSADCV2_AUTO_PERIOD_HT_TIME            50  /* msec */
 
 struct tsadc_table {
-       unsigned long code;
+       u32 code;
        long temp;
 };
 
@@ -164,7 +163,6 @@ static const struct tsadc_table v2_code_table[] = {
        {3452, 115000},
        {3437, 120000},
        {3421, 125000},
-       {0, 125000},
 };
 
 static u32 rk_tsadcv2_temp_to_code(long temp)
@@ -191,19 +189,21 @@ static u32 rk_tsadcv2_temp_to_code(long temp)
        return 0;
 }
 
-static int rk_tsadcv2_code_to_temp(u32 code)
+static int rk_tsadcv2_code_to_temp(u32 code, int *temp)
 {
-       unsigned int low = 0;
+       unsigned int low = 1;
        unsigned int high = ARRAY_SIZE(v2_code_table) - 1;
        unsigned int mid = (low + high) / 2;
        unsigned int num;
        unsigned long denom;
 
-       /* Invalid code, return -EAGAIN */
-       if (code > TSADCV2_DATA_MASK)
-               return -EAGAIN;
+       BUILD_BUG_ON(ARRAY_SIZE(v2_code_table) < 2);
 
-       while (low <= high && mid) {
+       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;
@@ -223,7 +223,9 @@ static int rk_tsadcv2_code_to_temp(u32 code)
        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;
-       return v2_code_table[mid - 1].temp + (num / denom);
+       *temp = v2_code_table[mid - 1].temp + (num / denom);
+
+       return 0;
 }
 
 /**
@@ -241,10 +243,10 @@ static void rk_tsadcv2_initialize(void __iomem *regs,
                                  enum tshut_polarity tshut_polarity)
 {
        if (tshut_polarity == TSHUT_HIGH_ACTIVE)
-               writel_relaxed(0 | (TSADCV2_AUTO_TSHUT_POLARITY_HIGH),
+               writel_relaxed(0U | TSADCV2_AUTO_TSHUT_POLARITY_HIGH,
                               regs + TSADCV2_AUTO_CON);
        else
-               writel_relaxed(0 | (TSADCV2_AUTO_TSHUT_POLARITY_LOW),
+               writel_relaxed(0U & ~TSADCV2_AUTO_TSHUT_POLARITY_HIGH,
                               regs + TSADCV2_AUTO_CON);
 
        writel_relaxed(TSADCV2_AUTO_PERIOD_TIME, regs + TSADCV2_AUTO_PERIOD);
@@ -261,7 +263,7 @@ static void rk_tsadcv2_irq_ack(void __iomem *regs)
        u32 val;
 
        val = readl_relaxed(regs + TSADCV2_INT_PD);
-       writel_relaxed(val & TSADCV2_INT_PD_CLEAR, regs + TSADCV2_INT_PD);
+       writel_relaxed(val & TSADCV2_INT_PD_CLEAR_MASK, regs + TSADCV2_INT_PD);
 }
 
 static void rk_tsadcv2_control(void __iomem *regs, bool enable)
@@ -281,14 +283,9 @@ static int rk_tsadcv2_get_temp(int chn, void __iomem *regs, int *temp)
 {
        u32 val;
 
-       /* the A/D value of the channel last conversion need some time */
        val = readl_relaxed(regs + TSADCV2_DATA(chn));
-       if (val == 0)
-               return -EAGAIN;
 
-       *temp = rk_tsadcv2_code_to_temp(val);
-
-       return 0;
+       return rk_tsadcv2_code_to_temp(val, temp);
 }
 
 static void rk_tsadcv2_tshut_temp(int chn, void __iomem *regs, long temp)
@@ -642,6 +639,8 @@ static int __maybe_unused rockchip_thermal_suspend(struct device *dev)
        clk_disable(thermal->pclk);
        clk_disable(thermal->clk);
 
+       pinctrl_pm_select_sleep_state(dev);
+
        return 0;
 }
 
@@ -678,6 +677,8 @@ static int __maybe_unused rockchip_thermal_resume(struct device *dev)
        for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++)
                rockchip_thermal_toggle_sensor(&thermal->sensors[i], true);
 
+       pinctrl_pm_select_default_state(dev);
+
        return 0;
 }
 
index ca920b0ecf8f8688763426ba2d6b253a3620a1b6..fa61eff88496e541334043f5457f1f989dd7e480 100644 (file)
@@ -548,7 +548,7 @@ static int exynos5433_tmu_initialize(struct platform_device *pdev)
        default:
                pdata->cal_type = TYPE_ONE_POINT_TRIMMING;
                break;
-       };
+       }
 
        dev_info(&pdev->dev, "Calibration type is %d-point calibration\n",
                        cal_type ?  2 : 1);
@@ -608,7 +608,7 @@ static int exynos5440_tmu_initialize(struct platform_device *pdev)
 {
        struct exynos_tmu_data *data = platform_get_drvdata(pdev);
        unsigned int trim_info = 0, con, rising_threshold;
-       int ret = 0, threshold_code;
+       int threshold_code;
        int crit_temp = 0;
 
        /*
@@ -651,7 +651,8 @@ static int exynos5440_tmu_initialize(struct platform_device *pdev)
        /* Clear the PMIN in the common TMU register */
        if (!data->id)
                writel(0, data->base_second + EXYNOS5440_TMU_PMIN);
-       return ret;
+
+       return 0;
 }
 
 static int exynos7_tmu_initialize(struct platform_device *pdev)
@@ -1168,27 +1169,10 @@ static int exynos_map_dt_data(struct platform_device *pdev)
        struct exynos_tmu_data *data = platform_get_drvdata(pdev);
        struct exynos_tmu_platform_data *pdata;
        struct resource res;
-       int ret;
 
        if (!data || !pdev->dev.of_node)
                return -ENODEV;
 
-       /*
-        * Try enabling the regulator if found
-        * TODO: Add regulator as an SOC feature, so that regulator enable
-        * is a compulsory call.
-        */
-       data->regulator = devm_regulator_get(&pdev->dev, "vtmu");
-       if (!IS_ERR(data->regulator)) {
-               ret = regulator_enable(data->regulator);
-               if (ret) {
-                       dev_err(&pdev->dev, "failed to enable vtmu\n");
-                       return ret;
-               }
-       } else {
-               dev_info(&pdev->dev, "Regulator node (vtmu) not found\n");
-       }
-
        data->id = of_alias_get_id(pdev->dev.of_node, "tmuctrl");
        if (data->id < 0)
                data->id = 0;
@@ -1306,12 +1290,22 @@ static int exynos_tmu_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, data);
        mutex_init(&data->lock);
 
-       data->tzd = thermal_zone_of_sensor_register(&pdev->dev, 0, data,
-                                                   &exynos_sensor_ops);
-       if (IS_ERR(data->tzd)) {
-               pr_err("thermal: tz: %p ERROR\n", data->tzd);
-               return PTR_ERR(data->tzd);
+       /*
+        * Try enabling the regulator if found
+        * TODO: Add regulator as an SOC feature, so that regulator enable
+        * is a compulsory call.
+        */
+       data->regulator = devm_regulator_get(&pdev->dev, "vtmu");
+       if (!IS_ERR(data->regulator)) {
+               ret = regulator_enable(data->regulator);
+               if (ret) {
+                       dev_err(&pdev->dev, "failed to enable vtmu\n");
+                       return ret;
+               }
+       } else {
+               dev_info(&pdev->dev, "Regulator node (vtmu) not found\n");
        }
+
        ret = exynos_map_dt_data(pdev);
        if (ret)
                goto err_sensor;
@@ -1363,23 +1357,38 @@ static int exynos_tmu_probe(struct platform_device *pdev)
                break;
        default:
                break;
-       };
+       }
+
+       /*
+        * data->tzd must be registered before calling exynos_tmu_initialize(),
+        * requesting irq and calling exynos_tmu_control().
+        */
+       data->tzd = thermal_zone_of_sensor_register(&pdev->dev, 0, data,
+                                                   &exynos_sensor_ops);
+       if (IS_ERR(data->tzd)) {
+               ret = PTR_ERR(data->tzd);
+               dev_err(&pdev->dev, "Failed to register sensor: %d\n", ret);
+               goto err_sclk;
+       }
 
        ret = exynos_tmu_initialize(pdev);
        if (ret) {
                dev_err(&pdev->dev, "Failed to initialize TMU\n");
-               goto err_sclk;
+               goto err_thermal;
        }
 
        ret = devm_request_irq(&pdev->dev, data->irq, exynos_tmu_irq,
                IRQF_TRIGGER_RISING | IRQF_SHARED, dev_name(&pdev->dev), data);
        if (ret) {
                dev_err(&pdev->dev, "Failed to request irq: %d\n", data->irq);
-               goto err_sclk;
+               goto err_thermal;
        }
 
        exynos_tmu_control(pdev, true);
        return 0;
+
+err_thermal:
+       thermal_zone_of_sensor_unregister(&pdev->dev, data->tzd);
 err_sclk:
        clk_disable_unprepare(data->sclk);
 err_clk:
@@ -1388,9 +1397,8 @@ err_clk_sec:
        if (!IS_ERR(data->clk_sec))
                clk_unprepare(data->clk_sec);
 err_sensor:
-       if (!IS_ERR_OR_NULL(data->regulator))
+       if (!IS_ERR(data->regulator))
                regulator_disable(data->regulator);
-       thermal_zone_of_sensor_unregister(&pdev->dev, data->tzd);
 
        return ret;
 }
index cb6686ff09ae9d64b18f68c7a1854f7694ee3ce4..ea8283f08aa68020cf3f7e5c7e7927d2be5b8b84 100644 (file)
@@ -19,6 +19,21 @@ config TI_THERMAL
          This includes trip points definitions, extrapolation rules and
          CPU cooling device bindings.
 
+config OMAP3_THERMAL
+       bool "Texas Instruments OMAP3 thermal support"
+       depends on TI_SOC_THERMAL
+       depends on ARCH_OMAP3 || COMPILE_TEST
+       help
+         If you say yes here you get thermal support for the Texas Instruments
+         OMAP3 SoC family. The current chips supported are:
+          - OMAP3430
+
+         OMAP3 chips normally don't need thermal management, and sensors in
+         this generation are not accurate, nor they are very close to
+         the important hotspots.
+
+         Say 'N' here.
+
 config OMAP4_THERMAL
        bool "Texas Instruments OMAP4 thermal support"
        depends on TI_SOC_THERMAL
index 1226b2484e550cba08e6233c6fdb56f02a54fef0..0f89bdf037909b10ff2012c5f3951fdb0cc6a222 100644 (file)
@@ -2,5 +2,6 @@ obj-$(CONFIG_TI_SOC_THERMAL)            += ti-soc-thermal.o
 ti-soc-thermal-y                       := ti-bandgap.o
 ti-soc-thermal-$(CONFIG_TI_THERMAL)    += ti-thermal-common.o
 ti-soc-thermal-$(CONFIG_DRA752_THERMAL)        += dra752-thermal-data.o
+ti-soc-thermal-$(CONFIG_OMAP3_THERMAL) += omap3-thermal-data.o
 ti-soc-thermal-$(CONFIG_OMAP4_THERMAL) += omap4-thermal-data.o
 ti-soc-thermal-$(CONFIG_OMAP5_THERMAL) += omap5-thermal-data.o
diff --git a/drivers/thermal/ti-soc-thermal/omap3-thermal-data.c b/drivers/thermal/ti-soc-thermal/omap3-thermal-data.c
new file mode 100644 (file)
index 0000000..3ee3434
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * OMAP3 thermal driver.
+ *
+ * Copyright (C) 2011-2012 Texas Instruments Inc.
+ * Copyright (C) 2014 Pavel Machek <pavel@ucw.cz>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ * Note
+ * http://www.ti.com/lit/er/sprz278f/sprz278f.pdf "Advisory
+ * 3.1.1.186 MMC OCP Clock Not Gated When Thermal Sensor Is Used"
+ *
+ * Also TI says:
+ * Just be careful when you try to make thermal policy like decisions
+ * based on this sensor. Placement of the sensor w.r.t the actual logic
+ * generating heat has to be a factor as well. If you are just looking
+ * for an approximation temperature (thermometerish kind), you might be
+ * ok with this. I am not sure we'd find any TI data around this.. just a
+ * heads up.
+ */
+
+#include "ti-thermal.h"
+#include "ti-bandgap.h"
+
+/*
+ * OMAP34XX has one instance of thermal sensor for MPU
+ * need to describe the individual bit fields
+ */
+static struct temp_sensor_registers
+omap34xx_mpu_temp_sensor_registers = {
+       .temp_sensor_ctrl = 0,
+       .bgap_soc_mask = BIT(8),
+       .bgap_eocz_mask = BIT(7),
+       .bgap_dtemp_mask = 0x7f,
+
+       .bgap_mode_ctrl = 0,
+       .mode_ctrl_mask = BIT(9),
+};
+
+/* Thresholds and limits for OMAP34XX MPU temperature sensor */
+static struct temp_sensor_data omap34xx_mpu_temp_sensor_data = {
+       .min_freq = 32768,
+       .max_freq = 32768,
+       .max_temp = 125000,
+       .min_temp = -40000,
+       .hyst_val = 5000,
+};
+
+/*
+ * Temperature values in milli degree celsius
+ */
+static const int
+omap34xx_adc_to_temp[128] = {
+       -40000, -40000, -40000, -40000, -40000, -39000, -38000, -36000,
+       -34000, -32000, -31000, -29000, -28000, -26000, -25000, -24000,
+       -22000, -21000, -19000, -18000, -17000, -15000, -14000, -12000,
+       -11000, -9000, -8000, -7000, -5000, -4000, -2000, -1000, 0000,
+       1000, 3000, 4000, 5000, 7000, 8000, 10000, 11000, 13000, 14000,
+       15000, 17000, 18000, 20000, 21000, 22000, 24000, 25000, 27000,
+       28000, 30000, 31000, 32000, 34000, 35000, 37000, 38000, 39000,
+       41000, 42000, 44000, 45000, 47000, 48000, 49000, 51000, 52000,
+       53000, 55000, 56000, 58000, 59000, 60000, 62000, 63000, 65000,
+       66000, 67000, 69000, 70000, 72000, 73000, 74000, 76000, 77000,
+       79000, 80000, 81000, 83000, 84000, 85000, 87000, 88000, 89000,
+       91000, 92000, 94000, 95000, 96000, 98000, 99000, 100000,
+       102000, 103000, 105000, 106000, 107000, 109000, 110000, 111000,
+       113000, 114000, 116000, 117000, 118000, 120000, 121000, 122000,
+       124000, 124000, 125000, 125000, 125000, 125000, 125000
+};
+
+/* OMAP34XX data */
+const struct ti_bandgap_data omap34xx_data = {
+       .features = TI_BANDGAP_FEATURE_CLK_CTRL | TI_BANDGAP_FEATURE_UNRELIABLE,
+       .fclock_name = "ts_fck",
+       .div_ck_name = "ts_fck",
+       .conv_table = omap34xx_adc_to_temp,
+       .adc_start_val = 0,
+       .adc_end_val = 127,
+       .expose_sensor = ti_thermal_expose_sensor,
+       .remove_sensor = ti_thermal_remove_sensor,
+
+       .sensors = {
+               {
+               .registers = &omap34xx_mpu_temp_sensor_registers,
+               .ts_data = &omap34xx_mpu_temp_sensor_data,
+               .domain = "cpu",
+               .slope = 0,
+               .constant = 20000,
+               .slope_pcb = 0,
+               .constant_pcb = 20000,
+               .register_cooling = NULL,
+               .unregister_cooling = NULL,
+               },
+       },
+       .sensor_count = 1,
+};
+
+/*
+ * OMAP36XX has one instance of thermal sensor for MPU
+ * need to describe the individual bit fields
+ */
+static struct temp_sensor_registers
+omap36xx_mpu_temp_sensor_registers = {
+       .temp_sensor_ctrl = 0,
+       .bgap_soc_mask = BIT(9),
+       .bgap_eocz_mask = BIT(8),
+       .bgap_dtemp_mask = 0xFF,
+
+       .bgap_mode_ctrl = 0,
+       .mode_ctrl_mask = BIT(10),
+};
+
+/* Thresholds and limits for OMAP36XX MPU temperature sensor */
+static struct temp_sensor_data omap36xx_mpu_temp_sensor_data = {
+       .min_freq = 32768,
+       .max_freq = 32768,
+       .max_temp = 125000,
+       .min_temp = -40000,
+       .hyst_val = 5000,
+};
+
+/*
+ * Temperature values in milli degree celsius
+ */
+static const int
+omap36xx_adc_to_temp[128] = {
+       -40000, -40000, -40000, -40000, -40000, -40000, -40000, -40000,
+       -40000, -40000, -40000, -40000, -40000, -38000, -35000, -34000,
+       -32000, -30000, -28000, -26000, -24000, -22000, -20000, -18500,
+       -17000, -15000, -13500, -12000, -10000, -8000, -6500, -5000, -3500,
+       -1500, 0, 2000, 3500, 5000, 6500, 8500, 10000, 12000, 13500,
+       15000, 17000, 19000, 21000, 23000, 25000, 27000, 28500, 30000,
+       32000, 33500, 35000, 37000, 38500, 40000, 42000, 43500, 45000,
+       47000, 48500, 50000, 52000, 53500, 55000, 57000, 58500, 60000,
+       62000, 64000, 66000, 68000, 70000, 71500, 73500, 75000, 77000,
+       78500, 80000, 82000, 83500, 85000, 87000, 88500, 90000, 92000,
+       93500, 95000, 97000, 98500, 100000, 102000, 103500, 105000, 107000,
+       109000, 111000, 113000, 115000, 117000, 118500, 120000, 122000,
+       123500, 125000, 125000, 125000, 125000, 125000, 125000, 125000,
+       125000, 125000, 125000, 125000, 125000, 125000, 125000, 125000,
+       125000, 125000, 125000, 125000, 125000, 125000, 125000
+};
+
+/* OMAP36XX data */
+const struct ti_bandgap_data omap36xx_data = {
+       .features = TI_BANDGAP_FEATURE_CLK_CTRL | TI_BANDGAP_FEATURE_UNRELIABLE,
+       .fclock_name = "ts_fck",
+       .div_ck_name = "ts_fck",
+       .conv_table = omap36xx_adc_to_temp,
+       .adc_start_val = 0,
+       .adc_end_val = 127,
+       .expose_sensor = ti_thermal_expose_sensor,
+       .remove_sensor = ti_thermal_remove_sensor,
+
+       .sensors = {
+               {
+               .registers = &omap36xx_mpu_temp_sensor_registers,
+               .ts_data = &omap36xx_mpu_temp_sensor_data,
+               .domain = "cpu",
+               .slope = 0,
+               .constant = 20000,
+               .slope_pcb = 0,
+               .constant_pcb = 20000,
+               .register_cooling = NULL,
+               .unregister_cooling = NULL,
+               },
+       },
+       .sensor_count = 1,
+};
index 10c47c048f7a3b0e4f5538c3698492fd5482c21b..1e34a1efc55431f3e05ebacba315756e8a9cd958 100644 (file)
@@ -1274,6 +1274,10 @@ int ti_bandgap_probe(struct platform_device *pdev)
        }
        bgp->dev = &pdev->dev;
 
+       if (TI_BANDGAP_HAS(bgp, UNRELIABLE))
+               dev_warn(&pdev->dev,
+                        "This OMAP thermal sensor is unreliable. You've been warned\n");
+
        if (TI_BANDGAP_HAS(bgp, TSHUT)) {
                ret = ti_bandgap_tshut_init(bgp, pdev);
                if (ret) {
@@ -1579,6 +1583,16 @@ static SIMPLE_DEV_PM_OPS(ti_bandgap_dev_pm_ops, ti_bandgap_suspend,
 #endif
 
 static const struct of_device_id of_ti_bandgap_match[] = {
+#ifdef CONFIG_OMAP3_THERMAL
+       {
+               .compatible = "ti,omap34xx-bandgap",
+               .data = (void *)&omap34xx_data,
+       },
+       {
+               .compatible = "ti,omap36xx-bandgap",
+               .data = (void *)&omap36xx_data,
+       },
+#endif
 #ifdef CONFIG_OMAP4_THERMAL
        {
                .compatible = "ti,omap4430-bandgap",
index 0c52f7afba00b5335adbeba60cd31f547d2256a3..fe0adb898764901b841d31b3696c5b5c15f15cac 100644 (file)
@@ -322,6 +322,8 @@ struct ti_temp_sensor {
  *     has Errata 814
  * TI_BANDGAP_FEATURE_ERRATA_813 - used to workaorund when the bandgap device
  *     has Errata 813
+ * TI_BANDGAP_FEATURE_UNRELIABLE - used when the sensor readings are too
+ *     inaccurate.
  * TI_BANDGAP_HAS(b, f) - macro to check if a bandgap device is capable of a
  *      specific feature (above) or not. Return non-zero, if yes.
  */
@@ -337,6 +339,7 @@ struct ti_temp_sensor {
 #define TI_BANDGAP_FEATURE_HISTORY_BUFFER      BIT(9)
 #define TI_BANDGAP_FEATURE_ERRATA_814          BIT(10)
 #define TI_BANDGAP_FEATURE_ERRATA_813          BIT(11)
+#define TI_BANDGAP_FEATURE_UNRELIABLE          BIT(12)
 #define TI_BANDGAP_HAS(b, f)                   \
                        ((b)->conf->features & TI_BANDGAP_FEATURE_ ## f)
 
@@ -390,6 +393,14 @@ int ti_bandgap_set_sensor_data(struct ti_bandgap *bgp, int id, void *data);
 void *ti_bandgap_get_sensor_data(struct ti_bandgap *bgp, int id);
 int ti_bandgap_get_trend(struct ti_bandgap *bgp, int id, int *trend);
 
+#ifdef CONFIG_OMAP3_THERMAL
+extern const struct ti_bandgap_data omap34xx_data;
+extern const struct ti_bandgap_data omap36xx_data;
+#else
+#define omap34xx_data                                  NULL
+#define omap36xx_data                                  NULL
+#endif
+
 #ifdef CONFIG_OMAP4_THERMAL
 extern const struct ti_bandgap_data omap4430_data;
 extern const struct ti_bandgap_data omap4460_data;
index 294eb74fb078508f6889902e1a0c841f3b603ece..163d305e1200bb07a73357d7b5824d97b362b924 100644 (file)
@@ -64,6 +64,11 @@ struct gadget_info {
        char qw_sign[OS_STRING_QW_SIGN_LEN];
 };
 
+static inline struct gadget_info *to_gadget_info(struct config_item *item)
+{
+        return container_of(to_config_group(item), struct gadget_info, group);
+}
+
 struct config_usb_cfg {
        struct config_group group;
        struct config_group strings_group;
@@ -74,6 +79,12 @@ struct config_usb_cfg {
        struct usb_gadget_strings *gstrings[MAX_USB_STRING_LANGS + 1];
 };
 
+static inline struct config_usb_cfg *to_config_usb_cfg(struct config_item *item)
+{
+       return container_of(to_config_group(item), struct config_usb_cfg,
+                       group);
+}
+
 struct gadget_strings {
        struct usb_gadget_strings stringtab_dev;
        struct usb_string strings[USB_GADGET_FIRST_AVAIL_IDX];
@@ -117,32 +128,25 @@ static int usb_string_copy(const char *s, char **s_copy)
        return 0;
 }
 
-CONFIGFS_ATTR_STRUCT(gadget_info);
-CONFIGFS_ATTR_STRUCT(config_usb_cfg);
-
-#define GI_DEVICE_DESC_ITEM_ATTR(name) \
-       static struct gadget_info_attribute gadget_cdev_desc_##name = \
-               __CONFIGFS_ATTR(name,  S_IRUGO | S_IWUSR,               \
-                               gadget_dev_desc_##name##_show,          \
-                               gadget_dev_desc_##name##_store)
-
 #define GI_DEVICE_DESC_SIMPLE_R_u8(__name)     \
-       static ssize_t gadget_dev_desc_##__name##_show(struct gadget_info *gi, \
+static ssize_t gadget_dev_desc_##__name##_show(struct config_item *item, \
                        char *page)     \
 {      \
-       return sprintf(page, "0x%02x\n", gi->cdev.desc.__name); \
+       return sprintf(page, "0x%02x\n", \
+               to_gadget_info(item)->cdev.desc.__name); \
 }
 
 #define GI_DEVICE_DESC_SIMPLE_R_u16(__name)    \
-       static ssize_t gadget_dev_desc_##__name##_show(struct gadget_info *gi, \
+static ssize_t gadget_dev_desc_##__name##_show(struct config_item *item, \
                        char *page)     \
 {      \
-       return sprintf(page, "0x%04x\n", le16_to_cpup(&gi->cdev.desc.__name)); \
+       return sprintf(page, "0x%04x\n", \
+               le16_to_cpup(&to_gadget_info(item)->cdev.desc.__name)); \
 }
 
 
 #define GI_DEVICE_DESC_SIMPLE_W_u8(_name)              \
-       static ssize_t gadget_dev_desc_##_name##_store(struct gadget_info *gi, \
+static ssize_t gadget_dev_desc_##_name##_store(struct config_item *item, \
                const char *page, size_t len)           \
 {                                                      \
        u8 val;                                         \
@@ -150,12 +154,12 @@ CONFIGFS_ATTR_STRUCT(config_usb_cfg);
        ret = kstrtou8(page, 0, &val);                  \
        if (ret)                                        \
                return ret;                             \
-       gi->cdev.desc._name = val;                      \
+       to_gadget_info(item)->cdev.desc._name = val;    \
        return len;                                     \
 }
 
 #define GI_DEVICE_DESC_SIMPLE_W_u16(_name)     \
-       static ssize_t gadget_dev_desc_##_name##_store(struct gadget_info *gi, \
+static ssize_t gadget_dev_desc_##_name##_store(struct config_item *item, \
                const char *page, size_t len)           \
 {                                                      \
        u16 val;                                        \
@@ -163,7 +167,7 @@ CONFIGFS_ATTR_STRUCT(config_usb_cfg);
        ret = kstrtou16(page, 0, &val);                 \
        if (ret)                                        \
                return ret;                             \
-       gi->cdev.desc._name = cpu_to_le16p(&val);       \
+       to_gadget_info(item)->cdev.desc._name = cpu_to_le16p(&val);     \
        return len;                                     \
 }
 
@@ -193,7 +197,7 @@ static ssize_t is_valid_bcd(u16 bcd_val)
        return 0;
 }
 
-static ssize_t gadget_dev_desc_bcdDevice_store(struct gadget_info *gi,
+static ssize_t gadget_dev_desc_bcdDevice_store(struct config_item *item,
                const char *page, size_t len)
 {
        u16 bcdDevice;
@@ -206,11 +210,11 @@ static ssize_t gadget_dev_desc_bcdDevice_store(struct gadget_info *gi,
        if (ret)
                return ret;
 
-       gi->cdev.desc.bcdDevice = cpu_to_le16(bcdDevice);
+       to_gadget_info(item)->cdev.desc.bcdDevice = cpu_to_le16(bcdDevice);
        return len;
 }
 
-static ssize_t gadget_dev_desc_bcdUSB_store(struct gadget_info *gi,
+static ssize_t gadget_dev_desc_bcdUSB_store(struct config_item *item,
                const char *page, size_t len)
 {
        u16 bcdUSB;
@@ -223,13 +227,13 @@ static ssize_t gadget_dev_desc_bcdUSB_store(struct gadget_info *gi,
        if (ret)
                return ret;
 
-       gi->cdev.desc.bcdUSB = cpu_to_le16(bcdUSB);
+       to_gadget_info(item)->cdev.desc.bcdUSB = cpu_to_le16(bcdUSB);
        return len;
 }
 
-static ssize_t gadget_dev_desc_UDC_show(struct gadget_info *gi, char *page)
+static ssize_t gadget_dev_desc_UDC_show(struct config_item *item, char *page)
 {
-       return sprintf(page, "%s\n", gi->udc_name ?: "");
+       return sprintf(page, "%s\n", to_gadget_info(item)->udc_name ?: "");
 }
 
 static int unregister_gadget(struct gadget_info *gi)
@@ -247,9 +251,10 @@ static int unregister_gadget(struct gadget_info *gi)
        return 0;
 }
 
-static ssize_t gadget_dev_desc_UDC_store(struct gadget_info *gi,
+static ssize_t gadget_dev_desc_UDC_store(struct config_item *item,
                const char *page, size_t len)
 {
+       struct gadget_info *gi = to_gadget_info(item);
        char *name;
        int ret;
 
@@ -283,34 +288,29 @@ err:
        return ret;
 }
 
-GI_DEVICE_DESC_ITEM_ATTR(bDeviceClass);
-GI_DEVICE_DESC_ITEM_ATTR(bDeviceSubClass);
-GI_DEVICE_DESC_ITEM_ATTR(bDeviceProtocol);
-GI_DEVICE_DESC_ITEM_ATTR(bMaxPacketSize0);
-GI_DEVICE_DESC_ITEM_ATTR(idVendor);
-GI_DEVICE_DESC_ITEM_ATTR(idProduct);
-GI_DEVICE_DESC_ITEM_ATTR(bcdDevice);
-GI_DEVICE_DESC_ITEM_ATTR(bcdUSB);
-GI_DEVICE_DESC_ITEM_ATTR(UDC);
+CONFIGFS_ATTR(gadget_dev_desc_, bDeviceClass);
+CONFIGFS_ATTR(gadget_dev_desc_, bDeviceSubClass);
+CONFIGFS_ATTR(gadget_dev_desc_, bDeviceProtocol);
+CONFIGFS_ATTR(gadget_dev_desc_, bMaxPacketSize0);
+CONFIGFS_ATTR(gadget_dev_desc_, idVendor);
+CONFIGFS_ATTR(gadget_dev_desc_, idProduct);
+CONFIGFS_ATTR(gadget_dev_desc_, bcdDevice);
+CONFIGFS_ATTR(gadget_dev_desc_, bcdUSB);
+CONFIGFS_ATTR(gadget_dev_desc_, UDC);
 
 static struct configfs_attribute *gadget_root_attrs[] = {
-       &gadget_cdev_desc_bDeviceClass.attr,
-       &gadget_cdev_desc_bDeviceSubClass.attr,
-       &gadget_cdev_desc_bDeviceProtocol.attr,
-       &gadget_cdev_desc_bMaxPacketSize0.attr,
-       &gadget_cdev_desc_idVendor.attr,
-       &gadget_cdev_desc_idProduct.attr,
-       &gadget_cdev_desc_bcdDevice.attr,
-       &gadget_cdev_desc_bcdUSB.attr,
-       &gadget_cdev_desc_UDC.attr,
+       &gadget_dev_desc_attr_bDeviceClass,
+       &gadget_dev_desc_attr_bDeviceSubClass,
+       &gadget_dev_desc_attr_bDeviceProtocol,
+       &gadget_dev_desc_attr_bMaxPacketSize0,
+       &gadget_dev_desc_attr_idVendor,
+       &gadget_dev_desc_attr_idProduct,
+       &gadget_dev_desc_attr_bcdDevice,
+       &gadget_dev_desc_attr_bcdUSB,
+       &gadget_dev_desc_attr_UDC,
        NULL,
 };
 
-static inline struct gadget_info *to_gadget_info(struct config_item *item)
-{
-        return container_of(to_config_group(item), struct gadget_info, group);
-}
-
 static inline struct gadget_strings *to_gadget_strings(struct config_item *item)
 {
         return container_of(to_config_group(item), struct gadget_strings,
@@ -324,12 +324,6 @@ static inline struct gadget_config_name *to_gadget_config_name(
                         group);
 }
 
-static inline struct config_usb_cfg *to_config_usb_cfg(struct config_item *item)
-{
-       return container_of(to_config_group(item), struct config_usb_cfg,
-                       group);
-}
-
 static inline struct usb_function_instance *to_usb_function_instance(
                struct config_item *item)
 {
@@ -348,12 +342,8 @@ static void gadget_info_attr_release(struct config_item *item)
        kfree(gi);
 }
 
-CONFIGFS_ATTR_OPS(gadget_info);
-
 static struct configfs_item_operations gadget_root_item_ops = {
        .release                = gadget_info_attr_release,
-       .show_attribute         = gadget_info_attr_show,
-       .store_attribute        = gadget_info_attr_store,
 };
 
 static void gadget_config_attr_release(struct config_item *item)
@@ -454,24 +444,20 @@ static int config_usb_cfg_unlink(
        return 0;
 }
 
-CONFIGFS_ATTR_OPS(config_usb_cfg);
-
 static struct configfs_item_operations gadget_config_item_ops = {
        .release                = gadget_config_attr_release,
-       .show_attribute         = config_usb_cfg_attr_show,
-       .store_attribute        = config_usb_cfg_attr_store,
        .allow_link             = config_usb_cfg_link,
        .drop_link              = config_usb_cfg_unlink,
 };
 
 
-static ssize_t gadget_config_desc_MaxPower_show(struct config_usb_cfg *cfg,
+static ssize_t gadget_config_desc_MaxPower_show(struct config_item *item,
                char *page)
 {
-       return sprintf(page, "%u\n", cfg->c.MaxPower);
+       return sprintf(page, "%u\n", to_config_usb_cfg(item)->c.MaxPower);
 }
 
-static ssize_t gadget_config_desc_MaxPower_store(struct config_usb_cfg *cfg,
+static ssize_t gadget_config_desc_MaxPower_store(struct config_item *item,
                const char *page, size_t len)
 {
        u16 val;
@@ -481,17 +467,18 @@ static ssize_t gadget_config_desc_MaxPower_store(struct config_usb_cfg *cfg,
                return ret;
        if (DIV_ROUND_UP(val, 8) > 0xff)
                return -ERANGE;
-       cfg->c.MaxPower = val;
+       to_config_usb_cfg(item)->c.MaxPower = val;
        return len;
 }
 
-static ssize_t gadget_config_desc_bmAttributes_show(struct config_usb_cfg *cfg,
+static ssize_t gadget_config_desc_bmAttributes_show(struct config_item *item,
                char *page)
 {
-       return sprintf(page, "0x%02x\n", cfg->c.bmAttributes);
+       return sprintf(page, "0x%02x\n",
+               to_config_usb_cfg(item)->c.bmAttributes);
 }
 
-static ssize_t gadget_config_desc_bmAttributes_store(struct config_usb_cfg *cfg,
+static ssize_t gadget_config_desc_bmAttributes_store(struct config_item *item,
                const char *page, size_t len)
 {
        u8 val;
@@ -504,22 +491,16 @@ static ssize_t gadget_config_desc_bmAttributes_store(struct config_usb_cfg *cfg,
        if (val & ~(USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER |
                                USB_CONFIG_ATT_WAKEUP))
                return -EINVAL;
-       cfg->c.bmAttributes = val;
+       to_config_usb_cfg(item)->c.bmAttributes = val;
        return len;
 }
 
-#define CFG_CONFIG_DESC_ITEM_ATTR(name)        \
-       static struct config_usb_cfg_attribute gadget_usb_cfg_##name = \
-               __CONFIGFS_ATTR(name,  S_IRUGO | S_IWUSR,               \
-                               gadget_config_desc_##name##_show,       \
-                               gadget_config_desc_##name##_store)
-
-CFG_CONFIG_DESC_ITEM_ATTR(MaxPower);
-CFG_CONFIG_DESC_ITEM_ATTR(bmAttributes);
+CONFIGFS_ATTR(gadget_config_desc_, MaxPower);
+CONFIGFS_ATTR(gadget_config_desc_, bmAttributes);
 
 static struct configfs_attribute *gadget_config_attrs[] = {
-       &gadget_usb_cfg_MaxPower.attr,
-       &gadget_usb_cfg_bmAttributes.attr,
+       &gadget_config_desc_attr_MaxPower,
+       &gadget_config_desc_attr_bmAttributes,
        NULL,
 };
 
@@ -616,11 +597,10 @@ static struct config_item_type functions_type = {
        .ct_owner       = THIS_MODULE,
 };
 
-CONFIGFS_ATTR_STRUCT(gadget_config_name);
 GS_STRINGS_RW(gadget_config_name, configuration);
 
 static struct configfs_attribute *gadget_config_name_langid_attrs[] = {
-       &gadget_config_name_configuration.attr,
+       &gadget_config_name_attr_configuration,
        NULL,
 };
 
@@ -719,15 +699,14 @@ static struct config_item_type config_desc_type = {
        .ct_owner       = THIS_MODULE,
 };
 
-CONFIGFS_ATTR_STRUCT(gadget_strings);
 GS_STRINGS_RW(gadget_strings, manufacturer);
 GS_STRINGS_RW(gadget_strings, product);
 GS_STRINGS_RW(gadget_strings, serialnumber);
 
 static struct configfs_attribute *gadget_strings_langid_attrs[] = {
-       &gadget_strings_manufacturer.attr,
-       &gadget_strings_product.attr,
-       &gadget_strings_serialnumber.attr,
+       &gadget_strings_attr_manufacturer,
+       &gadget_strings_attr_product,
+       &gadget_strings_attr_serialnumber,
        NULL,
 };
 
@@ -751,27 +730,25 @@ static inline struct os_desc *to_os_desc(struct config_item *item)
        return container_of(to_config_group(item), struct os_desc, group);
 }
 
-CONFIGFS_ATTR_STRUCT(os_desc);
-CONFIGFS_ATTR_OPS(os_desc);
-
-static ssize_t os_desc_use_show(struct os_desc *os_desc, char *page)
+static inline struct gadget_info *os_desc_item_to_gadget_info(
+               struct config_item *item)
 {
-       struct gadget_info *gi;
-
-       gi = to_gadget_info(os_desc->group.cg_item.ci_parent);
+       return to_gadget_info(to_os_desc(item)->group.cg_item.ci_parent);
+}
 
-       return sprintf(page, "%d", gi->use_os_desc);
+static ssize_t os_desc_use_show(struct config_item *item, char *page)
+{
+       return sprintf(page, "%d",
+                       os_desc_item_to_gadget_info(item)->use_os_desc);
 }
 
-static ssize_t os_desc_use_store(struct os_desc *os_desc, const char *page,
+static ssize_t os_desc_use_store(struct config_item *item, const char *page,
                                 size_t len)
 {
-       struct gadget_info *gi;
+       struct gadget_info *gi = os_desc_item_to_gadget_info(item);
        int ret;
        bool use;
 
-       gi = to_gadget_info(os_desc->group.cg_item.ci_parent);
-
        mutex_lock(&gi->lock);
        ret = strtobool(page, &use);
        if (!ret) {
@@ -783,29 +760,19 @@ static ssize_t os_desc_use_store(struct os_desc *os_desc, const char *page,
        return ret;
 }
 
-static struct os_desc_attribute os_desc_use =
-       __CONFIGFS_ATTR(use, S_IRUGO | S_IWUSR,
-                       os_desc_use_show,
-                       os_desc_use_store);
-
-static ssize_t os_desc_b_vendor_code_show(struct os_desc *os_desc, char *page)
+static ssize_t os_desc_b_vendor_code_show(struct config_item *item, char *page)
 {
-       struct gadget_info *gi;
-
-       gi = to_gadget_info(os_desc->group.cg_item.ci_parent);
-
-       return sprintf(page, "%d", gi->b_vendor_code);
+       return sprintf(page, "%d",
+                       os_desc_item_to_gadget_info(item)->b_vendor_code);
 }
 
-static ssize_t os_desc_b_vendor_code_store(struct os_desc *os_desc,
+static ssize_t os_desc_b_vendor_code_store(struct config_item *item,
                                           const char *page, size_t len)
 {
-       struct gadget_info *gi;
+       struct gadget_info *gi = os_desc_item_to_gadget_info(item);
        int ret;
        u8 b_vendor_code;
 
-       gi = to_gadget_info(os_desc->group.cg_item.ci_parent);
-
        mutex_lock(&gi->lock);
        ret = kstrtou8(page, 0, &b_vendor_code);
        if (!ret) {
@@ -817,29 +784,20 @@ static ssize_t os_desc_b_vendor_code_store(struct os_desc *os_desc,
        return ret;
 }
 
-static struct os_desc_attribute os_desc_b_vendor_code =
-       __CONFIGFS_ATTR(b_vendor_code, S_IRUGO | S_IWUSR,
-                       os_desc_b_vendor_code_show,
-                       os_desc_b_vendor_code_store);
-
-static ssize_t os_desc_qw_sign_show(struct os_desc *os_desc, char *page)
+static ssize_t os_desc_qw_sign_show(struct config_item *item, char *page)
 {
-       struct gadget_info *gi;
-
-       gi = to_gadget_info(os_desc->group.cg_item.ci_parent);
+       struct gadget_info *gi = os_desc_item_to_gadget_info(item);
 
        memcpy(page, gi->qw_sign, OS_STRING_QW_SIGN_LEN);
-
        return OS_STRING_QW_SIGN_LEN;
 }
 
-static ssize_t os_desc_qw_sign_store(struct os_desc *os_desc, const char *page,
+static ssize_t os_desc_qw_sign_store(struct config_item *item, const char *page,
                                     size_t len)
 {
-       struct gadget_info *gi;
+       struct gadget_info *gi = os_desc_item_to_gadget_info(item);
        int res, l;
 
-       gi = to_gadget_info(os_desc->group.cg_item.ci_parent);
        l = min((int)len, OS_STRING_QW_SIGN_LEN >> 1);
        if (page[l - 1] == '\n')
                --l;
@@ -855,15 +813,14 @@ static ssize_t os_desc_qw_sign_store(struct os_desc *os_desc, const char *page,
        return res;
 }
 
-static struct os_desc_attribute os_desc_qw_sign =
-       __CONFIGFS_ATTR(qw_sign, S_IRUGO | S_IWUSR,
-                       os_desc_qw_sign_show,
-                       os_desc_qw_sign_store);
+CONFIGFS_ATTR(os_desc_, use);
+CONFIGFS_ATTR(os_desc_, b_vendor_code);
+CONFIGFS_ATTR(os_desc_, qw_sign);
 
 static struct configfs_attribute *os_desc_attrs[] = {
-       &os_desc_use.attr,
-       &os_desc_b_vendor_code.attr,
-       &os_desc_qw_sign.attr,
+       &os_desc_attr_use,
+       &os_desc_attr_b_vendor_code,
+       &os_desc_attr_qw_sign,
        NULL,
 };
 
@@ -926,8 +883,6 @@ static int os_desc_unlink(struct config_item *os_desc_ci,
 
 static struct configfs_item_operations os_desc_ops = {
        .release                = os_desc_attr_release,
-       .show_attribute         = os_desc_attr_show,
-       .store_attribute        = os_desc_attr_store,
        .allow_link             = os_desc_link,
        .drop_link              = os_desc_unlink,
 };
@@ -938,28 +893,21 @@ static struct config_item_type os_desc_type = {
        .ct_owner       = THIS_MODULE,
 };
 
-CONFIGFS_ATTR_STRUCT(usb_os_desc);
-CONFIGFS_ATTR_OPS(usb_os_desc);
-
-
 static inline struct usb_os_desc_ext_prop
 *to_usb_os_desc_ext_prop(struct config_item *item)
 {
        return container_of(item, struct usb_os_desc_ext_prop, item);
 }
 
-CONFIGFS_ATTR_STRUCT(usb_os_desc_ext_prop);
-CONFIGFS_ATTR_OPS(usb_os_desc_ext_prop);
-
-static ssize_t ext_prop_type_show(struct usb_os_desc_ext_prop *ext_prop,
-                                 char *page)
+static ssize_t ext_prop_type_show(struct config_item *item, char *page)
 {
-       return sprintf(page, "%d", ext_prop->type);
+       return sprintf(page, "%d", to_usb_os_desc_ext_prop(item)->type);
 }
 
-static ssize_t ext_prop_type_store(struct usb_os_desc_ext_prop *ext_prop,
+static ssize_t ext_prop_type_store(struct config_item *item,
                                   const char *page, size_t len)
 {
+       struct usb_os_desc_ext_prop *ext_prop = to_usb_os_desc_ext_prop(item);
        struct usb_os_desc *desc = to_usb_os_desc(ext_prop->item.ci_parent);
        u8 type;
        int ret;
@@ -997,9 +945,9 @@ end:
        return ret;
 }
 
-static ssize_t ext_prop_data_show(struct usb_os_desc_ext_prop *ext_prop,
-                                 char *page)
+static ssize_t ext_prop_data_show(struct config_item *item, char *page)
 {
+       struct usb_os_desc_ext_prop *ext_prop = to_usb_os_desc_ext_prop(item);
        int len = ext_prop->data_len;
 
        if (ext_prop->type == USB_EXT_PROP_UNICODE ||
@@ -1011,9 +959,10 @@ static ssize_t ext_prop_data_show(struct usb_os_desc_ext_prop *ext_prop,
        return len;
 }
 
-static ssize_t ext_prop_data_store(struct usb_os_desc_ext_prop *ext_prop,
+static ssize_t ext_prop_data_store(struct config_item *item,
                                   const char *page, size_t len)
 {
+       struct usb_os_desc_ext_prop *ext_prop = to_usb_os_desc_ext_prop(item);
        struct usb_os_desc *desc = to_usb_os_desc(ext_prop->item.ci_parent);
        char *new_data;
        size_t ret_len = len;
@@ -1044,17 +993,12 @@ static ssize_t ext_prop_data_store(struct usb_os_desc_ext_prop *ext_prop,
        return ret_len;
 }
 
-static struct usb_os_desc_ext_prop_attribute ext_prop_type =
-       __CONFIGFS_ATTR(type, S_IRUGO | S_IWUSR,
-                       ext_prop_type_show, ext_prop_type_store);
-
-static struct usb_os_desc_ext_prop_attribute ext_prop_data =
-       __CONFIGFS_ATTR(data, S_IRUGO | S_IWUSR,
-                       ext_prop_data_show, ext_prop_data_store);
+CONFIGFS_ATTR(ext_prop_, type);
+CONFIGFS_ATTR(ext_prop_, data);
 
 static struct configfs_attribute *ext_prop_attrs[] = {
-       &ext_prop_type.attr,
-       &ext_prop_data.attr,
+       &ext_prop_attr_type,
+       &ext_prop_attr_data,
        NULL,
 };
 
@@ -1067,8 +1011,6 @@ static void usb_os_desc_ext_prop_release(struct config_item *item)
 
 static struct configfs_item_operations ext_prop_ops = {
        .release                = usb_os_desc_ext_prop_release,
-       .show_attribute         = usb_os_desc_ext_prop_attr_show,
-       .store_attribute        = usb_os_desc_ext_prop_attr_store,
 };
 
 static struct config_item *ext_prop_make(
@@ -1137,21 +1079,17 @@ static struct configfs_group_operations interf_grp_ops = {
        .drop_item      = &ext_prop_drop,
 };
 
-static struct configfs_item_operations interf_item_ops = {
-       .show_attribute         = usb_os_desc_attr_show,
-       .store_attribute        = usb_os_desc_attr_store,
-};
-
-static ssize_t interf_grp_compatible_id_show(struct usb_os_desc *desc,
+static ssize_t interf_grp_compatible_id_show(struct config_item *item,
                                             char *page)
 {
-       memcpy(page, desc->ext_compat_id, 8);
+       memcpy(page, to_usb_os_desc(item)->ext_compat_id, 8);
        return 8;
 }
 
-static ssize_t interf_grp_compatible_id_store(struct usb_os_desc *desc,
+static ssize_t interf_grp_compatible_id_store(struct config_item *item,
                                              const char *page, size_t len)
 {
+       struct usb_os_desc *desc = to_usb_os_desc(item);
        int l;
 
        l = min_t(int, 8, len);
@@ -1167,21 +1105,17 @@ static ssize_t interf_grp_compatible_id_store(struct usb_os_desc *desc,
        return len;
 }
 
-static struct usb_os_desc_attribute interf_grp_attr_compatible_id =
-       __CONFIGFS_ATTR(compatible_id, S_IRUGO | S_IWUSR,
-                       interf_grp_compatible_id_show,
-                       interf_grp_compatible_id_store);
-
-static ssize_t interf_grp_sub_compatible_id_show(struct usb_os_desc *desc,
+static ssize_t interf_grp_sub_compatible_id_show(struct config_item *item,
                                                 char *page)
 {
-       memcpy(page, desc->ext_compat_id + 8, 8);
+       memcpy(page, to_usb_os_desc(item)->ext_compat_id + 8, 8);
        return 8;
 }
 
-static ssize_t interf_grp_sub_compatible_id_store(struct usb_os_desc *desc,
+static ssize_t interf_grp_sub_compatible_id_store(struct config_item *item,
                                                  const char *page, size_t len)
 {
+       struct usb_os_desc *desc = to_usb_os_desc(item);
        int l;
 
        l = min_t(int, 8, len);
@@ -1197,14 +1131,12 @@ static ssize_t interf_grp_sub_compatible_id_store(struct usb_os_desc *desc,
        return len;
 }
 
-static struct usb_os_desc_attribute interf_grp_attr_sub_compatible_id =
-       __CONFIGFS_ATTR(sub_compatible_id, S_IRUGO | S_IWUSR,
-                       interf_grp_sub_compatible_id_show,
-                       interf_grp_sub_compatible_id_store);
+CONFIGFS_ATTR(interf_grp_, compatible_id);
+CONFIGFS_ATTR(interf_grp_, sub_compatible_id);
 
 static struct configfs_attribute *interf_grp_attrs[] = {
-       &interf_grp_attr_compatible_id.attr,
-       &interf_grp_attr_sub_compatible_id.attr,
+       &interf_grp_attr_compatible_id,
+       &interf_grp_attr_sub_compatible_id,
        NULL
 };
 
@@ -1242,7 +1174,6 @@ int usb_os_desc_prepare_interf_dir(struct config_group *parent,
        f_default_groups[0] = os_desc_group;
 
        os_desc_group->default_groups = interface_groups;
-       interface_type->ct_item_ops = &interf_item_ops;
        interface_type->ct_group_ops = &interf_grp_ops;
        interface_type->ct_attrs = interf_grp_attrs;
        interface_type->ct_owner = owner;
index 22e723d12d36ff4a6a24b07b703ac6172cf799ba..2fa1e80a3ce7bbdd941ddf30fb79e8860812a907 100644 (file)
@@ -761,21 +761,6 @@ static inline struct f_serial_opts *to_f_serial_opts(struct config_item *item)
                        func_inst.group);
 }
 
-CONFIGFS_ATTR_STRUCT(f_serial_opts);
-static ssize_t f_acm_attr_show(struct config_item *item,
-                                struct configfs_attribute *attr,
-                                char *page)
-{
-       struct f_serial_opts *opts = to_f_serial_opts(item);
-       struct f_serial_opts_attribute *f_serial_opts_attr =
-               container_of(attr, struct f_serial_opts_attribute, attr);
-       ssize_t ret = 0;
-
-       if (f_serial_opts_attr->show)
-               ret = f_serial_opts_attr->show(opts, page);
-       return ret;
-}
-
 static void acm_attr_release(struct config_item *item)
 {
        struct f_serial_opts *opts = to_f_serial_opts(item);
@@ -785,20 +770,17 @@ static void acm_attr_release(struct config_item *item)
 
 static struct configfs_item_operations acm_item_ops = {
        .release                = acm_attr_release,
-       .show_attribute         = f_acm_attr_show,
 };
 
-static ssize_t f_acm_port_num_show(struct f_serial_opts *opts, char *page)
+static ssize_t f_acm_port_num_show(struct config_item *item, char *page)
 {
-       return sprintf(page, "%u\n", opts->port_num);
+       return sprintf(page, "%u\n", to_f_serial_opts(item)->port_num);
 }
 
-static struct f_serial_opts_attribute f_acm_port_num =
-       __CONFIGFS_ATTR_RO(port_num, f_acm_port_num_show);
-
+CONFIGFS_ATTR_RO(f_acm_port_, num);
 
 static struct configfs_attribute *acm_attrs[] = {
-       &f_acm_port_num.attr,
+       &f_acm_port_attr_num,
        NULL,
 };
 
index 4abca70cdaab9d52e529dcc85b2dabb30137d7e1..7ad60ee419144fd89b6d109439dcacd99c6a3db7 100644 (file)
@@ -838,10 +838,10 @@ USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(ecm);
 USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(ecm);
 
 static struct configfs_attribute *ecm_attrs[] = {
-       &f_ecm_opts_dev_addr.attr,
-       &f_ecm_opts_host_addr.attr,
-       &f_ecm_opts_qmult.attr,
-       &f_ecm_opts_ifname.attr,
+       &ecm_opts_attr_dev_addr,
+       &ecm_opts_attr_host_addr,
+       &ecm_opts_attr_qmult,
+       &ecm_opts_attr_ifname,
        NULL,
 };
 
index 9a55757c729b2f59f1d512a8f4f67dffa89c5feb..cad35a502d3f73a64759cd8eb8d541d36104cbac 100644 (file)
@@ -545,10 +545,10 @@ USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(eem);
 USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(eem);
 
 static struct configfs_attribute *eem_attrs[] = {
-       &f_eem_opts_dev_addr.attr,
-       &f_eem_opts_host_addr.attr,
-       &f_eem_opts_qmult.attr,
-       &f_eem_opts_ifname.attr,
+       &eem_opts_attr_dev_addr,
+       &eem_opts_attr_host_addr,
+       &eem_opts_attr_qmult,
+       &eem_opts_attr_ifname,
        NULL,
 };
 
index 21fcf18f53a0409ed00bc302ac62b4f012e5c766..99285b416308f84917a6500aad64daff34c2ce05 100644 (file)
@@ -705,9 +705,6 @@ static inline struct f_hid_opts *to_f_hid_opts(struct config_item *item)
                            func_inst.group);
 }
 
-CONFIGFS_ATTR_STRUCT(f_hid_opts);
-CONFIGFS_ATTR_OPS(f_hid_opts);
-
 static void hid_attr_release(struct config_item *item)
 {
        struct f_hid_opts *opts = to_f_hid_opts(item);
@@ -717,13 +714,12 @@ static void hid_attr_release(struct config_item *item)
 
 static struct configfs_item_operations hidg_item_ops = {
        .release        = hid_attr_release,
-       .show_attribute = f_hid_opts_attr_show,
-       .store_attribute = f_hid_opts_attr_store,
 };
 
 #define F_HID_OPT(name, prec, limit)                                   \
-static ssize_t f_hid_opts_##name##_show(struct f_hid_opts *opts, char *page)\
+static ssize_t f_hid_opts_##name##_show(struct config_item *item, char *page)\
 {                                                                      \
+       struct f_hid_opts *opts = to_f_hid_opts(item);                  \
        int result;                                                     \
                                                                        \
        mutex_lock(&opts->lock);                                        \
@@ -733,9 +729,10 @@ static ssize_t f_hid_opts_##name##_show(struct f_hid_opts *opts, char *page)\
        return result;                                                  \
 }                                                                      \
                                                                        \
-static ssize_t f_hid_opts_##name##_store(struct f_hid_opts *opts,      \
+static ssize_t f_hid_opts_##name##_store(struct config_item *item,     \
                                         const char *page, size_t len)  \
 {                                                                      \
+       struct f_hid_opts *opts = to_f_hid_opts(item);                  \
        int ret;                                                        \
        u##prec num;                                                    \
                                                                        \
@@ -761,16 +758,15 @@ end:                                                                      \
        return ret;                                                     \
 }                                                                      \
                                                                        \
-static struct f_hid_opts_attribute f_hid_opts_##name =                 \
-       __CONFIGFS_ATTR(name, S_IRUGO | S_IWUSR, f_hid_opts_##name##_show,\
-                       f_hid_opts_##name##_store)
+CONFIGFS_ATTR(f_hid_opts_, name)
 
 F_HID_OPT(subclass, 8, 255);
 F_HID_OPT(protocol, 8, 255);
 F_HID_OPT(report_length, 16, 65535);
 
-static ssize_t f_hid_opts_report_desc_show(struct f_hid_opts *opts, char *page)
+static ssize_t f_hid_opts_report_desc_show(struct config_item *item, char *page)
 {
+       struct f_hid_opts *opts = to_f_hid_opts(item);
        int result;
 
        mutex_lock(&opts->lock);
@@ -781,9 +777,10 @@ static ssize_t f_hid_opts_report_desc_show(struct f_hid_opts *opts, char *page)
        return result;
 }
 
-static ssize_t f_hid_opts_report_desc_store(struct f_hid_opts *opts,
+static ssize_t f_hid_opts_report_desc_store(struct config_item *item,
                                            const char *page, size_t len)
 {
+       struct f_hid_opts *opts = to_f_hid_opts(item);
        int ret = -EBUSY;
        char *d;
 
@@ -810,16 +807,13 @@ end:
        return ret;
 }
 
-static struct f_hid_opts_attribute f_hid_opts_report_desc =
-       __CONFIGFS_ATTR(report_desc, S_IRUGO | S_IWUSR,
-                       f_hid_opts_report_desc_show,
-                       f_hid_opts_report_desc_store);
+CONFIGFS_ATTR(f_hid_opts_, report_desc);
 
 static struct configfs_attribute *hid_attrs[] = {
-       &f_hid_opts_subclass.attr,
-       &f_hid_opts_protocol.attr,
-       &f_hid_opts_report_length.attr,
-       &f_hid_opts_report_desc.attr,
+       &f_hid_opts_attr_subclass,
+       &f_hid_opts_attr_protocol,
+       &f_hid_opts_attr_report_length,
+       &f_hid_opts_attr_report_desc,
        NULL,
 };
 
index 6b2102bc069973554db95d3311470b0545067727..23933bdf2d9d6cebc66750050ba704c9a20d109c 100644 (file)
@@ -465,9 +465,6 @@ static inline struct f_lb_opts *to_f_lb_opts(struct config_item *item)
                            func_inst.group);
 }
 
-CONFIGFS_ATTR_STRUCT(f_lb_opts);
-CONFIGFS_ATTR_OPS(f_lb_opts);
-
 static void lb_attr_release(struct config_item *item)
 {
        struct f_lb_opts *lb_opts = to_f_lb_opts(item);
@@ -477,12 +474,11 @@ static void lb_attr_release(struct config_item *item)
 
 static struct configfs_item_operations lb_item_ops = {
        .release                = lb_attr_release,
-       .show_attribute         = f_lb_opts_attr_show,
-       .store_attribute        = f_lb_opts_attr_store,
 };
 
-static ssize_t f_lb_opts_qlen_show(struct f_lb_opts *opts, char *page)
+static ssize_t f_lb_opts_qlen_show(struct config_item *item, char *page)
 {
+       struct f_lb_opts *opts = to_f_lb_opts(item);
        int result;
 
        mutex_lock(&opts->lock);
@@ -492,9 +488,10 @@ static ssize_t f_lb_opts_qlen_show(struct f_lb_opts *opts, char *page)
        return result;
 }
 
-static ssize_t f_lb_opts_qlen_store(struct f_lb_opts *opts,
+static ssize_t f_lb_opts_qlen_store(struct config_item *item,
                                    const char *page, size_t len)
 {
+       struct f_lb_opts *opts = to_f_lb_opts(item);
        int ret;
        u32 num;
 
@@ -515,13 +512,11 @@ end:
        return ret;
 }
 
-static struct f_lb_opts_attribute f_lb_opts_qlen =
-       __CONFIGFS_ATTR(qlen, S_IRUGO | S_IWUSR,
-                       f_lb_opts_qlen_show,
-                       f_lb_opts_qlen_store);
+CONFIGFS_ATTR(f_lb_opts_, qlen);
 
-static ssize_t f_lb_opts_bulk_buflen_show(struct f_lb_opts *opts, char *page)
+static ssize_t f_lb_opts_bulk_buflen_show(struct config_item *item, char *page)
 {
+       struct f_lb_opts *opts = to_f_lb_opts(item);
        int result;
 
        mutex_lock(&opts->lock);
@@ -531,9 +526,10 @@ static ssize_t f_lb_opts_bulk_buflen_show(struct f_lb_opts *opts, char *page)
        return result;
 }
 
-static ssize_t f_lb_opts_bulk_buflen_store(struct f_lb_opts *opts,
+static ssize_t f_lb_opts_bulk_buflen_store(struct config_item *item,
                                    const char *page, size_t len)
 {
+       struct f_lb_opts *opts = to_f_lb_opts(item);
        int ret;
        u32 num;
 
@@ -554,14 +550,11 @@ end:
        return ret;
 }
 
-static struct f_lb_opts_attribute f_lb_opts_bulk_buflen =
-       __CONFIGFS_ATTR(buflen, S_IRUGO | S_IWUSR,
-                       f_lb_opts_bulk_buflen_show,
-                       f_lb_opts_bulk_buflen_store);
+CONFIGFS_ATTR(f_lb_opts_, bulk_buflen);
 
 static struct configfs_attribute *lb_attrs[] = {
-       &f_lb_opts_qlen.attr,
-       &f_lb_opts_bulk_buflen.attr,
+       &f_lb_opts_attr_qlen,
+       &f_lb_opts_attr_bulk_buflen,
        NULL,
 };
 
index 5ec533826621c7cfcb0975f9084f0ec4df3b7cf1..223ccf89d2263fb6483a1a22116a3743c9d7ed8e 100644 (file)
@@ -3140,9 +3140,6 @@ static inline struct fsg_opts *to_fsg_opts(struct config_item *item)
                            func_inst.group);
 }
 
-CONFIGFS_ATTR_STRUCT(fsg_lun_opts);
-CONFIGFS_ATTR_OPS(fsg_lun_opts);
-
 static void fsg_lun_attr_release(struct config_item *item)
 {
        struct fsg_lun_opts *lun_opts;
@@ -3153,110 +3150,93 @@ static void fsg_lun_attr_release(struct config_item *item)
 
 static struct configfs_item_operations fsg_lun_item_ops = {
        .release                = fsg_lun_attr_release,
-       .show_attribute         = fsg_lun_opts_attr_show,
-       .store_attribute        = fsg_lun_opts_attr_store,
 };
 
-static ssize_t fsg_lun_opts_file_show(struct fsg_lun_opts *opts, char *page)
+static ssize_t fsg_lun_opts_file_show(struct config_item *item, char *page)
 {
-       struct fsg_opts *fsg_opts;
-
-       fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
+       struct fsg_lun_opts *opts = to_fsg_lun_opts(item);
+       struct fsg_opts *fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
 
        return fsg_show_file(opts->lun, &fsg_opts->common->filesem, page);
 }
 
-static ssize_t fsg_lun_opts_file_store(struct fsg_lun_opts *opts,
+static ssize_t fsg_lun_opts_file_store(struct config_item *item,
                                       const char *page, size_t len)
 {
-       struct fsg_opts *fsg_opts;
-
-       fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
+       struct fsg_lun_opts *opts = to_fsg_lun_opts(item);
+       struct fsg_opts *fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
 
        return fsg_store_file(opts->lun, &fsg_opts->common->filesem, page, len);
 }
 
-static struct fsg_lun_opts_attribute fsg_lun_opts_file =
-       __CONFIGFS_ATTR(file, S_IRUGO | S_IWUSR, fsg_lun_opts_file_show,
-                       fsg_lun_opts_file_store);
+CONFIGFS_ATTR(fsg_lun_opts_, file);
 
-static ssize_t fsg_lun_opts_ro_show(struct fsg_lun_opts *opts, char *page)
+static ssize_t fsg_lun_opts_ro_show(struct config_item *item, char *page)
 {
-       return fsg_show_ro(opts->lun, page);
+       return fsg_show_ro(to_fsg_lun_opts(item)->lun, page);
 }
 
-static ssize_t fsg_lun_opts_ro_store(struct fsg_lun_opts *opts,
+static ssize_t fsg_lun_opts_ro_store(struct config_item *item,
                                       const char *page, size_t len)
 {
-       struct fsg_opts *fsg_opts;
-
-       fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
+       struct fsg_lun_opts *opts = to_fsg_lun_opts(item);
+       struct fsg_opts *fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
 
        return fsg_store_ro(opts->lun, &fsg_opts->common->filesem, page, len);
 }
 
-static struct fsg_lun_opts_attribute fsg_lun_opts_ro =
-       __CONFIGFS_ATTR(ro, S_IRUGO | S_IWUSR, fsg_lun_opts_ro_show,
-                       fsg_lun_opts_ro_store);
+CONFIGFS_ATTR(fsg_lun_opts_, ro);
 
-static ssize_t fsg_lun_opts_removable_show(struct fsg_lun_opts *opts,
+static ssize_t fsg_lun_opts_removable_show(struct config_item *item,
                                           char *page)
 {
-       return fsg_show_removable(opts->lun, page);
+       return fsg_show_removable(to_fsg_lun_opts(item)->lun, page);
 }
 
-static ssize_t fsg_lun_opts_removable_store(struct fsg_lun_opts *opts,
+static ssize_t fsg_lun_opts_removable_store(struct config_item *item,
                                       const char *page, size_t len)
 {
-       return fsg_store_removable(opts->lun, page, len);
+       return fsg_store_removable(to_fsg_lun_opts(item)->lun, page, len);
 }
 
-static struct fsg_lun_opts_attribute fsg_lun_opts_removable =
-       __CONFIGFS_ATTR(removable, S_IRUGO | S_IWUSR,
-                       fsg_lun_opts_removable_show,
-                       fsg_lun_opts_removable_store);
+CONFIGFS_ATTR(fsg_lun_opts_, removable);
 
-static ssize_t fsg_lun_opts_cdrom_show(struct fsg_lun_opts *opts, char *page)
+static ssize_t fsg_lun_opts_cdrom_show(struct config_item *item, char *page)
 {
-       return fsg_show_cdrom(opts->lun, page);
+       return fsg_show_cdrom(to_fsg_lun_opts(item)->lun, page);
 }
 
-static ssize_t fsg_lun_opts_cdrom_store(struct fsg_lun_opts *opts,
+static ssize_t fsg_lun_opts_cdrom_store(struct config_item *item,
                                       const char *page, size_t len)
 {
-       struct fsg_opts *fsg_opts;
-
-       fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
+       struct fsg_lun_opts *opts = to_fsg_lun_opts(item);
+       struct fsg_opts *fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
 
        return fsg_store_cdrom(opts->lun, &fsg_opts->common->filesem, page,
                               len);
 }
 
-static struct fsg_lun_opts_attribute fsg_lun_opts_cdrom =
-       __CONFIGFS_ATTR(cdrom, S_IRUGO | S_IWUSR, fsg_lun_opts_cdrom_show,
-                       fsg_lun_opts_cdrom_store);
+CONFIGFS_ATTR(fsg_lun_opts_, cdrom);
 
-static ssize_t fsg_lun_opts_nofua_show(struct fsg_lun_opts *opts, char *page)
+static ssize_t fsg_lun_opts_nofua_show(struct config_item *item, char *page)
 {
-       return fsg_show_nofua(opts->lun, page);
+       return fsg_show_nofua(to_fsg_lun_opts(item)->lun, page);
 }
 
-static ssize_t fsg_lun_opts_nofua_store(struct fsg_lun_opts *opts,
+static ssize_t fsg_lun_opts_nofua_store(struct config_item *item,
                                       const char *page, size_t len)
 {
-       return fsg_store_nofua(opts->lun, page, len);
+       return fsg_store_nofua(to_fsg_lun_opts(item)->lun, page, len);
 }
 
-static struct fsg_lun_opts_attribute fsg_lun_opts_nofua =
-       __CONFIGFS_ATTR(nofua, S_IRUGO | S_IWUSR, fsg_lun_opts_nofua_show,
-                       fsg_lun_opts_nofua_store);
+CONFIGFS_ATTR(fsg_lun_opts_, nofua);
 
 static struct configfs_attribute *fsg_lun_attrs[] = {
-       &fsg_lun_opts_file.attr,
-       &fsg_lun_opts_ro.attr,
-       &fsg_lun_opts_removable.attr,
-       &fsg_lun_opts_cdrom.attr,
-       &fsg_lun_opts_nofua.attr,
+       &fsg_lun_opts_attr_file,
+       &fsg_lun_opts_attr_ro,
+       &fsg_lun_opts_attr_removable,
+       &fsg_lun_opts_attr_cdrom,
+       &fsg_lun_opts_attr_nofua,
        NULL,
 };
 
@@ -3348,9 +3328,6 @@ static void fsg_lun_drop(struct config_group *group, struct config_item *item)
        config_item_put(item);
 }
 
-CONFIGFS_ATTR_STRUCT(fsg_opts);
-CONFIGFS_ATTR_OPS(fsg_opts);
-
 static void fsg_attr_release(struct config_item *item)
 {
        struct fsg_opts *opts = to_fsg_opts(item);
@@ -3360,12 +3337,11 @@ static void fsg_attr_release(struct config_item *item)
 
 static struct configfs_item_operations fsg_item_ops = {
        .release                = fsg_attr_release,
-       .show_attribute         = fsg_opts_attr_show,
-       .store_attribute        = fsg_opts_attr_store,
 };
 
-static ssize_t fsg_opts_stall_show(struct fsg_opts *opts, char *page)
+static ssize_t fsg_opts_stall_show(struct config_item *item, char *page)
 {
+       struct fsg_opts *opts = to_fsg_opts(item);
        int result;
 
        mutex_lock(&opts->lock);
@@ -3375,9 +3351,10 @@ static ssize_t fsg_opts_stall_show(struct fsg_opts *opts, char *page)
        return result;
 }
 
-static ssize_t fsg_opts_stall_store(struct fsg_opts *opts, const char *page,
+static ssize_t fsg_opts_stall_store(struct config_item *item, const char *page,
                                    size_t len)
 {
+       struct fsg_opts *opts = to_fsg_opts(item);
        int ret;
        bool stall;
 
@@ -3399,13 +3376,12 @@ static ssize_t fsg_opts_stall_store(struct fsg_opts *opts, const char *page,
        return ret;
 }
 
-static struct fsg_opts_attribute fsg_opts_stall =
-       __CONFIGFS_ATTR(stall, S_IRUGO | S_IWUSR, fsg_opts_stall_show,
-                       fsg_opts_stall_store);
+CONFIGFS_ATTR(fsg_opts_, stall);
 
 #ifdef CONFIG_USB_GADGET_DEBUG_FILES
-static ssize_t fsg_opts_num_buffers_show(struct fsg_opts *opts, char *page)
+static ssize_t fsg_opts_num_buffers_show(struct config_item *item, char *page)
 {
+       struct fsg_opts *opts = to_fsg_opts(item);
        int result;
 
        mutex_lock(&opts->lock);
@@ -3415,9 +3391,10 @@ static ssize_t fsg_opts_num_buffers_show(struct fsg_opts *opts, char *page)
        return result;
 }
 
-static ssize_t fsg_opts_num_buffers_store(struct fsg_opts *opts,
+static ssize_t fsg_opts_num_buffers_store(struct config_item *item,
                                          const char *page, size_t len)
 {
+       struct fsg_opts *opts = to_fsg_opts(item);
        int ret;
        u8 num;
 
@@ -3442,17 +3419,13 @@ end:
        return ret;
 }
 
-static struct fsg_opts_attribute fsg_opts_num_buffers =
-       __CONFIGFS_ATTR(num_buffers, S_IRUGO | S_IWUSR,
-                       fsg_opts_num_buffers_show,
-                       fsg_opts_num_buffers_store);
-
+CONFIGFS_ATTR(fsg_opts_, num_buffers);
 #endif
 
 static struct configfs_attribute *fsg_attrs[] = {
-       &fsg_opts_stall.attr,
+       &fsg_opts_attr_stall,
 #ifdef CONFIG_USB_GADGET_DEBUG_FILES
-       &fsg_opts_num_buffers.attr,
+       &fsg_opts_attr_num_buffers,
 #endif
        NULL,
 };
index ce3c8a629266c12d6de7638f2c9900af4085cd83..42acb45e1ab42dd9436244bec16d4903603d6089 100644 (file)
@@ -902,9 +902,6 @@ static inline struct f_midi_opts *to_f_midi_opts(struct config_item *item)
                            func_inst.group);
 }
 
-CONFIGFS_ATTR_STRUCT(f_midi_opts);
-CONFIGFS_ATTR_OPS(f_midi_opts);
-
 static void midi_attr_release(struct config_item *item)
 {
        struct f_midi_opts *opts = to_f_midi_opts(item);
@@ -914,13 +911,12 @@ static void midi_attr_release(struct config_item *item)
 
 static struct configfs_item_operations midi_item_ops = {
        .release        = midi_attr_release,
-       .show_attribute = f_midi_opts_attr_show,
-       .store_attribute = f_midi_opts_attr_store,
 };
 
 #define F_MIDI_OPT(name, test_limit, limit)                            \
-static ssize_t f_midi_opts_##name##_show(struct f_midi_opts *opts, char *page) \
+static ssize_t f_midi_opts_##name##_show(struct config_item *item, char *page) \
 {                                                                      \
+       struct f_midi_opts *opts = to_f_midi_opts(item);                \
        int result;                                                     \
                                                                        \
        mutex_lock(&opts->lock);                                        \
@@ -930,9 +926,10 @@ static ssize_t f_midi_opts_##name##_show(struct f_midi_opts *opts, char *page) \
        return result;                                                  \
 }                                                                      \
                                                                        \
-static ssize_t f_midi_opts_##name##_store(struct f_midi_opts *opts,    \
+static ssize_t f_midi_opts_##name##_store(struct config_item *item,    \
                                         const char *page, size_t len)  \
 {                                                                      \
+       struct f_midi_opts *opts = to_f_midi_opts(item);                \
        int ret;                                                        \
        u32 num;                                                        \
                                                                        \
@@ -958,9 +955,7 @@ end:                                                                        \
        return ret;                                                     \
 }                                                                      \
                                                                        \
-static struct f_midi_opts_attribute f_midi_opts_##name =               \
-       __CONFIGFS_ATTR(name, S_IRUGO | S_IWUSR, f_midi_opts_##name##_show, \
-                       f_midi_opts_##name##_store)
+CONFIGFS_ATTR(f_midi_opts_, name);
 
 F_MIDI_OPT(index, true, SNDRV_CARDS);
 F_MIDI_OPT(buflen, false, 0);
@@ -968,8 +963,9 @@ F_MIDI_OPT(qlen, false, 0);
 F_MIDI_OPT(in_ports, true, MAX_PORTS);
 F_MIDI_OPT(out_ports, true, MAX_PORTS);
 
-static ssize_t f_midi_opts_id_show(struct f_midi_opts *opts, char *page)
+static ssize_t f_midi_opts_id_show(struct config_item *item, char *page)
 {
+       struct f_midi_opts *opts = to_f_midi_opts(item);
        int result;
 
        mutex_lock(&opts->lock);
@@ -985,9 +981,10 @@ static ssize_t f_midi_opts_id_show(struct f_midi_opts *opts, char *page)
        return result;
 }
 
-static ssize_t f_midi_opts_id_store(struct f_midi_opts *opts,
+static ssize_t f_midi_opts_id_store(struct config_item *item,
                                    const char *page, size_t len)
 {
+       struct f_midi_opts *opts = to_f_midi_opts(item);
        int ret;
        char *c;
 
@@ -1012,17 +1009,15 @@ end:
        return ret;
 }
 
-static struct f_midi_opts_attribute f_midi_opts_id =
-       __CONFIGFS_ATTR(id, S_IRUGO | S_IWUSR, f_midi_opts_id_show,
-                       f_midi_opts_id_store);
+CONFIGFS_ATTR(f_midi_opts_, id);
 
 static struct configfs_attribute *midi_attrs[] = {
-       &f_midi_opts_index.attr,
-       &f_midi_opts_buflen.attr,
-       &f_midi_opts_qlen.attr,
-       &f_midi_opts_in_ports.attr,
-       &f_midi_opts_out_ports.attr,
-       &f_midi_opts_id.attr,
+       &f_midi_opts_attr_index,
+       &f_midi_opts_attr_buflen,
+       &f_midi_opts_attr_qlen,
+       &f_midi_opts_attr_in_ports,
+       &f_midi_opts_attr_out_ports,
+       &f_midi_opts_attr_id,
        NULL,
 };
 
index b6f7ed7d48a7fa6a297ccfeca6440465593462be..7ad798ace1e5b5d60c15712510fcf6b09ac81c86 100644 (file)
@@ -1488,10 +1488,10 @@ USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(ncm);
 USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(ncm);
 
 static struct configfs_attribute *ncm_attrs[] = {
-       &f_ncm_opts_dev_addr.attr,
-       &f_ncm_opts_host_addr.attr,
-       &f_ncm_opts_qmult.attr,
-       &f_ncm_opts_ifname.attr,
+       &ncm_opts_attr_dev_addr,
+       &ncm_opts_attr_host_addr,
+       &ncm_opts_attr_qmult,
+       &ncm_opts_attr_ifname,
        NULL,
 };
 
index 1c3d30ad2f92cb3edba2ab0eb3ca490378de86f1..d6396e0909eeb45898541094cb2347b4d38bde24 100644 (file)
@@ -387,22 +387,6 @@ static inline struct f_serial_opts *to_f_serial_opts(struct config_item *item)
                            func_inst.group);
 }
 
-CONFIGFS_ATTR_STRUCT(f_serial_opts);
-static ssize_t f_obex_attr_show(struct config_item *item,
-                               struct configfs_attribute *attr,
-                               char *page)
-{
-       struct f_serial_opts *opts = to_f_serial_opts(item);
-       struct f_serial_opts_attribute *f_serial_opts_attr =
-               container_of(attr, struct f_serial_opts_attribute, attr);
-       ssize_t ret = 0;
-
-       if (f_serial_opts_attr->show)
-               ret = f_serial_opts_attr->show(opts, page);
-
-       return ret;
-}
-
 static void obex_attr_release(struct config_item *item)
 {
        struct f_serial_opts *opts = to_f_serial_opts(item);
@@ -412,19 +396,17 @@ static void obex_attr_release(struct config_item *item)
 
 static struct configfs_item_operations obex_item_ops = {
        .release        = obex_attr_release,
-       .show_attribute = f_obex_attr_show,
 };
 
-static ssize_t f_obex_port_num_show(struct f_serial_opts *opts, char *page)
+static ssize_t f_obex_port_num_show(struct config_item *item, char *page)
 {
-       return sprintf(page, "%u\n", opts->port_num);
+       return sprintf(page, "%u\n", to_f_serial_opts(item)->port_num);
 }
 
-static struct f_serial_opts_attribute f_obex_port_num =
-       __CONFIGFS_ATTR_RO(port_num, f_obex_port_num_show);
+CONFIGFS_ATTR_RO(f_obex_, port_num);
 
 static struct configfs_attribute *acm_attrs[] = {
-       &f_obex_port_num.attr,
+       &f_obex_attr_port_num,
        NULL,
 };
 
index 62a198754029e1f707147a12713f758a186cdd8e..157441dbfeba861d4d877f8009dca6fb44acd740 100644 (file)
@@ -583,21 +583,6 @@ static inline struct f_phonet_opts *to_f_phonet_opts(struct config_item *item)
                        func_inst.group);
 }
 
-CONFIGFS_ATTR_STRUCT(f_phonet_opts);
-static ssize_t f_phonet_attr_show(struct config_item *item,
-                               struct configfs_attribute *attr,
-                               char *page)
-{
-       struct f_phonet_opts *opts = to_f_phonet_opts(item);
-       struct f_phonet_opts_attribute *f_phonet_opts_attr =
-               container_of(attr, struct f_phonet_opts_attribute, attr);
-       ssize_t ret = 0;
-
-       if (f_phonet_opts_attr->show)
-               ret = f_phonet_opts_attr->show(opts, page);
-       return ret;
-}
-
 static void phonet_attr_release(struct config_item *item)
 {
        struct f_phonet_opts *opts = to_f_phonet_opts(item);
@@ -607,19 +592,17 @@ static void phonet_attr_release(struct config_item *item)
 
 static struct configfs_item_operations phonet_item_ops = {
        .release                = phonet_attr_release,
-       .show_attribute         = f_phonet_attr_show,
 };
 
-static ssize_t f_phonet_ifname_show(struct f_phonet_opts *opts, char *page)
+static ssize_t f_phonet_ifname_show(struct config_item *item, char *page)
 {
-       return gether_get_ifname(opts->net, page, PAGE_SIZE);
+       return gether_get_ifname(to_f_phonet_opts(item)->net, page, PAGE_SIZE);
 }
 
-static struct f_phonet_opts_attribute f_phonet_ifname =
-       __CONFIGFS_ATTR_RO(ifname, f_phonet_ifname_show);
+CONFIGFS_ATTR_RO(f_phonet_, ifname);
 
 static struct configfs_attribute *phonet_attrs[] = {
-       &f_phonet_ifname.attr,
+       &f_phonet_attr_ifname,
        NULL,
 };
 
index 7fb3209ed52c31c662b24b1799e78ff9a4d38700..0fbfb2b2aa08b3ade8e4b487d012188687b29e05 100644 (file)
@@ -1146,9 +1146,6 @@ static inline struct f_printer_opts
                            func_inst.group);
 }
 
-CONFIGFS_ATTR_STRUCT(f_printer_opts);
-CONFIGFS_ATTR_OPS(f_printer_opts);
-
 static void printer_attr_release(struct config_item *item)
 {
        struct f_printer_opts *opts = to_f_printer_opts(item);
@@ -1158,13 +1155,12 @@ static void printer_attr_release(struct config_item *item)
 
 static struct configfs_item_operations printer_item_ops = {
        .release        = printer_attr_release,
-       .show_attribute = f_printer_opts_attr_show,
-       .store_attribute = f_printer_opts_attr_store,
 };
 
-static ssize_t f_printer_opts_pnp_string_show(struct f_printer_opts *opts,
+static ssize_t f_printer_opts_pnp_string_show(struct config_item *item,
                                              char *page)
 {
+       struct f_printer_opts *opts = to_f_printer_opts(item);
        int result;
 
        mutex_lock(&opts->lock);
@@ -1174,9 +1170,10 @@ static ssize_t f_printer_opts_pnp_string_show(struct f_printer_opts *opts,
        return result;
 }
 
-static ssize_t f_printer_opts_pnp_string_store(struct f_printer_opts *opts,
+static ssize_t f_printer_opts_pnp_string_store(struct config_item *item,
                                               const char *page, size_t len)
 {
+       struct f_printer_opts *opts = to_f_printer_opts(item);
        int result, l;
 
        mutex_lock(&opts->lock);
@@ -1189,14 +1186,12 @@ static ssize_t f_printer_opts_pnp_string_store(struct f_printer_opts *opts,
        return result;
 }
 
-static struct f_printer_opts_attribute f_printer_opts_pnp_string =
-       __CONFIGFS_ATTR(pnp_string, S_IRUGO | S_IWUSR,
-                       f_printer_opts_pnp_string_show,
-                       f_printer_opts_pnp_string_store);
+CONFIGFS_ATTR(f_printer_opts_, pnp_string);
 
-static ssize_t f_printer_opts_q_len_show(struct f_printer_opts *opts,
+static ssize_t f_printer_opts_q_len_show(struct config_item *item,
                                         char *page)
 {
+       struct f_printer_opts *opts = to_f_printer_opts(item);
        int result;
 
        mutex_lock(&opts->lock);
@@ -1206,9 +1201,10 @@ static ssize_t f_printer_opts_q_len_show(struct f_printer_opts *opts,
        return result;
 }
 
-static ssize_t f_printer_opts_q_len_store(struct f_printer_opts *opts,
+static ssize_t f_printer_opts_q_len_store(struct config_item *item,
                                          const char *page, size_t len)
 {
+       struct f_printer_opts *opts = to_f_printer_opts(item);
        int ret;
        u16 num;
 
@@ -1229,13 +1225,11 @@ end:
        return ret;
 }
 
-static struct f_printer_opts_attribute f_printer_opts_q_len =
-       __CONFIGFS_ATTR(q_len, S_IRUGO | S_IWUSR, f_printer_opts_q_len_show,
-                       f_printer_opts_q_len_store);
+CONFIGFS_ATTR(f_printer_opts_, q_len);
 
 static struct configfs_attribute *printer_attrs[] = {
-       &f_printer_opts_pnp_string.attr,
-       &f_printer_opts_q_len.attr,
+       &f_printer_opts_attr_pnp_string,
+       &f_printer_opts_attr_q_len,
        NULL,
 };
 
index fd301ed9e294fa480ad0336fc17833e772611765..e587767e374cbc2fbae3b02879b5358c38d48e69 100644 (file)
@@ -864,10 +864,10 @@ USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(rndis);
 USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(rndis);
 
 static struct configfs_attribute *rndis_attrs[] = {
-       &f_rndis_opts_dev_addr.attr,
-       &f_rndis_opts_host_addr.attr,
-       &f_rndis_opts_qmult.attr,
-       &f_rndis_opts_ifname.attr,
+       &rndis_opts_attr_dev_addr,
+       &rndis_opts_attr_host_addr,
+       &rndis_opts_attr_qmult,
+       &rndis_opts_attr_ifname,
        NULL,
 };
 
index ba705e047d7e0fca31ce8a2ede4d67f595efb5ca..6bb44d613baba28106d31023d337edf6367b9333 100644 (file)
@@ -258,22 +258,6 @@ static inline struct f_serial_opts *to_f_serial_opts(struct config_item *item)
                            func_inst.group);
 }
 
-CONFIGFS_ATTR_STRUCT(f_serial_opts);
-static ssize_t f_serial_attr_show(struct config_item *item,
-                                 struct configfs_attribute *attr,
-                                 char *page)
-{
-       struct f_serial_opts *opts = to_f_serial_opts(item);
-       struct f_serial_opts_attribute *f_serial_opts_attr =
-               container_of(attr, struct f_serial_opts_attribute, attr);
-       ssize_t ret = 0;
-
-       if (f_serial_opts_attr->show)
-               ret = f_serial_opts_attr->show(opts, page);
-
-       return ret;
-}
-
 static void serial_attr_release(struct config_item *item)
 {
        struct f_serial_opts *opts = to_f_serial_opts(item);
@@ -283,19 +267,17 @@ static void serial_attr_release(struct config_item *item)
 
 static struct configfs_item_operations serial_item_ops = {
        .release        = serial_attr_release,
-       .show_attribute = f_serial_attr_show,
 };
 
-static ssize_t f_serial_port_num_show(struct f_serial_opts *opts, char *page)
+static ssize_t f_serial_port_num_show(struct config_item *item, char *page)
 {
-       return sprintf(page, "%u\n", opts->port_num);
+       return sprintf(page, "%u\n", to_f_serial_opts(item)->port_num);
 }
 
-static struct f_serial_opts_attribute f_serial_port_num =
-       __CONFIGFS_ATTR_RO(port_num, f_serial_port_num_show);
+CONFIGFS_ATTR_RO(f_serial_, port_num);
 
 static struct configfs_attribute *acm_attrs[] = {
-       &f_serial_port_num.attr,
+       &f_serial_attr_port_num,
        NULL,
 };
 
index d7646d3acd63ecb4aa87362e069b54faff909844..9f3ced62d9162c991c03b0db68d10fd0cbe06ea9 100644 (file)
@@ -889,9 +889,6 @@ static inline struct f_ss_opts *to_f_ss_opts(struct config_item *item)
                            func_inst.group);
 }
 
-CONFIGFS_ATTR_STRUCT(f_ss_opts);
-CONFIGFS_ATTR_OPS(f_ss_opts);
-
 static void ss_attr_release(struct config_item *item)
 {
        struct f_ss_opts *ss_opts = to_f_ss_opts(item);
@@ -901,12 +898,11 @@ static void ss_attr_release(struct config_item *item)
 
 static struct configfs_item_operations ss_item_ops = {
        .release                = ss_attr_release,
-       .show_attribute         = f_ss_opts_attr_show,
-       .store_attribute        = f_ss_opts_attr_store,
 };
 
-static ssize_t f_ss_opts_pattern_show(struct f_ss_opts *opts, char *page)
+static ssize_t f_ss_opts_pattern_show(struct config_item *item, char *page)
 {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int result;
 
        mutex_lock(&opts->lock);
@@ -916,9 +912,10 @@ static ssize_t f_ss_opts_pattern_show(struct f_ss_opts *opts, char *page)
        return result;
 }
 
-static ssize_t f_ss_opts_pattern_store(struct f_ss_opts *opts,
+static ssize_t f_ss_opts_pattern_store(struct config_item *item,
                                       const char *page, size_t len)
 {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int ret;
        u8 num;
 
@@ -944,13 +941,11 @@ end:
        return ret;
 }
 
-static struct f_ss_opts_attribute f_ss_opts_pattern =
-       __CONFIGFS_ATTR(pattern, S_IRUGO | S_IWUSR,
-                       f_ss_opts_pattern_show,
-                       f_ss_opts_pattern_store);
+CONFIGFS_ATTR(f_ss_opts_, pattern);
 
-static ssize_t f_ss_opts_isoc_interval_show(struct f_ss_opts *opts, char *page)
+static ssize_t f_ss_opts_isoc_interval_show(struct config_item *item, char *page)
 {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int result;
 
        mutex_lock(&opts->lock);
@@ -960,9 +955,10 @@ static ssize_t f_ss_opts_isoc_interval_show(struct f_ss_opts *opts, char *page)
        return result;
 }
 
-static ssize_t f_ss_opts_isoc_interval_store(struct f_ss_opts *opts,
+static ssize_t f_ss_opts_isoc_interval_store(struct config_item *item,
                                       const char *page, size_t len)
 {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int ret;
        u8 num;
 
@@ -988,13 +984,11 @@ end:
        return ret;
 }
 
-static struct f_ss_opts_attribute f_ss_opts_isoc_interval =
-       __CONFIGFS_ATTR(isoc_interval, S_IRUGO | S_IWUSR,
-                       f_ss_opts_isoc_interval_show,
-                       f_ss_opts_isoc_interval_store);
+CONFIGFS_ATTR(f_ss_opts_, isoc_interval);
 
-static ssize_t f_ss_opts_isoc_maxpacket_show(struct f_ss_opts *opts, char *page)
+static ssize_t f_ss_opts_isoc_maxpacket_show(struct config_item *item, char *page)
 {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int result;
 
        mutex_lock(&opts->lock);
@@ -1004,9 +998,10 @@ static ssize_t f_ss_opts_isoc_maxpacket_show(struct f_ss_opts *opts, char *page)
        return result;
 }
 
-static ssize_t f_ss_opts_isoc_maxpacket_store(struct f_ss_opts *opts,
+static ssize_t f_ss_opts_isoc_maxpacket_store(struct config_item *item,
                                       const char *page, size_t len)
 {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int ret;
        u16 num;
 
@@ -1032,13 +1027,11 @@ end:
        return ret;
 }
 
-static struct f_ss_opts_attribute f_ss_opts_isoc_maxpacket =
-       __CONFIGFS_ATTR(isoc_maxpacket, S_IRUGO | S_IWUSR,
-                       f_ss_opts_isoc_maxpacket_show,
-                       f_ss_opts_isoc_maxpacket_store);
+CONFIGFS_ATTR(f_ss_opts_, isoc_maxpacket);
 
-static ssize_t f_ss_opts_isoc_mult_show(struct f_ss_opts *opts, char *page)
+static ssize_t f_ss_opts_isoc_mult_show(struct config_item *item, char *page)
 {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int result;
 
        mutex_lock(&opts->lock);
@@ -1048,9 +1041,10 @@ static ssize_t f_ss_opts_isoc_mult_show(struct f_ss_opts *opts, char *page)
        return result;
 }
 
-static ssize_t f_ss_opts_isoc_mult_store(struct f_ss_opts *opts,
+static ssize_t f_ss_opts_isoc_mult_store(struct config_item *item,
                                       const char *page, size_t len)
 {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int ret;
        u8 num;
 
@@ -1076,13 +1070,11 @@ end:
        return ret;
 }
 
-static struct f_ss_opts_attribute f_ss_opts_isoc_mult =
-       __CONFIGFS_ATTR(isoc_mult, S_IRUGO | S_IWUSR,
-                       f_ss_opts_isoc_mult_show,
-                       f_ss_opts_isoc_mult_store);
+CONFIGFS_ATTR(f_ss_opts_, isoc_mult);
 
-static ssize_t f_ss_opts_isoc_maxburst_show(struct f_ss_opts *opts, char *page)
+static ssize_t f_ss_opts_isoc_maxburst_show(struct config_item *item, char *page)
 {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int result;
 
        mutex_lock(&opts->lock);
@@ -1092,9 +1084,10 @@ static ssize_t f_ss_opts_isoc_maxburst_show(struct f_ss_opts *opts, char *page)
        return result;
 }
 
-static ssize_t f_ss_opts_isoc_maxburst_store(struct f_ss_opts *opts,
+static ssize_t f_ss_opts_isoc_maxburst_store(struct config_item *item,
                                       const char *page, size_t len)
 {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int ret;
        u8 num;
 
@@ -1120,13 +1113,11 @@ end:
        return ret;
 }
 
-static struct f_ss_opts_attribute f_ss_opts_isoc_maxburst =
-       __CONFIGFS_ATTR(isoc_maxburst, S_IRUGO | S_IWUSR,
-                       f_ss_opts_isoc_maxburst_show,
-                       f_ss_opts_isoc_maxburst_store);
+CONFIGFS_ATTR(f_ss_opts_, isoc_maxburst);
 
-static ssize_t f_ss_opts_bulk_buflen_show(struct f_ss_opts *opts, char *page)
+static ssize_t f_ss_opts_bulk_buflen_show(struct config_item *item, char *page)
 {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int result;
 
        mutex_lock(&opts->lock);
@@ -1136,9 +1127,10 @@ static ssize_t f_ss_opts_bulk_buflen_show(struct f_ss_opts *opts, char *page)
        return result;
 }
 
-static ssize_t f_ss_opts_bulk_buflen_store(struct f_ss_opts *opts,
+static ssize_t f_ss_opts_bulk_buflen_store(struct config_item *item,
                                           const char *page, size_t len)
 {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int ret;
        u32 num;
 
@@ -1159,18 +1151,15 @@ end:
        return ret;
 }
 
-static struct f_ss_opts_attribute f_ss_opts_bulk_buflen =
-       __CONFIGFS_ATTR(buflen, S_IRUGO | S_IWUSR,
-                       f_ss_opts_bulk_buflen_show,
-                       f_ss_opts_bulk_buflen_store);
+CONFIGFS_ATTR(f_ss_opts_, bulk_buflen);
 
 static struct configfs_attribute *ss_attrs[] = {
-       &f_ss_opts_pattern.attr,
-       &f_ss_opts_isoc_interval.attr,
-       &f_ss_opts_isoc_maxpacket.attr,
-       &f_ss_opts_isoc_mult.attr,
-       &f_ss_opts_isoc_maxburst.attr,
-       &f_ss_opts_bulk_buflen.attr,
+       &f_ss_opts_attr_pattern,
+       &f_ss_opts_attr_isoc_interval,
+       &f_ss_opts_attr_isoc_maxpacket,
+       &f_ss_opts_attr_isoc_mult,
+       &f_ss_opts_attr_isoc_maxburst,
+       &f_ss_opts_attr_bulk_buflen,
        NULL,
 };
 
index 2e66e624e6e13dfed2fde71fff294a10a986bb7a..829c78de9ebac728919784951b89d05d7d942361 100644 (file)
@@ -405,10 +405,10 @@ USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(gether);
 USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(gether);
 
 static struct configfs_attribute *gether_attrs[] = {
-       &f_gether_opts_dev_addr.attr,
-       &f_gether_opts_host_addr.attr,
-       &f_gether_opts_qmult.attr,
-       &f_gether_opts_ifname.attr,
+       &gether_opts_attr_dev_addr,
+       &gether_opts_attr_host_addr,
+       &gether_opts_attr_qmult,
+       &gether_opts_attr_ifname,
        NULL,
 };
 
index 8ee701924d29d0c5ad27edfed1b3e23c15b5c3e7..6a2346b99f5591911f92200d68e880ff3b2e5d18 100644 (file)
@@ -769,9 +769,6 @@ static inline struct f_uac1_opts *to_f_uac1_opts(struct config_item *item)
                            func_inst.group);
 }
 
-CONFIGFS_ATTR_STRUCT(f_uac1_opts);
-CONFIGFS_ATTR_OPS(f_uac1_opts);
-
 static void f_uac1_attr_release(struct config_item *item)
 {
        struct f_uac1_opts *opts = to_f_uac1_opts(item);
@@ -781,14 +778,13 @@ static void f_uac1_attr_release(struct config_item *item)
 
 static struct configfs_item_operations f_uac1_item_ops = {
        .release        = f_uac1_attr_release,
-       .show_attribute = f_uac1_opts_attr_show,
-       .store_attribute = f_uac1_opts_attr_store,
 };
 
 #define UAC1_INT_ATTRIBUTE(name)                                       \
-static ssize_t f_uac1_opts_##name##_show(struct f_uac1_opts *opts,     \
+static ssize_t f_uac1_opts_##name##_show(struct config_item *item,     \
                                         char *page)                    \
 {                                                                      \
+       struct f_uac1_opts *opts = to_f_uac1_opts(item);                \
        int result;                                                     \
                                                                        \
        mutex_lock(&opts->lock);                                        \
@@ -798,9 +794,10 @@ static ssize_t f_uac1_opts_##name##_show(struct f_uac1_opts *opts, \
        return result;                                                  \
 }                                                                      \
                                                                        \
-static ssize_t f_uac1_opts_##name##_store(struct f_uac1_opts *opts,    \
+static ssize_t f_uac1_opts_##name##_store(struct config_item *item,            \
                                          const char *page, size_t len) \
 {                                                                      \
+       struct f_uac1_opts *opts = to_f_uac1_opts(item);                \
        int ret;                                                        \
        u32 num;                                                        \
                                                                        \
@@ -822,19 +819,17 @@ end:                                                                      \
        return ret;                                                     \
 }                                                                      \
                                                                        \
-static struct f_uac1_opts_attribute f_uac1_opts_##name =               \
-       __CONFIGFS_ATTR(name, S_IRUGO | S_IWUSR,                        \
-                       f_uac1_opts_##name##_show,                      \
-                       f_uac1_opts_##name##_store)
+CONFIGFS_ATTR(f_uac1_opts_, name)
 
 UAC1_INT_ATTRIBUTE(req_buf_size);
 UAC1_INT_ATTRIBUTE(req_count);
 UAC1_INT_ATTRIBUTE(audio_buf_size);
 
 #define UAC1_STR_ATTRIBUTE(name)                                       \
-static ssize_t f_uac1_opts_##name##_show(struct f_uac1_opts *opts,     \
+static ssize_t f_uac1_opts_##name##_show(struct config_item *item,     \
                                         char *page)                    \
 {                                                                      \
+       struct f_uac1_opts *opts = to_f_uac1_opts(item);                \
        int result;                                                     \
                                                                        \
        mutex_lock(&opts->lock);                                        \
@@ -844,9 +839,10 @@ static ssize_t f_uac1_opts_##name##_show(struct f_uac1_opts *opts, \
        return result;                                                  \
 }                                                                      \
                                                                        \
-static ssize_t f_uac1_opts_##name##_store(struct f_uac1_opts *opts,    \
+static ssize_t f_uac1_opts_##name##_store(struct config_item *item,    \
                                          const char *page, size_t len) \
 {                                                                      \
+       struct f_uac1_opts *opts = to_f_uac1_opts(item);                \
        int ret = -EBUSY;                                               \
        char *tmp;                                                      \
                                                                        \
@@ -870,22 +866,19 @@ end:                                                                      \
        return ret;                                                     \
 }                                                                      \
                                                                        \
-static struct f_uac1_opts_attribute f_uac1_opts_##name =               \
-       __CONFIGFS_ATTR(name, S_IRUGO | S_IWUSR,                        \
-                       f_uac1_opts_##name##_show,                      \
-                       f_uac1_opts_##name##_store)
+CONFIGFS_ATTR(f_uac1_opts_, name)
 
 UAC1_STR_ATTRIBUTE(fn_play);
 UAC1_STR_ATTRIBUTE(fn_cap);
 UAC1_STR_ATTRIBUTE(fn_cntl);
 
 static struct configfs_attribute *f_uac1_attrs[] = {
-       &f_uac1_opts_req_buf_size.attr,
-       &f_uac1_opts_req_count.attr,
-       &f_uac1_opts_audio_buf_size.attr,
-       &f_uac1_opts_fn_play.attr,
-       &f_uac1_opts_fn_cap.attr,
-       &f_uac1_opts_fn_cntl.attr,
+       &f_uac1_opts_attr_req_buf_size,
+       &f_uac1_opts_attr_req_count,
+       &f_uac1_opts_attr_audio_buf_size,
+       &f_uac1_opts_attr_fn_play,
+       &f_uac1_opts_attr_fn_cap,
+       &f_uac1_opts_attr_fn_cntl,
        NULL,
 };
 
index 63336e269898d07ac42c2ab66117c9aaed2ae142..044ca79d3cb5d3b8a4764e27c1a1749caa43c971 100644 (file)
@@ -1439,9 +1439,6 @@ static inline struct f_uac2_opts *to_f_uac2_opts(struct config_item *item)
                            func_inst.group);
 }
 
-CONFIGFS_ATTR_STRUCT(f_uac2_opts);
-CONFIGFS_ATTR_OPS(f_uac2_opts);
-
 static void f_uac2_attr_release(struct config_item *item)
 {
        struct f_uac2_opts *opts = to_f_uac2_opts(item);
@@ -1451,14 +1448,13 @@ static void f_uac2_attr_release(struct config_item *item)
 
 static struct configfs_item_operations f_uac2_item_ops = {
        .release        = f_uac2_attr_release,
-       .show_attribute = f_uac2_opts_attr_show,
-       .store_attribute = f_uac2_opts_attr_store,
 };
 
 #define UAC2_ATTRIBUTE(name)                                           \
-static ssize_t f_uac2_opts_##name##_show(struct f_uac2_opts *opts,     \
+static ssize_t f_uac2_opts_##name##_show(struct config_item *item,     \
                                         char *page)                    \
 {                                                                      \
+       struct f_uac2_opts *opts = to_f_uac2_opts(item);                \
        int result;                                                     \
                                                                        \
        mutex_lock(&opts->lock);                                        \
@@ -1468,9 +1464,10 @@ static ssize_t f_uac2_opts_##name##_show(struct f_uac2_opts *opts,       \
        return result;                                                  \
 }                                                                      \
                                                                        \
-static ssize_t f_uac2_opts_##name##_store(struct f_uac2_opts *opts,    \
+static ssize_t f_uac2_opts_##name##_store(struct config_item *item,    \
                                          const char *page, size_t len) \
 {                                                                      \
+       struct f_uac2_opts *opts = to_f_uac2_opts(item);                \
        int ret;                                                        \
        u32 num;                                                        \
                                                                        \
@@ -1492,10 +1489,7 @@ end:                                                                     \
        return ret;                                                     \
 }                                                                      \
                                                                        \
-static struct f_uac2_opts_attribute f_uac2_opts_##name =               \
-       __CONFIGFS_ATTR(name, S_IRUGO | S_IWUSR,                        \
-                       f_uac2_opts_##name##_show,                      \
-                       f_uac2_opts_##name##_store)
+CONFIGFS_ATTR(f_uac2_opts_, name)
 
 UAC2_ATTRIBUTE(p_chmask);
 UAC2_ATTRIBUTE(p_srate);
@@ -1505,12 +1499,12 @@ UAC2_ATTRIBUTE(c_srate);
 UAC2_ATTRIBUTE(c_ssize);
 
 static struct configfs_attribute *f_uac2_attrs[] = {
-       &f_uac2_opts_p_chmask.attr,
-       &f_uac2_opts_p_srate.attr,
-       &f_uac2_opts_p_ssize.attr,
-       &f_uac2_opts_c_chmask.attr,
-       &f_uac2_opts_c_srate.attr,
-       &f_uac2_opts_c_ssize.attr,
+       &f_uac2_opts_attr_p_chmask,
+       &f_uac2_opts_attr_p_srate,
+       &f_uac2_opts_attr_p_ssize,
+       &f_uac2_opts_attr_c_chmask,
+       &f_uac2_opts_attr_c_srate,
+       &f_uac2_opts_attr_c_ssize,
        NULL,
 };
 
index bcbd30146cfde6a3ff74b252621ee6b0b3e1c764..4f47289fcf7cee45e93e8f9171a19390f91ee49f 100644 (file)
@@ -17,9 +17,6 @@
 #define __U_ETHER_CONFIGFS_H
 
 #define USB_ETHERNET_CONFIGFS_ITEM(_f_)                                        \
-       CONFIGFS_ATTR_STRUCT(f_##_f_##_opts);                           \
-       CONFIGFS_ATTR_OPS(f_##_f_##_opts);                              \
-                                                                       \
        static void _f_##_attr_release(struct config_item *item)        \
        {                                                               \
                struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);  \
                                                                        \
        static struct configfs_item_operations _f_##_item_ops = {       \
                .release        = _f_##_attr_release,                   \
-               .show_attribute = f_##_f_##_opts_attr_show,             \
-               .store_attribute = f_##_f_##_opts_attr_store,           \
        }
 
 #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_DEV_ADDR(_f_)                  \
-       static ssize_t _f_##_opts_dev_addr_show(struct f_##_f_##_opts *opts, \
+       static ssize_t _f_##_opts_dev_addr_show(struct config_item *item, \
                                                char *page)             \
        {                                                               \
+               struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);  \
                int result;                                             \
                                                                        \
                mutex_lock(&opts->lock);                                \
                return result;                                          \
        }                                                               \
                                                                        \
-       static ssize_t _f_##_opts_dev_addr_store(struct f_##_f_##_opts *opts, \
+       static ssize_t _f_##_opts_dev_addr_store(struct config_item *item, \
                                                 const char *page, size_t len)\
        {                                                               \
+               struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);  \
                int ret;                                                \
                                                                        \
                mutex_lock(&opts->lock);                                \
                return ret;                                             \
        }                                                               \
                                                                        \
-       static struct f_##_f_##_opts_attribute f_##_f_##_opts_dev_addr = \
-               __CONFIGFS_ATTR(dev_addr, S_IRUGO | S_IWUSR,            \
-                               _f_##_opts_dev_addr_show,               \
-                               _f_##_opts_dev_addr_store)
+       CONFIGFS_ATTR(_f_##_opts_, dev_addr)
 
 #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_HOST_ADDR(_f_)                 \
-       static ssize_t _f_##_opts_host_addr_show(struct f_##_f_##_opts *opts, \
+       static ssize_t _f_##_opts_host_addr_show(struct config_item *item, \
                                                 char *page)            \
        {                                                               \
+               struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);  \
                int result;                                             \
                                                                        \
                mutex_lock(&opts->lock);                                \
                return result;                                          \
        }                                                               \
                                                                        \
-       static ssize_t _f_##_opts_host_addr_store(struct f_##_f_##_opts *opts, \
+       static ssize_t _f_##_opts_host_addr_store(struct config_item *item, \
                                                  const char *page, size_t len)\
        {                                                               \
+               struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);  \
                int ret;                                                \
                                                                        \
                mutex_lock(&opts->lock);                                \
                return ret;                                             \
        }                                                               \
                                                                        \
-       static struct f_##_f_##_opts_attribute f_##_f_##_opts_host_addr = \
-               __CONFIGFS_ATTR(host_addr, S_IRUGO | S_IWUSR,           \
-                               _f_##_opts_host_addr_show,              \
-                               _f_##_opts_host_addr_store)
+       CONFIGFS_ATTR(_f_##_opts_, host_addr)
 
 #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(_f_)                     \
-       static ssize_t _f_##_opts_qmult_show(struct f_##_f_##_opts *opts, \
+       static ssize_t _f_##_opts_qmult_show(struct config_item *item,  \
                                             char *page)                \
        {                                                               \
+               struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);  \
                unsigned qmult;                                         \
                                                                        \
                mutex_lock(&opts->lock);                                \
                return sprintf(page, "%d", qmult);                      \
        }                                                               \
                                                                        \
-       static ssize_t _f_##_opts_qmult_store(struct f_##_f_##_opts *opts, \
+       static ssize_t _f_##_opts_qmult_store(struct config_item *item, \
                                              const char *page, size_t len)\
        {                                                               \
+               struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);  \
                u8 val;                                                 \
                int ret;                                                \
                                                                        \
@@ -140,15 +135,13 @@ out:                                                                      \
                return ret;                                             \
        }                                                               \
                                                                        \
-       static struct f_##_f_##_opts_attribute f_##_f_##_opts_qmult =   \
-               __CONFIGFS_ATTR(qmult, S_IRUGO | S_IWUSR,               \
-                               _f_##_opts_qmult_show,          \
-                               _f_##_opts_qmult_store)
+       CONFIGFS_ATTR(_f_##_opts_, qmult)
 
 #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(_f_)                    \
-       static ssize_t _f_##_opts_ifname_show(struct f_##_f_##_opts *opts, \
+       static ssize_t _f_##_opts_ifname_show(struct config_item *item, \
                                              char *page)               \
        {                                                               \
+               struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);  \
                int ret;                                                \
                                                                        \
                mutex_lock(&opts->lock);                                \
@@ -158,7 +151,6 @@ out:                                                                        \
                return ret;                                             \
        }                                                               \
                                                                        \
-       static struct f_##_f_##_opts_attribute f_##_f_##_opts_ifname =  \
-               __CONFIGFS_ATTR_RO(ifname, _f_##_opts_ifname_show)
+       CONFIGFS_ATTR_RO(_f_##_opts_, ifname)
 
 #endif /* __U_ETHER_CONFIGFS_H */
index 3c0467bcb14fd9a3ccc15104a22e24f461781b4d..289ebca316d3f4ab0e136a14858bb7275eee53c0 100644 (file)
 
 #define UVCG_STREAMING_CONTROL_SIZE    1
 
-#define CONFIGFS_ATTR_OPS_RO(_item)                                    \
-static ssize_t _item##_attr_show(struct config_item *item,             \
-                                struct configfs_attribute *attr,       \
-                                char *page)                            \
-{                                                                      \
-       struct _item *_item = to_##_item(item);                         \
-       struct _item##_attribute *_item##_attr =                        \
-               container_of(attr, struct _item##_attribute, attr);     \
-       ssize_t ret = 0;                                                \
-                                                                       \
-       if (_item##_attr->show)                                         \
-               ret = _item##_attr->show(_item, page);                  \
-       return ret;                                                     \
+#define UVC_ATTR(prefix, cname, aname) \
+static struct configfs_attribute prefix##attr_##cname = { \
+       .ca_name        = __stringify(aname),                           \
+       .ca_mode        = S_IRUGO,                                      \
+       .ca_owner       = THIS_MODULE,                                  \
+       .show           = prefix##cname##_show,                         \
+       .store          = prefix##cname##_store,                        \
+}
+
+#define UVC_ATTR_RO(prefix, cname, aname) \
+static struct configfs_attribute prefix##attr_##cname = { \
+       .ca_name        = __stringify(aname),                           \
+       .ca_mode        = S_IRUGO,                                      \
+       .ca_owner       = THIS_MODULE,                                  \
+       .show           = prefix##cname##_show,                         \
 }
 
 static inline struct f_uvc_opts *to_f_uvc_opts(struct config_item *item);
@@ -48,18 +50,11 @@ static struct uvcg_control_header *to_uvcg_control_header(struct config_item *it
        return container_of(item, struct uvcg_control_header, item);
 }
 
-CONFIGFS_ATTR_STRUCT(uvcg_control_header);
-CONFIGFS_ATTR_OPS(uvcg_control_header);
-
-static struct configfs_item_operations uvcg_control_header_item_ops = {
-       .show_attribute         = uvcg_control_header_attr_show,
-       .store_attribute        = uvcg_control_header_attr_store,
-};
-
 #define UVCG_CTRL_HDR_ATTR(cname, aname, conv, str2u, uxx, vnoc, limit)        \
 static ssize_t uvcg_control_header_##cname##_show(                     \
-       struct uvcg_control_header *ch, char *page)                     \
+       struct config_item *item, char *page)                   \
 {                                                                      \
+       struct uvcg_control_header *ch = to_uvcg_control_header(item);  \
        struct f_uvc_opts *opts;                                        \
        struct config_item *opts_item;                                  \
        struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex;\
@@ -79,9 +74,10 @@ static ssize_t uvcg_control_header_##cname##_show(                   \
 }                                                                      \
                                                                        \
 static ssize_t                                                         \
-uvcg_control_header_##cname##_store(struct uvcg_control_header *ch,    \
+uvcg_control_header_##cname##_store(struct config_item *item,          \
                           const char *page, size_t len)                \
 {                                                                      \
+       struct uvcg_control_header *ch = to_uvcg_control_header(item);  \
        struct f_uvc_opts *opts;                                        \
        struct config_item *opts_item;                                  \
        struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex;\
@@ -115,11 +111,7 @@ end:                                                                       \
        return ret;                                                     \
 }                                                                      \
                                                                        \
-static struct uvcg_control_header_attribute                            \
-       uvcg_control_header_##cname =                                   \
-       __CONFIGFS_ATTR(aname, S_IRUGO | S_IWUSR,                       \
-                       uvcg_control_header_##cname##_show,             \
-                       uvcg_control_header_##cname##_store)
+UVC_ATTR(uvcg_control_header_, cname, aname)
 
 UVCG_CTRL_HDR_ATTR(bcd_uvc, bcdUVC, le16_to_cpu, kstrtou16, u16, cpu_to_le16,
                   0xffff);
@@ -130,13 +122,12 @@ UVCG_CTRL_HDR_ATTR(dw_clock_frequency, dwClockFrequency, le32_to_cpu, kstrtou32,
 #undef UVCG_CTRL_HDR_ATTR
 
 static struct configfs_attribute *uvcg_control_header_attrs[] = {
-       &uvcg_control_header_bcd_uvc.attr,
-       &uvcg_control_header_dw_clock_frequency.attr,
+       &uvcg_control_header_attr_bcd_uvc,
+       &uvcg_control_header_attr_dw_clock_frequency,
        NULL,
 };
 
 static struct config_item_type uvcg_control_header_type = {
-       .ct_item_ops    = &uvcg_control_header_item_ops,
        .ct_attrs       = uvcg_control_header_attrs,
        .ct_owner       = THIS_MODULE,
 };
@@ -196,17 +187,11 @@ static inline struct uvcg_default_processing
                            struct uvcg_default_processing, group);
 }
 
-CONFIGFS_ATTR_STRUCT(uvcg_default_processing);
-CONFIGFS_ATTR_OPS_RO(uvcg_default_processing);
-
-static struct configfs_item_operations uvcg_default_processing_item_ops = {
-       .show_attribute         = uvcg_default_processing_attr_show,
-};
-
 #define UVCG_DEFAULT_PROCESSING_ATTR(cname, aname, conv)               \
 static ssize_t uvcg_default_processing_##cname##_show(                 \
-       struct uvcg_default_processing *dp, char *page)                 \
+       struct config_item *item, char *page)                           \
 {                                                                      \
+       struct uvcg_default_processing *dp = to_uvcg_default_processing(item); \
        struct f_uvc_opts *opts;                                        \
        struct config_item *opts_item;                                  \
        struct mutex *su_mutex = &dp->group.cg_subsys->su_mutex;        \
@@ -227,9 +212,7 @@ static ssize_t uvcg_default_processing_##cname##_show(                      \
        return result;                                                  \
 }                                                                      \
                                                                        \
-static struct uvcg_default_processing_attribute                                \
-       uvcg_default_processing_##cname =                               \
-       __CONFIGFS_ATTR_RO(aname, uvcg_default_processing_##cname##_show)
+UVC_ATTR_RO(uvcg_default_processing_, cname, aname)
 
 #define identity_conv(x) (x)
 
@@ -243,8 +226,9 @@ UVCG_DEFAULT_PROCESSING_ATTR(i_processing, iProcessing, identity_conv);
 #undef UVCG_DEFAULT_PROCESSING_ATTR
 
 static ssize_t uvcg_default_processing_bm_controls_show(
-       struct uvcg_default_processing *dp, char *page)
+       struct config_item *item, char *page)
 {
+       struct uvcg_default_processing *dp = to_uvcg_default_processing(item);
        struct f_uvc_opts *opts;
        struct config_item *opts_item;
        struct mutex *su_mutex = &dp->group.cg_subsys->su_mutex;
@@ -270,22 +254,18 @@ static ssize_t uvcg_default_processing_bm_controls_show(
        return result;
 }
 
-static struct uvcg_default_processing_attribute
-       uvcg_default_processing_bm_controls =
-       __CONFIGFS_ATTR_RO(bmControls,
-               uvcg_default_processing_bm_controls_show);
+UVC_ATTR_RO(uvcg_default_processing_, bm_controls, bmControls);
 
 static struct configfs_attribute *uvcg_default_processing_attrs[] = {
-       &uvcg_default_processing_b_unit_id.attr,
-       &uvcg_default_processing_b_source_id.attr,
-       &uvcg_default_processing_w_max_multiplier.attr,
-       &uvcg_default_processing_bm_controls.attr,
-       &uvcg_default_processing_i_processing.attr,
+       &uvcg_default_processing_attr_b_unit_id,
+       &uvcg_default_processing_attr_b_source_id,
+       &uvcg_default_processing_attr_w_max_multiplier,
+       &uvcg_default_processing_attr_bm_controls,
+       &uvcg_default_processing_attr_i_processing,
        NULL,
 };
 
 static struct config_item_type uvcg_default_processing_type = {
-       .ct_item_ops    = &uvcg_default_processing_item_ops,
        .ct_attrs       = uvcg_default_processing_attrs,
        .ct_owner       = THIS_MODULE,
 };
@@ -318,17 +298,11 @@ static inline struct uvcg_default_camera
                            struct uvcg_default_camera, group);
 }
 
-CONFIGFS_ATTR_STRUCT(uvcg_default_camera);
-CONFIGFS_ATTR_OPS_RO(uvcg_default_camera);
-
-static struct configfs_item_operations uvcg_default_camera_item_ops = {
-       .show_attribute         = uvcg_default_camera_attr_show,
-};
-
 #define UVCG_DEFAULT_CAMERA_ATTR(cname, aname, conv)                   \
 static ssize_t uvcg_default_camera_##cname##_show(                     \
-       struct uvcg_default_camera *dc, char *page)                     \
+       struct config_item *item, char *page)                           \
 {                                                                      \
+       struct uvcg_default_camera *dc = to_uvcg_default_camera(item);  \
        struct f_uvc_opts *opts;                                        \
        struct config_item *opts_item;                                  \
        struct mutex *su_mutex = &dc->group.cg_subsys->su_mutex;        \
@@ -351,9 +325,7 @@ static ssize_t uvcg_default_camera_##cname##_show(                  \
        return result;                                                  \
 }                                                                      \
                                                                        \
-static struct uvcg_default_camera_attribute                            \
-       uvcg_default_camera_##cname =                                   \
-       __CONFIGFS_ATTR_RO(aname, uvcg_default_camera_##cname##_show)
+UVC_ATTR_RO(uvcg_default_camera_, cname, aname)
 
 #define identity_conv(x) (x)
 
@@ -373,8 +345,9 @@ UVCG_DEFAULT_CAMERA_ATTR(w_ocular_focal_length, wOcularFocalLength,
 #undef UVCG_DEFAULT_CAMERA_ATTR
 
 static ssize_t uvcg_default_camera_bm_controls_show(
-       struct uvcg_default_camera *dc, char *page)
+       struct config_item *item, char *page)
 {
+       struct uvcg_default_camera *dc = to_uvcg_default_camera(item);
        struct f_uvc_opts *opts;
        struct config_item *opts_item;
        struct mutex *su_mutex = &dc->group.cg_subsys->su_mutex;
@@ -400,24 +373,21 @@ static ssize_t uvcg_default_camera_bm_controls_show(
        return result;
 }
 
-static struct uvcg_default_camera_attribute
-       uvcg_default_camera_bm_controls =
-       __CONFIGFS_ATTR_RO(bmControls, uvcg_default_camera_bm_controls_show);
+UVC_ATTR_RO(uvcg_default_camera_, bm_controls, bmControls);
 
 static struct configfs_attribute *uvcg_default_camera_attrs[] = {
-       &uvcg_default_camera_b_terminal_id.attr,
-       &uvcg_default_camera_w_terminal_type.attr,
-       &uvcg_default_camera_b_assoc_terminal.attr,
-       &uvcg_default_camera_i_terminal.attr,
-       &uvcg_default_camera_w_objective_focal_length_min.attr,
-       &uvcg_default_camera_w_objective_focal_length_max.attr,
-       &uvcg_default_camera_w_ocular_focal_length.attr,
-       &uvcg_default_camera_bm_controls.attr,
+       &uvcg_default_camera_attr_b_terminal_id,
+       &uvcg_default_camera_attr_w_terminal_type,
+       &uvcg_default_camera_attr_b_assoc_terminal,
+       &uvcg_default_camera_attr_i_terminal,
+       &uvcg_default_camera_attr_w_objective_focal_length_min,
+       &uvcg_default_camera_attr_w_objective_focal_length_max,
+       &uvcg_default_camera_attr_w_ocular_focal_length,
+       &uvcg_default_camera_attr_bm_controls,
        NULL,
 };
 
 static struct config_item_type uvcg_default_camera_type = {
-       .ct_item_ops    = &uvcg_default_camera_item_ops,
        .ct_attrs       = uvcg_default_camera_attrs,
        .ct_owner       = THIS_MODULE,
 };
@@ -450,17 +420,11 @@ static inline struct uvcg_default_output
                            struct uvcg_default_output, group);
 }
 
-CONFIGFS_ATTR_STRUCT(uvcg_default_output);
-CONFIGFS_ATTR_OPS_RO(uvcg_default_output);
-
-static struct configfs_item_operations uvcg_default_output_item_ops = {
-       .show_attribute         = uvcg_default_output_attr_show,
-};
-
 #define UVCG_DEFAULT_OUTPUT_ATTR(cname, aname, conv)                   \
 static ssize_t uvcg_default_output_##cname##_show(                     \
-       struct uvcg_default_output *dout, char *page)                   \
+       struct config_item *item, char *page)                   \
 {                                                                      \
+       struct uvcg_default_output *dout = to_uvcg_default_output(item); \
        struct f_uvc_opts *opts;                                        \
        struct config_item *opts_item;                                  \
        struct mutex *su_mutex = &dout->group.cg_subsys->su_mutex;      \
@@ -483,9 +447,7 @@ static ssize_t uvcg_default_output_##cname##_show(                  \
        return result;                                                  \
 }                                                                      \
                                                                        \
-static struct uvcg_default_output_attribute                            \
-       uvcg_default_output_##cname =                                   \
-       __CONFIGFS_ATTR_RO(aname, uvcg_default_output_##cname##_show)
+UVC_ATTR_RO(uvcg_default_output_, cname, aname)
 
 #define identity_conv(x) (x)
 
@@ -500,16 +462,15 @@ UVCG_DEFAULT_OUTPUT_ATTR(i_terminal, iTerminal, identity_conv);
 #undef UVCG_DEFAULT_OUTPUT_ATTR
 
 static struct configfs_attribute *uvcg_default_output_attrs[] = {
-       &uvcg_default_output_b_terminal_id.attr,
-       &uvcg_default_output_w_terminal_type.attr,
-       &uvcg_default_output_b_assoc_terminal.attr,
-       &uvcg_default_output_b_source_id.attr,
-       &uvcg_default_output_i_terminal.attr,
+       &uvcg_default_output_attr_b_terminal_id,
+       &uvcg_default_output_attr_w_terminal_type,
+       &uvcg_default_output_attr_b_assoc_terminal,
+       &uvcg_default_output_attr_b_source_id,
+       &uvcg_default_output_attr_i_terminal,
        NULL,
 };
 
 static struct config_item_type uvcg_default_output_type = {
-       .ct_item_ops    = &uvcg_default_output_item_ops,
        .ct_attrs       = uvcg_default_output_attrs,
        .ct_owner       = THIS_MODULE,
 };
@@ -800,9 +761,6 @@ static struct uvcg_streaming_header *to_uvcg_streaming_header(struct config_item
        return container_of(item, struct uvcg_streaming_header, item);
 }
 
-CONFIGFS_ATTR_STRUCT(uvcg_streaming_header);
-CONFIGFS_ATTR_OPS(uvcg_streaming_header);
-
 static int uvcg_streaming_header_allow_link(struct config_item *src,
                                            struct config_item *target)
 {
@@ -893,16 +851,15 @@ out:
 }
 
 static struct configfs_item_operations uvcg_streaming_header_item_ops = {
-       .show_attribute         = uvcg_streaming_header_attr_show,
-       .store_attribute        = uvcg_streaming_header_attr_store,
        .allow_link             = uvcg_streaming_header_allow_link,
        .drop_link              = uvcg_streaming_header_drop_link,
 };
 
 #define UVCG_STREAMING_HEADER_ATTR(cname, aname, conv)                 \
 static ssize_t uvcg_streaming_header_##cname##_show(                   \
-       struct uvcg_streaming_header *sh, char *page)                   \
+       struct config_item *item, char *page)                   \
 {                                                                      \
+       struct uvcg_streaming_header *sh = to_uvcg_streaming_header(item); \
        struct f_uvc_opts *opts;                                        \
        struct config_item *opts_item;                                  \
        struct mutex *su_mutex = &sh->item.ci_group->cg_subsys->su_mutex;\
@@ -921,9 +878,7 @@ static ssize_t uvcg_streaming_header_##cname##_show(                        \
        return result;                                                  \
 }                                                                      \
                                                                        \
-static struct uvcg_streaming_header_attribute                          \
-       uvcg_streaming_header_##cname =                                 \
-       __CONFIGFS_ATTR_RO(aname, uvcg_streaming_header_##cname##_show)
+UVC_ATTR_RO(uvcg_streaming_header_, cname, aname)
 
 #define identity_conv(x) (x)
 
@@ -939,11 +894,11 @@ UVCG_STREAMING_HEADER_ATTR(b_trigger_usage, bTriggerUsage, identity_conv);
 #undef UVCG_STREAMING_HEADER_ATTR
 
 static struct configfs_attribute *uvcg_streaming_header_attrs[] = {
-       &uvcg_streaming_header_bm_info.attr,
-       &uvcg_streaming_header_b_terminal_link.attr,
-       &uvcg_streaming_header_b_still_capture_method.attr,
-       &uvcg_streaming_header_b_trigger_support.attr,
-       &uvcg_streaming_header_b_trigger_usage.attr,
+       &uvcg_streaming_header_attr_bm_info,
+       &uvcg_streaming_header_attr_b_terminal_link,
+       &uvcg_streaming_header_attr_b_still_capture_method,
+       &uvcg_streaming_header_attr_b_trigger_support,
+       &uvcg_streaming_header_attr_b_trigger_usage,
        NULL,
 };
 
@@ -1022,17 +977,10 @@ static struct uvcg_frame *to_uvcg_frame(struct config_item *item)
        return container_of(item, struct uvcg_frame, item);
 }
 
-CONFIGFS_ATTR_STRUCT(uvcg_frame);
-CONFIGFS_ATTR_OPS(uvcg_frame);
-
-static struct configfs_item_operations uvcg_frame_item_ops = {
-       .show_attribute         = uvcg_frame_attr_show,
-       .store_attribute        = uvcg_frame_attr_store,
-};
-
 #define UVCG_FRAME_ATTR(cname, aname, to_cpu_endian, to_little_endian, bits) \
-static ssize_t uvcg_frame_##cname##_show(struct uvcg_frame *f, char *page)\
+static ssize_t uvcg_frame_##cname##_show(struct config_item *item, char *page)\
 {                                                                      \
+       struct uvcg_frame *f = to_uvcg_frame(item);                     \
        struct f_uvc_opts *opts;                                        \
        struct config_item *opts_item;                                  \
        struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\
@@ -1051,9 +999,10 @@ static ssize_t uvcg_frame_##cname##_show(struct uvcg_frame *f, char *page)\
        return result;                                                  \
 }                                                                      \
                                                                        \
-static ssize_t  uvcg_frame_##cname##_store(struct uvcg_frame *f,       \
+static ssize_t  uvcg_frame_##cname##_store(struct config_item *item,   \
                                           const char *page, size_t len)\
 {                                                                      \
+       struct uvcg_frame *f = to_uvcg_frame(item);                     \
        struct f_uvc_opts *opts;                                        \
        struct config_item *opts_item;                                  \
        struct uvcg_format *fmt;                                        \
@@ -1085,11 +1034,7 @@ end:                                                                     \
        return ret;                                                     \
 }                                                                      \
                                                                        \
-static struct uvcg_frame_attribute                                     \
-       uvcg_frame_##cname =                                            \
-       __CONFIGFS_ATTR(aname, S_IRUGO | S_IWUSR,                       \
-                       uvcg_frame_##cname##_show,                      \
-                       uvcg_frame_##cname##_store)
+UVC_ATTR(uvcg_frame_, cname, aname);
 
 #define noop_conversion(x) (x)
 
@@ -1108,9 +1053,10 @@ UVCG_FRAME_ATTR(dw_default_frame_interval, dwDefaultFrameInterval,
 
 #undef UVCG_FRAME_ATTR
 
-static ssize_t uvcg_frame_dw_frame_interval_show(struct uvcg_frame *frm,
+static ssize_t uvcg_frame_dw_frame_interval_show(struct config_item *item,
                                                 char *page)
 {
+       struct uvcg_frame *frm = to_uvcg_frame(item);
        struct f_uvc_opts *opts;
        struct config_item *opts_item;
        struct mutex *su_mutex = &frm->item.ci_group->cg_subsys->su_mutex;
@@ -1185,9 +1131,10 @@ static int __uvcg_iter_frm_intrv(const char *page, size_t len,
        return 0;
 }
 
-static ssize_t uvcg_frame_dw_frame_interval_store(struct uvcg_frame *ch,
+static ssize_t uvcg_frame_dw_frame_interval_store(struct config_item *item,
                                                  const char *page, size_t len)
 {
+       struct uvcg_frame *ch = to_uvcg_frame(item);
        struct f_uvc_opts *opts;
        struct config_item *opts_item;
        struct uvcg_format *fmt;
@@ -1234,26 +1181,21 @@ end:
        return ret;
 }
 
-static struct uvcg_frame_attribute
-       uvcg_frame_dw_frame_interval =
-       __CONFIGFS_ATTR(dwFrameInterval, S_IRUGO | S_IWUSR,
-                       uvcg_frame_dw_frame_interval_show,
-                       uvcg_frame_dw_frame_interval_store);
+UVC_ATTR(uvcg_frame_, dw_frame_interval, dwFrameInterval);
 
 static struct configfs_attribute *uvcg_frame_attrs[] = {
-       &uvcg_frame_bm_capabilities.attr,
-       &uvcg_frame_w_width.attr,
-       &uvcg_frame_w_height.attr,
-       &uvcg_frame_dw_min_bit_rate.attr,
-       &uvcg_frame_dw_max_bit_rate.attr,
-       &uvcg_frame_dw_max_video_frame_buffer_size.attr,
-       &uvcg_frame_dw_default_frame_interval.attr,
-       &uvcg_frame_dw_frame_interval.attr,
+       &uvcg_frame_attr_bm_capabilities,
+       &uvcg_frame_attr_w_width,
+       &uvcg_frame_attr_w_height,
+       &uvcg_frame_attr_dw_min_bit_rate,
+       &uvcg_frame_attr_dw_max_bit_rate,
+       &uvcg_frame_attr_dw_max_video_frame_buffer_size,
+       &uvcg_frame_attr_dw_default_frame_interval,
+       &uvcg_frame_attr_dw_frame_interval,
        NULL,
 };
 
 static struct config_item_type uvcg_frame_type = {
-       .ct_item_ops    = &uvcg_frame_item_ops,
        .ct_attrs       = uvcg_frame_attrs,
        .ct_owner       = THIS_MODULE,
 };
@@ -1333,22 +1275,15 @@ static struct uvcg_uncompressed *to_uvcg_uncompressed(struct config_item *item)
                struct uvcg_uncompressed, fmt);
 }
 
-CONFIGFS_ATTR_STRUCT(uvcg_uncompressed);
-CONFIGFS_ATTR_OPS(uvcg_uncompressed);
-
-static struct configfs_item_operations uvcg_uncompressed_item_ops = {
-       .show_attribute         = uvcg_uncompressed_attr_show,
-       .store_attribute        = uvcg_uncompressed_attr_store,
-};
-
 static struct configfs_group_operations uvcg_uncompressed_group_ops = {
        .make_item              = uvcg_frame_make,
        .drop_item              = uvcg_frame_drop,
 };
 
-static ssize_t uvcg_uncompressed_guid_format_show(struct uvcg_uncompressed *ch,
+static ssize_t uvcg_uncompressed_guid_format_show(struct config_item *item,
                                                        char *page)
 {
+       struct uvcg_uncompressed *ch = to_uvcg_uncompressed(item);
        struct f_uvc_opts *opts;
        struct config_item *opts_item;
        struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex;
@@ -1367,9 +1302,10 @@ static ssize_t uvcg_uncompressed_guid_format_show(struct uvcg_uncompressed *ch,
        return sizeof(ch->desc.guidFormat);
 }
 
-static ssize_t uvcg_uncompressed_guid_format_store(struct uvcg_uncompressed *ch,
+static ssize_t uvcg_uncompressed_guid_format_store(struct config_item *item,
                                                   const char *page, size_t len)
 {
+       struct uvcg_uncompressed *ch = to_uvcg_uncompressed(item);
        struct f_uvc_opts *opts;
        struct config_item *opts_item;
        struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex;
@@ -1396,16 +1332,13 @@ end:
        return ret;
 }
 
-static struct uvcg_uncompressed_attribute uvcg_uncompressed_guid_format =
-       __CONFIGFS_ATTR(guidFormat, S_IRUGO | S_IWUSR,
-                       uvcg_uncompressed_guid_format_show,
-                       uvcg_uncompressed_guid_format_store);
-
+UVC_ATTR(uvcg_uncompressed_, guid_format, guidFormat);
 
 #define UVCG_UNCOMPRESSED_ATTR_RO(cname, aname, conv)                  \
 static ssize_t uvcg_uncompressed_##cname##_show(                       \
-       struct uvcg_uncompressed *u, char *page)                        \
+       struct config_item *item, char *page)                           \
 {                                                                      \
+       struct uvcg_uncompressed *u = to_uvcg_uncompressed(item);       \
        struct f_uvc_opts *opts;                                        \
        struct config_item *opts_item;                                  \
        struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;     \
@@ -1424,14 +1357,13 @@ static ssize_t uvcg_uncompressed_##cname##_show(                        \
        return result;                                                  \
 }                                                                      \
                                                                        \
-static struct uvcg_uncompressed_attribute                              \
-       uvcg_uncompressed_##cname =                                     \
-       __CONFIGFS_ATTR_RO(aname, uvcg_uncompressed_##cname##_show)
+UVC_ATTR_RO(uvcg_uncompressed_, cname, aname);
 
 #define UVCG_UNCOMPRESSED_ATTR(cname, aname, conv)                     \
 static ssize_t uvcg_uncompressed_##cname##_show(                       \
-       struct uvcg_uncompressed *u, char *page)                        \
+       struct config_item *item, char *page)                           \
 {                                                                      \
+       struct uvcg_uncompressed *u = to_uvcg_uncompressed(item);       \
        struct f_uvc_opts *opts;                                        \
        struct config_item *opts_item;                                  \
        struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;     \
@@ -1451,9 +1383,10 @@ static ssize_t uvcg_uncompressed_##cname##_show(                 \
 }                                                                      \
                                                                        \
 static ssize_t                                                         \
-uvcg_uncompressed_##cname##_store(struct uvcg_uncompressed *u,         \
+uvcg_uncompressed_##cname##_store(struct config_item *item,            \
                                    const char *page, size_t len)       \
 {                                                                      \
+       struct uvcg_uncompressed *u = to_uvcg_uncompressed(item);       \
        struct f_uvc_opts *opts;                                        \
        struct config_item *opts_item;                                  \
        struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;     \
@@ -1487,11 +1420,7 @@ end:                                                                     \
        return ret;                                                     \
 }                                                                      \
                                                                        \
-static struct uvcg_uncompressed_attribute                              \
-       uvcg_uncompressed_##cname =                                     \
-       __CONFIGFS_ATTR(aname, S_IRUGO | S_IWUSR,                       \
-                       uvcg_uncompressed_##cname##_show,               \
-                       uvcg_uncompressed_##cname##_store)
+UVC_ATTR(uvcg_uncompressed_, cname, aname);
 
 #define identity_conv(x) (x)
 
@@ -1508,36 +1437,34 @@ UVCG_UNCOMPRESSED_ATTR_RO(bm_interface_flags, bmInterfaceFlags, identity_conv);
 #undef UVCG_UNCOMPRESSED_ATTR_RO
 
 static inline ssize_t
-uvcg_uncompressed_bma_controls_show(struct uvcg_uncompressed *unc, char *page)
+uvcg_uncompressed_bma_controls_show(struct config_item *item, char *page)
 {
+       struct uvcg_uncompressed *unc = to_uvcg_uncompressed(item);
        return uvcg_format_bma_controls_show(&unc->fmt, page);
 }
 
 static inline ssize_t
-uvcg_uncompressed_bma_controls_store(struct uvcg_uncompressed *ch,
+uvcg_uncompressed_bma_controls_store(struct config_item *item,
                                     const char *page, size_t len)
 {
-       return uvcg_format_bma_controls_store(&ch->fmt, page, len);
+       struct uvcg_uncompressed *unc = to_uvcg_uncompressed(item);
+       return uvcg_format_bma_controls_store(&unc->fmt, page, len);
 }
 
-static struct uvcg_uncompressed_attribute uvcg_uncompressed_bma_controls =
-       __CONFIGFS_ATTR(bmaControls, S_IRUGO | S_IWUSR,
-                       uvcg_uncompressed_bma_controls_show,
-                       uvcg_uncompressed_bma_controls_store);
+UVC_ATTR(uvcg_uncompressed_, bma_controls, bmaControls);
 
 static struct configfs_attribute *uvcg_uncompressed_attrs[] = {
-       &uvcg_uncompressed_guid_format.attr,
-       &uvcg_uncompressed_b_bits_per_pixel.attr,
-       &uvcg_uncompressed_b_default_frame_index.attr,
-       &uvcg_uncompressed_b_aspect_ratio_x.attr,
-       &uvcg_uncompressed_b_aspect_ratio_y.attr,
-       &uvcg_uncompressed_bm_interface_flags.attr,
-       &uvcg_uncompressed_bma_controls.attr,
+       &uvcg_uncompressed_attr_guid_format,
+       &uvcg_uncompressed_attr_b_bits_per_pixel,
+       &uvcg_uncompressed_attr_b_default_frame_index,
+       &uvcg_uncompressed_attr_b_aspect_ratio_x,
+       &uvcg_uncompressed_attr_b_aspect_ratio_y,
+       &uvcg_uncompressed_attr_bm_interface_flags,
+       &uvcg_uncompressed_attr_bma_controls,
        NULL,
 };
 
 static struct config_item_type uvcg_uncompressed_type = {
-       .ct_item_ops    = &uvcg_uncompressed_item_ops,
        .ct_group_ops   = &uvcg_uncompressed_group_ops,
        .ct_attrs       = uvcg_uncompressed_attrs,
        .ct_owner       = THIS_MODULE,
@@ -1605,22 +1532,15 @@ static struct uvcg_mjpeg *to_uvcg_mjpeg(struct config_item *item)
                struct uvcg_mjpeg, fmt);
 }
 
-CONFIGFS_ATTR_STRUCT(uvcg_mjpeg);
-CONFIGFS_ATTR_OPS(uvcg_mjpeg);
-
-static struct configfs_item_operations uvcg_mjpeg_item_ops = {
-       .show_attribute         = uvcg_mjpeg_attr_show,
-       .store_attribute        = uvcg_mjpeg_attr_store,
-};
-
 static struct configfs_group_operations uvcg_mjpeg_group_ops = {
        .make_item              = uvcg_frame_make,
        .drop_item              = uvcg_frame_drop,
 };
 
 #define UVCG_MJPEG_ATTR_RO(cname, aname, conv)                         \
-static ssize_t uvcg_mjpeg_##cname##_show(struct uvcg_mjpeg *u, char *page)\
+static ssize_t uvcg_mjpeg_##cname##_show(struct config_item *item, char *page)\
 {                                                                      \
+       struct uvcg_mjpeg *u = to_uvcg_mjpeg(item);                     \
        struct f_uvc_opts *opts;                                        \
        struct config_item *opts_item;                                  \
        struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;     \
@@ -1639,13 +1559,12 @@ static ssize_t uvcg_mjpeg_##cname##_show(struct uvcg_mjpeg *u, char *page)\
        return result;                                                  \
 }                                                                      \
                                                                        \
-static struct uvcg_mjpeg_attribute                                     \
-       uvcg_mjpeg_##cname =                                            \
-       __CONFIGFS_ATTR_RO(aname, uvcg_mjpeg_##cname##_show)
+UVC_ATTR_RO(uvcg_mjpeg_, cname, aname)
 
 #define UVCG_MJPEG_ATTR(cname, aname, conv)                            \
-static ssize_t uvcg_mjpeg_##cname##_show(struct uvcg_mjpeg *u, char *page)\
+static ssize_t uvcg_mjpeg_##cname##_show(struct config_item *item, char *page)\
 {                                                                      \
+       struct uvcg_mjpeg *u = to_uvcg_mjpeg(item);                     \
        struct f_uvc_opts *opts;                                        \
        struct config_item *opts_item;                                  \
        struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;     \
@@ -1665,9 +1584,10 @@ static ssize_t uvcg_mjpeg_##cname##_show(struct uvcg_mjpeg *u, char *page)\
 }                                                                      \
                                                                        \
 static ssize_t                                                         \
-uvcg_mjpeg_##cname##_store(struct uvcg_mjpeg *u,                       \
+uvcg_mjpeg_##cname##_store(struct config_item *item,                   \
                           const char *page, size_t len)                \
 {                                                                      \
+       struct uvcg_mjpeg *u = to_uvcg_mjpeg(item);                     \
        struct f_uvc_opts *opts;                                        \
        struct config_item *opts_item;                                  \
        struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;     \
@@ -1701,11 +1621,7 @@ end:                                                                     \
        return ret;                                                     \
 }                                                                      \
                                                                        \
-static struct uvcg_mjpeg_attribute                                     \
-       uvcg_mjpeg_##cname =                                            \
-       __CONFIGFS_ATTR(aname, S_IRUGO | S_IWUSR,                       \
-                       uvcg_mjpeg_##cname##_show,                      \
-                       uvcg_mjpeg_##cname##_store)
+UVC_ATTR(uvcg_mjpeg_, cname, aname)
 
 #define identity_conv(x) (x)
 
@@ -1722,35 +1638,33 @@ UVCG_MJPEG_ATTR_RO(bm_interface_flags, bmInterfaceFlags, identity_conv);
 #undef UVCG_MJPEG_ATTR_RO
 
 static inline ssize_t
-uvcg_mjpeg_bma_controls_show(struct uvcg_mjpeg *unc, char *page)
+uvcg_mjpeg_bma_controls_show(struct config_item *item, char *page)
 {
-       return uvcg_format_bma_controls_show(&unc->fmt, page);
+       struct uvcg_mjpeg *u = to_uvcg_mjpeg(item);
+       return uvcg_format_bma_controls_show(&u->fmt, page);
 }
 
 static inline ssize_t
-uvcg_mjpeg_bma_controls_store(struct uvcg_mjpeg *ch,
+uvcg_mjpeg_bma_controls_store(struct config_item *item,
                                     const char *page, size_t len)
 {
-       return uvcg_format_bma_controls_store(&ch->fmt, page, len);
+       struct uvcg_mjpeg *u = to_uvcg_mjpeg(item);
+       return uvcg_format_bma_controls_store(&u->fmt, page, len);
 }
 
-static struct uvcg_mjpeg_attribute uvcg_mjpeg_bma_controls =
-       __CONFIGFS_ATTR(bmaControls, S_IRUGO | S_IWUSR,
-                       uvcg_mjpeg_bma_controls_show,
-                       uvcg_mjpeg_bma_controls_store);
+UVC_ATTR(uvcg_mjpeg_, bma_controls, bmaControls);
 
 static struct configfs_attribute *uvcg_mjpeg_attrs[] = {
-       &uvcg_mjpeg_b_default_frame_index.attr,
-       &uvcg_mjpeg_bm_flags.attr,
-       &uvcg_mjpeg_b_aspect_ratio_x.attr,
-       &uvcg_mjpeg_b_aspect_ratio_y.attr,
-       &uvcg_mjpeg_bm_interface_flags.attr,
-       &uvcg_mjpeg_bma_controls.attr,
+       &uvcg_mjpeg_attr_b_default_frame_index,
+       &uvcg_mjpeg_attr_bm_flags,
+       &uvcg_mjpeg_attr_b_aspect_ratio_x,
+       &uvcg_mjpeg_attr_b_aspect_ratio_y,
+       &uvcg_mjpeg_attr_bm_interface_flags,
+       &uvcg_mjpeg_attr_bma_controls,
        NULL,
 };
 
 static struct config_item_type uvcg_mjpeg_type = {
-       .ct_item_ops    = &uvcg_mjpeg_item_ops,
        .ct_group_ops   = &uvcg_mjpeg_group_ops,
        .ct_attrs       = uvcg_mjpeg_attrs,
        .ct_owner       = THIS_MODULE,
@@ -1811,17 +1725,12 @@ static inline struct uvcg_default_color_matching
                            struct uvcg_default_color_matching, group);
 }
 
-CONFIGFS_ATTR_STRUCT(uvcg_default_color_matching);
-CONFIGFS_ATTR_OPS_RO(uvcg_default_color_matching);
-
-static struct configfs_item_operations uvcg_default_color_matching_item_ops = {
-       .show_attribute         = uvcg_default_color_matching_attr_show,
-};
-
 #define UVCG_DEFAULT_COLOR_MATCHING_ATTR(cname, aname, conv)           \
 static ssize_t uvcg_default_color_matching_##cname##_show(             \
-       struct uvcg_default_color_matching *dc, char *page)             \
+       struct config_item *item, char *page)           \
 {                                                                      \
+       struct uvcg_default_color_matching *dc =                        \
+               to_uvcg_default_color_matching(item);                   \
        struct f_uvc_opts *opts;                                        \
        struct config_item *opts_item;                                  \
        struct mutex *su_mutex = &dc->group.cg_subsys->su_mutex;        \
@@ -1842,9 +1751,7 @@ static ssize_t uvcg_default_color_matching_##cname##_show(                \
        return result;                                                  \
 }                                                                      \
                                                                        \
-static struct uvcg_default_color_matching_attribute                    \
-       uvcg_default_color_matching_##cname =                           \
-       __CONFIGFS_ATTR_RO(aname, uvcg_default_color_matching_##cname##_show)
+UVC_ATTR_RO(uvcg_default_color_matching_, cname, aname)
 
 #define identity_conv(x) (x)
 
@@ -1860,14 +1767,13 @@ UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_matrix_coefficients, bMatrixCoefficients,
 #undef UVCG_DEFAULT_COLOR_MATCHING_ATTR
 
 static struct configfs_attribute *uvcg_default_color_matching_attrs[] = {
-       &uvcg_default_color_matching_b_color_primaries.attr,
-       &uvcg_default_color_matching_b_transfer_characteristics.attr,
-       &uvcg_default_color_matching_b_matrix_coefficients.attr,
+       &uvcg_default_color_matching_attr_b_color_primaries,
+       &uvcg_default_color_matching_attr_b_transfer_characteristics,
+       &uvcg_default_color_matching_attr_b_matrix_coefficients,
        NULL,
 };
 
 static struct config_item_type uvcg_default_color_matching_type = {
-       .ct_item_ops    = &uvcg_default_color_matching_item_ops,
        .ct_attrs       = uvcg_default_color_matching_attrs,
        .ct_owner       = THIS_MODULE,
 };
@@ -2285,9 +2191,6 @@ static inline struct f_uvc_opts *to_f_uvc_opts(struct config_item *item)
                            func_inst.group);
 }
 
-CONFIGFS_ATTR_STRUCT(f_uvc_opts);
-CONFIGFS_ATTR_OPS(f_uvc_opts);
-
 static void uvc_attr_release(struct config_item *item)
 {
        struct f_uvc_opts *opts = to_f_uvc_opts(item);
@@ -2297,14 +2200,13 @@ static void uvc_attr_release(struct config_item *item)
 
 static struct configfs_item_operations uvc_item_ops = {
        .release                = uvc_attr_release,
-       .show_attribute         = f_uvc_opts_attr_show,
-       .store_attribute        = f_uvc_opts_attr_store,
 };
 
 #define UVCG_OPTS_ATTR(cname, conv, str2u, uxx, vnoc, limit)           \
 static ssize_t f_uvc_opts_##cname##_show(                              \
-       struct f_uvc_opts *opts, char *page)                            \
+       struct config_item *item, char *page)                           \
 {                                                                      \
+       struct f_uvc_opts *opts = to_f_uvc_opts(item);                  \
        int result;                                                     \
                                                                        \
        mutex_lock(&opts->lock);                                        \
@@ -2315,9 +2217,10 @@ static ssize_t f_uvc_opts_##cname##_show(                                \
 }                                                                      \
                                                                        \
 static ssize_t                                                         \
-f_uvc_opts_##cname##_store(struct f_uvc_opts *opts,                    \
+f_uvc_opts_##cname##_store(struct config_item *item,                   \
                           const char *page, size_t len)                \
 {                                                                      \
+       struct f_uvc_opts *opts = to_f_uvc_opts(item);                  \
        int ret;                                                        \
        uxx num;                                                        \
                                                                        \
@@ -2342,11 +2245,7 @@ end:                                                                     \
        return ret;                                                     \
 }                                                                      \
                                                                        \
-static struct f_uvc_opts_attribute                                     \
-       f_uvc_opts_attribute_##cname =                                  \
-       __CONFIGFS_ATTR(cname, S_IRUGO | S_IWUSR,                       \
-                       f_uvc_opts_##cname##_show,                      \
-                       f_uvc_opts_##cname##_store)
+UVC_ATTR(f_uvc_opts_, cname, aname)
 
 #define identity_conv(x) (x)
 
@@ -2362,9 +2261,9 @@ UVCG_OPTS_ATTR(streaming_maxburst, identity_conv, kstrtou8, u8, identity_conv,
 #undef UVCG_OPTS_ATTR
 
 static struct configfs_attribute *uvc_attrs[] = {
-       &f_uvc_opts_attribute_streaming_interval.attr,
-       &f_uvc_opts_attribute_streaming_maxpacket.attr,
-       &f_uvc_opts_attribute_streaming_maxburst.attr,
+       &f_uvc_opts_attr_streaming_interval,
+       &f_uvc_opts_attr_streaming_maxpacket,
+       &f_uvc_opts_attr_streaming_maxburst,
        NULL,
 };
 
index 778e42abb3cb8703fcf19b829e21f764ac798d1e..22e56158d5850236242375d036f70250b676dac7 100644 (file)
@@ -19,8 +19,6 @@
 #include <scsi/scsi_tcq.h>
 #include <target/target_core_base.h>
 #include <target/target_core_fabric.h>
-#include <target/target_core_fabric_configfs.h>
-#include <target/configfs_macros.h>
 #include <asm/unaligned.h>
 
 #include "tcm_usb_gadget.h"
@@ -1467,23 +1465,21 @@ static void usbg_drop_tport(struct se_wwn *wwn)
 /*
  * If somebody feels like dropping the version property, go ahead.
  */
-static ssize_t usbg_wwn_show_attr_version(
-       struct target_fabric_configfs *tf,
-       char *page)
+static ssize_t usbg_wwn_version_show(struct config_item *item, char *page)
 {
        return sprintf(page, "usb-gadget fabric module\n");
 }
-TF_WWN_ATTR_RO(usbg, version);
+
+CONFIGFS_ATTR_RO(usbg_wwn_, version);
 
 static struct configfs_attribute *usbg_wwn_attrs[] = {
-       &usbg_wwn_version.attr,
+       &usbg_wwn_attr_version,
        NULL,
 };
 
-static ssize_t tcm_usbg_tpg_show_enable(
-               struct se_portal_group *se_tpg,
-               char *page)
+static ssize_t tcm_usbg_tpg_enable_show(struct config_item *item, char *page)
 {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct usbg_tpg  *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg);
 
        return snprintf(page, PAGE_SIZE, "%u\n", tpg->gadget_connect);
@@ -1492,11 +1488,10 @@ static ssize_t tcm_usbg_tpg_show_enable(
 static int usbg_attach(struct usbg_tpg *);
 static void usbg_detach(struct usbg_tpg *);
 
-static ssize_t tcm_usbg_tpg_store_enable(
-               struct se_portal_group *se_tpg,
-               const char *page,
-               size_t count)
+static ssize_t tcm_usbg_tpg_enable_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct usbg_tpg  *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg);
        unsigned long op;
        ssize_t ret;
@@ -1523,12 +1518,10 @@ static ssize_t tcm_usbg_tpg_store_enable(
 out:
        return count;
 }
-TF_TPG_BASE_ATTR(tcm_usbg, enable, S_IRUGO | S_IWUSR);
 
-static ssize_t tcm_usbg_tpg_show_nexus(
-               struct se_portal_group *se_tpg,
-               char *page)
+static ssize_t tcm_usbg_tpg_nexus_show(struct config_item *item, char *page)
 {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct usbg_tpg *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg);
        struct tcm_usbg_nexus *tv_nexus;
        ssize_t ret;
@@ -1636,11 +1629,10 @@ out:
        return ret;
 }
 
-static ssize_t tcm_usbg_tpg_store_nexus(
-               struct se_portal_group *se_tpg,
-               const char *page,
-               size_t count)
+static ssize_t tcm_usbg_tpg_nexus_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct usbg_tpg *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg);
        unsigned char i_port[USBG_NAMELEN], *ptr;
        int ret;
@@ -1670,11 +1662,13 @@ static ssize_t tcm_usbg_tpg_store_nexus(
                return ret;
        return count;
 }
-TF_TPG_BASE_ATTR(tcm_usbg, nexus, S_IRUGO | S_IWUSR);
+
+CONFIGFS_ATTR(tcm_usbg_tpg_, enable);
+CONFIGFS_ATTR(tcm_usbg_tpg_, nexus);
 
 static struct configfs_attribute *usbg_base_attrs[] = {
-       &tcm_usbg_tpg_enable.attr,
-       &tcm_usbg_tpg_nexus.attr,
+       &tcm_usbg_tpg_attr_enable,
+       &tcm_usbg_tpg_attr_nexus,
        NULL,
 };
 
index 48ca9c204354168f079a1e9e5ceaf2ac4b74a0f5..e6915166443607283f8229eaca83fac38ed68377 100644 (file)
@@ -812,7 +812,6 @@ static struct scsi_host_template uas_host_template = {
        .this_id = -1,
        .sg_tablesize = SG_NONE,
        .skip_settle_delay = 1,
-       .use_blk_tags = 1,
 };
 
 #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
@@ -929,10 +928,6 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id)
        if (result)
                goto set_alt0;
 
-       result = scsi_init_shared_tag_map(shost, devinfo->qdepth - 2);
-       if (result)
-               goto free_streams;
-
        usb_set_intfdata(intf, shost);
        result = scsi_add_host(shost, &intf->dev);
        if (result)
index 850d86ca685b273344271eda7c95ad4f82b28244..da6e2ce77495b21ec127209664567b7e2f8f467e 100644 (file)
@@ -31,6 +31,21 @@ 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 964ad572aaeede1fc7d2522a9fdb69b7d66f3faa..32b88bd2c82c7e3a3f4cd8cae11a253a171c76fa 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 = iommu_group_get(&pdev->dev);
+       group = vfio_iommu_group_get(&pdev->dev);
        if (!group)
                return -EINVAL;
 
        vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
        if (!vdev) {
-               iommu_group_put(group);
+               vfio_iommu_group_put(group, &pdev->dev);
                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) {
-               iommu_group_put(group);
+               vfio_iommu_group_put(group, &pdev->dev);
                kfree(vdev);
                return ret;
        }
@@ -993,7 +993,7 @@ static void vfio_pci_remove(struct pci_dev *pdev)
        if (!vdev)
                return;
 
-       iommu_group_put(pdev->dev.iommu_group);
+       vfio_iommu_group_put(pdev->dev.iommu_group, &pdev->dev);
        kfree(vdev);
 
        if (vfio_pci_is_vga(pdev)) {
index ff75ca31a199d1a2c468b71bf0d9b4566f1894b7..fe2b470d7ec6b33c8fd75ffbfccb1168a6975ca2 100644 (file)
@@ -46,7 +46,7 @@
  *   0: Removed from the user visible capability list
  *   FF: Variable length
  */
-static u8 pci_cap_length[] = {
+static const u8 pci_cap_length[PCI_CAP_ID_MAX + 1] = {
        [PCI_CAP_ID_BASIC]      = PCI_STD_HEADER_SIZEOF, /* pci config header */
        [PCI_CAP_ID_PM]         = PCI_PM_SIZEOF,
        [PCI_CAP_ID_AGP]        = PCI_AGP_SIZEOF,
@@ -74,7 +74,7 @@ static u8 pci_cap_length[] = {
  *   0: Removed or masked from the user visible capabilty list
  *   FF: Variable length
  */
-static u16 pci_ext_cap_length[] = {
+static const u16 pci_ext_cap_length[PCI_EXT_CAP_ID_MAX + 1] = {
        [PCI_EXT_CAP_ID_ERR]    =       PCI_ERR_ROOT_COMMAND,
        [PCI_EXT_CAP_ID_VC]     =       0xFF,
        [PCI_EXT_CAP_ID_DSN]    =       PCI_EXT_CAP_DSN_SIZEOF,
@@ -671,6 +671,73 @@ static int __init init_pci_cap_pm_perm(struct perm_bits *perm)
        return 0;
 }
 
+static int vfio_vpd_config_write(struct vfio_pci_device *vdev, int pos,
+                                int count, struct perm_bits *perm,
+                                int offset, __le32 val)
+{
+       struct pci_dev *pdev = vdev->pdev;
+       __le16 *paddr = (__le16 *)(vdev->vconfig + pos - offset + PCI_VPD_ADDR);
+       __le32 *pdata = (__le32 *)(vdev->vconfig + pos - offset + PCI_VPD_DATA);
+       u16 addr;
+       u32 data;
+
+       /*
+        * Write through to emulation.  If the write includes the upper byte
+        * of PCI_VPD_ADDR, then the PCI_VPD_ADDR_F bit is written and we
+        * have work to do.
+        */
+       count = vfio_default_config_write(vdev, pos, count, perm, offset, val);
+       if (count < 0 || offset > PCI_VPD_ADDR + 1 ||
+           offset + count <= PCI_VPD_ADDR + 1)
+               return count;
+
+       addr = le16_to_cpu(*paddr);
+
+       if (addr & PCI_VPD_ADDR_F) {
+               data = le32_to_cpu(*pdata);
+               if (pci_write_vpd(pdev, addr & ~PCI_VPD_ADDR_F, 4, &data) != 4)
+                       return count;
+       } else {
+               if (pci_read_vpd(pdev, addr, 4, &data) != 4)
+                       return count;
+               *pdata = cpu_to_le32(data);
+       }
+
+       /*
+        * Toggle PCI_VPD_ADDR_F in the emulated PCI_VPD_ADDR register to
+        * signal completion.  If an error occurs above, we assume that not
+        * toggling this bit will induce a driver timeout.
+        */
+       addr ^= PCI_VPD_ADDR_F;
+       *paddr = cpu_to_le16(addr);
+
+       return count;
+}
+
+/* Permissions for Vital Product Data capability */
+static int __init init_pci_cap_vpd_perm(struct perm_bits *perm)
+{
+       if (alloc_perm_bits(perm, pci_cap_length[PCI_CAP_ID_VPD]))
+               return -ENOMEM;
+
+       perm->writefn = vfio_vpd_config_write;
+
+       /*
+        * We always virtualize the next field so we can remove
+        * capabilities from the chain if we want to.
+        */
+       p_setb(perm, PCI_CAP_LIST_NEXT, (u8)ALL_VIRT, NO_WRITE);
+
+       /*
+        * Both the address and data registers are virtualized to
+        * enable access through the pci_vpd_read/write functions
+        */
+       p_setw(perm, PCI_VPD_ADDR, (u16)ALL_VIRT, (u16)ALL_WRITE);
+       p_setd(perm, PCI_VPD_DATA, ALL_VIRT, ALL_WRITE);
+
+       return 0;
+}
+
 /* Permissions for PCI-X capability */
 static int __init init_pci_cap_pcix_perm(struct perm_bits *perm)
 {
@@ -790,6 +857,7 @@ void vfio_pci_uninit_perm_bits(void)
        free_perm_bits(&cap_perms[PCI_CAP_ID_BASIC]);
 
        free_perm_bits(&cap_perms[PCI_CAP_ID_PM]);
+       free_perm_bits(&cap_perms[PCI_CAP_ID_VPD]);
        free_perm_bits(&cap_perms[PCI_CAP_ID_PCIX]);
        free_perm_bits(&cap_perms[PCI_CAP_ID_EXP]);
        free_perm_bits(&cap_perms[PCI_CAP_ID_AF]);
@@ -807,7 +875,7 @@ int __init vfio_pci_init_perm_bits(void)
 
        /* Capabilities */
        ret |= init_pci_cap_pm_perm(&cap_perms[PCI_CAP_ID_PM]);
-       cap_perms[PCI_CAP_ID_VPD].writefn = vfio_raw_config_write;
+       ret |= init_pci_cap_vpd_perm(&cap_perms[PCI_CAP_ID_VPD]);
        ret |= init_pci_cap_pcix_perm(&cap_perms[PCI_CAP_ID_PCIX]);
        cap_perms[PCI_CAP_ID_VNDR].writefn = vfio_raw_config_write;
        ret |= init_pci_cap_exp_perm(&cap_perms[PCI_CAP_ID_EXP]);
index 9ce8afe2845041cbd064113bba85309678e37d7a..41a6224f5e6b6ab1b962605ac4e9aede6cac66f7 100644 (file)
@@ -1,10 +1,12 @@
-
-vfio-platform-y := vfio_platform.o vfio_platform_common.o vfio_platform_irq.o
+vfio-platform-base-y := vfio_platform_common.o vfio_platform_irq.o
+vfio-platform-y := vfio_platform.o
 
 obj-$(CONFIG_VFIO_PLATFORM) += vfio-platform.o
+obj-$(CONFIG_VFIO_PLATFORM) += vfio-platform-base.o
 obj-$(CONFIG_VFIO_PLATFORM) += reset/
 
 vfio-amba-y := vfio_amba.o
 
 obj-$(CONFIG_VFIO_AMBA) += vfio-amba.o
+obj-$(CONFIG_VFIO_AMBA) += vfio-platform-base.o
 obj-$(CONFIG_VFIO_AMBA) += reset/
index 746b96b0003be87f06af9037bafcf93c303c50aa..70cccc582bee6ec86047e38b473dc1be8acc10ff 100644 (file)
@@ -5,3 +5,11 @@ config VFIO_PLATFORM_CALXEDAXGMAC_RESET
          Enables the VFIO platform driver to handle reset for Calxeda xgmac
 
          If you don't know what to do here, say N.
+
+config VFIO_PLATFORM_AMDXGBE_RESET
+       tristate "VFIO support for AMD XGBE reset"
+       depends on VFIO_PLATFORM
+       help
+         Enables the VFIO platform driver to handle reset for AMD XGBE
+
+         If you don't know what to do here, say N.
index 2a486af9f8fa5da0a78f3ee000f8740553b2958a..93f4e232697bd62a9761fae12ad479e29eee88be 100644 (file)
@@ -1,5 +1,7 @@
 vfio-platform-calxedaxgmac-y := vfio_platform_calxedaxgmac.o
+vfio-platform-amdxgbe-y := vfio_platform_amdxgbe.o
 
 ccflags-y += -Idrivers/vfio/platform
 
 obj-$(CONFIG_VFIO_PLATFORM_CALXEDAXGMAC_RESET) += vfio-platform-calxedaxgmac.o
+obj-$(CONFIG_VFIO_PLATFORM_AMDXGBE_RESET) += vfio-platform-amdxgbe.o
diff --git a/drivers/vfio/platform/reset/vfio_platform_amdxgbe.c b/drivers/vfio/platform/reset/vfio_platform_amdxgbe.c
new file mode 100644 (file)
index 0000000..da5356f
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * VFIO platform driver specialized for AMD xgbe reset
+ * reset code is inherited from AMD xgbe native driver
+ *
+ * Copyright (c) 2015 Linaro Ltd.
+ *              www.linaro.org
+ *
+ * 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.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <uapi/linux/mdio.h>
+#include <linux/delay.h>
+
+#include "vfio_platform_private.h"
+
+#define DMA_MR                 0x3000
+#define MAC_VR                 0x0110
+#define DMA_ISR                        0x3008
+#define MAC_ISR                        0x00b0
+#define PCS_MMD_SELECT         0xff
+#define MDIO_AN_INT            0x8002
+#define MDIO_AN_INTMASK                0x8001
+
+static unsigned int xmdio_read(void *ioaddr, unsigned int mmd,
+                              unsigned int reg)
+{
+       unsigned int mmd_address, value;
+
+       mmd_address = (mmd << 16) | ((reg) & 0xffff);
+       iowrite32(mmd_address >> 8, ioaddr + (PCS_MMD_SELECT << 2));
+       value = ioread32(ioaddr + ((mmd_address & 0xff) << 2));
+       return value;
+}
+
+static void xmdio_write(void *ioaddr, unsigned int mmd,
+                       unsigned int reg, unsigned int value)
+{
+       unsigned int mmd_address;
+
+       mmd_address = (mmd << 16) | ((reg) & 0xffff);
+       iowrite32(mmd_address >> 8, ioaddr + (PCS_MMD_SELECT << 2));
+       iowrite32(value, ioaddr + ((mmd_address & 0xff) << 2));
+}
+
+int vfio_platform_amdxgbe_reset(struct vfio_platform_device *vdev)
+{
+       struct vfio_platform_region *xgmac_regs = &vdev->regions[0];
+       struct vfio_platform_region *xpcs_regs = &vdev->regions[1];
+       u32 dma_mr_value, pcs_value, value;
+       unsigned int count;
+
+       if (!xgmac_regs->ioaddr) {
+               xgmac_regs->ioaddr =
+                       ioremap_nocache(xgmac_regs->addr, xgmac_regs->size);
+               if (!xgmac_regs->ioaddr)
+                       return -ENOMEM;
+       }
+       if (!xpcs_regs->ioaddr) {
+               xpcs_regs->ioaddr =
+                       ioremap_nocache(xpcs_regs->addr, xpcs_regs->size);
+               if (!xpcs_regs->ioaddr)
+                       return -ENOMEM;
+       }
+
+       /* reset the PHY through MDIO*/
+       pcs_value = xmdio_read(xpcs_regs->ioaddr, MDIO_MMD_PCS, MDIO_CTRL1);
+       pcs_value |= MDIO_CTRL1_RESET;
+       xmdio_write(xpcs_regs->ioaddr, MDIO_MMD_PCS, MDIO_CTRL1, pcs_value);
+
+       count = 50;
+       do {
+               msleep(20);
+               pcs_value = xmdio_read(xpcs_regs->ioaddr, MDIO_MMD_PCS,
+                                       MDIO_CTRL1);
+       } while ((pcs_value & MDIO_CTRL1_RESET) && --count);
+
+       if (pcs_value & MDIO_CTRL1_RESET)
+               pr_warn("%s XGBE PHY reset timeout\n", __func__);
+
+       /* disable auto-negotiation */
+       value = xmdio_read(xpcs_regs->ioaddr, MDIO_MMD_AN, MDIO_CTRL1);
+       value &= ~MDIO_AN_CTRL1_ENABLE;
+       xmdio_write(xpcs_regs->ioaddr, MDIO_MMD_AN, MDIO_CTRL1, value);
+
+       /* disable AN IRQ */
+       xmdio_write(xpcs_regs->ioaddr, MDIO_MMD_AN, MDIO_AN_INTMASK, 0);
+
+       /* clear AN IRQ */
+       xmdio_write(xpcs_regs->ioaddr, MDIO_MMD_AN, MDIO_AN_INT, 0);
+
+       /* MAC software reset */
+       dma_mr_value = ioread32(xgmac_regs->ioaddr + DMA_MR);
+       dma_mr_value |= 0x1;
+       iowrite32(dma_mr_value, xgmac_regs->ioaddr + DMA_MR);
+
+       usleep_range(10, 15);
+
+       count = 2000;
+       while (count-- && (ioread32(xgmac_regs->ioaddr + DMA_MR) & 1))
+               usleep_range(500, 600);
+
+       if (!count)
+               pr_warn("%s MAC SW reset failed\n", __func__);
+
+       return 0;
+}
+
+module_vfio_reset_handler("amd,xgbe-seattle-v1a", vfio_platform_amdxgbe_reset);
+
+MODULE_VERSION("0.1");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Eric Auger <eric.auger@linaro.org>");
+MODULE_DESCRIPTION("Reset support for AMD xgbe vfio platform device");
index 619dc7d22082407771dc257a3a1a61d5a70e77eb..e3d3d948e6618c9732db62740031f2d8a42c5d0c 100644 (file)
@@ -30,8 +30,6 @@
 #define DRIVER_AUTHOR   "Eric Auger <eric.auger@linaro.org>"
 #define DRIVER_DESC     "Reset support for Calxeda xgmac vfio platform device"
 
-#define CALXEDAXGMAC_COMPAT "calxeda,hb-xgmac"
-
 /* XGMAC Register definitions */
 #define XGMAC_CONTROL           0x00000000      /* MAC Configuration */
 
@@ -61,24 +59,25 @@ static inline void xgmac_mac_disable(void __iomem *ioaddr)
 
 int vfio_platform_calxedaxgmac_reset(struct vfio_platform_device *vdev)
 {
-       struct vfio_platform_region reg = vdev->regions[0];
+       struct vfio_platform_region *reg = &vdev->regions[0];
 
-       if (!reg.ioaddr) {
-               reg.ioaddr =
-                       ioremap_nocache(reg.addr, reg.size);
-               if (!reg.ioaddr)
+       if (!reg->ioaddr) {
+               reg->ioaddr =
+                       ioremap_nocache(reg->addr, reg->size);
+               if (!reg->ioaddr)
                        return -ENOMEM;
        }
 
        /* disable IRQ */
-       writel(0, reg.ioaddr + XGMAC_DMA_INTR_ENA);
+       writel(0, reg->ioaddr + XGMAC_DMA_INTR_ENA);
 
        /* Disable the MAC core */
-       xgmac_mac_disable(reg.ioaddr);
+       xgmac_mac_disable(reg->ioaddr);
 
        return 0;
 }
-EXPORT_SYMBOL_GPL(vfio_platform_calxedaxgmac_reset);
+
+module_vfio_reset_handler("calxeda,hb-xgmac", vfio_platform_calxedaxgmac_reset);
 
 MODULE_VERSION(DRIVER_VERSION);
 MODULE_LICENSE("GPL v2");
index ff0331f72526b30e2d84a46f7895b97e5478b690..a66479bd0edf968c8209b384264052f79a6ec272 100644 (file)
@@ -67,6 +67,7 @@ static int vfio_amba_probe(struct amba_device *adev, const struct amba_id *id)
        vdev->flags = VFIO_DEVICE_FLAGS_AMBA;
        vdev->get_resource = get_amba_resource;
        vdev->get_irq = get_amba_irq;
+       vdev->parent_module = THIS_MODULE;
 
        ret = vfio_platform_probe_common(vdev, &adev->dev);
        if (ret) {
index cef645c8399679056b130ad19c3dbcbe2e480549..f1625dcfbb23d49d6b0586977a203462df0e75a5 100644 (file)
@@ -65,6 +65,7 @@ static int vfio_platform_probe(struct platform_device *pdev)
        vdev->flags = VFIO_DEVICE_FLAGS_PLATFORM;
        vdev->get_resource = get_platform_resource;
        vdev->get_irq = get_platform_irq;
+       vdev->parent_module = THIS_MODULE;
 
        ret = vfio_platform_probe_common(vdev, &pdev->dev);
        if (ret)
index e43efb5e92bf5bf6115d2df38391979d898b465d..a1c50d63079200ce90741ccd55e60bc703c73eb2 100644 (file)
 
 #include "vfio_platform_private.h"
 
-static DEFINE_MUTEX(driver_lock);
+#define DRIVER_VERSION  "0.10"
+#define DRIVER_AUTHOR   "Antonios Motakis <a.motakis@virtualopensystems.com>"
+#define DRIVER_DESC     "VFIO platform base module"
 
-static const struct vfio_platform_reset_combo reset_lookup_table[] = {
-       {
-               .compat = "calxeda,hb-xgmac",
-               .reset_function_name = "vfio_platform_calxedaxgmac_reset",
-               .module_name = "vfio-platform-calxedaxgmac",
-       },
-};
+static LIST_HEAD(reset_list);
+static DEFINE_MUTEX(driver_lock);
 
-static void vfio_platform_get_reset(struct vfio_platform_device *vdev,
-                                   struct device *dev)
+static vfio_platform_reset_fn_t vfio_platform_lookup_reset(const char *compat,
+                                       struct module **module)
 {
-       const char *compat;
-       int (*reset)(struct vfio_platform_device *);
-       int ret, i;
-
-       ret = device_property_read_string(dev, "compatible", &compat);
-       if (ret)
-               return;
-
-       for (i = 0 ; i < ARRAY_SIZE(reset_lookup_table); i++) {
-               if (!strcmp(reset_lookup_table[i].compat, compat)) {
-                       request_module(reset_lookup_table[i].module_name);
-                       reset = __symbol_get(
-                               reset_lookup_table[i].reset_function_name);
-                       if (reset) {
-                               vdev->reset = reset;
-                               return;
-                       }
+       struct vfio_platform_reset_node *iter;
+       vfio_platform_reset_fn_t reset_fn = NULL;
+
+       mutex_lock(&driver_lock);
+       list_for_each_entry(iter, &reset_list, link) {
+               if (!strcmp(iter->compat, compat) &&
+                       try_module_get(iter->owner)) {
+                       *module = iter->owner;
+                       reset_fn = iter->reset;
+                       break;
                }
        }
+       mutex_unlock(&driver_lock);
+       return reset_fn;
+}
+
+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);
+               vdev->reset = vfio_platform_lookup_reset(vdev->compat,
+                                                        &vdev->reset_module);
+       }
 }
 
 static void vfio_platform_put_reset(struct vfio_platform_device *vdev)
 {
        if (vdev->reset)
-               symbol_put_addr(vdev->reset);
+               module_put(vdev->reset_module);
 }
 
 static int vfio_platform_regions_init(struct vfio_platform_device *vdev)
@@ -138,15 +144,19 @@ static void vfio_platform_release(void *device_data)
        mutex_lock(&driver_lock);
 
        if (!(--vdev->refcnt)) {
-               if (vdev->reset)
+               if (vdev->reset) {
+                       dev_info(vdev->device, "reset\n");
                        vdev->reset(vdev);
+               } else {
+                       dev_warn(vdev->device, "no reset function found!\n");
+               }
                vfio_platform_regions_cleanup(vdev);
                vfio_platform_irq_cleanup(vdev);
        }
 
        mutex_unlock(&driver_lock);
 
-       module_put(THIS_MODULE);
+       module_put(vdev->parent_module);
 }
 
 static int vfio_platform_open(void *device_data)
@@ -154,7 +164,7 @@ static int vfio_platform_open(void *device_data)
        struct vfio_platform_device *vdev = device_data;
        int ret;
 
-       if (!try_module_get(THIS_MODULE))
+       if (!try_module_get(vdev->parent_module))
                return -ENODEV;
 
        mutex_lock(&driver_lock);
@@ -168,8 +178,12 @@ static int vfio_platform_open(void *device_data)
                if (ret)
                        goto err_irq;
 
-               if (vdev->reset)
+               if (vdev->reset) {
+                       dev_info(vdev->device, "reset\n");
                        vdev->reset(vdev);
+               } else {
+                       dev_warn(vdev->device, "no reset function found!\n");
+               }
        }
 
        vdev->refcnt++;
@@ -307,17 +321,17 @@ static long vfio_platform_ioctl(void *device_data,
        return -ENOTTY;
 }
 
-static ssize_t vfio_platform_read_mmio(struct vfio_platform_region reg,
+static ssize_t vfio_platform_read_mmio(struct vfio_platform_region *reg,
                                       char __user *buf, size_t count,
                                       loff_t off)
 {
        unsigned int done = 0;
 
-       if (!reg.ioaddr) {
-               reg.ioaddr =
-                       ioremap_nocache(reg.addr, reg.size);
+       if (!reg->ioaddr) {
+               reg->ioaddr =
+                       ioremap_nocache(reg->addr, reg->size);
 
-               if (!reg.ioaddr)
+               if (!reg->ioaddr)
                        return -ENOMEM;
        }
 
@@ -327,7 +341,7 @@ static ssize_t vfio_platform_read_mmio(struct vfio_platform_region reg,
                if (count >= 4 && !(off % 4)) {
                        u32 val;
 
-                       val = ioread32(reg.ioaddr + off);
+                       val = ioread32(reg->ioaddr + off);
                        if (copy_to_user(buf, &val, 4))
                                goto err;
 
@@ -335,7 +349,7 @@ static ssize_t vfio_platform_read_mmio(struct vfio_platform_region reg,
                } else if (count >= 2 && !(off % 2)) {
                        u16 val;
 
-                       val = ioread16(reg.ioaddr + off);
+                       val = ioread16(reg->ioaddr + off);
                        if (copy_to_user(buf, &val, 2))
                                goto err;
 
@@ -343,7 +357,7 @@ static ssize_t vfio_platform_read_mmio(struct vfio_platform_region reg,
                } else {
                        u8 val;
 
-                       val = ioread8(reg.ioaddr + off);
+                       val = ioread8(reg->ioaddr + off);
                        if (copy_to_user(buf, &val, 1))
                                goto err;
 
@@ -376,7 +390,7 @@ static ssize_t vfio_platform_read(void *device_data, char __user *buf,
                return -EINVAL;
 
        if (vdev->regions[index].type & VFIO_PLATFORM_REGION_TYPE_MMIO)
-               return vfio_platform_read_mmio(vdev->regions[index],
+               return vfio_platform_read_mmio(&vdev->regions[index],
                                                        buf, count, off);
        else if (vdev->regions[index].type & VFIO_PLATFORM_REGION_TYPE_PIO)
                return -EINVAL; /* not implemented */
@@ -384,17 +398,17 @@ static ssize_t vfio_platform_read(void *device_data, char __user *buf,
        return -EINVAL;
 }
 
-static ssize_t vfio_platform_write_mmio(struct vfio_platform_region reg,
+static ssize_t vfio_platform_write_mmio(struct vfio_platform_region *reg,
                                        const char __user *buf, size_t count,
                                        loff_t off)
 {
        unsigned int done = 0;
 
-       if (!reg.ioaddr) {
-               reg.ioaddr =
-                       ioremap_nocache(reg.addr, reg.size);
+       if (!reg->ioaddr) {
+               reg->ioaddr =
+                       ioremap_nocache(reg->addr, reg->size);
 
-               if (!reg.ioaddr)
+               if (!reg->ioaddr)
                        return -ENOMEM;
        }
 
@@ -406,7 +420,7 @@ static ssize_t vfio_platform_write_mmio(struct vfio_platform_region reg,
 
                        if (copy_from_user(&val, buf, 4))
                                goto err;
-                       iowrite32(val, reg.ioaddr + off);
+                       iowrite32(val, reg->ioaddr + off);
 
                        filled = 4;
                } else if (count >= 2 && !(off % 2)) {
@@ -414,7 +428,7 @@ static ssize_t vfio_platform_write_mmio(struct vfio_platform_region reg,
 
                        if (copy_from_user(&val, buf, 2))
                                goto err;
-                       iowrite16(val, reg.ioaddr + off);
+                       iowrite16(val, reg->ioaddr + off);
 
                        filled = 2;
                } else {
@@ -422,7 +436,7 @@ static ssize_t vfio_platform_write_mmio(struct vfio_platform_region reg,
 
                        if (copy_from_user(&val, buf, 1))
                                goto err;
-                       iowrite8(val, reg.ioaddr + off);
+                       iowrite8(val, reg->ioaddr + off);
 
                        filled = 1;
                }
@@ -452,7 +466,7 @@ static ssize_t vfio_platform_write(void *device_data, const char __user *buf,
                return -EINVAL;
 
        if (vdev->regions[index].type & VFIO_PLATFORM_REGION_TYPE_MMIO)
-               return vfio_platform_write_mmio(vdev->regions[index],
+               return vfio_platform_write_mmio(&vdev->regions[index],
                                                        buf, count, off);
        else if (vdev->regions[index].type & VFIO_PLATFORM_REGION_TYPE_PIO)
                return -EINVAL; /* not implemented */
@@ -539,6 +553,14 @@ int vfio_platform_probe_common(struct vfio_platform_device *vdev,
        if (!vdev)
                return -EINVAL;
 
+       ret = device_property_read_string(dev, "compatible", &vdev->compat);
+       if (ret) {
+               pr_err("VFIO: cannot retrieve compat for %s\n", vdev->name);
+               return -EINVAL;
+       }
+
+       vdev->device = dev;
+
        group = iommu_group_get(dev);
        if (!group) {
                pr_err("VFIO: No IOMMU group for device %s\n", vdev->name);
@@ -551,7 +573,7 @@ int vfio_platform_probe_common(struct vfio_platform_device *vdev,
                return ret;
        }
 
-       vfio_platform_get_reset(vdev, dev);
+       vfio_platform_get_reset(vdev);
 
        mutex_init(&vdev->igate);
 
@@ -573,3 +595,34 @@ struct vfio_platform_device *vfio_platform_remove_common(struct device *dev)
        return vdev;
 }
 EXPORT_SYMBOL_GPL(vfio_platform_remove_common);
+
+void __vfio_platform_register_reset(struct vfio_platform_reset_node *node)
+{
+       mutex_lock(&driver_lock);
+       list_add(&node->link, &reset_list);
+       mutex_unlock(&driver_lock);
+}
+EXPORT_SYMBOL_GPL(__vfio_platform_register_reset);
+
+void vfio_platform_unregister_reset(const char *compat,
+                                   vfio_platform_reset_fn_t fn)
+{
+       struct vfio_platform_reset_node *iter, *temp;
+
+       mutex_lock(&driver_lock);
+       list_for_each_entry_safe(iter, temp, &reset_list, link) {
+               if (!strcmp(iter->compat, compat) && (iter->reset == fn)) {
+                       list_del(&iter->link);
+                       break;
+               }
+       }
+
+       mutex_unlock(&driver_lock);
+
+}
+EXPORT_SYMBOL_GPL(vfio_platform_unregister_reset);
+
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
index 88bba57b30a8b28eefded76cd3ec3f9cd8912001..46d4750f43a8dccd574ea21f4fe53ecef4ec764c 100644 (file)
@@ -185,6 +185,7 @@ static int vfio_set_trigger(struct vfio_platform_device *vdev, int index,
        int ret;
 
        if (irq->trigger) {
+               irq_clear_status_flags(irq->hwirq, IRQ_NOAUTOEN);
                free_irq(irq->hwirq, irq);
                kfree(irq->name);
                eventfd_ctx_put(irq->trigger);
index 1c9b3d59543c1f32e60737be19bb46824bbebda3..42816dd280cb98ac4e27fabced74c2d9aa1df3d7 100644 (file)
@@ -56,6 +56,10 @@ struct vfio_platform_device {
        u32                             num_irqs;
        int                             refcnt;
        struct mutex                    igate;
+       struct module                   *parent_module;
+       const char                      *compat;
+       struct module                   *reset_module;
+       struct device                   *device;
 
        /*
         * These fields should be filled by the bus specific binder
@@ -70,10 +74,13 @@ struct vfio_platform_device {
        int     (*reset)(struct vfio_platform_device *vdev);
 };
 
-struct vfio_platform_reset_combo {
-       const char *compat;
-       const char *reset_function_name;
-       const char *module_name;
+typedef int (*vfio_platform_reset_fn_t)(struct vfio_platform_device *vdev);
+
+struct vfio_platform_reset_node {
+       struct list_head link;
+       char *compat;
+       struct module *owner;
+       vfio_platform_reset_fn_t reset;
 };
 
 extern int vfio_platform_probe_common(struct vfio_platform_device *vdev,
@@ -89,4 +96,29 @@ extern int vfio_platform_set_irqs_ioctl(struct vfio_platform_device *vdev,
                                        unsigned start, unsigned count,
                                        void *data);
 
+extern void __vfio_platform_register_reset(struct vfio_platform_reset_node *n);
+extern void vfio_platform_unregister_reset(const char *compat,
+                                          vfio_platform_reset_fn_t fn);
+#define vfio_platform_register_reset(__compat, __reset)                \
+static struct vfio_platform_reset_node __reset ## _node = {    \
+       .owner = THIS_MODULE,                                   \
+       .compat = __compat,                                     \
+       .reset = __reset,                                       \
+};                                                             \
+__vfio_platform_register_reset(&__reset ## _node)
+
+#define module_vfio_reset_handler(compat, reset)               \
+MODULE_ALIAS("vfio-reset:" compat);                            \
+static int __init reset ## _module_init(void)                  \
+{                                                              \
+       vfio_platform_register_reset(compat, reset);            \
+       return 0;                                               \
+};                                                             \
+static void __exit reset ## _module_exit(void)                 \
+{                                                              \
+       vfio_platform_unregister_reset(compat, reset);          \
+};                                                             \
+module_init(reset ## _module_init);                            \
+module_exit(reset ## _module_exit)
+
 #endif /* VFIO_PLATFORM_PRIVATE_H */
index 563c510f285c47d2a7362a4da8729fdc38e1dee0..de632da2e22f60d4eee042631821c1a4a9b7e558 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/miscdevice.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
+#include <linux/pci.h>
 #include <linux/rwsem.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
@@ -61,6 +62,7 @@ struct vfio_container {
        struct rw_semaphore             group_lock;
        struct vfio_iommu_driver        *iommu_driver;
        void                            *iommu_data;
+       bool                            noiommu;
 };
 
 struct vfio_unbound_dev {
@@ -83,6 +85,7 @@ struct vfio_group {
        struct list_head                unbound_list;
        struct mutex                    unbound_lock;
        atomic_t                        opened;
+       bool                            noiommu;
 };
 
 struct vfio_device {
@@ -94,6 +97,147 @@ 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
  */
@@ -198,7 +342,8 @@ 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)
+static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group,
+                                           bool noiommu)
 {
        struct vfio_group *group, *tmp;
        struct device *dev;
@@ -216,6 +361,7 @@ 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;
 
@@ -251,7 +397,8 @@ 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, "%d", iommu_group_id(iommu_group));
+                           group, "%s%d", noiommu ? "noiommu-" : "",
+                           iommu_group_id(iommu_group));
        if (IS_ERR(dev)) {
                vfio_free_group_minor(minor);
                vfio_group_unlock_and_free(group);
@@ -438,16 +585,33 @@ static struct vfio_device *vfio_group_get_device(struct vfio_group *group,
 }
 
 /*
- * Whitelist some drivers that we know are safe (no dma) or just sit on
- * a device.  It's not always practical to leave a device within a group
- * driverless as it could get re-bound to something unsafe.
+ * Some drivers, like pci-stub, are only used to prevent other drivers from
+ * claiming a device and are therefore perfectly legitimate for a user owned
+ * group.  The pci-stub driver has no dependencies on DMA or the IOVA mapping
+ * of the device, but it does prevent the user from having direct access to
+ * the device, which is useful in some circumstances.
+ *
+ * We also assume that we can include PCI interconnect devices, ie. bridges.
+ * IOMMU grouping on PCI necessitates that if we lack isolation on a bridge
+ * then all of the downstream devices will be part of the same IOMMU group as
+ * the bridge.  Thus, if placing the bridge into the user owned IOVA space
+ * breaks anything, it only does so for user owned devices downstream.  Note
+ * that error notification via MSI can be affected for platforms that handle
+ * MSI within the same IOVA space as DMA.
  */
-static const char * const vfio_driver_whitelist[] = { "pci-stub", "pcieport" };
+static const char * const vfio_driver_whitelist[] = { "pci-stub" };
 
-static bool vfio_whitelisted_driver(struct device_driver *drv)
+static bool vfio_dev_whitelisted(struct device *dev, struct device_driver *drv)
 {
        int i;
 
+       if (dev_is_pci(dev)) {
+               struct pci_dev *pdev = to_pci_dev(dev);
+
+               if (pdev->hdr_type != PCI_HEADER_TYPE_NORMAL)
+                       return true;
+       }
+
        for (i = 0; i < ARRAY_SIZE(vfio_driver_whitelist); i++) {
                if (!strcmp(drv->name, vfio_driver_whitelist[i]))
                        return true;
@@ -462,6 +626,7 @@ static bool vfio_whitelisted_driver(struct device_driver *drv)
  *  - driver-less
  *  - bound to a vfio driver
  *  - bound to a whitelisted driver
+ *  - a PCI interconnect device
  *
  * We use two methods to determine whether a device is bound to a vfio
  * driver.  The first is to test whether the device exists in the vfio
@@ -486,7 +651,7 @@ static int vfio_dev_viable(struct device *dev, void *data)
        }
        mutex_unlock(&group->unbound_lock);
 
-       if (!ret || !drv || vfio_whitelisted_driver(drv))
+       if (!ret || !drv || vfio_dev_whitelisted(dev, drv))
                return 0;
 
        device = vfio_group_get_device(group, dev);
@@ -621,7 +786,8 @@ int vfio_add_group_dev(struct device *dev,
 
        group = vfio_group_get_from_iommu(iommu_group);
        if (!group) {
-               group = vfio_create_group(iommu_group);
+               group = vfio_create_group(iommu_group,
+                                         !iommu_present(dev->bus));
                if (IS_ERR(group)) {
                        iommu_group_put(iommu_group);
                        return PTR_ERR(group);
@@ -692,11 +858,12 @@ EXPORT_SYMBOL_GPL(vfio_device_get_from_dev);
 static struct vfio_device *vfio_device_get_from_name(struct vfio_group *group,
                                                     char *buf)
 {
-       struct vfio_device *device;
+       struct vfio_device *it, *device = NULL;
 
        mutex_lock(&group->device_lock);
-       list_for_each_entry(device, &group->device_list, group_next) {
-               if (!strcmp(dev_name(device->dev), buf)) {
+       list_for_each_entry(it, &group->device_list, group_next) {
+               if (!strcmp(dev_name(it->dev), buf)) {
+                       device = it;
                        vfio_device_get(device);
                        break;
                }
@@ -832,8 +999,7 @@ static long vfio_ioctl_check_extension(struct vfio_container *container,
                 */
                if (!driver) {
                        mutex_lock(&vfio.iommu_drivers_lock);
-                       list_for_each_entry(driver, &vfio.iommu_drivers_list,
-                                           vfio_next) {
+                       vfio_for_each_iommu_driver(container, driver) {
                                if (!try_module_get(driver->ops->owner))
                                        continue;
 
@@ -902,7 +1068,7 @@ static long vfio_ioctl_set_iommu(struct vfio_container *container,
        }
 
        mutex_lock(&vfio.iommu_drivers_lock);
-       list_for_each_entry(driver, &vfio.iommu_drivers_list, vfio_next) {
+       vfio_for_each_iommu_driver(container, driver) {
                void *data;
 
                if (!try_module_get(driver->ops->owner))
@@ -1167,6 +1333,9 @@ 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;
@@ -1182,6 +1351,13 @@ 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,
@@ -1191,6 +1367,7 @@ 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 */
@@ -1221,6 +1398,9 @@ 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;
@@ -1263,6 +1443,10 @@ 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;
 }
 
@@ -1351,6 +1535,11 @@ 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) {
@@ -1513,6 +1702,11 @@ 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 57d8c37a002b0e0b8d49891536b8ddfab64afc6b..59d47cb638d5d18aac6700157ecc9be918772f91 100644 (file)
@@ -403,13 +403,26 @@ static void vfio_remove_dma(struct vfio_iommu *iommu, struct vfio_dma *dma)
 static unsigned long vfio_pgsize_bitmap(struct vfio_iommu *iommu)
 {
        struct vfio_domain *domain;
-       unsigned long bitmap = PAGE_MASK;
+       unsigned long bitmap = ULONG_MAX;
 
        mutex_lock(&iommu->lock);
        list_for_each_entry(domain, &iommu->domain_list, next)
                bitmap &= domain->domain->ops->pgsize_bitmap;
        mutex_unlock(&iommu->lock);
 
+       /*
+        * In case the IOMMU supports page sizes smaller than PAGE_SIZE
+        * we pretend PAGE_SIZE is supported and hide sub-PAGE_SIZE sizes.
+        * That way the user will be able to map/unmap buffers whose size/
+        * start address is aligned with PAGE_SIZE. Pinning code uses that
+        * granularity while iommu driver can use the sub-PAGE_SIZE size
+        * to map the buffer.
+        */
+       if (bitmap & ~PAGE_MASK) {
+               bitmap &= PAGE_MASK;
+               bitmap |= PAGE_SIZE;
+       }
+
        return bitmap;
 }
 
index e25a23692822c16ce26f7a2b9b9f7f96153a6563..29cfc57d496e9497ebcf7bd5c5bd07a083bd91dc 100644 (file)
@@ -42,8 +42,6 @@
 #include <scsi/scsi_proto.h>
 #include <target/target_core_base.h>
 #include <target/target_core_fabric.h>
-#include <target/target_core_fabric_configfs.h>
-#include <target/configfs_macros.h>
 #include <linux/vhost.h>
 #include <linux/virtio_scsi.h>
 #include <linux/llist.h>
@@ -1684,11 +1682,10 @@ static void vhost_scsi_free_cmd_map_res(struct vhost_scsi_nexus *nexus,
        }
 }
 
-static ssize_t vhost_scsi_tpg_attrib_store_fabric_prot_type(
-       struct se_portal_group *se_tpg,
-       const char *page,
-       size_t count)
+static ssize_t vhost_scsi_tpg_attrib_fabric_prot_type_store(
+               struct config_item *item, const char *page, size_t count)
 {
+       struct se_portal_group *se_tpg = attrib_to_tpg(item);
        struct vhost_scsi_tpg *tpg = container_of(se_tpg,
                                struct vhost_scsi_tpg, se_tpg);
        unsigned long val;
@@ -1707,19 +1704,20 @@ static ssize_t vhost_scsi_tpg_attrib_store_fabric_prot_type(
        return count;
 }
 
-static ssize_t vhost_scsi_tpg_attrib_show_fabric_prot_type(
-       struct se_portal_group *se_tpg,
-       char *page)
+static ssize_t vhost_scsi_tpg_attrib_fabric_prot_type_show(
+               struct config_item *item, char *page)
 {
+       struct se_portal_group *se_tpg = attrib_to_tpg(item);
        struct vhost_scsi_tpg *tpg = container_of(se_tpg,
                                struct vhost_scsi_tpg, se_tpg);
 
        return sprintf(page, "%d\n", tpg->tv_fabric_prot_type);
 }
-TF_TPG_ATTRIB_ATTR(vhost_scsi, fabric_prot_type, S_IRUGO | S_IWUSR);
+
+CONFIGFS_ATTR(vhost_scsi_tpg_attrib_, fabric_prot_type);
 
 static struct configfs_attribute *vhost_scsi_tpg_attrib_attrs[] = {
-       &vhost_scsi_tpg_attrib_fabric_prot_type.attr,
+       &vhost_scsi_tpg_attrib_attr_fabric_prot_type,
        NULL,
 };
 
@@ -1867,9 +1865,9 @@ static int vhost_scsi_drop_nexus(struct vhost_scsi_tpg *tpg)
        return 0;
 }
 
-static ssize_t vhost_scsi_tpg_show_nexus(struct se_portal_group *se_tpg,
-                                       char *page)
+static ssize_t vhost_scsi_tpg_nexus_show(struct config_item *item, char *page)
 {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct vhost_scsi_tpg *tpg = container_of(se_tpg,
                                struct vhost_scsi_tpg, se_tpg);
        struct vhost_scsi_nexus *tv_nexus;
@@ -1888,10 +1886,10 @@ static ssize_t vhost_scsi_tpg_show_nexus(struct se_portal_group *se_tpg,
        return ret;
 }
 
-static ssize_t vhost_scsi_tpg_store_nexus(struct se_portal_group *se_tpg,
-                                        const char *page,
-                                        size_t count)
+static ssize_t vhost_scsi_tpg_nexus_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct vhost_scsi_tpg *tpg = container_of(se_tpg,
                                struct vhost_scsi_tpg, se_tpg);
        struct vhost_scsi_tport *tport_wwn = tpg->tport;
@@ -1966,10 +1964,10 @@ check_newline:
        return count;
 }
 
-TF_TPG_BASE_ATTR(vhost_scsi, nexus, S_IRUGO | S_IWUSR);
+CONFIGFS_ATTR(vhost_scsi_tpg_, nexus);
 
 static struct configfs_attribute *vhost_scsi_tpg_attrs[] = {
-       &vhost_scsi_tpg_nexus.attr,
+       &vhost_scsi_tpg_attr_nexus,
        NULL,
 };
 
@@ -2105,18 +2103,17 @@ static void vhost_scsi_drop_tport(struct se_wwn *wwn)
 }
 
 static ssize_t
-vhost_scsi_wwn_show_attr_version(struct target_fabric_configfs *tf,
-                               char *page)
+vhost_scsi_wwn_version_show(struct config_item *item, char *page)
 {
        return sprintf(page, "TCM_VHOST fabric module %s on %s/%s"
                "on "UTS_RELEASE"\n", VHOST_SCSI_VERSION, utsname()->sysname,
                utsname()->machine);
 }
 
-TF_WWN_ATTR_RO(vhost_scsi, version);
+CONFIGFS_ATTR_RO(vhost_scsi_wwn_, version);
 
 static struct configfs_attribute *vhost_scsi_wwn_attrs[] = {
-       &vhost_scsi_wwn_version.attr,
+       &vhost_scsi_wwn_attr_version,
        NULL,
 };
 
index 9eeefd7cad41127dcade5d81c06647218abeaccc..43bcae852546ad2e5021b4a1d326dda375ae4023 100644 (file)
@@ -53,7 +53,6 @@
 
 #include <target/target_core_base.h>
 #include <target/target_core_fabric.h>
-#include <target/target_core_fabric_configfs.h>
 
 #include <asm/hypervisor.h>
 
@@ -1438,9 +1437,10 @@ static void scsiback_aborted_task(struct se_cmd *se_cmd)
 {
 }
 
-static ssize_t scsiback_tpg_param_show_alias(struct se_portal_group *se_tpg,
+static ssize_t scsiback_tpg_param_alias_show(struct config_item *item,
                                             char *page)
 {
+       struct se_portal_group *se_tpg = param_to_tpg(item);
        struct scsiback_tpg *tpg = container_of(se_tpg, struct scsiback_tpg,
                                                se_tpg);
        ssize_t rb;
@@ -1452,9 +1452,10 @@ static ssize_t scsiback_tpg_param_show_alias(struct se_portal_group *se_tpg,
        return rb;
 }
 
-static ssize_t scsiback_tpg_param_store_alias(struct se_portal_group *se_tpg,
+static ssize_t scsiback_tpg_param_alias_store(struct config_item *item,
                                              const char *page, size_t count)
 {
+       struct se_portal_group *se_tpg = param_to_tpg(item);
        struct scsiback_tpg *tpg = container_of(se_tpg, struct scsiback_tpg,
                                                se_tpg);
        int len;
@@ -1474,10 +1475,10 @@ static ssize_t scsiback_tpg_param_store_alias(struct se_portal_group *se_tpg,
        return count;
 }
 
-TF_TPG_PARAM_ATTR(scsiback, alias, S_IRUGO | S_IWUSR);
+CONFIGFS_ATTR(scsiback_tpg_param_, alias);
 
 static struct configfs_attribute *scsiback_param_attrs[] = {
-       &scsiback_tpg_param_alias.attr,
+       &scsiback_tpg_param_attr_alias,
        NULL,
 };
 
@@ -1585,9 +1586,9 @@ static int scsiback_drop_nexus(struct scsiback_tpg *tpg)
        return 0;
 }
 
-static ssize_t scsiback_tpg_show_nexus(struct se_portal_group *se_tpg,
-                                       char *page)
+static ssize_t scsiback_tpg_nexus_show(struct config_item *item, char *page)
 {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct scsiback_tpg *tpg = container_of(se_tpg,
                                struct scsiback_tpg, se_tpg);
        struct scsiback_nexus *tv_nexus;
@@ -1606,10 +1607,10 @@ static ssize_t scsiback_tpg_show_nexus(struct se_portal_group *se_tpg,
        return ret;
 }
 
-static ssize_t scsiback_tpg_store_nexus(struct se_portal_group *se_tpg,
-                                        const char *page,
-                                        size_t count)
+static ssize_t scsiback_tpg_nexus_store(struct config_item *item,
+               const char *page, size_t count)
 {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct scsiback_tpg *tpg = container_of(se_tpg,
                                struct scsiback_tpg, se_tpg);
        struct scsiback_tport *tport_wwn = tpg->tport;
@@ -1681,26 +1682,25 @@ check_newline:
        return count;
 }
 
-TF_TPG_BASE_ATTR(scsiback, nexus, S_IRUGO | S_IWUSR);
+CONFIGFS_ATTR(scsiback_tpg_, nexus);
 
 static struct configfs_attribute *scsiback_tpg_attrs[] = {
-       &scsiback_tpg_nexus.attr,
+       &scsiback_tpg_attr_nexus,
        NULL,
 };
 
 static ssize_t
-scsiback_wwn_show_attr_version(struct target_fabric_configfs *tf,
-                               char *page)
+scsiback_wwn_version_show(struct config_item *item, char *page)
 {
        return sprintf(page, "xen-pvscsi fabric module %s on %s/%s on "
                UTS_RELEASE"\n",
                VSCSI_VERSION, utsname()->sysname, utsname()->machine);
 }
 
-TF_WWN_ATTR_RO(scsiback, version);
+CONFIGFS_ATTR_RO(scsiback_wwn_, version);
 
 static struct configfs_attribute *scsiback_wwn_attrs[] = {
-       &scsiback_wwn_version.attr,
+       &scsiback_wwn_attr_version,
        NULL,
 };
 
index ff7be98f84f2412359bba865b34314fc62dd6ae9..9619ccadd2fcd9717bb3e186d8de78db932b9653 100644 (file)
@@ -10,10 +10,7 @@ obj-$(CONFIG_9P_FS) := 9p.o
        vfs_dentry.o \
        v9fs.o \
        fid.o  \
-       xattr.o \
-       xattr_user.o \
-       xattr_trusted.o
+       xattr.o
 
 9p-$(CONFIG_9P_FSCACHE) += cache.o
 9p-$(CONFIG_9P_FS_POSIX_ACL) += acl.o
-9p-$(CONFIG_9P_FS_SECURITY) += xattr_security.o
index 31c010372660154f6665782e89cea669b8457d29..a7e28890f5efb4ec8729fc9de4f09e16d4fb91bd 100644 (file)
@@ -212,26 +212,9 @@ int v9fs_acl_mode(struct inode *dir, umode_t *modep,
        return 0;
 }
 
-static int v9fs_remote_get_acl(struct dentry *dentry, const char *name,
-                              void *buffer, size_t size, int type)
-{
-       char *full_name;
-
-       switch (type) {
-       case ACL_TYPE_ACCESS:
-               full_name =  POSIX_ACL_XATTR_ACCESS;
-               break;
-       case ACL_TYPE_DEFAULT:
-               full_name = POSIX_ACL_XATTR_DEFAULT;
-               break;
-       default:
-               BUG();
-       }
-       return v9fs_xattr_get(dentry, full_name, buffer, size);
-}
-
-static int v9fs_xattr_get_acl(struct dentry *dentry, const char *name,
-                             void *buffer, size_t size, int type)
+static int v9fs_xattr_get_acl(const struct xattr_handler *handler,
+                             struct dentry *dentry, const char *name,
+                             void *buffer, size_t size)
 {
        struct v9fs_session_info *v9ses;
        struct posix_acl *acl;
@@ -245,9 +228,9 @@ static int v9fs_xattr_get_acl(struct dentry *dentry, const char *name,
         * We allow set/get/list of acl when access=client is not specified
         */
        if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT)
-               return v9fs_remote_get_acl(dentry, name, buffer, size, type);
+               return v9fs_xattr_get(dentry, handler->prefix, buffer, size);
 
-       acl = v9fs_get_cached_acl(d_inode(dentry), type);
+       acl = v9fs_get_cached_acl(d_inode(dentry), handler->flags);
        if (IS_ERR(acl))
                return PTR_ERR(acl);
        if (acl == NULL)
@@ -258,29 +241,9 @@ static int v9fs_xattr_get_acl(struct dentry *dentry, const char *name,
        return error;
 }
 
-static int v9fs_remote_set_acl(struct dentry *dentry, const char *name,
-                             const void *value, size_t size,
-                             int flags, int type)
-{
-       char *full_name;
-
-       switch (type) {
-       case ACL_TYPE_ACCESS:
-               full_name =  POSIX_ACL_XATTR_ACCESS;
-               break;
-       case ACL_TYPE_DEFAULT:
-               full_name = POSIX_ACL_XATTR_DEFAULT;
-               break;
-       default:
-               BUG();
-       }
-       return v9fs_xattr_set(dentry, full_name, value, size, flags);
-}
-
-
-static int v9fs_xattr_set_acl(struct dentry *dentry, const char *name,
-                             const void *value, size_t size,
-                             int flags, int type)
+static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
+                             struct dentry *dentry, const char *name,
+                             const void *value, size_t size, int flags)
 {
        int retval;
        struct posix_acl *acl;
@@ -296,8 +259,8 @@ static int v9fs_xattr_set_acl(struct dentry *dentry, const char *name,
         * xattr value. We leave it to the server to validate
         */
        if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT)
-               return v9fs_remote_set_acl(dentry, name,
-                                          value, size, flags, type);
+               return v9fs_xattr_set(dentry, handler->prefix, value, size,
+                                     flags);
 
        if (S_ISLNK(inode->i_mode))
                return -EOPNOTSUPP;
@@ -316,9 +279,8 @@ static int v9fs_xattr_set_acl(struct dentry *dentry, const char *name,
        } else
                acl = NULL;
 
-       switch (type) {
+       switch (handler->flags) {
        case ACL_TYPE_ACCESS:
-               name = POSIX_ACL_XATTR_ACCESS;
                if (acl) {
                        umode_t mode = inode->i_mode;
                        retval = posix_acl_equiv_mode(acl, &mode);
@@ -349,7 +311,6 @@ static int v9fs_xattr_set_acl(struct dentry *dentry, const char *name,
                }
                break;
        case ACL_TYPE_DEFAULT:
-               name = POSIX_ACL_XATTR_DEFAULT;
                if (!S_ISDIR(inode->i_mode)) {
                        retval = acl ? -EINVAL : 0;
                        goto err_out;
@@ -358,9 +319,9 @@ static int v9fs_xattr_set_acl(struct dentry *dentry, const char *name,
        default:
                BUG();
        }
-       retval = v9fs_xattr_set(dentry, name, value, size, flags);
+       retval = v9fs_xattr_set(dentry, handler->prefix, value, size, flags);
        if (!retval)
-               set_cached_acl(inode, type, acl);
+               set_cached_acl(inode, handler->flags, acl);
 err_out:
        posix_acl_release(acl);
        return retval;
index 2f96754910950b59b26ac4a2046808cc7bf043c1..247e47e54bcc2c0836a334172367a140884d5c08 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #ifndef _9P_CACHE_H
+#define _9P_CACHE_H
 #ifdef CONFIG_9P_FSCACHE
 #include <linux/fscache.h>
 #include <linux/spinlock.h>
index 0cf44b6cccd6ee7dd131033845c7619ad778ab89..e3d026ac382eb482c9840140466b946aa554dd78 100644 (file)
@@ -137,6 +137,48 @@ ssize_t v9fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
        return v9fs_xattr_get(dentry, NULL, buffer, buffer_size);
 }
 
+static int v9fs_xattr_handler_get(const struct xattr_handler *handler,
+                                 struct dentry *dentry, const char *name,
+                                 void *buffer, size_t size)
+{
+       const char *full_name = xattr_full_name(handler, name);
+
+       if (strcmp(name, "") == 0)
+               return -EINVAL;
+       return v9fs_xattr_get(dentry, full_name, buffer, size);
+}
+
+static int v9fs_xattr_handler_set(const struct xattr_handler *handler,
+                                 struct dentry *dentry, const char *name,
+                                 const void *value, size_t size, int flags)
+{
+       const char *full_name = xattr_full_name(handler, name);
+
+       if (strcmp(name, "") == 0)
+               return -EINVAL;
+       return v9fs_xattr_set(dentry, full_name, value, size, flags);
+}
+
+static struct xattr_handler v9fs_xattr_user_handler = {
+       .prefix = XATTR_USER_PREFIX,
+       .get    = v9fs_xattr_handler_get,
+       .set    = v9fs_xattr_handler_set,
+};
+
+static struct xattr_handler v9fs_xattr_trusted_handler = {
+       .prefix = XATTR_TRUSTED_PREFIX,
+       .get    = v9fs_xattr_handler_get,
+       .set    = v9fs_xattr_handler_set,
+};
+
+#ifdef CONFIG_9P_FS_SECURITY
+static struct xattr_handler v9fs_xattr_security_handler = {
+       .prefix = XATTR_SECURITY_PREFIX,
+       .get    = v9fs_xattr_handler_get,
+       .set    = v9fs_xattr_handler_set,
+};
+#endif
+
 const struct xattr_handler *v9fs_xattr_handlers[] = {
        &v9fs_xattr_user_handler,
        &v9fs_xattr_trusted_handler,
index d3e2ea3840bedf2f6e3a2f1b0274172810a17ff8..c63c3bea5de550d87159e55ccedb0f057fcebedb 100644 (file)
@@ -19,9 +19,6 @@
 #include <net/9p/client.h>
 
 extern const struct xattr_handler *v9fs_xattr_handlers[];
-extern struct xattr_handler v9fs_xattr_user_handler;
-extern struct xattr_handler v9fs_xattr_trusted_handler;
-extern struct xattr_handler v9fs_xattr_security_handler;
 extern const struct xattr_handler v9fs_xattr_acl_access_handler;
 extern const struct xattr_handler v9fs_xattr_acl_default_handler;
 
diff --git a/fs/9p/xattr_security.c b/fs/9p/xattr_security.c
deleted file mode 100644 (file)
index cb247a1..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright IBM Corporation, 2010
- * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2.1 of the GNU Lesser General Public License
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- */
-
-
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include "xattr.h"
-
-static int v9fs_xattr_security_get(struct dentry *dentry, const char *name,
-                       void *buffer, size_t size, int type)
-{
-       int retval;
-       char *full_name;
-       size_t name_len;
-       size_t prefix_len = XATTR_SECURITY_PREFIX_LEN;
-
-       if (name == NULL)
-               return -EINVAL;
-
-       if (strcmp(name, "") == 0)
-               return -EINVAL;
-
-       name_len = strlen(name);
-       full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL);
-       if (!full_name)
-               return -ENOMEM;
-       memcpy(full_name, XATTR_SECURITY_PREFIX, prefix_len);
-       memcpy(full_name+prefix_len, name, name_len);
-       full_name[prefix_len + name_len] = '\0';
-
-       retval = v9fs_xattr_get(dentry, full_name, buffer, size);
-       kfree(full_name);
-       return retval;
-}
-
-static int v9fs_xattr_security_set(struct dentry *dentry, const char *name,
-                       const void *value, size_t size, int flags, int type)
-{
-       int retval;
-       char *full_name;
-       size_t name_len;
-       size_t prefix_len = XATTR_SECURITY_PREFIX_LEN;
-
-       if (name == NULL)
-               return -EINVAL;
-
-       if (strcmp(name, "") == 0)
-               return -EINVAL;
-
-       name_len = strlen(name);
-       full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL);
-       if (!full_name)
-               return -ENOMEM;
-       memcpy(full_name, XATTR_SECURITY_PREFIX, prefix_len);
-       memcpy(full_name + prefix_len, name, name_len);
-       full_name[prefix_len + name_len] = '\0';
-
-       retval = v9fs_xattr_set(dentry, full_name, value, size, flags);
-       kfree(full_name);
-       return retval;
-}
-
-struct xattr_handler v9fs_xattr_security_handler = {
-       .prefix = XATTR_SECURITY_PREFIX,
-       .get    = v9fs_xattr_security_get,
-       .set    = v9fs_xattr_security_set,
-};
diff --git a/fs/9p/xattr_trusted.c b/fs/9p/xattr_trusted.c
deleted file mode 100644 (file)
index e30d33b..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright IBM Corporation, 2010
- * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2.1 of the GNU Lesser General Public License
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- */
-
-
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include "xattr.h"
-
-static int v9fs_xattr_trusted_get(struct dentry *dentry, const char *name,
-                       void *buffer, size_t size, int type)
-{
-       int retval;
-       char *full_name;
-       size_t name_len;
-       size_t prefix_len = XATTR_TRUSTED_PREFIX_LEN;
-
-       if (name == NULL)
-               return -EINVAL;
-
-       if (strcmp(name, "") == 0)
-               return -EINVAL;
-
-       name_len = strlen(name);
-       full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL);
-       if (!full_name)
-               return -ENOMEM;
-       memcpy(full_name, XATTR_TRUSTED_PREFIX, prefix_len);
-       memcpy(full_name+prefix_len, name, name_len);
-       full_name[prefix_len + name_len] = '\0';
-
-       retval = v9fs_xattr_get(dentry, full_name, buffer, size);
-       kfree(full_name);
-       return retval;
-}
-
-static int v9fs_xattr_trusted_set(struct dentry *dentry, const char *name,
-                       const void *value, size_t size, int flags, int type)
-{
-       int retval;
-       char *full_name;
-       size_t name_len;
-       size_t prefix_len = XATTR_TRUSTED_PREFIX_LEN;
-
-       if (name == NULL)
-               return -EINVAL;
-
-       if (strcmp(name, "") == 0)
-               return -EINVAL;
-
-       name_len = strlen(name);
-       full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL);
-       if (!full_name)
-               return -ENOMEM;
-       memcpy(full_name, XATTR_TRUSTED_PREFIX, prefix_len);
-       memcpy(full_name + prefix_len, name, name_len);
-       full_name[prefix_len + name_len] = '\0';
-
-       retval = v9fs_xattr_set(dentry, full_name, value, size, flags);
-       kfree(full_name);
-       return retval;
-}
-
-struct xattr_handler v9fs_xattr_trusted_handler = {
-       .prefix = XATTR_TRUSTED_PREFIX,
-       .get    = v9fs_xattr_trusted_get,
-       .set    = v9fs_xattr_trusted_set,
-};
diff --git a/fs/9p/xattr_user.c b/fs/9p/xattr_user.c
deleted file mode 100644 (file)
index d0b701b..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright IBM Corporation, 2010
- * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2.1 of the GNU Lesser General Public License
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- */
-
-
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include "xattr.h"
-
-static int v9fs_xattr_user_get(struct dentry *dentry, const char *name,
-                       void *buffer, size_t size, int type)
-{
-       int retval;
-       char *full_name;
-       size_t name_len;
-       size_t prefix_len = XATTR_USER_PREFIX_LEN;
-
-       if (name == NULL)
-               return -EINVAL;
-
-       if (strcmp(name, "") == 0)
-               return -EINVAL;
-
-       name_len = strlen(name);
-       full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL);
-       if (!full_name)
-               return -ENOMEM;
-       memcpy(full_name, XATTR_USER_PREFIX, prefix_len);
-       memcpy(full_name+prefix_len, name, name_len);
-       full_name[prefix_len + name_len] = '\0';
-
-       retval = v9fs_xattr_get(dentry, full_name, buffer, size);
-       kfree(full_name);
-       return retval;
-}
-
-static int v9fs_xattr_user_set(struct dentry *dentry, const char *name,
-                       const void *value, size_t size, int flags, int type)
-{
-       int retval;
-       char *full_name;
-       size_t name_len;
-       size_t prefix_len = XATTR_USER_PREFIX_LEN;
-
-       if (name == NULL)
-               return -EINVAL;
-
-       if (strcmp(name, "") == 0)
-               return -EINVAL;
-
-       name_len = strlen(name);
-       full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL);
-       if (!full_name)
-               return -ENOMEM;
-       memcpy(full_name, XATTR_USER_PREFIX, prefix_len);
-       memcpy(full_name + prefix_len, name, name_len);
-       full_name[prefix_len + name_len] = '\0';
-
-       retval = v9fs_xattr_set(dentry, full_name, value, size, flags);
-       kfree(full_name);
-       return retval;
-}
-
-struct xattr_handler v9fs_xattr_user_handler = {
-       .prefix = XATTR_USER_PREFIX,
-       .get    = v9fs_xattr_user_get,
-       .set    = v9fs_xattr_user_set,
-};
index 5f399ea1d20a75301f31c0b4e50261319cd778f5..3a93755e880fee23fa6d8370916caefb21f2c9eb 100644 (file)
@@ -488,7 +488,7 @@ static inline int arch_elf_pt_proc(struct elfhdr *ehdr,
 }
 
 /**
- * arch_check_elf() - check a PT_LOPROC..PT_HIPROC ELF program header
+ * arch_check_elf() - check an ELF executable
  * @ehdr:      The main ELF header
  * @has_interp:        True if the ELF has an interpreter, else false.
  * @state:     Architecture-specific state preserved throughout the process
@@ -760,16 +760,16 @@ static int load_elf_binary(struct linux_binprm *bprm)
                         */
                        would_dump(bprm, interpreter);
 
-                       retval = kernel_read(interpreter, 0, bprm->buf,
-                                            BINPRM_BUF_SIZE);
-                       if (retval != BINPRM_BUF_SIZE) {
+                       /* Get the exec headers */
+                       retval = kernel_read(interpreter, 0,
+                                            (void *)&loc->interp_elf_ex,
+                                            sizeof(loc->interp_elf_ex));
+                       if (retval != sizeof(loc->interp_elf_ex)) {
                                if (retval >= 0)
                                        retval = -EIO;
                                goto out_free_dentry;
                        }
 
-                       /* Get the exec headers */
-                       loc->interp_elf_ex = *((struct elfhdr *)bprm->buf);
                        break;
                }
                elf_ppnt++;
index 0a793c7930eba290ab50555ea3def8fd1d99203b..bb0dfb1c7af1838029bb6d66625e179c733ddc02 100644 (file)
@@ -50,12 +50,21 @@ struct block_device *I_BDEV(struct inode *inode)
 }
 EXPORT_SYMBOL(I_BDEV);
 
-static void bdev_write_inode(struct inode *inode)
+static void bdev_write_inode(struct block_device *bdev)
 {
+       struct inode *inode = bdev->bd_inode;
+       int ret;
+
        spin_lock(&inode->i_lock);
        while (inode->i_state & I_DIRTY) {
                spin_unlock(&inode->i_lock);
-               WARN_ON_ONCE(write_inode_now(inode, true));
+               ret = write_inode_now(inode, true);
+               if (ret) {
+                       char name[BDEVNAME_SIZE];
+                       pr_warn_ratelimited("VFS: Dirty inode writeback failed "
+                                           "for block device %s (err=%d).\n",
+                                           bdevname(bdev, name), ret);
+               }
                spin_lock(&inode->i_lock);
        }
        spin_unlock(&inode->i_lock);
@@ -1504,7 +1513,7 @@ static void __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part)
                 * ->release can cause the queue to disappear, so flush all
                 * dirty data before.
                 */
-               bdev_write_inode(bdev->bd_inode);
+               bdev_write_inode(bdev);
        }
        if (bdev->bd_contains == bdev) {
                if (disk->fops->release)
index 640598c0d0e7585ff125b1a63ed9e74c2c42eaed..974be09e7556ca3f342cac89357364f4ce3cc016 100644 (file)
@@ -3780,6 +3780,9 @@ void close_ctree(struct btrfs_root *root)
        fs_info->closing = 1;
        smp_mb();
 
+       /* wait for the qgroup rescan worker to stop */
+       btrfs_qgroup_wait_for_completion(fs_info);
+
        /* wait for the uuid_scan task to finish */
        down(&fs_info->uuid_tree_rescan_sem);
        /* avoid complains from lockdep et al., set sem back to initial state */
index 99a8e57da8a11fbbdcbc0d833a687d79629200cc..acf3ed11cfb60e95b685aeb009e4d72fbdba3c3b 100644 (file)
@@ -10279,22 +10279,25 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info)
                block_group = list_first_entry(&fs_info->unused_bgs,
                                               struct btrfs_block_group_cache,
                                               bg_list);
-               space_info = block_group->space_info;
                list_del_init(&block_group->bg_list);
+
+               space_info = block_group->space_info;
+
                if (ret || btrfs_mixed_space_info(space_info)) {
                        btrfs_put_block_group(block_group);
                        continue;
                }
                spin_unlock(&fs_info->unused_bgs_lock);
 
-               mutex_lock(&root->fs_info->delete_unused_bgs_mutex);
+               mutex_lock(&fs_info->delete_unused_bgs_mutex);
 
                /* Don't want to race with allocators so take the groups_sem */
                down_write(&space_info->groups_sem);
                spin_lock(&block_group->lock);
                if (block_group->reserved ||
                    btrfs_block_group_used(&block_group->item) ||
-                   block_group->ro) {
+                   block_group->ro ||
+                   list_is_singular(&block_group->list)) {
                        /*
                         * We want to bail if we made new allocations or have
                         * outstanding allocations in this block group.  We do
@@ -10410,7 +10413,7 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info)
 end_trans:
                btrfs_end_transaction(trans, root);
 next:
-               mutex_unlock(&root->fs_info->delete_unused_bgs_mutex);
+               mutex_unlock(&fs_info->delete_unused_bgs_mutex);
                btrfs_put_block_group(block_group);
                spin_lock(&fs_info->unused_bgs_lock);
        }
index 6bd5ce9d75f0ab8eaca5a2f808bfaf5a66132742..977e715f0bf21a4ea8908700cfe4207dee1fe95d 100644 (file)
@@ -756,8 +756,16 @@ next_slot:
                }
 
                btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
-               if (key.objectid > ino ||
-                   key.type > BTRFS_EXTENT_DATA_KEY || key.offset >= end)
+
+               if (key.objectid > ino)
+                       break;
+               if (WARN_ON_ONCE(key.objectid < ino) ||
+                   key.type < BTRFS_EXTENT_DATA_KEY) {
+                       ASSERT(del_nr == 0);
+                       path->slots[0]++;
+                       goto next_slot;
+               }
+               if (key.type > BTRFS_EXTENT_DATA_KEY || key.offset >= end)
                        break;
 
                fi = btrfs_item_ptr(leaf, path->slots[0],
@@ -776,8 +784,8 @@ next_slot:
                                btrfs_file_extent_inline_len(leaf,
                                                     path->slots[0], fi);
                } else {
-                       WARN_ON(1);
-                       extent_end = search_start;
+                       /* can't happen */
+                       BUG();
                }
 
                /*
index 0e4f2bfcc37d083da90f381c0cfeeeb28f643cd2..994490d5fa6423dee4971e0ff013777d853fe6a6 100644 (file)
@@ -1304,8 +1304,14 @@ next_slot:
                num_bytes = 0;
                btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
 
-               if (found_key.objectid > ino ||
-                   found_key.type > BTRFS_EXTENT_DATA_KEY ||
+               if (found_key.objectid > ino)
+                       break;
+               if (WARN_ON_ONCE(found_key.objectid < ino) ||
+                   found_key.type < BTRFS_EXTENT_DATA_KEY) {
+                       path->slots[0]++;
+                       goto next_slot;
+               }
+               if (found_key.type > BTRFS_EXTENT_DATA_KEY ||
                    found_key.offset > end)
                        break;
 
@@ -7503,6 +7509,28 @@ struct btrfs_dio_data {
        u64 reserve;
 };
 
+static void adjust_dio_outstanding_extents(struct inode *inode,
+                                          struct btrfs_dio_data *dio_data,
+                                          const u64 len)
+{
+       unsigned num_extents;
+
+       num_extents = (unsigned) div64_u64(len + BTRFS_MAX_EXTENT_SIZE - 1,
+                                          BTRFS_MAX_EXTENT_SIZE);
+       /*
+        * If we have an outstanding_extents count still set then we're
+        * within our reservation, otherwise we need to adjust our inode
+        * counter appropriately.
+        */
+       if (dio_data->outstanding_extents) {
+               dio_data->outstanding_extents -= num_extents;
+       } else {
+               spin_lock(&BTRFS_I(inode)->lock);
+               BTRFS_I(inode)->outstanding_extents += num_extents;
+               spin_unlock(&BTRFS_I(inode)->lock);
+       }
+}
+
 static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock,
                                   struct buffer_head *bh_result, int create)
 {
@@ -7538,8 +7566,11 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock,
         * If this errors out it's because we couldn't invalidate pagecache for
         * this range and we need to fallback to buffered.
         */
-       if (lock_extent_direct(inode, lockstart, lockend, &cached_state, create))
-               return -ENOTBLK;
+       if (lock_extent_direct(inode, lockstart, lockend, &cached_state,
+                              create)) {
+               ret = -ENOTBLK;
+               goto err;
+       }
 
        em = btrfs_get_extent(inode, NULL, 0, start, len, 0);
        if (IS_ERR(em)) {
@@ -7657,19 +7688,7 @@ unlock:
                if (start + len > i_size_read(inode))
                        i_size_write(inode, start + len);
 
-               /*
-                * If we have an outstanding_extents count still set then we're
-                * within our reservation, otherwise we need to adjust our inode
-                * counter appropriately.
-                */
-               if (dio_data->outstanding_extents) {
-                       (dio_data->outstanding_extents)--;
-               } else {
-                       spin_lock(&BTRFS_I(inode)->lock);
-                       BTRFS_I(inode)->outstanding_extents++;
-                       spin_unlock(&BTRFS_I(inode)->lock);
-               }
-
+               adjust_dio_outstanding_extents(inode, dio_data, len);
                btrfs_free_reserved_data_space(inode, start, len);
                WARN_ON(dio_data->reserve < len);
                dio_data->reserve -= len;
@@ -7696,8 +7715,17 @@ unlock:
 unlock_err:
        clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, lockend,
                         unlock_bits, 1, 0, &cached_state, GFP_NOFS);
+err:
        if (dio_data)
                current->journal_info = dio_data;
+       /*
+        * Compensate the delalloc release we do in btrfs_direct_IO() when we
+        * write less data then expected, so that we don't underflow our inode's
+        * outstanding extents counter.
+        */
+       if (create && dio_data)
+               adjust_dio_outstanding_extents(inode, dio_data, len);
+
        return ret;
 }
 
index 46476c226395e777045a2303a1ada87b9e4b4a78..93e12c18ffd736ec77351ecb0443bbfec606a938 100644 (file)
@@ -2198,7 +2198,6 @@ qgroup_rescan_leaf(struct btrfs_fs_info *fs_info, struct btrfs_path *path,
        int slot;
        int ret;
 
-       path->leave_spinning = 1;
        mutex_lock(&fs_info->qgroup_rescan_lock);
        ret = btrfs_search_slot_for_read(fs_info->extent_root,
                                         &fs_info->qgroup_rescan_progress,
@@ -2286,7 +2285,7 @@ static void btrfs_qgroup_rescan_worker(struct btrfs_work *work)
                goto out;
 
        err = 0;
-       while (!err) {
+       while (!err && !btrfs_fs_closing(fs_info)) {
                trans = btrfs_start_transaction(fs_info->fs_root, 0);
                if (IS_ERR(trans)) {
                        err = PTR_ERR(trans);
@@ -2307,7 +2306,8 @@ out:
        btrfs_free_path(path);
 
        mutex_lock(&fs_info->qgroup_rescan_lock);
-       fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_RESCAN;
+       if (!btrfs_fs_closing(fs_info))
+               fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_RESCAN;
 
        if (err > 0 &&
            fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT) {
@@ -2336,7 +2336,9 @@ out:
        }
        btrfs_end_transaction(trans, fs_info->quota_root);
 
-       if (err >= 0) {
+       if (btrfs_fs_closing(fs_info)) {
+               btrfs_info(fs_info, "qgroup scan paused");
+       } else if (err >= 0) {
                btrfs_info(fs_info, "qgroup scan completed%s",
                        err > 0 ? " (inconsistency flag cleared)" : "");
        } else {
@@ -2384,12 +2386,11 @@ qgroup_rescan_init(struct btrfs_fs_info *fs_info, u64 progress_objectid,
        memset(&fs_info->qgroup_rescan_progress, 0,
                sizeof(fs_info->qgroup_rescan_progress));
        fs_info->qgroup_rescan_progress.objectid = progress_objectid;
+       init_completion(&fs_info->qgroup_rescan_completion);
 
        spin_unlock(&fs_info->qgroup_lock);
        mutex_unlock(&fs_info->qgroup_rescan_lock);
 
-       init_completion(&fs_info->qgroup_rescan_completion);
-
        memset(&fs_info->qgroup_rescan_work, 0,
               sizeof(fs_info->qgroup_rescan_work));
        btrfs_init_work(&fs_info->qgroup_rescan_work,
index 550de89a8661af8fdb1c08783ffadde680c138ec..2907a77fb1f6f4670885a7985ab40ed3e79c4925 100644 (file)
@@ -248,14 +248,9 @@ static int scrub_handle_errored_block(struct scrub_block *sblock_to_check);
 static int scrub_setup_recheck_block(struct scrub_block *original_sblock,
                                     struct scrub_block *sblocks_for_recheck);
 static void scrub_recheck_block(struct btrfs_fs_info *fs_info,
-                               struct scrub_block *sblock, int is_metadata,
-                               int have_csum, u8 *csum, u64 generation,
-                               u16 csum_size, int retry_failed_mirror);
-static void scrub_recheck_block_checksum(struct btrfs_fs_info *fs_info,
-                                        struct scrub_block *sblock,
-                                        int is_metadata, int have_csum,
-                                        const u8 *csum, u64 generation,
-                                        u16 csum_size);
+                               struct scrub_block *sblock,
+                               int retry_failed_mirror);
+static void scrub_recheck_block_checksum(struct scrub_block *sblock);
 static int scrub_repair_block_from_good_copy(struct scrub_block *sblock_bad,
                                             struct scrub_block *sblock_good);
 static int scrub_repair_page_from_good_copy(struct scrub_block *sblock_bad,
@@ -889,11 +884,9 @@ static int scrub_handle_errored_block(struct scrub_block *sblock_to_check)
        struct btrfs_fs_info *fs_info;
        u64 length;
        u64 logical;
-       u64 generation;
        unsigned int failed_mirror_index;
        unsigned int is_metadata;
        unsigned int have_csum;
-       u8 *csum;
        struct scrub_block *sblocks_for_recheck; /* holds one for each mirror */
        struct scrub_block *sblock_bad;
        int ret;
@@ -918,13 +911,11 @@ static int scrub_handle_errored_block(struct scrub_block *sblock_to_check)
        }
        length = sblock_to_check->page_count * PAGE_SIZE;
        logical = sblock_to_check->pagev[0]->logical;
-       generation = sblock_to_check->pagev[0]->generation;
        BUG_ON(sblock_to_check->pagev[0]->mirror_num < 1);
        failed_mirror_index = sblock_to_check->pagev[0]->mirror_num - 1;
        is_metadata = !(sblock_to_check->pagev[0]->flags &
                        BTRFS_EXTENT_FLAG_DATA);
        have_csum = sblock_to_check->pagev[0]->have_csum;
-       csum = sblock_to_check->pagev[0]->csum;
        dev = sblock_to_check->pagev[0]->dev;
 
        if (sctx->is_dev_replace && !is_metadata && !have_csum) {
@@ -987,8 +978,7 @@ static int scrub_handle_errored_block(struct scrub_block *sblock_to_check)
        sblock_bad = sblocks_for_recheck + failed_mirror_index;
 
        /* build and submit the bios for the failed mirror, check checksums */
-       scrub_recheck_block(fs_info, sblock_bad, is_metadata, have_csum,
-                           csum, generation, sctx->csum_size, 1);
+       scrub_recheck_block(fs_info, sblock_bad, 1);
 
        if (!sblock_bad->header_error && !sblock_bad->checksum_error &&
            sblock_bad->no_io_error_seen) {
@@ -1101,9 +1091,7 @@ nodatasum_case:
                sblock_other = sblocks_for_recheck + mirror_index;
 
                /* build and submit the bios, check checksums */
-               scrub_recheck_block(fs_info, sblock_other, is_metadata,
-                                   have_csum, csum, generation,
-                                   sctx->csum_size, 0);
+               scrub_recheck_block(fs_info, sblock_other, 0);
 
                if (!sblock_other->header_error &&
                    !sblock_other->checksum_error &&
@@ -1215,9 +1203,7 @@ nodatasum_case:
                         * is verified, but most likely the data comes out
                         * of the page cache.
                         */
-                       scrub_recheck_block(fs_info, sblock_bad,
-                                           is_metadata, have_csum, csum,
-                                           generation, sctx->csum_size, 1);
+                       scrub_recheck_block(fs_info, sblock_bad, 1);
                        if (!sblock_bad->header_error &&
                            !sblock_bad->checksum_error &&
                            sblock_bad->no_io_error_seen)
@@ -1318,6 +1304,9 @@ static int scrub_setup_recheck_block(struct scrub_block *original_sblock,
        struct btrfs_fs_info *fs_info = sctx->dev_root->fs_info;
        u64 length = original_sblock->page_count * PAGE_SIZE;
        u64 logical = original_sblock->pagev[0]->logical;
+       u64 generation = original_sblock->pagev[0]->generation;
+       u64 flags = original_sblock->pagev[0]->flags;
+       u64 have_csum = original_sblock->pagev[0]->have_csum;
        struct scrub_recover *recover;
        struct btrfs_bio *bbio;
        u64 sublen;
@@ -1372,6 +1361,7 @@ static int scrub_setup_recheck_block(struct scrub_block *original_sblock,
 
                        sblock = sblocks_for_recheck + mirror_index;
                        sblock->sctx = sctx;
+
                        page = kzalloc(sizeof(*page), GFP_NOFS);
                        if (!page) {
 leave_nomem:
@@ -1383,7 +1373,15 @@ leave_nomem:
                        }
                        scrub_page_get(page);
                        sblock->pagev[page_index] = page;
+                       page->sblock = sblock;
+                       page->flags = flags;
+                       page->generation = generation;
                        page->logical = logical;
+                       page->have_csum = have_csum;
+                       if (have_csum)
+                               memcpy(page->csum,
+                                      original_sblock->pagev[0]->csum,
+                                      sctx->csum_size);
 
                        scrub_stripe_index_and_offset(logical,
                                                      bbio->map_type,
@@ -1474,15 +1472,12 @@ static int scrub_submit_raid56_bio_wait(struct btrfs_fs_info *fs_info,
  * the pages that are errored in the just handled mirror can be repaired.
  */
 static void scrub_recheck_block(struct btrfs_fs_info *fs_info,
-                               struct scrub_block *sblock, int is_metadata,
-                               int have_csum, u8 *csum, u64 generation,
-                               u16 csum_size, int retry_failed_mirror)
+                               struct scrub_block *sblock,
+                               int retry_failed_mirror)
 {
        int page_num;
 
        sblock->no_io_error_seen = 1;
-       sblock->header_error = 0;
-       sblock->checksum_error = 0;
 
        for (page_num = 0; page_num < sblock->page_count; page_num++) {
                struct bio *bio;
@@ -1518,9 +1513,7 @@ static void scrub_recheck_block(struct btrfs_fs_info *fs_info,
        }
 
        if (sblock->no_io_error_seen)
-               scrub_recheck_block_checksum(fs_info, sblock, is_metadata,
-                                            have_csum, csum, generation,
-                                            csum_size);
+               scrub_recheck_block_checksum(sblock);
 
        return;
 }
@@ -1535,61 +1528,16 @@ static inline int scrub_check_fsid(u8 fsid[],
        return !ret;
 }
 
-static void scrub_recheck_block_checksum(struct btrfs_fs_info *fs_info,
-                                        struct scrub_block *sblock,
-                                        int is_metadata, int have_csum,
-                                        const u8 *csum, u64 generation,
-                                        u16 csum_size)
+static void scrub_recheck_block_checksum(struct scrub_block *sblock)
 {
-       int page_num;
-       u8 calculated_csum[BTRFS_CSUM_SIZE];
-       u32 crc = ~(u32)0;
-       void *mapped_buffer;
-
-       WARN_ON(!sblock->pagev[0]->page);
-       if (is_metadata) {
-               struct btrfs_header *h;
-
-               mapped_buffer = kmap_atomic(sblock->pagev[0]->page);
-               h = (struct btrfs_header *)mapped_buffer;
-
-               if (sblock->pagev[0]->logical != btrfs_stack_header_bytenr(h) ||
-                   !scrub_check_fsid(h->fsid, sblock->pagev[0]) ||
-                   memcmp(h->chunk_tree_uuid, fs_info->chunk_tree_uuid,
-                          BTRFS_UUID_SIZE)) {
-                       sblock->header_error = 1;
-               } else if (generation != btrfs_stack_header_generation(h)) {
-                       sblock->header_error = 1;
-                       sblock->generation_error = 1;
-               }
-               csum = h->csum;
-       } else {
-               if (!have_csum)
-                       return;
-
-               mapped_buffer = kmap_atomic(sblock->pagev[0]->page);
-       }
-
-       for (page_num = 0;;) {
-               if (page_num == 0 && is_metadata)
-                       crc = btrfs_csum_data(
-                               ((u8 *)mapped_buffer) + BTRFS_CSUM_SIZE,
-                               crc, PAGE_SIZE - BTRFS_CSUM_SIZE);
-               else
-                       crc = btrfs_csum_data(mapped_buffer, crc, PAGE_SIZE);
-
-               kunmap_atomic(mapped_buffer);
-               page_num++;
-               if (page_num >= sblock->page_count)
-                       break;
-               WARN_ON(!sblock->pagev[page_num]->page);
-
-               mapped_buffer = kmap_atomic(sblock->pagev[page_num]->page);
-       }
+       sblock->header_error = 0;
+       sblock->checksum_error = 0;
+       sblock->generation_error = 0;
 
-       btrfs_csum_final(crc, calculated_csum);
-       if (memcmp(calculated_csum, csum, csum_size))
-               sblock->checksum_error = 1;
+       if (sblock->pagev[0]->flags & BTRFS_EXTENT_FLAG_DATA)
+               scrub_checksum_data(sblock);
+       else
+               scrub_checksum_tree_block(sblock);
 }
 
 static int scrub_repair_block_from_good_copy(struct scrub_block *sblock_bad,
@@ -1833,6 +1781,18 @@ static int scrub_checksum(struct scrub_block *sblock)
        u64 flags;
        int ret;
 
+       /*
+        * No need to initialize these stats currently,
+        * because this function only use return value
+        * instead of these stats value.
+        *
+        * Todo:
+        * always use stats
+        */
+       sblock->header_error = 0;
+       sblock->generation_error = 0;
+       sblock->checksum_error = 0;
+
        WARN_ON(sblock->page_count < 1);
        flags = sblock->pagev[0]->flags;
        ret = 0;
@@ -1858,7 +1818,6 @@ static int scrub_checksum_data(struct scrub_block *sblock)
        struct page *page;
        void *buffer;
        u32 crc = ~(u32)0;
-       int fail = 0;
        u64 len;
        int index;
 
@@ -1889,9 +1848,9 @@ static int scrub_checksum_data(struct scrub_block *sblock)
 
        btrfs_csum_final(crc, csum);
        if (memcmp(csum, on_disk_csum, sctx->csum_size))
-               fail = 1;
+               sblock->checksum_error = 1;
 
-       return fail;
+       return sblock->checksum_error;
 }
 
 static int scrub_checksum_tree_block(struct scrub_block *sblock)
@@ -1907,8 +1866,6 @@ static int scrub_checksum_tree_block(struct scrub_block *sblock)
        u64 mapped_size;
        void *p;
        u32 crc = ~(u32)0;
-       int fail = 0;
-       int crc_fail = 0;
        u64 len;
        int index;
 
@@ -1923,19 +1880,20 @@ static int scrub_checksum_tree_block(struct scrub_block *sblock)
         * a) don't have an extent buffer and
         * b) the page is already kmapped
         */
-
        if (sblock->pagev[0]->logical != btrfs_stack_header_bytenr(h))
-               ++fail;
+               sblock->header_error = 1;
 
-       if (sblock->pagev[0]->generation != btrfs_stack_header_generation(h))
-               ++fail;
+       if (sblock->pagev[0]->generation != btrfs_stack_header_generation(h)) {
+               sblock->header_error = 1;
+               sblock->generation_error = 1;
+       }
 
        if (!scrub_check_fsid(h->fsid, sblock->pagev[0]))
-               ++fail;
+               sblock->header_error = 1;
 
        if (memcmp(h->chunk_tree_uuid, fs_info->chunk_tree_uuid,
                   BTRFS_UUID_SIZE))
-               ++fail;
+               sblock->header_error = 1;
 
        len = sctx->nodesize - BTRFS_CSUM_SIZE;
        mapped_size = PAGE_SIZE - BTRFS_CSUM_SIZE;
@@ -1960,9 +1918,9 @@ static int scrub_checksum_tree_block(struct scrub_block *sblock)
 
        btrfs_csum_final(crc, calculated_csum);
        if (memcmp(calculated_csum, on_disk_csum, sctx->csum_size))
-               ++crc_fail;
+               sblock->checksum_error = 1;
 
-       return fail || crc_fail;
+       return sblock->header_error || sblock->checksum_error;
 }
 
 static int scrub_checksum_super(struct scrub_block *sblock)
@@ -2176,39 +2134,27 @@ static void scrub_missing_raid56_worker(struct btrfs_work *work)
 {
        struct scrub_block *sblock = container_of(work, struct scrub_block, work);
        struct scrub_ctx *sctx = sblock->sctx;
-       struct btrfs_fs_info *fs_info = sctx->dev_root->fs_info;
-       unsigned int is_metadata;
-       unsigned int have_csum;
-       u8 *csum;
-       u64 generation;
        u64 logical;
        struct btrfs_device *dev;
 
-       is_metadata = !(sblock->pagev[0]->flags & BTRFS_EXTENT_FLAG_DATA);
-       have_csum = sblock->pagev[0]->have_csum;
-       csum = sblock->pagev[0]->csum;
-       generation = sblock->pagev[0]->generation;
        logical = sblock->pagev[0]->logical;
        dev = sblock->pagev[0]->dev;
 
-       if (sblock->no_io_error_seen) {
-               scrub_recheck_block_checksum(fs_info, sblock, is_metadata,
-                                            have_csum, csum, generation,
-                                            sctx->csum_size);
-       }
+       if (sblock->no_io_error_seen)
+               scrub_recheck_block_checksum(sblock);
 
        if (!sblock->no_io_error_seen) {
                spin_lock(&sctx->stat_lock);
                sctx->stat.read_errors++;
                spin_unlock(&sctx->stat_lock);
-               btrfs_err_rl_in_rcu(fs_info,
+               btrfs_err_rl_in_rcu(sctx->dev_root->fs_info,
                        "IO error rebuilding logical %llu for dev %s",
                        logical, rcu_str_deref(dev->name));
        } else if (sblock->header_error || sblock->checksum_error) {
                spin_lock(&sctx->stat_lock);
                sctx->stat.uncorrectable_errors++;
                spin_unlock(&sctx->stat_lock);
-               btrfs_err_rl_in_rcu(fs_info,
+               btrfs_err_rl_in_rcu(sctx->dev_root->fs_info,
                        "failed to rebuild valid logical %llu for dev %s",
                        logical, rcu_str_deref(dev->name));
        } else {
@@ -2500,8 +2446,7 @@ static void scrub_block_complete(struct scrub_block *sblock)
        }
 }
 
-static int scrub_find_csum(struct scrub_ctx *sctx, u64 logical, u64 len,
-                          u8 *csum)
+static int scrub_find_csum(struct scrub_ctx *sctx, u64 logical, u8 *csum)
 {
        struct btrfs_ordered_sum *sum = NULL;
        unsigned long index;
@@ -2565,7 +2510,7 @@ static int scrub_extent(struct scrub_ctx *sctx, u64 logical, u64 len,
 
                if (flags & BTRFS_EXTENT_FLAG_DATA) {
                        /* push csums to sbio */
-                       have_csum = scrub_find_csum(sctx, logical, l, csum);
+                       have_csum = scrub_find_csum(sctx, logical, csum);
                        if (have_csum == 0)
                                ++sctx->stat.no_csum;
                        if (sctx->is_dev_replace && !have_csum) {
@@ -2703,7 +2648,7 @@ static int scrub_extent_for_parity(struct scrub_parity *sparity,
 
                if (flags & BTRFS_EXTENT_FLAG_DATA) {
                        /* push csums to sbio */
-                       have_csum = scrub_find_csum(sctx, logical, l, csum);
+                       have_csum = scrub_find_csum(sctx, logical, csum);
                        if (have_csum == 0)
                                goto skip;
                }
@@ -3012,6 +2957,9 @@ static noinline_for_stack int scrub_raid56_parity(struct scrub_ctx *sctx,
                             logic_start + map->stripe_len)) {
                                btrfs_err(fs_info, "scrub: tree block %llu spanning stripes, ignored. logical=%llu",
                                          key.objectid, logic_start);
+                               spin_lock(&sctx->stat_lock);
+                               sctx->stat.uncorrectable_errors++;
+                               spin_unlock(&sctx->stat_lock);
                                goto next;
                        }
 again:
@@ -3361,6 +3309,9 @@ static noinline_for_stack int scrub_stripe(struct scrub_ctx *sctx,
                                           "scrub: tree block %llu spanning "
                                           "stripes, ignored. logical=%llu",
                                       key.objectid, logical);
+                               spin_lock(&sctx->stat_lock);
+                               sctx->stat.uncorrectable_errors++;
+                               spin_unlock(&sctx->stat_lock);
                                goto next;
                        }
 
index 9b2dafa5ba59178644c6c01879583cc2769a52e8..a6df8fdc1312ce78e97f9f90037ff5b236a58a92 100644 (file)
@@ -3400,6 +3400,7 @@ static int __btrfs_balance(struct btrfs_fs_info *fs_info)
        u32 count_data = 0;
        u32 count_meta = 0;
        u32 count_sys = 0;
+       int chunk_reserved = 0;
 
        /* step one make some room on all the devices */
        devices = &fs_info->fs_devices->devices;
@@ -3501,6 +3502,7 @@ again:
 
                ret = should_balance_chunk(chunk_root, leaf, chunk,
                                           found_key.offset);
+
                btrfs_release_path(path);
                if (!ret) {
                        mutex_unlock(&fs_info->delete_unused_bgs_mutex);
@@ -3537,6 +3539,25 @@ again:
                        goto loop;
                }
 
+               if ((chunk_type & BTRFS_BLOCK_GROUP_DATA) && !chunk_reserved) {
+                       trans = btrfs_start_transaction(chunk_root, 0);
+                       if (IS_ERR(trans)) {
+                               mutex_unlock(&fs_info->delete_unused_bgs_mutex);
+                               ret = PTR_ERR(trans);
+                               goto error;
+                       }
+
+                       ret = btrfs_force_chunk_alloc(trans, chunk_root,
+                                                     BTRFS_BLOCK_GROUP_DATA);
+                       if (ret < 0) {
+                               mutex_unlock(&fs_info->delete_unused_bgs_mutex);
+                               goto error;
+                       }
+
+                       btrfs_end_transaction(trans, chunk_root);
+                       chunk_reserved = 1;
+               }
+
                ret = btrfs_relocate_chunk(chunk_root,
                                           found_key.offset);
                mutex_unlock(&fs_info->delete_unused_bgs_mutex);
index 6f518c90e1c14b6966d80ab9202c0bff0e399686..1fcd7b6e7564defa675b3abe12589473a58e937d 100644 (file)
@@ -313,8 +313,10 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
                /* check to make sure this item is what we want */
                if (found_key.objectid != key.objectid)
                        break;
-               if (found_key.type != BTRFS_XATTR_ITEM_KEY)
+               if (found_key.type > BTRFS_XATTR_ITEM_KEY)
                        break;
+               if (found_key.type < BTRFS_XATTR_ITEM_KEY)
+                       goto next;
 
                di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
                if (verify_dir_item(root, leaf, di))
index 51aff0296ce2435189aaa71b68a18219e0e34578..4f4cd959da7c8fdfef9fcf49fd90e73c24c6d230 100644 (file)
@@ -2420,9 +2420,9 @@ EXPORT_SYMBOL(block_commit_write);
  * unlock the page.
  *
  * Direct callers of this function should protect against filesystem freezing
- * using sb_start_write() - sb_end_write() functions.
+ * using sb_start_pagefault() - sb_end_pagefault() functions.
  */
-int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
+int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
                         get_block_t get_block)
 {
        struct page *page = vmf->page;
@@ -2459,26 +2459,6 @@ out_unlock:
        unlock_page(page);
        return ret;
 }
-EXPORT_SYMBOL(__block_page_mkwrite);
-
-int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
-                  get_block_t get_block)
-{
-       int ret;
-       struct super_block *sb = file_inode(vma->vm_file)->i_sb;
-
-       sb_start_pagefault(sb);
-
-       /*
-        * Update file times before taking page lock. We may end up failing the
-        * fault so this update may be superfluous but who really cares...
-        */
-       file_update_time(vma->vm_file);
-
-       ret = __block_page_mkwrite(vma, vmf, get_block);
-       sb_end_pagefault(sb);
-       return block_page_mkwrite_return(ret);
-}
 EXPORT_SYMBOL(block_page_mkwrite);
 
 /*
index fc1056f5c96a3c750c3c5c9009048b234a7fd745..c4b893453e0eefda8475b3537e934f2bfc46d268 100644 (file)
@@ -655,6 +655,8 @@ lookup_again:
                        aops = d_backing_inode(object->dentry)->i_mapping->a_ops;
                        if (!aops->bmap)
                                goto check_error;
+                       if (object->dentry->d_sb->s_blocksize > PAGE_SIZE)
+                               goto check_error;
 
                        object->backer = object->dentry;
                } else {
index 3cbb0e834694131d461c927fddb2340b72755415..c0f3da3926a0c6d4b8cf95e2c24a2a1ebd9d6655 100644 (file)
@@ -414,9 +414,6 @@ int cachefiles_read_or_alloc_page(struct fscache_retrieval *op,
        ASSERT(inode->i_mapping->a_ops->readpages);
 
        /* calculate the shift required to use bmap */
-       if (inode->i_sb->s_blocksize > PAGE_SIZE)
-               goto enobufs;
-
        shift = PAGE_SHIFT - inode->i_sb->s_blocksize_bits;
 
        op->op.flags &= FSCACHE_OP_KEEP_FLAGS;
@@ -711,9 +708,6 @@ int cachefiles_read_or_alloc_pages(struct fscache_retrieval *op,
        ASSERT(inode->i_mapping->a_ops->readpages);
 
        /* calculate the shift required to use bmap */
-       if (inode->i_sb->s_blocksize > PAGE_SIZE)
-               goto all_enobufs;
-
        shift = PAGE_SHIFT - inode->i_sb->s_blocksize_bits;
 
        pagevec_init(&pagevec, 0);
@@ -885,7 +879,7 @@ int cachefiles_write_page(struct fscache_storage *op, struct page *page)
        loff_t pos, eof;
        size_t len;
        void *data;
-       int ret;
+       int ret = -ENOBUFS;
 
        ASSERT(op != NULL);
        ASSERT(page != NULL);
@@ -905,6 +899,15 @@ int cachefiles_write_page(struct fscache_storage *op, struct page *page)
        cache = container_of(object->fscache.cache,
                             struct cachefiles_cache, cache);
 
+       pos = (loff_t)page->index << PAGE_SHIFT;
+
+       /* We mustn't write more data than we have, so we have to beware of a
+        * partial page at EOF.
+        */
+       eof = object->fscache.store_limit_l;
+       if (pos >= eof)
+               goto error;
+
        /* write the page to the backing filesystem and let it store it in its
         * own time */
        path.mnt = cache->mnt;
@@ -912,40 +915,38 @@ int cachefiles_write_page(struct fscache_storage *op, struct page *page)
        file = dentry_open(&path, O_RDWR | O_LARGEFILE, cache->cache_cred);
        if (IS_ERR(file)) {
                ret = PTR_ERR(file);
-       } else {
-               pos = (loff_t) page->index << PAGE_SHIFT;
-
-               /* we mustn't write more data than we have, so we have
-                * to beware of a partial page at EOF */
-               eof = object->fscache.store_limit_l;
-               len = PAGE_SIZE;
-               if (eof & ~PAGE_MASK) {
-                       ASSERTCMP(pos, <, eof);
-                       if (eof - pos < PAGE_SIZE) {
-                               _debug("cut short %llx to %llx",
-                                      pos, eof);
-                               len = eof - pos;
-                               ASSERTCMP(pos + len, ==, eof);
-                       }
-               }
-
-               data = kmap(page);
-               ret = __kernel_write(file, data, len, &pos);
-               kunmap(page);
-               if (ret != len)
-                       ret = -EIO;
-               fput(file);
+               goto error_2;
        }
 
-       if (ret < 0) {
-               if (ret == -EIO)
-                       cachefiles_io_error_obj(
-                               object, "Write page to backing file failed");
-               ret = -ENOBUFS;
+       len = PAGE_SIZE;
+       if (eof & ~PAGE_MASK) {
+               if (eof - pos < PAGE_SIZE) {
+                       _debug("cut short %llx to %llx",
+                              pos, eof);
+                       len = eof - pos;
+                       ASSERTCMP(pos + len, ==, eof);
+               }
        }
 
-       _leave(" = %d", ret);
-       return ret;
+       data = kmap(page);
+       ret = __kernel_write(file, data, len, &pos);
+       kunmap(page);
+       fput(file);
+       if (ret != len)
+               goto error_eio;
+
+       _leave(" = 0");
+       return 0;
+
+error_eio:
+       ret = -EIO;
+error_2:
+       if (ret == -EIO)
+               cachefiles_io_error_obj(object,
+                                       "Write page to backing file failed");
+error:
+       _leave(" = -ENOBUFS [%d]", ret);
+       return -ENOBUFS;
 }
 
 /*
index 834f9f3723fbe3980e8a9705e8c1d0f86936eb40..a4766ded1ba78e8bbbff70d4c5e65b3f9060d687 100644 (file)
@@ -88,7 +88,7 @@ static uint16_t ceph_fscache_inode_get_key(const void *cookie_netfs_data,
        const struct ceph_inode_info* ci = cookie_netfs_data;
        uint16_t klen;
 
-       /* use ceph virtual inode (id + snaphot) */
+       /* use ceph virtual inode (id + snapshot) */
        klen = sizeof(ci->i_vino);
        if (klen > maxbuf)
                return 0;
index 27b566874bc1d2b0494b49ebe1769f380ccf8648..c69e1253b47bfbefb2eb2cb1564a5c4b9d87f9a3 100644 (file)
@@ -1655,9 +1655,8 @@ retry_locked:
            !S_ISDIR(inode->i_mode) &&          /* ignore readdir cache */
            ci->i_wrbuffer_ref == 0 &&          /* no dirty pages... */
            inode->i_data.nrpages &&            /* have cached pages */
-           (file_wanted == 0 ||                /* no open files */
-            (revoking & (CEPH_CAP_FILE_CACHE|
-                         CEPH_CAP_FILE_LAZYIO))) && /*  or revoking cache */
+           (revoking & (CEPH_CAP_FILE_CACHE|
+                        CEPH_CAP_FILE_LAZYIO)) && /*  or revoking cache */
            !tried_invalidate) {
                dout("check_caps trying to invalidate on %p\n", inode);
                if (try_nonblocking_invalidate(inode) < 0) {
@@ -1971,49 +1970,46 @@ out:
 }
 
 /*
- * wait for any uncommitted directory operations to commit.
+ * wait for any unsafe requests to complete.
  */
-static int unsafe_dirop_wait(struct inode *inode)
+static int unsafe_request_wait(struct inode *inode)
 {
        struct ceph_inode_info *ci = ceph_inode(inode);
-       struct list_head *head = &ci->i_unsafe_dirops;
-       struct ceph_mds_request *req;
-       u64 last_tid;
-       int ret = 0;
-
-       if (!S_ISDIR(inode->i_mode))
-               return 0;
+       struct ceph_mds_request *req1 = NULL, *req2 = NULL;
+       int ret, err = 0;
 
        spin_lock(&ci->i_unsafe_lock);
-       if (list_empty(head))
-               goto out;
-
-       req = list_last_entry(head, struct ceph_mds_request,
-                             r_unsafe_dir_item);
-       last_tid = req->r_tid;
-
-       do {
-               ceph_mdsc_get_request(req);
-               spin_unlock(&ci->i_unsafe_lock);
+       if (S_ISDIR(inode->i_mode) && !list_empty(&ci->i_unsafe_dirops)) {
+               req1 = list_last_entry(&ci->i_unsafe_dirops,
+                                       struct ceph_mds_request,
+                                       r_unsafe_dir_item);
+               ceph_mdsc_get_request(req1);
+       }
+       if (!list_empty(&ci->i_unsafe_iops)) {
+               req2 = list_last_entry(&ci->i_unsafe_iops,
+                                       struct ceph_mds_request,
+                                       r_unsafe_target_item);
+               ceph_mdsc_get_request(req2);
+       }
+       spin_unlock(&ci->i_unsafe_lock);
 
-               dout("unsafe_dirop_wait %p wait on tid %llu (until %llu)\n",
-                    inode, req->r_tid, last_tid);
-               ret = !wait_for_completion_timeout(&req->r_safe_completion,
-                                       ceph_timeout_jiffies(req->r_timeout));
+       dout("unsafe_requeset_wait %p wait on tid %llu %llu\n",
+            inode, req1 ? req1->r_tid : 0ULL, req2 ? req2->r_tid : 0ULL);
+       if (req1) {
+               ret = !wait_for_completion_timeout(&req1->r_safe_completion,
+                                       ceph_timeout_jiffies(req1->r_timeout));
                if (ret)
-                       ret = -EIO;  /* timed out */
-
-               ceph_mdsc_put_request(req);
-
-               spin_lock(&ci->i_unsafe_lock);
-               if (ret || list_empty(head))
-                       break;
-               req = list_first_entry(head, struct ceph_mds_request,
-                                      r_unsafe_dir_item);
-       } while (req->r_tid < last_tid);
-out:
-       spin_unlock(&ci->i_unsafe_lock);
-       return ret;
+                       err = -EIO;
+               ceph_mdsc_put_request(req1);
+       }
+       if (req2) {
+               ret = !wait_for_completion_timeout(&req2->r_safe_completion,
+                                       ceph_timeout_jiffies(req2->r_timeout));
+               if (ret)
+                       err = -EIO;
+               ceph_mdsc_put_request(req2);
+       }
+       return err;
 }
 
 int ceph_fsync(struct file *file, loff_t start, loff_t end, int datasync)
@@ -2039,7 +2035,7 @@ int ceph_fsync(struct file *file, loff_t start, loff_t end, int datasync)
        dirty = try_flush_caps(inode, &flush_tid);
        dout("fsync dirty caps are %s\n", ceph_cap_string(dirty));
 
-       ret = unsafe_dirop_wait(inode);
+       ret = unsafe_request_wait(inode);
 
        /*
         * only wait on non-file metadata writeback (the mds
index 0c62868b5c561b37fa866b68bbe34f3ffb1fd6a6..3c68e6aee2f0531bdd8afb0125bbae48419d0dfb 100644 (file)
  * need to wait for MDS acknowledgement.
  */
 
+/*
+ * Calculate the length sum of direct io vectors that can
+ * be combined into one page vector.
+ */
+static size_t dio_get_pagev_size(const struct iov_iter *it)
+{
+    const struct iovec *iov = it->iov;
+    const struct iovec *iovend = iov + it->nr_segs;
+    size_t size;
+
+    size = iov->iov_len - it->iov_offset;
+    /*
+     * An iov can be page vectored when both the current tail
+     * and the next base are page aligned.
+     */
+    while (PAGE_ALIGNED((iov->iov_base + iov->iov_len)) &&
+           (++iov < iovend && PAGE_ALIGNED((iov->iov_base)))) {
+        size += iov->iov_len;
+    }
+    dout("dio_get_pagevlen len = %zu\n", size);
+    return size;
+}
+
+/*
+ * Allocate a page vector based on (@it, @nbytes).
+ * The return value is the tuple describing a page vector,
+ * that is (@pages, @page_align, @num_pages).
+ */
+static struct page **
+dio_get_pages_alloc(const struct iov_iter *it, size_t nbytes,
+                   size_t *page_align, int *num_pages)
+{
+       struct iov_iter tmp_it = *it;
+       size_t align;
+       struct page **pages;
+       int ret = 0, idx, npages;
+
+       align = (unsigned long)(it->iov->iov_base + it->iov_offset) &
+               (PAGE_SIZE - 1);
+       npages = calc_pages_for(align, nbytes);
+       pages = kmalloc(sizeof(*pages) * npages, GFP_KERNEL);
+       if (!pages) {
+               pages = vmalloc(sizeof(*pages) * npages);
+               if (!pages)
+                       return ERR_PTR(-ENOMEM);
+       }
+
+       for (idx = 0; idx < npages; ) {
+               size_t start;
+               ret = iov_iter_get_pages(&tmp_it, pages + idx, nbytes,
+                                        npages - idx, &start);
+               if (ret < 0)
+                       goto fail;
+
+               iov_iter_advance(&tmp_it, ret);
+               nbytes -= ret;
+               idx += (ret + start + PAGE_SIZE - 1) / PAGE_SIZE;
+       }
+
+       BUG_ON(nbytes != 0);
+       *num_pages = npages;
+       *page_align = align;
+       dout("dio_get_pages_alloc: got %d pages align %zu\n", npages, align);
+       return pages;
+fail:
+       ceph_put_page_vector(pages, idx, false);
+       return ERR_PTR(ret);
+}
 
 /*
  * Prepare an open request.  Preallocate ceph_cap to avoid an
@@ -458,11 +526,10 @@ static ssize_t ceph_sync_read(struct kiocb *iocb, struct iov_iter *i,
                        size_t start;
                        ssize_t n;
 
-                       n = iov_iter_get_pages_alloc(i, &pages, INT_MAX, &start);
-                       if (n < 0)
-                               return n;
-
-                       num_pages = (n + start + PAGE_SIZE - 1) / PAGE_SIZE;
+                       n = dio_get_pagev_size(i);
+                       pages = dio_get_pages_alloc(i, n, &start, &num_pages);
+                       if (IS_ERR(pages))
+                               return PTR_ERR(pages);
 
                        ret = striped_read(inode, off, n,
                                           pages, num_pages, checkeof,
@@ -592,7 +659,7 @@ ceph_sync_direct_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos,
                CEPH_OSD_FLAG_WRITE;
 
        while (iov_iter_count(from) > 0) {
-               u64 len = iov_iter_single_seg_count(from);
+               u64 len = dio_get_pagev_size(from);
                size_t start;
                ssize_t n;
 
@@ -611,14 +678,14 @@ ceph_sync_direct_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos,
 
                osd_req_op_init(req, 1, CEPH_OSD_OP_STARTSYNC, 0);
 
-               n = iov_iter_get_pages_alloc(from, &pages, len, &start);
-               if (unlikely(n < 0)) {
-                       ret = n;
+               n = len;
+               pages = dio_get_pages_alloc(from, len, &start, &num_pages);
+               if (IS_ERR(pages)) {
                        ceph_osdc_put_request(req);
+                       ret = PTR_ERR(pages);
                        break;
                }
 
-               num_pages = (n + start + PAGE_SIZE - 1) / PAGE_SIZE;
                /*
                 * throw out any page cache pages in this range. this
                 * may block.
index 96d2bd8299022e554c8bfdc0b7f1c759be8fc8cd..498dcfa2dcdbedf393ae26fc9f7f68cf90bceb90 100644 (file)
@@ -452,6 +452,7 @@ struct inode *ceph_alloc_inode(struct super_block *sb)
 
        INIT_LIST_HEAD(&ci->i_unsafe_writes);
        INIT_LIST_HEAD(&ci->i_unsafe_dirops);
+       INIT_LIST_HEAD(&ci->i_unsafe_iops);
        spin_lock_init(&ci->i_unsafe_lock);
 
        ci->i_snap_realm = NULL;
index 51cb02da75d98979b18e05d7bdad4dee89e258d4..e7b130a637f9f31a34efd67d6cf5789a8fcdef00 100644 (file)
@@ -633,13 +633,8 @@ static void __register_request(struct ceph_mds_client *mdsc,
                mdsc->oldest_tid = req->r_tid;
 
        if (dir) {
-               struct ceph_inode_info *ci = ceph_inode(dir);
-
                ihold(dir);
-               spin_lock(&ci->i_unsafe_lock);
                req->r_unsafe_dir = dir;
-               list_add_tail(&req->r_unsafe_dir_item, &ci->i_unsafe_dirops);
-               spin_unlock(&ci->i_unsafe_lock);
        }
 }
 
@@ -665,13 +660,20 @@ static void __unregister_request(struct ceph_mds_client *mdsc,
        rb_erase(&req->r_node, &mdsc->request_tree);
        RB_CLEAR_NODE(&req->r_node);
 
-       if (req->r_unsafe_dir) {
+       if (req->r_unsafe_dir && req->r_got_unsafe) {
                struct ceph_inode_info *ci = ceph_inode(req->r_unsafe_dir);
-
                spin_lock(&ci->i_unsafe_lock);
                list_del_init(&req->r_unsafe_dir_item);
                spin_unlock(&ci->i_unsafe_lock);
+       }
+       if (req->r_target_inode && req->r_got_unsafe) {
+               struct ceph_inode_info *ci = ceph_inode(req->r_target_inode);
+               spin_lock(&ci->i_unsafe_lock);
+               list_del_init(&req->r_unsafe_target_item);
+               spin_unlock(&ci->i_unsafe_lock);
+       }
 
+       if (req->r_unsafe_dir) {
                iput(req->r_unsafe_dir);
                req->r_unsafe_dir = NULL;
        }
@@ -1430,6 +1432,13 @@ static int trim_caps_cb(struct inode *inode, struct ceph_cap *cap, void *arg)
                if ((used | wanted) & CEPH_CAP_ANY_WR)
                        goto out;
        }
+       /* The inode has cached pages, but it's no longer used.
+        * we can safely drop it */
+       if (wanted == 0 && used == CEPH_CAP_FILE_CACHE &&
+           !(oissued & CEPH_CAP_FILE_CACHE)) {
+         used = 0;
+         oissued = 0;
+       }
        if ((used | wanted) & ~oissued & mine)
                goto out;   /* we need these caps */
 
@@ -1438,7 +1447,7 @@ static int trim_caps_cb(struct inode *inode, struct ceph_cap *cap, void *arg)
                /* we aren't the only cap.. just remove us */
                __ceph_remove_cap(cap, true);
        } else {
-               /* try to drop referring dentries */
+               /* try dropping referring dentries */
                spin_unlock(&ci->i_ceph_lock);
                d_prune_aliases(inode);
                dout("trim_caps_cb %p cap %p  pruned, count now %d\n",
@@ -1704,6 +1713,7 @@ ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode)
        req->r_started = jiffies;
        req->r_resend_mds = -1;
        INIT_LIST_HEAD(&req->r_unsafe_dir_item);
+       INIT_LIST_HEAD(&req->r_unsafe_target_item);
        req->r_fmode = -1;
        kref_init(&req->r_kref);
        INIT_LIST_HEAD(&req->r_wait);
@@ -1935,7 +1945,7 @@ static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc,
 
        len = sizeof(*head) +
                pathlen1 + pathlen2 + 2*(1 + sizeof(u32) + sizeof(u64)) +
-               sizeof(struct timespec);
+               sizeof(struct ceph_timespec);
 
        /* calculate (max) length for cap releases */
        len += sizeof(struct ceph_mds_request_release) *
@@ -2477,6 +2487,14 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
        } else {
                req->r_got_unsafe = true;
                list_add_tail(&req->r_unsafe_item, &req->r_session->s_unsafe);
+               if (req->r_unsafe_dir) {
+                       struct ceph_inode_info *ci =
+                                       ceph_inode(req->r_unsafe_dir);
+                       spin_lock(&ci->i_unsafe_lock);
+                       list_add_tail(&req->r_unsafe_dir_item,
+                                     &ci->i_unsafe_dirops);
+                       spin_unlock(&ci->i_unsafe_lock);
+               }
        }
 
        dout("handle_reply tid %lld result %d\n", tid, result);
@@ -2518,6 +2536,13 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
        up_read(&mdsc->snap_rwsem);
        if (realm)
                ceph_put_snap_realm(mdsc, realm);
+
+       if (err == 0 && req->r_got_unsafe && req->r_target_inode) {
+               struct ceph_inode_info *ci = ceph_inode(req->r_target_inode);
+               spin_lock(&ci->i_unsafe_lock);
+               list_add_tail(&req->r_unsafe_target_item, &ci->i_unsafe_iops);
+               spin_unlock(&ci->i_unsafe_lock);
+       }
 out_err:
        mutex_lock(&mdsc->mutex);
        if (!req->r_aborted) {
@@ -3917,17 +3942,19 @@ static struct ceph_msg *mds_alloc_msg(struct ceph_connection *con,
        return msg;
 }
 
-static int sign_message(struct ceph_connection *con, struct ceph_msg *msg)
+static int mds_sign_message(struct ceph_msg *msg)
 {
-       struct ceph_mds_session *s = con->private;
+       struct ceph_mds_session *s = msg->con->private;
        struct ceph_auth_handshake *auth = &s->s_auth;
+
        return ceph_auth_sign_message(auth, msg);
 }
 
-static int check_message_signature(struct ceph_connection *con, struct ceph_msg *msg)
+static int mds_check_message_signature(struct ceph_msg *msg)
 {
-       struct ceph_mds_session *s = con->private;
+       struct ceph_mds_session *s = msg->con->private;
        struct ceph_auth_handshake *auth = &s->s_auth;
+
        return ceph_auth_check_message_signature(auth, msg);
 }
 
@@ -3940,8 +3967,8 @@ static const struct ceph_connection_operations mds_con_ops = {
        .invalidate_authorizer = invalidate_authorizer,
        .peer_reset = peer_reset,
        .alloc_msg = mds_alloc_msg,
-       .sign_message = sign_message,
-       .check_message_signature = check_message_signature,
+       .sign_message = mds_sign_message,
+       .check_message_signature = mds_check_message_signature,
 };
 
 /* eof */
index f575eafe2261cbd5974d8d4f072879e9d5bd7a39..ccf11ef0ca8717f79e6bfc9d6cf806ec359b5e8c 100644 (file)
@@ -236,6 +236,9 @@ struct ceph_mds_request {
        struct inode    *r_unsafe_dir;
        struct list_head r_unsafe_dir_item;
 
+       /* unsafe requests that modify the target inode */
+       struct list_head r_unsafe_target_item;
+
        struct ceph_mds_session *r_session;
 
        int               r_attempts;   /* resend attempts */
index 2f2460d23a0600f8f9bf2e1cc4fe3b2286684356..75b7d125ce668a9b3f4f851d2be1c688d6d5f964 100644 (file)
@@ -342,6 +342,7 @@ struct ceph_inode_info {
 
        struct list_head i_unsafe_writes; /* uncommitted sync writes */
        struct list_head i_unsafe_dirops; /* uncommitted mds dir ops */
+       struct list_head i_unsafe_iops;   /* uncommitted mds inode ops */
        spinlock_t i_unsafe_lock;
 
        struct ceph_snap_realm *i_snap_realm; /* snap realm (if caps) */
index e739950ca08485543db80bee53f1021384ed0b9a..cbc0f4bca0c0dfa73b6a545fb6978a72b1a702ef 100644 (file)
@@ -454,6 +454,10 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
                seq_puts(s, ",nocase");
        if (tcon->retry)
                seq_puts(s, ",hard");
+       if (tcon->use_persistent)
+               seq_puts(s, ",persistenthandles");
+       else if (tcon->use_resilient)
+               seq_puts(s, ",resilienthandles");
        if (tcon->unix_ext)
                seq_puts(s, ",unix");
        else
@@ -921,9 +925,7 @@ const struct file_operations cifs_file_ops = {
        .mmap  = cifs_file_mmap,
        .splice_read = generic_file_splice_read,
        .llseek = cifs_llseek,
-#ifdef CONFIG_CIFS_POSIX
        .unlocked_ioctl = cifs_ioctl,
-#endif /* CONFIG_CIFS_POSIX */
        .setlease = cifs_setlease,
        .fallocate = cifs_fallocate,
 };
@@ -939,9 +941,7 @@ const struct file_operations cifs_file_strict_ops = {
        .mmap = cifs_file_strict_mmap,
        .splice_read = generic_file_splice_read,
        .llseek = cifs_llseek,
-#ifdef CONFIG_CIFS_POSIX
        .unlocked_ioctl = cifs_ioctl,
-#endif /* CONFIG_CIFS_POSIX */
        .setlease = cifs_setlease,
        .fallocate = cifs_fallocate,
 };
@@ -957,9 +957,7 @@ const struct file_operations cifs_file_direct_ops = {
        .flush = cifs_flush,
        .mmap = cifs_file_mmap,
        .splice_read = generic_file_splice_read,
-#ifdef CONFIG_CIFS_POSIX
        .unlocked_ioctl  = cifs_ioctl,
-#endif /* CONFIG_CIFS_POSIX */
        .llseek = cifs_llseek,
        .setlease = cifs_setlease,
        .fallocate = cifs_fallocate,
@@ -975,9 +973,7 @@ const struct file_operations cifs_file_nobrl_ops = {
        .mmap  = cifs_file_mmap,
        .splice_read = generic_file_splice_read,
        .llseek = cifs_llseek,
-#ifdef CONFIG_CIFS_POSIX
        .unlocked_ioctl = cifs_ioctl,
-#endif /* CONFIG_CIFS_POSIX */
        .setlease = cifs_setlease,
        .fallocate = cifs_fallocate,
 };
@@ -992,9 +988,7 @@ const struct file_operations cifs_file_strict_nobrl_ops = {
        .mmap = cifs_file_strict_mmap,
        .splice_read = generic_file_splice_read,
        .llseek = cifs_llseek,
-#ifdef CONFIG_CIFS_POSIX
        .unlocked_ioctl = cifs_ioctl,
-#endif /* CONFIG_CIFS_POSIX */
        .setlease = cifs_setlease,
        .fallocate = cifs_fallocate,
 };
@@ -1009,9 +1003,7 @@ const struct file_operations cifs_file_direct_nobrl_ops = {
        .flush = cifs_flush,
        .mmap = cifs_file_mmap,
        .splice_read = generic_file_splice_read,
-#ifdef CONFIG_CIFS_POSIX
        .unlocked_ioctl  = cifs_ioctl,
-#endif /* CONFIG_CIFS_POSIX */
        .llseek = cifs_llseek,
        .setlease = cifs_setlease,
        .fallocate = cifs_fallocate,
index b406a32deb1f6bf2f9e8d416bc019a71f589d8db..2b510c537a0d588c532fe9200cdd4a9b03a4c9f4 100644 (file)
@@ -493,7 +493,10 @@ struct smb_vol {
        bool mfsymlinks:1; /* use Minshall+French Symlinks */
        bool multiuser:1;
        bool rwpidforward:1; /* pid forward for read/write operations */
-       bool nosharesock;
+       bool nosharesock:1;
+       bool persistent:1;
+       bool nopersistent:1;
+       bool resilient:1; /* noresilient not required since not fored for CA */
        unsigned int rsize;
        unsigned int wsize;
        bool sockopt_tcp_nodelay:1;
@@ -895,6 +898,8 @@ struct cifs_tcon {
        bool broken_posix_open; /* e.g. Samba server versions < 3.3.2, 3.2.9 */
        bool broken_sparse_sup; /* if server or share does not support sparse */
        bool need_reconnect:1; /* connection reset, tid now invalid */
+       bool use_resilient:1; /* use resilient instead of durable handles */
+       bool use_persistent:1; /* use persistent instead of durable handles */
 #ifdef CONFIG_CIFS_SMB2
        bool print:1;           /* set if connection to printer share */
        bool bad_network_name:1; /* set if ret status STATUS_BAD_NETWORK_NAME */
@@ -1015,6 +1020,7 @@ struct cifs_fid {
        __u64 persistent_fid;   /* persist file id for smb2 */
        __u64 volatile_fid;     /* volatile file id for smb2 */
        __u8 lease_key[SMB2_LEASE_KEY_SIZE];    /* lease key for smb2 */
+       __u8 create_guid[16];
 #endif
        struct cifs_pending_open *pending_open;
        unsigned int epoch;
index 3f2228570d441840b7e6d11c10a3b814a2b60962..ecb0803bdb0e50479f50b0e874a4e87cb064e2d0 100644 (file)
@@ -87,6 +87,8 @@ enum {
        Opt_sign, Opt_seal, Opt_noac,
        Opt_fsc, Opt_mfsymlinks,
        Opt_multiuser, Opt_sloppy, Opt_nosharesock,
+       Opt_persistent, Opt_nopersistent,
+       Opt_resilient, Opt_noresilient,
 
        /* Mount options which take numeric value */
        Opt_backupuid, Opt_backupgid, Opt_uid,
@@ -169,6 +171,10 @@ static const match_table_t cifs_mount_option_tokens = {
        { Opt_multiuser, "multiuser" },
        { Opt_sloppy, "sloppy" },
        { Opt_nosharesock, "nosharesock" },
+       { Opt_persistent, "persistenthandles"},
+       { Opt_nopersistent, "nopersistenthandles"},
+       { Opt_resilient, "resilienthandles"},
+       { Opt_noresilient, "noresilienthandles"},
 
        { Opt_backupuid, "backupuid=%s" },
        { Opt_backupgid, "backupgid=%s" },
@@ -1497,6 +1503,33 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                case Opt_nosharesock:
                        vol->nosharesock = true;
                        break;
+               case Opt_nopersistent:
+                       vol->nopersistent = true;
+                       if (vol->persistent) {
+                               cifs_dbg(VFS,
+                                 "persistenthandles mount options conflict\n");
+                               goto cifs_parse_mount_err;
+                       }
+                       break;
+               case Opt_persistent:
+                       vol->persistent = true;
+                       if ((vol->nopersistent) || (vol->resilient)) {
+                               cifs_dbg(VFS,
+                                 "persistenthandles mount options conflict\n");
+                               goto cifs_parse_mount_err;
+                       }
+                       break;
+               case Opt_resilient:
+                       vol->resilient = true;
+                       if (vol->persistent) {
+                               cifs_dbg(VFS,
+                                 "persistenthandles mount options conflict\n");
+                               goto cifs_parse_mount_err;
+                       }
+                       break;
+               case Opt_noresilient:
+                       vol->resilient = false; /* already the default */
+                       break;
 
                /* Numeric Values */
                case Opt_backupuid:
@@ -2655,6 +2688,42 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
                cifs_dbg(FYI, "DFS disabled (%d)\n", tcon->Flags);
        }
        tcon->seal = volume_info->seal;
+       tcon->use_persistent = false;
+       /* check if SMB2 or later, CIFS does not support persistent handles */
+       if (volume_info->persistent) {
+               if (ses->server->vals->protocol_id == 0) {
+                       cifs_dbg(VFS,
+                            "SMB3 or later required for persistent handles\n");
+                       rc = -EOPNOTSUPP;
+                       goto out_fail;
+#ifdef CONFIG_CIFS_SMB2
+               } else if (ses->server->capabilities &
+                          SMB2_GLOBAL_CAP_PERSISTENT_HANDLES)
+                       tcon->use_persistent = true;
+               else /* persistent handles requested but not supported */ {
+                       cifs_dbg(VFS,
+                               "Persistent handles not supported on share\n");
+                       rc = -EOPNOTSUPP;
+                       goto out_fail;
+#endif /* CONFIG_CIFS_SMB2 */
+               }
+#ifdef CONFIG_CIFS_SMB2
+       } else if ((tcon->capabilities & SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY)
+            && (ses->server->capabilities & SMB2_GLOBAL_CAP_PERSISTENT_HANDLES)
+            && (volume_info->nopersistent == false)) {
+               cifs_dbg(FYI, "enabling persistent handles\n");
+               tcon->use_persistent = true;
+#endif /* CONFIG_CIFS_SMB2 */
+       } else if (volume_info->resilient) {
+               if (ses->server->vals->protocol_id == 0) {
+                       cifs_dbg(VFS,
+                            "SMB2.1 or later required for resilient handles\n");
+                       rc = -EOPNOTSUPP;
+                       goto out_fail;
+               }
+               tcon->use_resilient = true;
+       }
+
        /*
         * We can have only one retry value for a connection to a share so for
         * resources mounted more than once to the same server share the last
@@ -3503,6 +3572,15 @@ try_mount_again:
                goto mount_fail_check;
        }
 
+#ifdef CONFIG_CIFS_SMB2
+       if ((volume_info->persistent == true) && ((ses->server->capabilities &
+               SMB2_GLOBAL_CAP_PERSISTENT_HANDLES) == 0)) {
+               cifs_dbg(VFS, "persistent handles not supported by server\n");
+               rc = -EOPNOTSUPP;
+               goto mount_fail_check;
+       }
+#endif /* CONFIG_CIFS_SMB2*/
+
        /* search for existing tcon to this server share */
        tcon = cifs_get_tcon(ses, volume_info);
        if (IS_ERR(tcon)) {
index 28a77bf1d55924693d27d1c701571e1b1fef2d49..35cf990f87d3245d01662cc550f4f3b43cc2dc58 100644 (file)
@@ -85,9 +85,14 @@ static long cifs_ioctl_clone(unsigned int xid, struct file *dst_file,
        src_tcon = tlink_tcon(smb_file_src->tlink);
        target_tcon = tlink_tcon(smb_file_target->tlink);
 
-       /* check if source and target are on same tree connection */
-       if (src_tcon != target_tcon) {
-               cifs_dbg(VFS, "file copy src and target on different volume\n");
+       /* check source and target on same server (or volume if dup_extents) */
+       if (dup_extents && (src_tcon != target_tcon)) {
+               cifs_dbg(VFS, "source and target of copy not on same share\n");
+               goto out_fput;
+       }
+
+       if (!dup_extents && (src_tcon->ses != target_tcon->ses)) {
+               cifs_dbg(VFS, "source and target of copy not on same server\n");
                goto out_fput;
        }
 
index 2ab297dae5a7b2b4e544e3f35abc5f09b9fa7b1d..f9e766f464beec408b628146c4e0d4e04010e0f2 100644 (file)
@@ -43,6 +43,7 @@ smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms,
        struct smb2_file_all_info *smb2_data = NULL;
        __u8 smb2_oplock[17];
        struct cifs_fid *fid = oparms->fid;
+       struct network_resiliency_req nr_ioctl_req;
 
        smb2_path = cifs_convert_path_to_utf16(oparms->path, oparms->cifs_sb);
        if (smb2_path == NULL) {
@@ -67,6 +68,24 @@ smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms,
        if (rc)
                goto out;
 
+
+        if (oparms->tcon->use_resilient) {
+               nr_ioctl_req.Timeout = 0; /* use server default (120 seconds) */
+               nr_ioctl_req.Reserved = 0;
+               rc = SMB2_ioctl(xid, oparms->tcon, fid->persistent_fid,
+                       fid->volatile_fid, FSCTL_LMR_REQUEST_RESILIENCY, true,
+                       (char *)&nr_ioctl_req, sizeof(nr_ioctl_req),
+                       NULL, NULL /* no return info */);
+               if (rc == -EOPNOTSUPP) {
+                       cifs_dbg(VFS,
+                            "resiliency not supported by server, disabling\n");
+                       oparms->tcon->use_resilient = false;
+               } else if (rc)
+                       cifs_dbg(FYI, "error %d setting resiliency\n", rc);
+
+               rc = 0;
+       }
+
        if (buf) {
                /* open response does not have IndexNumber field - get it */
                rc = SMB2_get_srv_num(xid, oparms->tcon, fid->persistent_fid,
index 18da19f4f811ed19c327ab44a706e66c3a339bb0..53ccdde6ff187c16084e10dd07372d6516d25139 100644 (file)
@@ -810,7 +810,6 @@ smb2_set_file_size(const unsigned int xid, struct cifs_tcon *tcon,
                            cfile->fid.volatile_fid, cfile->pid, &eof, false);
 }
 
-#ifdef CONFIG_CIFS_SMB311
 static int
 smb2_duplicate_extents(const unsigned int xid,
                        struct cifsFileInfo *srcfile,
@@ -854,8 +853,6 @@ smb2_duplicate_extents(const unsigned int xid,
 duplicate_extents_out:
        return rc;
 }
-#endif /* CONFIG_CIFS_SMB311 */
-
 
 static int
 smb2_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
@@ -1703,6 +1700,7 @@ struct smb_version_operations smb30_operations = {
        .create_lease_buf = smb3_create_lease_buf,
        .parse_lease_buf = smb3_parse_lease_buf,
        .clone_range = smb2_clone_range,
+       .duplicate_extents = smb2_duplicate_extents,
        .validate_negotiate = smb3_validate_negotiate,
        .wp_retry_size = smb2_wp_retry_size,
        .dir_needs_close = smb2_dir_needs_close,
@@ -1840,7 +1838,7 @@ struct smb_version_values smb21_values = {
 struct smb_version_values smb30_values = {
        .version_string = SMB30_VERSION_STRING,
        .protocol_id = SMB30_PROT_ID,
-       .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU,
+       .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES,
        .large_lock_type = 0,
        .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
        .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
@@ -1860,7 +1858,7 @@ struct smb_version_values smb30_values = {
 struct smb_version_values smb302_values = {
        .version_string = SMB302_VERSION_STRING,
        .protocol_id = SMB302_PROT_ID,
-       .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU,
+       .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES,
        .large_lock_type = 0,
        .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
        .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
@@ -1881,7 +1879,7 @@ struct smb_version_values smb302_values = {
 struct smb_version_values smb311_values = {
        .version_string = SMB311_VERSION_STRING,
        .protocol_id = SMB311_PROT_ID,
-       .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU,
+       .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES,
        .large_lock_type = 0,
        .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
        .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
index 61276929d139f64d1309481e69f2dfce2c8f1fe5..767555518d40ccd357b6f5540f2758bb8be6e654 100644 (file)
@@ -1151,13 +1151,130 @@ add_lease_context(struct TCP_Server_Info *server, struct kvec *iov,
        return 0;
 }
 
+static struct create_durable_v2 *
+create_durable_v2_buf(struct cifs_fid *pfid)
+{
+       struct create_durable_v2 *buf;
+
+       buf = kzalloc(sizeof(struct create_durable_v2), GFP_KERNEL);
+       if (!buf)
+               return NULL;
+
+       buf->ccontext.DataOffset = cpu_to_le16(offsetof
+                                       (struct create_durable_v2, dcontext));
+       buf->ccontext.DataLength = cpu_to_le32(sizeof(struct durable_context_v2));
+       buf->ccontext.NameOffset = cpu_to_le16(offsetof
+                               (struct create_durable_v2, Name));
+       buf->ccontext.NameLength = cpu_to_le16(4);
+
+       buf->dcontext.Timeout = 0; /* Should this be configurable by workload */
+       buf->dcontext.Flags = cpu_to_le32(SMB2_DHANDLE_FLAG_PERSISTENT);
+       get_random_bytes(buf->dcontext.CreateGuid, 16);
+       memcpy(pfid->create_guid, buf->dcontext.CreateGuid, 16);
+
+       /* SMB2_CREATE_DURABLE_HANDLE_REQUEST is "DH2Q" */
+       buf->Name[0] = 'D';
+       buf->Name[1] = 'H';
+       buf->Name[2] = '2';
+       buf->Name[3] = 'Q';
+       return buf;
+}
+
+static struct create_durable_handle_reconnect_v2 *
+create_reconnect_durable_v2_buf(struct cifs_fid *fid)
+{
+       struct create_durable_handle_reconnect_v2 *buf;
+
+       buf = kzalloc(sizeof(struct create_durable_handle_reconnect_v2),
+                       GFP_KERNEL);
+       if (!buf)
+               return NULL;
+
+       buf->ccontext.DataOffset =
+               cpu_to_le16(offsetof(struct create_durable_handle_reconnect_v2,
+                                    dcontext));
+       buf->ccontext.DataLength =
+               cpu_to_le32(sizeof(struct durable_reconnect_context_v2));
+       buf->ccontext.NameOffset =
+               cpu_to_le16(offsetof(struct create_durable_handle_reconnect_v2,
+                           Name));
+       buf->ccontext.NameLength = cpu_to_le16(4);
+
+       buf->dcontext.Fid.PersistentFileId = fid->persistent_fid;
+       buf->dcontext.Fid.VolatileFileId = fid->volatile_fid;
+       buf->dcontext.Flags = cpu_to_le32(SMB2_DHANDLE_FLAG_PERSISTENT);
+       memcpy(buf->dcontext.CreateGuid, fid->create_guid, 16);
+
+       /* SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 is "DH2C" */
+       buf->Name[0] = 'D';
+       buf->Name[1] = 'H';
+       buf->Name[2] = '2';
+       buf->Name[3] = 'C';
+       return buf;
+}
+
 static int
-add_durable_context(struct kvec *iov, unsigned int *num_iovec,
+add_durable_v2_context(struct kvec *iov, unsigned int *num_iovec,
                    struct cifs_open_parms *oparms)
 {
        struct smb2_create_req *req = iov[0].iov_base;
        unsigned int num = *num_iovec;
 
+       iov[num].iov_base = create_durable_v2_buf(oparms->fid);
+       if (iov[num].iov_base == NULL)
+               return -ENOMEM;
+       iov[num].iov_len = sizeof(struct create_durable_v2);
+       if (!req->CreateContextsOffset)
+               req->CreateContextsOffset =
+                       cpu_to_le32(sizeof(struct smb2_create_req) - 4 +
+                                                               iov[1].iov_len);
+       le32_add_cpu(&req->CreateContextsLength, sizeof(struct create_durable_v2));
+       inc_rfc1001_len(&req->hdr, sizeof(struct create_durable_v2));
+       *num_iovec = num + 1;
+       return 0;
+}
+
+static int
+add_durable_reconnect_v2_context(struct kvec *iov, unsigned int *num_iovec,
+                   struct cifs_open_parms *oparms)
+{
+       struct smb2_create_req *req = iov[0].iov_base;
+       unsigned int num = *num_iovec;
+
+       /* indicate that we don't need to relock the file */
+       oparms->reconnect = false;
+
+       iov[num].iov_base = create_reconnect_durable_v2_buf(oparms->fid);
+       if (iov[num].iov_base == NULL)
+               return -ENOMEM;
+       iov[num].iov_len = sizeof(struct create_durable_handle_reconnect_v2);
+       if (!req->CreateContextsOffset)
+               req->CreateContextsOffset =
+                       cpu_to_le32(sizeof(struct smb2_create_req) - 4 +
+                                                               iov[1].iov_len);
+       le32_add_cpu(&req->CreateContextsLength,
+                       sizeof(struct create_durable_handle_reconnect_v2));
+       inc_rfc1001_len(&req->hdr,
+                       sizeof(struct create_durable_handle_reconnect_v2));
+       *num_iovec = num + 1;
+       return 0;
+}
+
+static int
+add_durable_context(struct kvec *iov, unsigned int *num_iovec,
+                   struct cifs_open_parms *oparms, bool use_persistent)
+{
+       struct smb2_create_req *req = iov[0].iov_base;
+       unsigned int num = *num_iovec;
+
+       if (use_persistent) {
+               if (oparms->reconnect)
+                       return add_durable_reconnect_v2_context(iov, num_iovec,
+                                                               oparms);
+               else
+                       return add_durable_v2_context(iov, num_iovec, oparms);
+       }
+
        if (oparms->reconnect) {
                iov[num].iov_base = create_reconnect_durable_buf(oparms->fid);
                /* indicate that we don't need to relock the file */
@@ -1275,7 +1392,9 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
                        ccontext->Next =
                                cpu_to_le32(server->vals->create_lease_size);
                }
-               rc = add_durable_context(iov, &num_iovecs, oparms);
+
+               rc = add_durable_context(iov, &num_iovecs, oparms,
+                                       tcon->use_persistent);
                if (rc) {
                        cifs_small_buf_release(req);
                        kfree(copy_path);
index 451108284a2f438203568d90749f149ea567a602..4af52780ec350323cd41e993389e7214fb50f97d 100644 (file)
@@ -590,6 +590,44 @@ struct create_durable {
        } Data;
 } __packed;
 
+/* See MS-SMB2 2.2.13.2.11 */
+/* Flags */
+#define SMB2_DHANDLE_FLAG_PERSISTENT   0x00000002
+struct durable_context_v2 {
+       __le32 Timeout;
+       __le32 Flags;
+       __u64 Reserved;
+       __u8 CreateGuid[16];
+} __packed;
+
+struct create_durable_v2 {
+       struct create_context ccontext;
+       __u8   Name[8];
+       struct durable_context_v2 dcontext;
+} __packed;
+
+/* See MS-SMB2 2.2.13.2.12 */
+struct durable_reconnect_context_v2 {
+       struct {
+               __u64 PersistentFileId;
+               __u64 VolatileFileId;
+       } Fid;
+       __u8 CreateGuid[16];
+       __le32 Flags; /* see above DHANDLE_FLAG_PERSISTENT */
+} __packed;
+
+/* See MS-SMB2 2.2.14.2.12 */
+struct durable_reconnect_context_v2_rsp {
+       __le32 Timeout;
+       __le32 Flags; /* see above DHANDLE_FLAG_PERSISTENT */
+} __packed;
+
+struct create_durable_handle_reconnect_v2 {
+       struct create_context ccontext;
+       __u8   Name[8];
+       struct durable_reconnect_context_v2 dcontext;
+} __packed;
+
 #define COPY_CHUNK_RES_KEY_SIZE        24
 struct resume_key_req {
        char ResumeKey[COPY_CHUNK_RES_KEY_SIZE];
@@ -643,6 +681,13 @@ struct fsctl_get_integrity_information_rsp {
 /* Integrity flags for above */
 #define FSCTL_INTEGRITY_FLAG_CHECKSUM_ENFORCEMENT_OFF  0x00000001
 
+/* See MS-SMB2 2.2.31.3 */
+struct network_resiliency_req {
+       __le32 Timeout;
+       __le32 Reserved;
+} __packed;
+/* There is no buffer for the response ie no struct network_resiliency_rsp */
+
 
 struct validate_negotiate_info_req {
        __le32 Capabilities;
index a639d0dab453373f4ae5dd2e2a6ee63f3867176d..f996daeea271142ede2bcb476226c66b1fe31f87 100644 (file)
@@ -90,7 +90,7 @@
 #define FSCTL_SRV_ENUMERATE_SNAPSHOTS 0x00144064
 /* Retrieve an opaque file reference for server-side data movement ie copy */
 #define FSCTL_SRV_REQUEST_RESUME_KEY 0x00140078
-#define FSCTL_LMR_REQUEST_RESILIENCY 0x001401D4 /* BB add struct */
+#define FSCTL_LMR_REQUEST_RESILIENCY 0x001401D4
 #define FSCTL_LMR_GET_LINK_TRACK_INF 0x001400E8 /* BB add struct */
 #define FSCTL_LMR_SET_LINK_TRACK_INF 0x001400EC /* BB add struct */
 #define FSCTL_VALIDATE_NEGOTIATE_INFO 0x00140204
index 403269ffcdf3518b45f878166270c12e3365c17e..d39099ea7df76d723e4501c316eb43352b11e69c 100644 (file)
@@ -65,7 +65,6 @@ static int fill_read_buffer(struct dentry * dentry, struct configfs_buffer * buf
 {
        struct configfs_attribute * attr = to_attr(dentry);
        struct config_item * item = to_item(dentry->d_parent);
-       struct configfs_item_operations * ops = buffer->ops;
        int ret = 0;
        ssize_t count;
 
@@ -74,7 +73,8 @@ static int fill_read_buffer(struct dentry * dentry, struct configfs_buffer * buf
        if (!buffer->page)
                return -ENOMEM;
 
-       count = ops->show_attribute(item,attr,buffer->page);
+       count = attr->show(item, buffer->page);
+
        buffer->needs_read_fill = 0;
        BUG_ON(count > (ssize_t)SIMPLE_ATTR_SIZE);
        if (count >= 0)
@@ -171,9 +171,8 @@ flush_write_buffer(struct dentry * dentry, struct configfs_buffer * buffer, size
 {
        struct configfs_attribute * attr = to_attr(dentry);
        struct config_item * item = to_item(dentry->d_parent);
-       struct configfs_item_operations * ops = buffer->ops;
 
-       return ops->store_attribute(item,attr,buffer->page,count);
+       return attr->store(item, buffer->page, count);
 }
 
 
@@ -237,8 +236,7 @@ static int check_perm(struct inode * inode, struct file * file)
         * and we must have a store method.
         */
        if (file->f_mode & FMODE_WRITE) {
-
-               if (!(inode->i_mode & S_IWUGO) || !ops->store_attribute)
+               if (!(inode->i_mode & S_IWUGO) || !attr->store)
                        goto Eaccess;
 
        }
@@ -248,7 +246,7 @@ static int check_perm(struct inode * inode, struct file * file)
         * must be a show method for it.
         */
        if (file->f_mode & FMODE_READ) {
-               if (!(inode->i_mode & S_IRUGO) || !ops->show_attribute)
+               if (!(inode->i_mode & S_IRUGO) || !attr->show)
                        goto Eaccess;
        }
 
index a86d3cc2b38941b0e39f23be84e4986d8852ae42..d1e5cb7311a1de295ecd4348360a9a9947e71142 100644 (file)
--- a/fs/dax.c
+++ b/fs/dax.c
 #include <linux/uio.h>
 #include <linux/vmstat.h>
 
+/*
+ * dax_clear_blocks() is called from within transaction context from XFS,
+ * and hence this means the stack from this point must follow GFP_NOFS
+ * semantics for all operations.
+ */
 int dax_clear_blocks(struct inode *inode, sector_t block, long size)
 {
        struct block_device *bdev = inode->i_sb->s_bdev;
@@ -169,8 +174,10 @@ static ssize_t dax_io(struct inode *inode, struct iov_iter *iter,
                else
                        len = iov_iter_zero(max - pos, iter);
 
-               if (!len)
+               if (!len) {
+                       retval = -EFAULT;
                        break;
+               }
 
                pos += len;
                addr += len;
@@ -622,6 +629,13 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address,
                if ((length < PMD_SIZE) || (pfn & PG_PMD_COLOUR))
                        goto fallback;
 
+               /*
+                * TODO: teach vmf_insert_pfn_pmd() to support
+                * 'pte_special' for pmds
+                */
+               if (pfn_valid(pfn))
+                       goto fallback;
+
                if (buffer_unwritten(&bh) || buffer_new(&bh)) {
                        int i;
                        for (i = 0; i < PTRS_PER_PMD; i++)
index 5d8f35f1382ab11032f50dcd7029c40f5adf2159..b7fcc0de0b2f2771aff08a130eb20564adb3cbd4 100644 (file)
@@ -271,8 +271,12 @@ static struct dentry *start_creating(const char *name, struct dentry *parent)
                dput(dentry);
                dentry = ERR_PTR(-EEXIST);
        }
-       if (IS_ERR(dentry))
+
+       if (IS_ERR(dentry)) {
                mutex_unlock(&d_inode(parent)->i_mutex);
+               simple_release_fs(&debugfs_mount, &debugfs_mount_count);
+       }
+
        return dentry;
 }
 
index d521bddf876dce012927937f83546db31a3426e7..8e294fbbac392c9bacdc6ee886be7ba3e80cd070 100644 (file)
@@ -61,35 +61,8 @@ static struct config_item *make_node(struct config_group *, const char *);
 static void drop_node(struct config_group *, struct config_item *);
 static void release_node(struct config_item *);
 
-static ssize_t show_cluster(struct config_item *i, struct configfs_attribute *a,
-                           char *buf);
-static ssize_t store_cluster(struct config_item *i,
-                            struct configfs_attribute *a,
-                            const char *buf, size_t len);
-static ssize_t show_comm(struct config_item *i, struct configfs_attribute *a,
-                        char *buf);
-static ssize_t store_comm(struct config_item *i, struct configfs_attribute *a,
-                         const char *buf, size_t len);
-static ssize_t show_node(struct config_item *i, struct configfs_attribute *a,
-                        char *buf);
-static ssize_t store_node(struct config_item *i, struct configfs_attribute *a,
-                         const char *buf, size_t len);
-
-static ssize_t comm_nodeid_read(struct dlm_comm *cm, char *buf);
-static ssize_t comm_nodeid_write(struct dlm_comm *cm, const char *buf,
-                               size_t len);
-static ssize_t comm_local_read(struct dlm_comm *cm, char *buf);
-static ssize_t comm_local_write(struct dlm_comm *cm, const char *buf,
-                               size_t len);
-static ssize_t comm_addr_write(struct dlm_comm *cm, const char *buf,
-                               size_t len);
-static ssize_t comm_addr_list_read(struct dlm_comm *cm, char *buf);
-static ssize_t node_nodeid_read(struct dlm_node *nd, char *buf);
-static ssize_t node_nodeid_write(struct dlm_node *nd, const char *buf,
-                               size_t len);
-static ssize_t node_weight_read(struct dlm_node *nd, char *buf);
-static ssize_t node_weight_write(struct dlm_node *nd, const char *buf,
-                               size_t len);
+static struct configfs_attribute *comm_attrs[];
+static struct configfs_attribute *node_attrs[];
 
 struct dlm_cluster {
        struct config_group group;
@@ -108,6 +81,12 @@ struct dlm_cluster {
        char cl_cluster_name[DLM_LOCKSPACE_LEN];
 };
 
+static struct dlm_cluster *config_item_to_cluster(struct config_item *i)
+{
+       return i ? container_of(to_config_group(i), struct dlm_cluster, group) :
+                  NULL;
+}
+
 enum {
        CLUSTER_ATTR_TCP_PORT = 0,
        CLUSTER_ATTR_BUFFER_SIZE,
@@ -124,33 +103,24 @@ enum {
        CLUSTER_ATTR_CLUSTER_NAME,
 };
 
-struct cluster_attribute {
-       struct configfs_attribute attr;
-       ssize_t (*show)(struct dlm_cluster *, char *);
-       ssize_t (*store)(struct dlm_cluster *, const char *, size_t);
-};
-
-static ssize_t cluster_cluster_name_read(struct dlm_cluster *cl, char *buf)
+static ssize_t cluster_cluster_name_show(struct config_item *item, char *buf)
 {
+       struct dlm_cluster *cl = config_item_to_cluster(item);
        return sprintf(buf, "%s\n", cl->cl_cluster_name);
 }
 
-static ssize_t cluster_cluster_name_write(struct dlm_cluster *cl,
+static ssize_t cluster_cluster_name_store(struct config_item *item,
                                          const char *buf, size_t len)
 {
+       struct dlm_cluster *cl = config_item_to_cluster(item);
+
        strlcpy(dlm_config.ci_cluster_name, buf,
                                sizeof(dlm_config.ci_cluster_name));
        strlcpy(cl->cl_cluster_name, buf, sizeof(cl->cl_cluster_name));
        return len;
 }
 
-static struct cluster_attribute cluster_attr_cluster_name = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                    .ca_name = "cluster_name",
-                    .ca_mode = S_IRUGO | S_IWUSR },
-       .show   = cluster_cluster_name_read,
-       .store  = cluster_cluster_name_write,
-};
+CONFIGFS_ATTR(cluster_, cluster_name);
 
 static ssize_t cluster_set(struct dlm_cluster *cl, unsigned int *cl_field,
                           int *info_field, int check_zero,
@@ -175,17 +145,19 @@ static ssize_t cluster_set(struct dlm_cluster *cl, unsigned int *cl_field,
 }
 
 #define CLUSTER_ATTR(name, check_zero)                                        \
-static ssize_t name##_write(struct dlm_cluster *cl, const char *buf, size_t len) \
+static ssize_t cluster_##name##_store(struct config_item *item, \
+               const char *buf, size_t len) \
 {                                                                             \
+       struct dlm_cluster *cl = config_item_to_cluster(item);                \
        return cluster_set(cl, &cl->cl_##name, &dlm_config.ci_##name,         \
                           check_zero, buf, len);                             \
 }                                                                             \
-static ssize_t name##_read(struct dlm_cluster *cl, char *buf)                 \
+static ssize_t cluster_##name##_show(struct config_item *item, char *buf)     \
 {                                                                             \
+       struct dlm_cluster *cl = config_item_to_cluster(item);                \
        return snprintf(buf, PAGE_SIZE, "%u\n", cl->cl_##name);               \
 }                                                                             \
-static struct cluster_attribute cluster_attr_##name =                         \
-__CONFIGFS_ATTR(name, 0644, name##_read, name##_write)
+CONFIGFS_ATTR(cluster_, name);
 
 CLUSTER_ATTR(tcp_port, 1);
 CLUSTER_ATTR(buffer_size, 1);
@@ -201,19 +173,19 @@ CLUSTER_ATTR(new_rsb_count, 0);
 CLUSTER_ATTR(recover_callbacks, 0);
 
 static struct configfs_attribute *cluster_attrs[] = {
-       [CLUSTER_ATTR_TCP_PORT] = &cluster_attr_tcp_port.attr,
-       [CLUSTER_ATTR_BUFFER_SIZE] = &cluster_attr_buffer_size.attr,
-       [CLUSTER_ATTR_RSBTBL_SIZE] = &cluster_attr_rsbtbl_size.attr,
-       [CLUSTER_ATTR_RECOVER_TIMER] = &cluster_attr_recover_timer.attr,
-       [CLUSTER_ATTR_TOSS_SECS] = &cluster_attr_toss_secs.attr,
-       [CLUSTER_ATTR_SCAN_SECS] = &cluster_attr_scan_secs.attr,
-       [CLUSTER_ATTR_LOG_DEBUG] = &cluster_attr_log_debug.attr,
-       [CLUSTER_ATTR_PROTOCOL] = &cluster_attr_protocol.attr,
-       [CLUSTER_ATTR_TIMEWARN_CS] = &cluster_attr_timewarn_cs.attr,
-       [CLUSTER_ATTR_WAITWARN_US] = &cluster_attr_waitwarn_us.attr,
-       [CLUSTER_ATTR_NEW_RSB_COUNT] = &cluster_attr_new_rsb_count.attr,
-       [CLUSTER_ATTR_RECOVER_CALLBACKS] = &cluster_attr_recover_callbacks.attr,
-       [CLUSTER_ATTR_CLUSTER_NAME] = &cluster_attr_cluster_name.attr,
+       [CLUSTER_ATTR_TCP_PORT] = &cluster_attr_tcp_port,
+       [CLUSTER_ATTR_BUFFER_SIZE] = &cluster_attr_buffer_size,
+       [CLUSTER_ATTR_RSBTBL_SIZE] = &cluster_attr_rsbtbl_size,
+       [CLUSTER_ATTR_RECOVER_TIMER] = &cluster_attr_recover_timer,
+       [CLUSTER_ATTR_TOSS_SECS] = &cluster_attr_toss_secs,
+       [CLUSTER_ATTR_SCAN_SECS] = &cluster_attr_scan_secs,
+       [CLUSTER_ATTR_LOG_DEBUG] = &cluster_attr_log_debug,
+       [CLUSTER_ATTR_PROTOCOL] = &cluster_attr_protocol,
+       [CLUSTER_ATTR_TIMEWARN_CS] = &cluster_attr_timewarn_cs,
+       [CLUSTER_ATTR_WAITWARN_US] = &cluster_attr_waitwarn_us,
+       [CLUSTER_ATTR_NEW_RSB_COUNT] = &cluster_attr_new_rsb_count,
+       [CLUSTER_ATTR_RECOVER_CALLBACKS] = &cluster_attr_recover_callbacks,
+       [CLUSTER_ATTR_CLUSTER_NAME] = &cluster_attr_cluster_name,
        NULL,
 };
 
@@ -224,83 +196,11 @@ enum {
        COMM_ATTR_ADDR_LIST,
 };
 
-struct comm_attribute {
-       struct configfs_attribute attr;
-       ssize_t (*show)(struct dlm_comm *, char *);
-       ssize_t (*store)(struct dlm_comm *, const char *, size_t);
-};
-
-static struct comm_attribute comm_attr_nodeid = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                    .ca_name = "nodeid",
-                    .ca_mode = S_IRUGO | S_IWUSR },
-       .show   = comm_nodeid_read,
-       .store  = comm_nodeid_write,
-};
-
-static struct comm_attribute comm_attr_local = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                    .ca_name = "local",
-                    .ca_mode = S_IRUGO | S_IWUSR },
-       .show   = comm_local_read,
-       .store  = comm_local_write,
-};
-
-static struct comm_attribute comm_attr_addr = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                    .ca_name = "addr",
-                    .ca_mode = S_IWUSR },
-       .store  = comm_addr_write,
-};
-
-static struct comm_attribute comm_attr_addr_list = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                    .ca_name = "addr_list",
-                    .ca_mode = S_IRUGO },
-       .show   = comm_addr_list_read,
-};
-
-static struct configfs_attribute *comm_attrs[] = {
-       [COMM_ATTR_NODEID] = &comm_attr_nodeid.attr,
-       [COMM_ATTR_LOCAL] = &comm_attr_local.attr,
-       [COMM_ATTR_ADDR] = &comm_attr_addr.attr,
-       [COMM_ATTR_ADDR_LIST] = &comm_attr_addr_list.attr,
-       NULL,
-};
-
 enum {
        NODE_ATTR_NODEID = 0,
        NODE_ATTR_WEIGHT,
 };
 
-struct node_attribute {
-       struct configfs_attribute attr;
-       ssize_t (*show)(struct dlm_node *, char *);
-       ssize_t (*store)(struct dlm_node *, const char *, size_t);
-};
-
-static struct node_attribute node_attr_nodeid = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                    .ca_name = "nodeid",
-                    .ca_mode = S_IRUGO | S_IWUSR },
-       .show   = node_nodeid_read,
-       .store  = node_nodeid_write,
-};
-
-static struct node_attribute node_attr_weight = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                    .ca_name = "weight",
-                    .ca_mode = S_IRUGO | S_IWUSR },
-       .show   = node_weight_read,
-       .store  = node_weight_write,
-};
-
-static struct configfs_attribute *node_attrs[] = {
-       [NODE_ATTR_NODEID] = &node_attr_nodeid.attr,
-       [NODE_ATTR_WEIGHT] = &node_attr_weight.attr,
-       NULL,
-};
-
 struct dlm_clusters {
        struct configfs_subsystem subsys;
 };
@@ -349,8 +249,6 @@ static struct configfs_group_operations clusters_ops = {
 
 static struct configfs_item_operations cluster_ops = {
        .release = release_cluster,
-       .show_attribute = show_cluster,
-       .store_attribute = store_cluster,
 };
 
 static struct configfs_group_operations spaces_ops = {
@@ -369,8 +267,6 @@ static struct configfs_group_operations comms_ops = {
 
 static struct configfs_item_operations comm_ops = {
        .release = release_comm,
-       .show_attribute = show_comm,
-       .store_attribute = store_comm,
 };
 
 static struct configfs_group_operations nodes_ops = {
@@ -380,8 +276,6 @@ static struct configfs_group_operations nodes_ops = {
 
 static struct configfs_item_operations node_ops = {
        .release = release_node,
-       .show_attribute = show_node,
-       .store_attribute = store_node,
 };
 
 static struct config_item_type clusters_type = {
@@ -427,12 +321,6 @@ static struct config_item_type node_type = {
        .ct_owner = THIS_MODULE,
 };
 
-static struct dlm_cluster *config_item_to_cluster(struct config_item *i)
-{
-       return i ? container_of(to_config_group(i), struct dlm_cluster, group) :
-                  NULL;
-}
-
 static struct dlm_space *config_item_to_space(struct config_item *i)
 {
        return i ? container_of(to_config_group(i), struct dlm_space, group) :
@@ -687,66 +575,30 @@ void dlm_config_exit(void)
  * Functions for user space to read/write attributes
  */
 
-static ssize_t show_cluster(struct config_item *i, struct configfs_attribute *a,
-                           char *buf)
-{
-       struct dlm_cluster *cl = config_item_to_cluster(i);
-       struct cluster_attribute *cla =
-                       container_of(a, struct cluster_attribute, attr);
-       return cla->show ? cla->show(cl, buf) : 0;
-}
-
-static ssize_t store_cluster(struct config_item *i,
-                            struct configfs_attribute *a,
-                            const char *buf, size_t len)
+static ssize_t comm_nodeid_show(struct config_item *item, char *buf)
 {
-       struct dlm_cluster *cl = config_item_to_cluster(i);
-       struct cluster_attribute *cla =
-               container_of(a, struct cluster_attribute, attr);
-       return cla->store ? cla->store(cl, buf, len) : -EINVAL;
-}
-
-static ssize_t show_comm(struct config_item *i, struct configfs_attribute *a,
-                        char *buf)
-{
-       struct dlm_comm *cm = config_item_to_comm(i);
-       struct comm_attribute *cma =
-                       container_of(a, struct comm_attribute, attr);
-       return cma->show ? cma->show(cm, buf) : 0;
-}
-
-static ssize_t store_comm(struct config_item *i, struct configfs_attribute *a,
-                         const char *buf, size_t len)
-{
-       struct dlm_comm *cm = config_item_to_comm(i);
-       struct comm_attribute *cma =
-               container_of(a, struct comm_attribute, attr);
-       return cma->store ? cma->store(cm, buf, len) : -EINVAL;
+       return sprintf(buf, "%d\n", config_item_to_comm(item)->nodeid);
 }
 
-static ssize_t comm_nodeid_read(struct dlm_comm *cm, char *buf)
-{
-       return sprintf(buf, "%d\n", cm->nodeid);
-}
-
-static ssize_t comm_nodeid_write(struct dlm_comm *cm, const char *buf,
+static ssize_t comm_nodeid_store(struct config_item *item, const char *buf,
                                 size_t len)
 {
-       int rc = kstrtoint(buf, 0, &cm->nodeid);
+       int rc = kstrtoint(buf, 0, &config_item_to_comm(item)->nodeid);
 
        if (rc)
                return rc;
        return len;
 }
 
-static ssize_t comm_local_read(struct dlm_comm *cm, char *buf)
+static ssize_t comm_local_show(struct config_item *item, char *buf)
 {
-       return sprintf(buf, "%d\n", cm->local);
+       return sprintf(buf, "%d\n", config_item_to_comm(item)->local);
 }
 
-static ssize_t comm_local_write(struct dlm_comm *cm, const char *buf,
+static ssize_t comm_local_store(struct config_item *item, const char *buf,
                                size_t len)
 {
+       struct dlm_comm *cm = config_item_to_comm(item);
        int rc = kstrtoint(buf, 0, &cm->local);
 
        if (rc)
@@ -756,8 +608,10 @@ static ssize_t comm_local_write(struct dlm_comm *cm, const char *buf,
        return len;
 }
 
-static ssize_t comm_addr_write(struct dlm_comm *cm, const char *buf, size_t len)
+static ssize_t comm_addr_store(struct config_item *item, const char *buf,
+               size_t len)
 {
+       struct dlm_comm *cm = config_item_to_comm(item);
        struct sockaddr_storage *addr;
        int rv;
 
@@ -783,8 +637,9 @@ static ssize_t comm_addr_write(struct dlm_comm *cm, const char *buf, size_t len)
        return len;
 }
 
-static ssize_t comm_addr_list_read(struct dlm_comm *cm, char *buf)
+static ssize_t comm_addr_list_show(struct config_item *item, char *buf)
 {
+       struct dlm_comm *cm = config_item_to_comm(item);
        ssize_t s;
        ssize_t allowance;
        int i;
@@ -827,32 +682,28 @@ static ssize_t comm_addr_list_read(struct dlm_comm *cm, char *buf)
        return 4096 - allowance;
 }
 
-static ssize_t show_node(struct config_item *i, struct configfs_attribute *a,
-                        char *buf)
-{
-       struct dlm_node *nd = config_item_to_node(i);
-       struct node_attribute *nda =
-                       container_of(a, struct node_attribute, attr);
-       return nda->show ? nda->show(nd, buf) : 0;
-}
+CONFIGFS_ATTR(comm_, nodeid);
+CONFIGFS_ATTR(comm_, local);
+CONFIGFS_ATTR_WO(comm_, addr);
+CONFIGFS_ATTR_RO(comm_, addr_list);
 
-static ssize_t store_node(struct config_item *i, struct configfs_attribute *a,
-                         const char *buf, size_t len)
-{
-       struct dlm_node *nd = config_item_to_node(i);
-       struct node_attribute *nda =
-               container_of(a, struct node_attribute, attr);
-       return nda->store ? nda->store(nd, buf, len) : -EINVAL;
-}
+static struct configfs_attribute *comm_attrs[] = {
+       [COMM_ATTR_NODEID] = &comm_attr_nodeid,
+       [COMM_ATTR_LOCAL] = &comm_attr_local,
+       [COMM_ATTR_ADDR] = &comm_attr_addr,
+       [COMM_ATTR_ADDR_LIST] = &comm_attr_addr_list,
+       NULL,
+};
 
-static ssize_t node_nodeid_read(struct dlm_node *nd, char *buf)
+static ssize_t node_nodeid_show(struct config_item *item, char *buf)
 {
-       return sprintf(buf, "%d\n", nd->nodeid);
+       return sprintf(buf, "%d\n", config_item_to_node(item)->nodeid);
 }
 
-static ssize_t node_nodeid_write(struct dlm_node *nd, const char *buf,
+static ssize_t node_nodeid_store(struct config_item *item, const char *buf,
                                 size_t len)
 {
+       struct dlm_node *nd = config_item_to_node(item);
        uint32_t seq = 0;
        int rc = kstrtoint(buf, 0, &nd->nodeid);
 
@@ -863,21 +714,30 @@ static ssize_t node_nodeid_write(struct dlm_node *nd, const char *buf,
        return len;
 }
 
-static ssize_t node_weight_read(struct dlm_node *nd, char *buf)
+static ssize_t node_weight_show(struct config_item *item, char *buf)
 {
-       return sprintf(buf, "%d\n", nd->weight);
+       return sprintf(buf, "%d\n", config_item_to_node(item)->weight);
 }
 
-static ssize_t node_weight_write(struct dlm_node *nd, const char *buf,
+static ssize_t node_weight_store(struct config_item *item, const char *buf,
                                 size_t len)
 {
-       int rc = kstrtoint(buf, 0, &nd->weight);
+       int rc = kstrtoint(buf, 0, &config_item_to_node(item)->weight);
 
        if (rc)
                return rc;
        return len;
 }
 
+CONFIGFS_ATTR(node_, nodeid);
+CONFIGFS_ATTR(node_, weight);
+
+static struct configfs_attribute *node_attrs[] = {
+       [NODE_ATTR_NODEID] = &node_attr_nodeid,
+       [NODE_ATTR_WEIGHT] = &node_attr_weight,
+       NULL,
+};
+
 /*
  * Functions for the dlm to get the info that's been configured
  */
index 0b6bfd3a398bd320cf8bbbbe81745f364decd765..fa70848afa8f4c403e988d058966db0b6af456b6 100644 (file)
@@ -293,10 +293,9 @@ bad_block: ext2_error(inode->i_sb, "ext2_xattr_list",
                        ext2_xattr_handler(entry->e_name_index);
 
                if (handler) {
-                       size_t size = handler->list(dentry, buffer, rest,
-                                                   entry->e_name,
-                                                   entry->e_name_len,
-                                                   handler->flags);
+                       size_t size = handler->list(handler, dentry, buffer,
+                                                   rest, entry->e_name,
+                                                   entry->e_name_len);
                        if (buffer) {
                                if (size > rest) {
                                        error = -ERANGE;
index 702fc6840246e7484e5cc3d4c553c9dd2fa5d37e..dfb08750370d85d71a7fc89bef68345229b7740d 100644 (file)
@@ -8,8 +8,9 @@
 #include "xattr.h"
 
 static size_t
-ext2_xattr_security_list(struct dentry *dentry, char *list, size_t list_size,
-                        const char *name, size_t name_len, int type)
+ext2_xattr_security_list(const struct xattr_handler *handler,
+                        struct dentry *dentry, char *list, size_t list_size,
+                        const char *name, size_t name_len)
 {
        const int prefix_len = XATTR_SECURITY_PREFIX_LEN;
        const size_t total_len = prefix_len + name_len + 1;
@@ -23,8 +24,9 @@ ext2_xattr_security_list(struct dentry *dentry, char *list, size_t list_size,
 }
 
 static int
-ext2_xattr_security_get(struct dentry *dentry, const char *name,
-                      void *buffer, size_t size, int type)
+ext2_xattr_security_get(const struct xattr_handler *handler,
+                       struct dentry *dentry, const char *name,
+                       void *buffer, size_t size)
 {
        if (strcmp(name, "") == 0)
                return -EINVAL;
@@ -33,8 +35,9 @@ ext2_xattr_security_get(struct dentry *dentry, const char *name,
 }
 
 static int
-ext2_xattr_security_set(struct dentry *dentry, const char *name,
-               const void *value, size_t size, int flags, int type)
+ext2_xattr_security_set(const struct xattr_handler *handler,
+                       struct dentry *dentry, const char *name,
+                       const void *value, size_t size, int flags)
 {
        if (strcmp(name, "") == 0)
                return -EINVAL;
index 42b6e9874bccf5501737ac53e62228ce22a6e3dd..3150dd3a78595084d0a6bfd5916f86272e68303a 100644 (file)
@@ -9,8 +9,9 @@
 #include "xattr.h"
 
 static size_t
-ext2_xattr_trusted_list(struct dentry *dentry, char *list, size_t list_size,
-               const char *name, size_t name_len, int type)
+ext2_xattr_trusted_list(const struct xattr_handler *handler,
+                       struct dentry *dentry, char *list, size_t list_size,
+                       const char *name, size_t name_len)
 {
        const int prefix_len = XATTR_TRUSTED_PREFIX_LEN;
        const size_t total_len = prefix_len + name_len + 1;
@@ -27,8 +28,9 @@ ext2_xattr_trusted_list(struct dentry *dentry, char *list, size_t list_size,
 }
 
 static int
-ext2_xattr_trusted_get(struct dentry *dentry, const char *name,
-               void *buffer, size_t size, int type)
+ext2_xattr_trusted_get(const struct xattr_handler *handler,
+                      struct dentry *dentry, const char *name,
+                      void *buffer, size_t size)
 {
        if (strcmp(name, "") == 0)
                return -EINVAL;
@@ -37,8 +39,9 @@ ext2_xattr_trusted_get(struct dentry *dentry, const char *name,
 }
 
 static int
-ext2_xattr_trusted_set(struct dentry *dentry, const char *name,
-               const void *value, size_t size, int flags, int type)
+ext2_xattr_trusted_set(const struct xattr_handler *handler,
+                      struct dentry *dentry, const char *name,
+                      const void *value, size_t size, int flags)
 {
        if (strcmp(name, "") == 0)
                return -EINVAL;
index ecdc4605192cef4d502e6633e5537b5d06117a45..339a49bbb8efbee752138fc600399c712d1b98a7 100644 (file)
@@ -11,8 +11,9 @@
 #include "xattr.h"
 
 static size_t
-ext2_xattr_user_list(struct dentry *dentry, char *list, size_t list_size,
-               const char *name, size_t name_len, int type)
+ext2_xattr_user_list(const struct xattr_handler *handler,
+                    struct dentry *dentry, char *list, size_t list_size,
+                    const char *name, size_t name_len)
 {
        const size_t prefix_len = XATTR_USER_PREFIX_LEN;
        const size_t total_len = prefix_len + name_len + 1;
@@ -29,8 +30,9 @@ ext2_xattr_user_list(struct dentry *dentry, char *list, size_t list_size,
 }
 
 static int
-ext2_xattr_user_get(struct dentry *dentry, const char *name,
-               void *buffer, size_t size, int type)
+ext2_xattr_user_get(const struct xattr_handler *handler,
+                   struct dentry *dentry, const char *name,
+                   void *buffer, size_t size)
 {
        if (strcmp(name, "") == 0)
                return -EINVAL;
@@ -41,8 +43,9 @@ ext2_xattr_user_get(struct dentry *dentry, const char *name,
 }
 
 static int
-ext2_xattr_user_set(struct dentry *dentry, const char *name,
-               const void *value, size_t size, int flags, int type)
+ext2_xattr_user_set(const struct xattr_handler *handler,
+                   struct dentry *dentry, const char *name,
+                   const void *value, size_t size, int flags)
 {
        if (strcmp(name, "") == 0)
                return -EINVAL;
index 7d1aad1d9313155f3780cde3923710fe7f60ea1c..ea433a7f4bca21511ba84fbfbe52f71883680661 100644 (file)
@@ -5283,7 +5283,7 @@ int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
            !ext4_should_journal_data(inode) &&
            !ext4_nonda_switch(inode->i_sb)) {
                do {
-                       ret = __block_page_mkwrite(vma, vmf,
+                       ret = block_page_mkwrite(vma, vmf,
                                                   ext4_da_get_block_prep);
                } while (ret == -ENOSPC &&
                       ext4_should_retry_alloc(inode->i_sb, &retries));
@@ -5330,7 +5330,7 @@ retry_alloc:
                ret = VM_FAULT_SIGBUS;
                goto out;
        }
-       ret = __block_page_mkwrite(vma, vmf, get_block);
+       ret = block_page_mkwrite(vma, vmf, get_block);
        if (!ret && ext4_should_journal_data(inode)) {
                if (ext4_walk_page_buffers(handle, page_buffers(page), 0,
                          PAGE_CACHE_SIZE, NULL, do_journal_get_write_access)) {
index 984448c6f5f0af1d429a982cce28f7ab26b3b093..6b6b3e751f8c77ebc9089c412f9019b4774a4301 100644 (file)
@@ -405,10 +405,9 @@ ext4_xattr_list_entries(struct dentry *dentry, struct ext4_xattr_entry *entry,
                        ext4_xattr_handler(entry->e_name_index);
 
                if (handler) {
-                       size_t size = handler->list(dentry, buffer, rest,
-                                                   entry->e_name,
-                                                   entry->e_name_len,
-                                                   handler->flags);
+                       size_t size = handler->list(handler, dentry, buffer,
+                                                   rest, entry->e_name,
+                                                   entry->e_name_len);
                        if (buffer) {
                                if (size > rest)
                                        return -ERANGE;
index 95d90e0560f05677279db254936a4fa086ad67d2..36f4c1a84c218307a1ae5c7e5c9805747025cf38 100644 (file)
@@ -12,8 +12,9 @@
 #include "xattr.h"
 
 static size_t
-ext4_xattr_security_list(struct dentry *dentry, char *list, size_t list_size,
-               const char *name, size_t name_len, int type)
+ext4_xattr_security_list(const struct xattr_handler *handler,
+                        struct dentry *dentry, char *list, size_t list_size,
+                        const char *name, size_t name_len)
 {
        const size_t prefix_len = sizeof(XATTR_SECURITY_PREFIX)-1;
        const size_t total_len = prefix_len + name_len + 1;
@@ -28,8 +29,9 @@ ext4_xattr_security_list(struct dentry *dentry, char *list, size_t list_size,
 }
 
 static int
-ext4_xattr_security_get(struct dentry *dentry, const char *name,
-                      void *buffer, size_t size, int type)
+ext4_xattr_security_get(const struct xattr_handler *handler,
+                       struct dentry *dentry, const char *name,
+                       void *buffer, size_t size)
 {
        if (strcmp(name, "") == 0)
                return -EINVAL;
@@ -38,8 +40,9 @@ ext4_xattr_security_get(struct dentry *dentry, const char *name,
 }
 
 static int
-ext4_xattr_security_set(struct dentry *dentry, const char *name,
-               const void *value, size_t size, int flags, int type)
+ext4_xattr_security_set(const struct xattr_handler *handler,
+                       struct dentry *dentry, const char *name,
+                       const void *value, size_t size, int flags)
 {
        if (strcmp(name, "") == 0)
                return -EINVAL;
index 891ee2ddfbd64a7b5f5201f6252edaafb3550b97..4880890533424ca63e67fc8ce0536254ce669028 100644 (file)
@@ -13,8 +13,9 @@
 #include "xattr.h"
 
 static size_t
-ext4_xattr_trusted_list(struct dentry *dentry, char *list, size_t list_size,
-               const char *name, size_t name_len, int type)
+ext4_xattr_trusted_list(const struct xattr_handler *handler,
+                       struct dentry *dentry, char *list, size_t list_size,
+                       const char *name, size_t name_len)
 {
        const size_t prefix_len = XATTR_TRUSTED_PREFIX_LEN;
        const size_t total_len = prefix_len + name_len + 1;
@@ -31,8 +32,9 @@ ext4_xattr_trusted_list(struct dentry *dentry, char *list, size_t list_size,
 }
 
 static int
-ext4_xattr_trusted_get(struct dentry *dentry, const char *name, void *buffer,
-               size_t size, int type)
+ext4_xattr_trusted_get(const struct xattr_handler *handler,
+                      struct dentry *dentry, const char *name, void *buffer,
+                      size_t size)
 {
        if (strcmp(name, "") == 0)
                return -EINVAL;
@@ -41,8 +43,9 @@ ext4_xattr_trusted_get(struct dentry *dentry, const char *name, void *buffer,
 }
 
 static int
-ext4_xattr_trusted_set(struct dentry *dentry, const char *name,
-               const void *value, size_t size, int flags, int type)
+ext4_xattr_trusted_set(const struct xattr_handler *handler,
+                      struct dentry *dentry, const char *name,
+                      const void *value, size_t size, int flags)
 {
        if (strcmp(name, "") == 0)
                return -EINVAL;
index 6ed932b3c04359b0817698ebcfcaf4a2d007b03f..d2dec33640620024aae408cdb394f4689d23dd87 100644 (file)
@@ -12,8 +12,9 @@
 #include "xattr.h"
 
 static size_t
-ext4_xattr_user_list(struct dentry *dentry, char *list, size_t list_size,
-                    const char *name, size_t name_len, int type)
+ext4_xattr_user_list(const struct xattr_handler *handler,
+                    struct dentry *dentry, char *list, size_t list_size,
+                    const char *name, size_t name_len)
 {
        const size_t prefix_len = XATTR_USER_PREFIX_LEN;
        const size_t total_len = prefix_len + name_len + 1;
@@ -30,8 +31,9 @@ ext4_xattr_user_list(struct dentry *dentry, char *list, size_t list_size,
 }
 
 static int
-ext4_xattr_user_get(struct dentry *dentry, const char *name,
-                   void *buffer, size_t size, int type)
+ext4_xattr_user_get(const struct xattr_handler *handler,
+                   struct dentry *dentry, const char *name,
+                   void *buffer, size_t size)
 {
        if (strcmp(name, "") == 0)
                return -EINVAL;
@@ -42,8 +44,9 @@ ext4_xattr_user_get(struct dentry *dentry, const char *name,
 }
 
 static int
-ext4_xattr_user_set(struct dentry *dentry, const char *name,
-                   const void *value, size_t size, int flags, int type)
+ext4_xattr_user_set(const struct xattr_handler *handler,
+                   struct dentry *dentry, const char *name,
+                   const void *value, size_t size, int flags)
 {
        if (strcmp(name, "") == 0)
                return -EINVAL;
index 4de2286c0e4df6e226922b181e92929dc81bb7ca..862368a32e5354c3d9458f39f933e87d05c3e287 100644 (file)
 #include "f2fs.h"
 #include "xattr.h"
 
-static size_t f2fs_xattr_generic_list(struct dentry *dentry, char *list,
-               size_t list_size, const char *name, size_t len, int type)
+static size_t f2fs_xattr_generic_list(const struct xattr_handler *handler,
+               struct dentry *dentry, char *list, size_t list_size,
+               const char *name, size_t len)
 {
        struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
-       int total_len, prefix_len = 0;
-       const char *prefix = NULL;
+       int total_len, prefix_len;
 
-       switch (type) {
+       switch (handler->flags) {
        case F2FS_XATTR_INDEX_USER:
                if (!test_opt(sbi, XATTR_USER))
                        return -EOPNOTSUPP;
-               prefix = XATTR_USER_PREFIX;
-               prefix_len = XATTR_USER_PREFIX_LEN;
                break;
        case F2FS_XATTR_INDEX_TRUSTED:
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
-               prefix = XATTR_TRUSTED_PREFIX;
-               prefix_len = XATTR_TRUSTED_PREFIX_LEN;
                break;
        case F2FS_XATTR_INDEX_SECURITY:
-               prefix = XATTR_SECURITY_PREFIX;
-               prefix_len = XATTR_SECURITY_PREFIX_LEN;
                break;
        default:
                return -EINVAL;
        }
 
+       prefix_len = strlen(handler->prefix);
        total_len = prefix_len + len + 1;
        if (list && total_len <= list_size) {
-               memcpy(list, prefix, prefix_len);
+               memcpy(list, handler->prefix, prefix_len);
                memcpy(list + prefix_len, name, len);
                list[prefix_len + len] = '\0';
        }
        return total_len;
 }
 
-static int f2fs_xattr_generic_get(struct dentry *dentry, const char *name,
-               void *buffer, size_t size, int type)
+static int f2fs_xattr_generic_get(const struct xattr_handler *handler,
+               struct dentry *dentry, const char *name, void *buffer,
+               size_t size)
 {
        struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
 
-       switch (type) {
+       switch (handler->flags) {
        case F2FS_XATTR_INDEX_USER:
                if (!test_opt(sbi, XATTR_USER))
                        return -EOPNOTSUPP;
@@ -83,15 +79,17 @@ static int f2fs_xattr_generic_get(struct dentry *dentry, const char *name,
        }
        if (strcmp(name, "") == 0)
                return -EINVAL;
-       return f2fs_getxattr(d_inode(dentry), type, name, buffer, size, NULL);
+       return f2fs_getxattr(d_inode(dentry), handler->flags, name,
+                            buffer, size, NULL);
 }
 
-static int f2fs_xattr_generic_set(struct dentry *dentry, const char *name,
-               const void *value, size_t size, int flags, int type)
+static int f2fs_xattr_generic_set(const struct xattr_handler *handler,
+               struct dentry *dentry, const char *name, const void *value,
+               size_t size, int flags)
 {
        struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
 
-       switch (type) {
+       switch (handler->flags) {
        case F2FS_XATTR_INDEX_USER:
                if (!test_opt(sbi, XATTR_USER))
                        return -EOPNOTSUPP;
@@ -108,27 +106,26 @@ static int f2fs_xattr_generic_set(struct dentry *dentry, const char *name,
        if (strcmp(name, "") == 0)
                return -EINVAL;
 
-       return f2fs_setxattr(d_inode(dentry), type, name,
+       return f2fs_setxattr(d_inode(dentry), handler->flags, name,
                                        value, size, NULL, flags);
 }
 
-static size_t f2fs_xattr_advise_list(struct dentry *dentry, char *list,
-               size_t list_size, const char *name, size_t len, int type)
+static size_t f2fs_xattr_advise_list(const struct xattr_handler *handler,
+               struct dentry *dentry, char *list, size_t list_size,
+               const char *name, size_t len)
 {
        const char *xname = F2FS_SYSTEM_ADVISE_PREFIX;
        size_t size;
 
-       if (type != F2FS_XATTR_INDEX_ADVISE)
-               return 0;
-
        size = strlen(xname) + 1;
        if (list && size <= list_size)
                memcpy(list, xname, size);
        return size;
 }
 
-static int f2fs_xattr_advise_get(struct dentry *dentry, const char *name,
-               void *buffer, size_t size, int type)
+static int f2fs_xattr_advise_get(const struct xattr_handler *handler,
+               struct dentry *dentry, const char *name, void *buffer,
+               size_t size)
 {
        struct inode *inode = d_inode(dentry);
 
@@ -140,8 +137,9 @@ static int f2fs_xattr_advise_get(struct dentry *dentry, const char *name,
        return sizeof(char);
 }
 
-static int f2fs_xattr_advise_set(struct dentry *dentry, const char *name,
-               const void *value, size_t size, int flags, int type)
+static int f2fs_xattr_advise_set(const struct xattr_handler *handler,
+               struct dentry *dentry, const char *name, const void *value,
+               size_t size, int flags)
 {
        struct inode *inode = d_inode(dentry);
 
@@ -462,8 +460,8 @@ ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
                if (!handler)
                        continue;
 
-               size = handler->list(dentry, buffer, rest, entry->e_name,
-                               entry->e_name_len, handler->flags);
+               size = handler->list(handler, dentry, buffer, rest,
+                                    entry->e_name, entry->e_name_len);
                if (buffer && size > rest) {
                        error = -ERANGE;
                        goto cleanup;
index 6d941f56faf436398f0d20c146ad9b7dc77d0b61..9b28649df3a1fdc6f0f0c23b58b03db94dd69eb2 100644 (file)
@@ -22,6 +22,7 @@ static LIST_HEAD(fscache_netfs_list);
 int __fscache_register_netfs(struct fscache_netfs *netfs)
 {
        struct fscache_netfs *ptr;
+       struct fscache_cookie *cookie;
        int ret;
 
        _enter("{%s}", netfs->name);
@@ -29,29 +30,25 @@ int __fscache_register_netfs(struct fscache_netfs *netfs)
        INIT_LIST_HEAD(&netfs->link);
 
        /* allocate a cookie for the primary index */
-       netfs->primary_index =
-               kmem_cache_zalloc(fscache_cookie_jar, GFP_KERNEL);
+       cookie = kmem_cache_zalloc(fscache_cookie_jar, GFP_KERNEL);
 
-       if (!netfs->primary_index) {
+       if (!cookie) {
                _leave(" = -ENOMEM");
                return -ENOMEM;
        }
 
        /* initialise the primary index cookie */
-       atomic_set(&netfs->primary_index->usage, 1);
-       atomic_set(&netfs->primary_index->n_children, 0);
-       atomic_set(&netfs->primary_index->n_active, 1);
+       atomic_set(&cookie->usage, 1);
+       atomic_set(&cookie->n_children, 0);
+       atomic_set(&cookie->n_active, 1);
 
-       netfs->primary_index->def               = &fscache_fsdef_netfs_def;
-       netfs->primary_index->parent            = &fscache_fsdef_index;
-       netfs->primary_index->netfs_data        = netfs;
-       netfs->primary_index->flags             = 1 << FSCACHE_COOKIE_ENABLED;
+       cookie->def             = &fscache_fsdef_netfs_def;
+       cookie->parent          = &fscache_fsdef_index;
+       cookie->netfs_data      = netfs;
+       cookie->flags           = 1 << FSCACHE_COOKIE_ENABLED;
 
-       atomic_inc(&netfs->primary_index->parent->usage);
-       atomic_inc(&netfs->primary_index->parent->n_children);
-
-       spin_lock_init(&netfs->primary_index->lock);
-       INIT_HLIST_HEAD(&netfs->primary_index->backing_objects);
+       spin_lock_init(&cookie->lock);
+       INIT_HLIST_HEAD(&cookie->backing_objects);
 
        /* check the netfs type is not already present */
        down_write(&fscache_addremove_sem);
@@ -62,6 +59,10 @@ int __fscache_register_netfs(struct fscache_netfs *netfs)
                        goto already_registered;
        }
 
+       atomic_inc(&cookie->parent->usage);
+       atomic_inc(&cookie->parent->n_children);
+
+       netfs->primary_index = cookie;
        list_add(&netfs->link, &fscache_netfs_list);
        ret = 0;
 
@@ -70,11 +71,8 @@ int __fscache_register_netfs(struct fscache_netfs *netfs)
 already_registered:
        up_write(&fscache_addremove_sem);
 
-       if (ret < 0) {
-               netfs->primary_index->parent = NULL;
-               __fscache_cookie_put(netfs->primary_index);
-               netfs->primary_index = NULL;
-       }
+       if (ret < 0)
+               kmem_cache_free(fscache_cookie_jar, cookie);
 
        _leave(" = %d", ret);
        return ret;
index 79483b3d8c6f273f9a8e8a5c0c997efa949d48ff..6b35fc4860a0381ab33ccc6162ca5184555373b6 100644 (file)
@@ -816,7 +816,7 @@ static void fscache_write_op(struct fscache_operation *_op)
                goto superseded;
        page = results[0];
        _debug("gang %d [%lx]", n, page->index);
-       if (page->index > op->store_limit) {
+       if (page->index >= op->store_limit) {
                fscache_stat(&fscache_n_store_pages_over_limit);
                goto superseded;
        }
index 4c096fa9e2a18c4c52ef528c96198d9a08ef9b6a..53ce76a374fe7313314eafd274b8a58db81b52d0 100644 (file)
@@ -583,11 +583,13 @@ out:
  *
  * Returns: actual size of data on success, -errno on error
  */
-static int gfs2_xattr_get(struct dentry *dentry, const char *name,
-               void *buffer, size_t size, int type)
+static int gfs2_xattr_get(const struct xattr_handler *handler,
+                         struct dentry *dentry, const char *name,
+                         void *buffer, size_t size)
 {
        struct gfs2_inode *ip = GFS2_I(d_inode(dentry));
        struct gfs2_ea_location el;
+       int type = handler->flags;
        int error;
 
        if (!ip->i_eattr)
@@ -1227,11 +1229,12 @@ int __gfs2_xattr_set(struct inode *inode, const char *name,
        return error;
 }
 
-static int gfs2_xattr_set(struct dentry *dentry, const char *name,
-               const void *value, size_t size, int flags, int type)
+static int gfs2_xattr_set(const struct xattr_handler *handler,
+                         struct dentry *dentry, const char *name,
+                         const void *value, size_t size, int flags)
 {
        return __gfs2_xattr_set(d_inode(dentry), name, value,
-                               size, flags, type);
+                               size, flags, handler->flags);
 }
 
 
index 416b1dbafe516583b22efad4a851e7f6cf2abb25..e41a010cd89ca6ca8e76dec51d2d8914782e1db6 100644 (file)
@@ -849,8 +849,9 @@ end_removexattr:
        return err;
 }
 
-static int hfsplus_osx_getxattr(struct dentry *dentry, const char *name,
-                                       void *buffer, size_t size, int type)
+static int hfsplus_osx_getxattr(const struct xattr_handler *handler,
+                               struct dentry *dentry, const char *name,
+                               void *buffer, size_t size)
 {
        if (!strcmp(name, ""))
                return -EINVAL;
@@ -871,8 +872,9 @@ static int hfsplus_osx_getxattr(struct dentry *dentry, const char *name,
        return __hfsplus_getxattr(d_inode(dentry), name, buffer, size);
 }
 
-static int hfsplus_osx_setxattr(struct dentry *dentry, const char *name,
-               const void *buffer, size_t size, int flags, int type)
+static int hfsplus_osx_setxattr(const struct xattr_handler *handler,
+                               struct dentry *dentry, const char *name,
+                               const void *buffer, size_t size, int flags)
 {
        if (!strcmp(name, ""))
                return -EINVAL;
@@ -893,19 +895,8 @@ static int hfsplus_osx_setxattr(struct dentry *dentry, const char *name,
        return __hfsplus_setxattr(d_inode(dentry), name, buffer, size, flags);
 }
 
-static size_t hfsplus_osx_listxattr(struct dentry *dentry, char *list,
-               size_t list_size, const char *name, size_t name_len, int type)
-{
-       /*
-        * This method is not used.
-        * It is used hfsplus_listxattr() instead of generic_listxattr().
-        */
-       return -EOPNOTSUPP;
-}
-
 const struct xattr_handler hfsplus_xattr_osx_handler = {
        .prefix = XATTR_MAC_OSX_PREFIX,
-       .list   = hfsplus_osx_listxattr,
        .get    = hfsplus_osx_getxattr,
        .set    = hfsplus_osx_setxattr,
 };
index aacff00a9ff9e77c5d6f6cca250dc90cf4e1cbfc..72a68a3a0c996e1ca73fb2ec462c30f19b56f247 100644 (file)
 #include "xattr.h"
 #include "acl.h"
 
-static int hfsplus_security_getxattr(struct dentry *dentry, const char *name,
-                                       void *buffer, size_t size, int type)
+static int hfsplus_security_getxattr(const struct xattr_handler *handler,
+                                    struct dentry *dentry, const char *name,
+                                    void *buffer, size_t size)
 {
        return hfsplus_getxattr(dentry, name, buffer, size,
                                XATTR_SECURITY_PREFIX,
                                XATTR_SECURITY_PREFIX_LEN);
 }
 
-static int hfsplus_security_setxattr(struct dentry *dentry, const char *name,
-               const void *buffer, size_t size, int flags, int type)
+static int hfsplus_security_setxattr(const struct xattr_handler *handler,
+                                    struct dentry *dentry, const char *name,
+                                    const void *buffer, size_t size, int flags)
 {
        return hfsplus_setxattr(dentry, name, buffer, size, flags,
                                XATTR_SECURITY_PREFIX,
                                XATTR_SECURITY_PREFIX_LEN);
 }
 
-static size_t hfsplus_security_listxattr(struct dentry *dentry, char *list,
-               size_t list_size, const char *name, size_t name_len, int type)
-{
-       /*
-        * This method is not used.
-        * It is used hfsplus_listxattr() instead of generic_listxattr().
-        */
-       return -EOPNOTSUPP;
-}
-
 static int hfsplus_initxattrs(struct inode *inode,
                                const struct xattr *xattr_array,
                                void *fs_info)
@@ -92,7 +84,6 @@ int hfsplus_init_inode_security(struct inode *inode,
 
 const struct xattr_handler hfsplus_xattr_security_handler = {
        .prefix = XATTR_SECURITY_PREFIX,
-       .list   = hfsplus_security_listxattr,
        .get    = hfsplus_security_getxattr,
        .set    = hfsplus_security_setxattr,
 };
index bcf65089b7f7f11179d2304a9cee613664d8bd55..95a7704c7abb7b82358d5516c366ead6091d4fda 100644 (file)
 #include "hfsplus_fs.h"
 #include "xattr.h"
 
-static int hfsplus_trusted_getxattr(struct dentry *dentry, const char *name,
-                                       void *buffer, size_t size, int type)
+static int hfsplus_trusted_getxattr(const struct xattr_handler *handler,
+                                   struct dentry *dentry, const char *name,
+                                   void *buffer, size_t size)
 {
        return hfsplus_getxattr(dentry, name, buffer, size,
                                XATTR_TRUSTED_PREFIX,
                                XATTR_TRUSTED_PREFIX_LEN);
 }
 
-static int hfsplus_trusted_setxattr(struct dentry *dentry, const char *name,
-               const void *buffer, size_t size, int flags, int type)
+static int hfsplus_trusted_setxattr(const struct xattr_handler *handler,
+                                   struct dentry *dentry, const char *name,
+                                   const void *buffer, size_t size, int flags)
 {
        return hfsplus_setxattr(dentry, name, buffer, size, flags,
                                XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN);
 }
 
-static size_t hfsplus_trusted_listxattr(struct dentry *dentry, char *list,
-               size_t list_size, const char *name, size_t name_len, int type)
-{
-       /*
-        * This method is not used.
-        * It is used hfsplus_listxattr() instead of generic_listxattr().
-        */
-       return -EOPNOTSUPP;
-}
-
 const struct xattr_handler hfsplus_xattr_trusted_handler = {
        .prefix = XATTR_TRUSTED_PREFIX,
-       .list   = hfsplus_trusted_listxattr,
        .get    = hfsplus_trusted_getxattr,
        .set    = hfsplus_trusted_setxattr,
 };
index 5aa0e6dc4a1ee922edbde9ae440ea86572e17bc9..6fc269baf959a34bb9889b2be5c8a0711e895c94 100644 (file)
 #include "hfsplus_fs.h"
 #include "xattr.h"
 
-static int hfsplus_user_getxattr(struct dentry *dentry, const char *name,
-                                       void *buffer, size_t size, int type)
+static int hfsplus_user_getxattr(const struct xattr_handler *handler,
+                                struct dentry *dentry, const char *name,
+                                void *buffer, size_t size)
 {
 
        return hfsplus_getxattr(dentry, name, buffer, size,
                                XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
 }
 
-static int hfsplus_user_setxattr(struct dentry *dentry, const char *name,
-               const void *buffer, size_t size, int flags, int type)
+static int hfsplus_user_setxattr(const struct xattr_handler *handler,
+                                struct dentry *dentry, const char *name,
+                                const void *buffer, size_t size, int flags)
 {
        return hfsplus_setxattr(dentry, name, buffer, size, flags,
                                XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
 }
 
-static size_t hfsplus_user_listxattr(struct dentry *dentry, char *list,
-               size_t list_size, const char *name, size_t name_len, int type)
-{
-       /*
-        * This method is not used.
-        * It is used hfsplus_listxattr() instead of generic_listxattr().
-        */
-       return -EOPNOTSUPP;
-}
-
 const struct xattr_handler hfsplus_xattr_user_handler = {
        .prefix = XATTR_USER_PREFIX,
-       .list   = hfsplus_user_listxattr,
        .get    = hfsplus_user_getxattr,
        .set    = hfsplus_user_setxattr,
 };
index d4b43fb7adb18db678fc6bacf9cf9a0f3432af19..bf12fe5f83d7e66fa1cf34883539126f12cadfe0 100644 (file)
@@ -48,8 +48,9 @@ int jffs2_init_security(struct inode *inode, struct inode *dir,
 }
 
 /* ---- XATTR Handler for "security.*" ----------------- */
-static int jffs2_security_getxattr(struct dentry *dentry, const char *name,
-                                  void *buffer, size_t size, int type)
+static int jffs2_security_getxattr(const struct xattr_handler *handler,
+                                  struct dentry *dentry, const char *name,
+                                  void *buffer, size_t size)
 {
        if (!strcmp(name, ""))
                return -EINVAL;
@@ -58,8 +59,9 @@ static int jffs2_security_getxattr(struct dentry *dentry, const char *name,
                                 name, buffer, size);
 }
 
-static int jffs2_security_setxattr(struct dentry *dentry, const char *name,
-               const void *buffer, size_t size, int flags, int type)
+static int jffs2_security_setxattr(const struct xattr_handler *handler,
+                                  struct dentry *dentry, const char *name,
+                                  const void *buffer, size_t size, int flags)
 {
        if (!strcmp(name, ""))
                return -EINVAL;
@@ -68,8 +70,10 @@ static int jffs2_security_setxattr(struct dentry *dentry, const char *name,
                                 name, buffer, size, flags);
 }
 
-static size_t jffs2_security_listxattr(struct dentry *dentry, char *list,
-               size_t list_size, const char *name, size_t name_len, int type)
+static size_t jffs2_security_listxattr(const struct xattr_handler *handler,
+                                      struct dentry *dentry, char *list,
+                                      size_t list_size, const char *name,
+                                      size_t name_len)
 {
        size_t retlen = XATTR_SECURITY_PREFIX_LEN + name_len + 1;
 
index f092fee5be50511f643e9fac79c03d393cef18f2..4c2c03663533dc2fbf1e0c24dc5b08dec6ea943f 100644 (file)
@@ -1001,11 +1001,12 @@ ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
                if (!xhandle)
                        continue;
                if (buffer) {
-                       rc = xhandle->list(dentry, buffer+len, size-len,
-                                          xd->xname, xd->name_len, xd->flags);
+                       rc = xhandle->list(xhandle, dentry, buffer + len,
+                                          size - len, xd->xname,
+                                          xd->name_len);
                } else {
-                       rc = xhandle->list(dentry, NULL, 0, xd->xname,
-                                          xd->name_len, xd->flags);
+                       rc = xhandle->list(xhandle, dentry, NULL, 0,
+                                          xd->xname, xd->name_len);
                }
                if (rc < 0)
                        goto out;
index ceaf9c693225b44edeb5bb3bddea534c1b62ad51..a562da0d6a26186dc2116d6b8a05795903a46897 100644 (file)
@@ -16,8 +16,9 @@
 #include <linux/mtd/mtd.h>
 #include "nodelist.h"
 
-static int jffs2_trusted_getxattr(struct dentry *dentry, const char *name,
-               void *buffer, size_t size, int type)
+static int jffs2_trusted_getxattr(const struct xattr_handler *handler,
+                                 struct dentry *dentry, const char *name,
+                                 void *buffer, size_t size)
 {
        if (!strcmp(name, ""))
                return -EINVAL;
@@ -25,8 +26,9 @@ static int jffs2_trusted_getxattr(struct dentry *dentry, const char *name,
                                 name, buffer, size);
 }
 
-static int jffs2_trusted_setxattr(struct dentry *dentry, const char *name,
-               const void *buffer, size_t size, int flags, int type)
+static int jffs2_trusted_setxattr(const struct xattr_handler *handler,
+                                 struct dentry *dentry, const char *name,
+                                 const void *buffer, size_t size, int flags)
 {
        if (!strcmp(name, ""))
                return -EINVAL;
@@ -34,11 +36,16 @@ static int jffs2_trusted_setxattr(struct dentry *dentry, const char *name,
                                 name, buffer, size, flags);
 }
 
-static size_t jffs2_trusted_listxattr(struct dentry *dentry, char *list,
-               size_t list_size, const char *name, size_t name_len, int type)
+static size_t jffs2_trusted_listxattr(const struct xattr_handler *handler,
+                                     struct dentry *dentry, char *list,
+                                     size_t list_size, const char *name,
+                                     size_t name_len)
 {
        size_t retlen = XATTR_TRUSTED_PREFIX_LEN + name_len + 1;
 
+       if (!capable(CAP_SYS_ADMIN))
+               return 0;
+
        if (list && retlen<=list_size) {
                strcpy(list, XATTR_TRUSTED_PREFIX);
                strcpy(list + XATTR_TRUSTED_PREFIX_LEN, name);
index a71391eba51497bf7902f10ee44955e67b623e5e..cbc0472e59a8b01b81ea142f35d29c88c3a12c00 100644 (file)
@@ -16,8 +16,9 @@
 #include <linux/mtd/mtd.h>
 #include "nodelist.h"
 
-static int jffs2_user_getxattr(struct dentry *dentry, const char *name,
-                              void *buffer, size_t size, int type)
+static int jffs2_user_getxattr(const struct xattr_handler *handler,
+                              struct dentry *dentry, const char *name,
+                              void *buffer, size_t size)
 {
        if (!strcmp(name, ""))
                return -EINVAL;
@@ -25,8 +26,9 @@ static int jffs2_user_getxattr(struct dentry *dentry, const char *name,
                                 name, buffer, size);
 }
 
-static int jffs2_user_setxattr(struct dentry *dentry, const char *name,
-               const void *buffer, size_t size, int flags, int type)
+static int jffs2_user_setxattr(const struct xattr_handler *handler,
+                              struct dentry *dentry, const char *name,
+                              const void *buffer, size_t size, int flags)
 {
        if (!strcmp(name, ""))
                return -EINVAL;
@@ -34,8 +36,10 @@ static int jffs2_user_setxattr(struct dentry *dentry, const char *name,
                                 name, buffer, size, flags);
 }
 
-static size_t jffs2_user_listxattr(struct dentry *dentry, char *list,
-               size_t list_size, const char *name, size_t name_len, int type)
+static size_t jffs2_user_listxattr(const struct xattr_handler *handler,
+                                  struct dentry *dentry, char *list,
+                                  size_t list_size, const char *name,
+                                  size_t name_len)
 {
        size_t retlen = XATTR_USER_PREFIX_LEN + name_len + 1;
 
index 969d589c848df8e066754e5ca5f3b02729eed919..d716c9993a261cc0f62115bc65aecd74c15ea7b3 100644 (file)
@@ -116,7 +116,7 @@ static struct nlm_host *nlm_alloc_host(struct nlm_lookup_host_info *ni,
                atomic_inc(&nsm->sm_count);
        else {
                host = NULL;
-               nsm = nsm_get_handle(ni->sap, ni->salen,
+               nsm = nsm_get_handle(ni->net, ni->sap, ni->salen,
                                        ni->hostname, ni->hostname_len);
                if (unlikely(nsm == NULL)) {
                        dprintk("lockd: %s failed; no nsm handle\n",
@@ -161,6 +161,7 @@ static struct nlm_host *nlm_alloc_host(struct nlm_lookup_host_info *ni,
        host->h_nsmhandle  = nsm;
        host->h_addrbuf    = nsm->sm_addrbuf;
        host->net          = ni->net;
+       strlcpy(host->nodename, utsname()->nodename, sizeof(host->nodename));
 
 out:
        return host;
@@ -534,17 +535,18 @@ static struct nlm_host *next_host_state(struct hlist_head *cache,
 
 /**
  * nlm_host_rebooted - Release all resources held by rebooted host
+ * @net:  network namespace
  * @info: pointer to decoded results of NLM_SM_NOTIFY call
  *
  * We were notified that the specified host has rebooted.  Release
  * all resources held by that peer.
  */
-void nlm_host_rebooted(const struct nlm_reboot *info)
+void nlm_host_rebooted(const struct net *net, const struct nlm_reboot *info)
 {
        struct nsm_handle *nsm;
        struct nlm_host *host;
 
-       nsm = nsm_reboot_lookup(info);
+       nsm = nsm_reboot_lookup(net, info);
        if (unlikely(nsm == NULL))
                return;
 
index 47a32b6d9b9001a2a58a54fd154e50f7c08891be..19166d4a8d313b73424d5668bcffa3c3baee2683 100644 (file)
@@ -42,7 +42,7 @@ struct nsm_args {
        u32                     proc;
 
        char                    *mon_name;
-       char                    *nodename;
+       const char              *nodename;
 };
 
 struct nsm_res {
@@ -51,7 +51,6 @@ struct nsm_res {
 };
 
 static const struct rpc_program        nsm_program;
-static                         LIST_HEAD(nsm_handles);
 static                         DEFINE_SPINLOCK(nsm_lock);
 
 /*
@@ -87,69 +86,18 @@ static struct rpc_clnt *nsm_create(struct net *net, const char *nodename)
        return rpc_create(&args);
 }
 
-static struct rpc_clnt *nsm_client_set(struct lockd_net *ln,
-               struct rpc_clnt *clnt)
-{
-       spin_lock(&ln->nsm_clnt_lock);
-       if (ln->nsm_users == 0) {
-               if (clnt == NULL)
-                       goto out;
-               ln->nsm_clnt = clnt;
-       }
-       clnt = ln->nsm_clnt;
-       ln->nsm_users++;
-out:
-       spin_unlock(&ln->nsm_clnt_lock);
-       return clnt;
-}
-
-static struct rpc_clnt *nsm_client_get(struct net *net, const char *nodename)
-{
-       struct rpc_clnt *clnt, *new;
-       struct lockd_net *ln = net_generic(net, lockd_net_id);
-
-       clnt = nsm_client_set(ln, NULL);
-       if (clnt != NULL)
-               goto out;
-
-       clnt = new = nsm_create(net, nodename);
-       if (IS_ERR(clnt))
-               goto out;
-
-       clnt = nsm_client_set(ln, new);
-       if (clnt != new)
-               rpc_shutdown_client(new);
-out:
-       return clnt;
-}
-
-static void nsm_client_put(struct net *net)
-{
-       struct lockd_net *ln = net_generic(net, lockd_net_id);
-       struct rpc_clnt *clnt = NULL;
-
-       spin_lock(&ln->nsm_clnt_lock);
-       ln->nsm_users--;
-       if (ln->nsm_users == 0) {
-               clnt = ln->nsm_clnt;
-               ln->nsm_clnt = NULL;
-       }
-       spin_unlock(&ln->nsm_clnt_lock);
-       if (clnt != NULL)
-               rpc_shutdown_client(clnt);
-}
-
 static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res,
-                        struct rpc_clnt *clnt)
+                        const struct nlm_host *host)
 {
        int             status;
+       struct rpc_clnt *clnt;
        struct nsm_args args = {
                .priv           = &nsm->sm_priv,
                .prog           = NLM_PROGRAM,
                .vers           = 3,
                .proc           = NLMPROC_NSM_NOTIFY,
                .mon_name       = nsm->sm_mon_name,
-               .nodename       = clnt->cl_nodename,
+               .nodename       = host->nodename,
        };
        struct rpc_message msg = {
                .rpc_argp       = &args,
@@ -158,6 +106,13 @@ static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res,
 
        memset(res, 0, sizeof(*res));
 
+       clnt = nsm_create(host->net, host->nodename);
+       if (IS_ERR(clnt)) {
+               dprintk("lockd: failed to create NSM upcall transport, "
+                       "status=%ld, net=%p\n", PTR_ERR(clnt), host->net);
+               return PTR_ERR(clnt);
+       }
+
        msg.rpc_proc = &clnt->cl_procinfo[proc];
        status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFTCONN);
        if (status == -ECONNREFUSED) {
@@ -171,6 +126,8 @@ static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res,
                                status);
        else
                status = 0;
+
+       rpc_shutdown_client(clnt);
        return status;
 }
 
@@ -190,32 +147,19 @@ int nsm_monitor(const struct nlm_host *host)
        struct nsm_handle *nsm = host->h_nsmhandle;
        struct nsm_res  res;
        int             status;
-       struct rpc_clnt *clnt;
-       const char *nodename = NULL;
 
        dprintk("lockd: nsm_monitor(%s)\n", nsm->sm_name);
 
        if (nsm->sm_monitored)
                return 0;
 
-       if (host->h_rpcclnt)
-               nodename = host->h_rpcclnt->cl_nodename;
-
        /*
         * Choose whether to record the caller_name or IP address of
         * this peer in the local rpc.statd's database.
         */
        nsm->sm_mon_name = nsm_use_hostnames ? nsm->sm_name : nsm->sm_addrbuf;
 
-       clnt = nsm_client_get(host->net, nodename);
-       if (IS_ERR(clnt)) {
-               status = PTR_ERR(clnt);
-               dprintk("lockd: failed to create NSM upcall transport, "
-                               "status=%d, net=%p\n", status, host->net);
-               return status;
-       }
-
-       status = nsm_mon_unmon(nsm, NSMPROC_MON, &res, clnt);
+       status = nsm_mon_unmon(nsm, NSMPROC_MON, &res, host);
        if (unlikely(res.status != 0))
                status = -EIO;
        if (unlikely(status < 0)) {
@@ -247,11 +191,9 @@ void nsm_unmonitor(const struct nlm_host *host)
 
        if (atomic_read(&nsm->sm_count) == 1
         && nsm->sm_monitored && !nsm->sm_sticky) {
-               struct lockd_net *ln = net_generic(host->net, lockd_net_id);
-
                dprintk("lockd: nsm_unmonitor(%s)\n", nsm->sm_name);
 
-               status = nsm_mon_unmon(nsm, NSMPROC_UNMON, &res, ln->nsm_clnt);
+               status = nsm_mon_unmon(nsm, NSMPROC_UNMON, &res, host);
                if (res.status != 0)
                        status = -EIO;
                if (status < 0)
@@ -259,38 +201,38 @@ void nsm_unmonitor(const struct nlm_host *host)
                                        nsm->sm_name);
                else
                        nsm->sm_monitored = 0;
-
-               nsm_client_put(host->net);
        }
 }
 
-static struct nsm_handle *nsm_lookup_hostname(const char *hostname,
-                                             const size_t len)
+static struct nsm_handle *nsm_lookup_hostname(const struct list_head *nsm_handles,
+                                       const char *hostname, const size_t len)
 {
        struct nsm_handle *nsm;
 
-       list_for_each_entry(nsm, &nsm_handles, sm_link)
+       list_for_each_entry(nsm, nsm_handles, sm_link)
                if (strlen(nsm->sm_name) == len &&
                    memcmp(nsm->sm_name, hostname, len) == 0)
                        return nsm;
        return NULL;
 }
 
-static struct nsm_handle *nsm_lookup_addr(const struct sockaddr *sap)
+static struct nsm_handle *nsm_lookup_addr(const struct list_head *nsm_handles,
+                                       const struct sockaddr *sap)
 {
        struct nsm_handle *nsm;
 
-       list_for_each_entry(nsm, &nsm_handles, sm_link)
+       list_for_each_entry(nsm, nsm_handles, sm_link)
                if (rpc_cmp_addr(nsm_addr(nsm), sap))
                        return nsm;
        return NULL;
 }
 
-static struct nsm_handle *nsm_lookup_priv(const struct nsm_private *priv)
+static struct nsm_handle *nsm_lookup_priv(const struct list_head *nsm_handles,
+                                       const struct nsm_private *priv)
 {
        struct nsm_handle *nsm;
 
-       list_for_each_entry(nsm, &nsm_handles, sm_link)
+       list_for_each_entry(nsm, nsm_handles, sm_link)
                if (memcmp(nsm->sm_priv.data, priv->data,
                                        sizeof(priv->data)) == 0)
                        return nsm;
@@ -353,6 +295,7 @@ static struct nsm_handle *nsm_create_handle(const struct sockaddr *sap,
 
 /**
  * nsm_get_handle - Find or create a cached nsm_handle
+ * @net: network namespace
  * @sap: pointer to socket address of handle to find
  * @salen: length of socket address
  * @hostname: pointer to C string containing hostname to find
@@ -365,11 +308,13 @@ static struct nsm_handle *nsm_create_handle(const struct sockaddr *sap,
  * @hostname cannot be found in the handle cache.  Returns NULL if
  * an error occurs.
  */
-struct nsm_handle *nsm_get_handle(const struct sockaddr *sap,
+struct nsm_handle *nsm_get_handle(const struct net *net,
+                                 const struct sockaddr *sap,
                                  const size_t salen, const char *hostname,
                                  const size_t hostname_len)
 {
        struct nsm_handle *cached, *new = NULL;
+       struct lockd_net *ln = net_generic(net, lockd_net_id);
 
        if (hostname && memchr(hostname, '/', hostname_len) != NULL) {
                if (printk_ratelimit()) {
@@ -384,9 +329,10 @@ retry:
        spin_lock(&nsm_lock);
 
        if (nsm_use_hostnames && hostname != NULL)
-               cached = nsm_lookup_hostname(hostname, hostname_len);
+               cached = nsm_lookup_hostname(&ln->nsm_handles,
+                                       hostname, hostname_len);
        else
-               cached = nsm_lookup_addr(sap);
+               cached = nsm_lookup_addr(&ln->nsm_handles, sap);
 
        if (cached != NULL) {
                atomic_inc(&cached->sm_count);
@@ -400,7 +346,7 @@ retry:
        }
 
        if (new != NULL) {
-               list_add(&new->sm_link, &nsm_handles);
+               list_add(&new->sm_link, &ln->nsm_handles);
                spin_unlock(&nsm_lock);
                dprintk("lockd: created nsm_handle for %s (%s)\n",
                                new->sm_name, new->sm_addrbuf);
@@ -417,19 +363,22 @@ retry:
 
 /**
  * nsm_reboot_lookup - match NLMPROC_SM_NOTIFY arguments to an nsm_handle
+ * @net:  network namespace
  * @info: pointer to NLMPROC_SM_NOTIFY arguments
  *
  * Returns a matching nsm_handle if found in the nsm cache. The returned
  * nsm_handle's reference count is bumped. Otherwise returns NULL if some
  * error occurred.
  */
-struct nsm_handle *nsm_reboot_lookup(const struct nlm_reboot *info)
+struct nsm_handle *nsm_reboot_lookup(const struct net *net,
+                               const struct nlm_reboot *info)
 {
        struct nsm_handle *cached;
+       struct lockd_net *ln = net_generic(net, lockd_net_id);
 
        spin_lock(&nsm_lock);
 
-       cached = nsm_lookup_priv(&info->priv);
+       cached = nsm_lookup_priv(&ln->nsm_handles, &info->priv);
        if (unlikely(cached == NULL)) {
                spin_unlock(&nsm_lock);
                dprintk("lockd: never saw rebooted peer '%.*s' before\n",
index 097bfa3adb1c54a6402e5dabcfce7a3bc13b88a4..5426189406c17c233bfcd0e139db5e7921e412fb 100644 (file)
@@ -12,9 +12,7 @@ struct lockd_net {
        struct delayed_work grace_period_end;
        struct lock_manager lockd_manager;
 
-       spinlock_t nsm_clnt_lock;
-       unsigned int nsm_users;
-       struct rpc_clnt *nsm_clnt;
+       struct list_head nsm_handles;
 };
 
 extern int lockd_net_id;
index d678bcc3cbcb440e90045e578c755f6972079852..5f31ebd96c068ce125172e064a1461a8b93bda68 100644 (file)
@@ -592,7 +592,7 @@ static int lockd_init_net(struct net *net)
        INIT_DELAYED_WORK(&ln->grace_period_end, grace_ender);
        INIT_LIST_HEAD(&ln->lockd_manager.list);
        ln->lockd_manager.block_opens = false;
-       spin_lock_init(&ln->nsm_clnt_lock);
+       INIT_LIST_HEAD(&ln->nsm_handles);
        return 0;
 }
 
index b147d1ae71fd9ec3c21ea69f847be1b2b047896d..09c576f26c7b76f5f39a6f7e98a37f297d09e533 100644 (file)
@@ -421,7 +421,7 @@ nlm4svc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp,
                return rpc_system_err;
        }
 
-       nlm_host_rebooted(argp);
+       nlm_host_rebooted(SVC_NET(rqstp), argp);
        return rpc_success;
 }
 
index 21171f0c6477560d7a5f6deb3e336e6c98581f96..fb26b9f522e74df4529b59c55b02502284f37dbc 100644 (file)
@@ -464,7 +464,7 @@ nlmsvc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp,
                return rpc_system_err;
        }
 
-       nlm_host_rebooted(argp);
+       nlm_host_rebooted(SVC_NET(rqstp), argp);
        return rpc_success;
 }
 
index ff5bddc49a2a30449a63a6c2a32a2aadc6db84b5..765a035593638cfd17b4aedd646c0362068343c6 100644 (file)
@@ -6248,9 +6248,10 @@ nfs4_release_lockowner(struct nfs_server *server, struct nfs4_lock_state *lsp)
 
 #define XATTR_NAME_NFSV4_ACL "system.nfs4_acl"
 
-static int nfs4_xattr_set_nfs4_acl(struct dentry *dentry, const char *key,
+static int nfs4_xattr_set_nfs4_acl(const struct xattr_handler *handler,
+                                  struct dentry *dentry, const char *key,
                                   const void *buf, size_t buflen,
-                                  int flags, int type)
+                                  int flags)
 {
        if (strcmp(key, "") != 0)
                return -EINVAL;
@@ -6258,8 +6259,9 @@ static int nfs4_xattr_set_nfs4_acl(struct dentry *dentry, const char *key,
        return nfs4_proc_set_acl(d_inode(dentry), buf, buflen);
 }
 
-static int nfs4_xattr_get_nfs4_acl(struct dentry *dentry, const char *key,
-                                  void *buf, size_t buflen, int type)
+static int nfs4_xattr_get_nfs4_acl(const struct xattr_handler *handler,
+                                  struct dentry *dentry, const char *key,
+                                  void *buf, size_t buflen)
 {
        if (strcmp(key, "") != 0)
                return -EINVAL;
@@ -6267,9 +6269,10 @@ static int nfs4_xattr_get_nfs4_acl(struct dentry *dentry, const char *key,
        return nfs4_proc_get_acl(d_inode(dentry), buf, buflen);
 }
 
-static size_t nfs4_xattr_list_nfs4_acl(struct dentry *dentry, char *list,
+static size_t nfs4_xattr_list_nfs4_acl(const struct xattr_handler *handler,
+                                      struct dentry *dentry, char *list,
                                       size_t list_len, const char *name,
-                                      size_t name_len, int type)
+                                      size_t name_len)
 {
        size_t len = sizeof(XATTR_NAME_NFSV4_ACL);
 
@@ -6287,9 +6290,10 @@ static inline int nfs4_server_supports_labels(struct nfs_server *server)
        return server->caps & NFS_CAP_SECURITY_LABEL;
 }
 
-static int nfs4_xattr_set_nfs4_label(struct dentry *dentry, const char *key,
-                                  const void *buf, size_t buflen,
-                                  int flags, int type)
+static int nfs4_xattr_set_nfs4_label(const struct xattr_handler *handler,
+                                    struct dentry *dentry, const char *key,
+                                    const void *buf, size_t buflen,
+                                    int flags)
 {
        if (security_ismaclabel(key))
                return nfs4_set_security_label(dentry, buf, buflen);
@@ -6297,17 +6301,19 @@ static int nfs4_xattr_set_nfs4_label(struct dentry *dentry, const char *key,
        return -EOPNOTSUPP;
 }
 
-static int nfs4_xattr_get_nfs4_label(struct dentry *dentry, const char *key,
-                                  void *buf, size_t buflen, int type)
+static int nfs4_xattr_get_nfs4_label(const struct xattr_handler *handler,
+                                    struct dentry *dentry, const char *key,
+                                    void *buf, size_t buflen)
 {
        if (security_ismaclabel(key))
                return nfs4_get_security_label(d_inode(dentry), buf, buflen);
        return -EOPNOTSUPP;
 }
 
-static size_t nfs4_xattr_list_nfs4_label(struct dentry *dentry, char *list,
-                                      size_t list_len, const char *name,
-                                      size_t name_len, int type)
+static size_t nfs4_xattr_list_nfs4_label(const struct xattr_handler *handler,
+                                        struct dentry *dentry, char *list,
+                                        size_t list_len, const char *name,
+                                        size_t name_len)
 {
        size_t len = 0;
 
index f6e7cbabac5a29a7e837ab87039dc157e6e7c46b..00575d776d91f58576523d1fc30e558585a91ace 100644 (file)
@@ -262,11 +262,11 @@ void fill_post_wcc(struct svc_fh *fhp)
        err = fh_getattr(fhp, &fhp->fh_post_attr);
        fhp->fh_post_change = d_inode(fhp->fh_dentry)->i_version;
        if (err) {
-               fhp->fh_post_saved = 0;
+               fhp->fh_post_saved = false;
                /* Grab the ctime anyway - set_change_info might use it */
                fhp->fh_post_attr.ctime = d_inode(fhp->fh_dentry)->i_ctime;
        } else
-               fhp->fh_post_saved = 1;
+               fhp->fh_post_saved = true;
 }
 
 /*
index ebf90e487c752b59270aa559588a8805468ad0f5..9ffef06b30d51e2acb2ae1a6570f14c2c47eac59 100644 (file)
@@ -201,6 +201,7 @@ nfsd4_alloc_layout_stateid(struct nfsd4_compound_state *cstate,
        INIT_LIST_HEAD(&ls->ls_perfile);
        spin_lock_init(&ls->ls_lock);
        INIT_LIST_HEAD(&ls->ls_layouts);
+       mutex_init(&ls->ls_mutex);
        ls->ls_layout_type = layout_type;
        nfsd4_init_cb(&ls->ls_recall, clp, &nfsd4_cb_layout_ops,
                        NFSPROC4_CLNT_CB_LAYOUT);
@@ -262,19 +263,23 @@ nfsd4_preprocess_layout_stateid(struct svc_rqst *rqstp,
                status = nfserr_jukebox;
                if (!ls)
                        goto out;
+               mutex_lock(&ls->ls_mutex);
        } else {
                ls = container_of(stid, struct nfs4_layout_stateid, ls_stid);
 
                status = nfserr_bad_stateid;
+               mutex_lock(&ls->ls_mutex);
                if (stateid->si_generation > stid->sc_stateid.si_generation)
-                       goto out_put_stid;
+                       goto out_unlock_stid;
                if (layout_type != ls->ls_layout_type)
-                       goto out_put_stid;
+                       goto out_unlock_stid;
        }
 
        *lsp = ls;
        return 0;
 
+out_unlock_stid:
+       mutex_unlock(&ls->ls_mutex);
 out_put_stid:
        nfs4_put_stid(stid);
 out:
@@ -296,8 +301,6 @@ nfsd4_recall_file_layout(struct nfs4_layout_stateid *ls)
        trace_layout_recall(&ls->ls_stid.sc_stateid);
 
        atomic_inc(&ls->ls_stid.sc_count);
-       update_stateid(&ls->ls_stid.sc_stateid);
-       memcpy(&ls->ls_recall_sid, &ls->ls_stid.sc_stateid, sizeof(stateid_t));
        nfsd4_run_cb(&ls->ls_recall);
 
 out_unlock:
@@ -406,8 +409,7 @@ nfsd4_insert_layout(struct nfsd4_layoutget *lgp, struct nfs4_layout_stateid *ls)
        list_add_tail(&new->lo_perstate, &ls->ls_layouts);
        new = NULL;
 done:
-       update_stateid(&ls->ls_stid.sc_stateid);
-       memcpy(&lgp->lg_sid, &ls->ls_stid.sc_stateid, sizeof(stateid_t));
+       nfs4_inc_and_copy_stateid(&lgp->lg_sid, &ls->ls_stid);
        spin_unlock(&ls->ls_lock);
 out:
        spin_unlock(&fp->fi_lock);
@@ -481,11 +483,8 @@ nfsd4_return_file_layouts(struct svc_rqst *rqstp,
                }
        }
        if (!list_empty(&ls->ls_layouts)) {
-               if (found) {
-                       update_stateid(&ls->ls_stid.sc_stateid);
-                       memcpy(&lrp->lr_sid, &ls->ls_stid.sc_stateid,
-                               sizeof(stateid_t));
-               }
+               if (found)
+                       nfs4_inc_and_copy_stateid(&lrp->lr_sid, &ls->ls_stid);
                lrp->lrs_present = 1;
        } else {
                trace_layoutstate_unhash(&ls->ls_stid.sc_stateid);
@@ -494,6 +493,7 @@ nfsd4_return_file_layouts(struct svc_rqst *rqstp,
        }
        spin_unlock(&ls->ls_lock);
 
+       mutex_unlock(&ls->ls_mutex);
        nfs4_put_stid(&ls->ls_stid);
        nfsd4_free_layouts(&reaplist);
        return nfs_ok;
@@ -608,6 +608,16 @@ nfsd4_cb_layout_fail(struct nfs4_layout_stateid *ls)
        }
 }
 
+static void
+nfsd4_cb_layout_prepare(struct nfsd4_callback *cb)
+{
+       struct nfs4_layout_stateid *ls =
+               container_of(cb, struct nfs4_layout_stateid, ls_recall);
+
+       mutex_lock(&ls->ls_mutex);
+       nfs4_inc_and_copy_stateid(&ls->ls_recall_sid, &ls->ls_stid);
+}
+
 static int
 nfsd4_cb_layout_done(struct nfsd4_callback *cb, struct rpc_task *task)
 {
@@ -649,12 +659,14 @@ nfsd4_cb_layout_release(struct nfsd4_callback *cb)
 
        trace_layout_recall_release(&ls->ls_stid.sc_stateid);
 
+       mutex_unlock(&ls->ls_mutex);
        nfsd4_return_all_layouts(ls, &reaplist);
        nfsd4_free_layouts(&reaplist);
        nfs4_put_stid(&ls->ls_stid);
 }
 
 static struct nfsd4_callback_ops nfsd4_cb_layout_ops = {
+       .prepare        = nfsd4_cb_layout_prepare,
        .done           = nfsd4_cb_layout_done,
        .release        = nfsd4_cb_layout_release,
 };
index 4ce6b97b31adec12b47deafecf28e2e672753b8f..a9f096c7e99f5dd36b40fac5bad04300e3b7f4e8 100644 (file)
@@ -1309,6 +1309,7 @@ nfsd4_layoutget(struct svc_rqst *rqstp,
        nfserr = nfsd4_insert_layout(lgp, ls);
 
 out_put_stid:
+       mutex_unlock(&ls->ls_mutex);
        nfs4_put_stid(&ls->ls_stid);
 out:
        return nfserr;
@@ -1362,6 +1363,9 @@ nfsd4_layoutcommit(struct svc_rqst *rqstp,
                goto out;
        }
 
+       /* LAYOUTCOMMIT does not require any serialization */
+       mutex_unlock(&ls->ls_mutex);
+
        if (new_size > i_size_read(inode)) {
                lcp->lc_size_chg = 1;
                lcp->lc_newsize = new_size;
index 0f1d5691b795751553d02003c32c4ceb90a1ee5c..6b800b5b8fedb5d60c8bf1a8d1ca6d35f3d54114 100644 (file)
@@ -575,6 +575,7 @@ struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl,
        stid->sc_stateid.si_opaque.so_clid = cl->cl_clientid;
        /* Will be incremented before return to client: */
        atomic_set(&stid->sc_count, 1);
+       spin_lock_init(&stid->sc_lock);
 
        /*
         * It shouldn't be a problem to reuse an opaque stateid value.
@@ -745,6 +746,18 @@ nfs4_put_stid(struct nfs4_stid *s)
                put_nfs4_file(fp);
 }
 
+void
+nfs4_inc_and_copy_stateid(stateid_t *dst, struct nfs4_stid *stid)
+{
+       stateid_t *src = &stid->sc_stateid;
+
+       spin_lock(&stid->sc_lock);
+       if (unlikely(++src->si_generation == 0))
+               src->si_generation = 1;
+       memcpy(dst, src, sizeof(*dst));
+       spin_unlock(&stid->sc_lock);
+}
+
 static void nfs4_put_deleg_lease(struct nfs4_file *fp)
 {
        struct file *filp = NULL;
@@ -765,16 +778,68 @@ void nfs4_unhash_stid(struct nfs4_stid *s)
        s->sc_type = 0;
 }
 
-static void
+/**
+ * nfs4_get_existing_delegation - Discover if this delegation already exists
+ * @clp:     a pointer to the nfs4_client we're granting a delegation to
+ * @fp:      a pointer to the nfs4_file we're granting a delegation on
+ *
+ * Return:
+ *      On success: NULL if an existing delegation was not found.
+ *
+ *      On error: -EAGAIN if one was previously granted to this nfs4_client
+ *                 for this nfs4_file.
+ *
+ */
+
+static int
+nfs4_get_existing_delegation(struct nfs4_client *clp, struct nfs4_file *fp)
+{
+       struct nfs4_delegation *searchdp = NULL;
+       struct nfs4_client *searchclp = NULL;
+
+       lockdep_assert_held(&state_lock);
+       lockdep_assert_held(&fp->fi_lock);
+
+       list_for_each_entry(searchdp, &fp->fi_delegations, dl_perfile) {
+               searchclp = searchdp->dl_stid.sc_client;
+               if (clp == searchclp) {
+                       return -EAGAIN;
+               }
+       }
+       return 0;
+}
+
+/**
+ * hash_delegation_locked - Add a delegation to the appropriate lists
+ * @dp:     a pointer to the nfs4_delegation we are adding.
+ * @fp:     a pointer to the nfs4_file we're granting a delegation on
+ *
+ * Return:
+ *      On success: NULL if the delegation was successfully hashed.
+ *
+ *      On error: -EAGAIN if one was previously granted to this
+ *                 nfs4_client for this nfs4_file. Delegation is not hashed.
+ *
+ */
+
+static int
 hash_delegation_locked(struct nfs4_delegation *dp, struct nfs4_file *fp)
 {
+       int status;
+       struct nfs4_client *clp = dp->dl_stid.sc_client;
+
        lockdep_assert_held(&state_lock);
        lockdep_assert_held(&fp->fi_lock);
 
+       status = nfs4_get_existing_delegation(clp, fp);
+       if (status)
+               return status;
+       ++fp->fi_delegees;
        atomic_inc(&dp->dl_stid.sc_count);
        dp->dl_stid.sc_type = NFS4_DELEG_STID;
        list_add(&dp->dl_perfile, &fp->fi_delegations);
-       list_add(&dp->dl_perclnt, &dp->dl_stid.sc_client->cl_delegations);
+       list_add(&dp->dl_perclnt, &clp->cl_delegations);
+       return 0;
 }
 
 static bool
@@ -2256,15 +2321,20 @@ nfsd4_set_ex_flags(struct nfs4_client *new, struct nfsd4_exchange_id *clid)
        clid->flags = new->cl_exchange_flags;
 }
 
+static bool client_has_openowners(struct nfs4_client *clp)
+{
+       struct nfs4_openowner *oo;
+
+       list_for_each_entry(oo, &clp->cl_openowners, oo_perclient) {
+               if (!list_empty(&oo->oo_owner.so_stateids))
+                       return true;
+       }
+       return false;
+}
+
 static bool client_has_state(struct nfs4_client *clp)
 {
-       /*
-        * Note clp->cl_openowners check isn't quite right: there's no
-        * need to count owners without stateid's.
-        *
-        * Also note we should probably be using this in 4.0 case too.
-        */
-       return !list_empty(&clp->cl_openowners)
+       return client_has_openowners(clp)
 #ifdef CONFIG_NFSD_PNFS
                || !list_empty(&clp->cl_lo_states)
 #endif
@@ -3049,7 +3119,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        /* Cases below refer to rfc 3530 section 14.2.33: */
        spin_lock(&nn->client_lock);
        conf = find_confirmed_client_by_name(&clname, nn);
-       if (conf) {
+       if (conf && client_has_state(conf)) {
                /* case 0: */
                status = nfserr_clid_inuse;
                if (clp_used_exchangeid(conf))
@@ -3136,6 +3206,11 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
        } else { /* case 3: normal case; new or rebooted client */
                old = find_confirmed_client_by_name(&unconf->cl_name, nn);
                if (old) {
+                       status = nfserr_clid_inuse;
+                       if (client_has_state(old)
+                                       && !same_creds(&unconf->cl_cred,
+                                                       &old->cl_cred))
+                               goto out;
                        status = mark_client_expired_locked(old);
                        if (status) {
                                old = NULL;
@@ -3317,6 +3392,27 @@ static const struct nfs4_stateowner_operations openowner_ops = {
        .so_free =      nfs4_free_openowner,
 };
 
+static struct nfs4_ol_stateid *
+nfsd4_find_existing_open(struct nfs4_file *fp, struct nfsd4_open *open)
+{
+       struct nfs4_ol_stateid *local, *ret = NULL;
+       struct nfs4_openowner *oo = open->op_openowner;
+
+       lockdep_assert_held(&fp->fi_lock);
+
+       list_for_each_entry(local, &fp->fi_stateids, st_perfile) {
+               /* ignore lock owners */
+               if (local->st_stateowner->so_is_open_owner == 0)
+                       continue;
+               if (local->st_stateowner == &oo->oo_owner) {
+                       ret = local;
+                       atomic_inc(&ret->st_stid.sc_count);
+                       break;
+               }
+       }
+       return ret;
+}
+
 static struct nfs4_openowner *
 alloc_init_open_stateowner(unsigned int strhashval, struct nfsd4_open *open,
                           struct nfsd4_compound_state *cstate)
@@ -3348,9 +3444,20 @@ alloc_init_open_stateowner(unsigned int strhashval, struct nfsd4_open *open,
        return ret;
 }
 
-static void init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp, struct nfsd4_open *open) {
+static struct nfs4_ol_stateid *
+init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp,
+               struct nfsd4_open *open)
+{
+
        struct nfs4_openowner *oo = open->op_openowner;
+       struct nfs4_ol_stateid *retstp = NULL;
 
+       spin_lock(&oo->oo_owner.so_client->cl_lock);
+       spin_lock(&fp->fi_lock);
+
+       retstp = nfsd4_find_existing_open(fp, open);
+       if (retstp)
+               goto out_unlock;
        atomic_inc(&stp->st_stid.sc_count);
        stp->st_stid.sc_type = NFS4_OPEN_STID;
        INIT_LIST_HEAD(&stp->st_locks);
@@ -3360,12 +3467,14 @@ static void init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp,
        stp->st_access_bmap = 0;
        stp->st_deny_bmap = 0;
        stp->st_openstp = NULL;
-       spin_lock(&oo->oo_owner.so_client->cl_lock);
+       init_rwsem(&stp->st_rwsem);
        list_add(&stp->st_perstateowner, &oo->oo_owner.so_stateids);
-       spin_lock(&fp->fi_lock);
        list_add(&stp->st_perfile, &fp->fi_stateids);
+
+out_unlock:
        spin_unlock(&fp->fi_lock);
        spin_unlock(&oo->oo_owner.so_client->cl_lock);
+       return retstp;
 }
 
 /*
@@ -3776,27 +3885,6 @@ out:
        return nfs_ok;
 }
 
-static struct nfs4_ol_stateid *
-nfsd4_find_existing_open(struct nfs4_file *fp, struct nfsd4_open *open)
-{
-       struct nfs4_ol_stateid *local, *ret = NULL;
-       struct nfs4_openowner *oo = open->op_openowner;
-
-       spin_lock(&fp->fi_lock);
-       list_for_each_entry(local, &fp->fi_stateids, st_perfile) {
-               /* ignore lock owners */
-               if (local->st_stateowner->so_is_open_owner == 0)
-                       continue;
-               if (local->st_stateowner == &oo->oo_owner) {
-                       ret = local;
-                       atomic_inc(&ret->st_stid.sc_count);
-                       break;
-               }
-       }
-       spin_unlock(&fp->fi_lock);
-       return ret;
-}
-
 static inline int nfs4_access_to_access(u32 nfs4_access)
 {
        int flags = 0;
@@ -3945,6 +4033,18 @@ static struct file_lock *nfs4_alloc_init_lease(struct nfs4_file *fp, int flag)
        return fl;
 }
 
+/**
+ * nfs4_setlease - Obtain a delegation by requesting lease from vfs layer
+ * @dp:   a pointer to the nfs4_delegation we're adding.
+ *
+ * Return:
+ *      On success: Return code will be 0 on success.
+ *
+ *      On error: -EAGAIN if there was an existing delegation.
+ *                 nonzero if there is an error in other cases.
+ *
+ */
+
 static int nfs4_setlease(struct nfs4_delegation *dp)
 {
        struct nfs4_file *fp = dp->dl_stid.sc_file;
@@ -3976,16 +4076,19 @@ static int nfs4_setlease(struct nfs4_delegation *dp)
                goto out_unlock;
        /* Race breaker */
        if (fp->fi_deleg_file) {
-               status = 0;
-               ++fp->fi_delegees;
-               hash_delegation_locked(dp, fp);
+               status = hash_delegation_locked(dp, fp);
                goto out_unlock;
        }
        fp->fi_deleg_file = filp;
-       fp->fi_delegees = 1;
-       hash_delegation_locked(dp, fp);
+       fp->fi_delegees = 0;
+       status = hash_delegation_locked(dp, fp);
        spin_unlock(&fp->fi_lock);
        spin_unlock(&state_lock);
+       if (status) {
+               /* Should never happen, this is a new fi_deleg_file  */
+               WARN_ON_ONCE(1);
+               goto out_fput;
+       }
        return 0;
 out_unlock:
        spin_unlock(&fp->fi_lock);
@@ -4005,6 +4108,15 @@ nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh,
        if (fp->fi_had_conflict)
                return ERR_PTR(-EAGAIN);
 
+       spin_lock(&state_lock);
+       spin_lock(&fp->fi_lock);
+       status = nfs4_get_existing_delegation(clp, fp);
+       spin_unlock(&fp->fi_lock);
+       spin_unlock(&state_lock);
+
+       if (status)
+               return ERR_PTR(status);
+
        dp = alloc_init_deleg(clp, fh, odstate);
        if (!dp)
                return ERR_PTR(-ENOMEM);
@@ -4023,9 +4135,7 @@ nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh,
                status = -EAGAIN;
                goto out_unlock;
        }
-       ++fp->fi_delegees;
-       hash_delegation_locked(dp, fp);
-       status = 0;
+       status = hash_delegation_locked(dp, fp);
 out_unlock:
        spin_unlock(&fp->fi_lock);
        spin_unlock(&state_lock);
@@ -4160,6 +4270,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
        struct nfs4_client *cl = open->op_openowner->oo_owner.so_client;
        struct nfs4_file *fp = NULL;
        struct nfs4_ol_stateid *stp = NULL;
+       struct nfs4_ol_stateid *swapstp = NULL;
        struct nfs4_delegation *dp = NULL;
        __be32 status;
 
@@ -4173,7 +4284,9 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
                status = nfs4_check_deleg(cl, open, &dp);
                if (status)
                        goto out;
+               spin_lock(&fp->fi_lock);
                stp = nfsd4_find_existing_open(fp, open);
+               spin_unlock(&fp->fi_lock);
        } else {
                open->op_file = NULL;
                status = nfserr_bad_stateid;
@@ -4187,15 +4300,32 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
         */
        if (stp) {
                /* Stateid was found, this is an OPEN upgrade */
+               down_read(&stp->st_rwsem);
                status = nfs4_upgrade_open(rqstp, fp, current_fh, stp, open);
-               if (status)
+               if (status) {
+                       up_read(&stp->st_rwsem);
                        goto out;
+               }
        } else {
                stp = open->op_stp;
                open->op_stp = NULL;
-               init_open_stateid(stp, fp, open);
+               swapstp = init_open_stateid(stp, fp, open);
+               if (swapstp) {
+                       nfs4_put_stid(&stp->st_stid);
+                       stp = swapstp;
+                       down_read(&stp->st_rwsem);
+                       status = nfs4_upgrade_open(rqstp, fp, current_fh,
+                                               stp, open);
+                       if (status) {
+                               up_read(&stp->st_rwsem);
+                               goto out;
+                       }
+                       goto upgrade_out;
+               }
+               down_read(&stp->st_rwsem);
                status = nfs4_get_vfs_file(rqstp, fp, current_fh, stp, open);
                if (status) {
+                       up_read(&stp->st_rwsem);
                        release_open_stateid(stp);
                        goto out;
                }
@@ -4205,8 +4335,9 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
                if (stp->st_clnt_odstate == open->op_odstate)
                        open->op_odstate = NULL;
        }
-       update_stateid(&stp->st_stid.sc_stateid);
-       memcpy(&open->op_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
+upgrade_out:
+       nfs4_inc_and_copy_stateid(&open->op_stateid, &stp->st_stid);
+       up_read(&stp->st_rwsem);
 
        if (nfsd4_has_session(&resp->cstate)) {
                if (open->op_deleg_want & NFS4_SHARE_WANT_NO_DELEG) {
@@ -4819,10 +4950,13 @@ static __be32 nfs4_seqid_op_checks(struct nfsd4_compound_state *cstate, stateid_
                 * revoked delegations are kept only for free_stateid.
                 */
                return nfserr_bad_stateid;
+       down_write(&stp->st_rwsem);
        status = check_stateid_generation(stateid, &stp->st_stid.sc_stateid, nfsd4_has_session(cstate));
-       if (status)
-               return status;
-       return nfs4_check_fh(current_fh, &stp->st_stid);
+       if (status == nfs_ok)
+               status = nfs4_check_fh(current_fh, &stp->st_stid);
+       if (status != nfs_ok)
+               up_write(&stp->st_rwsem);
+       return status;
 }
 
 /* 
@@ -4869,6 +5003,7 @@ static __be32 nfs4_preprocess_confirmed_seqid_op(struct nfsd4_compound_state *cs
                return status;
        oo = openowner(stp->st_stateowner);
        if (!(oo->oo_flags & NFS4_OO_CONFIRMED)) {
+               up_write(&stp->st_rwsem);
                nfs4_put_stid(&stp->st_stid);
                return nfserr_bad_stateid;
        }
@@ -4899,11 +5034,13 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                goto out;
        oo = openowner(stp->st_stateowner);
        status = nfserr_bad_stateid;
-       if (oo->oo_flags & NFS4_OO_CONFIRMED)
+       if (oo->oo_flags & NFS4_OO_CONFIRMED) {
+               up_write(&stp->st_rwsem);
                goto put_stateid;
+       }
        oo->oo_flags |= NFS4_OO_CONFIRMED;
-       update_stateid(&stp->st_stid.sc_stateid);
-       memcpy(&oc->oc_resp_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
+       nfs4_inc_and_copy_stateid(&oc->oc_resp_stateid, &stp->st_stid);
+       up_write(&stp->st_rwsem);
        dprintk("NFSD: %s: success, seqid=%d stateid=" STATEID_FMT "\n",
                __func__, oc->oc_seqid, STATEID_VAL(&stp->st_stid.sc_stateid));
 
@@ -4975,13 +5112,11 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
                goto put_stateid;
        }
        nfs4_stateid_downgrade(stp, od->od_share_access);
-
        reset_union_bmap_deny(od->od_share_deny, stp);
-
-       update_stateid(&stp->st_stid.sc_stateid);
-       memcpy(&od->od_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
+       nfs4_inc_and_copy_stateid(&od->od_stateid, &stp->st_stid);
        status = nfs_ok;
 put_stateid:
+       up_write(&stp->st_rwsem);
        nfs4_put_stid(&stp->st_stid);
 out:
        nfsd4_bump_seqid(cstate, status);
@@ -5033,8 +5168,8 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        nfsd4_bump_seqid(cstate, status);
        if (status)
                goto out; 
-       update_stateid(&stp->st_stid.sc_stateid);
-       memcpy(&close->cl_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
+       nfs4_inc_and_copy_stateid(&close->cl_stateid, &stp->st_stid);
+       up_write(&stp->st_rwsem);
 
        nfsd4_close_open_stateid(stp);
 
@@ -5260,6 +5395,7 @@ init_lock_stateid(struct nfs4_ol_stateid *stp, struct nfs4_lockowner *lo,
        stp->st_access_bmap = 0;
        stp->st_deny_bmap = open_stp->st_deny_bmap;
        stp->st_openstp = open_stp;
+       init_rwsem(&stp->st_rwsem);
        list_add(&stp->st_locks, &open_stp->st_locks);
        list_add(&stp->st_perstateowner, &lo->lo_owner.so_stateids);
        spin_lock(&fp->fi_lock);
@@ -5428,6 +5564,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                                        &open_stp, nn);
                if (status)
                        goto out;
+               up_write(&open_stp->st_rwsem);
                open_sop = openowner(open_stp->st_stateowner);
                status = nfserr_bad_stateid;
                if (!same_clid(&open_sop->oo_owner.so_client->cl_clientid,
@@ -5435,6 +5572,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                        goto out;
                status = lookup_or_create_lock_state(cstate, open_stp, lock,
                                                        &lock_stp, &new);
+               if (status == nfs_ok)
+                       down_write(&lock_stp->st_rwsem);
        } else {
                status = nfs4_preprocess_seqid_op(cstate,
                                       lock->lk_old_lock_seqid,
@@ -5512,9 +5651,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        err = vfs_lock_file(filp, F_SETLK, file_lock, conflock);
        switch (-err) {
        case 0: /* success! */
-               update_stateid(&lock_stp->st_stid.sc_stateid);
-               memcpy(&lock->lk_resp_stateid, &lock_stp->st_stid.sc_stateid, 
-                               sizeof(stateid_t));
+               nfs4_inc_and_copy_stateid(&lock->lk_resp_stateid, &lock_stp->st_stid);
                status = 0;
                break;
        case (EAGAIN):          /* conflock holds conflicting lock */
@@ -5540,6 +5677,8 @@ out:
                    seqid_mutating_err(ntohl(status)))
                        lock_sop->lo_owner.so_seqid++;
 
+               up_write(&lock_stp->st_rwsem);
+
                /*
                 * If this is a new, never-before-used stateid, and we are
                 * returning an error, then just go ahead and release it.
@@ -5704,11 +5843,11 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                dprintk("NFSD: nfs4_locku: vfs_lock_file failed!\n");
                goto out_nfserr;
        }
-       update_stateid(&stp->st_stid.sc_stateid);
-       memcpy(&locku->lu_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
+       nfs4_inc_and_copy_stateid(&locku->lu_stateid, &stp->st_stid);
 fput:
        fput(filp);
 put_stateid:
+       up_write(&stp->st_rwsem);
        nfs4_put_stid(&stp->st_stid);
 out:
        nfsd4_bump_seqid(cstate, status);
index 46ec934f5dee8c529020558bed4cd820956734f1..54cde9a5864e18f12ed198474c4f48c0dc8b1f16 100644 (file)
@@ -63,7 +63,6 @@ static unsigned int           longest_chain;
 static unsigned int            longest_chain_cachesize;
 
 static int     nfsd_cache_append(struct svc_rqst *rqstp, struct kvec *vec);
-static void    cache_cleaner_func(struct work_struct *unused);
 static unsigned long nfsd_reply_cache_count(struct shrinker *shrink,
                                            struct shrink_control *sc);
 static unsigned long nfsd_reply_cache_scan(struct shrinker *shrink,
@@ -75,13 +74,6 @@ static struct shrinker nfsd_reply_cache_shrinker = {
        .seeks  = 1,
 };
 
-/*
- * locking for the reply cache:
- * A cache entry is "single use" if c_state == RC_INPROG
- * Otherwise, it when accessing _prev or _next, the lock must be held.
- */
-static DECLARE_DELAYED_WORK(cache_cleaner, cache_cleaner_func);
-
 /*
  * Put a cap on the size of the DRC based on the amount of available
  * low memory in the machine.
@@ -203,7 +195,6 @@ void nfsd_reply_cache_shutdown(void)
        unsigned int i;
 
        unregister_shrinker(&nfsd_reply_cache_shrinker);
-       cancel_delayed_work_sync(&cache_cleaner);
 
        for (i = 0; i < drc_hashsize; i++) {
                struct list_head *head = &drc_hashtbl[i].lru_head;
@@ -217,10 +208,8 @@ void nfsd_reply_cache_shutdown(void)
        drc_hashtbl = NULL;
        drc_hashsize = 0;
 
-       if (drc_slab) {
-               kmem_cache_destroy(drc_slab);
-               drc_slab = NULL;
-       }
+       kmem_cache_destroy(drc_slab);
+       drc_slab = NULL;
 }
 
 /*
@@ -232,7 +221,6 @@ lru_put_end(struct nfsd_drc_bucket *b, struct svc_cacherep *rp)
 {
        rp->c_timestamp = jiffies;
        list_move_tail(&rp->c_lru, &b->lru_head);
-       schedule_delayed_work(&cache_cleaner, RC_EXPIRE);
 }
 
 static long
@@ -266,7 +254,6 @@ prune_cache_entries(void)
 {
        unsigned int i;
        long freed = 0;
-       bool cancel = true;
 
        for (i = 0; i < drc_hashsize; i++) {
                struct nfsd_drc_bucket *b = &drc_hashtbl[i];
@@ -275,26 +262,11 @@ prune_cache_entries(void)
                        continue;
                spin_lock(&b->cache_lock);
                freed += prune_bucket(b);
-               if (!list_empty(&b->lru_head))
-                       cancel = false;
                spin_unlock(&b->cache_lock);
        }
-
-       /*
-        * Conditionally rearm the job to run in RC_EXPIRE since we just
-        * ran the pruner.
-        */
-       if (!cancel)
-               mod_delayed_work(system_wq, &cache_cleaner, RC_EXPIRE);
        return freed;
 }
 
-static void
-cache_cleaner_func(struct work_struct *unused)
-{
-       prune_cache_entries();
-}
-
 static unsigned long
 nfsd_reply_cache_count(struct shrinker *shrink, struct shrink_control *sc)
 {
index 350041a40fe519ac22fa14901c84a6dfddcec9c1..c1681ce894c5e51f9c384e42c01fc6b440b6c70e 100644 (file)
@@ -631,10 +631,7 @@ fh_put(struct svc_fh *fhp)
                fh_unlock(fhp);
                fhp->fh_dentry = NULL;
                dput(dentry);
-#ifdef CONFIG_NFSD_V3
-               fhp->fh_pre_saved = 0;
-               fhp->fh_post_saved = 0;
-#endif
+               fh_clear_wcc(fhp);
        }
        fh_drop_write(fhp);
        if (exp) {
index 1e90dad4926b4aa2e5158d5d0e7acb7c26d73472..2087bae17582a9631bba33777f93b94da6e3e452 100644 (file)
@@ -26,16 +26,16 @@ static inline ino_t u32_to_ino_t(__u32 uino)
  */
 typedef struct svc_fh {
        struct knfsd_fh         fh_handle;      /* FH data */
+       int                     fh_maxsize;     /* max size for fh_handle */
        struct dentry *         fh_dentry;      /* validated dentry */
        struct svc_export *     fh_export;      /* export pointer */
-       int                     fh_maxsize;     /* max size for fh_handle */
 
-       unsigned char           fh_locked;      /* inode locked by us */
-       unsigned char           fh_want_write;  /* remount protection taken */
+       bool                    fh_locked;      /* inode locked by us */
+       bool                    fh_want_write;  /* remount protection taken */
 
 #ifdef CONFIG_NFSD_V3
-       unsigned char           fh_post_saved;  /* post-op attrs saved */
-       unsigned char           fh_pre_saved;   /* pre-op attrs saved */
+       bool                    fh_post_saved;  /* post-op attrs saved */
+       bool                    fh_pre_saved;   /* pre-op attrs saved */
 
        /* Pre-op attributes saved during fh_lock */
        __u64                   fh_pre_size;    /* size before operation */
@@ -213,8 +213,8 @@ static inline bool fh_fsid_match(struct knfsd_fh *fh1, struct knfsd_fh *fh2)
 static inline void
 fh_clear_wcc(struct svc_fh *fhp)
 {
-       fhp->fh_post_saved = 0;
-       fhp->fh_pre_saved = 0;
+       fhp->fh_post_saved = false;
+       fhp->fh_pre_saved = false;
 }
 
 /*
@@ -231,7 +231,7 @@ fill_pre_wcc(struct svc_fh *fhp)
                fhp->fh_pre_ctime = inode->i_ctime;
                fhp->fh_pre_size  = inode->i_size;
                fhp->fh_pre_change = inode->i_version;
-               fhp->fh_pre_saved = 1;
+               fhp->fh_pre_saved = true;
        }
 }
 
@@ -267,7 +267,7 @@ fh_lock_nested(struct svc_fh *fhp, unsigned int subclass)
        inode = d_inode(dentry);
        mutex_lock_nested(&inode->i_mutex, subclass);
        fill_pre_wcc(fhp);
-       fhp->fh_locked = 1;
+       fhp->fh_locked = true;
 }
 
 static inline void
@@ -285,7 +285,7 @@ fh_unlock(struct svc_fh *fhp)
        if (fhp->fh_locked) {
                fill_post_wcc(fhp);
                mutex_unlock(&d_inode(fhp->fh_dentry)->i_mutex);
-               fhp->fh_locked = 0;
+               fhp->fh_locked = false;
        }
 }
 
index 583ffc13cae27d165be052609f37dc7428b54dcc..77fdf4de91baa102dbefd2f15c5314be40aff162 100644 (file)
@@ -84,7 +84,7 @@ struct nfsd4_callback_ops {
  * fields that are of general use to any stateid.
  */
 struct nfs4_stid {
-       atomic_t sc_count;
+       atomic_t                sc_count;
 #define NFS4_OPEN_STID 1
 #define NFS4_LOCK_STID 2
 #define NFS4_DELEG_STID 4
@@ -94,11 +94,12 @@ struct nfs4_stid {
 #define NFS4_REVOKED_DELEG_STID 16
 #define NFS4_CLOSED_DELEG_STID 32
 #define NFS4_LAYOUT_STID 64
-       unsigned char sc_type;
-       stateid_t sc_stateid;
-       struct nfs4_client *sc_client;
-       struct nfs4_file *sc_file;
-       void (*sc_free)(struct nfs4_stid *);
+       unsigned char           sc_type;
+       stateid_t               sc_stateid;
+       spinlock_t              sc_lock;
+       struct nfs4_client      *sc_client;
+       struct nfs4_file        *sc_file;
+       void                    (*sc_free)(struct nfs4_stid *);
 };
 
 /*
@@ -364,15 +365,6 @@ struct nfs4_client_reclaim {
        char                    cr_recdir[HEXDIR_LEN]; /* recover dir */
 };
 
-static inline void
-update_stateid(stateid_t *stateid)
-{
-       stateid->si_generation++;
-       /* Wraparound recommendation from 3530bis-13 9.1.3.2: */
-       if (stateid->si_generation == 0)
-               stateid->si_generation = 1;
-}
-
 /* A reasonable value for REPLAY_ISIZE was estimated as follows:  
  * The OPEN response, typically the largest, requires 
  *   4(status) + 8(stateid) + 20(changeinfo) + 4(rflags) +  8(verifier) + 
@@ -534,15 +526,16 @@ struct nfs4_file {
  * Better suggestions welcome.
  */
 struct nfs4_ol_stateid {
-       struct nfs4_stid    st_stid; /* must be first field */
-       struct list_head              st_perfile;
-       struct list_head              st_perstateowner;
-       struct list_head              st_locks;
-       struct nfs4_stateowner      * st_stateowner;
-       struct nfs4_clnt_odstate    * st_clnt_odstate;
-       unsigned char                 st_access_bmap;
-       unsigned char                 st_deny_bmap;
-       struct nfs4_ol_stateid         * st_openstp;
+       struct nfs4_stid                st_stid;
+       struct list_head                st_perfile;
+       struct list_head                st_perstateowner;
+       struct list_head                st_locks;
+       struct nfs4_stateowner          *st_stateowner;
+       struct nfs4_clnt_odstate        *st_clnt_odstate;
+       unsigned char                   st_access_bmap;
+       unsigned char                   st_deny_bmap;
+       struct nfs4_ol_stateid          *st_openstp;
+       struct rw_semaphore             st_rwsem;
 };
 
 static inline struct nfs4_ol_stateid *openlockstateid(struct nfs4_stid *s)
@@ -561,6 +554,7 @@ struct nfs4_layout_stateid {
        struct nfsd4_callback           ls_recall;
        stateid_t                       ls_recall_sid;
        bool                            ls_recalled;
+       struct mutex                    ls_mutex;
 };
 
 static inline struct nfs4_layout_stateid *layoutstateid(struct nfs4_stid *s)
@@ -593,6 +587,7 @@ struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl,
                struct kmem_cache *slab);
 void nfs4_unhash_stid(struct nfs4_stid *s);
 void nfs4_put_stid(struct nfs4_stid *s);
+void nfs4_inc_and_copy_stateid(stateid_t *dst, struct nfs4_stid *stid);
 void nfs4_remove_reclaim_record(struct nfs4_client_reclaim *, struct nfsd_net *);
 extern void nfs4_release_reclaim(struct nfsd_net *);
 extern struct nfs4_client_reclaim *nfsd4_find_reclaim_client(const char *recdir,
index 82f89070594c7671018b98e0cd116ceb7870fd79..90967466a1e56bc9ec6d1fc36aa5e815721328a5 100644 (file)
@@ -1,5 +1,3 @@
 
-#include "state.h"
-
 #define CREATE_TRACE_POINTS
 #include "trace.h"
index c668520c344b5290a219a499af313978f22c51fc..0befe762762b0eb8837df625b71e2f165e668d1e 100644 (file)
@@ -9,6 +9,8 @@
 
 #include <linux/tracepoint.h>
 
+#include "state.h"
+
 DECLARE_EVENT_CLASS(nfsd_stateid_class,
        TP_PROTO(stateid_t *stp),
        TP_ARGS(stp),
index 45c04979e7b3c1fed3d14c387c50de9ce95a729a..994d66fbb4467ac8892a4d2ae0e5e9fda2a05722 100644 (file)
@@ -1631,7 +1631,7 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
        /* cannot use fh_lock as we need deadlock protective ordering
         * so do it by hand */
        trap = lock_rename(tdentry, fdentry);
-       ffhp->fh_locked = tfhp->fh_locked = 1;
+       ffhp->fh_locked = tfhp->fh_locked = true;
        fill_pre_wcc(ffhp);
        fill_pre_wcc(tfhp);
 
@@ -1681,7 +1681,7 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
        fill_post_wcc(ffhp);
        fill_post_wcc(tfhp);
        unlock_rename(tdentry, fdentry);
-       ffhp->fh_locked = tfhp->fh_locked = 0;
+       ffhp->fh_locked = tfhp->fh_locked = false;
        fh_drop_write(ffhp);
 
 out:
index fee2451ae24824830481e1d4005922e63f39dabe..fcfc48cbe1360822896d479c3e0a6bf8997c147c 100644 (file)
@@ -112,14 +112,14 @@ static inline int fh_want_write(struct svc_fh *fh)
        int ret = mnt_want_write(fh->fh_export->ex_path.mnt);
 
        if (!ret)
-               fh->fh_want_write = 1;
+               fh->fh_want_write = true;
        return ret;
 }
 
 static inline void fh_drop_write(struct svc_fh *fh)
 {
        if (fh->fh_want_write) {
-               fh->fh_want_write = 0;
+               fh->fh_want_write = false;
                mnt_drop_write(fh->fh_export->ex_path.mnt);
        }
 }
index 9f991007a5781314d1473bf826062e59c8918ef8..ce7362c88b4875958201b5c8db9e35f3347dd4a8 100644 (file)
@@ -632,7 +632,7 @@ static inline void
 set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp)
 {
        BUG_ON(!fhp->fh_pre_saved);
-       cinfo->atomic = fhp->fh_post_saved;
+       cinfo->atomic = (u32)fhp->fh_post_saved;
        cinfo->change_supported = IS_I_VERSION(d_inode(fhp->fh_dentry));
 
        cinfo->before_change = fhp->fh_pre_change;
index 54575e3cc1a24eda326fd19bde268bbc1b187f21..088ba001c6ef5e622d31b3a0f2786451c369eb72 100644 (file)
@@ -109,7 +109,7 @@ static int nilfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
                goto out;
 
        file_update_time(vma->vm_file);
-       ret = __block_page_mkwrite(vma, vmf, nilfs_get_block);
+       ret = block_page_mkwrite(vma, vmf, nilfs_get_block);
        if (ret) {
                nilfs_transaction_abort(inode->i_sb);
                goto out;
index ddddef0021a0f8cd94f456969099bc660ec1fdb5..709fbbd44c65366ce1e31aebce0904b5966d53a6 100644 (file)
@@ -1480,16 +1480,17 @@ static int o2hb_read_block_input(struct o2hb_region *reg,
        return 0;
 }
 
-static ssize_t o2hb_region_block_bytes_read(struct o2hb_region *reg,
+static ssize_t o2hb_region_block_bytes_show(struct config_item *item,
                                            char *page)
 {
-       return sprintf(page, "%u\n", reg->hr_block_bytes);
+       return sprintf(page, "%u\n", to_o2hb_region(item)->hr_block_bytes);
 }
 
-static ssize_t o2hb_region_block_bytes_write(struct o2hb_region *reg,
+static ssize_t o2hb_region_block_bytes_store(struct config_item *item,
                                             const char *page,
                                             size_t count)
 {
+       struct o2hb_region *reg = to_o2hb_region(item);
        int status;
        unsigned long block_bytes;
        unsigned int block_bits;
@@ -1508,16 +1509,17 @@ static ssize_t o2hb_region_block_bytes_write(struct o2hb_region *reg,
        return count;
 }
 
-static ssize_t o2hb_region_start_block_read(struct o2hb_region *reg,
+static ssize_t o2hb_region_start_block_show(struct config_item *item,
                                            char *page)
 {
-       return sprintf(page, "%llu\n", reg->hr_start_block);
+       return sprintf(page, "%llu\n", to_o2hb_region(item)->hr_start_block);
 }
 
-static ssize_t o2hb_region_start_block_write(struct o2hb_region *reg,
+static ssize_t o2hb_region_start_block_store(struct config_item *item,
                                             const char *page,
                                             size_t count)
 {
+       struct o2hb_region *reg = to_o2hb_region(item);
        unsigned long long tmp;
        char *p = (char *)page;
 
@@ -1533,16 +1535,16 @@ static ssize_t o2hb_region_start_block_write(struct o2hb_region *reg,
        return count;
 }
 
-static ssize_t o2hb_region_blocks_read(struct o2hb_region *reg,
-                                      char *page)
+static ssize_t o2hb_region_blocks_show(struct config_item *item, char *page)
 {
-       return sprintf(page, "%d\n", reg->hr_blocks);
+       return sprintf(page, "%d\n", to_o2hb_region(item)->hr_blocks);
 }
 
-static ssize_t o2hb_region_blocks_write(struct o2hb_region *reg,
+static ssize_t o2hb_region_blocks_store(struct config_item *item,
                                        const char *page,
                                        size_t count)
 {
+       struct o2hb_region *reg = to_o2hb_region(item);
        unsigned long tmp;
        char *p = (char *)page;
 
@@ -1561,13 +1563,12 @@ static ssize_t o2hb_region_blocks_write(struct o2hb_region *reg,
        return count;
 }
 
-static ssize_t o2hb_region_dev_read(struct o2hb_region *reg,
-                                   char *page)
+static ssize_t o2hb_region_dev_show(struct config_item *item, char *page)
 {
        unsigned int ret = 0;
 
-       if (reg->hr_bdev)
-               ret = sprintf(page, "%s\n", reg->hr_dev_name);
+       if (to_o2hb_region(item)->hr_bdev)
+               ret = sprintf(page, "%s\n", to_o2hb_region(item)->hr_dev_name);
 
        return ret;
 }
@@ -1677,10 +1678,11 @@ out:
 }
 
 /* this is acting as commit; we set up all of hr_bdev and hr_task or nothing */
-static ssize_t o2hb_region_dev_write(struct o2hb_region *reg,
+static ssize_t o2hb_region_dev_store(struct config_item *item,
                                     const char *page,
                                     size_t count)
 {
+       struct o2hb_region *reg = to_o2hb_region(item);
        struct task_struct *hb_task;
        long fd;
        int sectsize;
@@ -1841,9 +1843,9 @@ out:
        return ret;
 }
 
-static ssize_t o2hb_region_pid_read(struct o2hb_region *reg,
-                                      char *page)
+static ssize_t o2hb_region_pid_show(struct config_item *item, char *page)
 {
+       struct o2hb_region *reg = to_o2hb_region(item);
        pid_t pid = 0;
 
        spin_lock(&o2hb_live_lock);
@@ -1857,92 +1859,23 @@ static ssize_t o2hb_region_pid_read(struct o2hb_region *reg,
        return sprintf(page, "%u\n", pid);
 }
 
-struct o2hb_region_attribute {
-       struct configfs_attribute attr;
-       ssize_t (*show)(struct o2hb_region *, char *);
-       ssize_t (*store)(struct o2hb_region *, const char *, size_t);
-};
-
-static struct o2hb_region_attribute o2hb_region_attr_block_bytes = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                   .ca_name = "block_bytes",
-                   .ca_mode = S_IRUGO | S_IWUSR },
-       .show   = o2hb_region_block_bytes_read,
-       .store  = o2hb_region_block_bytes_write,
-};
-
-static struct o2hb_region_attribute o2hb_region_attr_start_block = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                   .ca_name = "start_block",
-                   .ca_mode = S_IRUGO | S_IWUSR },
-       .show   = o2hb_region_start_block_read,
-       .store  = o2hb_region_start_block_write,
-};
-
-static struct o2hb_region_attribute o2hb_region_attr_blocks = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                   .ca_name = "blocks",
-                   .ca_mode = S_IRUGO | S_IWUSR },
-       .show   = o2hb_region_blocks_read,
-       .store  = o2hb_region_blocks_write,
-};
-
-static struct o2hb_region_attribute o2hb_region_attr_dev = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                   .ca_name = "dev",
-                   .ca_mode = S_IRUGO | S_IWUSR },
-       .show   = o2hb_region_dev_read,
-       .store  = o2hb_region_dev_write,
-};
-
-static struct o2hb_region_attribute o2hb_region_attr_pid = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                   .ca_name = "pid",
-                   .ca_mode = S_IRUGO | S_IRUSR },
-       .show   = o2hb_region_pid_read,
-};
+CONFIGFS_ATTR(o2hb_region_, block_bytes);
+CONFIGFS_ATTR(o2hb_region_, start_block);
+CONFIGFS_ATTR(o2hb_region_, blocks);
+CONFIGFS_ATTR(o2hb_region_, dev);
+CONFIGFS_ATTR_RO(o2hb_region_, pid);
 
 static struct configfs_attribute *o2hb_region_attrs[] = {
-       &o2hb_region_attr_block_bytes.attr,
-       &o2hb_region_attr_start_block.attr,
-       &o2hb_region_attr_blocks.attr,
-       &o2hb_region_attr_dev.attr,
-       &o2hb_region_attr_pid.attr,
+       &o2hb_region_attr_block_bytes,
+       &o2hb_region_attr_start_block,
+       &o2hb_region_attr_blocks,
+       &o2hb_region_attr_dev,
+       &o2hb_region_attr_pid,
        NULL,
 };
 
-static ssize_t o2hb_region_show(struct config_item *item,
-                               struct configfs_attribute *attr,
-                               char *page)
-{
-       struct o2hb_region *reg = to_o2hb_region(item);
-       struct o2hb_region_attribute *o2hb_region_attr =
-               container_of(attr, struct o2hb_region_attribute, attr);
-       ssize_t ret = 0;
-
-       if (o2hb_region_attr->show)
-               ret = o2hb_region_attr->show(reg, page);
-       return ret;
-}
-
-static ssize_t o2hb_region_store(struct config_item *item,
-                                struct configfs_attribute *attr,
-                                const char *page, size_t count)
-{
-       struct o2hb_region *reg = to_o2hb_region(item);
-       struct o2hb_region_attribute *o2hb_region_attr =
-               container_of(attr, struct o2hb_region_attribute, attr);
-       ssize_t ret = -EINVAL;
-
-       if (o2hb_region_attr->store)
-               ret = o2hb_region_attr->store(reg, page, count);
-       return ret;
-}
-
 static struct configfs_item_operations o2hb_region_item_ops = {
        .release                = o2hb_region_release,
-       .show_attribute         = o2hb_region_show,
-       .store_attribute        = o2hb_region_store,
 };
 
 static struct config_item_type o2hb_region_type = {
@@ -2137,49 +2070,14 @@ unlock:
        spin_unlock(&o2hb_live_lock);
 }
 
-struct o2hb_heartbeat_group_attribute {
-       struct configfs_attribute attr;
-       ssize_t (*show)(struct o2hb_heartbeat_group *, char *);
-       ssize_t (*store)(struct o2hb_heartbeat_group *, const char *, size_t);
-};
-
-static ssize_t o2hb_heartbeat_group_show(struct config_item *item,
-                                        struct configfs_attribute *attr,
-                                        char *page)
-{
-       struct o2hb_heartbeat_group *reg = to_o2hb_heartbeat_group(to_config_group(item));
-       struct o2hb_heartbeat_group_attribute *o2hb_heartbeat_group_attr =
-               container_of(attr, struct o2hb_heartbeat_group_attribute, attr);
-       ssize_t ret = 0;
-
-       if (o2hb_heartbeat_group_attr->show)
-               ret = o2hb_heartbeat_group_attr->show(reg, page);
-       return ret;
-}
-
-static ssize_t o2hb_heartbeat_group_store(struct config_item *item,
-                                         struct configfs_attribute *attr,
-                                         const char *page, size_t count)
-{
-       struct o2hb_heartbeat_group *reg = to_o2hb_heartbeat_group(to_config_group(item));
-       struct o2hb_heartbeat_group_attribute *o2hb_heartbeat_group_attr =
-               container_of(attr, struct o2hb_heartbeat_group_attribute, attr);
-       ssize_t ret = -EINVAL;
-
-       if (o2hb_heartbeat_group_attr->store)
-               ret = o2hb_heartbeat_group_attr->store(reg, page, count);
-       return ret;
-}
-
-static ssize_t o2hb_heartbeat_group_threshold_show(struct o2hb_heartbeat_group *group,
-                                                    char *page)
+static ssize_t o2hb_heartbeat_group_threshold_show(struct config_item *item,
+               char *page)
 {
        return sprintf(page, "%u\n", o2hb_dead_threshold);
 }
 
-static ssize_t o2hb_heartbeat_group_threshold_store(struct o2hb_heartbeat_group *group,
-                                                   const char *page,
-                                                   size_t count)
+static ssize_t o2hb_heartbeat_group_threshold_store(struct config_item *item,
+               const char *page, size_t count)
 {
        unsigned long tmp;
        char *p = (char *)page;
@@ -2194,17 +2092,15 @@ static ssize_t o2hb_heartbeat_group_threshold_store(struct o2hb_heartbeat_group
        return count;
 }
 
-static
-ssize_t o2hb_heartbeat_group_mode_show(struct o2hb_heartbeat_group *group,
-                                      char *page)
+static ssize_t o2hb_heartbeat_group_mode_show(struct config_item *item,
+               char *page)
 {
        return sprintf(page, "%s\n",
                       o2hb_heartbeat_mode_desc[o2hb_heartbeat_mode]);
 }
 
-static
-ssize_t o2hb_heartbeat_group_mode_store(struct o2hb_heartbeat_group *group,
-                                       const char *page, size_t count)
+static ssize_t o2hb_heartbeat_group_mode_store(struct config_item *item,
+               const char *page, size_t count)
 {
        unsigned int i;
        int ret;
@@ -2229,33 +2125,15 @@ ssize_t o2hb_heartbeat_group_mode_store(struct o2hb_heartbeat_group *group,
 
 }
 
-static struct o2hb_heartbeat_group_attribute o2hb_heartbeat_group_attr_threshold = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                   .ca_name = "dead_threshold",
-                   .ca_mode = S_IRUGO | S_IWUSR },
-       .show   = o2hb_heartbeat_group_threshold_show,
-       .store  = o2hb_heartbeat_group_threshold_store,
-};
-
-static struct o2hb_heartbeat_group_attribute o2hb_heartbeat_group_attr_mode = {
-       .attr   = { .ca_owner = THIS_MODULE,
-               .ca_name = "mode",
-               .ca_mode = S_IRUGO | S_IWUSR },
-       .show   = o2hb_heartbeat_group_mode_show,
-       .store  = o2hb_heartbeat_group_mode_store,
-};
+CONFIGFS_ATTR(o2hb_heartbeat_group_, threshold);
+CONFIGFS_ATTR(o2hb_heartbeat_group_, mode);
 
 static struct configfs_attribute *o2hb_heartbeat_group_attrs[] = {
-       &o2hb_heartbeat_group_attr_threshold.attr,
-       &o2hb_heartbeat_group_attr_mode.attr,
+       &o2hb_heartbeat_group_attr_threshold,
+       &o2hb_heartbeat_group_attr_mode,
        NULL,
 };
 
-static struct configfs_item_operations o2hb_heartbeat_group_item_ops = {
-       .show_attribute         = o2hb_heartbeat_group_show,
-       .store_attribute        = o2hb_heartbeat_group_store,
-};
-
 static struct configfs_group_operations o2hb_heartbeat_group_group_ops = {
        .make_item      = o2hb_heartbeat_group_make_item,
        .drop_item      = o2hb_heartbeat_group_drop_item,
@@ -2263,7 +2141,6 @@ static struct configfs_group_operations o2hb_heartbeat_group_group_ops = {
 
 static struct config_item_type o2hb_heartbeat_group_type = {
        .ct_group_ops   = &o2hb_heartbeat_group_group_ops,
-       .ct_item_ops    = &o2hb_heartbeat_group_item_ops,
        .ct_attrs       = o2hb_heartbeat_group_attrs,
        .ct_owner       = THIS_MODULE,
 };
index 441c84e169e6f05e819d7331027f6e519d02b3be..72afdca3cea70cbf87e2720e99dbff510be535f9 100644 (file)
@@ -172,9 +172,9 @@ static void o2nm_node_release(struct config_item *item)
        kfree(node);
 }
 
-static ssize_t o2nm_node_num_read(struct o2nm_node *node, char *page)
+static ssize_t o2nm_node_num_show(struct config_item *item, char *page)
 {
-       return sprintf(page, "%d\n", node->nd_num);
+       return sprintf(page, "%d\n", to_o2nm_node(item)->nd_num);
 }
 
 static struct o2nm_cluster *to_o2nm_cluster_from_node(struct o2nm_node *node)
@@ -188,15 +188,16 @@ enum {
        O2NM_NODE_ATTR_NUM = 0,
        O2NM_NODE_ATTR_PORT,
        O2NM_NODE_ATTR_ADDRESS,
-       O2NM_NODE_ATTR_LOCAL,
 };
 
-static ssize_t o2nm_node_num_write(struct o2nm_node *node, const char *page,
+static ssize_t o2nm_node_num_store(struct config_item *item, const char *page,
                                   size_t count)
 {
+       struct o2nm_node *node = to_o2nm_node(item);
        struct o2nm_cluster *cluster = to_o2nm_cluster_from_node(node);
        unsigned long tmp;
        char *p = (char *)page;
+       int ret = 0;
 
        tmp = simple_strtoul(p, &p, 0);
        if (!p || (*p && (*p != '\n')))
@@ -215,26 +216,30 @@ static ssize_t o2nm_node_num_write(struct o2nm_node *node, const char *page,
 
        write_lock(&cluster->cl_nodes_lock);
        if (cluster->cl_nodes[tmp])
-               p = NULL;
+               ret = -EEXIST;
+       else if (test_and_set_bit(O2NM_NODE_ATTR_NUM,
+                       &node->nd_set_attributes))
+               ret = -EBUSY;
        else  {
                cluster->cl_nodes[tmp] = node;
                node->nd_num = tmp;
                set_bit(tmp, cluster->cl_nodes_bitmap);
        }
        write_unlock(&cluster->cl_nodes_lock);
-       if (p == NULL)
-               return -EEXIST;
+       if (ret)
+               return ret;
 
        return count;
 }
-static ssize_t o2nm_node_ipv4_port_read(struct o2nm_node *node, char *page)
+static ssize_t o2nm_node_ipv4_port_show(struct config_item *item, char *page)
 {
-       return sprintf(page, "%u\n", ntohs(node->nd_ipv4_port));
+       return sprintf(page, "%u\n", ntohs(to_o2nm_node(item)->nd_ipv4_port));
 }
 
-static ssize_t o2nm_node_ipv4_port_write(struct o2nm_node *node,
+static ssize_t o2nm_node_ipv4_port_store(struct config_item *item,
                                         const char *page, size_t count)
 {
+       struct o2nm_node *node = to_o2nm_node(item);
        unsigned long tmp;
        char *p = (char *)page;
 
@@ -247,20 +252,23 @@ static ssize_t o2nm_node_ipv4_port_write(struct o2nm_node *node,
        if (tmp >= (u16)-1)
                return -ERANGE;
 
+       if (test_and_set_bit(O2NM_NODE_ATTR_PORT, &node->nd_set_attributes))
+               return -EBUSY;
        node->nd_ipv4_port = htons(tmp);
 
        return count;
 }
 
-static ssize_t o2nm_node_ipv4_address_read(struct o2nm_node *node, char *page)
+static ssize_t o2nm_node_ipv4_address_show(struct config_item *item, char *page)
 {
-       return sprintf(page, "%pI4\n", &node->nd_ipv4_address);
+       return sprintf(page, "%pI4\n", &to_o2nm_node(item)->nd_ipv4_address);
 }
 
-static ssize_t o2nm_node_ipv4_address_write(struct o2nm_node *node,
+static ssize_t o2nm_node_ipv4_address_store(struct config_item *item,
                                            const char *page,
                                            size_t count)
 {
+       struct o2nm_node *node = to_o2nm_node(item);
        struct o2nm_cluster *cluster = to_o2nm_cluster_from_node(node);
        int ret, i;
        struct rb_node **p, *parent;
@@ -282,6 +290,9 @@ static ssize_t o2nm_node_ipv4_address_write(struct o2nm_node *node,
        write_lock(&cluster->cl_nodes_lock);
        if (o2nm_node_ip_tree_lookup(cluster, ipv4_addr, &p, &parent))
                ret = -EEXIST;
+       else if (test_and_set_bit(O2NM_NODE_ATTR_ADDRESS,
+                       &node->nd_set_attributes))
+               ret = -EBUSY;
        else {
                rb_link_node(&node->nd_ip_node, parent, p);
                rb_insert_color(&node->nd_ip_node, &cluster->cl_node_ip_tree);
@@ -295,14 +306,15 @@ static ssize_t o2nm_node_ipv4_address_write(struct o2nm_node *node,
        return count;
 }
 
-static ssize_t o2nm_node_local_read(struct o2nm_node *node, char *page)
+static ssize_t o2nm_node_local_show(struct config_item *item, char *page)
 {
-       return sprintf(page, "%d\n", node->nd_local);
+       return sprintf(page, "%d\n", to_o2nm_node(item)->nd_local);
 }
 
-static ssize_t o2nm_node_local_write(struct o2nm_node *node, const char *page,
+static ssize_t o2nm_node_local_store(struct config_item *item, const char *page,
                                     size_t count)
 {
+       struct o2nm_node *node = to_o2nm_node(item);
        struct o2nm_cluster *cluster = to_o2nm_cluster_from_node(node);
        unsigned long tmp;
        char *p = (char *)page;
@@ -349,108 +361,21 @@ static ssize_t o2nm_node_local_write(struct o2nm_node *node, const char *page,
        return count;
 }
 
-struct o2nm_node_attribute {
-       struct configfs_attribute attr;
-       ssize_t (*show)(struct o2nm_node *, char *);
-       ssize_t (*store)(struct o2nm_node *, const char *, size_t);
-};
-
-static struct o2nm_node_attribute o2nm_node_attr_num = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                   .ca_name = "num",
-                   .ca_mode = S_IRUGO | S_IWUSR },
-       .show   = o2nm_node_num_read,
-       .store  = o2nm_node_num_write,
-};
-
-static struct o2nm_node_attribute o2nm_node_attr_ipv4_port = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                   .ca_name = "ipv4_port",
-                   .ca_mode = S_IRUGO | S_IWUSR },
-       .show   = o2nm_node_ipv4_port_read,
-       .store  = o2nm_node_ipv4_port_write,
-};
-
-static struct o2nm_node_attribute o2nm_node_attr_ipv4_address = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                   .ca_name = "ipv4_address",
-                   .ca_mode = S_IRUGO | S_IWUSR },
-       .show   = o2nm_node_ipv4_address_read,
-       .store  = o2nm_node_ipv4_address_write,
-};
-
-static struct o2nm_node_attribute o2nm_node_attr_local = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                   .ca_name = "local",
-                   .ca_mode = S_IRUGO | S_IWUSR },
-       .show   = o2nm_node_local_read,
-       .store  = o2nm_node_local_write,
-};
+CONFIGFS_ATTR(o2nm_node_, num);
+CONFIGFS_ATTR(o2nm_node_, ipv4_port);
+CONFIGFS_ATTR(o2nm_node_, ipv4_address);
+CONFIGFS_ATTR(o2nm_node_, local);
 
 static struct configfs_attribute *o2nm_node_attrs[] = {
-       [O2NM_NODE_ATTR_NUM] = &o2nm_node_attr_num.attr,
-       [O2NM_NODE_ATTR_PORT] = &o2nm_node_attr_ipv4_port.attr,
-       [O2NM_NODE_ATTR_ADDRESS] = &o2nm_node_attr_ipv4_address.attr,
-       [O2NM_NODE_ATTR_LOCAL] = &o2nm_node_attr_local.attr,
+       &o2nm_node_attr_num,
+       &o2nm_node_attr_ipv4_port,
+       &o2nm_node_attr_ipv4_address,
+       &o2nm_node_attr_local,
        NULL,
 };
 
-static int o2nm_attr_index(struct configfs_attribute *attr)
-{
-       int i;
-       for (i = 0; i < ARRAY_SIZE(o2nm_node_attrs); i++) {
-               if (attr == o2nm_node_attrs[i])
-                       return i;
-       }
-       BUG();
-       return 0;
-}
-
-static ssize_t o2nm_node_show(struct config_item *item,
-                             struct configfs_attribute *attr,
-                             char *page)
-{
-       struct o2nm_node *node = to_o2nm_node(item);
-       struct o2nm_node_attribute *o2nm_node_attr =
-               container_of(attr, struct o2nm_node_attribute, attr);
-       ssize_t ret = 0;
-
-       if (o2nm_node_attr->show)
-               ret = o2nm_node_attr->show(node, page);
-       return ret;
-}
-
-static ssize_t o2nm_node_store(struct config_item *item,
-                              struct configfs_attribute *attr,
-                              const char *page, size_t count)
-{
-       struct o2nm_node *node = to_o2nm_node(item);
-       struct o2nm_node_attribute *o2nm_node_attr =
-               container_of(attr, struct o2nm_node_attribute, attr);
-       ssize_t ret;
-       int attr_index = o2nm_attr_index(attr);
-
-       if (o2nm_node_attr->store == NULL) {
-               ret = -EINVAL;
-               goto out;
-       }
-
-       if (test_bit(attr_index, &node->nd_set_attributes))
-               return -EBUSY;
-
-       ret = o2nm_node_attr->store(node, page, count);
-       if (ret < count)
-               goto out;
-
-       set_bit(attr_index, &node->nd_set_attributes);
-out:
-       return ret;
-}
-
 static struct configfs_item_operations o2nm_node_item_ops = {
        .release                = o2nm_node_release,
-       .show_attribute         = o2nm_node_show,
-       .store_attribute        = o2nm_node_store,
 };
 
 static struct config_item_type o2nm_node_type = {
@@ -475,12 +400,6 @@ static struct o2nm_node_group *to_o2nm_node_group(struct config_group *group)
 }
 #endif
 
-struct o2nm_cluster_attribute {
-       struct configfs_attribute attr;
-       ssize_t (*show)(struct o2nm_cluster *, char *);
-       ssize_t (*store)(struct o2nm_cluster *, const char *, size_t);
-};
-
 static ssize_t o2nm_cluster_attr_write(const char *page, ssize_t count,
                                        unsigned int *val)
 {
@@ -501,15 +420,16 @@ static ssize_t o2nm_cluster_attr_write(const char *page, ssize_t count,
        return count;
 }
 
-static ssize_t o2nm_cluster_attr_idle_timeout_ms_read(
-       struct o2nm_cluster *cluster, char *page)
+static ssize_t o2nm_cluster_idle_timeout_ms_show(struct config_item *item,
+       char *page)
 {
-       return sprintf(page, "%u\n", cluster->cl_idle_timeout_ms);
+       return sprintf(page, "%u\n", to_o2nm_cluster(item)->cl_idle_timeout_ms);
 }
 
-static ssize_t o2nm_cluster_attr_idle_timeout_ms_write(
-       struct o2nm_cluster *cluster, const char *page, size_t count)
+static ssize_t o2nm_cluster_idle_timeout_ms_store(struct config_item *item,
+       const char *page, size_t count)
 {
+       struct o2nm_cluster *cluster = to_o2nm_cluster(item);
        ssize_t ret;
        unsigned int val;
 
@@ -536,15 +456,17 @@ static ssize_t o2nm_cluster_attr_idle_timeout_ms_write(
        return ret;
 }
 
-static ssize_t o2nm_cluster_attr_keepalive_delay_ms_read(
-       struct o2nm_cluster *cluster, char *page)
+static ssize_t o2nm_cluster_keepalive_delay_ms_show(
+       struct config_item *item, char *page)
 {
-       return sprintf(page, "%u\n", cluster->cl_keepalive_delay_ms);
+       return sprintf(page, "%u\n",
+                       to_o2nm_cluster(item)->cl_keepalive_delay_ms);
 }
 
-static ssize_t o2nm_cluster_attr_keepalive_delay_ms_write(
-       struct o2nm_cluster *cluster, const char *page, size_t count)
+static ssize_t o2nm_cluster_keepalive_delay_ms_store(
+       struct config_item *item, const char *page, size_t count)
 {
+       struct o2nm_cluster *cluster = to_o2nm_cluster(item);
        ssize_t ret;
        unsigned int val;
 
@@ -571,22 +493,24 @@ static ssize_t o2nm_cluster_attr_keepalive_delay_ms_write(
        return ret;
 }
 
-static ssize_t o2nm_cluster_attr_reconnect_delay_ms_read(
-       struct o2nm_cluster *cluster, char *page)
+static ssize_t o2nm_cluster_reconnect_delay_ms_show(
+       struct config_item *item, char *page)
 {
-       return sprintf(page, "%u\n", cluster->cl_reconnect_delay_ms);
+       return sprintf(page, "%u\n",
+                       to_o2nm_cluster(item)->cl_reconnect_delay_ms);
 }
 
-static ssize_t o2nm_cluster_attr_reconnect_delay_ms_write(
-       struct o2nm_cluster *cluster, const char *page, size_t count)
+static ssize_t o2nm_cluster_reconnect_delay_ms_store(
+       struct config_item *item, const char *page, size_t count)
 {
        return o2nm_cluster_attr_write(page, count,
-                                      &cluster->cl_reconnect_delay_ms);
+                               &to_o2nm_cluster(item)->cl_reconnect_delay_ms);
 }
 
-static ssize_t o2nm_cluster_attr_fence_method_read(
-       struct o2nm_cluster *cluster, char *page)
+static ssize_t o2nm_cluster_fence_method_show(
+       struct config_item *item, char *page)
 {
+       struct o2nm_cluster *cluster = to_o2nm_cluster(item);
        ssize_t ret = 0;
 
        if (cluster)
@@ -595,8 +519,8 @@ static ssize_t o2nm_cluster_attr_fence_method_read(
        return ret;
 }
 
-static ssize_t o2nm_cluster_attr_fence_method_write(
-       struct o2nm_cluster *cluster, const char *page, size_t count)
+static ssize_t o2nm_cluster_fence_method_store(
+       struct config_item *item, const char *page, size_t count)
 {
        unsigned int i;
 
@@ -608,10 +532,10 @@ static ssize_t o2nm_cluster_attr_fence_method_write(
                        continue;
                if (strncasecmp(page, o2nm_fence_method_desc[i], count - 1))
                        continue;
-               if (cluster->cl_fence_method != i) {
+               if (to_o2nm_cluster(item)->cl_fence_method != i) {
                        printk(KERN_INFO "ocfs2: Changing fence method to %s\n",
                               o2nm_fence_method_desc[i]);
-                       cluster->cl_fence_method = i;
+                       to_o2nm_cluster(item)->cl_fence_method = i;
                }
                return count;
        }
@@ -620,79 +544,18 @@ bail:
        return -EINVAL;
 }
 
-static struct o2nm_cluster_attribute o2nm_cluster_attr_idle_timeout_ms = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                   .ca_name = "idle_timeout_ms",
-                   .ca_mode = S_IRUGO | S_IWUSR },
-       .show   = o2nm_cluster_attr_idle_timeout_ms_read,
-       .store  = o2nm_cluster_attr_idle_timeout_ms_write,
-};
-
-static struct o2nm_cluster_attribute o2nm_cluster_attr_keepalive_delay_ms = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                   .ca_name = "keepalive_delay_ms",
-                   .ca_mode = S_IRUGO | S_IWUSR },
-       .show   = o2nm_cluster_attr_keepalive_delay_ms_read,
-       .store  = o2nm_cluster_attr_keepalive_delay_ms_write,
-};
-
-static struct o2nm_cluster_attribute o2nm_cluster_attr_reconnect_delay_ms = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                   .ca_name = "reconnect_delay_ms",
-                   .ca_mode = S_IRUGO | S_IWUSR },
-       .show   = o2nm_cluster_attr_reconnect_delay_ms_read,
-       .store  = o2nm_cluster_attr_reconnect_delay_ms_write,
-};
-
-static struct o2nm_cluster_attribute o2nm_cluster_attr_fence_method = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                   .ca_name = "fence_method",
-                   .ca_mode = S_IRUGO | S_IWUSR },
-       .show   = o2nm_cluster_attr_fence_method_read,
-       .store  = o2nm_cluster_attr_fence_method_write,
-};
+CONFIGFS_ATTR(o2nm_cluster_, idle_timeout_ms);
+CONFIGFS_ATTR(o2nm_cluster_, keepalive_delay_ms);
+CONFIGFS_ATTR(o2nm_cluster_, reconnect_delay_ms);
+CONFIGFS_ATTR(o2nm_cluster_, fence_method);
 
 static struct configfs_attribute *o2nm_cluster_attrs[] = {
-       &o2nm_cluster_attr_idle_timeout_ms.attr,
-       &o2nm_cluster_attr_keepalive_delay_ms.attr,
-       &o2nm_cluster_attr_reconnect_delay_ms.attr,
-       &o2nm_cluster_attr_fence_method.attr,
+       &o2nm_cluster_attr_idle_timeout_ms,
+       &o2nm_cluster_attr_keepalive_delay_ms,
+       &o2nm_cluster_attr_reconnect_delay_ms,
+       &o2nm_cluster_attr_fence_method,
        NULL,
 };
-static ssize_t o2nm_cluster_show(struct config_item *item,
-                                 struct configfs_attribute *attr,
-                                 char *page)
-{
-       struct o2nm_cluster *cluster = to_o2nm_cluster(item);
-       struct o2nm_cluster_attribute *o2nm_cluster_attr =
-               container_of(attr, struct o2nm_cluster_attribute, attr);
-       ssize_t ret = 0;
-
-       if (o2nm_cluster_attr->show)
-               ret = o2nm_cluster_attr->show(cluster, page);
-       return ret;
-}
-
-static ssize_t o2nm_cluster_store(struct config_item *item,
-                                  struct configfs_attribute *attr,
-                                  const char *page, size_t count)
-{
-       struct o2nm_cluster *cluster = to_o2nm_cluster(item);
-       struct o2nm_cluster_attribute *o2nm_cluster_attr =
-               container_of(attr, struct o2nm_cluster_attribute, attr);
-       ssize_t ret;
-
-       if (o2nm_cluster_attr->store == NULL) {
-               ret = -EINVAL;
-               goto out;
-       }
-
-       ret = o2nm_cluster_attr->store(cluster, page, count);
-       if (ret < count)
-               goto out;
-out:
-       return ret;
-}
 
 static struct config_item *o2nm_node_group_make_item(struct config_group *group,
                                                     const char *name)
@@ -773,8 +636,6 @@ static void o2nm_cluster_release(struct config_item *item)
 
 static struct configfs_item_operations o2nm_cluster_item_ops = {
        .release        = o2nm_cluster_release,
-       .show_attribute         = o2nm_cluster_show,
-       .store_attribute        = o2nm_cluster_store,
 };
 
 static struct config_item_type o2nm_cluster_type = {
index ebfdea78659b1bda5a93674837e8f818c2503d44..e9164f09841bfd6bc3f5baf439b91f8dfe5345f2 100644 (file)
@@ -7229,9 +7229,10 @@ leave:
 /*
  * 'security' attributes support
  */
-static size_t ocfs2_xattr_security_list(struct dentry *dentry, char *list,
+static size_t ocfs2_xattr_security_list(const struct xattr_handler *handler,
+                                       struct dentry *dentry, char *list,
                                        size_t list_size, const char *name,
-                                       size_t name_len, int type)
+                                       size_t name_len)
 {
        const size_t prefix_len = XATTR_SECURITY_PREFIX_LEN;
        const size_t total_len = prefix_len + name_len + 1;
@@ -7244,8 +7245,9 @@ static size_t ocfs2_xattr_security_list(struct dentry *dentry, char *list,
        return total_len;
 }
 
-static int ocfs2_xattr_security_get(struct dentry *dentry, const char *name,
-                                   void *buffer, size_t size, int type)
+static int ocfs2_xattr_security_get(const struct xattr_handler *handler,
+                                   struct dentry *dentry, const char *name,
+                                   void *buffer, size_t size)
 {
        if (strcmp(name, "") == 0)
                return -EINVAL;
@@ -7253,8 +7255,9 @@ static int ocfs2_xattr_security_get(struct dentry *dentry, const char *name,
                               name, buffer, size);
 }
 
-static int ocfs2_xattr_security_set(struct dentry *dentry, const char *name,
-               const void *value, size_t size, int flags, int type)
+static int ocfs2_xattr_security_set(const struct xattr_handler *handler,
+                                   struct dentry *dentry, const char *name,
+                                   const void *value, size_t size, int flags)
 {
        if (strcmp(name, "") == 0)
                return -EINVAL;
@@ -7319,9 +7322,10 @@ const struct xattr_handler ocfs2_xattr_security_handler = {
 /*
  * 'trusted' attributes support
  */
-static size_t ocfs2_xattr_trusted_list(struct dentry *dentry, char *list,
+static size_t ocfs2_xattr_trusted_list(const struct xattr_handler *handler,
+                                      struct dentry *dentry, char *list,
                                       size_t list_size, const char *name,
-                                      size_t name_len, int type)
+                                      size_t name_len)
 {
        const size_t prefix_len = XATTR_TRUSTED_PREFIX_LEN;
        const size_t total_len = prefix_len + name_len + 1;
@@ -7337,8 +7341,9 @@ static size_t ocfs2_xattr_trusted_list(struct dentry *dentry, char *list,
        return total_len;
 }
 
-static int ocfs2_xattr_trusted_get(struct dentry *dentry, const char *name,
-               void *buffer, size_t size, int type)
+static int ocfs2_xattr_trusted_get(const struct xattr_handler *handler,
+                                  struct dentry *dentry, const char *name,
+                                  void *buffer, size_t size)
 {
        if (strcmp(name, "") == 0)
                return -EINVAL;
@@ -7346,8 +7351,9 @@ static int ocfs2_xattr_trusted_get(struct dentry *dentry, const char *name,
                               name, buffer, size);
 }
 
-static int ocfs2_xattr_trusted_set(struct dentry *dentry, const char *name,
-               const void *value, size_t size, int flags, int type)
+static int ocfs2_xattr_trusted_set(const struct xattr_handler *handler,
+                                  struct dentry *dentry, const char *name,
+                                  const void *value, size_t size, int flags)
 {
        if (strcmp(name, "") == 0)
                return -EINVAL;
@@ -7366,9 +7372,10 @@ const struct xattr_handler ocfs2_xattr_trusted_handler = {
 /*
  * 'user' attributes support
  */
-static size_t ocfs2_xattr_user_list(struct dentry *dentry, char *list,
+static size_t ocfs2_xattr_user_list(const struct xattr_handler *handler,
+                                   struct dentry *dentry, char *list,
                                    size_t list_size, const char *name,
-                                   size_t name_len, int type)
+                                   size_t name_len)
 {
        const size_t prefix_len = XATTR_USER_PREFIX_LEN;
        const size_t total_len = prefix_len + name_len + 1;
@@ -7385,8 +7392,9 @@ static size_t ocfs2_xattr_user_list(struct dentry *dentry, char *list,
        return total_len;
 }
 
-static int ocfs2_xattr_user_get(struct dentry *dentry, const char *name,
-               void *buffer, size_t size, int type)
+static int ocfs2_xattr_user_get(const struct xattr_handler *handler,
+                               struct dentry *dentry, const char *name,
+                               void *buffer, size_t size)
 {
        struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb);
 
@@ -7398,8 +7406,9 @@ static int ocfs2_xattr_user_get(struct dentry *dentry, const char *name,
                               buffer, size);
 }
 
-static int ocfs2_xattr_user_set(struct dentry *dentry, const char *name,
-               const void *value, size_t size, int flags, int type)
+static int ocfs2_xattr_user_set(const struct xattr_handler *handler,
+                               struct dentry *dentry, const char *name,
+                               const void *value, size_t size, int flags)
 {
        struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb);
 
index 8865f796370074dbe7a191ab39c9645e80ed481d..42cf8ddf0e5599da6621fcdf741d6a61fd2f2d7a 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -366,18 +366,17 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from)
                int offset = buf->offset + buf->len;
 
                if (ops->can_merge && offset + chars <= PAGE_SIZE) {
-                       int error = ops->confirm(pipe, buf);
-                       if (error)
+                       ret = ops->confirm(pipe, buf);
+                       if (ret)
                                goto out;
 
                        ret = copy_page_from_iter(buf->page, offset, chars, from);
                        if (unlikely(ret < chars)) {
-                               error = -EFAULT;
+                               ret = -EFAULT;
                                goto out;
                        }
                        do_wakeup = 1;
-                       buf->len += chars;
-                       ret = chars;
+                       buf->len += ret;
                        if (!iov_iter_count(from))
                                goto out;
                }
@@ -693,17 +692,20 @@ int create_pipe_files(struct file **res, int flags)
 
        d_instantiate(path.dentry, inode);
 
-       err = -ENFILE;
        f = alloc_file(&path, FMODE_WRITE, &pipefifo_fops);
-       if (IS_ERR(f))
+       if (IS_ERR(f)) {
+               err = PTR_ERR(f);
                goto err_dentry;
+       }
 
        f->f_flags = O_WRONLY | (flags & (O_NONBLOCK | O_DIRECT));
        f->private_data = inode->i_pipe;
 
        res[0] = alloc_file(&path, FMODE_READ, &pipefifo_fops);
-       if (IS_ERR(res[0]))
+       if (IS_ERR(res[0])) {
+               err = PTR_ERR(res[0]);
                goto err_file;
+       }
 
        path_get(&path);
        res[0]->private_data = inode->i_pipe;
index 4fb17ded7d4780d8d19e7c68cb1c7cedfeb79cf7..4adde1e2cbece693ebab67527a555e3a33e6fbfa 100644 (file)
@@ -762,18 +762,21 @@ posix_acl_to_xattr(struct user_namespace *user_ns, const struct posix_acl *acl,
 EXPORT_SYMBOL (posix_acl_to_xattr);
 
 static int
-posix_acl_xattr_get(struct dentry *dentry, const char *name,
-               void *value, size_t size, int type)
+posix_acl_xattr_get(const struct xattr_handler *handler,
+                   struct dentry *dentry, const char *name,
+                   void *value, size_t size)
 {
        struct posix_acl *acl;
        int error;
 
+       if (strcmp(name, "") != 0)
+               return -EINVAL;
        if (!IS_POSIXACL(d_backing_inode(dentry)))
                return -EOPNOTSUPP;
        if (d_is_symlink(dentry))
                return -EOPNOTSUPP;
 
-       acl = get_acl(d_backing_inode(dentry), type);
+       acl = get_acl(d_backing_inode(dentry), handler->flags);
        if (IS_ERR(acl))
                return PTR_ERR(acl);
        if (acl == NULL)
@@ -786,19 +789,22 @@ posix_acl_xattr_get(struct dentry *dentry, const char *name,
 }
 
 static int
-posix_acl_xattr_set(struct dentry *dentry, const char *name,
-               const void *value, size_t size, int flags, int type)
+posix_acl_xattr_set(const struct xattr_handler *handler,
+                   struct dentry *dentry, const char *name,
+                   const void *value, size_t size, int flags)
 {
        struct inode *inode = d_backing_inode(dentry);
        struct posix_acl *acl = NULL;
        int ret;
 
+       if (strcmp(name, "") != 0)
+               return -EINVAL;
        if (!IS_POSIXACL(inode))
                return -EOPNOTSUPP;
        if (!inode->i_op->set_acl)
                return -EOPNOTSUPP;
 
-       if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode))
+       if (handler->flags == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode))
                return value ? -EACCES : 0;
        if (!inode_owner_or_capable(inode))
                return -EPERM;
@@ -815,28 +821,22 @@ posix_acl_xattr_set(struct dentry *dentry, const char *name,
                }
        }
 
-       ret = inode->i_op->set_acl(inode, acl, type);
+       ret = inode->i_op->set_acl(inode, acl, handler->flags);
 out:
        posix_acl_release(acl);
        return ret;
 }
 
 static size_t
-posix_acl_xattr_list(struct dentry *dentry, char *list, size_t list_size,
-               const char *name, size_t name_len, int type)
+posix_acl_xattr_list(const struct xattr_handler *handler,
+                    struct dentry *dentry, char *list, size_t list_size,
+                    const char *name, size_t name_len)
 {
-       const char *xname;
+       const char *xname = handler->prefix;
        size_t size;
 
        if (!IS_POSIXACL(d_backing_inode(dentry)))
-               return -EOPNOTSUPP;
-       if (d_is_symlink(dentry))
-               return -EOPNOTSUPP;
-
-       if (type == ACL_TYPE_ACCESS)
-               xname = POSIX_ACL_XATTR_ACCESS;
-       else
-               xname = POSIX_ACL_XATTR_DEFAULT;
+               return 0;
 
        size = strlen(xname) + 1;
        if (list && size <= list_size)
index e87f9b52bf069af087979782767b6c3471689fd5..66b26fdfff8d6de51082b48b0f9a61fba9567466 100644 (file)
@@ -778,7 +778,7 @@ reiserfs_getxattr(struct dentry * dentry, const char *name, void *buffer,
        if (!handler || get_inode_sd_version(d_inode(dentry)) == STAT_DATA_V1)
                return -EOPNOTSUPP;
 
-       return handler->get(dentry, name, buffer, size, handler->flags);
+       return handler->get(handler, dentry, name, buffer, size);
 }
 
 /*
@@ -797,7 +797,7 @@ reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value,
        if (!handler || get_inode_sd_version(d_inode(dentry)) == STAT_DATA_V1)
                return -EOPNOTSUPP;
 
-       return handler->set(dentry, name, value, size, flags, handler->flags);
+       return handler->set(handler, dentry, name, value, size, flags);
 }
 
 /*
@@ -814,7 +814,7 @@ int reiserfs_removexattr(struct dentry *dentry, const char *name)
        if (!handler || get_inode_sd_version(d_inode(dentry)) == STAT_DATA_V1)
                return -EOPNOTSUPP;
 
-       return handler->set(dentry, name, NULL, 0, XATTR_REPLACE, handler->flags);
+       return handler->set(handler, dentry, name, NULL, 0, XATTR_REPLACE);
 }
 
 struct listxattr_buf {
@@ -842,14 +842,14 @@ static int listxattr_filler(struct dir_context *ctx, const char *name,
                if (!handler)   /* Unsupported xattr name */
                        return 0;
                if (b->buf) {
-                       size = handler->list(b->dentry, b->buf + b->pos,
-                                        b->size, name, namelen,
-                                        handler->flags);
+                       size = handler->list(handler, b->dentry,
+                                            b->buf + b->pos, b->size, name,
+                                            namelen);
                        if (size > b->size)
                                return -ERANGE;
                } else {
-                       size = handler->list(b->dentry, NULL, 0, name,
-                                            namelen, handler->flags);
+                       size = handler->list(handler, b->dentry,
+                                            NULL, 0, name, namelen);
                }
 
                b->pos += size;
index 9a3b0616f2838848c88dbf90497ebb9af0a68e2a..ac659af431aec83d5ba7b85e7b69c1ac49e7b4c0 100644 (file)
@@ -9,8 +9,8 @@
 #include <linux/uaccess.h>
 
 static int
-security_get(struct dentry *dentry, const char *name, void *buffer, size_t size,
-               int handler_flags)
+security_get(const struct xattr_handler *handler, struct dentry *dentry,
+            const char *name, void *buffer, size_t size)
 {
        if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX))
                return -EINVAL;
@@ -22,8 +22,8 @@ security_get(struct dentry *dentry, const char *name, void *buffer, size_t size,
 }
 
 static int
-security_set(struct dentry *dentry, const char *name, const void *buffer,
-            size_t size, int flags, int handler_flags)
+security_set(const struct xattr_handler *handler, struct dentry *dentry,
+            const char *name, const void *buffer, size_t size, int flags)
 {
        if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX))
                return -EINVAL;
@@ -34,8 +34,9 @@ security_set(struct dentry *dentry, const char *name, const void *buffer,
        return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags);
 }
 
-static size_t security_list(struct dentry *dentry, char *list, size_t list_len,
-                           const char *name, size_t namelen, int handler_flags)
+static size_t security_list(const struct xattr_handler *handler,
+                           struct dentry *dentry, char *list, size_t list_len,
+                           const char *name, size_t namelen)
 {
        const size_t len = namelen + 1;
 
index e4f1343714e0ea8a89598bb776dc8a3f6b42c67d..a338adf1b8b4816c19ca84557a0142179f93b9a7 100644 (file)
@@ -8,8 +8,8 @@
 #include <linux/uaccess.h>
 
 static int
-trusted_get(struct dentry *dentry, const char *name, void *buffer, size_t size,
-           int handler_flags)
+trusted_get(const struct xattr_handler *handler, struct dentry *dentry,
+           const char *name, void *buffer, size_t size)
 {
        if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX))
                return -EINVAL;
@@ -21,8 +21,8 @@ trusted_get(struct dentry *dentry, const char *name, void *buffer, size_t size,
 }
 
 static int
-trusted_set(struct dentry *dentry, const char *name, const void *buffer,
-           size_t size, int flags, int handler_flags)
+trusted_set(const struct xattr_handler *handler, struct dentry *dentry,
+           const char *name, const void *buffer, size_t size, int flags)
 {
        if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX))
                return -EINVAL;
@@ -33,8 +33,9 @@ trusted_set(struct dentry *dentry, const char *name, const void *buffer,
        return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags);
 }
 
-static size_t trusted_list(struct dentry *dentry, char *list, size_t list_size,
-                          const char *name, size_t name_len, int handler_flags)
+static size_t trusted_list(const struct xattr_handler *handler,
+                          struct dentry *dentry, char *list, size_t list_size,
+                          const char *name, size_t name_len)
 {
        const size_t len = name_len + 1;
 
index d0b08d3e5689d39aeffbd1d86e13711b50e56f22..39c9667191c5db5b3c930e538d81799b96bea6fb 100644 (file)
@@ -7,8 +7,8 @@
 #include <linux/uaccess.h>
 
 static int
-user_get(struct dentry *dentry, const char *name, void *buffer, size_t size,
-        int handler_flags)
+user_get(const struct xattr_handler *handler, struct dentry *dentry,
+        const char *name, void *buffer, size_t size)
 {
 
        if (strlen(name) < sizeof(XATTR_USER_PREFIX))
@@ -19,8 +19,8 @@ user_get(struct dentry *dentry, const char *name, void *buffer, size_t size,
 }
 
 static int
-user_set(struct dentry *dentry, const char *name, const void *buffer,
-        size_t size, int flags, int handler_flags)
+user_set(const struct xattr_handler *handler, struct dentry *dentry,
+        const char *name, const void *buffer, size_t size, int flags)
 {
        if (strlen(name) < sizeof(XATTR_USER_PREFIX))
                return -EINVAL;
@@ -30,8 +30,9 @@ user_set(struct dentry *dentry, const char *name, const void *buffer,
        return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags);
 }
 
-static size_t user_list(struct dentry *dentry, char *list, size_t list_size,
-                       const char *name, size_t name_len, int handler_flags)
+static size_t user_list(const struct xattr_handler *handler,
+                       struct dentry *dentry, char *list, size_t list_size,
+                       const char *name, size_t name_len)
 {
        const size_t len = name_len + 1;
 
index e5e0ddf5b1430d335075220824897c2e38d1b289..6a4cc344085c0a9ecb3ce4106b168172739dd161 100644 (file)
@@ -68,8 +68,8 @@ ssize_t squashfs_listxattr(struct dentry *d, char *buffer,
                name_size = le16_to_cpu(entry.size);
                handler = squashfs_xattr_handler(le16_to_cpu(entry.type));
                if (handler)
-                       prefix_size = handler->list(d, buffer, rest, NULL,
-                               name_size, handler->flags);
+                       prefix_size = handler->list(handler, d, buffer, rest,
+                                                   NULL, name_size);
                if (prefix_size) {
                        if (buffer) {
                                if (prefix_size + name_size + 1 > rest) {
@@ -212,88 +212,68 @@ failed:
 }
 
 
-/*
- * User namespace support
- */
-static size_t squashfs_user_list(struct dentry *d, char *list, size_t list_size,
-       const char *name, size_t name_len, int type)
+static size_t squashfs_xattr_handler_list(const struct xattr_handler *handler,
+                                         struct dentry *d, char *list,
+                                         size_t list_size, const char *name,
+                                         size_t name_len)
 {
-       if (list && XATTR_USER_PREFIX_LEN <= list_size)
-               memcpy(list, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
-       return XATTR_USER_PREFIX_LEN;
+       int len = strlen(handler->prefix);
+
+       if (list && len <= list_size)
+               memcpy(list, handler->prefix, len);
+       return len;
 }
 
-static int squashfs_user_get(struct dentry *d, const char *name, void *buffer,
-       size_t size, int type)
+static int squashfs_xattr_handler_get(const struct xattr_handler *handler,
+                                     struct dentry *d, const char *name,
+                                     void *buffer, size_t size)
 {
        if (name[0] == '\0')
                return  -EINVAL;
 
-       return squashfs_xattr_get(d_inode(d), SQUASHFS_XATTR_USER, name,
+       return squashfs_xattr_get(d_inode(d), handler->flags, name,
                buffer, size);
 }
 
+/*
+ * User namespace support
+ */
 static const struct xattr_handler squashfs_xattr_user_handler = {
        .prefix = XATTR_USER_PREFIX,
-       .list   = squashfs_user_list,
-       .get    = squashfs_user_get
+       .flags  = SQUASHFS_XATTR_USER,
+       .list   = squashfs_xattr_handler_list,
+       .get    = squashfs_xattr_handler_get
 };
 
 /*
  * Trusted namespace support
  */
-static size_t squashfs_trusted_list(struct dentry *d, char *list,
-       size_t list_size, const char *name, size_t name_len, int type)
+static size_t squashfs_trusted_xattr_handler_list(const struct xattr_handler *handler,
+                                                 struct dentry *d, char *list,
+                                                 size_t list_size, const char *name,
+                                                 size_t name_len)
 {
        if (!capable(CAP_SYS_ADMIN))
                return 0;
-
-       if (list && XATTR_TRUSTED_PREFIX_LEN <= list_size)
-               memcpy(list, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN);
-       return XATTR_TRUSTED_PREFIX_LEN;
-}
-
-static int squashfs_trusted_get(struct dentry *d, const char *name,
-       void *buffer, size_t size, int type)
-{
-       if (name[0] == '\0')
-               return  -EINVAL;
-
-       return squashfs_xattr_get(d_inode(d), SQUASHFS_XATTR_TRUSTED, name,
-               buffer, size);
+       return squashfs_xattr_handler_list(handler, d, list, list_size, name,
+                                          name_len);
 }
 
 static const struct xattr_handler squashfs_xattr_trusted_handler = {
        .prefix = XATTR_TRUSTED_PREFIX,
-       .list   = squashfs_trusted_list,
-       .get    = squashfs_trusted_get
+       .flags  = SQUASHFS_XATTR_TRUSTED,
+       .list   = squashfs_trusted_xattr_handler_list,
+       .get    = squashfs_xattr_handler_get
 };
 
 /*
  * Security namespace support
  */
-static size_t squashfs_security_list(struct dentry *d, char *list,
-       size_t list_size, const char *name, size_t name_len, int type)
-{
-       if (list && XATTR_SECURITY_PREFIX_LEN <= list_size)
-               memcpy(list, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN);
-       return XATTR_SECURITY_PREFIX_LEN;
-}
-
-static int squashfs_security_get(struct dentry *d, const char *name,
-       void *buffer, size_t size, int type)
-{
-       if (name[0] == '\0')
-               return  -EINVAL;
-
-       return squashfs_xattr_get(d_inode(d), SQUASHFS_XATTR_SECURITY, name,
-               buffer, size);
-}
-
 static const struct xattr_handler squashfs_xattr_security_handler = {
        .prefix = XATTR_SECURITY_PREFIX,
-       .list   = squashfs_security_list,
-       .get    = squashfs_security_get
+       .flags  = SQUASHFS_XATTR_SECURITY,
+       .list   = squashfs_xattr_handler_list,
+       .get    = squashfs_xattr_handler_get
 };
 
 static const struct xattr_handler *squashfs_xattr_handler(int type)
index e1236594fffec8d50b79eada956fdaadba663aff..dc1358b5ec95814c4e0f0ca0bec3d2b847029b24 100644 (file)
@@ -73,13 +73,26 @@ static int create_files(struct kernfs_node *parent, struct kobject *kobj,
        }
 
        if (grp->bin_attrs) {
-               for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++) {
+               for (i = 0, bin_attr = grp->bin_attrs; *bin_attr; i++, bin_attr++) {
+                       umode_t mode = (*bin_attr)->attr.mode;
+
                        if (update)
                                kernfs_remove_by_name(parent,
                                                (*bin_attr)->attr.name);
+                       if (grp->is_bin_visible) {
+                               mode = grp->is_bin_visible(kobj, *bin_attr, i);
+                               if (!mode)
+                                       continue;
+                       }
+
+                       WARN(mode & ~(SYSFS_PREALLOC | 0664),
+                            "Attribute %s: Invalid permissions 0%o\n",
+                            (*bin_attr)->attr.name, mode);
+
+                       mode &= SYSFS_PREALLOC | 0664;
                        error = sysfs_add_file_mode_ns(parent,
                                        &(*bin_attr)->attr, true,
-                                       (*bin_attr)->attr.mode, NULL);
+                                       mode, NULL);
                        if (error)
                                break;
                }
index 8ee3133dd8e49af9f413025683236cf464a62f12..1fd90c0795374b6abae3d9787e1b898bd1819546 100644 (file)
@@ -2040,7 +2040,6 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
        if (c->max_inode_sz > MAX_LFS_FILESIZE)
                sb->s_maxbytes = c->max_inode_sz = MAX_LFS_FILESIZE;
        sb->s_op = &ubifs_super_operations;
-       sb->s_xattr = ubifs_xattr_handlers;
 
        mutex_lock(&c->umount_mutex);
        err = mount_ubifs(c);
index 01142e129d168ccba3139992ce50df56c9acea3a..a5697de763f516f659b7f69e42e5eba4ad94efec 100644 (file)
@@ -1470,7 +1470,6 @@ extern spinlock_t ubifs_infos_lock;
 extern atomic_long_t ubifs_clean_zn_cnt;
 extern struct kmem_cache *ubifs_inode_slab;
 extern const struct super_operations ubifs_super_operations;
-extern const struct xattr_handler *ubifs_xattr_handlers[];
 extern const struct address_space_operations ubifs_file_address_operations;
 extern const struct file_operations ubifs_file_operations;
 extern const struct inode_operations ubifs_file_inode_operations;
index 259fbabf143d8cb8cf4e88df59268710fd420137..e8b01b721e99d3954e344686fc615c9455e4246c 100644 (file)
@@ -588,46 +588,6 @@ out_free:
        return err;
 }
 
-static size_t security_listxattr(struct dentry *d, char *list, size_t list_size,
-                                const char *name, size_t name_len, int flags)
-{
-       const int prefix_len = XATTR_SECURITY_PREFIX_LEN;
-       const size_t total_len = prefix_len + name_len + 1;
-
-       if (list && total_len <= list_size) {
-               memcpy(list, XATTR_SECURITY_PREFIX, prefix_len);
-               memcpy(list + prefix_len, name, name_len);
-               list[prefix_len + name_len] = '\0';
-       }
-
-       return total_len;
-}
-
-static int security_getxattr(struct dentry *d, const char *name, void *buffer,
-                     size_t size, int flags)
-{
-       return ubifs_getxattr(d, name, buffer, size);
-}
-
-static int security_setxattr(struct dentry *d, const char *name,
-                            const void *value, size_t size, int flags,
-                            int handler_flags)
-{
-       return ubifs_setxattr(d, name, value, size, flags);
-}
-
-static const struct xattr_handler ubifs_xattr_security_handler = {
-       .prefix = XATTR_SECURITY_PREFIX,
-       .list   = security_listxattr,
-       .get    = security_getxattr,
-       .set    = security_setxattr,
-};
-
-const struct xattr_handler *ubifs_xattr_handlers[] = {
-       &ubifs_xattr_security_handler,
-       NULL,
-};
-
 static int init_xattrs(struct inode *inode, const struct xattr *xattr_array,
                      void *fs_info)
 {
index 072fee1258dd87e58d44ab3263909bab4f3a2e89..9b932b95d74e4faeb5653d1a3c4b11553d1e51e1 100644 (file)
@@ -720,7 +720,7 @@ generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t s
        handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);
        if (!handler)
                return -EOPNOTSUPP;
-       return handler->get(dentry, name, buffer, size, handler->flags);
+       return handler->get(handler, dentry, name, buffer, size);
 }
 
 /*
@@ -735,15 +735,15 @@ generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
 
        if (!buffer) {
                for_each_xattr_handler(handlers, handler) {
-                       size += handler->list(dentry, NULL, 0, NULL, 0,
-                                             handler->flags);
+                       size += handler->list(handler, dentry, NULL, 0,
+                                             NULL, 0);
                }
        } else {
                char *buf = buffer;
 
                for_each_xattr_handler(handlers, handler) {
-                       size = handler->list(dentry, buf, buffer_size,
-                                            NULL, 0, handler->flags);
+                       size = handler->list(handler, dentry, buf, buffer_size,
+                                            NULL, 0);
                        if (size > buffer_size)
                                return -ERANGE;
                        buf += size;
@@ -767,7 +767,7 @@ generic_setxattr(struct dentry *dentry, const char *name, const void *value, siz
        handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);
        if (!handler)
                return -EOPNOTSUPP;
-       return handler->set(dentry, name, value, size, flags, handler->flags);
+       return handler->set(handler, dentry, name, value, size, flags);
 }
 
 /*
@@ -782,8 +782,7 @@ generic_removexattr(struct dentry *dentry, const char *name)
        handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);
        if (!handler)
                return -EOPNOTSUPP;
-       return handler->set(dentry, name, NULL, 0,
-                           XATTR_REPLACE, handler->flags);
+       return handler->set(handler, dentry, name, NULL, 0, XATTR_REPLACE);
 }
 
 EXPORT_SYMBOL(generic_getxattr);
@@ -791,6 +790,30 @@ EXPORT_SYMBOL(generic_listxattr);
 EXPORT_SYMBOL(generic_setxattr);
 EXPORT_SYMBOL(generic_removexattr);
 
+/**
+ * xattr_full_name  -  Compute full attribute name from suffix
+ *
+ * @handler:   handler of the xattr_handler operation
+ * @name:      name passed to the xattr_handler operation
+ *
+ * The get and set xattr handler operations are called with the remainder of
+ * the attribute name after skipping the handler's prefix: for example, "foo"
+ * is passed to the get operation of a handler with prefix "user." to get
+ * attribute "user.foo".  The full name is still "there" in the name though.
+ *
+ * Note: the list xattr handler operation when called from the vfs is passed a
+ * NULL name; some file systems use this operation internally, with varying
+ * semantics.
+ */
+const char *xattr_full_name(const struct xattr_handler *handler,
+                           const char *name)
+{
+       size_t prefix_len = strlen(handler->prefix);
+
+       return name - prefix_len;
+}
+EXPORT_SYMBOL(xattr_full_name);
+
 /*
  * Allocate new xattr and copy in the value; but leave the name to callers.
  */
index a096841bd06ca1f424249c21d5b21a908de739cc..f64639176670b2228ac532607c0454d4b6e5a784 100644 (file)
@@ -84,6 +84,7 @@ xfs-y                         += xfs_aops.o \
                                   xfs_message.o \
                                   xfs_mount.o \
                                   xfs_mru_cache.o \
+                                  xfs_stats.o \
                                   xfs_super.o \
                                   xfs_symlink.o \
                                   xfs_sysfs.o \
@@ -118,7 +119,6 @@ xfs-$(CONFIG_XFS_QUOTA)             += xfs_dquot.o \
 xfs-$(CONFIG_XFS_RT)           += xfs_rtalloc.o
 
 xfs-$(CONFIG_XFS_POSIX_ACL)    += xfs_acl.o
-xfs-$(CONFIG_PROC_FS)          += xfs_stats.o
 xfs-$(CONFIG_SYSCTL)           += xfs_sysctl.o
 xfs-$(CONFIG_COMPAT)           += xfs_ioctl32.o
 xfs-$(CONFIG_NFSD_PNFS)                += xfs_pnfs.o
index a7a3a63bb360c098889dab8341ac656ddbd348af..686ba6fb20ddc942638f6e698b98bf4c1bb8785f 100644 (file)
@@ -55,8 +55,9 @@ kmem_alloc(size_t size, xfs_km_flags_t flags)
                        return ptr;
                if (!(++retries % 100))
                        xfs_err(NULL,
-               "possible memory allocation deadlock in %s (mode:0x%x)",
-                                       __func__, lflags);
+       "%s(%u) possible memory allocation deadlock size %u in %s (mode:0x%x)",
+                               current->comm, current->pid,
+                               (unsigned int)size, __func__, lflags);
                congestion_wait(BLK_RW_ASYNC, HZ/50);
        } while (1);
 }
@@ -120,8 +121,9 @@ kmem_zone_alloc(kmem_zone_t *zone, xfs_km_flags_t flags)
                        return ptr;
                if (!(++retries % 100))
                        xfs_err(NULL,
-               "possible memory allocation deadlock in %s (mode:0x%x)",
-                                       __func__, lflags);
+               "%s(%u) possible memory allocation deadlock in %s (mode:0x%x)",
+                               current->comm, current->pid,
+                               __func__, lflags);
                congestion_wait(BLK_RW_ASYNC, HZ/50);
        } while (1);
 }
index ffad7f20342f6e328b8daafa918ffeb1ae076ab1..3479294c1d586603d75c432267a91ff744a31006 100644 (file)
@@ -482,7 +482,9 @@ xfs_agfl_verify(
                    be32_to_cpu(agfl->agfl_bno[i]) >= mp->m_sb.sb_agblocks)
                        return false;
        }
-       return true;
+
+       return xfs_log_check_lsn(mp,
+                                be64_to_cpu(XFS_BUF_TO_AGFL(bp)->agfl_lsn));
 }
 
 static void
@@ -651,8 +653,8 @@ xfs_alloc_ag_vextent(
                                 -((long)(args->len)));
        }
 
-       XFS_STATS_INC(xs_allocx);
-       XFS_STATS_ADD(xs_allocb, args->len);
+       XFS_STATS_INC(args->mp, xs_allocx);
+       XFS_STATS_ADD(args->mp, xs_allocb, args->len);
        return error;
 }
 
@@ -1808,8 +1810,8 @@ xfs_free_ag_extent(
 
        if (!isfl)
                xfs_trans_mod_sb(tp, XFS_TRANS_SB_FDBLOCKS, (long)len);
-       XFS_STATS_INC(xs_freex);
-       XFS_STATS_ADD(xs_freeb, len);
+       XFS_STATS_INC(mp, xs_freex);
+       XFS_STATS_ADD(mp, xs_freeb, len);
 
        trace_xfs_free_extent(mp, agno, bno, len, isfl, haveleft, haveright);
 
@@ -2259,9 +2261,13 @@ xfs_agf_verify(
  {
        struct xfs_agf  *agf = XFS_BUF_TO_AGF(bp);
 
-       if (xfs_sb_version_hascrc(&mp->m_sb) &&
-           !uuid_equal(&agf->agf_uuid, &mp->m_sb.sb_meta_uuid))
+       if (xfs_sb_version_hascrc(&mp->m_sb)) {
+               if (!uuid_equal(&agf->agf_uuid, &mp->m_sb.sb_meta_uuid))
                        return false;
+               if (!xfs_log_check_lsn(mp,
+                               be64_to_cpu(XFS_BUF_TO_AGF(bp)->agf_lsn)))
+                       return false;
+       }
 
        if (!(agf->agf_magicnum == cpu_to_be32(XFS_AGF_MAGIC) &&
              XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum)) &&
@@ -2503,7 +2509,7 @@ xfs_alloc_vextent(
                 * Try near allocation first, then anywhere-in-ag after
                 * the first a.g. fails.
                 */
-               if ((args->userdata  == XFS_ALLOC_INITIAL_USER_DATA) &&
+               if ((args->userdata & XFS_ALLOC_INITIAL_USER_DATA) &&
                    (mp->m_flags & XFS_MOUNT_32BITINODES)) {
                        args->fsbno = XFS_AGB_TO_FSB(mp,
                                        ((mp->m_agfrotor / rotorstep) %
@@ -2634,6 +2640,14 @@ xfs_alloc_vextent(
                XFS_AG_CHECK_DADDR(mp, XFS_FSB_TO_DADDR(mp, args->fsbno),
                        args->len);
 #endif
+
+               /* Zero the extent if we were asked to do so */
+               if (args->userdata & XFS_ALLOC_USERDATA_ZERO) {
+                       error = xfs_zero_extent(args->ip, args->fsbno, args->len);
+                       if (error)
+                               goto error0;
+               }
+
        }
        xfs_perag_put(args->pag);
        return 0;
index ca1c8168373aa444ebb2ef7eb2865e1d859c1ceb..0ecde4d5cac8ff2ceaf2c373efd87583fcb8152a 100644 (file)
@@ -101,6 +101,7 @@ typedef struct xfs_alloc_arg {
        struct xfs_mount *mp;           /* file system mount point */
        struct xfs_buf  *agbp;          /* buffer for a.g. freelist header */
        struct xfs_perag *pag;          /* per-ag struct for this agno */
+       struct xfs_inode *ip;           /* for userdata zeroing method */
        xfs_fsblock_t   fsbno;          /* file system block number */
        xfs_agnumber_t  agno;           /* allocation group number */
        xfs_agblock_t   agbno;          /* allocation group-relative block # */
@@ -120,15 +121,16 @@ typedef struct xfs_alloc_arg {
        char            wasdel;         /* set if allocation was prev delayed */
        char            wasfromfl;      /* set if allocation is from freelist */
        char            isfl;           /* set if is freelist blocks - !acctg */
-       char            userdata;       /* set if this is user data */
+       char            userdata;       /* mask defining userdata treatment */
        xfs_fsblock_t   firstblock;     /* io first block allocated */
 } xfs_alloc_arg_t;
 
 /*
  * Defines for userdata
  */
-#define XFS_ALLOC_USERDATA             1       /* allocation is for user data*/
-#define XFS_ALLOC_INITIAL_USER_DATA    2       /* special case start of file */
+#define XFS_ALLOC_USERDATA             (1 << 0)/* allocation is for user data*/
+#define XFS_ALLOC_INITIAL_USER_DATA    (1 << 1)/* special case start of file */
+#define XFS_ALLOC_USERDATA_ZERO                (1 << 2)/* zero extent on allocation */
 
 xfs_extlen_t xfs_alloc_longest_free_extent(struct xfs_mount *mp,
                struct xfs_perag *pag, xfs_extlen_t need);
index ff065578969f27cd40065043ebfe292c5743ab4e..f949818fa1c76dd099588086be960bef3959c4ac 100644 (file)
@@ -125,7 +125,7 @@ xfs_attr_get(
        uint                    lock_mode;
        int                     error;
 
-       XFS_STATS_INC(xs_attr_get);
+       XFS_STATS_INC(ip->i_mount, xs_attr_get);
 
        if (XFS_FORCED_SHUTDOWN(ip->i_mount))
                return -EIO;
@@ -209,7 +209,7 @@ xfs_attr_set(
        int                     rsvd = (flags & ATTR_ROOT) != 0;
        int                     error, err2, committed, local;
 
-       XFS_STATS_INC(xs_attr_set);
+       XFS_STATS_INC(mp, xs_attr_set);
 
        if (XFS_FORCED_SHUTDOWN(dp->i_mount))
                return -EIO;
@@ -412,7 +412,7 @@ xfs_attr_remove(
        xfs_fsblock_t           firstblock;
        int                     error;
 
-       XFS_STATS_INC(xs_attr_remove);
+       XFS_STATS_INC(mp, xs_attr_remove);
 
        if (XFS_FORCED_SHUTDOWN(dp->i_mount))
                return -EIO;
index 33df52d97ec77bfeb07e4eb8bf45c33d7033a15c..aa187f7ba2dd341a4a797ab268747881f3f4deca 100644 (file)
@@ -41,6 +41,7 @@
 #include "xfs_buf_item.h"
 #include "xfs_cksum.h"
 #include "xfs_dir2.h"
+#include "xfs_log.h"
 
 
 /*
@@ -266,6 +267,8 @@ xfs_attr3_leaf_verify(
                        return false;
                if (be64_to_cpu(hdr3->info.blkno) != bp->b_bn)
                        return false;
+               if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr3->info.lsn)))
+                       return false;
        } else {
                if (ichdr.magic != XFS_ATTR_LEAF_MAGIC)
                        return false;
index f38f9bd81557062a69e3381cb90e9af50297e9ed..5ab95ffa4ae9f6ee38ff4b56a5f1ca0d61e38e67 100644 (file)
@@ -107,7 +107,7 @@ xfs_attr3_rmt_verify(
        if (be32_to_cpu(rmt->rm_bytes) > fsbsize - sizeof(*rmt))
                return false;
        if (be32_to_cpu(rmt->rm_offset) +
-                               be32_to_cpu(rmt->rm_bytes) > XATTR_SIZE_MAX)
+                               be32_to_cpu(rmt->rm_bytes) > XFS_XATTR_SIZE_MAX)
                return false;
        if (rmt->rm_owner == 0)
                return false;
index 8e2010d53b079556de461d6a1be1f9cbbc7e2924..119c2422aac78bcbfb65b8af527efff0aa8e5951 100644 (file)
@@ -948,14 +948,16 @@ xfs_bmap_local_to_extents(
        bp = xfs_btree_get_bufl(args.mp, tp, args.fsbno, 0);
 
        /*
-        * Initialise the block and copy the data
+        * Initialize the block, copy the data and log the remote buffer.
         *
-        * Note: init_fn must set the buffer log item type correctly!
+        * The callout is responsible for logging because the remote format
+        * might differ from the local format and thus we don't know how much to
+        * log here. Note that init_fn must also set the buffer log item type
+        * correctly.
         */
        init_fn(tp, bp, ip, ifp);
 
-       /* account for the change in fork size and log everything */
-       xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1);
+       /* account for the change in fork size */
        xfs_idata_realloc(ip, -ifp->if_bytes, whichfork);
        xfs_bmap_local_to_extents_empty(ip, whichfork);
        flags |= XFS_ILOG_CORE;
@@ -1435,7 +1437,7 @@ xfs_bmap_search_extents(
        xfs_ifork_t     *ifp;           /* inode fork pointer */
        xfs_bmbt_rec_host_t  *ep;            /* extent record pointer */
 
-       XFS_STATS_INC(xs_look_exlist);
+       XFS_STATS_INC(ip->i_mount, xs_look_exlist);
        ifp = XFS_IFORK_PTR(ip, fork);
 
        ep = xfs_bmap_search_multi_extents(ifp, bno, eofp, lastxp, gotp, prevp);
@@ -1732,7 +1734,7 @@ xfs_bmap_add_extent_delay_real(
        ASSERT(!bma->cur ||
               (bma->cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL));
 
-       XFS_STATS_INC(xs_add_exlist);
+       XFS_STATS_INC(mp, xs_add_exlist);
 
 #define        LEFT            r[0]
 #define        RIGHT           r[1]
@@ -2286,7 +2288,7 @@ xfs_bmap_add_extent_unwritten_real(
        ASSERT(*idx <= ifp->if_bytes / sizeof(struct xfs_bmbt_rec));
        ASSERT(!isnullstartblock(new->br_startblock));
 
-       XFS_STATS_INC(xs_add_exlist);
+       XFS_STATS_INC(mp, xs_add_exlist);
 
 #define        LEFT            r[0]
 #define        RIGHT           r[1]
@@ -2946,7 +2948,7 @@ xfs_bmap_add_extent_hole_real(
        ASSERT(!bma->cur ||
               !(bma->cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL));
 
-       XFS_STATS_INC(xs_add_exlist);
+       XFS_STATS_INC(mp, xs_add_exlist);
 
        state = 0;
        if (whichfork == XFS_ATTR_FORK)
@@ -3800,8 +3802,13 @@ xfs_bmap_btalloc(
        args.wasdel = ap->wasdel;
        args.isfl = 0;
        args.userdata = ap->userdata;
-       if ((error = xfs_alloc_vextent(&args)))
+       if (ap->userdata & XFS_ALLOC_USERDATA_ZERO)
+               args.ip = ap->ip;
+
+       error = xfs_alloc_vextent(&args);
+       if (error)
                return error;
+
        if (tryagain && args.fsbno == NULLFSBLOCK) {
                /*
                 * Exact allocation failed. Now try with alignment
@@ -4036,7 +4043,7 @@ xfs_bmapi_read(
        if (XFS_FORCED_SHUTDOWN(mp))
                return -EIO;
 
-       XFS_STATS_INC(xs_blk_mapr);
+       XFS_STATS_INC(mp, xs_blk_mapr);
 
        ifp = XFS_IFORK_PTR(ip, whichfork);
 
@@ -4221,7 +4228,7 @@ xfs_bmapi_delay(
        if (XFS_FORCED_SHUTDOWN(mp))
                return -EIO;
 
-       XFS_STATS_INC(xs_blk_mapw);
+       XFS_STATS_INC(mp, xs_blk_mapw);
 
        if (!(ifp->if_flags & XFS_IFEXTENTS)) {
                error = xfs_iread_extents(NULL, ip, XFS_DATA_FORK);
@@ -4300,11 +4307,14 @@ xfs_bmapi_allocate(
 
        /*
         * Indicate if this is the first user data in the file, or just any
-        * user data.
+        * user data. And if it is userdata, indicate whether it needs to
+        * be initialised to zero during allocation.
         */
        if (!(bma->flags & XFS_BMAPI_METADATA)) {
                bma->userdata = (bma->offset == 0) ?
                        XFS_ALLOC_INITIAL_USER_DATA : XFS_ALLOC_USERDATA;
+               if (bma->flags & XFS_BMAPI_ZERO)
+                       bma->userdata |= XFS_ALLOC_USERDATA_ZERO;
        }
 
        bma->minlen = (bma->flags & XFS_BMAPI_CONTIG) ? bma->length : 1;
@@ -4419,6 +4429,17 @@ xfs_bmapi_convert_unwritten(
        mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN)
                                ? XFS_EXT_NORM : XFS_EXT_UNWRITTEN;
 
+       /*
+        * Before insertion into the bmbt, zero the range being converted
+        * if required.
+        */
+       if (flags & XFS_BMAPI_ZERO) {
+               error = xfs_zero_extent(bma->ip, mval->br_startblock,
+                                       mval->br_blockcount);
+               if (error)
+                       return error;
+       }
+
        error = xfs_bmap_add_extent_unwritten_real(bma->tp, bma->ip, &bma->idx,
                        &bma->cur, mval, bma->firstblock, bma->flist,
                        &tmp_logflags);
@@ -4512,6 +4533,18 @@ xfs_bmapi_write(
        ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL);
        ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
 
+       /* zeroing is for currently only for data extents, not metadata */
+       ASSERT((flags & (XFS_BMAPI_METADATA | XFS_BMAPI_ZERO)) !=
+                       (XFS_BMAPI_METADATA | XFS_BMAPI_ZERO));
+       /*
+        * we can allocate unwritten extents or pre-zero allocated blocks,
+        * but it makes no sense to do both at once. This would result in
+        * zeroing the unwritten extent twice, but it still being an
+        * unwritten extent....
+        */
+       ASSERT((flags & (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO)) !=
+                       (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO));
+
        if (unlikely(XFS_TEST_ERROR(
            (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
             XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE),
@@ -4525,7 +4558,7 @@ xfs_bmapi_write(
 
        ifp = XFS_IFORK_PTR(ip, whichfork);
 
-       XFS_STATS_INC(xs_blk_mapw);
+       XFS_STATS_INC(mp, xs_blk_mapw);
 
        if (*firstblock == NULLFSBLOCK) {
                if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE)
@@ -4718,12 +4751,12 @@ xfs_bmap_del_extent(
        xfs_filblks_t           temp2;  /* for indirect length calculations */
        int                     state = 0;
 
-       XFS_STATS_INC(xs_del_exlist);
+       mp = ip->i_mount;
+       XFS_STATS_INC(mp, xs_del_exlist);
 
        if (whichfork == XFS_ATTR_FORK)
                state |= BMAP_ATTRFORK;
 
-       mp = ip->i_mount;
        ifp = XFS_IFORK_PTR(ip, whichfork);
        ASSERT((*idx >= 0) && (*idx < ifp->if_bytes /
                (uint)sizeof(xfs_bmbt_rec_t)));
@@ -5070,7 +5103,7 @@ xfs_bunmapi(
                *done = 1;
                return 0;
        }
-       XFS_STATS_INC(xs_blk_unmap);
+       XFS_STATS_INC(mp, xs_blk_unmap);
        isrt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip);
        start = bno;
        bno = start + len - 1;
index 6aaa0c1c7200594de983a02b40d61900ced8e200..a160f8a5a3fcd280ac1af5e02063fd3818710fe5 100644 (file)
@@ -52,9 +52,9 @@ struct xfs_bmalloca {
        xfs_extlen_t            minleft; /* amount must be left after alloc */
        bool                    eof;    /* set if allocating past last extent */
        bool                    wasdel; /* replacing a delayed allocation */
-       bool                    userdata;/* set if is user data */
        bool                    aeof;   /* allocated space at eof */
        bool                    conv;   /* overwriting unwritten extents */
+       char                    userdata;/* userdata mask */
        int                     flags;
 };
 
@@ -109,6 +109,14 @@ typedef    struct xfs_bmap_free
  */
 #define XFS_BMAPI_CONVERT      0x040
 
+/*
+ * allocate zeroed extents - this requires all newly allocated user data extents
+ * to be initialised to zero. It will be ignored if XFS_BMAPI_METADATA is set.
+ * Use in conjunction with XFS_BMAPI_CONVERT to convert unwritten extents found
+ * during the allocation range to zeroed written extents.
+ */
+#define XFS_BMAPI_ZERO         0x080
+
 #define XFS_BMAPI_FLAGS \
        { XFS_BMAPI_ENTIRE,     "ENTIRE" }, \
        { XFS_BMAPI_METADATA,   "METADATA" }, \
@@ -116,7 +124,8 @@ typedef     struct xfs_bmap_free
        { XFS_BMAPI_PREALLOC,   "PREALLOC" }, \
        { XFS_BMAPI_IGSTATE,    "IGSTATE" }, \
        { XFS_BMAPI_CONTIG,     "CONTIG" }, \
-       { XFS_BMAPI_CONVERT,    "CONVERT" }
+       { XFS_BMAPI_CONVERT,    "CONVERT" }, \
+       { XFS_BMAPI_ZERO,       "ZERO" }
 
 
 static inline int xfs_bmapi_aflag(int w)
index f7d7ee7a26072587262dfd27509ba8f502214cc7..af1bbee5586e4fef04ee03b6b826f89a56566f39 100644 (file)
@@ -32,6 +32,7 @@
 #include "xfs_trace.h"
 #include "xfs_cksum.h"
 #include "xfs_alloc.h"
+#include "xfs_log.h"
 
 /*
  * Cursor allocation zone.
@@ -222,7 +223,7 @@ xfs_btree_check_ptr(
  * long-form btree header.
  *
  * Prior to calculting the CRC, pull the LSN out of the buffer log item and put
- * it into the buffer so recovery knows what the last modifcation was that made
+ * it into the buffer so recovery knows what the last modification was that made
  * it to disk.
  */
 void
@@ -243,8 +244,14 @@ bool
 xfs_btree_lblock_verify_crc(
        struct xfs_buf          *bp)
 {
-       if (xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb))
+       struct xfs_btree_block  *block = XFS_BUF_TO_BLOCK(bp);
+       struct xfs_mount        *mp = bp->b_target->bt_mount;
+
+       if (xfs_sb_version_hascrc(&mp->m_sb)) {
+               if (!xfs_log_check_lsn(mp, be64_to_cpu(block->bb_u.l.bb_lsn)))
+                       return false;
                return xfs_buf_verify_cksum(bp, XFS_BTREE_LBLOCK_CRC_OFF);
+       }
 
        return true;
 }
@@ -254,7 +261,7 @@ xfs_btree_lblock_verify_crc(
  * short-form btree header.
  *
  * Prior to calculting the CRC, pull the LSN out of the buffer log item and put
- * it into the buffer so recovery knows what the last modifcation was that made
+ * it into the buffer so recovery knows what the last modification was that made
  * it to disk.
  */
 void
@@ -275,8 +282,14 @@ bool
 xfs_btree_sblock_verify_crc(
        struct xfs_buf          *bp)
 {
-       if (xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb))
+       struct xfs_btree_block  *block = XFS_BUF_TO_BLOCK(bp);
+       struct xfs_mount        *mp = bp->b_target->bt_mount;
+
+       if (xfs_sb_version_hascrc(&mp->m_sb)) {
+               if (!xfs_log_check_lsn(mp, be64_to_cpu(block->bb_u.s.bb_lsn)))
+                       return false;
                return xfs_buf_verify_cksum(bp, XFS_BTREE_SBLOCK_CRC_OFF);
+       }
 
        return true;
 }
index 8f18bab73ea535d8de8cd20a78b14d68b35f079f..992dec0638f331095bffb51d910eb63b5ac67ac9 100644 (file)
@@ -84,31 +84,38 @@ union xfs_btree_rec {
 /*
  * Generic stats interface
  */
-#define __XFS_BTREE_STATS_INC(type, stat) \
-       XFS_STATS_INC(xs_ ## type ## _2_ ## stat)
-#define XFS_BTREE_STATS_INC(cur, stat)  \
+#define __XFS_BTREE_STATS_INC(mp, type, stat) \
+       XFS_STATS_INC(mp, xs_ ## type ## _2_ ## stat)
+#define XFS_BTREE_STATS_INC(cur, stat) \
 do {    \
+       struct xfs_mount *__mp = cur->bc_mp; \
        switch (cur->bc_btnum) {  \
-       case XFS_BTNUM_BNO: __XFS_BTREE_STATS_INC(abtb, stat); break;   \
-       case XFS_BTNUM_CNT: __XFS_BTREE_STATS_INC(abtc, stat); break;   \
-       case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_INC(bmbt, stat); break;  \
-       case XFS_BTNUM_INO: __XFS_BTREE_STATS_INC(ibt, stat); break;    \
-       case XFS_BTNUM_FINO: __XFS_BTREE_STATS_INC(fibt, stat); break;  \
+       case XFS_BTNUM_BNO: __XFS_BTREE_STATS_INC(__mp, abtb, stat); break; \
+       case XFS_BTNUM_CNT: __XFS_BTREE_STATS_INC(__mp, abtc, stat); break; \
+       case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_INC(__mp, bmbt, stat); break; \
+       case XFS_BTNUM_INO: __XFS_BTREE_STATS_INC(__mp, ibt, stat); break; \
+       case XFS_BTNUM_FINO: __XFS_BTREE_STATS_INC(__mp, fibt, stat); break; \
        case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break;       \
        }       \
 } while (0)
 
-#define __XFS_BTREE_STATS_ADD(type, stat, val) \
-       XFS_STATS_ADD(xs_ ## type ## _2_ ## stat, val)
+#define __XFS_BTREE_STATS_ADD(mp, type, stat, val) \
+       XFS_STATS_ADD(mp, xs_ ## type ## _2_ ## stat, val)
 #define XFS_BTREE_STATS_ADD(cur, stat, val)  \
 do {    \
+       struct xfs_mount *__mp = cur->bc_mp; \
        switch (cur->bc_btnum) {  \
-       case XFS_BTNUM_BNO: __XFS_BTREE_STATS_ADD(abtb, stat, val); break; \
-       case XFS_BTNUM_CNT: __XFS_BTREE_STATS_ADD(abtc, stat, val); break; \
-       case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_ADD(bmbt, stat, val); break; \
-       case XFS_BTNUM_INO: __XFS_BTREE_STATS_ADD(ibt, stat, val); break; \
-       case XFS_BTNUM_FINO: __XFS_BTREE_STATS_ADD(fibt, stat, val); break; \
-       case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break;       \
+       case XFS_BTNUM_BNO:     \
+               __XFS_BTREE_STATS_ADD(__mp, abtb, stat, val); break; \
+       case XFS_BTNUM_CNT:     \
+               __XFS_BTREE_STATS_ADD(__mp, abtc, stat, val); break; \
+       case XFS_BTNUM_BMAP:    \
+               __XFS_BTREE_STATS_ADD(__mp, bmbt, stat, val); break; \
+       case XFS_BTNUM_INO:     \
+               __XFS_BTREE_STATS_ADD(__mp, ibt, stat, val); break; \
+       case XFS_BTNUM_FINO:    \
+               __XFS_BTREE_STATS_ADD(__mp, fibt, stat, val); break; \
+       case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \
        }       \
 } while (0)
 
index be43248a5822844f642007ad40bd1e00c808d54e..e89a0f8f827ce0da6829c7189471a4438d019b05 100644 (file)
@@ -39,6 +39,7 @@
 #include "xfs_trace.h"
 #include "xfs_cksum.h"
 #include "xfs_buf_item.h"
+#include "xfs_log.h"
 
 /*
  * xfs_da_btree.c
@@ -150,6 +151,8 @@ xfs_da3_node_verify(
                        return false;
                if (be64_to_cpu(hdr3->info.blkno) != bp->b_bn)
                        return false;
+               if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr3->info.lsn)))
+                       return false;
        } else {
                if (ichdr.magic != XFS_DA_NODE_MAGIC)
                        return false;
@@ -322,6 +325,7 @@ xfs_da3_node_create(
        if (xfs_sb_version_hascrc(&mp->m_sb)) {
                struct xfs_da3_node_hdr *hdr3 = bp->b_addr;
 
+               memset(hdr3, 0, sizeof(struct xfs_da3_node_hdr));
                ichdr.magic = XFS_DA3_NODE_MAGIC;
                hdr3->info.blkno = cpu_to_be64(bp->b_bn);
                hdr3->info.owner = cpu_to_be64(args->dp->i_ino);
index 9de401d297e5bf1972922849d221c4495edd86be..2fb53a5c0a745259d2e18164e8505cb21d704724 100644 (file)
@@ -271,7 +271,7 @@ xfs_dir_createname(
                rval = xfs_dir_ino_validate(tp->t_mountp, inum);
                if (rval)
                        return rval;
-               XFS_STATS_INC(xs_dir_create);
+               XFS_STATS_INC(dp->i_mount, xs_dir_create);
        }
 
        args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS);
@@ -365,7 +365,7 @@ xfs_dir_lookup(
        int             lock_mode;
 
        ASSERT(S_ISDIR(dp->i_d.di_mode));
-       XFS_STATS_INC(xs_dir_lookup);
+       XFS_STATS_INC(dp->i_mount, xs_dir_lookup);
 
        /*
         * We need to use KM_NOFS here so that lockdep will not throw false
@@ -444,7 +444,7 @@ xfs_dir_removename(
        int             v;              /* type-checking value */
 
        ASSERT(S_ISDIR(dp->i_d.di_mode));
-       XFS_STATS_INC(xs_dir_remove);
+       XFS_STATS_INC(dp->i_mount, xs_dir_remove);
 
        args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS);
        if (!args)
index 4778d1dd511afae50eee4c6a7b5d0a7220fc4c4d..9c10e2b8cfcb594101a38011ee68bfcf6a5e09a1 100644 (file)
@@ -34,6 +34,7 @@
 #include "xfs_error.h"
 #include "xfs_trace.h"
 #include "xfs_cksum.h"
+#include "xfs_log.h"
 
 /*
  * Local function prototypes.
@@ -71,6 +72,8 @@ xfs_dir3_block_verify(
                        return false;
                if (be64_to_cpu(hdr3->blkno) != bp->b_bn)
                        return false;
+               if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr3->lsn)))
+                       return false;
        } else {
                if (hdr3->magic != cpu_to_be32(XFS_DIR2_BLOCK_MAGIC))
                        return false;
index 824131e71bc53017082f518355c47f963e792cd8..af71a84f343c33b98471665df2d2f37b025571cc 100644 (file)
@@ -31,6 +31,7 @@
 #include "xfs_trans.h"
 #include "xfs_buf_item.h"
 #include "xfs_cksum.h"
+#include "xfs_log.h"
 
 /*
  * Check the consistency of the data block.
@@ -224,6 +225,8 @@ xfs_dir3_data_verify(
                        return false;
                if (be64_to_cpu(hdr3->blkno) != bp->b_bn)
                        return false;
+               if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr3->lsn)))
+                       return false;
        } else {
                if (hdr3->magic != cpu_to_be32(XFS_DIR2_DATA_MAGIC))
                        return false;
index f300240ebb8d1575191379978ba5ed722c009718..3923e1f9469761548b34a6db73076bb8f90d0c66 100644 (file)
@@ -33,6 +33,7 @@
 #include "xfs_trans.h"
 #include "xfs_buf_item.h"
 #include "xfs_cksum.h"
+#include "xfs_log.h"
 
 /*
  * Local function declarations.
@@ -164,6 +165,8 @@ xfs_dir3_leaf_verify(
                        return false;
                if (be64_to_cpu(leaf3->info.blkno) != bp->b_bn)
                        return false;
+               if (!xfs_log_check_lsn(mp, be64_to_cpu(leaf3->info.lsn)))
+                       return false;
        } else {
                if (leaf->hdr.info.magic != cpu_to_be16(magic))
                        return false;
index cc28e924545b52159cb8b0201b5d52dba58f7b1d..70b0cb2fd55606422eaf08ce9e016e33f66fe6a2 100644 (file)
@@ -33,6 +33,7 @@
 #include "xfs_trans.h"
 #include "xfs_buf_item.h"
 #include "xfs_cksum.h"
+#include "xfs_log.h"
 
 /*
  * Function declarations.
@@ -97,6 +98,8 @@ xfs_dir3_free_verify(
                        return false;
                if (be64_to_cpu(hdr3->blkno) != bp->b_bn)
                        return false;
+               if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr3->lsn)))
+                       return false;
        } else {
                if (hdr->magic != cpu_to_be32(XFS_DIR2_FREE_MAGIC))
                        return false;
index 9590a069e5569a88942e4726382db7819d7884f7..8774498ce0ffab68918e69e6f29571a8a34e969e 100644 (file)
@@ -59,6 +59,14 @@ struct xfs_ifork;
 #define        XFS_SB_VERSION_BORGBIT          0x4000  /* ASCII only case-insens. */
 #define        XFS_SB_VERSION_MOREBITSBIT      0x8000
 
+/*
+ * The size of a single extended attribute on disk is limited by
+ * the size of index values within the attribute entries themselves.
+ * These are be16 fields, so we can only support attribute data
+ * sizes up to 2^16 bytes in length.
+ */
+#define XFS_XATTR_SIZE_MAX (1 << 16)
+
 /*
  * Supported feature bit list is just all bits in the versionnum field because
  * we've used them all up and understand them all. Except, of course, for the
@@ -1483,13 +1491,17 @@ struct xfs_acl {
  */
 #define XFS_ACL_MAX_ENTRIES(mp)        \
        (xfs_sb_version_hascrc(&mp->m_sb) \
-               ?  (XATTR_SIZE_MAX - sizeof(struct xfs_acl)) / \
+               ?  (XFS_XATTR_SIZE_MAX - sizeof(struct xfs_acl)) / \
                                                sizeof(struct xfs_acl_entry) \
                : 25)
 
-#define XFS_ACL_MAX_SIZE(mp) \
+#define XFS_ACL_SIZE(cnt) \
        (sizeof(struct xfs_acl) + \
-               sizeof(struct xfs_acl_entry) * XFS_ACL_MAX_ENTRIES((mp)))
+               sizeof(struct xfs_acl_entry) * cnt)
+
+#define XFS_ACL_MAX_SIZE(mp) \
+       XFS_ACL_SIZE(XFS_ACL_MAX_ENTRIES((mp)))
+
 
 /* On-disk XFS extended attribute names */
 #define SGI_ACL_FILE           "SGI_ACL_FILE"
index 89689c6a43e2cf6a0f042f2abaa9dcd0da5a0873..b2b73a998d425d04779262ead61d02d65b153bc8 100644 (file)
@@ -489,6 +489,16 @@ typedef struct xfs_swapext
 #define XFS_FSOP_GOING_FLAGS_LOGFLUSH          0x1     /* flush log but not data */
 #define XFS_FSOP_GOING_FLAGS_NOLOGFLUSH                0x2     /* don't flush log nor data */
 
+/*
+ * ioctl limits
+ */
+#ifdef XATTR_LIST_MAX
+#  define XFS_XATTR_LIST_MAX XATTR_LIST_MAX
+#else
+#  define XFS_XATTR_LIST_MAX 65536
+#endif
+
+
 /*
  * ioctl commands that are used by Linux filesystems
  */
index 54deb2d12ac6bdfeb55ca2e05b56c81ed169e1a5..70c1db99f6a720df26fa0d4c430ad401141f1ad2 100644 (file)
@@ -38,6 +38,7 @@
 #include "xfs_icreate_item.h"
 #include "xfs_icache.h"
 #include "xfs_trace.h"
+#include "xfs_log.h"
 
 
 /*
@@ -2500,9 +2501,14 @@ xfs_agi_verify(
        struct xfs_mount *mp = bp->b_target->bt_mount;
        struct xfs_agi  *agi = XFS_BUF_TO_AGI(bp);
 
-       if (xfs_sb_version_hascrc(&mp->m_sb) &&
-           !uuid_equal(&agi->agi_uuid, &mp->m_sb.sb_meta_uuid))
+       if (xfs_sb_version_hascrc(&mp->m_sb)) {
+               if (!uuid_equal(&agi->agi_uuid, &mp->m_sb.sb_meta_uuid))
+                       return false;
+               if (!xfs_log_check_lsn(mp,
+                               be64_to_cpu(XFS_BUF_TO_AGI(bp)->agi_lsn)))
                        return false;
+       }
+
        /*
         * Validate the magic number of the agi block.
         */
index 47425140f34303745bd8ff4b2b2dd0d34d0f033e..a0b071d881a02aa3d99b08e83aadb999b65270a4 100644 (file)
@@ -35,6 +35,7 @@
 #include "xfs_bmap_btree.h"
 #include "xfs_alloc_btree.h"
 #include "xfs_ialloc_btree.h"
+#include "xfs_log.h"
 
 /*
  * Physical superblock buffer manipulations. Shared with libxfs in userspace.
@@ -163,6 +164,15 @@ xfs_mount_validate_sb(
 "Filesystem can not be safely mounted by this kernel.");
                        return -EINVAL;
                }
+       } else if (xfs_sb_version_hascrc(sbp)) {
+               /*
+                * We can't read verify the sb LSN because the read verifier is
+                * called before the log is allocated and processed. We know the
+                * log is set up before write verifier (!check_version) calls,
+                * so just check it here.
+                */
+               if (!xfs_log_check_lsn(mp, sbp->sb_lsn))
+                       return -EFSCORRUPTED;
        }
 
        if (xfs_sb_version_has_pquotino(sbp)) {
index 8f8af05b3f13da7acadc9ebfbc64f0e7debaf655..cb6fd20a4d3d19b61ac5db3dde29345a18432845 100644 (file)
@@ -31,6 +31,7 @@
 #include "xfs_cksum.h"
 #include "xfs_trans.h"
 #include "xfs_buf_item.h"
+#include "xfs_log.h"
 
 
 /*
@@ -60,6 +61,7 @@ xfs_symlink_hdr_set(
        if (!xfs_sb_version_hascrc(&mp->m_sb))
                return 0;
 
+       memset(dsl, 0, sizeof(struct xfs_dsymlink_hdr));
        dsl->sl_magic = cpu_to_be32(XFS_SYMLINK_MAGIC);
        dsl->sl_offset = cpu_to_be32(offset);
        dsl->sl_bytes = cpu_to_be32(size);
@@ -116,6 +118,8 @@ xfs_symlink_verify(
                return false;
        if (dsl->sl_owner == 0)
                return false;
+       if (!xfs_log_check_lsn(mp, be64_to_cpu(dsl->sl_lsn)))
+               return false;
 
        return true;
 }
@@ -183,6 +187,7 @@ xfs_symlink_local_to_remote(
        if (!xfs_sb_version_hascrc(&mp->m_sb)) {
                bp->b_ops = NULL;
                memcpy(bp->b_addr, ifp->if_u1.if_data, ifp->if_bytes);
+               xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1);
                return;
        }
 
@@ -198,4 +203,6 @@ xfs_symlink_local_to_remote(
        buf = bp->b_addr;
        buf += xfs_symlink_hdr_set(mp, ip->i_ino, 0, ifp->if_bytes, bp);
        memcpy(buf, ifp->if_u1.if_data, ifp->if_bytes);
+       xfs_trans_log_buf(tp, bp, 0, sizeof(struct xfs_dsymlink_hdr) +
+                                       ifp->if_bytes - 1);
 }
index 4b641676f258d7ac76c4462a562cc4406b89d882..6bb470fbb8e8ff3567abfb23b774607c7eab2dda 100644 (file)
 
 STATIC struct posix_acl *
 xfs_acl_from_disk(
-       struct xfs_acl  *aclp,
-       int             max_entries)
+       const struct xfs_acl    *aclp,
+       int                     len,
+       int                     max_entries)
 {
        struct posix_acl_entry *acl_e;
        struct posix_acl *acl;
-       struct xfs_acl_entry *ace;
+       const struct xfs_acl_entry *ace;
        unsigned int count, i;
 
+       if (len < sizeof(*aclp))
+               return ERR_PTR(-EFSCORRUPTED);
        count = be32_to_cpu(aclp->acl_cnt);
-       if (count > max_entries)
+       if (count > max_entries || XFS_ACL_SIZE(count) != len)
                return ERR_PTR(-EFSCORRUPTED);
 
        acl = posix_acl_alloc(count, GFP_KERNEL);
@@ -160,10 +163,11 @@ xfs_get_acl(struct inode *inode, int type)
                 */
                if (error == -ENOATTR)
                        goto out_update_cache;
+               acl = ERR_PTR(error);
                goto out;
        }
 
-       acl = xfs_acl_from_disk(xfs_acl, XFS_ACL_MAX_ENTRIES(ip->i_mount));
+       acl = xfs_acl_from_disk(xfs_acl, len, XFS_ACL_MAX_ENTRIES(ip->i_mount));
        if (IS_ERR(acl))
                goto out;
 
index 3841b07f27bf0106a9c1ed901deaf6f8b3d3472f..52f8255d6bdfe0c511bd9d29fb76b89a5b05efdf 100644 (file)
@@ -20,7 +20,6 @@
 
 struct inode;
 struct posix_acl;
-struct xfs_inode;
 
 #ifdef CONFIG_XFS_POSIX_ACL
 extern struct posix_acl *xfs_get_acl(struct inode *inode, int type);
@@ -36,4 +35,7 @@ static inline struct posix_acl *xfs_get_acl(struct inode *inode, int type)
 # define posix_acl_access_exists(inode)                        0
 # define posix_acl_default_exists(inode)               0
 #endif /* CONFIG_XFS_POSIX_ACL */
+
+extern void xfs_forget_acl(struct inode *inode, const char *name, int xflags);
+
 #endif /* __XFS_ACL_H__ */
index 50ab2879b9da0ec1211abacbf6598b0a90eddd8a..29e7e5dd5178ef84638752f31ce6149c64398061 100644 (file)
@@ -172,6 +172,12 @@ xfs_setfilesize_ioend(
        current_set_flags_nested(&tp->t_pflags, PF_FSTRANS);
        __sb_writers_acquired(VFS_I(ip)->i_sb, SB_FREEZE_FS);
 
+       /* we abort the update if there was an IO error */
+       if (ioend->io_error) {
+               xfs_trans_cancel(tp);
+               return ioend->io_error;
+       }
+
        return xfs_setfilesize(ip, tp, ioend->io_offset, ioend->io_size);
 }
 
@@ -212,14 +218,17 @@ xfs_end_io(
                ioend->io_error = -EIO;
                goto done;
        }
-       if (ioend->io_error)
-               goto done;
 
        /*
         * For unwritten extents we need to issue transactions to convert a
         * range to normal written extens after the data I/O has finished.
+        * Detecting and handling completion IO errors is done individually
+        * for each case as different cleanup operations need to be performed
+        * on error.
         */
        if (ioend->io_type == XFS_IO_UNWRITTEN) {
+               if (ioend->io_error)
+                       goto done;
                error = xfs_iomap_write_unwritten(ip, ioend->io_offset,
                                                  ioend->io_size);
        } else if (ioend->io_append_trans) {
@@ -1250,13 +1259,28 @@ xfs_vm_releasepage(
  * the DIO. There is only going to be one reference to the ioend and its life
  * cycle is constrained by the DIO completion code. hence we don't need
  * reference counting here.
+ *
+ * Note that for DIO, an IO to the highest supported file block offset (i.e.
+ * 2^63 - 1FSB bytes) will result in the offset + count overflowing a signed 64
+ * bit variable. Hence if we see this overflow, we have to assume that the IO is
+ * extending the file size. We won't know for sure until IO completion is run
+ * and the actual max write offset is communicated to the IO completion
+ * routine.
+ *
+ * For DAX page faults, we are preparing to never see unwritten extents here,
+ * nor should we ever extend the inode size. Hence we will soon have nothing to
+ * do here for this case, ensuring we don't have to provide an IO completion
+ * callback to free an ioend that we don't actually need for a fault into the
+ * page at offset (2^63 - 1FSB) bytes.
  */
+
 static void
 xfs_map_direct(
        struct inode            *inode,
        struct buffer_head      *bh_result,
        struct xfs_bmbt_irec    *imap,
-       xfs_off_t               offset)
+       xfs_off_t               offset,
+       bool                    dax_fault)
 {
        struct xfs_ioend        *ioend;
        xfs_off_t               size = bh_result->b_size;
@@ -1269,6 +1293,13 @@ xfs_map_direct(
 
        trace_xfs_gbmap_direct(XFS_I(inode), offset, size, type, imap);
 
+       if (dax_fault) {
+               ASSERT(type == XFS_IO_OVERWRITE);
+               trace_xfs_gbmap_direct_none(XFS_I(inode), offset, size, type,
+                                           imap);
+               return;
+       }
+
        if (bh_result->b_private) {
                ioend = bh_result->b_private;
                ASSERT(ioend->io_size > 0);
@@ -1283,7 +1314,8 @@ xfs_map_direct(
                                              ioend->io_size, ioend->io_type,
                                              imap);
        } else if (type == XFS_IO_UNWRITTEN ||
-                  offset + size > i_size_read(inode)) {
+                  offset + size > i_size_read(inode) ||
+                  offset + size < 0) {
                ioend = xfs_alloc_ioend(inode, type);
                ioend->io_offset = offset;
                ioend->io_size = size;
@@ -1345,7 +1377,8 @@ __xfs_get_blocks(
        sector_t                iblock,
        struct buffer_head      *bh_result,
        int                     create,
-       bool                    direct)
+       bool                    direct,
+       bool                    dax_fault)
 {
        struct xfs_inode        *ip = XFS_I(inode);
        struct xfs_mount        *mp = ip->i_mount;
@@ -1393,18 +1426,20 @@ __xfs_get_blocks(
        if (error)
                goto out_unlock;
 
+       /* for DAX, we convert unwritten extents directly */
        if (create &&
            (!nimaps ||
             (imap.br_startblock == HOLESTARTBLOCK ||
-             imap.br_startblock == DELAYSTARTBLOCK))) {
+             imap.br_startblock == DELAYSTARTBLOCK) ||
+            (IS_DAX(inode) && ISUNWRITTEN(&imap)))) {
                if (direct || xfs_get_extsz_hint(ip)) {
                        /*
-                        * Drop the ilock in preparation for starting the block
-                        * allocation transaction.  It will be retaken
-                        * exclusively inside xfs_iomap_write_direct for the
-                        * actual allocation.
+                        * xfs_iomap_write_direct() expects the shared lock. It
+                        * is unlocked on return.
                         */
-                       xfs_iunlock(ip, lockmode);
+                       if (lockmode == XFS_ILOCK_EXCL)
+                               xfs_ilock_demote(ip, lockmode);
+
                        error = xfs_iomap_write_direct(ip, offset, size,
                                                       &imap, nimaps);
                        if (error)
@@ -1441,6 +1476,12 @@ __xfs_get_blocks(
                goto out_unlock;
        }
 
+       if (IS_DAX(inode) && create) {
+               ASSERT(!ISUNWRITTEN(&imap));
+               /* zeroing is not needed at a higher layer */
+               new = 0;
+       }
+
        /* trim mapping down to size requested */
        if (direct || size > (1 << inode->i_blkbits))
                xfs_map_trim_size(inode, iblock, bh_result,
@@ -1458,7 +1499,8 @@ __xfs_get_blocks(
                        set_buffer_unwritten(bh_result);
                /* direct IO needs special help */
                if (create && direct)
-                       xfs_map_direct(inode, bh_result, &imap, offset);
+                       xfs_map_direct(inode, bh_result, &imap, offset,
+                                      dax_fault);
        }
 
        /*
@@ -1505,7 +1547,7 @@ xfs_get_blocks(
        struct buffer_head      *bh_result,
        int                     create)
 {
-       return __xfs_get_blocks(inode, iblock, bh_result, create, false);
+       return __xfs_get_blocks(inode, iblock, bh_result, create, false, false);
 }
 
 int
@@ -1515,7 +1557,17 @@ xfs_get_blocks_direct(
        struct buffer_head      *bh_result,
        int                     create)
 {
-       return __xfs_get_blocks(inode, iblock, bh_result, create, true);
+       return __xfs_get_blocks(inode, iblock, bh_result, create, true, false);
+}
+
+int
+xfs_get_blocks_dax_fault(
+       struct inode            *inode,
+       sector_t                iblock,
+       struct buffer_head      *bh_result,
+       int                     create)
+{
+       return __xfs_get_blocks(inode, iblock, bh_result, create, true, true);
 }
 
 static void
@@ -1614,45 +1666,6 @@ xfs_end_io_direct_write(
        __xfs_end_io_direct_write(inode, ioend, offset, size);
 }
 
-/*
- * For DAX we need a mapping buffer callback for unwritten extent conversion
- * when page faults allocate blocks and then zero them. Note that in this
- * case the mapping indicated by the ioend may extend beyond EOF. We most
- * definitely do not want to extend EOF here, so we trim back the ioend size to
- * EOF.
- */
-#ifdef CONFIG_FS_DAX
-void
-xfs_end_io_dax_write(
-       struct buffer_head      *bh,
-       int                     uptodate)
-{
-       struct xfs_ioend        *ioend = bh->b_private;
-       struct inode            *inode = ioend->io_inode;
-       ssize_t                 size = ioend->io_size;
-
-       ASSERT(IS_DAX(ioend->io_inode));
-
-       /* if there was an error zeroing, then don't convert it */
-       if (!uptodate)
-               ioend->io_error = -EIO;
-
-       /*
-        * Trim update to EOF, so we don't extend EOF during unwritten extent
-        * conversion of partial EOF blocks.
-        */
-       spin_lock(&XFS_I(inode)->i_flags_lock);
-       if (ioend->io_offset + size > i_size_read(inode))
-               size = i_size_read(inode) - ioend->io_offset;
-       spin_unlock(&XFS_I(inode)->i_flags_lock);
-
-       __xfs_end_io_direct_write(inode, ioend, ioend->io_offset, size);
-
-}
-#else
-void xfs_end_io_dax_write(struct buffer_head *bh, int uptodate) { }
-#endif
-
 static inline ssize_t
 xfs_vm_do_dio(
        struct inode            *inode,
index 86afd1ac7895f8d225fa2da2285c03f7014666e3..f6ffc9ae5cebeae7ebf8c2cc7c3598c07c4c68f5 100644 (file)
@@ -58,7 +58,8 @@ int   xfs_get_blocks(struct inode *inode, sector_t offset,
                       struct buffer_head *map_bh, int create);
 int    xfs_get_blocks_direct(struct inode *inode, sector_t offset,
                              struct buffer_head *map_bh, int create);
-void   xfs_end_io_dax_write(struct buffer_head *bh, int uptodate);
+int    xfs_get_blocks_dax_fault(struct inode *inode, sector_t offset,
+                                struct buffer_head *map_bh, int create);
 
 extern void xfs_count_page_state(struct page *, int *, int *);
 
index 65fb37a18e92316616967bc7465c4e36e3fa116f..0ef7c2ed3f8a8e30e260485ee130d1a3b008ea07 100644 (file)
@@ -511,7 +511,7 @@ xfs_attr_list_int(
        xfs_inode_t *dp = context->dp;
        uint            lock_mode;
 
-       XFS_STATS_INC(xs_attr_list);
+       XFS_STATS_INC(dp->i_mount, xs_attr_list);
 
        if (XFS_FORCED_SHUTDOWN(dp->i_mount))
                return -EIO;
index 3bf4ad0d19e4f3203bdb36b23f74616f9c691741..dbae6490a79a5f41e5407b57f82477e5ed7582b8 100644 (file)
@@ -56,6 +56,35 @@ xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb)
                 XFS_FSB_TO_DADDR((ip)->i_mount, (fsb)));
 }
 
+/*
+ * Routine to zero an extent on disk allocated to the specific inode.
+ *
+ * The VFS functions take a linearised filesystem block offset, so we have to
+ * convert the sparse xfs fsb to the right format first.
+ * VFS types are real funky, too.
+ */
+int
+xfs_zero_extent(
+       struct xfs_inode *ip,
+       xfs_fsblock_t   start_fsb,
+       xfs_off_t       count_fsb)
+{
+       struct xfs_mount *mp = ip->i_mount;
+       xfs_daddr_t     sector = xfs_fsb_to_db(ip, start_fsb);
+       sector_t        block = XFS_BB_TO_FSBT(mp, sector);
+       ssize_t         size = XFS_FSB_TO_B(mp, count_fsb);
+
+       if (IS_DAX(VFS_I(ip)))
+               return dax_clear_blocks(VFS_I(ip), block, size);
+
+       /*
+        * let the block layer decide on the fastest method of
+        * implementing the zeroing.
+        */
+       return sb_issue_zeroout(mp->m_super, block, count_fsb, GFP_NOFS);
+
+}
+
 /*
  * Routine to be called at transaction's end by xfs_bmapi, xfs_bunmapi
  * caller.  Frees all the extents that need freeing, which must be done
@@ -229,6 +258,13 @@ xfs_bmap_rtalloc(
                xfs_trans_mod_dquot_byino(ap->tp, ap->ip,
                        ap->wasdel ? XFS_TRANS_DQ_DELRTBCOUNT :
                                        XFS_TRANS_DQ_RTBCOUNT, (long) ralen);
+
+               /* Zero the extent if we were asked to do so */
+               if (ap->userdata & XFS_ALLOC_USERDATA_ZERO) {
+                       error = xfs_zero_extent(ap->ip, ap->blkno, ap->length);
+                       if (error)
+                               return error;
+               }
        } else {
                ap->length = 0;
        }
@@ -1027,7 +1063,7 @@ xfs_alloc_file_space(
                xfs_bmap_init(&free_list, &firstfsb);
                error = xfs_bmapi_write(tp, ip, startoffset_fsb,
                                        allocatesize_fsb, alloc_type, &firstfsb,
-                                       0, imapp, &nimaps, &free_list);
+                                       resblks, imapp, &nimaps, &free_list);
                if (error) {
                        goto error0;
                }
index 8ecffb35935b0c6f66cbc8d49993b740e052658d..3243cdf97f33f2998de6d8207d1128093a0ec587 100644 (file)
@@ -201,7 +201,7 @@ _xfs_buf_alloc(
        atomic_set(&bp->b_pin_count, 0);
        init_waitqueue_head(&bp->b_waiters);
 
-       XFS_STATS_INC(xb_create);
+       XFS_STATS_INC(target->bt_mount, xb_create);
        trace_xfs_buf_init(bp, _RET_IP_);
 
        return bp;
@@ -354,15 +354,16 @@ retry:
                         */
                        if (!(++retries % 100))
                                xfs_err(NULL,
-               "possible memory allocation deadlock in %s (mode:0x%x)",
+               "%s(%u) possible memory allocation deadlock in %s (mode:0x%x)",
+                                       current->comm, current->pid,
                                        __func__, gfp_mask);
 
-                       XFS_STATS_INC(xb_page_retries);
+                       XFS_STATS_INC(bp->b_target->bt_mount, xb_page_retries);
                        congestion_wait(BLK_RW_ASYNC, HZ/50);
                        goto retry;
                }
 
-               XFS_STATS_INC(xb_page_found);
+               XFS_STATS_INC(bp->b_target->bt_mount, xb_page_found);
 
                nbytes = min_t(size_t, size, PAGE_SIZE - offset);
                size -= nbytes;
@@ -516,7 +517,7 @@ _xfs_buf_find(
                new_bp->b_pag = pag;
                spin_unlock(&pag->pag_buf_lock);
        } else {
-               XFS_STATS_INC(xb_miss_locked);
+               XFS_STATS_INC(btp->bt_mount, xb_miss_locked);
                spin_unlock(&pag->pag_buf_lock);
                xfs_perag_put(pag);
        }
@@ -529,11 +530,11 @@ found:
        if (!xfs_buf_trylock(bp)) {
                if (flags & XBF_TRYLOCK) {
                        xfs_buf_rele(bp);
-                       XFS_STATS_INC(xb_busy_locked);
+                       XFS_STATS_INC(btp->bt_mount, xb_busy_locked);
                        return NULL;
                }
                xfs_buf_lock(bp);
-               XFS_STATS_INC(xb_get_locked_waited);
+               XFS_STATS_INC(btp->bt_mount, xb_get_locked_waited);
        }
 
        /*
@@ -549,7 +550,7 @@ found:
        }
 
        trace_xfs_buf_find(bp, flags, _RET_IP_);
-       XFS_STATS_INC(xb_get_locked);
+       XFS_STATS_INC(btp->bt_mount, xb_get_locked);
        return bp;
 }
 
@@ -603,7 +604,7 @@ found:
                }
        }
 
-       XFS_STATS_INC(xb_get);
+       XFS_STATS_INC(target->bt_mount, xb_get);
        trace_xfs_buf_get(bp, flags, _RET_IP_);
        return bp;
 }
@@ -643,7 +644,7 @@ xfs_buf_read_map(
                trace_xfs_buf_read(bp, flags, _RET_IP_);
 
                if (!XFS_BUF_ISDONE(bp)) {
-                       XFS_STATS_INC(xb_get_read);
+                       XFS_STATS_INC(target->bt_mount, xb_get_read);
                        bp->b_ops = ops;
                        _xfs_buf_read(bp, flags);
                } else if (flags & XBF_ASYNC) {
index a989a9c7edb7fe22e2a425c3efaef417bde89b72..642d55d100758b10fb3b9deec90de526707c3d98 100644 (file)
@@ -666,7 +666,7 @@ xfs_readdir(
                return -EIO;
 
        ASSERT(S_ISDIR(dp->i_d.di_mode));
-       XFS_STATS_INC(xs_dir_getdents);
+       XFS_STATS_INC(dp->i_mount, xs_dir_getdents);
 
        args.dp = dp;
        args.geo = dp->i_mount->m_dir_geo;
index 30cb3afb67f091e3e96f7b6a6d189d4464706b68..7ac6c5c586cbadbd7784f24c7880f72d7ff66ed0 100644 (file)
@@ -75,9 +75,9 @@ xfs_qm_dqdestroy(
        ASSERT(list_empty(&dqp->q_lru));
 
        mutex_destroy(&dqp->q_qlock);
-       kmem_zone_free(xfs_qm_dqzone, dqp);
 
-       XFS_STATS_DEC(xs_qm_dquot);
+       XFS_STATS_DEC(dqp->q_mount, xs_qm_dquot);
+       kmem_zone_free(xfs_qm_dqzone, dqp);
 }
 
 /*
@@ -605,7 +605,7 @@ xfs_qm_dqread(
                break;
        }
 
-       XFS_STATS_INC(xs_qm_dquot);
+       XFS_STATS_INC(mp, xs_qm_dquot);
 
        trace_xfs_dqread(dqp);
 
@@ -747,12 +747,12 @@ restart:
                mutex_unlock(&qi->qi_tree_lock);
 
                trace_xfs_dqget_hit(dqp);
-               XFS_STATS_INC(xs_qm_dqcachehits);
+               XFS_STATS_INC(mp, xs_qm_dqcachehits);
                *O_dqpp = dqp;
                return 0;
        }
        mutex_unlock(&qi->qi_tree_lock);
-       XFS_STATS_INC(xs_qm_dqcachemisses);
+       XFS_STATS_INC(mp, xs_qm_dqcachemisses);
 
        /*
         * Dquot cache miss. We don't want to keep the inode lock across
@@ -806,7 +806,7 @@ restart:
                mutex_unlock(&qi->qi_tree_lock);
                trace_xfs_dqget_dup(dqp);
                xfs_qm_dqdestroy(dqp);
-               XFS_STATS_INC(xs_qm_dquot_dups);
+               XFS_STATS_INC(mp, xs_qm_dquot_dups);
                goto restart;
        }
 
@@ -846,7 +846,7 @@ xfs_qm_dqput(
                trace_xfs_dqput_free(dqp);
 
                if (list_lru_add(&qi->qi_lru, &dqp->q_lru))
-                       XFS_STATS_INC(xs_qm_dquot_unused);
+                       XFS_STATS_INC(dqp->q_mount, xs_qm_dquot_unused);
        }
        xfs_dqunlock(dqp);
 }
index e78feb400e22b22d59228b4f959d5b845848a675..f5392ab2def1ab806aa075bcc19643cbac6ca8f9 100644 (file)
@@ -242,19 +242,30 @@ xfs_file_fsync(
        }
 
        /*
-        * All metadata updates are logged, which means that we just have
-        * to flush the log up to the latest LSN that touched the inode.
+        * All metadata updates are logged, which means that we just have to
+        * flush the log up to the latest LSN that touched the inode. If we have
+        * concurrent fsync/fdatasync() calls, we need them to all block on the
+        * log force before we clear the ili_fsync_fields field. This ensures
+        * that we don't get a racing sync operation that does not wait for the
+        * metadata to hit the journal before returning. If we race with
+        * clearing the ili_fsync_fields, then all that will happen is the log
+        * force will do nothing as the lsn will already be on disk. We can't
+        * race with setting ili_fsync_fields because that is done under
+        * XFS_ILOCK_EXCL, and that can't happen because we hold the lock shared
+        * until after the ili_fsync_fields is cleared.
         */
        xfs_ilock(ip, XFS_ILOCK_SHARED);
        if (xfs_ipincount(ip)) {
                if (!datasync ||
-                   (ip->i_itemp->ili_fields & ~XFS_ILOG_TIMESTAMP))
+                   (ip->i_itemp->ili_fsync_fields & ~XFS_ILOG_TIMESTAMP))
                        lsn = ip->i_itemp->ili_last_lsn;
        }
-       xfs_iunlock(ip, XFS_ILOCK_SHARED);
 
-       if (lsn)
+       if (lsn) {
                error = _xfs_log_force_lsn(mp, lsn, XFS_LOG_SYNC, &log_flushed);
+               ip->i_itemp->ili_fsync_fields = 0;
+       }
+       xfs_iunlock(ip, XFS_ILOCK_SHARED);
 
        /*
         * If we only have a single device, and the log force about was
@@ -287,7 +298,7 @@ xfs_file_read_iter(
        xfs_fsize_t             n;
        loff_t                  pos = iocb->ki_pos;
 
-       XFS_STATS_INC(xs_read_calls);
+       XFS_STATS_INC(mp, xs_read_calls);
 
        if (unlikely(iocb->ki_flags & IOCB_DIRECT))
                ioflags |= XFS_IO_ISDIRECT;
@@ -365,7 +376,7 @@ xfs_file_read_iter(
 
        ret = generic_file_read_iter(iocb, to);
        if (ret > 0)
-               XFS_STATS_ADD(xs_read_bytes, ret);
+               XFS_STATS_ADD(mp, xs_read_bytes, ret);
 
        xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED);
        return ret;
@@ -383,7 +394,7 @@ xfs_file_splice_read(
        int                     ioflags = 0;
        ssize_t                 ret;
 
-       XFS_STATS_INC(xs_read_calls);
+       XFS_STATS_INC(ip->i_mount, xs_read_calls);
 
        if (infilp->f_mode & FMODE_NOCMTIME)
                ioflags |= XFS_IO_INVIS;
@@ -401,7 +412,7 @@ xfs_file_splice_read(
        else
                ret = generic_file_splice_read(infilp, ppos, pipe, count, flags);
        if (ret > 0)
-               XFS_STATS_ADD(xs_read_bytes, ret);
+               XFS_STATS_ADD(ip->i_mount, xs_read_bytes, ret);
 
        xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED);
        return ret;
@@ -482,6 +493,8 @@ xfs_zero_eof(
        ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL));
        ASSERT(offset > isize);
 
+       trace_xfs_zero_eof(ip, isize, offset - isize);
+
        /*
         * First handle zeroing the block on which isize resides.
         *
@@ -574,6 +587,7 @@ xfs_file_aio_write_checks(
        struct xfs_inode        *ip = XFS_I(inode);
        ssize_t                 error = 0;
        size_t                  count = iov_iter_count(from);
+       bool                    drained_dio = false;
 
 restart:
        error = generic_write_checks(iocb, from);
@@ -611,12 +625,13 @@ restart:
                bool    zero = false;
 
                spin_unlock(&ip->i_flags_lock);
-               if (*iolock == XFS_IOLOCK_SHARED) {
-                       xfs_rw_iunlock(ip, *iolock);
-                       *iolock = XFS_IOLOCK_EXCL;
-                       xfs_rw_ilock(ip, *iolock);
-                       iov_iter_reexpand(from, count);
-
+               if (!drained_dio) {
+                       if (*iolock == XFS_IOLOCK_SHARED) {
+                               xfs_rw_iunlock(ip, *iolock);
+                               *iolock = XFS_IOLOCK_EXCL;
+                               xfs_rw_ilock(ip, *iolock);
+                               iov_iter_reexpand(from, count);
+                       }
                        /*
                         * We now have an IO submission barrier in place, but
                         * AIO can do EOF updates during IO completion and hence
@@ -626,6 +641,7 @@ restart:
                         * no-op.
                         */
                        inode_dio_wait(inode);
+                       drained_dio = true;
                        goto restart;
                }
                error = xfs_zero_eof(ip, iocb->ki_pos, i_size_read(inode), &zero);
@@ -867,7 +883,7 @@ xfs_file_write_iter(
        ssize_t                 ret;
        size_t                  ocount = iov_iter_count(from);
 
-       XFS_STATS_INC(xs_write_calls);
+       XFS_STATS_INC(ip->i_mount, xs_write_calls);
 
        if (ocount == 0)
                return 0;
@@ -883,7 +899,7 @@ xfs_file_write_iter(
        if (ret > 0) {
                ssize_t err;
 
-               XFS_STATS_ADD(xs_write_bytes, ret);
+               XFS_STATS_ADD(ip->i_mount, xs_write_bytes, ret);
 
                /* Handle various SYNC-type writes */
                err = generic_write_sync(file, iocb->ki_pos - ret, ret);
@@ -1477,7 +1493,7 @@ xfs_file_llseek(
  *
  * mmap_sem (MM)
  *   sb_start_pagefault(vfs, freeze)
- *     i_mmap_lock (XFS - truncate serialisation)
+ *     i_mmaplock (XFS - truncate serialisation)
  *       page_lock (MM)
  *         i_lock (XFS - extent map serialisation)
  */
@@ -1503,10 +1519,9 @@ xfs_filemap_page_mkwrite(
        xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED);
 
        if (IS_DAX(inode)) {
-               ret = __dax_mkwrite(vma, vmf, xfs_get_blocks_direct,
-                                   xfs_end_io_dax_write);
+               ret = __dax_mkwrite(vma, vmf, xfs_get_blocks_dax_fault, NULL);
        } else {
-               ret = __block_page_mkwrite(vma, vmf, xfs_get_blocks);
+               ret = block_page_mkwrite(vma, vmf, xfs_get_blocks);
                ret = block_page_mkwrite_return(ret);
        }
 
@@ -1538,7 +1553,7 @@ xfs_filemap_fault(
                 * changes to xfs_get_blocks_direct() to map unwritten extent
                 * ioend for conversion on read-only mappings.
                 */
-               ret = __dax_fault(vma, vmf, xfs_get_blocks_direct, NULL);
+               ret = __dax_fault(vma, vmf, xfs_get_blocks_dax_fault, NULL);
        } else
                ret = filemap_fault(vma, vmf);
        xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED);
@@ -1546,6 +1561,13 @@ xfs_filemap_fault(
        return ret;
 }
 
+/*
+ * Similar to xfs_filemap_fault(), the DAX fault path can call into here on
+ * both read and write faults. Hence we need to handle both cases. There is no
+ * ->pmd_mkwrite callout for huge pages, so we have a single function here to
+ * handle both cases here. @flags carries the information on the type of fault
+ * occuring.
+ */
 STATIC int
 xfs_filemap_pmd_fault(
        struct vm_area_struct   *vma,
@@ -1562,15 +1584,54 @@ xfs_filemap_pmd_fault(
 
        trace_xfs_filemap_pmd_fault(ip);
 
-       sb_start_pagefault(inode->i_sb);
-       file_update_time(vma->vm_file);
+       if (flags & FAULT_FLAG_WRITE) {
+               sb_start_pagefault(inode->i_sb);
+               file_update_time(vma->vm_file);
+       }
+
        xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED);
-       ret = __dax_pmd_fault(vma, addr, pmd, flags, xfs_get_blocks_direct,
-                                   xfs_end_io_dax_write);
+       ret = __dax_pmd_fault(vma, addr, pmd, flags, xfs_get_blocks_dax_fault,
+                             NULL);
        xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED);
-       sb_end_pagefault(inode->i_sb);
 
+       if (flags & FAULT_FLAG_WRITE)
+               sb_end_pagefault(inode->i_sb);
+
+       return ret;
+}
+
+/*
+ * pfn_mkwrite was originally inteneded to ensure we capture time stamp
+ * updates on write faults. In reality, it's need to serialise against
+ * truncate similar to page_mkwrite. Hence we open-code dax_pfn_mkwrite()
+ * here and cycle the XFS_MMAPLOCK_SHARED to ensure we serialise the fault
+ * barrier in place.
+ */
+static int
+xfs_filemap_pfn_mkwrite(
+       struct vm_area_struct   *vma,
+       struct vm_fault         *vmf)
+{
+
+       struct inode            *inode = file_inode(vma->vm_file);
+       struct xfs_inode        *ip = XFS_I(inode);
+       int                     ret = VM_FAULT_NOPAGE;
+       loff_t                  size;
+
+       trace_xfs_filemap_pfn_mkwrite(ip);
+
+       sb_start_pagefault(inode->i_sb);
+       file_update_time(vma->vm_file);
+
+       /* check if the faulting page hasn't raced with truncate */
+       xfs_ilock(ip, XFS_MMAPLOCK_SHARED);
+       size = (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT;
+       if (vmf->pgoff >= size)
+               ret = VM_FAULT_SIGBUS;
+       xfs_iunlock(ip, XFS_MMAPLOCK_SHARED);
+       sb_end_pagefault(inode->i_sb);
        return ret;
+
 }
 
 static const struct vm_operations_struct xfs_file_vm_ops = {
@@ -1578,6 +1639,7 @@ static const struct vm_operations_struct xfs_file_vm_ops = {
        .pmd_fault      = xfs_filemap_pmd_fault,
        .map_pages      = filemap_map_pages,
        .page_mkwrite   = xfs_filemap_page_mkwrite,
+       .pfn_mkwrite    = xfs_filemap_pfn_mkwrite,
 };
 
 STATIC int
index 0a326bd64d4e39b3b197437cf6e964bffb4cca0a..d7a490f24ead08e3abf5019654ee5ee6e2e1eb7b 100644 (file)
@@ -63,7 +63,7 @@ xfs_inode_alloc(
                return NULL;
        }
 
-       XFS_STATS_INC(vn_active);
+       XFS_STATS_INC(mp, vn_active);
        ASSERT(atomic_read(&ip->i_pincount) == 0);
        ASSERT(!spin_is_locked(&ip->i_flags_lock));
        ASSERT(!xfs_isiflocked(ip));
@@ -129,7 +129,7 @@ xfs_inode_free(
        /* asserts to verify all state is correct here */
        ASSERT(atomic_read(&ip->i_pincount) == 0);
        ASSERT(!xfs_isiflocked(ip));
-       XFS_STATS_DEC(vn_active);
+       XFS_STATS_DEC(ip->i_mount, vn_active);
 
        call_rcu(&VFS_I(ip)->i_rcu, xfs_inode_free_callback);
 }
@@ -159,7 +159,7 @@ xfs_iget_cache_hit(
        spin_lock(&ip->i_flags_lock);
        if (ip->i_ino != ino) {
                trace_xfs_iget_skip(ip);
-               XFS_STATS_INC(xs_ig_frecycle);
+               XFS_STATS_INC(mp, xs_ig_frecycle);
                error = -EAGAIN;
                goto out_error;
        }
@@ -177,7 +177,7 @@ xfs_iget_cache_hit(
         */
        if (ip->i_flags & (XFS_INEW|XFS_IRECLAIM)) {
                trace_xfs_iget_skip(ip);
-               XFS_STATS_INC(xs_ig_frecycle);
+               XFS_STATS_INC(mp, xs_ig_frecycle);
                error = -EAGAIN;
                goto out_error;
        }
@@ -259,7 +259,7 @@ xfs_iget_cache_hit(
                xfs_ilock(ip, lock_flags);
 
        xfs_iflags_clear(ip, XFS_ISTALE | XFS_IDONTCACHE);
-       XFS_STATS_INC(xs_ig_found);
+       XFS_STATS_INC(mp, xs_ig_found);
 
        return 0;
 
@@ -342,7 +342,7 @@ xfs_iget_cache_miss(
        error = radix_tree_insert(&pag->pag_ici_root, agino, ip);
        if (unlikely(error)) {
                WARN_ON(error != -EEXIST);
-               XFS_STATS_INC(xs_ig_dup);
+               XFS_STATS_INC(mp, xs_ig_dup);
                error = -EAGAIN;
                goto out_preload_end;
        }
@@ -412,7 +412,7 @@ xfs_iget(
        if (!ino || XFS_INO_TO_AGNO(mp, ino) >= mp->m_sb.sb_agcount)
                return -EINVAL;
 
-       XFS_STATS_INC(xs_ig_attempts);
+       XFS_STATS_INC(mp, xs_ig_attempts);
 
        /* get the perag structure and ensure that it's inode capable */
        pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ino));
@@ -429,7 +429,7 @@ again:
                        goto out_error_or_again;
        } else {
                rcu_read_unlock();
-               XFS_STATS_INC(xs_ig_missed);
+               XFS_STATS_INC(mp, xs_ig_missed);
 
                error = xfs_iget_cache_miss(mp, pag, tp, ino, &ip,
                                                        flags, lock_flags);
@@ -965,7 +965,7 @@ reclaim:
        xfs_ifunlock(ip);
        xfs_iunlock(ip, XFS_ILOCK_EXCL);
 
-       XFS_STATS_INC(xs_ig_reclaims);
+       XFS_STATS_INC(ip->i_mount, xs_ig_reclaims);
        /*
         * Remove the inode from the per-AG radix tree.
         *
index dc40a6d5ae0dc909a79ef72917c5eb1551fae227..8ee393996b7d6852f8820ca7c411be1f16a2f097 100644 (file)
@@ -2365,6 +2365,7 @@ retry:
 
                        iip->ili_last_fields = iip->ili_fields;
                        iip->ili_fields = 0;
+                       iip->ili_fsync_fields = 0;
                        iip->ili_logged = 1;
                        xfs_trans_ail_copy_lsn(mp->m_ail, &iip->ili_flush_lsn,
                                                &iip->ili_item.li_lsn);
@@ -3271,8 +3272,8 @@ xfs_iflush_cluster(
        }
 
        if (clcount) {
-               XFS_STATS_INC(xs_icluster_flushcnt);
-               XFS_STATS_ADD(xs_icluster_flushinode, clcount);
+               XFS_STATS_INC(mp, xs_icluster_flushcnt);
+               XFS_STATS_ADD(mp, xs_icluster_flushinode, clcount);
        }
 
 out_free:
@@ -3345,7 +3346,7 @@ xfs_iflush(
        struct xfs_dinode       *dip;
        int                     error;
 
-       XFS_STATS_INC(xs_iflush_count);
+       XFS_STATS_INC(mp, xs_iflush_count);
 
        ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED));
        ASSERT(xfs_isiflocked(ip));
@@ -3560,6 +3561,7 @@ xfs_iflush_int(
         */
        iip->ili_last_fields = iip->ili_fields;
        iip->ili_fields = 0;
+       iip->ili_fsync_fields = 0;
        iip->ili_logged = 1;
 
        xfs_trans_ail_copy_lsn(mp->m_ail, &iip->ili_flush_lsn,
index 62bd80f4edd9aacb74c254c70b3e9de8618ef988..d14b12b8cfefb90f8fe4c92a0033a41cbde2e552 100644 (file)
@@ -719,6 +719,7 @@ xfs_iflush_abort(
                 * attempted.
                 */
                iip->ili_fields = 0;
+               iip->ili_fsync_fields = 0;
        }
        /*
         * Release the inode's flush lock since we're done with it.
index 488d81254e28a73e26fba494fd89d21139415ac6..4c7722e325b369332d381c8435edfc33728a4067 100644 (file)
@@ -34,6 +34,7 @@ typedef struct xfs_inode_log_item {
        unsigned short          ili_logged;        /* flushed logged data */
        unsigned int            ili_last_fields;   /* fields when flushed */
        unsigned int            ili_fields;        /* fields to be logged */
+       unsigned int            ili_fsync_fields;  /* logged since last fsync */
 } xfs_inode_log_item_t;
 
 static inline int xfs_inode_clean(xfs_inode_t *ip)
index ea7d85af53101f25ed0d1b9598edae5c8af77bcc..d42738deec6de6128b1a4b0784c45b5447848d02 100644 (file)
@@ -40,6 +40,7 @@
 #include "xfs_symlink.h"
 #include "xfs_trans.h"
 #include "xfs_pnfs.h"
+#include "xfs_acl.h"
 
 #include <linux/capability.h>
 #include <linux/dcache.h>
@@ -411,7 +412,7 @@ xfs_attrlist_by_handle(
        if (copy_from_user(&al_hreq, arg, sizeof(xfs_fsop_attrlist_handlereq_t)))
                return -EFAULT;
        if (al_hreq.buflen < sizeof(struct attrlist) ||
-           al_hreq.buflen > XATTR_LIST_MAX)
+           al_hreq.buflen > XFS_XATTR_LIST_MAX)
                return -EINVAL;
 
        /*
@@ -455,7 +456,7 @@ xfs_attrmulti_attr_get(
        unsigned char           *kbuf;
        int                     error = -EFAULT;
 
-       if (*len > XATTR_SIZE_MAX)
+       if (*len > XFS_XATTR_SIZE_MAX)
                return -EINVAL;
        kbuf = kmem_zalloc_large(*len, KM_SLEEP);
        if (!kbuf)
@@ -482,17 +483,22 @@ xfs_attrmulti_attr_set(
        __uint32_t              flags)
 {
        unsigned char           *kbuf;
+       int                     error;
 
        if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
                return -EPERM;
-       if (len > XATTR_SIZE_MAX)
+       if (len > XFS_XATTR_SIZE_MAX)
                return -EINVAL;
 
        kbuf = memdup_user(ubuf, len);
        if (IS_ERR(kbuf))
                return PTR_ERR(kbuf);
 
-       return xfs_attr_set(XFS_I(inode), name, kbuf, len, flags);
+       error = xfs_attr_set(XFS_I(inode), name, kbuf, len, flags);
+       if (!error)
+               xfs_forget_acl(inode, name, flags);
+       kfree(kbuf);
+       return error;
 }
 
 int
@@ -501,9 +507,14 @@ xfs_attrmulti_attr_remove(
        unsigned char           *name,
        __uint32_t              flags)
 {
+       int                     error;
+
        if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
                return -EPERM;
-       return xfs_attr_remove(XFS_I(inode), name, flags);
+       error = xfs_attr_remove(XFS_I(inode), name, flags);
+       if (!error)
+               xfs_forget_acl(inode, name, flags);
+       return error;
 }
 
 STATIC int
@@ -1028,7 +1039,7 @@ xfs_ioctl_setattr_xflags(
        xfs_diflags_to_linux(ip);
        xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
        xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-       XFS_STATS_INC(xs_ig_attrchg);
+       XFS_STATS_INC(mp, xs_ig_attrchg);
        return 0;
 }
 
index b88bdc85dd3db365230d51e31fc97030ed2de38d..1a05d8ae327dbc2fa0e6d3212bbfde1a209a5502 100644 (file)
@@ -356,7 +356,7 @@ xfs_compat_attrlist_by_handle(
                           sizeof(compat_xfs_fsop_attrlist_handlereq_t)))
                return -EFAULT;
        if (al_hreq.buflen < sizeof(struct attrlist) ||
-           al_hreq.buflen > XATTR_LIST_MAX)
+           al_hreq.buflen > XFS_XATTR_LIST_MAX)
                return -EINVAL;
 
        /*
index 1f86033171c84ef4b12a201e112c9c37c7c69bdf..f4f5b43cf64712cf8fe46924820142fc75a33e86 100644 (file)
@@ -131,20 +131,30 @@ xfs_iomap_write_direct(
        uint            qblocks, resblks, resrtextents;
        int             committed;
        int             error;
-
-       error = xfs_qm_dqattach(ip, 0);
-       if (error)
-               return error;
+       int             lockmode;
+       int             bmapi_flags = XFS_BMAPI_PREALLOC;
 
        rt = XFS_IS_REALTIME_INODE(ip);
        extsz = xfs_get_extsz_hint(ip);
+       lockmode = XFS_ILOCK_SHARED;    /* locked by caller */
+
+       ASSERT(xfs_isilocked(ip, lockmode));
 
        offset_fsb = XFS_B_TO_FSBT(mp, offset);
        last_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)(offset + count)));
        if ((offset + count) > XFS_ISIZE(ip)) {
+               /*
+                * Assert that the in-core extent list is present since this can
+                * call xfs_iread_extents() and we only have the ilock shared.
+                * This should be safe because the lock was held around a bmapi
+                * call in the caller and we only need it to access the in-core
+                * list.
+                */
+               ASSERT(XFS_IFORK_PTR(ip, XFS_DATA_FORK)->if_flags &
+                                                               XFS_IFEXTENTS);
                error = xfs_iomap_eof_align_last_fsb(mp, ip, extsz, &last_fsb);
                if (error)
-                       return error;
+                       goto out_unlock;
        } else {
                if (nmaps && (imap->br_startblock == HOLESTARTBLOCK))
                        last_fsb = MIN(last_fsb, (xfs_fileoff_t)
@@ -173,10 +183,36 @@ xfs_iomap_write_direct(
                quota_flag = XFS_QMOPT_RES_REGBLKS;
        }
 
+       /*
+        * Drop the shared lock acquired by the caller, attach the dquot if
+        * necessary and move on to transaction setup.
+        */
+       xfs_iunlock(ip, lockmode);
+       error = xfs_qm_dqattach(ip, 0);
+       if (error)
+               return error;
+
        /*
         * Allocate and setup the transaction
         */
        tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT);
+
+       /*
+        * For DAX, we do not allocate unwritten extents, but instead we zero
+        * the block before we commit the transaction.  Ideally we'd like to do
+        * this outside the transaction context, but if we commit and then crash
+        * we may not have zeroed the blocks and this will be exposed on
+        * recovery of the allocation. Hence we must zero before commit.
+        * Further, if we are mapping unwritten extents here, we need to zero
+        * and convert them to written so that we don't need an unwritten extent
+        * callback for DAX. This also means that we need to be able to dip into
+        * the reserve block pool if there is no space left but we need to do
+        * unwritten extent conversion.
+        */
+       if (IS_DAX(VFS_I(ip))) {
+               bmapi_flags = XFS_BMAPI_CONVERT | XFS_BMAPI_ZERO;
+               tp->t_flags |= XFS_TRANS_RESERVE;
+       }
        error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write,
                                  resblks, resrtextents);
        /*
@@ -187,7 +223,8 @@ xfs_iomap_write_direct(
                return error;
        }
 
-       xfs_ilock(ip, XFS_ILOCK_EXCL);
+       lockmode = XFS_ILOCK_EXCL;
+       xfs_ilock(ip, lockmode);
 
        error = xfs_trans_reserve_quota_nblks(tp, ip, qblocks, 0, quota_flag);
        if (error)
@@ -202,8 +239,8 @@ xfs_iomap_write_direct(
        xfs_bmap_init(&free_list, &firstfsb);
        nimaps = 1;
        error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb,
-                               XFS_BMAPI_PREALLOC, &firstfsb, 0,
-                               imap, &nimaps, &free_list);
+                               bmapi_flags, &firstfsb, resblks, imap,
+                               &nimaps, &free_list);
        if (error)
                goto out_bmap_cancel;
 
@@ -213,6 +250,7 @@ xfs_iomap_write_direct(
        error = xfs_bmap_finish(&tp, &free_list, &committed);
        if (error)
                goto out_bmap_cancel;
+
        error = xfs_trans_commit(tp);
        if (error)
                goto out_unlock;
@@ -229,7 +267,7 @@ xfs_iomap_write_direct(
                error = xfs_alert_fsblock_zero(ip, imap);
 
 out_unlock:
-       xfs_iunlock(ip, XFS_ILOCK_EXCL);
+       xfs_iunlock(ip, lockmode);
        return error;
 
 out_bmap_cancel:
@@ -670,7 +708,7 @@ xfs_iomap_write_allocate(
        count_fsb = imap->br_blockcount;
        map_start_fsb = imap->br_startoff;
 
-       XFS_STATS_ADD(xs_xstrat_bytes, XFS_FSB_TO_B(mp, count_fsb));
+       XFS_STATS_ADD(mp, xs_xstrat_bytes, XFS_FSB_TO_B(mp, count_fsb));
 
        while (count_fsb != 0) {
                /*
@@ -750,9 +788,9 @@ xfs_iomap_write_allocate(
                         * pointer that the caller gave to us.
                         */
                        error = xfs_bmapi_write(tp, ip, map_start_fsb,
-                                               count_fsb, 0,
-                                               &first_block, 1,
-                                               imap, &nimaps, &free_list);
+                                               count_fsb, 0, &first_block,
+                                               nres, imap, &nimaps,
+                                               &free_list);
                        if (error)
                                goto trans_cancel;
 
@@ -777,7 +815,7 @@ xfs_iomap_write_allocate(
                if ((offset_fsb >= imap->br_startoff) &&
                    (offset_fsb < (imap->br_startoff +
                                   imap->br_blockcount))) {
-                       XFS_STATS_INC(xs_xstrat_quick);
+                       XFS_STATS_INC(mp, xs_xstrat_quick);
                        return 0;
                }
 
@@ -866,8 +904,8 @@ xfs_iomap_write_unwritten(
                xfs_bmap_init(&free_list, &firstfsb);
                nimaps = 1;
                error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb,
-                                 XFS_BMAPI_CONVERT, &firstfsb,
-                                 1, &imap, &nimaps, &free_list);
+                                       XFS_BMAPI_CONVERT, &firstfsb, resblks,
+                                       &imap, &nimaps, &free_list);
                if (error)
                        goto error_on_bmapi_transaction;
 
index 8294132e6a3cdda41704a76a871ddd15d3bb271d..245268a0cdf06e4d518ee915a0add70ef5a42dc6 100644 (file)
@@ -695,7 +695,7 @@ xfs_setattr_nonsize(
 
        xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
 
-       XFS_STATS_INC(xs_ig_attrchg);
+       XFS_STATS_INC(mp, xs_ig_attrchg);
 
        if (mp->m_flags & XFS_MOUNT_WSYNC)
                xfs_trans_set_sync(tp);
@@ -922,7 +922,7 @@ xfs_setattr_size(
 
        xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
 
-       XFS_STATS_INC(xs_ig_attrchg);
+       XFS_STATS_INC(mp, xs_ig_attrchg);
 
        if (mp->m_flags & XFS_MOUNT_WSYNC)
                xfs_trans_set_sync(tp);
index 85f883dd6207bd41b6b2951111009cb5097ae339..ec0e239a0fa9070f30541b14f305b8d28c153339 100644 (file)
@@ -171,6 +171,13 @@ struct xfs_kobj {
        struct completion       complete;
 };
 
+struct xstats {
+       struct xfsstats __percpu        *xs_stats;
+       struct xfs_kobj                 xs_kobj;
+};
+
+extern struct xstats xfsstats;
+
 /* Kernel uid/gid conversion. These are used to convert to/from the on disk
  * uid_t/gid_t types to the kuid_t/kgid_t types that the kernel uses internally.
  * The conversion here is type only, the value will remain the same since we
index aaadee0969c929022725b11dcc2cd3a66995bd29..f52c72a1a06f28c8438dc9248040fe6682ad6843 100644 (file)
@@ -268,7 +268,7 @@ xlog_grant_head_wait(
                __set_current_state(TASK_UNINTERRUPTIBLE);
                spin_unlock(&head->lock);
 
-               XFS_STATS_INC(xs_sleep_logspace);
+               XFS_STATS_INC(log->l_mp, xs_sleep_logspace);
 
                trace_xfs_log_grant_sleep(log, tic);
                schedule();
@@ -379,7 +379,7 @@ xfs_log_regrant(
        if (XLOG_FORCED_SHUTDOWN(log))
                return -EIO;
 
-       XFS_STATS_INC(xs_try_logspace);
+       XFS_STATS_INC(mp, xs_try_logspace);
 
        /*
         * This is a new transaction on the ticket, so we need to change the
@@ -448,7 +448,7 @@ xfs_log_reserve(
        if (XLOG_FORCED_SHUTDOWN(log))
                return -EIO;
 
-       XFS_STATS_INC(xs_try_logspace);
+       XFS_STATS_INC(mp, xs_try_logspace);
 
        ASSERT(*ticp == NULL);
        tic = xlog_ticket_alloc(log, unit_bytes, cnt, client, permanent,
@@ -1768,7 +1768,7 @@ xlog_sync(
        int             v2 = xfs_sb_version_haslogv2(&log->l_mp->m_sb);
        int             size;
 
-       XFS_STATS_INC(xs_log_writes);
+       XFS_STATS_INC(log->l_mp, xs_log_writes);
        ASSERT(atomic_read(&iclog->ic_refcnt) == 0);
 
        /* Add for LR header */
@@ -1805,7 +1805,7 @@ xlog_sync(
        bp = iclog->ic_bp;
        XFS_BUF_SET_ADDR(bp, BLOCK_LSN(be64_to_cpu(iclog->ic_header.h_lsn)));
 
-       XFS_STATS_ADD(xs_log_blocks, BTOBB(count));
+       XFS_STATS_ADD(log->l_mp, xs_log_blocks, BTOBB(count));
 
        /* Do we need to split this write into 2 parts? */
        if (XFS_BUF_ADDR(bp) + BTOBB(count) > log->l_logBBsize) {
@@ -2422,11 +2422,20 @@ xlog_write(
                                                     &partial_copy_len);
                        xlog_verify_dest_ptr(log, ptr);
 
-                       /* copy region */
+                       /*
+                        * Copy region.
+                        *
+                        * Unmount records just log an opheader, so can have
+                        * empty payloads with no data region to copy. Hence we
+                        * only copy the payload if the vector says it has data
+                        * to copy.
+                        */
                        ASSERT(copy_len >= 0);
-                       memcpy(ptr, reg->i_addr + copy_off, copy_len);
-                       xlog_write_adv_cnt(&ptr, &len, &log_offset, copy_len);
-
+                       if (copy_len > 0) {
+                               memcpy(ptr, reg->i_addr + copy_off, copy_len);
+                               xlog_write_adv_cnt(&ptr, &len, &log_offset,
+                                                  copy_len);
+                       }
                        copy_len += start_rec_copy + sizeof(xlog_op_header_t);
                        record_cnt++;
                        data_cnt += contwr ? copy_len : 0;
@@ -2913,7 +2922,7 @@ restart:
 
        iclog = log->l_iclog;
        if (iclog->ic_state != XLOG_STATE_ACTIVE) {
-               XFS_STATS_INC(xs_log_noiclogs);
+               XFS_STATS_INC(log->l_mp, xs_log_noiclogs);
 
                /* Wait for log writes to have flushed */
                xlog_wait(&log->l_flush_wait, &log->l_icloglock);
@@ -3165,11 +3174,19 @@ xlog_state_switch_iclogs(
        }
 
        if (log->l_curr_block >= log->l_logBBsize) {
+               /*
+                * Rewind the current block before the cycle is bumped to make
+                * sure that the combined LSN never transiently moves forward
+                * when the log wraps to the next cycle. This is to support the
+                * unlocked sample of these fields from xlog_valid_lsn(). Most
+                * other cases should acquire l_icloglock.
+                */
+               log->l_curr_block -= log->l_logBBsize;
+               ASSERT(log->l_curr_block >= 0);
+               smp_wmb();
                log->l_curr_cycle++;
                if (log->l_curr_cycle == XLOG_HEADER_MAGIC_NUM)
                        log->l_curr_cycle++;
-               log->l_curr_block -= log->l_logBBsize;
-               ASSERT(log->l_curr_block >= 0);
        }
        ASSERT(iclog == log->l_iclog);
        log->l_iclog = iclog->ic_next;
@@ -3212,7 +3229,7 @@ _xfs_log_force(
        struct xlog_in_core     *iclog;
        xfs_lsn_t               lsn;
 
-       XFS_STATS_INC(xs_log_force);
+       XFS_STATS_INC(mp, xs_log_force);
 
        xlog_cil_force(log);
 
@@ -3297,7 +3314,7 @@ maybe_sleep:
                        spin_unlock(&log->l_icloglock);
                        return -EIO;
                }
-               XFS_STATS_INC(xs_log_force_sleep);
+               XFS_STATS_INC(mp, xs_log_force_sleep);
                xlog_wait(&iclog->ic_force_wait, &log->l_icloglock);
                /*
                 * No need to grab the log lock here since we're
@@ -3362,7 +3379,7 @@ _xfs_log_force_lsn(
 
        ASSERT(lsn != 0);
 
-       XFS_STATS_INC(xs_log_force);
+       XFS_STATS_INC(mp, xs_log_force);
 
        lsn = xlog_cil_force_lsn(log, lsn);
        if (lsn == NULLCOMMITLSN)
@@ -3411,7 +3428,7 @@ try_again:
                             (XLOG_STATE_WANT_SYNC | XLOG_STATE_SYNCING))) {
                                ASSERT(!(iclog->ic_state & XLOG_STATE_IOERROR));
 
-                               XFS_STATS_INC(xs_log_force_sleep);
+                               XFS_STATS_INC(mp, xs_log_force_sleep);
 
                                xlog_wait(&iclog->ic_prev->ic_write_wait,
                                                        &log->l_icloglock);
@@ -3441,7 +3458,7 @@ try_again:
                                spin_unlock(&log->l_icloglock);
                                return -EIO;
                        }
-                       XFS_STATS_INC(xs_log_force_sleep);
+                       XFS_STATS_INC(mp, xs_log_force_sleep);
                        xlog_wait(&iclog->ic_force_wait, &log->l_icloglock);
                        /*
                         * No need to grab the log lock here since we're
@@ -4023,3 +4040,45 @@ xlog_iclogs_empty(
        return 1;
 }
 
+/*
+ * Verify that an LSN stamped into a piece of metadata is valid. This is
+ * intended for use in read verifiers on v5 superblocks.
+ */
+bool
+xfs_log_check_lsn(
+       struct xfs_mount        *mp,
+       xfs_lsn_t               lsn)
+{
+       struct xlog             *log = mp->m_log;
+       bool                    valid;
+
+       /*
+        * norecovery mode skips mount-time log processing and unconditionally
+        * resets the in-core LSN. We can't validate in this mode, but
+        * modifications are not allowed anyways so just return true.
+        */
+       if (mp->m_flags & XFS_MOUNT_NORECOVERY)
+               return true;
+
+       /*
+        * Some metadata LSNs are initialized to NULL (e.g., the agfl). This is
+        * handled by recovery and thus safe to ignore here.
+        */
+       if (lsn == NULLCOMMITLSN)
+               return true;
+
+       valid = xlog_valid_lsn(mp->m_log, lsn);
+
+       /* warn the user about what's gone wrong before verifier failure */
+       if (!valid) {
+               spin_lock(&log->l_icloglock);
+               xfs_warn(mp,
+"Corruption warning: Metadata has LSN (%d:%d) ahead of current LSN (%d:%d). "
+"Please unmount and run xfs_repair (>= v4.3) to resolve.",
+                        CYCLE_LSN(lsn), BLOCK_LSN(lsn),
+                        log->l_curr_cycle, log->l_curr_block);
+               spin_unlock(&log->l_icloglock);
+       }
+
+       return valid;
+}
index 09d91d3166cde43479366e0a3a3ad8e325350cf5..aa533a7d50f2186f051b09c7dcfd78b431571d15 100644 (file)
@@ -181,5 +181,6 @@ bool        xfs_log_item_in_current_chkpt(struct xfs_log_item *lip);
 void   xfs_log_work_queue(struct xfs_mount *mp);
 void   xfs_log_worker(struct work_struct *work);
 void   xfs_log_quiesce(struct xfs_mount *mp);
+bool   xfs_log_check_lsn(struct xfs_mount *, xfs_lsn_t);
 
 #endif /* __XFS_LOG_H__ */
index 950f3f94720c66524baa9a6a4dc0b853e41c3d1b..8daba7491b13f094750d082d5eb8f14a4b3d03d6 100644 (file)
@@ -560,4 +560,55 @@ static inline void xlog_wait(wait_queue_head_t *wq, spinlock_t *lock)
        remove_wait_queue(wq, &wait);
 }
 
+/*
+ * The LSN is valid so long as it is behind the current LSN. If it isn't, this
+ * means that the next log record that includes this metadata could have a
+ * smaller LSN. In turn, this means that the modification in the log would not
+ * replay.
+ */
+static inline bool
+xlog_valid_lsn(
+       struct xlog     *log,
+       xfs_lsn_t       lsn)
+{
+       int             cur_cycle;
+       int             cur_block;
+       bool            valid = true;
+
+       /*
+        * First, sample the current lsn without locking to avoid added
+        * contention from metadata I/O. The current cycle and block are updated
+        * (in xlog_state_switch_iclogs()) and read here in a particular order
+        * to avoid false negatives (e.g., thinking the metadata LSN is valid
+        * when it is not).
+        *
+        * The current block is always rewound before the cycle is bumped in
+        * xlog_state_switch_iclogs() to ensure the current LSN is never seen in
+        * a transiently forward state. Instead, we can see the LSN in a
+        * transiently behind state if we happen to race with a cycle wrap.
+        */
+       cur_cycle = ACCESS_ONCE(log->l_curr_cycle);
+       smp_rmb();
+       cur_block = ACCESS_ONCE(log->l_curr_block);
+
+       if ((CYCLE_LSN(lsn) > cur_cycle) ||
+           (CYCLE_LSN(lsn) == cur_cycle && BLOCK_LSN(lsn) > cur_block)) {
+               /*
+                * If the metadata LSN appears invalid, it's possible the check
+                * above raced with a wrap to the next log cycle. Grab the lock
+                * to check for sure.
+                */
+               spin_lock(&log->l_icloglock);
+               cur_cycle = log->l_curr_cycle;
+               cur_block = log->l_curr_block;
+               spin_unlock(&log->l_icloglock);
+
+               if ((CYCLE_LSN(lsn) > cur_cycle) ||
+                   (CYCLE_LSN(lsn) == cur_cycle && BLOCK_LSN(lsn) > cur_block))
+                       valid = false;
+       }
+
+       return valid;
+}
+
 #endif /* __XFS_LOG_PRIV_H__ */
index 512a0945d52ac4e023e2181510e70e65f3da04e8..c5ecaacdd21833eed42a4852ce16f9a37d5d1bd6 100644 (file)
@@ -3431,7 +3431,7 @@ xlog_recover_add_to_cont_trans(
         * previous record. Copy the rest of the header.
         */
        if (list_empty(&trans->r_itemq)) {
-               ASSERT(len < sizeof(struct xfs_trans_header));
+               ASSERT(len <= sizeof(struct xfs_trans_header));
                if (len > sizeof(struct xfs_trans_header)) {
                        xfs_warn(log->l_mp, "%s: bad header length", __func__);
                        return -EIO;
@@ -4609,9 +4609,19 @@ xlog_recover(
        int             error;
 
        /* find the tail of the log */
-       if ((error = xlog_find_tail(log, &head_blk, &tail_blk)))
+       error = xlog_find_tail(log, &head_blk, &tail_blk);
+       if (error)
                return error;
 
+       /*
+        * The superblock was read before the log was available and thus the LSN
+        * could not be verified. Check the superblock LSN against the current
+        * LSN now that it's known.
+        */
+       if (xfs_sb_version_hascrc(&log->l_mp->m_sb) &&
+           !xfs_log_check_lsn(log->l_mp, log->l_mp->m_sb.sb_lsn))
+               return -EINVAL;
+
        if (tail_blk != head_blk) {
                /* There used to be a comment here:
                 *
index d8b67547ab343ab9eded15a2d56113d001b73224..11792d888e4e707b91a528390deadbf212417e8e 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "xfs.h"
 #include "xfs_fs.h"
+#include "xfs_error.h"
 #include "xfs_format.h"
 #include "xfs_log_format.h"
 #include "xfs_trans_resv.h"
@@ -43,6 +44,7 @@ void func(const struct xfs_mount *mp, const char *fmt, ...)   \
 {                                                              \
        struct va_format        vaf;                            \
        va_list                 args;                           \
+       int                     level;                          \
                                                                \
        va_start(args, fmt);                                    \
                                                                \
@@ -51,6 +53,11 @@ void func(const struct xfs_mount *mp, const char *fmt, ...)  \
                                                                \
        __xfs_printk(kern_level, mp, &vaf);                     \
        va_end(args);                                           \
+                                                               \
+       if (!kstrtoint(kern_level, 0, &level) &&                \
+           level <= LOGLEVEL_ERR &&                            \
+           xfs_error_level >= XFS_ERRLEVEL_HIGH)               \
+               xfs_stack_trace();                              \
 }                                                              \
 
 define_xfs_printk_level(xfs_emerg, KERN_EMERG);
index bf92e0c037c7378cadf1848a4324968170e1ae29..bb753b359bee188b13023caf4597582b402cd31d 100644 (file)
@@ -47,6 +47,16 @@ static DEFINE_MUTEX(xfs_uuid_table_mutex);
 static int xfs_uuid_table_size;
 static uuid_t *xfs_uuid_table;
 
+void
+xfs_uuid_table_free(void)
+{
+       if (xfs_uuid_table_size == 0)
+               return;
+       kmem_free(xfs_uuid_table);
+       xfs_uuid_table = NULL;
+       xfs_uuid_table_size = 0;
+}
+
 /*
  * See if the UUID is unique among mounted XFS filesystems.
  * Mount fails if UUID is nil or a FS with the same UUID is already mounted.
@@ -693,10 +703,15 @@ xfs_mountfs(
        if (error)
                goto out;
 
-       error = xfs_uuid_mount(mp);
+       error = xfs_sysfs_init(&mp->m_stats.xs_kobj, &xfs_stats_ktype,
+                              &mp->m_kobj, "stats");
        if (error)
                goto out_remove_sysfs;
 
+       error = xfs_uuid_mount(mp);
+       if (error)
+               goto out_del_stats;
+
        /*
         * Set the minimum read and write sizes
         */
@@ -971,6 +986,8 @@ xfs_mountfs(
        xfs_da_unmount(mp);
  out_remove_uuid:
        xfs_uuid_unmount(mp);
+ out_del_stats:
+       xfs_sysfs_del(&mp->m_stats.xs_kobj);
  out_remove_sysfs:
        xfs_sysfs_del(&mp->m_kobj);
  out:
@@ -1047,6 +1064,7 @@ xfs_unmountfs(
                xfs_warn(mp, "Unable to update superblock counters. "
                                "Freespace may not be correct on next mount.");
 
+
        xfs_log_unmount(mp);
        xfs_da_unmount(mp);
        xfs_uuid_unmount(mp);
@@ -1056,6 +1074,7 @@ xfs_unmountfs(
 #endif
        xfs_free_perag(mp);
 
+       xfs_sysfs_del(&mp->m_stats.xs_kobj);
        xfs_sysfs_del(&mp->m_kobj);
 }
 
index 7999e91cd49ad862d5fbeb29a5e5487ed94509a8..b57098481c10a2a55a05bf6e75e6e43f7e224401 100644 (file)
@@ -127,6 +127,7 @@ typedef struct xfs_mount {
        int64_t                 m_low_space[XFS_LOWSP_MAX];
                                                /* low free space thresholds */
        struct xfs_kobj         m_kobj;
+       struct xstats           m_stats;        /* per-fs stats */
 
        struct workqueue_struct *m_buf_workqueue;
        struct workqueue_struct *m_data_workqueue;
@@ -312,6 +313,7 @@ typedef struct xfs_perag {
        int             pagb_count;     /* pagb slots in use */
 } xfs_perag_t;
 
+extern void    xfs_uuid_table_free(void);
 extern int     xfs_log_sbcount(xfs_mount_t *);
 extern __uint64_t xfs_default_resblks(xfs_mount_t *mp);
 extern int     xfs_mountfs(xfs_mount_t *mp);
@@ -336,4 +338,7 @@ extern int  xfs_dev_is_read_only(struct xfs_mount *, char *);
 
 extern void    xfs_set_low_space_thresholds(struct xfs_mount *);
 
+int    xfs_zero_extent(struct xfs_inode *ip, xfs_fsblock_t start_fsb,
+                       xfs_off_t count_fsb);
+
 #endif /* __XFS_MOUNT_H__ */
index ab4a6066f7ca7b24fbe4cdf2db0f2c1ddfdab3df..dc6221942b85f437767decfca9bf7ca9b0a94026 100644 (file)
@@ -181,6 +181,11 @@ xfs_fs_map_blocks(
                ASSERT(imap.br_startblock != DELAYSTARTBLOCK);
 
                if (!nimaps || imap.br_startblock == HOLESTARTBLOCK) {
+                       /*
+                        * xfs_iomap_write_direct() expects to take ownership of
+                        * the shared ilock.
+                        */
+                       xfs_ilock(ip, XFS_ILOCK_SHARED);
                        error = xfs_iomap_write_direct(ip, offset, length,
                                                       &imap, nimaps);
                        if (error)
index 587174fd4f2c216637eda70b9986848a0980fd09..532ab79d38fe376c14a5463a97195b59a61d8f84 100644 (file)
@@ -184,7 +184,7 @@ xfs_qm_dqpurge(
         */
        ASSERT(!list_empty(&dqp->q_lru));
        list_lru_del(&qi->qi_lru, &dqp->q_lru);
-       XFS_STATS_DEC(xs_qm_dquot_unused);
+       XFS_STATS_DEC(mp, xs_qm_dquot_unused);
 
        xfs_qm_dqdestroy(dqp);
        return 0;
@@ -448,11 +448,11 @@ xfs_qm_dquot_isolate(
         */
        if (dqp->q_nrefs) {
                xfs_dqunlock(dqp);
-               XFS_STATS_INC(xs_qm_dqwants);
+               XFS_STATS_INC(dqp->q_mount, xs_qm_dqwants);
 
                trace_xfs_dqreclaim_want(dqp);
                list_lru_isolate(lru, &dqp->q_lru);
-               XFS_STATS_DEC(xs_qm_dquot_unused);
+               XFS_STATS_DEC(dqp->q_mount, xs_qm_dquot_unused);
                return LRU_REMOVED;
        }
 
@@ -496,19 +496,19 @@ xfs_qm_dquot_isolate(
 
        ASSERT(dqp->q_nrefs == 0);
        list_lru_isolate_move(lru, &dqp->q_lru, &isol->dispose);
-       XFS_STATS_DEC(xs_qm_dquot_unused);
+       XFS_STATS_DEC(dqp->q_mount, xs_qm_dquot_unused);
        trace_xfs_dqreclaim_done(dqp);
-       XFS_STATS_INC(xs_qm_dqreclaims);
+       XFS_STATS_INC(dqp->q_mount, xs_qm_dqreclaims);
        return LRU_REMOVED;
 
 out_miss_busy:
        trace_xfs_dqreclaim_busy(dqp);
-       XFS_STATS_INC(xs_qm_dqreclaim_misses);
+       XFS_STATS_INC(dqp->q_mount, xs_qm_dqreclaim_misses);
        return LRU_SKIP;
 
 out_unlock_dirty:
        trace_xfs_dqreclaim_busy(dqp);
-       XFS_STATS_INC(xs_qm_dqreclaim_misses);
+       XFS_STATS_INC(dqp->q_mount, xs_qm_dqreclaim_misses);
        xfs_dqunlock(dqp);
        spin_lock(lru_lock);
        return LRU_RETRY;
index f2240383d4bba79b75f78f7d45803c76728457c5..8686df6c76095b907b2e1b78c144f5b1c271a62d 100644 (file)
 #include "xfs.h"
 #include <linux/proc_fs.h>
 
-DEFINE_PER_CPU(struct xfsstats, xfsstats);
+struct xstats xfsstats;
 
-static int counter_val(int idx)
+static int counter_val(struct xfsstats __percpu *stats, int idx)
 {
        int val = 0, cpu;
 
        for_each_possible_cpu(cpu)
-               val += *(((__u32 *)&per_cpu(xfsstats, cpu) + idx));
+               val += *(((__u32 *)per_cpu_ptr(stats, cpu) + idx));
        return val;
 }
 
-static int xfs_stat_proc_show(struct seq_file *m, void *v)
+int xfs_stats_format(struct xfsstats __percpu *stats, char *buf)
 {
        int             i, j;
+       int             len = 0;
        __uint64_t      xs_xstrat_bytes = 0;
        __uint64_t      xs_write_bytes = 0;
        __uint64_t      xs_read_bytes = 0;
@@ -65,54 +66,59 @@ static int xfs_stat_proc_show(struct seq_file *m, void *v)
        };
 
        /* Loop over all stats groups */
+
        for (i = j = 0; i < ARRAY_SIZE(xstats); i++) {
-               seq_printf(m, "%s", xstats[i].desc);
+               len += snprintf(buf + len, PATH_MAX - len, "%s",
+                               xstats[i].desc);
                /* inner loop does each group */
                for (; j < xstats[i].endpoint; j++)
-                       seq_printf(m, " %u", counter_val(j));
-               seq_putc(m, '\n');
+                       len += snprintf(buf + len, PATH_MAX - len, " %u",
+                                       counter_val(stats, j));
+               len += snprintf(buf + len, PATH_MAX - len, "\n");
        }
        /* extra precision counters */
        for_each_possible_cpu(i) {
-               xs_xstrat_bytes += per_cpu(xfsstats, i).xs_xstrat_bytes;
-               xs_write_bytes += per_cpu(xfsstats, i).xs_write_bytes;
-               xs_read_bytes += per_cpu(xfsstats, i).xs_read_bytes;
+               xs_xstrat_bytes += per_cpu_ptr(stats, i)->xs_xstrat_bytes;
+               xs_write_bytes += per_cpu_ptr(stats, i)->xs_write_bytes;
+               xs_read_bytes += per_cpu_ptr(stats, i)->xs_read_bytes;
        }
 
-       seq_printf(m, "xpc %Lu %Lu %Lu\n",
+       len += snprintf(buf + len, PATH_MAX-len, "xpc %Lu %Lu %Lu\n",
                        xs_xstrat_bytes, xs_write_bytes, xs_read_bytes);
-       seq_printf(m, "debug %u\n",
+       len += snprintf(buf + len, PATH_MAX-len, "debug %u\n",
 #if defined(DEBUG)
                1);
 #else
                0);
 #endif
-       return 0;
+
+       return len;
 }
 
-static int xfs_stat_proc_open(struct inode *inode, struct file *file)
+void xfs_stats_clearall(struct xfsstats __percpu *stats)
 {
-       return single_open(file, xfs_stat_proc_show, NULL);
+       int             c;
+       __uint32_t      vn_active;
+
+       xfs_notice(NULL, "Clearing xfsstats");
+       for_each_possible_cpu(c) {
+               preempt_disable();
+               /* save vn_active, it's a universal truth! */
+               vn_active = per_cpu_ptr(stats, c)->vn_active;
+               memset(per_cpu_ptr(stats, c), 0, sizeof(*stats));
+               per_cpu_ptr(stats, c)->vn_active = vn_active;
+               preempt_enable();
+       }
 }
 
-static const struct file_operations xfs_stat_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = xfs_stat_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-};
-
 /* legacy quota interfaces */
 #ifdef CONFIG_XFS_QUOTA
 static int xqm_proc_show(struct seq_file *m, void *v)
 {
        /* maximum; incore; ratio free to inuse; freelist */
        seq_printf(m, "%d\t%d\t%d\t%u\n",
-                       0,
-                       counter_val(XFSSTAT_END_XQMSTAT),
-                       0,
-                       counter_val(XFSSTAT_END_XQMSTAT + 1));
+                  0, counter_val(xfsstats.xs_stats, XFSSTAT_END_XQMSTAT),
+                  0, counter_val(xfsstats.xs_stats, XFSSTAT_END_XQMSTAT + 1));
        return 0;
 }
 
@@ -136,7 +142,7 @@ static int xqmstat_proc_show(struct seq_file *m, void *v)
 
        seq_printf(m, "qm");
        for (j = XFSSTAT_END_IBT_V2; j < XFSSTAT_END_XQMSTAT; j++)
-               seq_printf(m, " %u", counter_val(j));
+               seq_printf(m, " %u", counter_val(xfsstats.xs_stats, j));
        seq_putc(m, '\n');
        return 0;
 }
@@ -155,44 +161,35 @@ static const struct file_operations xqmstat_proc_fops = {
 };
 #endif /* CONFIG_XFS_QUOTA */
 
+#ifdef CONFIG_PROC_FS
 int
 xfs_init_procfs(void)
 {
        if (!proc_mkdir("fs/xfs", NULL))
+               return -ENOMEM;
+
+       if (!proc_symlink("fs/xfs/stat", NULL,
+                         "/sys/fs/xfs/stats/stats"))
                goto out;
 
-       if (!proc_create("fs/xfs/stat", 0, NULL,
-                        &xfs_stat_proc_fops))
-               goto out_remove_xfs_dir;
 #ifdef CONFIG_XFS_QUOTA
        if (!proc_create("fs/xfs/xqmstat", 0, NULL,
                         &xqmstat_proc_fops))
-               goto out_remove_stat_file;
+               goto out;
        if (!proc_create("fs/xfs/xqm", 0, NULL,
                         &xqm_proc_fops))
-               goto out_remove_xqmstat_file;
+               goto out;
 #endif
        return 0;
 
-#ifdef CONFIG_XFS_QUOTA
- out_remove_xqmstat_file:
-       remove_proc_entry("fs/xfs/xqmstat", NULL);
- out_remove_stat_file:
-       remove_proc_entry("fs/xfs/stat", NULL);
-#endif
- out_remove_xfs_dir:
-       remove_proc_entry("fs/xfs", NULL);
- out:
+out:
+       remove_proc_subtree("fs/xfs", NULL);
        return -ENOMEM;
 }
 
 void
 xfs_cleanup_procfs(void)
 {
-#ifdef CONFIG_XFS_QUOTA
-       remove_proc_entry("fs/xfs/xqm", NULL);
-       remove_proc_entry("fs/xfs/xqmstat", NULL);
-#endif
-       remove_proc_entry("fs/xfs/stat", NULL);
-       remove_proc_entry("fs/xfs", NULL);
+       remove_proc_subtree("fs/xfs", NULL);
 }
+#endif /* CONFIG_PROC_FS */
index c8f238b8299a1bc96ce11ff0c20b9be1bb0044a9..483b0eff198836ca1516cf56bdffc5f283af8dad 100644 (file)
@@ -19,8 +19,6 @@
 #define __XFS_STATS_H__
 
 
-#if defined(CONFIG_PROC_FS) && !defined(XFS_STATS_OFF)
-
 #include <linux/percpu.h>
 
 /*
@@ -215,15 +213,29 @@ struct xfsstats {
        __uint64_t              xs_read_bytes;
 };
 
-DECLARE_PER_CPU(struct xfsstats, xfsstats);
+int xfs_stats_format(struct xfsstats __percpu *stats, char *buf);
+void xfs_stats_clearall(struct xfsstats __percpu *stats);
+extern struct xstats xfsstats;
 
-/*
- * We don't disable preempt, not too worried about poking the
- * wrong CPU's stat for now (also aggregated before reporting).
- */
-#define XFS_STATS_INC(v)       (per_cpu(xfsstats, current_cpu()).v++)
-#define XFS_STATS_DEC(v)       (per_cpu(xfsstats, current_cpu()).v--)
-#define XFS_STATS_ADD(v, inc)  (per_cpu(xfsstats, current_cpu()).v += (inc))
+#define XFS_STATS_INC(mp, v)                                   \
+do {                                                           \
+       per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v++;     \
+       per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->v++;  \
+} while (0)
+
+#define XFS_STATS_DEC(mp, v)                                   \
+do {                                                           \
+       per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v--;     \
+       per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->v--;  \
+} while (0)
+
+#define XFS_STATS_ADD(mp, v, inc)                                      \
+do {                                                                   \
+       per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v += (inc);      \
+       per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->v += (inc);   \
+} while (0)
+
+#if defined(CONFIG_PROC_FS)
 
 extern int xfs_init_procfs(void);
 extern void xfs_cleanup_procfs(void);
@@ -231,10 +243,6 @@ extern void xfs_cleanup_procfs(void);
 
 #else  /* !CONFIG_PROC_FS */
 
-# define XFS_STATS_INC(count)
-# define XFS_STATS_DEC(count)
-# define XFS_STATS_ADD(count, inc)
-
 static inline int xfs_init_procfs(void)
 {
        return 0;
index 904f637cfa5f3c2f40c0e7c4bb0ba6ffe3b65d1a..36bd8825bfb03cd2faafbecd202730869f8321d3 100644 (file)
@@ -838,17 +838,18 @@ xfs_init_mount_workqueues(
                goto out_destroy_unwritten;
 
        mp->m_reclaim_workqueue = alloc_workqueue("xfs-reclaim/%s",
-                       WQ_FREEZABLE, 0, mp->m_fsname);
+                       WQ_MEM_RECLAIM|WQ_FREEZABLE, 0, mp->m_fsname);
        if (!mp->m_reclaim_workqueue)
                goto out_destroy_cil;
 
        mp->m_log_workqueue = alloc_workqueue("xfs-log/%s",
-                       WQ_FREEZABLE|WQ_HIGHPRI, 0, mp->m_fsname);
+                       WQ_MEM_RECLAIM|WQ_FREEZABLE|WQ_HIGHPRI, 0,
+                       mp->m_fsname);
        if (!mp->m_log_workqueue)
                goto out_destroy_reclaim;
 
        mp->m_eofblocks_workqueue = alloc_workqueue("xfs-eofblocks/%s",
-                       WQ_FREEZABLE, 0, mp->m_fsname);
+                       WQ_MEM_RECLAIM|WQ_FREEZABLE, 0, mp->m_fsname);
        if (!mp->m_eofblocks_workqueue)
                goto out_destroy_log;
 
@@ -922,7 +923,7 @@ xfs_fs_destroy_inode(
 
        trace_xfs_destroy_inode(ip);
 
-       XFS_STATS_INC(vn_reclaim);
+       XFS_STATS_INC(ip->i_mount, vn_reclaim);
 
        ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0);
 
@@ -983,8 +984,8 @@ xfs_fs_evict_inode(
 
        truncate_inode_pages_final(&inode->i_data);
        clear_inode(inode);
-       XFS_STATS_INC(vn_rele);
-       XFS_STATS_INC(vn_remove);
+       XFS_STATS_INC(ip->i_mount, vn_rele);
+       XFS_STATS_INC(ip->i_mount, vn_remove);
 
        xfs_inactive(ip);
 }
@@ -1474,9 +1475,16 @@ xfs_fs_fill_super(
        if (error)
                goto out_destroy_workqueues;
 
+       /* Allocate stats memory before we do operations that might use it */
+       mp->m_stats.xs_stats = alloc_percpu(struct xfsstats);
+       if (!mp->m_stats.xs_stats) {
+               error = -ENOMEM;
+               goto out_destroy_counters;
+       }
+
        error = xfs_readsb(mp, flags);
        if (error)
-               goto out_destroy_counters;
+               goto out_free_stats;
 
        error = xfs_finish_flags(mp);
        if (error)
@@ -1545,9 +1553,11 @@ xfs_fs_fill_super(
        xfs_filestream_unmount(mp);
  out_free_sb:
        xfs_freesb(mp);
+ out_free_stats:
+       free_percpu(mp->m_stats.xs_stats);
  out_destroy_counters:
        xfs_destroy_percpu_counters(mp);
-out_destroy_workqueues:
+ out_destroy_workqueues:
        xfs_destroy_mount_workqueues(mp);
  out_close_devices:
        xfs_close_devices(mp);
@@ -1574,6 +1584,7 @@ xfs_fs_put_super(
        xfs_unmountfs(mp);
 
        xfs_freesb(mp);
+       free_percpu(mp->m_stats.xs_stats);
        xfs_destroy_percpu_counters(mp);
        xfs_destroy_mount_workqueues(mp);
        xfs_close_devices(mp);
@@ -1838,19 +1849,32 @@ init_xfs_fs(void)
        xfs_kset = kset_create_and_add("xfs", NULL, fs_kobj);
        if (!xfs_kset) {
                error = -ENOMEM;
-               goto out_sysctl_unregister;;
+               goto out_sysctl_unregister;
        }
 
+       xfsstats.xs_kobj.kobject.kset = xfs_kset;
+
+       xfsstats.xs_stats = alloc_percpu(struct xfsstats);
+       if (!xfsstats.xs_stats) {
+               error = -ENOMEM;
+               goto out_kset_unregister;
+       }
+
+       error = xfs_sysfs_init(&xfsstats.xs_kobj, &xfs_stats_ktype, NULL,
+                              "stats");
+       if (error)
+               goto out_free_stats;
+
 #ifdef DEBUG
        xfs_dbg_kobj.kobject.kset = xfs_kset;
        error = xfs_sysfs_init(&xfs_dbg_kobj, &xfs_dbg_ktype, NULL, "debug");
        if (error)
-               goto out_kset_unregister;
+               goto out_remove_stats_kobj;
 #endif
 
        error = xfs_qm_init();
        if (error)
-               goto out_remove_kobj;
+               goto out_remove_dbg_kobj;
 
        error = register_filesystem(&xfs_fs_type);
        if (error)
@@ -1859,11 +1883,15 @@ init_xfs_fs(void)
 
  out_qm_exit:
        xfs_qm_exit();
- out_remove_kobj:
+ out_remove_dbg_kobj:
 #ifdef DEBUG
        xfs_sysfs_del(&xfs_dbg_kobj);
- out_kset_unregister:
+ out_remove_stats_kobj:
 #endif
+       xfs_sysfs_del(&xfsstats.xs_kobj);
+ out_free_stats:
+       free_percpu(xfsstats.xs_stats);
+ out_kset_unregister:
        kset_unregister(xfs_kset);
  out_sysctl_unregister:
        xfs_sysctl_unregister();
@@ -1889,6 +1917,8 @@ exit_xfs_fs(void)
 #ifdef DEBUG
        xfs_sysfs_del(&xfs_dbg_kobj);
 #endif
+       xfs_sysfs_del(&xfsstats.xs_kobj);
+       free_percpu(xfsstats.xs_stats);
        kset_unregister(xfs_kset);
        xfs_sysctl_unregister();
        xfs_cleanup_procfs();
@@ -1896,6 +1926,7 @@ exit_xfs_fs(void)
        xfs_mru_cache_uninit();
        xfs_destroy_workqueues();
        xfs_destroy_zones();
+       xfs_uuid_table_free();
 }
 
 module_init(init_xfs_fs);
index a0c8067cea6f2c0055f7274a7d0dbd65f2d52887..aed74d3f8da93a9b80b7bafe8b76f004b481ca5a 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/sysctl.h>
 #include <linux/proc_fs.h>
 #include "xfs_error.h"
+#include "xfs_stats.h"
 
 static struct ctl_table_header *xfs_table_header;
 
@@ -31,22 +32,12 @@ xfs_stats_clear_proc_handler(
        size_t                  *lenp,
        loff_t                  *ppos)
 {
-       int             c, ret, *valp = ctl->data;
-       __uint32_t      vn_active;
+       int             ret, *valp = ctl->data;
 
        ret = proc_dointvec_minmax(ctl, write, buffer, lenp, ppos);
 
        if (!ret && write && *valp) {
-               xfs_notice(NULL, "Clearing xfsstats");
-               for_each_possible_cpu(c) {
-                       preempt_disable();
-                       /* save vn_active, it's a universal truth! */
-                       vn_active = per_cpu(xfsstats, c).vn_active;
-                       memset(&per_cpu(xfsstats, c), 0,
-                              sizeof(struct xfsstats));
-                       per_cpu(xfsstats, c).vn_active = vn_active;
-                       preempt_enable();
-               }
+               xfs_stats_clearall(xfsstats.xs_stats);
                xfs_stats_clear = 0;
        }
 
index aa03670851d86574cc542a2eccb1b5c4607e4ca5..ee70f5dec9dccf088eada0d354b06cb847577a2a 100644 (file)
 #include "xfs_log_format.h"
 #include "xfs_log.h"
 #include "xfs_log_priv.h"
+#include "xfs_stats.h"
 
 struct xfs_sysfs_attr {
        struct attribute attr;
-       ssize_t (*show)(char *buf, void *data);
-       ssize_t (*store)(const char *buf, size_t count, void *data);
+       ssize_t (*show)(struct kobject *kobject, char *buf);
+       ssize_t (*store)(struct kobject *kobject, const char *buf,
+                        size_t count);
 };
 
 static inline struct xfs_sysfs_attr *
@@ -38,6 +40,8 @@ to_attr(struct attribute *attr)
        static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_RW(name)
 #define XFS_SYSFS_ATTR_RO(name) \
        static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_RO(name)
+#define XFS_SYSFS_ATTR_WO(name) \
+       static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_WO(name)
 
 #define ATTR_LIST(name) &xfs_sysfs_attr_##name.attr
 
@@ -51,14 +55,42 @@ struct kobj_type xfs_mp_ktype = {
        .release = xfs_sysfs_release,
 };
 
+STATIC ssize_t
+xfs_sysfs_object_show(
+       struct kobject          *kobject,
+       struct attribute        *attr,
+       char                    *buf)
+{
+       struct xfs_sysfs_attr *xfs_attr = to_attr(attr);
+
+       return xfs_attr->show ? xfs_attr->show(kobject, buf) : 0;
+}
+
+STATIC ssize_t
+xfs_sysfs_object_store(
+       struct kobject          *kobject,
+       struct attribute        *attr,
+       const char              *buf,
+       size_t                  count)
+{
+       struct xfs_sysfs_attr *xfs_attr = to_attr(attr);
+
+       return xfs_attr->store ? xfs_attr->store(kobject, buf, count) : 0;
+}
+
+static const struct sysfs_ops xfs_sysfs_ops = {
+       .show = xfs_sysfs_object_show,
+       .store = xfs_sysfs_object_store,
+};
+
 #ifdef DEBUG
 /* debug */
 
 STATIC ssize_t
 log_recovery_delay_store(
+       struct kobject  *kobject,
        const char      *buf,
-       size_t          count,
-       void            *data)
+       size_t          count)
 {
        int             ret;
        int             val;
@@ -77,8 +109,8 @@ log_recovery_delay_store(
 
 STATIC ssize_t
 log_recovery_delay_show(
-       char    *buf,
-       void    *data)
+       struct kobject  *kobject,
+       char            *buf)
 {
        return snprintf(buf, PAGE_SIZE, "%d\n", xfs_globals.log_recovery_delay);
 }
@@ -89,52 +121,87 @@ static struct attribute *xfs_dbg_attrs[] = {
        NULL,
 };
 
+struct kobj_type xfs_dbg_ktype = {
+       .release = xfs_sysfs_release,
+       .sysfs_ops = &xfs_sysfs_ops,
+       .default_attrs = xfs_dbg_attrs,
+};
+
+#endif /* DEBUG */
+
+/* stats */
+
+static inline struct xstats *
+to_xstats(struct kobject *kobject)
+{
+       struct xfs_kobj *kobj = to_kobj(kobject);
+
+       return container_of(kobj, struct xstats, xs_kobj);
+}
+
 STATIC ssize_t
-xfs_dbg_show(
-       struct kobject          *kobject,
-       struct attribute        *attr,
-       char                    *buf)
+stats_show(
+       struct kobject  *kobject,
+       char            *buf)
 {
-       struct xfs_sysfs_attr *xfs_attr = to_attr(attr);
+       struct xstats   *stats = to_xstats(kobject);
 
-       return xfs_attr->show ? xfs_attr->show(buf, NULL) : 0;
+       return xfs_stats_format(stats->xs_stats, buf);
 }
+XFS_SYSFS_ATTR_RO(stats);
 
 STATIC ssize_t
-xfs_dbg_store(
-       struct kobject          *kobject,
-       struct attribute        *attr,
-       const char              *buf,
-       size_t                  count)
+stats_clear_store(
+       struct kobject  *kobject,
+       const char      *buf,
+       size_t          count)
 {
-       struct xfs_sysfs_attr *xfs_attr = to_attr(attr);
+       int             ret;
+       int             val;
+       struct xstats   *stats = to_xstats(kobject);
+
+       ret = kstrtoint(buf, 0, &val);
+       if (ret)
+               return ret;
 
-       return xfs_attr->store ? xfs_attr->store(buf, count, NULL) : 0;
+       if (val != 1)
+               return -EINVAL;
+
+       xfs_stats_clearall(stats->xs_stats);
+       return count;
 }
+XFS_SYSFS_ATTR_WO(stats_clear);
 
-static struct sysfs_ops xfs_dbg_ops = {
-       .show = xfs_dbg_show,
-       .store = xfs_dbg_store,
+static struct attribute *xfs_stats_attrs[] = {
+       ATTR_LIST(stats),
+       ATTR_LIST(stats_clear),
+       NULL,
 };
 
-struct kobj_type xfs_dbg_ktype = {
+struct kobj_type xfs_stats_ktype = {
        .release = xfs_sysfs_release,
-       .sysfs_ops = &xfs_dbg_ops,
-       .default_attrs = xfs_dbg_attrs,
+       .sysfs_ops = &xfs_sysfs_ops,
+       .default_attrs = xfs_stats_attrs,
 };
 
-#endif /* DEBUG */
-
 /* xlog */
 
+static inline struct xlog *
+to_xlog(struct kobject *kobject)
+{
+       struct xfs_kobj *kobj = to_kobj(kobject);
+
+       return container_of(kobj, struct xlog, l_kobj);
+}
+
 STATIC ssize_t
 log_head_lsn_show(
-       char    *buf,
-       void    *data)
+       struct kobject  *kobject,
+       char            *buf)
 {
-       struct xlog *log = data;
        int cycle;
        int block;
+       struct xlog *log = to_xlog(kobject);
 
        spin_lock(&log->l_icloglock);
        cycle = log->l_curr_cycle;
@@ -147,12 +214,12 @@ XFS_SYSFS_ATTR_RO(log_head_lsn);
 
 STATIC ssize_t
 log_tail_lsn_show(
-       char    *buf,
-       void    *data)
+       struct kobject  *kobject,
+       char            *buf)
 {
-       struct xlog *log = data;
        int cycle;
        int block;
+       struct xlog *log = to_xlog(kobject);
 
        xlog_crack_atomic_lsn(&log->l_tail_lsn, &cycle, &block);
        return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, block);
@@ -161,12 +228,13 @@ XFS_SYSFS_ATTR_RO(log_tail_lsn);
 
 STATIC ssize_t
 reserve_grant_head_show(
-       char    *buf,
-       void    *data)
+       struct kobject  *kobject,
+       char            *buf)
+
 {
-       struct xlog *log = data;
        int cycle;
        int bytes;
+       struct xlog *log = to_xlog(kobject);
 
        xlog_crack_grant_head(&log->l_reserve_head.grant, &cycle, &bytes);
        return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, bytes);
@@ -175,12 +243,12 @@ XFS_SYSFS_ATTR_RO(reserve_grant_head);
 
 STATIC ssize_t
 write_grant_head_show(
-       char    *buf,
-       void    *data)
+       struct kobject  *kobject,
+       char            *buf)
 {
-       struct xlog *log = data;
        int cycle;
        int bytes;
+       struct xlog *log = to_xlog(kobject);
 
        xlog_crack_grant_head(&log->l_write_head.grant, &cycle, &bytes);
        return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, bytes);
@@ -195,45 +263,8 @@ static struct attribute *xfs_log_attrs[] = {
        NULL,
 };
 
-static inline struct xlog *
-to_xlog(struct kobject *kobject)
-{
-       struct xfs_kobj *kobj = to_kobj(kobject);
-       return container_of(kobj, struct xlog, l_kobj);
-}
-
-STATIC ssize_t
-xfs_log_show(
-       struct kobject          *kobject,
-       struct attribute        *attr,
-       char                    *buf)
-{
-       struct xlog *log = to_xlog(kobject);
-       struct xfs_sysfs_attr *xfs_attr = to_attr(attr);
-
-       return xfs_attr->show ? xfs_attr->show(buf, log) : 0;
-}
-
-STATIC ssize_t
-xfs_log_store(
-       struct kobject          *kobject,
-       struct attribute        *attr,
-       const char              *buf,
-       size_t                  count)
-{
-       struct xlog *log = to_xlog(kobject);
-       struct xfs_sysfs_attr *xfs_attr = to_attr(attr);
-
-       return xfs_attr->store ? xfs_attr->store(buf, count, log) : 0;
-}
-
-static struct sysfs_ops xfs_log_ops = {
-       .show = xfs_log_show,
-       .store = xfs_log_store,
-};
-
 struct kobj_type xfs_log_ktype = {
        .release = xfs_sysfs_release,
-       .sysfs_ops = &xfs_log_ops,
+       .sysfs_ops = &xfs_sysfs_ops,
        .default_attrs = xfs_log_attrs,
 };
index 240eee35f342b8bbae4511f0ef04d38e32e3a0c4..be692e59938db7e8cba4ca4186b1a8f90928887c 100644 (file)
@@ -22,6 +22,7 @@
 extern struct kobj_type xfs_mp_ktype;  /* xfs_mount */
 extern struct kobj_type xfs_dbg_ktype; /* debug */
 extern struct kobj_type xfs_log_ktype; /* xlog */
+extern struct kobj_type xfs_stats_ktype;       /* stats */
 
 static inline struct xfs_kobj *
 to_kobj(struct kobject *kobject)
index 5ed36b1e04c1af6103122450e33aa8e1f2546c1b..877079eb0f8f0e5d286e4c797761df6bf2f55228 100644 (file)
@@ -689,6 +689,7 @@ DEFINE_INODE_EVENT(xfs_inode_free_eofblocks_invalid);
 DEFINE_INODE_EVENT(xfs_filemap_fault);
 DEFINE_INODE_EVENT(xfs_filemap_pmd_fault);
 DEFINE_INODE_EVENT(xfs_filemap_page_mkwrite);
+DEFINE_INODE_EVENT(xfs_filemap_pfn_mkwrite);
 
 DECLARE_EVENT_CLASS(xfs_iref_class,
        TP_PROTO(struct xfs_inode *ip, unsigned long caller_ip),
@@ -1312,6 +1313,7 @@ DEFINE_SIMPLE_IO_EVENT(xfs_delalloc_enospc);
 DEFINE_SIMPLE_IO_EVENT(xfs_unwritten_convert);
 DEFINE_SIMPLE_IO_EVENT(xfs_get_blocks_notfound);
 DEFINE_SIMPLE_IO_EVENT(xfs_setfilesize);
+DEFINE_SIMPLE_IO_EVENT(xfs_zero_eof);
 
 DECLARE_EVENT_CLASS(xfs_itrunc_class,
        TP_PROTO(struct xfs_inode *ip, xfs_fsize_t new_size),
index a0ab1dae9c312ec0b67fe83a1d2936e7d716b339..748b16aff45a1cf959603b24131a69e289d99a95 100644 (file)
@@ -930,9 +930,9 @@ __xfs_trans_commit(
         */
        if (sync) {
                error = _xfs_log_force_lsn(mp, commit_lsn, XFS_LOG_SYNC, NULL);
-               XFS_STATS_INC(xs_trans_sync);
+               XFS_STATS_INC(mp, xs_trans_sync);
        } else {
-               XFS_STATS_INC(xs_trans_async);
+               XFS_STATS_INC(mp, xs_trans_async);
        }
 
        return error;
@@ -955,7 +955,7 @@ out_unreserve:
        xfs_trans_free_items(tp, NULLCOMMITLSN, !!error);
        xfs_trans_free(tp);
 
-       XFS_STATS_INC(xs_trans_empty);
+       XFS_STATS_INC(mp, xs_trans_empty);
        return error;
 }
 
index 1098cf4901892830184c0a3f2306210be1930f9f..aa67339b953722b4e5c73442ac14835f0f9c4e32 100644 (file)
@@ -349,7 +349,7 @@ xfsaild_push(
             xfs_ail_min_lsn(ailp))) {
                ailp->xa_log_flush = 0;
 
-               XFS_STATS_INC(xs_push_ail_flush);
+               XFS_STATS_INC(mp, xs_push_ail_flush);
                xfs_log_force(mp, XFS_LOG_SYNC);
        }
 
@@ -371,7 +371,7 @@ xfsaild_push(
                goto out_done;
        }
 
-       XFS_STATS_INC(xs_push_ail);
+       XFS_STATS_INC(mp, xs_push_ail);
 
        lsn = lip->li_lsn;
        while ((XFS_LSN_CMP(lip->li_lsn, target) <= 0)) {
@@ -385,7 +385,7 @@ xfsaild_push(
                lock_result = lip->li_ops->iop_push(lip, &ailp->xa_buf_list);
                switch (lock_result) {
                case XFS_ITEM_SUCCESS:
-                       XFS_STATS_INC(xs_push_ail_success);
+                       XFS_STATS_INC(mp, xs_push_ail_success);
                        trace_xfs_ail_push(lip);
 
                        ailp->xa_last_pushed_lsn = lsn;
@@ -403,7 +403,7 @@ xfsaild_push(
                         * re-try the flushing relatively soon if most of the
                         * AIL is beeing flushed.
                         */
-                       XFS_STATS_INC(xs_push_ail_flushing);
+                       XFS_STATS_INC(mp, xs_push_ail_flushing);
                        trace_xfs_ail_flushing(lip);
 
                        flushing++;
@@ -411,14 +411,14 @@ xfsaild_push(
                        break;
 
                case XFS_ITEM_PINNED:
-                       XFS_STATS_INC(xs_push_ail_pinned);
+                       XFS_STATS_INC(mp, xs_push_ail_pinned);
                        trace_xfs_ail_pinned(lip);
 
                        stuck++;
                        ailp->xa_log_flush++;
                        break;
                case XFS_ITEM_LOCKED:
-                       XFS_STATS_INC(xs_push_ail_locked);
+                       XFS_STATS_INC(mp, xs_push_ail_locked);
                        trace_xfs_ail_locked(lip);
 
                        stuck++;
@@ -497,6 +497,7 @@ xfsaild(
        long            tout = 0;       /* milliseconds */
 
        current->flags |= PF_MEMALLOC;
+       set_freezable();
 
        while (!kthread_should_stop()) {
                if (tout && tout <= 20)
index 17280cd71934b3eff4ea11f44639d763042238a2..b97f1df910abb0bd60ac5850fbe549237806d078 100644 (file)
@@ -107,6 +107,15 @@ xfs_trans_log_inode(
        ASSERT(ip->i_itemp != NULL);
        ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
 
+       /*
+        * Record the specific change for fdatasync optimisation. This
+        * allows fdatasync to skip log forces for inodes that are only
+        * timestamp dirty. We do this before the change count so that
+        * the core being logged in this case does not impact on fdatasync
+        * behaviour.
+        */
+       ip->i_itemp->ili_fsync_fields |= flags;
+
        /*
         * First time we log the inode in a transaction, bump the inode change
         * counter if it is configured for this to occur. We don't use
index c036815183cb69bd82c58a0300c243e7e7ca7f32..839b35ca21c69320c736ac636ef681b1362402ce 100644 (file)
 
 
 static int
-xfs_xattr_get(struct dentry *dentry, const char *name,
-               void *value, size_t size, int xflags)
+xfs_xattr_get(const struct xattr_handler *handler, struct dentry *dentry,
+               const char *name, void *value, size_t size)
 {
+       int xflags = handler->flags;
        struct xfs_inode *ip = XFS_I(d_inode(dentry));
        int error, asize = size;
 
@@ -53,11 +54,35 @@ xfs_xattr_get(struct dentry *dentry, const char *name,
        return asize;
 }
 
+void
+xfs_forget_acl(
+       struct inode            *inode,
+       const char              *name,
+       int                     xflags)
+{
+       /*
+        * Invalidate any cached ACLs if the user has bypassed the ACL
+        * interface. We don't validate the content whatsoever so it is caller
+        * responsibility to provide data in valid format and ensure i_mode is
+        * consistent.
+        */
+       if (xflags & ATTR_ROOT) {
+#ifdef CONFIG_XFS_POSIX_ACL
+               if (!strcmp(name, SGI_ACL_FILE))
+                       forget_cached_acl(inode, ACL_TYPE_ACCESS);
+               else if (!strcmp(name, SGI_ACL_DEFAULT))
+                       forget_cached_acl(inode, ACL_TYPE_DEFAULT);
+#endif
+       }
+}
+
 static int
-xfs_xattr_set(struct dentry *dentry, const char *name, const void *value,
-               size_t size, int flags, int xflags)
+xfs_xattr_set(const struct xattr_handler *handler, struct dentry *dentry,
+               const char *name, const void *value, size_t size, int flags)
 {
-       struct xfs_inode *ip = XFS_I(d_inode(dentry));
+       int                     xflags = handler->flags;
+       struct xfs_inode        *ip = XFS_I(d_inode(dentry));
+       int                     error;
 
        if (strcmp(name, "") == 0)
                return -EINVAL;
@@ -70,8 +95,12 @@ xfs_xattr_set(struct dentry *dentry, const char *name, const void *value,
 
        if (!value)
                return xfs_attr_remove(ip, (unsigned char *)name, xflags);
-       return xfs_attr_set(ip, (unsigned char *)name,
+       error = xfs_attr_set(ip, (unsigned char *)name,
                                (void *)value, size, xflags);
+       if (!error)
+               xfs_forget_acl(d_inode(dentry), name, xflags);
+
+       return error;
 }
 
 static const struct xattr_handler xfs_xattr_user_handler = {
index d11eff8a4efe95f92d8e75a18498017709ca096f..ad0a5ff3d4cd724128b36074d428f475155df1b4 100644 (file)
@@ -390,39 +390,6 @@ struct acpi_data_node {
        struct completion kobj_done;
 };
 
-static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent)
-{
-       bool ret = false;
-
-       if (!adev)
-               return ret;
-
-       /**
-        * Currently, we only support _CCA=1 (i.e. coherent_dma=1)
-        * This should be equivalent to specifyig dma-coherent for
-        * a device in OF.
-        *
-        * For the case when _CCA=0 (i.e. coherent_dma=0 && cca_seen=1),
-        * There are two cases:
-        * case 1. Do not support and disable DMA.
-        * case 2. Support but rely on arch-specific cache maintenance for
-        *         non-coherence DMA operations.
-        * Currently, we implement case 1 above.
-        *
-        * For the case when _CCA is missing (i.e. cca_seen=0) and
-        * platform specifies ACPI_CCA_REQUIRED, we do not support DMA,
-        * and fallback to arch-specific default handling.
-        *
-        * See acpi_init_coherency() for more info.
-        */
-       if (adev->flags.coherent_dma) {
-               ret = true;
-               if (coherent)
-                       *coherent = adev->flags.coherent_dma;
-       }
-       return ret;
-}
-
 static inline bool is_acpi_node(struct fwnode_handle *fwnode)
 {
        return fwnode && (fwnode->type == FWNODE_ACPI
@@ -595,6 +562,9 @@ struct acpi_pci_root {
 
 /* helper */
 
+bool acpi_dma_supported(struct acpi_device *adev);
+enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
+
 struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
                                           u64 address, bool check_children);
 int acpi_is_root_bridge(acpi_handle);
index 72d8803832ff64ef5e53b666abdcb7ea21d44a61..1bfa602958f2a2f7beb16fab8f98263d198c652b 100644 (file)
@@ -163,9 +163,10 @@ static inline __must_check long __copy_to_user(void __user *to,
 
 #define put_user(x, ptr)                                       \
 ({                                                             \
+       void *__p = (ptr);                                      \
        might_fault();                                          \
-       access_ok(VERIFY_WRITE, ptr, sizeof(*ptr)) ?            \
-               __put_user(x, ptr) :                            \
+       access_ok(VERIFY_WRITE, __p, sizeof(*ptr)) ?            \
+               __put_user((x), ((__typeof__(*(ptr)) *)__p)) :  \
                -EFAULT;                                        \
 })
 
@@ -225,9 +226,10 @@ extern int __put_user_bad(void) __attribute__((noreturn));
 
 #define get_user(x, ptr)                                       \
 ({                                                             \
+       const void *__p = (ptr);                                \
        might_fault();                                          \
-       access_ok(VERIFY_READ, ptr, sizeof(*ptr)) ?             \
-               __get_user(x, ptr) :                            \
+       access_ok(VERIFY_READ, __p, sizeof(*ptr)) ?             \
+               __get_user((x), (__typeof__(*(ptr)) *)__p) :    \
                -EFAULT;                                        \
 })
 
index ebfac2fe0c813bea9d98d01e8dc4f244e1bd97d4..05483393999534d91425b01c4573a5a4aa494fbc 100644 (file)
@@ -601,11 +601,16 @@ static inline int acpi_device_modalias(struct device *dev,
        return -ENODEV;
 }
 
-static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent)
+static inline bool acpi_dma_supported(struct acpi_device *adev)
 {
        return false;
 }
 
+static inline enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
+{
+       return DEV_DMA_NOT_SUPPORTED;
+}
+
 #define ACPI_PTR(_ptr) (NULL)
 
 #endif /* !CONFIG_ACPI */
index 641e5a3ed58c4d2e1d8fb5c64c216eb3b5b821a5..0fb65843ec1e8522461dfe2d308c06e6fe33e2af 100644 (file)
@@ -265,7 +265,7 @@ static inline unsigned int blk_qc_t_to_queue_num(blk_qc_t cookie)
 
 static inline unsigned int blk_qc_t_to_tag(blk_qc_t cookie)
 {
-       return cookie & 0xffff;
+       return cookie & ((1u << BLK_QC_T_SHIFT) - 1);
 }
 
 #endif /* __LINUX_BLK_TYPES_H */
index e6797ded700ec8f7ef6a8fccccddf71212715077..89d9aa9e79bf438905dd3bb7d48a4f3b1bb808b7 100644 (file)
@@ -227,8 +227,6 @@ int cont_write_begin(struct file *, struct address_space *, loff_t,
                        get_block_t *, loff_t *);
 int generic_cont_expand_simple(struct inode *inode, loff_t size);
 int block_commit_write(struct page *page, unsigned from, unsigned to);
-int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
-                               get_block_t get_block);
 int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
                                get_block_t get_block);
 /* Convert errno to return value from ->page_mkwrite() call */
index 397c5cd09794854ebc8891fac59b4dfa50e7e141..3e3799cdc6e66d719fed8ae9adc8539d4e2cb0c6 100644 (file)
@@ -29,8 +29,9 @@
 #define CEPH_OPT_NOSHARE          (1<<1) /* don't share client with other sbs */
 #define CEPH_OPT_MYIP             (1<<2) /* specified my ip */
 #define CEPH_OPT_NOCRC            (1<<3) /* no data crc on writes */
-#define CEPH_OPT_NOMSGAUTH       (1<<4) /* not require cephx message signature */
+#define CEPH_OPT_NOMSGAUTH       (1<<4) /* don't require msg signing feat */
 #define CEPH_OPT_TCP_NODELAY     (1<<5) /* TCP_NODELAY on TCP sockets */
+#define CEPH_OPT_NOMSGSIGN       (1<<6) /* don't sign msgs */
 
 #define CEPH_OPT_DEFAULT   (CEPH_OPT_TCP_NODELAY)
 
@@ -137,6 +138,7 @@ struct ceph_client {
 #endif
 };
 
+#define from_msgr(ms)  container_of(ms, struct ceph_client, msgr)
 
 
 /*
index b2371d9b51fac6ea69032576ac1c3cddfc104016..71b1d6cdcb5d1fc53dd45fa3950e138cfac19dfe 100644 (file)
@@ -43,10 +43,9 @@ struct ceph_connection_operations {
        struct ceph_msg * (*alloc_msg) (struct ceph_connection *con,
                                        struct ceph_msg_header *hdr,
                                        int *skip);
-       int (*sign_message) (struct ceph_connection *con, struct ceph_msg *msg);
 
-       int (*check_message_signature) (struct ceph_connection *con,
-                                       struct ceph_msg *msg);
+       int (*sign_message) (struct ceph_msg *msg);
+       int (*check_message_signature) (struct ceph_msg *msg);
 };
 
 /* use format string %s%d */
@@ -58,8 +57,6 @@ struct ceph_messenger {
 
        atomic_t stopping;
        possible_net_t net;
-       bool nocrc;
-       bool tcp_nodelay;
 
        /*
         * the global_seq counts connections i (attempt to) initiate
@@ -67,9 +64,6 @@ struct ceph_messenger {
         */
        u32 global_seq;
        spinlock_t global_seq_lock;
-
-       u64 supported_features;
-       u64 required_features;
 };
 
 enum ceph_msg_data_type {
@@ -268,11 +262,7 @@ extern void ceph_msgr_exit(void);
 extern void ceph_msgr_flush(void);
 
 extern void ceph_messenger_init(struct ceph_messenger *msgr,
-                       struct ceph_entity_addr *myaddr,
-                       u64 supported_features,
-                       u64 required_features,
-                       bool nocrc,
-                       bool tcp_nodelay);
+                               struct ceph_entity_addr *myaddr);
 extern void ceph_messenger_fini(struct ceph_messenger *msgr);
 
 extern void ceph_con_init(struct ceph_connection *con, void *private,
index 63a36e89d0eb6b3f718d7058b723291662c186d3..a8a335b7fce083984c0b05df49e3ff74f7732719 100644 (file)
@@ -125,86 +125,33 @@ struct configfs_attribute {
        const char              *ca_name;
        struct module           *ca_owner;
        umode_t                 ca_mode;
+       ssize_t (*show)(struct config_item *, char *);
+       ssize_t (*store)(struct config_item *, const char *, size_t);
 };
 
-/*
- * Users often need to create attribute structures for their configurable
- * attributes, containing a configfs_attribute member and function pointers
- * for the show() and store() operations on that attribute. If they don't
- * need anything else on the extended attribute structure, they can use
- * this macro to define it  The argument _item is the name of the
- * config_item structure.
- */
-#define CONFIGFS_ATTR_STRUCT(_item)                                    \
-struct _item##_attribute {                                             \
-       struct configfs_attribute attr;                                 \
-       ssize_t (*show)(struct _item *, char *);                        \
-       ssize_t (*store)(struct _item *, const char *, size_t);         \
+#define CONFIGFS_ATTR(_pfx, _name)                     \
+static struct configfs_attribute _pfx##attr_##_name = {        \
+       .ca_name        = __stringify(_name),           \
+       .ca_mode        = S_IRUGO | S_IWUSR,            \
+       .ca_owner       = THIS_MODULE,                  \
+       .show           = _pfx##_name##_show,           \
+       .store          = _pfx##_name##_store,          \
 }
 
-/*
- * With the extended attribute structure, users can use this macro
- * (similar to sysfs' __ATTR) to make defining attributes easier.
- * An example:
- * #define MYITEM_ATTR(_name, _mode, _show, _store)    \
- * struct myitem_attribute childless_attr_##_name =    \
- *         __CONFIGFS_ATTR(_name, _mode, _show, _store)
- */
-#define __CONFIGFS_ATTR(_name, _mode, _show, _store)                   \
-{                                                                      \
-       .attr   = {                                                     \
-                       .ca_name = __stringify(_name),                  \
-                       .ca_mode = _mode,                               \
-                       .ca_owner = THIS_MODULE,                        \
-       },                                                              \
-       .show   = _show,                                                \
-       .store  = _store,                                               \
-}
-/* Here is a readonly version, only requiring a show() operation */
-#define __CONFIGFS_ATTR_RO(_name, _show)                               \
-{                                                                      \
-       .attr   = {                                                     \
-                       .ca_name = __stringify(_name),                  \
-                       .ca_mode = 0444,                                \
-                       .ca_owner = THIS_MODULE,                        \
-       },                                                              \
-       .show   = _show,                                                \
+#define CONFIGFS_ATTR_RO(_pfx, _name)                  \
+static struct configfs_attribute _pfx##attr_##_name = {        \
+       .ca_name        = __stringify(_name),           \
+       .ca_mode        = S_IRUGO,                      \
+       .ca_owner       = THIS_MODULE,                  \
+       .show           = _pfx##_name##_show,           \
 }
 
-/*
- * With these extended attributes, the simple show_attribute() and
- * store_attribute() operations need to call the show() and store() of the
- * attributes.  This is a common pattern, so we provide a macro to define
- * them.  The argument _item is the name of the config_item structure.
- * This macro expects the attributes to be named "struct <name>_attribute"
- * and the function to_<name>() to exist;
- */
-#define CONFIGFS_ATTR_OPS(_item)                                       \
-static ssize_t _item##_attr_show(struct config_item *item,             \
-                                struct configfs_attribute *attr,       \
-                                char *page)                            \
-{                                                                      \
-       struct _item *_item = to_##_item(item);                         \
-       struct _item##_attribute *_item##_attr =                        \
-               container_of(attr, struct _item##_attribute, attr);     \
-       ssize_t ret = 0;                                                \
-                                                                       \
-       if (_item##_attr->show)                                         \
-               ret = _item##_attr->show(_item, page);                  \
-       return ret;                                                     \
-}                                                                      \
-static ssize_t _item##_attr_store(struct config_item *item,            \
-                                 struct configfs_attribute *attr,      \
-                                 const char *page, size_t count)       \
-{                                                                      \
-       struct _item *_item = to_##_item(item);                         \
-       struct _item##_attribute *_item##_attr =                        \
-               container_of(attr, struct _item##_attribute, attr);     \
-       ssize_t ret = -EINVAL;                                          \
-                                                                       \
-       if (_item##_attr->store)                                        \
-               ret = _item##_attr->store(_item, page, count);          \
-       return ret;                                                     \
+#define CONFIGFS_ATTR_WO(_pfx, _name)                  \
+static struct configfs_attribute _pfx##attr_##_name = {        \
+       .ca_name        = __stringify(_name),           \
+       .ca_mode        = S_IWUSR,                      \
+       .ca_owner       = THIS_MODULE,                  \
+       .store          = _pfx##_name##_store,          \
 }
 
 /*
@@ -223,8 +170,6 @@ static ssize_t _item##_attr_store(struct config_item *item,         \
  */
 struct configfs_item_operations {
        void (*release)(struct config_item *);
-       ssize_t (*show_attribute)(struct config_item *, struct configfs_attribute *,char *);
-       ssize_t (*store_attribute)(struct config_item *,struct configfs_attribute *,const char *, size_t);
        int (*allow_link)(struct config_item *src, struct config_item *target);
        int (*drop_link)(struct config_item *src, struct config_item *target);
 };
index 008fc67d0d963ea811feb5cdfcdf1c750f407864..68b575afe5f5909f78b88f88c4dcbd086ef19720 100644 (file)
 #ifdef CONFIG_CONTEXT_TRACKING
 extern void context_tracking_cpu_set(int cpu);
 
+/* Called with interrupts disabled.  */
+extern void __context_tracking_enter(enum ctx_state state);
+extern void __context_tracking_exit(enum ctx_state state);
+
 extern void context_tracking_enter(enum ctx_state state);
 extern void context_tracking_exit(enum ctx_state state);
 extern void context_tracking_user_enter(void);
@@ -18,13 +22,13 @@ extern void context_tracking_user_exit(void);
 static inline void user_enter(void)
 {
        if (context_tracking_is_enabled())
-               context_tracking_user_enter();
+               context_tracking_enter(CONTEXT_USER);
 
 }
 static inline void user_exit(void)
 {
        if (context_tracking_is_enabled())
-               context_tracking_user_exit();
+               context_tracking_exit(CONTEXT_USER);
 }
 
 static inline enum ctx_state exception_enter(void)
@@ -88,13 +92,13 @@ static inline void guest_enter(void)
                current->flags |= PF_VCPU;
 
        if (context_tracking_is_enabled())
-               context_tracking_enter(CONTEXT_GUEST);
+               __context_tracking_enter(CONTEXT_GUEST);
 }
 
 static inline void guest_exit(void)
 {
        if (context_tracking_is_enabled())
-               context_tracking_exit(CONTEXT_GUEST);
+               __context_tracking_exit(CONTEXT_GUEST);
 
        if (vtime_accounting_enabled())
                vtime_guest_exit(current);
diff --git a/include/linux/devfreq_cooling.h b/include/linux/devfreq_cooling.h
new file mode 100644 (file)
index 0000000..7adf6cc
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * devfreq_cooling: Thermal cooling device implementation for devices using
+ *                  devfreq
+ *
+ * Copyright (C) 2014-2015 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __DEVFREQ_COOLING_H__
+#define __DEVFREQ_COOLING_H__
+
+#include <linux/devfreq.h>
+#include <linux/thermal.h>
+
+#ifdef CONFIG_DEVFREQ_THERMAL
+
+/**
+ * struct devfreq_cooling_power - Devfreq cooling power ops
+ * @get_static_power:  Take voltage, in mV, and return the static power
+ *                     in mW.  If NULL, the static power is assumed
+ *                     to be 0.
+ * @get_dynamic_power: Take voltage, in mV, and frequency, in HZ, and
+ *                     return the dynamic power draw in mW.  If NULL,
+ *                     a simple power model is used.
+ * @dyn_power_coeff:   Coefficient for the simple dynamic power model in
+ *                     mW/(MHz mV mV).
+ *                     If get_dynamic_power() is NULL, then the
+ *                     dynamic power is calculated as
+ *                     @dyn_power_coeff * frequency * voltage^2
+ */
+struct devfreq_cooling_power {
+       unsigned long (*get_static_power)(unsigned long voltage);
+       unsigned long (*get_dynamic_power)(unsigned long freq,
+                                          unsigned long voltage);
+       unsigned long dyn_power_coeff;
+};
+
+struct thermal_cooling_device *
+of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df,
+                                 struct devfreq_cooling_power *dfc_power);
+struct thermal_cooling_device *
+of_devfreq_cooling_register(struct device_node *np, struct devfreq *df);
+struct thermal_cooling_device *devfreq_cooling_register(struct devfreq *df);
+void devfreq_cooling_unregister(struct thermal_cooling_device *dfc);
+
+#else /* !CONFIG_DEVFREQ_THERMAL */
+
+struct thermal_cooling_device *
+of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df,
+                                 struct devfreq_cooling_power *dfc_power)
+{
+       return ERR_PTR(-EINVAL);
+}
+
+static inline struct thermal_cooling_device *
+of_devfreq_cooling_register(struct device_node *np, struct devfreq *df)
+{
+       return ERR_PTR(-EINVAL);
+}
+
+static inline struct thermal_cooling_device *
+devfreq_cooling_register(struct devfreq *df)
+{
+       return ERR_PTR(-EINVAL);
+}
+
+static inline void
+devfreq_cooling_unregister(struct thermal_cooling_device *dfc)
+{
+}
+
+#endif /* CONFIG_DEVFREQ_THERMAL */
+#endif /* __DEVFREQ_COOLING_H__ */
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 6230eb2a9ccadc1657a25b88e48f09e9560e067f..3aa51425416148f5bec14b6faf4e6f4e81370a22 100644 (file)
@@ -1665,8 +1665,6 @@ struct inode_operations {
                           umode_t create_mode, int *opened);
        int (*tmpfile) (struct inode *, struct dentry *, umode_t);
        int (*set_acl)(struct inode *, struct posix_acl *, int);
-
-       /* WARNING: probably going away soon, do not use! */
 } ____cacheline_aligned;
 
 ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
index 4e6861605050489e4ca3df78d94520993805c0ce..ce824db48d64c7fd29fc41babb0df6923da0774f 100644 (file)
@@ -9,6 +9,7 @@
 #define __LINUX_IRQCHIP_MIPS_GIC_H
 
 #include <linux/clocksource.h>
+#include <linux/ioport.h>
 
 #define GIC_MAX_INTRS                  256
 
 #define GIC_SHARED_TO_HWIRQ(x) (GIC_SHARED_HWIRQ_BASE + (x))
 #define GIC_HWIRQ_TO_SHARED(x) ((x) - GIC_SHARED_HWIRQ_BASE)
 
+#ifdef CONFIG_MIPS_GIC
+
 extern unsigned int gic_present;
 
 extern void gic_init(unsigned long gic_base_addr,
@@ -264,4 +267,18 @@ extern unsigned int plat_ipi_resched_int_xlate(unsigned int);
 extern int gic_get_c0_compare_int(void);
 extern int gic_get_c0_perfcount_int(void);
 extern int gic_get_c0_fdc_int(void);
+extern int gic_get_usm_range(struct resource *gic_usm_res);
+
+#else /* CONFIG_MIPS_GIC */
+
+#define gic_present    0
+
+static inline int gic_get_usm_range(struct resource *gic_usm_res)
+{
+       /* Shouldn't be called. */
+       return -1;
+}
+
+#endif /* CONFIG_MIPS_GIC */
+
 #endif /* __LINUX_IRQCHIP_MIPS_GIC_H */
index 242a6d2b53ff2713b21496072289bbb576754fb6..5706a2108f0a67826ed644dce761edd21a6a05c0 100644 (file)
@@ -1183,4 +1183,5 @@ void kvm_arch_irq_bypass_start(struct irq_bypass_consumer *);
 int kvm_arch_update_irqfd_routing(struct kvm *kvm, unsigned int host_irq,
                                  uint32_t guest_irq, bool set);
 #endif /* CONFIG_HAVE_KVM_IRQ_BYPASS */
+
 #endif
index ff82a32871b566401eb0a177a4b0bf45450b8f4d..c15373894a42a01a8c135a9b55619e3dbf5673a0 100644 (file)
@@ -68,6 +68,7 @@ struct nlm_host {
        struct nsm_handle       *h_nsmhandle;   /* NSM status handle */
        char                    *h_addrbuf;     /* address eyecatcher */
        struct net              *net;           /* host net */
+       char                    nodename[UNX_MAXNODENAME + 1];
 };
 
 /*
@@ -235,7 +236,8 @@ void                  nlm_rebind_host(struct nlm_host *);
 struct nlm_host * nlm_get_host(struct nlm_host *);
 void             nlm_shutdown_hosts(void);
 void             nlm_shutdown_hosts_net(struct net *net);
-void             nlm_host_rebooted(const struct nlm_reboot *);
+void             nlm_host_rebooted(const struct net *net,
+                                       const struct nlm_reboot *);
 
 /*
  * Host monitoring
@@ -243,11 +245,13 @@ void                nlm_host_rebooted(const struct nlm_reboot *);
 int              nsm_monitor(const struct nlm_host *host);
 void             nsm_unmonitor(const struct nlm_host *host);
 
-struct nsm_handle *nsm_get_handle(const struct sockaddr *sap,
+struct nsm_handle *nsm_get_handle(const struct net *net,
+                                       const struct sockaddr *sap,
                                        const size_t salen,
                                        const char *hostname,
                                        const size_t hostname_len);
-struct nsm_handle *nsm_reboot_lookup(const struct nlm_reboot *info);
+struct nsm_handle *nsm_reboot_lookup(const struct net *net,
+                                       const struct nlm_reboot *info);
 void             nsm_release(struct nsm_handle *nsm);
 
 /*
index e6982ac3200d65a537f2561bd51c2a0696b62e70..a57f0dfb6db7f2c0e0e268397b261fe8b45efa89 100644 (file)
@@ -16,6 +16,7 @@
 #define MARVELL_PHY_ID_88E1318S                0x01410e90
 #define MARVELL_PHY_ID_88E1116R                0x01410e40
 #define MARVELL_PHY_ID_88E1510         0x01410dd0
+#define MARVELL_PHY_ID_88E1540         0x01410eb0
 #define MARVELL_PHY_ID_88E3016         0x01410e60
 
 /* struct phy_device dev_flags definitions */
index c45c089bfdaca9a91f32832102ff32291444884f..6e8b5b270ffeada870b3cdcd638530f2479b84ee 100644 (file)
@@ -142,6 +142,13 @@ static inline u64 mul_u64_u32_shr(u64 a, u32 mul, unsigned int shift)
 }
 #endif /* mul_u64_u32_shr */
 
+#ifndef mul_u64_u64_shr
+static inline u64 mul_u64_u64_shr(u64 a, u64 mul, unsigned int shift)
+{
+       return (u64)(((unsigned __int128)a * mul) >> shift);
+}
+#endif /* mul_u64_u64_shr */
+
 #else
 
 #ifndef mul_u64_u32_shr
@@ -161,6 +168,79 @@ static inline u64 mul_u64_u32_shr(u64 a, u32 mul, unsigned int shift)
 }
 #endif /* mul_u64_u32_shr */
 
+#ifndef mul_u64_u64_shr
+static inline u64 mul_u64_u64_shr(u64 a, u64 b, unsigned int shift)
+{
+       union {
+               u64 ll;
+               struct {
+#ifdef __BIG_ENDIAN
+                       u32 high, low;
+#else
+                       u32 low, high;
+#endif
+               } l;
+       } rl, rm, rn, rh, a0, b0;
+       u64 c;
+
+       a0.ll = a;
+       b0.ll = b;
+
+       rl.ll = (u64)a0.l.low * b0.l.low;
+       rm.ll = (u64)a0.l.low * b0.l.high;
+       rn.ll = (u64)a0.l.high * b0.l.low;
+       rh.ll = (u64)a0.l.high * b0.l.high;
+
+       /*
+        * Each of these lines computes a 64-bit intermediate result into "c",
+        * starting at bits 32-95.  The low 32-bits go into the result of the
+        * multiplication, the high 32-bits are carried into the next step.
+        */
+       rl.l.high = c = (u64)rl.l.high + rm.l.low + rn.l.low;
+       rh.l.low = c = (c >> 32) + rm.l.high + rn.l.high + rh.l.low;
+       rh.l.high = (c >> 32) + rh.l.high;
+
+       /*
+        * The 128-bit result of the multiplication is in rl.ll and rh.ll,
+        * shift it right and throw away the high part of the result.
+        */
+       if (shift == 0)
+               return rl.ll;
+       if (shift < 64)
+               return (rl.ll >> shift) | (rh.ll << (64 - shift));
+       return rh.ll >> (shift & 63);
+}
+#endif /* mul_u64_u64_shr */
+
 #endif
 
+#ifndef mul_u64_u32_div
+static inline u64 mul_u64_u32_div(u64 a, u32 mul, u32 divisor)
+{
+       union {
+               u64 ll;
+               struct {
+#ifdef __BIG_ENDIAN
+                       u32 high, low;
+#else
+                       u32 low, high;
+#endif
+               } l;
+       } u, rl, rh;
+
+       u.ll = a;
+       rl.ll = (u64)u.l.low * mul;
+       rh.ll = (u64)u.l.high * mul + rl.l.high;
+
+       /* Bits 32-63 of the result will be in rh.l.low. */
+       rl.l.high = do_div(rh.ll, divisor);
+
+       /* Bits 0-31 of the result will be in rl.l.low. */
+       do_div(rl.ll, divisor);
+
+       rl.l.high = rh.l.low;
+       return rl.ll;
+}
+#endif /* mul_u64_u32_div */
+
 #endif /* _LINUX_MATH64_H */
index da72671a42fa6ed14d81a875c0fb8e6a2e66284f..494682ce4bf38b2c308dae7ad4e0bf1cab600495 100644 (file)
@@ -255,5 +255,6 @@ int cros_ec_query_all(struct cros_ec_device *ec_dev);
 /* sysfs stuff */
 extern struct attribute_group cros_ec_attr_group;
 extern struct attribute_group cros_ec_lightbar_attr_group;
+extern struct attribute_group cros_ec_vbc_attr_group;
 
 #endif /* __LINUX_MFD_CROS_EC_H */
index cc221b9676874fb2f138229a05c33f80a0791985..67bfac1abfc1ac8bd95bf3ddcf35aac07145166b 100644 (file)
@@ -3857,6 +3857,11 @@ static inline bool netif_is_bridge_master(const struct net_device *dev)
        return dev->priv_flags & IFF_EBRIDGE;
 }
 
+static inline bool netif_is_bridge_port(const struct net_device *dev)
+{
+       return dev->priv_flags & IFF_BRIDGE_PORT;
+}
+
 static inline bool netif_is_ovs_master(const struct net_device *dev)
 {
        return dev->priv_flags & IFF_OPENVSWITCH;
index 2194b8ca41f92fe4edb7bb32ecd4bc4507f1ddf0..dd10626a615fb160587ecf09f860de36ba583c19 100644 (file)
@@ -126,6 +126,8 @@ extern raw_spinlock_t devtree_lock;
 #define OF_POPULATED   3 /* device already created for the node */
 #define OF_POPULATED_BUS       4 /* of_platform_populate recursed to children of this node */
 
+#define OF_BAD_ADDR    ((u64)-1)
+
 #ifdef CONFIG_OF
 void of_core_init(void);
 
@@ -229,8 +231,6 @@ static inline unsigned long of_read_ulong(const __be32 *cell, int size)
 #define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags)
 #define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags)
 
-#define OF_BAD_ADDR    ((u64)-1)
-
 static inline const char *of_node_full_name(const struct device_node *np)
 {
        return np ? np->full_name : "<no-node>";
index d88e81be6368d2e2a07e34a8c0d28bbf9366a878..507daad0bc8d5d7e49dde6f5ef8ca353f56e02f0 100644 (file)
@@ -57,6 +57,13 @@ extern int of_dma_get_range(struct device_node *np, u64 *dma_addr,
                                u64 *paddr, u64 *size);
 extern bool of_dma_is_coherent(struct device_node *np);
 #else /* CONFIG_OF_ADDRESS */
+
+static inline u64 of_translate_address(struct device_node *np,
+                                      const __be32 *addr)
+{
+       return OF_BAD_ADDR;
+}
+
 static inline struct device_node *of_find_matching_node_by_address(
                                        struct device_node *from,
                                        const struct of_device_id *matches,
index 38c0533a33598bc8891af481589687c282739b37..2c51ee78b1c0e31074ee17eb9a341021ee3162e0 100644 (file)
@@ -16,7 +16,6 @@ int of_pci_get_devfn(struct device_node *np);
 int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin);
 int of_pci_parse_bus_range(struct device_node *node, struct resource *res);
 int of_get_pci_domain_nr(struct device_node *node);
-void of_pci_dma_configure(struct pci_dev *pci_dev);
 void of_pci_check_probe_only(void);
 #else
 static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq)
@@ -53,8 +52,6 @@ of_get_pci_domain_nr(struct device_node *node)
        return -1;
 }
 
-static inline void of_pci_dma_configure(struct pci_dev *pci_dev) { }
-
 static inline void of_pci_check_probe_only(void) { }
 #endif
 
index 463de52fe8915486d2e2159bde7edf12834f8dcc..0a3705a7c9f2a9cafeee00ab8d901b202d631c47 100644 (file)
@@ -27,6 +27,12 @@ enum dev_prop_type {
        DEV_PROP_MAX,
 };
 
+enum dev_dma_attr {
+       DEV_DMA_NOT_SUPPORTED,
+       DEV_DMA_NON_COHERENT,
+       DEV_DMA_COHERENT,
+};
+
 bool device_property_present(struct device *dev, const char *propname);
 int device_property_read_u8_array(struct device *dev, const char *propname,
                                  u8 *val, size_t nval);
@@ -168,7 +174,9 @@ struct property_set {
 
 void device_add_property_set(struct device *dev, struct property_set *pset);
 
-bool device_dma_is_coherent(struct device *dev);
+bool device_dma_supported(struct device *dev);
+
+enum dev_dma_attr device_get_dma_attr(struct device *dev);
 
 int device_get_phy_mode(struct device *dev);
 
index d681f6875aef1a7a8b22c9453b8f9019f9fd45eb..cfc3ed46cad20a26ffa131b51e25927ac6045f4c 100644 (file)
@@ -2,6 +2,7 @@
 #define __LINUX_PWM_H
 
 #include <linux/err.h>
+#include <linux/mutex.h>
 #include <linux/of.h>
 
 struct pwm_device;
@@ -87,6 +88,7 @@ enum {
  * @pwm: global index of the PWM device
  * @chip: PWM chip providing this PWM device
  * @chip_data: chip-private data associated with the PWM device
+ * @lock: used to serialize accesses to the PWM device where necessary
  * @period: period of the PWM signal (in nanoseconds)
  * @duty_cycle: duty cycle of the PWM signal (in nanoseconds)
  * @polarity: polarity of the PWM signal
@@ -98,6 +100,7 @@ struct pwm_device {
        unsigned int pwm;
        struct pwm_chip *chip;
        void *chip_data;
+       struct mutex lock;
 
        unsigned int period;
        unsigned int duty_cycle;
index 03d3b4c92d9f1171134e4dcea78080d4f42ccafe..ed03c9f7f908d7a477ef5349f35439b30b014b85 100644 (file)
 struct cache_head {
        struct hlist_node       cache_list;
        time_t          expiry_time;    /* After time time, don't use the data */
-       time_t          last_refresh;   /* If CACHE_PENDING, this is when upcall 
-                                        * was sent, else this is when update was received
+       time_t          last_refresh;   /* If CACHE_PENDING, this is when upcall was
+                                        * sent, else this is when update was
+                                        * received, though it is alway set to
+                                        * be *after* ->flush_time.
                                         */
        struct kref     ref;
        unsigned long   flags;
@@ -105,8 +107,12 @@ struct cache_detail {
        /* fields below this comment are for internal use
         * and should not be touched by cache owners
         */
-       time_t                  flush_time;             /* flush all cache items with last_refresh
-                                                        * earlier than this */
+       time_t                  flush_time;             /* flush all cache items with
+                                                        * last_refresh at or earlier
+                                                        * than this.  last_refresh
+                                                        * is never set at or earlier
+                                                        * than this.
+                                                        */
        struct list_head        others;
        time_t                  nextcheck;
        int                     entries;
@@ -203,7 +209,7 @@ static inline void cache_put(struct cache_head *h, struct cache_detail *cd)
 static inline int cache_is_expired(struct cache_detail *detail, struct cache_head *h)
 {
        return  (h->expiry_time < seconds_since_boot()) ||
-               (detail->flush_time > h->last_refresh);
+               (detail->flush_time >= h->last_refresh);
 }
 
 extern int cache_check(struct cache_detail *detail,
index ea090eaf468c6337b5ad29685b0d4919e44d2fab..c6f0f0d0e17e07609a8f6ae493bd71bdef093676 100644 (file)
@@ -64,10 +64,18 @@ do {                                                        \
  *             a new subdirectory with this name.
  * @is_visible:        Optional: Function to return permissions associated with an
  *             attribute of the group. Will be called repeatedly for each
- *             attribute in the group. Only read/write permissions as well as
- *             SYSFS_PREALLOC are accepted. Must return 0 if an attribute is
- *             not visible. The returned value will replace static permissions
- *             defined in struct attribute or struct bin_attribute.
+ *             non-binary attribute in the group. Only read/write
+ *             permissions as well as SYSFS_PREALLOC are accepted. Must
+ *             return 0 if an attribute is not visible. The returned value
+ *             will replace static permissions defined in struct attribute.
+ * @is_bin_visible:
+ *             Optional: Function to return permissions associated with a
+ *             binary attribute of the group. Will be called repeatedly
+ *             for each binary attribute in the group. Only read/write
+ *             permissions as well as SYSFS_PREALLOC are accepted. Must
+ *             return 0 if a binary attribute is not visible. The returned
+ *             value will replace static permissions defined in
+ *             struct bin_attribute.
  * @attrs:     Pointer to NULL terminated list of attributes.
  * @bin_attrs: Pointer to NULL terminated list of binary attributes.
  *             Either attrs or bin_attrs or both must be provided.
@@ -76,6 +84,8 @@ struct attribute_group {
        const char              *name;
        umode_t                 (*is_visible)(struct kobject *,
                                              struct attribute *, int);
+       umode_t                 (*is_bin_visible)(struct kobject *,
+                                                 struct bin_attribute *, int);
        struct attribute        **attrs;
        struct bin_attribute    **bin_attrs;
 };
index 157d366e761b31541a545904783fea3e21628e24..4014a59828fcba8142e27f6feb1feaf4f64d3171 100644 (file)
 #define THERMAL_WEIGHT_DEFAULT 0
 
 /* Unit conversion macros */
-#define KELVIN_TO_CELSIUS(t)   (long)(((long)t-2732 >= 0) ?    \
-                               ((long)t-2732+5)/10 : ((long)t-2732-5)/10)
-#define CELSIUS_TO_KELVIN(t)   ((t)*10+2732)
+#define DECI_KELVIN_TO_CELSIUS(t)      ({                      \
+       long _t = (t);                                          \
+       ((_t-2732 >= 0) ? (_t-2732+5)/10 : (_t-2732-5)/10);     \
+})
+#define CELSIUS_TO_DECI_KELVIN(t)      ((t)*10+2732)
 #define DECI_KELVIN_TO_MILLICELSIUS_WITH_OFFSET(t, off) (((t) - (off)) * 100)
 #define DECI_KELVIN_TO_MILLICELSIUS(t) DECI_KELVIN_TO_MILLICELSIUS_WITH_OFFSET(t, 2732)
 #define MILLICELSIUS_TO_DECI_KELVIN_WITH_OFFSET(t, off) (((t) / 100) + (off))
index d74c0ae989d501d4d50af2cd974595f49632b3dc..c36e95730de14d577e2a84962dc1c9fa2694f27a 100644 (file)
@@ -7,9 +7,10 @@ int check_user_usb_string(const char *name,
                struct usb_gadget_strings *stringtab_dev);
 
 #define GS_STRINGS_W(__struct, __name) \
-       static ssize_t __struct##_##__name##_store(struct __struct *gs, \
+static ssize_t __struct##_##__name##_store(struct config_item *item, \
                const char *page, size_t len)           \
 {                                                      \
+       struct __struct *gs = to_##__struct(item);      \
        int ret;                                        \
                                                        \
        ret = usb_string_copy(page, &gs->__name);       \
@@ -19,30 +20,20 @@ int check_user_usb_string(const char *name,
 }
 
 #define GS_STRINGS_R(__struct, __name) \
-       static ssize_t __struct##_##__name##_show(struct __struct *gs, \
-                       char *page)     \
+static ssize_t __struct##_##__name##_show(struct config_item *item, char *page) \
 {      \
+       struct __struct *gs = to_##__struct(item);      \
        return sprintf(page, "%s\n", gs->__name ?: ""); \
 }
 
-#define GS_STRING_ITEM_ATTR(struct_name, name) \
-       static struct struct_name##_attribute struct_name##_##name = \
-               __CONFIGFS_ATTR(name,  S_IRUGO | S_IWUSR,               \
-                               struct_name##_##name##_show,            \
-                               struct_name##_##name##_store)
-
 #define GS_STRINGS_RW(struct_name, _name)      \
        GS_STRINGS_R(struct_name, _name)        \
        GS_STRINGS_W(struct_name, _name)        \
-       GS_STRING_ITEM_ATTR(struct_name, _name)
+       CONFIGFS_ATTR(struct_name##_, _name)
 
 #define USB_CONFIG_STRING_RW_OPS(struct_in)                            \
-       CONFIGFS_ATTR_OPS(struct_in);                                   \
-                                                                       \
 static struct configfs_item_operations struct_in##_langid_item_ops = { \
        .release                = struct_in##_attr_release,             \
-       .show_attribute         = struct_in##_attr_show,                \
-       .store_attribute        = struct_in##_attr_store,               \
 };                                                                     \
                                                                        \
 static struct config_item_type struct_in##_langid_type = {             \
index ddb44097538245f17e882efff635143ada49e089..610a86a892b8896363ece505cdbe686096505cfc 100644 (file)
@@ -44,6 +44,9 @@ 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 91b0a68d38dc2a4941c1b36a8cac270af0136422..89474b9d260cf44151b21e26ce5d64aecf62b6cb 100644 (file)
@@ -21,15 +21,19 @@ struct dentry;
 
 struct xattr_handler {
        const char *prefix;
-       int flags;      /* fs private flags passed back to the handlers */
-       size_t (*list)(struct dentry *dentry, char *list, size_t list_size,
-                      const char *name, size_t name_len, int handler_flags);
-       int (*get)(struct dentry *dentry, const char *name, void *buffer,
-                  size_t size, int handler_flags);
-       int (*set)(struct dentry *dentry, const char *name, const void *buffer,
-                  size_t size, int flags, int handler_flags);
+       int flags;      /* fs private flags */
+       size_t (*list)(const struct xattr_handler *, struct dentry *dentry,
+                      char *list, size_t list_size, const char *name,
+                      size_t name_len);
+       int (*get)(const struct xattr_handler *, struct dentry *dentry,
+                  const char *name, void *buffer, size_t size);
+       int (*set)(const struct xattr_handler *, struct dentry *dentry,
+                  const char *name, const void *buffer, size_t size,
+                  int flags);
 };
 
+const char *xattr_full_name(const struct xattr_handler *, const char *);
+
 struct xattr {
        const char *name;
        void *value;
index e113c757d555ef097954a4b41137f4d4b5a8f4e1..ed527121031dd31b424c1ff596f9139cfcdefd02 100644 (file)
@@ -405,11 +405,6 @@ struct scsi_host_template {
        /* If use block layer to manage tags, this is tag allocation policy */
        int tag_alloc_policy;
 
-       /*
-        * Let the block layer assigns tags to all commands.
-        */
-       unsigned use_blk_tags:1;
-
        /*
         * Track QUEUE_FULL events and reduce queue depth on demand.
         */
index b27977e8aaed9b12bf6497fbdf01879a47b26cbc..4416b1026189c182bb75fbc5f677f587007522a7 100644 (file)
 
 
 #ifdef CONFIG_BLOCK
-static inline struct scsi_cmnd *scsi_mq_find_tag(struct Scsi_Host *shost,
-                                                int unique_tag)
-{
-       u16 hwq = blk_mq_unique_tag_to_hwq(unique_tag);
-       struct request *req = NULL;
-
-       if (hwq < shost->tag_set.nr_hw_queues)
-               req = blk_mq_tag_to_rq(shost->tag_set.tags[hwq],
-                                      blk_mq_unique_tag_to_tag(unique_tag));
-       return req ? (struct scsi_cmnd *)req->special : NULL;
-}
-
-/**
- * scsi_find_tag - find a tagged command by device
- * @SDpnt:     pointer to the ScSI device
- * @tag:       tag generated by blk_mq_unique_tag()
- *
- * Notes:
- *     Only works with tags allocated by the generic blk layer.
- **/
-static inline struct scsi_cmnd *scsi_find_tag(struct scsi_device *sdev, int tag)
-{
-        struct request *req;
-
-        if (tag != SCSI_NO_TAG) {
-               if (shost_use_blk_mq(sdev->host))
-                       return scsi_mq_find_tag(sdev->host, tag);
-
-               req = blk_queue_find_tag(sdev->request_queue, tag);
-               return req ? (struct scsi_cmnd *)req->special : NULL;
-       }
-
-       /* single command, look in space */
-       return sdev->current_cmnd;
-}
-
-
-/**
- * scsi_init_shared_tag_map - create a shared tag map
- * @shost:     the host to share the tag map among all devices
- * @depth:     the total depth of the map
- */
-static inline int scsi_init_shared_tag_map(struct Scsi_Host *shost, int depth)
-{
-       /*
-        * We always have a shared tag map around when using blk-mq.
-        */
-       if (shost_use_blk_mq(shost))
-               return 0;
-
-       /*
-        * If the shared tag map isn't already initialized, do it now.
-        * This saves callers from having to check ->bqt when setting up
-        * devices on the shared host (for libata)
-        */
-       if (!shost->bqt) {
-               shost->bqt = blk_init_tags(depth,
-                       shost->hostt->tag_alloc_policy);
-               if (!shost->bqt)
-                       return -ENOMEM;
-       }
-
-       return 0;
-}
-
 /**
  * scsi_host_find_tag - find the tagged command by host
  * @shost:     pointer to scsi_host
- * @tag:       tag generated by blk_mq_unique_tag()
+ * @tag:       tag
  *
- * Notes:
- *     Only works with tags allocated by the generic blk layer.
+ * Note: for devices using multiple hardware queues tag must have been
+ * generated by blk_mq_unique_tag().
  **/
 static inline struct scsi_cmnd *scsi_host_find_tag(struct Scsi_Host *shost,
-                                               int tag)
+               int tag)
 {
-       struct request *req;
+       struct request *req = NULL;
 
-       if (tag != SCSI_NO_TAG) {
-               if (shost_use_blk_mq(shost))
-                       return scsi_mq_find_tag(shost, tag);
+       if (tag == SCSI_NO_TAG)
+               return NULL;
+
+       if (shost_use_blk_mq(shost)) {
+               u16 hwq = blk_mq_unique_tag_to_hwq(tag);
+
+               if (hwq < shost->tag_set.nr_hw_queues) {
+                       req = blk_mq_tag_to_rq(shost->tag_set.tags[hwq],
+                               blk_mq_unique_tag_to_tag(tag));
+               }
+       } else {
                req = blk_map_queue_find_tag(shost->bqt, tag);
-               return req ? (struct scsi_cmnd *)req->special : NULL;
        }
-       return NULL;
+
+       if (!req)
+               return NULL;
+       return req->special;
 }
 
 #endif /* CONFIG_BLOCK */
diff --git a/include/target/configfs_macros.h b/include/target/configfs_macros.h
deleted file mode 100644 (file)
index a0fc85b..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; -*-
- * vim: noexpandtab sw=8 ts=8 sts=0:
- *
- * configfs_macros.h - extends macros for configfs
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 021110-1307, USA.
- *
- * Based on sysfs:
- *     sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
- *
- * Based on kobject.h:
- *      Copyright (c) 2002-2003        Patrick Mochel
- *      Copyright (c) 2002-2003        Open Source Development Labs
- *
- * configfs Copyright (C) 2005 Oracle.  All rights reserved.
- *
- * Added CONFIGFS_EATTR() macros from original configfs.h macros
- * Copright (C) 2008-2009 Nicholas A. Bellinger <nab@linux-iscsi.org>
- *
- * Please read Documentation/filesystems/configfs/configfs.txt before using
- * the configfs interface, ESPECIALLY the parts about reference counts and
- * item destructors.
- */
-
-#ifndef _CONFIGFS_MACROS_H_
-#define _CONFIGFS_MACROS_H_
-
-#include <linux/configfs.h>
-
-/*
- * Users often need to create attribute structures for their configurable
- * attributes, containing a configfs_attribute member and function pointers
- * for the show() and store() operations on that attribute. If they don't
- * need anything else on the extended attribute structure, they can use
- * this macro to define it.  The argument _name isends up as
- * 'struct _name_attribute, as well as names of to CONFIGFS_ATTR_OPS() below.
- * The argument _item is the name of the structure containing the
- * struct config_item or struct config_group structure members
- */
-#define CONFIGFS_EATTR_STRUCT(_name, _item)                            \
-struct _name##_attribute {                                             \
-       struct configfs_attribute attr;                                 \
-       ssize_t (*show)(struct _item *, char *);                        \
-       ssize_t (*store)(struct _item *, const char *, size_t);         \
-}
-
-/*
- * With the extended attribute structure, users can use this macro
- * (similar to sysfs' __ATTR) to make defining attributes easier.
- * An example:
- * #define MYITEM_EATTR(_name, _mode, _show, _store)   \
- * struct myitem_attribute childless_attr_##_name =    \
- *         __CONFIGFS_EATTR(_name, _mode, _show, _store)
- */
-#define __CONFIGFS_EATTR(_name, _mode, _show, _store)                  \
-{                                                                      \
-       .attr   = {                                                     \
-                       .ca_name = __stringify(_name),                  \
-                       .ca_mode = _mode,                               \
-                       .ca_owner = THIS_MODULE,                        \
-       },                                                              \
-       .show   = _show,                                                \
-       .store  = _store,                                               \
-}
-/* Here is a readonly version, only requiring a show() operation */
-#define __CONFIGFS_EATTR_RO(_name, _show)                              \
-{                                                                      \
-       .attr   = {                                                     \
-                       .ca_name = __stringify(_name),                  \
-                       .ca_mode = 0444,                                \
-                       .ca_owner = THIS_MODULE,                        \
-       },                                                              \
-       .show   = _show,                                                \
-}
-
-/*
- * With these extended attributes, the simple show_attribute() and
- * store_attribute() operations need to call the show() and store() of the
- * attributes.  This is a common pattern, so we provide a macro to define
- * them.  The argument _name is the name of the attribute defined by
- * CONFIGFS_ATTR_STRUCT(). The argument _item is the name of the structure
- * containing the struct config_item or struct config_group structure member.
- * The argument _item_member is the actual name of the struct config_* struct
- * in your _item structure.  Meaning  my_structure->some_config_group.
- *                                   ^^_item^^^^^  ^^_item_member^^^
- * This macro expects the attributes to be named "struct <name>_attribute".
- */
-#define CONFIGFS_EATTR_OPS_TO_FUNC(_name, _item, _item_member)         \
-static struct _item *to_##_name(struct config_item *ci)                        \
-{                                                                      \
-       return (ci) ? container_of(to_config_group(ci), struct _item,   \
-               _item_member) : NULL;                                   \
-}
-
-#define CONFIGFS_EATTR_OPS_SHOW(_name, _item)                          \
-static ssize_t _name##_attr_show(struct config_item *item,             \
-                                struct configfs_attribute *attr,       \
-                                char *page)                            \
-{                                                                      \
-       struct _item *_item = to_##_name(item);                         \
-       struct _name##_attribute * _name##_attr =                       \
-               container_of(attr, struct _name##_attribute, attr);     \
-       ssize_t ret = 0;                                                \
-                                                                       \
-       if (_name##_attr->show)                                         \
-               ret = _name##_attr->show(_item, page);                  \
-       return ret;                                                     \
-}
-
-#define CONFIGFS_EATTR_OPS_STORE(_name, _item)                         \
-static ssize_t _name##_attr_store(struct config_item *item,            \
-                                 struct configfs_attribute *attr,      \
-                                 const char *page, size_t count)       \
-{                                                                      \
-       struct _item *_item = to_##_name(item);                         \
-       struct _name##_attribute * _name##_attr =                       \
-               container_of(attr, struct _name##_attribute, attr);     \
-       ssize_t ret = -EINVAL;                                          \
-                                                                       \
-       if (_name##_attr->store)                                        \
-               ret = _name##_attr->store(_item, page, count);          \
-       return ret;                                                     \
-}
-
-#define CONFIGFS_EATTR_OPS(_name, _item, _item_member)                 \
-       CONFIGFS_EATTR_OPS_TO_FUNC(_name, _item, _item_member);         \
-       CONFIGFS_EATTR_OPS_SHOW(_name, _item);                          \
-       CONFIGFS_EATTR_OPS_STORE(_name, _item);
-
-#define CONFIGFS_EATTR_OPS_RO(_name, _item, _item_member)              \
-       CONFIGFS_EATTR_OPS_TO_FUNC(_name, _item, _item_member);         \
-       CONFIGFS_EATTR_OPS_SHOW(_name, _item);
-
-#endif /* _CONFIGFS_MACROS_H_ */
index 5f48754dc36ae0e15e06527c0cb63dc29324721e..0a2c74008e5388f6d817272735882f40abc3a013 100644 (file)
@@ -563,6 +563,36 @@ struct se_node_acl {
        struct kref             acl_kref;
 };
 
+static inline struct se_node_acl *acl_to_nacl(struct config_item *item)
+{
+       return container_of(to_config_group(item), struct se_node_acl,
+                       acl_group);
+}
+
+static inline struct se_node_acl *attrib_to_nacl(struct config_item *item)
+{
+       return container_of(to_config_group(item), struct se_node_acl,
+                       acl_attrib_group);
+}
+
+static inline struct se_node_acl *auth_to_nacl(struct config_item *item)
+{
+       return container_of(to_config_group(item), struct se_node_acl,
+                       acl_auth_group);
+}
+
+static inline struct se_node_acl *param_to_nacl(struct config_item *item)
+{
+       return container_of(to_config_group(item), struct se_node_acl,
+                       acl_param_group);
+}
+
+static inline struct se_node_acl *fabric_stat_to_nacl(struct config_item *item)
+{
+       return container_of(to_config_group(item), struct se_node_acl,
+                       acl_fabric_stat_group);
+}
+
 struct se_session {
        unsigned                sess_tearing_down:1;
        u64                     sess_bin_isid;
@@ -821,6 +851,12 @@ struct se_tpg_np {
        struct config_group     tpg_np_group;
 };
 
+static inline struct se_tpg_np *to_tpg_np(struct config_item *item)
+{
+       return container_of(to_config_group(item), struct se_tpg_np,
+                       tpg_np_group);
+}
+
 struct se_portal_group {
        /*
         * PROTOCOL IDENTIFIER value per SPC4, 7.5.1.
@@ -857,6 +893,30 @@ struct se_portal_group {
        struct config_group     tpg_param_group;
 };
 
+static inline struct se_portal_group *to_tpg(struct config_item *item)
+{
+       return container_of(to_config_group(item), struct se_portal_group,
+                       tpg_group);
+}
+
+static inline struct se_portal_group *attrib_to_tpg(struct config_item *item)
+{
+       return container_of(to_config_group(item), struct se_portal_group,
+                       tpg_attrib_group);
+}
+
+static inline struct se_portal_group *auth_to_tpg(struct config_item *item)
+{
+       return container_of(to_config_group(item), struct se_portal_group,
+                       tpg_auth_group);
+}
+
+static inline struct se_portal_group *param_to_tpg(struct config_item *item)
+{
+       return container_of(to_config_group(item), struct se_portal_group,
+                       tpg_param_group);
+}
+
 struct se_wwn {
        struct target_fabric_configfs *wwn_tf;
        struct config_group     wwn_group;
diff --git a/include/target/target_core_fabric_configfs.h b/include/target/target_core_fabric_configfs.h
deleted file mode 100644 (file)
index 7a0649c..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Used for tfc_wwn_cit attributes
- */
-
-#include <target/configfs_macros.h>
-
-CONFIGFS_EATTR_STRUCT(target_fabric_nacl_attrib, se_node_acl);
-#define TF_NACL_ATTRIB_ATTR(_fabric, _name, _mode)                     \
-static struct target_fabric_nacl_attrib_attribute _fabric##_nacl_attrib_##_name = \
-       __CONFIGFS_EATTR(_name, _mode,                                  \
-       _fabric##_nacl_attrib_show_##_name,                             \
-       _fabric##_nacl_attrib_store_##_name);
-
-CONFIGFS_EATTR_STRUCT(target_fabric_nacl_auth, se_node_acl);
-#define TF_NACL_AUTH_ATTR(_fabric, _name, _mode)                       \
-static struct target_fabric_nacl_auth_attribute _fabric##_nacl_auth_##_name = \
-       __CONFIGFS_EATTR(_name, _mode,                                  \
-       _fabric##_nacl_auth_show_##_name,                               \
-       _fabric##_nacl_auth_store_##_name);
-
-#define TF_NACL_AUTH_ATTR_RO(_fabric, _name)                           \
-static struct target_fabric_nacl_auth_attribute _fabric##_nacl_auth_##_name = \
-       __CONFIGFS_EATTR_RO(_name,                                      \
-       _fabric##_nacl_auth_show_##_name);
-
-CONFIGFS_EATTR_STRUCT(target_fabric_nacl_param, se_node_acl);
-#define TF_NACL_PARAM_ATTR(_fabric, _name, _mode)                      \
-static struct target_fabric_nacl_param_attribute _fabric##_nacl_param_##_name = \
-       __CONFIGFS_EATTR(_name, _mode,                                  \
-       _fabric##_nacl_param_show_##_name,                              \
-       _fabric##_nacl_param_store_##_name);
-
-#define TF_NACL_PARAM_ATTR_RO(_fabric, _name)                          \
-static struct target_fabric_nacl_param_attribute _fabric##_nacl_param_##_name = \
-       __CONFIGFS_EATTR_RO(_name,                                      \
-       _fabric##_nacl_param_show_##_name);
-
-
-CONFIGFS_EATTR_STRUCT(target_fabric_nacl_base, se_node_acl);
-#define TF_NACL_BASE_ATTR(_fabric, _name, _mode)                       \
-static struct target_fabric_nacl_base_attribute _fabric##_nacl_##_name = \
-       __CONFIGFS_EATTR(_name, _mode,                                  \
-       _fabric##_nacl_show_##_name,                                    \
-       _fabric##_nacl_store_##_name);
-
-#define TF_NACL_BASE_ATTR_RO(_fabric, _name)                           \
-static struct target_fabric_nacl_base_attribute _fabric##_nacl_##_name = \
-       __CONFIGFS_EATTR_RO(_name,                                      \
-       _fabric##_nacl_show_##_name);
-
-CONFIGFS_EATTR_STRUCT(target_fabric_np_base, se_tpg_np);
-#define TF_NP_BASE_ATTR(_fabric, _name, _mode)                         \
-static struct target_fabric_np_base_attribute _fabric##_np_##_name =   \
-       __CONFIGFS_EATTR(_name, _mode,                                  \
-       _fabric##_np_show_##_name,                                      \
-       _fabric##_np_store_##_name);
-
-CONFIGFS_EATTR_STRUCT(target_fabric_tpg_attrib, se_portal_group);
-#define TF_TPG_ATTRIB_ATTR(_fabric, _name, _mode)                      \
-static struct target_fabric_tpg_attrib_attribute _fabric##_tpg_attrib_##_name = \
-       __CONFIGFS_EATTR(_name, _mode,                                  \
-       _fabric##_tpg_attrib_show_##_name,                              \
-       _fabric##_tpg_attrib_store_##_name);
-
-CONFIGFS_EATTR_STRUCT(target_fabric_tpg_auth, se_portal_group);
-#define TF_TPG_AUTH_ATTR(_fabric, _name, _mode)                        \
-static struct target_fabric_tpg_auth_attribute _fabric##_tpg_auth_##_name = \
-       __CONFIGFS_EATTR(_name, _mode,                                  \
-       _fabric##_tpg_auth_show_##_name,                                \
-       _fabric##_tpg_auth_store_##_name);
-
-#define TF_TPG_AUTH_ATTR_RO(_fabric, _name)                            \
-static struct target_fabric_tpg_auth_attribute _fabric##_tpg_auth_##_name = \
-       __CONFIGFS_EATTR_RO(_name,                                      \
-       _fabric##_tpg_auth_show_##_name);
-
-CONFIGFS_EATTR_STRUCT(target_fabric_tpg_param, se_portal_group);
-#define TF_TPG_PARAM_ATTR(_fabric, _name, _mode)                       \
-static struct target_fabric_tpg_param_attribute _fabric##_tpg_param_##_name = \
-       __CONFIGFS_EATTR(_name, _mode,                                  \
-       _fabric##_tpg_param_show_##_name,                               \
-       _fabric##_tpg_param_store_##_name);
-
-
-CONFIGFS_EATTR_STRUCT(target_fabric_tpg, se_portal_group);
-#define TF_TPG_BASE_ATTR(_fabric, _name, _mode)                                \
-static struct target_fabric_tpg_attribute _fabric##_tpg_##_name =      \
-       __CONFIGFS_EATTR(_name, _mode,                                  \
-       _fabric##_tpg_show_##_name,                                     \
-       _fabric##_tpg_store_##_name);
-
-
-#define TF_TPG_BASE_ATTR_RO(_fabric, _name)                            \
-static struct target_fabric_tpg_attribute _fabric##_tpg_##_name =      \
-       __CONFIGFS_EATTR_RO(_name,                                      \
-       _fabric##_tpg_show_##_name);
-
-CONFIGFS_EATTR_STRUCT(target_fabric_wwn, target_fabric_configfs);
-#define TF_WWN_ATTR(_fabric, _name, _mode)                             \
-static struct target_fabric_wwn_attribute _fabric##_wwn_##_name =      \
-       __CONFIGFS_EATTR(_name, _mode,                                  \
-       _fabric##_wwn_show_attr_##_name,                                \
-       _fabric##_wwn_store_attr_##_name);
-
-#define TF_WWN_ATTR_RO(_fabric, _name)                                 \
-static struct target_fabric_wwn_attribute _fabric##_wwn_##_name =      \
-       __CONFIGFS_EATTR_RO(_name,                                      \
-       _fabric##_wwn_show_attr_##_name);
-
-CONFIGFS_EATTR_STRUCT(target_fabric_discovery, target_fabric_configfs);
-#define TF_DISC_ATTR(_fabric, _name, _mode)                            \
-static struct target_fabric_discovery_attribute _fabric##_disc_##_name = \
-       __CONFIGFS_EATTR(_name, _mode,                                  \
-       _fabric##_disc_show_##_name,                                    \
-       _fabric##_disc_store_##_name);
-
-#define TF_DISC_ATTR_RO(_fabric, _name)                                        \
-static struct target_fabric_discovery_attribute _fabric##_disc_##_name = \
-       __CONFIGFS_EATTR_RO(_name,                                      \
-       _fabric##_disc_show_##_name);
-
-extern int target_fabric_setup_cits(struct target_fabric_configfs *);
index 8b1f80682b8047c1f77a08830a16e7b529ddfb00..5738bb3e2343d6d0edb4bb0548454b29eed94c74 100644 (file)
@@ -4,6 +4,7 @@
 #if !defined(_TRACE_THERMAL_H) || defined(TRACE_HEADER_MULTI_READ)
 #define _TRACE_THERMAL_H
 
+#include <linux/devfreq.h>
 #include <linux/thermal.h>
 #include <linux/tracepoint.h>
 
@@ -135,6 +136,58 @@ TRACE_EVENT(thermal_power_cpu_limit,
                __entry->power)
 );
 
+TRACE_EVENT(thermal_power_devfreq_get_power,
+       TP_PROTO(struct thermal_cooling_device *cdev,
+                struct devfreq_dev_status *status, unsigned long freq,
+               u32 dynamic_power, u32 static_power),
+
+       TP_ARGS(cdev, status,  freq, dynamic_power, static_power),
+
+       TP_STRUCT__entry(
+               __string(type,         cdev->type    )
+               __field(unsigned long, freq          )
+               __field(u32,           load          )
+               __field(u32,           dynamic_power )
+               __field(u32,           static_power  )
+       ),
+
+       TP_fast_assign(
+               __assign_str(type, cdev->type);
+               __entry->freq = freq;
+               __entry->load = (100 * status->busy_time) / status->total_time;
+               __entry->dynamic_power = dynamic_power;
+               __entry->static_power = static_power;
+       ),
+
+       TP_printk("type=%s freq=%lu load=%u dynamic_power=%u static_power=%u",
+               __get_str(type), __entry->freq,
+               __entry->load, __entry->dynamic_power, __entry->static_power)
+);
+
+TRACE_EVENT(thermal_power_devfreq_limit,
+       TP_PROTO(struct thermal_cooling_device *cdev, unsigned long freq,
+               unsigned long cdev_state, u32 power),
+
+       TP_ARGS(cdev, freq, cdev_state, power),
+
+       TP_STRUCT__entry(
+               __string(type,         cdev->type)
+               __field(unsigned int,  freq      )
+               __field(unsigned long, cdev_state)
+               __field(u32,           power     )
+       ),
+
+       TP_fast_assign(
+               __assign_str(type, cdev->type);
+               __entry->freq = freq;
+               __entry->cdev_state = cdev_state;
+               __entry->power = power;
+       ),
+
+       TP_printk("type=%s freq=%u cdev_state=%lu power=%u",
+               __get_str(type), __entry->freq, __entry->cdev_state,
+               __entry->power)
+);
 #endif /* _TRACE_THERMAL_H */
 
 /* This part must be outside protection */
index 8c5e8b91a3cbbb6b35542e57b64365b608c4073b..0b69a7753558ff27a07748f2d5ca7f3f054b2ba2 100644 (file)
 /* add more to the end as needed */
 
 #define fourcc_mod_code(vendor, val) \
-       ((((u64)DRM_FORMAT_MOD_VENDOR_## vendor) << 56) | (val & 0x00ffffffffffffffULL))
+       ((((__u64)DRM_FORMAT_MOD_VENDOR_## vendor) << 56) | (val & 0x00ffffffffffffffULL))
 
 /*
  * Format Modifier tokens:
index 9fd7b5d8df2fa357f434a899cccfa7810f826107..751b69f858c80411c910f21db7fb50c8902e94cf 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 0a495ab35bc72b55d8eab13f0922e6fdb8099d9a..d8560ee3bab788c15be6d1be8eb610473fc5c4b5 100644 (file)
@@ -58,36 +58,13 @@ static void context_tracking_recursion_exit(void)
  * instructions to execute won't use any RCU read side critical section
  * because this function sets RCU in extended quiescent state.
  */
-void context_tracking_enter(enum ctx_state state)
+void __context_tracking_enter(enum ctx_state state)
 {
-       unsigned long flags;
-
-       /*
-        * Repeat the user_enter() check here because some archs may be calling
-        * this from asm and if no CPU needs context tracking, they shouldn't
-        * go further. Repeat the check here until they support the inline static
-        * key check.
-        */
-       if (!context_tracking_is_enabled())
-               return;
-
-       /*
-        * Some contexts may involve an exception occuring in an irq,
-        * leading to that nesting:
-        * rcu_irq_enter() rcu_user_exit() rcu_user_exit() rcu_irq_exit()
-        * This would mess up the dyntick_nesting count though. And rcu_irq_*()
-        * helpers are enough to protect RCU uses inside the exception. So
-        * just return immediately if we detect we are in an IRQ.
-        */
-       if (in_interrupt())
-               return;
-
        /* Kernel threads aren't supposed to go to userspace */
        WARN_ON_ONCE(!current->mm);
 
-       local_irq_save(flags);
        if (!context_tracking_recursion_enter())
-               goto out_irq_restore;
+               return;
 
        if ( __this_cpu_read(context_tracking.state) != state) {
                if (__this_cpu_read(context_tracking.active)) {
@@ -120,7 +97,27 @@ void context_tracking_enter(enum ctx_state state)
                __this_cpu_write(context_tracking.state, state);
        }
        context_tracking_recursion_exit();
-out_irq_restore:
+}
+NOKPROBE_SYMBOL(__context_tracking_enter);
+EXPORT_SYMBOL_GPL(__context_tracking_enter);
+
+void context_tracking_enter(enum ctx_state state)
+{
+       unsigned long flags;
+
+       /*
+        * Some contexts may involve an exception occuring in an irq,
+        * leading to that nesting:
+        * rcu_irq_enter() rcu_user_exit() rcu_user_exit() rcu_irq_exit()
+        * This would mess up the dyntick_nesting count though. And rcu_irq_*()
+        * helpers are enough to protect RCU uses inside the exception. So
+        * just return immediately if we detect we are in an IRQ.
+        */
+       if (in_interrupt())
+               return;
+
+       local_irq_save(flags);
+       __context_tracking_enter(state);
        local_irq_restore(flags);
 }
 NOKPROBE_SYMBOL(context_tracking_enter);
@@ -128,7 +125,7 @@ EXPORT_SYMBOL_GPL(context_tracking_enter);
 
 void context_tracking_user_enter(void)
 {
-       context_tracking_enter(CONTEXT_USER);
+       user_enter();
 }
 NOKPROBE_SYMBOL(context_tracking_user_enter);
 
@@ -144,19 +141,10 @@ NOKPROBE_SYMBOL(context_tracking_user_enter);
  * This call supports re-entrancy. This way it can be called from any exception
  * handler without needing to know if we came from userspace or not.
  */
-void context_tracking_exit(enum ctx_state state)
+void __context_tracking_exit(enum ctx_state state)
 {
-       unsigned long flags;
-
-       if (!context_tracking_is_enabled())
-               return;
-
-       if (in_interrupt())
-               return;
-
-       local_irq_save(flags);
        if (!context_tracking_recursion_enter())
-               goto out_irq_restore;
+               return;
 
        if (__this_cpu_read(context_tracking.state) == state) {
                if (__this_cpu_read(context_tracking.active)) {
@@ -173,7 +161,19 @@ void context_tracking_exit(enum ctx_state state)
                __this_cpu_write(context_tracking.state, CONTEXT_KERNEL);
        }
        context_tracking_recursion_exit();
-out_irq_restore:
+}
+NOKPROBE_SYMBOL(__context_tracking_exit);
+EXPORT_SYMBOL_GPL(__context_tracking_exit);
+
+void context_tracking_exit(enum ctx_state state)
+{
+       unsigned long flags;
+
+       if (in_interrupt())
+               return;
+
+       local_irq_save(flags);
+       __context_tracking_exit(state);
        local_irq_restore(flags);
 }
 NOKPROBE_SYMBOL(context_tracking_exit);
@@ -181,7 +181,7 @@ EXPORT_SYMBOL_GPL(context_tracking_exit);
 
 void context_tracking_user_exit(void)
 {
-       context_tracking_exit(CONTEXT_USER);
+       user_exit();
 }
 NOKPROBE_SYMBOL(context_tracking_user_exit);
 
index 1a734e0adfa78259dac6cae57239a2d5f992a9ac..36babfd2064842c28d4951a656ea1e84500bbf8f 100644 (file)
@@ -1050,13 +1050,13 @@ retry:
        /*
         * One of the few rules of preemptible RCU is that one cannot do
         * rcu_read_unlock() while holding a scheduler (or nested) lock when
-        * part of the read side critical section was preemptible -- see
+        * part of the read side critical section was irqs-enabled -- see
         * rcu_read_unlock_special().
         *
         * Since ctx->lock nests under rq->lock we must ensure the entire read
-        * side critical section is non-preemptible.
+        * side critical section has interrupts disabled.
         */
-       preempt_disable();
+       local_irq_save(*flags);
        rcu_read_lock();
        ctx = rcu_dereference(task->perf_event_ctxp[ctxn]);
        if (ctx) {
@@ -1070,21 +1070,22 @@ retry:
                 * if so.  If we locked the right context, then it
                 * can't get swapped on us any more.
                 */
-               raw_spin_lock_irqsave(&ctx->lock, *flags);
+               raw_spin_lock(&ctx->lock);
                if (ctx != rcu_dereference(task->perf_event_ctxp[ctxn])) {
-                       raw_spin_unlock_irqrestore(&ctx->lock, *flags);
+                       raw_spin_unlock(&ctx->lock);
                        rcu_read_unlock();
-                       preempt_enable();
+                       local_irq_restore(*flags);
                        goto retry;
                }
 
                if (!atomic_inc_not_zero(&ctx->refcount)) {
-                       raw_spin_unlock_irqrestore(&ctx->lock, *flags);
+                       raw_spin_unlock(&ctx->lock);
                        ctx = NULL;
                }
        }
        rcu_read_unlock();
-       preempt_enable();
+       if (!ctx)
+               local_irq_restore(*flags);
        return ctx;
 }
 
@@ -6913,6 +6914,10 @@ static int perf_tp_filter_match(struct perf_event *event,
 {
        void *record = data->raw->data;
 
+       /* only top level events have filters set */
+       if (event->parent)
+               event = event->parent;
+
        if (likely(!event->filter) || filter_match_preds(event->filter, record))
                return 1;
        return 0;
index 05c2188271b86730323c9bce053adc2d16e8d5a3..fcab63c669059308d3cc27054742587b0627b23f 100644 (file)
@@ -199,6 +199,11 @@ static inline int irq_desc_get_node(struct irq_desc *desc)
        return irq_common_data_get_node(&desc->irq_common_data);
 }
 
+static inline int irq_desc_is_chained(struct irq_desc *desc)
+{
+       return (desc->action && desc->action == &chained_action);
+}
+
 #ifdef CONFIG_PM_SLEEP
 bool irq_pm_check_wakeup(struct irq_desc *desc);
 void irq_pm_install_action(struct irq_desc *desc, struct irqaction *action);
index e80c4400118ae7a8e3f09476964260490fccf01a..cea1de0161f18a164aebb84e275ad67d5899eda8 100644 (file)
@@ -70,7 +70,8 @@ void irq_pm_remove_action(struct irq_desc *desc, struct irqaction *action)
 
 static bool suspend_device_irq(struct irq_desc *desc)
 {
-       if (!desc->action || desc->no_suspend_depth)
+       if (!desc->action || irq_desc_is_chained(desc) ||
+           desc->no_suspend_depth)
                return false;
 
        if (irqd_is_wakeup_set(&desc->irq_data)) {
index a916cf144b6550caf452fc304a1e848d40246b8a..a2c02fd5d6d0f8c1ade72ab2680287f37321aa25 100644 (file)
@@ -475,7 +475,7 @@ int show_interrupts(struct seq_file *p, void *v)
        for_each_online_cpu(j)
                any_count |= kstat_irqs_cpu(i, j);
        action = desc->action;
-       if ((!action || action == &chained_action) && !any_count)
+       if ((!action || irq_desc_is_chained(desc)) && !any_count)
                goto out;
 
        seq_printf(p, "%*d: ", prec, i);
index 824aa9f501a3b2a183a5a700dee57c984c51f89e..f04fda8f669c8eff57e936fcb1334b13a4140ce5 100644 (file)
@@ -2302,7 +2302,7 @@ void task_tick_numa(struct rq *rq, struct task_struct *curr)
        now = curr->se.sum_exec_runtime;
        period = (u64)curr->numa_scan_period * NSEC_PER_MSEC;
 
-       if (now - curr->node_stamp > period) {
+       if (now > curr->node_stamp + period) {
                if (!curr->node_stamp)
                        curr->numa_scan_period = task_scan_min(curr);
                curr->node_stamp += period;
index 74591ba9474f4dff4e0c3d7b7acedbe14b5d57a8..bbc5d1114583b21f1ab489cd40a98f3aa5ebd61d 100644 (file)
@@ -977,13 +977,29 @@ EXPORT_SYMBOL(add_timer);
  */
 void add_timer_on(struct timer_list *timer, int cpu)
 {
-       struct tvec_base *base = per_cpu_ptr(&tvec_bases, cpu);
+       struct tvec_base *new_base = per_cpu_ptr(&tvec_bases, cpu);
+       struct tvec_base *base;
        unsigned long flags;
 
        timer_stats_timer_set_start_info(timer);
        BUG_ON(timer_pending(timer) || !timer->function);
-       spin_lock_irqsave(&base->lock, flags);
-       timer->flags = (timer->flags & ~TIMER_BASEMASK) | cpu;
+
+       /*
+        * If @timer was on a different CPU, it should be migrated with the
+        * old base locked to prevent other operations proceeding with the
+        * wrong base locked.  See lock_timer_base().
+        */
+       base = lock_timer_base(timer, &flags);
+       if (base != new_base) {
+               timer->flags |= TIMER_MIGRATING;
+
+               spin_unlock(&base->lock);
+               base = new_base;
+               spin_lock(&base->lock);
+               WRITE_ONCE(timer->flags,
+                          (timer->flags & ~TIMER_BASEMASK) | cpu);
+       }
+
        debug_activate(timer, timer->expires);
        internal_add_timer(base, timer);
        spin_unlock_irqrestore(&base->lock, flags);
index 2198a630ef5826a30e51a2974d472b078273f80c..87fb9801bd9eead0d6e45bef49bc1eefc324c6a7 100644 (file)
@@ -100,8 +100,6 @@ static DEFINE_PER_CPU(bool, trace_cmdline_save);
  */
 static int tracing_disabled = 1;
 
-DEFINE_PER_CPU(int, ftrace_cpu_disabled);
-
 cpumask_var_t __read_mostly    tracing_buffer_mask;
 
 /*
@@ -1775,10 +1773,6 @@ trace_function(struct trace_array *tr,
        struct ring_buffer_event *event;
        struct ftrace_entry *entry;
 
-       /* If we are reading the ring buffer, don't trace */
-       if (unlikely(__this_cpu_read(ftrace_cpu_disabled)))
-               return;
-
        event = trace_buffer_lock_reserve(buffer, TRACE_FN, sizeof(*entry),
                                          flags, pc);
        if (!event)
@@ -4554,6 +4548,8 @@ out:
        return ret;
 }
 
+#ifdef CONFIG_TRACER_MAX_TRACE
+
 static ssize_t
 tracing_max_lat_read(struct file *filp, char __user *ubuf,
                     size_t cnt, loff_t *ppos)
@@ -4568,6 +4564,8 @@ tracing_max_lat_write(struct file *filp, const char __user *ubuf,
        return tracing_nsecs_write(filp->private_data, ubuf, cnt, ppos);
 }
 
+#endif
+
 static int tracing_open_pipe(struct inode *inode, struct file *filp)
 {
        struct trace_array *tr = inode->i_private;
@@ -5469,12 +5467,14 @@ static const struct file_operations tracing_thresh_fops = {
        .llseek         = generic_file_llseek,
 };
 
+#ifdef CONFIG_TRACER_MAX_TRACE
 static const struct file_operations tracing_max_lat_fops = {
        .open           = tracing_open_generic,
        .read           = tracing_max_lat_read,
        .write          = tracing_max_lat_write,
        .llseek         = generic_file_llseek,
 };
+#endif
 
 static const struct file_operations set_tracer_fops = {
        .open           = tracing_open_generic,
@@ -6847,7 +6847,9 @@ struct dentry *tracing_init_dentry(void)
        if (tr->dir)
                return NULL;
 
-       if (WARN_ON(!debugfs_initialized()))
+       if (WARN_ON(!tracefs_initialized()) ||
+               (IS_ENABLED(CONFIG_DEBUG_FS) &&
+                WARN_ON(!debugfs_initialized())))
                return ERR_PTR(-ENODEV);
 
        /*
index dd7620802e725e1e2f262f77ba7d8c76dda98ef9..919d9d07686f5bcaad65699f400748a4b4db8a5e 100644 (file)
@@ -667,7 +667,6 @@ extern int DYN_FTRACE_TEST_NAME2(void);
 
 extern bool ring_buffer_expanded;
 extern bool tracing_selftest_disabled;
-DECLARE_PER_CPU(int, ftrace_cpu_disabled);
 
 #ifdef CONFIG_FTRACE_STARTUP_TEST
 extern int trace_selftest_startup_function(struct tracer *trace,
index 92382af7a21312c03ecef0cabdfbce19e2c8111e..a663cbb84107d71039200011e4b3ec5f897c9213 100644 (file)
@@ -288,9 +288,6 @@ int __trace_graph_entry(struct trace_array *tr,
        struct ring_buffer *buffer = tr->trace_buffer.buffer;
        struct ftrace_graph_ent_entry *entry;
 
-       if (unlikely(__this_cpu_read(ftrace_cpu_disabled)))
-               return 0;
-
        event = trace_buffer_lock_reserve(buffer, TRACE_GRAPH_ENT,
                                          sizeof(*entry), flags, pc);
        if (!event)
@@ -403,9 +400,6 @@ void __trace_graph_return(struct trace_array *tr,
        struct ring_buffer *buffer = tr->trace_buffer.buffer;
        struct ftrace_graph_ret_entry *entry;
 
-       if (unlikely(__this_cpu_read(ftrace_cpu_disabled)))
-               return;
-
        event = trace_buffer_lock_reserve(buffer, TRACE_GRAPH_RET,
                                          sizeof(*entry), flags, pc);
        if (!event)
index 496b27588493ded6edb0bf408440ecaa56dcd59c..e2ed69850489bb79a6a055ee3264456a31acee3e 100644 (file)
@@ -30,7 +30,9 @@ bool vlan_do_receive(struct sk_buff **skbp)
                        skb->pkt_type = PACKET_HOST;
        }
 
-       if (!(vlan_dev_priv(vlan_dev)->flags & VLAN_FLAG_REORDER_HDR)) {
+       if (!(vlan_dev_priv(vlan_dev)->flags & VLAN_FLAG_REORDER_HDR) &&
+           !netif_is_macvlan_port(vlan_dev) &&
+           !netif_is_bridge_port(vlan_dev)) {
                unsigned int offset = skb->data - skb_mac_header(skb);
 
                /*
index ba6eb17226da424d59bb462a2089186bbd3233af..10d87753ed8737329c244b1ae7718e95c8abd118 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/ceph/decode.h>
 #include <linux/ceph/auth.h>
+#include <linux/ceph/libceph.h>
 #include <linux/ceph/messenger.h>
 
 #include "crypto.h"
@@ -279,6 +280,15 @@ bad:
        return -EINVAL;
 }
 
+static void ceph_x_authorizer_cleanup(struct ceph_x_authorizer *au)
+{
+       ceph_crypto_key_destroy(&au->session_key);
+       if (au->buf) {
+               ceph_buffer_put(au->buf);
+               au->buf = NULL;
+       }
+}
+
 static int ceph_x_build_authorizer(struct ceph_auth_client *ac,
                                   struct ceph_x_ticket_handler *th,
                                   struct ceph_x_authorizer *au)
@@ -297,7 +307,7 @@ static int ceph_x_build_authorizer(struct ceph_auth_client *ac,
        ceph_crypto_key_destroy(&au->session_key);
        ret = ceph_crypto_key_clone(&au->session_key, &th->session_key);
        if (ret)
-               return ret;
+               goto out_au;
 
        maxlen = sizeof(*msg_a) + sizeof(msg_b) +
                ceph_x_encrypt_buflen(ticket_blob_len);
@@ -309,8 +319,8 @@ static int ceph_x_build_authorizer(struct ceph_auth_client *ac,
        if (!au->buf) {
                au->buf = ceph_buffer_new(maxlen, GFP_NOFS);
                if (!au->buf) {
-                       ceph_crypto_key_destroy(&au->session_key);
-                       return -ENOMEM;
+                       ret = -ENOMEM;
+                       goto out_au;
                }
        }
        au->service = th->service;
@@ -340,7 +350,7 @@ static int ceph_x_build_authorizer(struct ceph_auth_client *ac,
        ret = ceph_x_encrypt(&au->session_key, &msg_b, sizeof(msg_b),
                             p, end - p);
        if (ret < 0)
-               goto out_buf;
+               goto out_au;
        p += ret;
        au->buf->vec.iov_len = p - au->buf->vec.iov_base;
        dout(" built authorizer nonce %llx len %d\n", au->nonce,
@@ -348,9 +358,8 @@ static int ceph_x_build_authorizer(struct ceph_auth_client *ac,
        BUG_ON(au->buf->vec.iov_len > maxlen);
        return 0;
 
-out_buf:
-       ceph_buffer_put(au->buf);
-       au->buf = NULL;
+out_au:
+       ceph_x_authorizer_cleanup(au);
        return ret;
 }
 
@@ -624,8 +633,7 @@ static void ceph_x_destroy_authorizer(struct ceph_auth_client *ac,
 {
        struct ceph_x_authorizer *au = (void *)a;
 
-       ceph_crypto_key_destroy(&au->session_key);
-       ceph_buffer_put(au->buf);
+       ceph_x_authorizer_cleanup(au);
        kfree(au);
 }
 
@@ -653,8 +661,7 @@ static void ceph_x_destroy(struct ceph_auth_client *ac)
                remove_ticket_handler(ac, th);
        }
 
-       if (xi->auth_authorizer.buf)
-               ceph_buffer_put(xi->auth_authorizer.buf);
+       ceph_x_authorizer_cleanup(&xi->auth_authorizer);
 
        kfree(ac->private);
        ac->private = NULL;
@@ -691,8 +698,10 @@ static int ceph_x_sign_message(struct ceph_auth_handshake *auth,
                               struct ceph_msg *msg)
 {
        int ret;
-       if (!auth->authorizer)
+
+       if (ceph_test_opt(from_msgr(msg->con->msgr), NOMSGSIGN))
                return 0;
+
        ret = calcu_signature((struct ceph_x_authorizer *)auth->authorizer,
                              msg, &msg->footer.sig);
        if (ret < 0)
@@ -707,8 +716,9 @@ static int ceph_x_check_message_signature(struct ceph_auth_handshake *auth,
        __le64 sig_check;
        int ret;
 
-       if (!auth->authorizer)
+       if (ceph_test_opt(from_msgr(msg->con->msgr), NOMSGSIGN))
                return 0;
+
        ret = calcu_signature((struct ceph_x_authorizer *)auth->authorizer,
                              msg, &sig_check);
        if (ret < 0)
index 78f098a20796d7dd0d71b364c5de3d99239dc4ac..bcbec33c6a14a8f5d962fb1d803a6503a6e11f9b 100644 (file)
@@ -245,6 +245,8 @@ enum {
        Opt_nocrc,
        Opt_cephx_require_signatures,
        Opt_nocephx_require_signatures,
+       Opt_cephx_sign_messages,
+       Opt_nocephx_sign_messages,
        Opt_tcp_nodelay,
        Opt_notcp_nodelay,
 };
@@ -267,6 +269,8 @@ static match_table_t opt_tokens = {
        {Opt_nocrc, "nocrc"},
        {Opt_cephx_require_signatures, "cephx_require_signatures"},
        {Opt_nocephx_require_signatures, "nocephx_require_signatures"},
+       {Opt_cephx_sign_messages, "cephx_sign_messages"},
+       {Opt_nocephx_sign_messages, "nocephx_sign_messages"},
        {Opt_tcp_nodelay, "tcp_nodelay"},
        {Opt_notcp_nodelay, "notcp_nodelay"},
        {-1, NULL}
@@ -491,6 +495,12 @@ ceph_parse_options(char *options, const char *dev_name,
                case Opt_nocephx_require_signatures:
                        opt->flags |= CEPH_OPT_NOMSGAUTH;
                        break;
+               case Opt_cephx_sign_messages:
+                       opt->flags &= ~CEPH_OPT_NOMSGSIGN;
+                       break;
+               case Opt_nocephx_sign_messages:
+                       opt->flags |= CEPH_OPT_NOMSGSIGN;
+                       break;
 
                case Opt_tcp_nodelay:
                        opt->flags |= CEPH_OPT_TCP_NODELAY;
@@ -534,6 +544,8 @@ int ceph_print_client_options(struct seq_file *m, struct ceph_client *client)
                seq_puts(m, "nocrc,");
        if (opt->flags & CEPH_OPT_NOMSGAUTH)
                seq_puts(m, "nocephx_require_signatures,");
+       if (opt->flags & CEPH_OPT_NOMSGSIGN)
+               seq_puts(m, "nocephx_sign_messages,");
        if ((opt->flags & CEPH_OPT_TCP_NODELAY) == 0)
                seq_puts(m, "notcp_nodelay,");
 
@@ -596,11 +608,7 @@ struct ceph_client *ceph_create_client(struct ceph_options *opt, void *private,
        if (ceph_test_opt(client, MYIP))
                myaddr = &client->options->my_addr;
 
-       ceph_messenger_init(&client->msgr, myaddr,
-               client->supported_features,
-               client->required_features,
-               ceph_test_opt(client, NOCRC),
-               ceph_test_opt(client, TCP_NODELAY));
+       ceph_messenger_init(&client->msgr, myaddr);
 
        /* subsystems */
        err = ceph_monc_init(&client->monc, client);
index d1498224c49d4c6c18e082ea908cb3e5a8fed30c..2e9cab09f37ba65c9c5961c12e10d2aded02413f 100644 (file)
@@ -16,8 +16,10 @@ struct ceph_crypto_key {
 
 static inline void ceph_crypto_key_destroy(struct ceph_crypto_key *key)
 {
-       if (key)
+       if (key) {
                kfree(key->key);
+               key->key = NULL;
+       }
 }
 
 int ceph_crypto_key_clone(struct ceph_crypto_key *dst,
index b9b0e3b5da49f84d9fb1775e75aca83f55e80b2d..9981039ef4ffcca29081b83a5e06a81ce6871f20 100644 (file)
@@ -509,7 +509,7 @@ static int ceph_tcp_connect(struct ceph_connection *con)
                return ret;
        }
 
-       if (con->msgr->tcp_nodelay) {
+       if (ceph_test_opt(from_msgr(con->msgr), TCP_NODELAY)) {
                int optval = 1;
 
                ret = kernel_setsockopt(sock, SOL_TCP, TCP_NODELAY,
@@ -637,9 +637,6 @@ static int con_close_socket(struct ceph_connection *con)
 static void ceph_msg_remove(struct ceph_msg *msg)
 {
        list_del_init(&msg->list_head);
-       BUG_ON(msg->con == NULL);
-       msg->con->ops->put(msg->con);
-       msg->con = NULL;
 
        ceph_msg_put(msg);
 }
@@ -662,15 +659,14 @@ static void reset_connection(struct ceph_connection *con)
 
        if (con->in_msg) {
                BUG_ON(con->in_msg->con != con);
-               con->in_msg->con = NULL;
                ceph_msg_put(con->in_msg);
                con->in_msg = NULL;
-               con->ops->put(con);
        }
 
        con->connect_seq = 0;
        con->out_seq = 0;
        if (con->out_msg) {
+               BUG_ON(con->out_msg->con != con);
                ceph_msg_put(con->out_msg);
                con->out_msg = NULL;
        }
@@ -1205,7 +1201,7 @@ static void prepare_write_message_footer(struct ceph_connection *con)
        con->out_kvec[v].iov_base = &m->footer;
        if (con->peer_features & CEPH_FEATURE_MSG_AUTH) {
                if (con->ops->sign_message)
-                       con->ops->sign_message(con, m);
+                       con->ops->sign_message(m);
                else
                        m->footer.sig = 0;
                con->out_kvec[v].iov_len = sizeof(m->footer);
@@ -1432,7 +1428,8 @@ static int prepare_write_connect(struct ceph_connection *con)
        dout("prepare_write_connect %p cseq=%d gseq=%d proto=%d\n", con,
             con->connect_seq, global_seq, proto);
 
-       con->out_connect.features = cpu_to_le64(con->msgr->supported_features);
+       con->out_connect.features =
+           cpu_to_le64(from_msgr(con->msgr)->supported_features);
        con->out_connect.host_type = cpu_to_le32(CEPH_ENTITY_TYPE_CLIENT);
        con->out_connect.connect_seq = cpu_to_le32(con->connect_seq);
        con->out_connect.global_seq = cpu_to_le32(global_seq);
@@ -1527,7 +1524,7 @@ static int write_partial_message_data(struct ceph_connection *con)
 {
        struct ceph_msg *msg = con->out_msg;
        struct ceph_msg_data_cursor *cursor = &msg->cursor;
-       bool do_datacrc = !con->msgr->nocrc;
+       bool do_datacrc = !ceph_test_opt(from_msgr(con->msgr), NOCRC);
        u32 crc;
 
        dout("%s %p msg %p\n", __func__, con, msg);
@@ -1552,8 +1549,8 @@ static int write_partial_message_data(struct ceph_connection *con)
                bool need_crc;
                int ret;
 
-               page = ceph_msg_data_next(&msg->cursor, &page_offset, &length,
-                                                       &last_piece);
+               page = ceph_msg_data_next(cursor, &page_offset, &length,
+                                         &last_piece);
                ret = ceph_tcp_sendpage(con->sock, page, page_offset,
                                        length, !last_piece);
                if (ret <= 0) {
@@ -1564,7 +1561,7 @@ static int write_partial_message_data(struct ceph_connection *con)
                }
                if (do_datacrc && cursor->need_crc)
                        crc = ceph_crc32c_page(crc, page, page_offset, length);
-               need_crc = ceph_msg_data_advance(&msg->cursor, (size_t)ret);
+               need_crc = ceph_msg_data_advance(cursor, (size_t)ret);
        }
 
        dout("%s %p msg %p done\n", __func__, con, msg);
@@ -2005,8 +2002,8 @@ static int process_banner(struct ceph_connection *con)
 
 static int process_connect(struct ceph_connection *con)
 {
-       u64 sup_feat = con->msgr->supported_features;
-       u64 req_feat = con->msgr->required_features;
+       u64 sup_feat = from_msgr(con->msgr)->supported_features;
+       u64 req_feat = from_msgr(con->msgr)->required_features;
        u64 server_feat = ceph_sanitize_features(
                                le64_to_cpu(con->in_reply.features));
        int ret;
@@ -2232,7 +2229,7 @@ static int read_partial_msg_data(struct ceph_connection *con)
 {
        struct ceph_msg *msg = con->in_msg;
        struct ceph_msg_data_cursor *cursor = &msg->cursor;
-       const bool do_datacrc = !con->msgr->nocrc;
+       bool do_datacrc = !ceph_test_opt(from_msgr(con->msgr), NOCRC);
        struct page *page;
        size_t page_offset;
        size_t length;
@@ -2246,8 +2243,7 @@ static int read_partial_msg_data(struct ceph_connection *con)
        if (do_datacrc)
                crc = con->in_data_crc;
        while (cursor->resid) {
-               page = ceph_msg_data_next(&msg->cursor, &page_offset, &length,
-                                                       NULL);
+               page = ceph_msg_data_next(cursor, &page_offset, &length, NULL);
                ret = ceph_tcp_recvpage(con->sock, page, page_offset, length);
                if (ret <= 0) {
                        if (do_datacrc)
@@ -2258,7 +2254,7 @@ static int read_partial_msg_data(struct ceph_connection *con)
 
                if (do_datacrc)
                        crc = ceph_crc32c_page(crc, page, page_offset, ret);
-               (void) ceph_msg_data_advance(&msg->cursor, (size_t)ret);
+               (void) ceph_msg_data_advance(cursor, (size_t)ret);
        }
        if (do_datacrc)
                con->in_data_crc = crc;
@@ -2278,7 +2274,7 @@ static int read_partial_message(struct ceph_connection *con)
        int end;
        int ret;
        unsigned int front_len, middle_len, data_len;
-       bool do_datacrc = !con->msgr->nocrc;
+       bool do_datacrc = !ceph_test_opt(from_msgr(con->msgr), NOCRC);
        bool need_sign = (con->peer_features & CEPH_FEATURE_MSG_AUTH);
        u64 seq;
        u32 crc;
@@ -2423,7 +2419,7 @@ static int read_partial_message(struct ceph_connection *con)
        }
 
        if (need_sign && con->ops->check_message_signature &&
-           con->ops->check_message_signature(con, m)) {
+           con->ops->check_message_signature(m)) {
                pr_err("read_partial_message %p signature check failed\n", m);
                return -EBADMSG;
        }
@@ -2438,13 +2434,10 @@ static int read_partial_message(struct ceph_connection *con)
  */
 static void process_message(struct ceph_connection *con)
 {
-       struct ceph_msg *msg;
+       struct ceph_msg *msg = con->in_msg;
 
        BUG_ON(con->in_msg->con != con);
-       con->in_msg->con = NULL;
-       msg = con->in_msg;
        con->in_msg = NULL;
-       con->ops->put(con);
 
        /* if first message, set peer_name */
        if (con->peer_name.type == 0)
@@ -2677,7 +2670,7 @@ more:
                if (ret <= 0) {
                        switch (ret) {
                        case -EBADMSG:
-                               con->error_msg = "bad crc";
+                               con->error_msg = "bad crc/signature";
                                /* fall through */
                        case -EBADE:
                                ret = -EIO;
@@ -2918,10 +2911,8 @@ static void con_fault(struct ceph_connection *con)
 
        if (con->in_msg) {
                BUG_ON(con->in_msg->con != con);
-               con->in_msg->con = NULL;
                ceph_msg_put(con->in_msg);
                con->in_msg = NULL;
-               con->ops->put(con);
        }
 
        /* Requeue anything that hasn't been acked */
@@ -2952,15 +2943,8 @@ static void con_fault(struct ceph_connection *con)
  * initialize a new messenger instance
  */
 void ceph_messenger_init(struct ceph_messenger *msgr,
-                       struct ceph_entity_addr *myaddr,
-                       u64 supported_features,
-                       u64 required_features,
-                       bool nocrc,
-                       bool tcp_nodelay)
+                        struct ceph_entity_addr *myaddr)
 {
-       msgr->supported_features = supported_features;
-       msgr->required_features = required_features;
-
        spin_lock_init(&msgr->global_seq_lock);
 
        if (myaddr)
@@ -2970,8 +2954,6 @@ void ceph_messenger_init(struct ceph_messenger *msgr,
        msgr->inst.addr.type = 0;
        get_random_bytes(&msgr->inst.addr.nonce, sizeof(msgr->inst.addr.nonce));
        encode_my_addr(msgr);
-       msgr->nocrc = nocrc;
-       msgr->tcp_nodelay = tcp_nodelay;
 
        atomic_set(&msgr->stopping, 0);
        write_pnet(&msgr->net, get_net(current->nsproxy->net_ns));
@@ -2986,6 +2968,15 @@ void ceph_messenger_fini(struct ceph_messenger *msgr)
 }
 EXPORT_SYMBOL(ceph_messenger_fini);
 
+static void msg_con_set(struct ceph_msg *msg, struct ceph_connection *con)
+{
+       if (msg->con)
+               msg->con->ops->put(msg->con);
+
+       msg->con = con ? con->ops->get(con) : NULL;
+       BUG_ON(msg->con != con);
+}
+
 static void clear_standby(struct ceph_connection *con)
 {
        /* come back from STANDBY? */
@@ -3017,9 +3008,7 @@ void ceph_con_send(struct ceph_connection *con, struct ceph_msg *msg)
                return;
        }
 
-       BUG_ON(msg->con != NULL);
-       msg->con = con->ops->get(con);
-       BUG_ON(msg->con == NULL);
+       msg_con_set(msg, con);
 
        BUG_ON(!list_empty(&msg->list_head));
        list_add_tail(&msg->list_head, &con->out_queue);
@@ -3047,16 +3036,15 @@ void ceph_msg_revoke(struct ceph_msg *msg)
 {
        struct ceph_connection *con = msg->con;
 
-       if (!con)
+       if (!con) {
+               dout("%s msg %p null con\n", __func__, msg);
                return;         /* Message not in our possession */
+       }
 
        mutex_lock(&con->mutex);
        if (!list_empty(&msg->list_head)) {
                dout("%s %p msg %p - was on queue\n", __func__, con, msg);
                list_del_init(&msg->list_head);
-               BUG_ON(msg->con == NULL);
-               msg->con->ops->put(msg->con);
-               msg->con = NULL;
                msg->hdr.seq = 0;
 
                ceph_msg_put(msg);
@@ -3080,16 +3068,13 @@ void ceph_msg_revoke(struct ceph_msg *msg)
  */
 void ceph_msg_revoke_incoming(struct ceph_msg *msg)
 {
-       struct ceph_connection *con;
+       struct ceph_connection *con = msg->con;
 
-       BUG_ON(msg == NULL);
-       if (!msg->con) {
+       if (!con) {
                dout("%s msg %p null con\n", __func__, msg);
-
                return;         /* Message not in our possession */
        }
 
-       con = msg->con;
        mutex_lock(&con->mutex);
        if (con->in_msg == msg) {
                unsigned int front_len = le32_to_cpu(con->in_hdr.front_len);
@@ -3335,9 +3320,8 @@ static int ceph_con_in_msg_alloc(struct ceph_connection *con, int *skip)
        }
        if (msg) {
                BUG_ON(*skip);
+               msg_con_set(msg, con);
                con->in_msg = msg;
-               con->in_msg->con = con->ops->get(con);
-               BUG_ON(con->in_msg->con == NULL);
        } else {
                /*
                 * Null message pointer means either we should skip
@@ -3384,6 +3368,8 @@ static void ceph_msg_release(struct kref *kref)
        dout("%s %p\n", __func__, m);
        WARN_ON(!list_empty(&m->list_head));
 
+       msg_con_set(m, NULL);
+
        /* drop middle, data, if any */
        if (m->middle) {
                ceph_buffer_put(m->middle);
index f79ccac6699fb7b171b680261db9000f7fe4c70c..f8f235930d887adf1df94314b18c719638328df0 100644 (file)
@@ -120,11 +120,13 @@ static void ceph_osd_data_bio_init(struct ceph_osd_data *osd_data,
 }
 #endif /* CONFIG_BLOCK */
 
-#define osd_req_op_data(oreq, whch, typ, fld)  \
-       ({                                              \
-               BUG_ON(whch >= (oreq)->r_num_ops);      \
-               &(oreq)->r_ops[whch].typ.fld;           \
-       })
+#define osd_req_op_data(oreq, whch, typ, fld)                          \
+({                                                                     \
+       struct ceph_osd_request *__oreq = (oreq);                       \
+       unsigned int __whch = (whch);                                   \
+       BUG_ON(__whch >= __oreq->r_num_ops);                            \
+       &__oreq->r_ops[__whch].typ.fld;                                 \
+})
 
 static struct ceph_osd_data *
 osd_req_op_raw_data_in(struct ceph_osd_request *osd_req, unsigned int which)
@@ -1750,8 +1752,7 @@ static void complete_request(struct ceph_osd_request *req)
  * handle osd op reply.  either call the callback if it is specified,
  * or do the completion to wake up the waiting thread.
  */
-static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg,
-                        struct ceph_connection *con)
+static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg)
 {
        void *p, *end;
        struct ceph_osd_request *req;
@@ -2807,7 +2808,7 @@ static void dispatch(struct ceph_connection *con, struct ceph_msg *msg)
                ceph_osdc_handle_map(osdc, msg);
                break;
        case CEPH_MSG_OSD_OPREPLY:
-               handle_reply(osdc, msg, con);
+               handle_reply(osdc, msg);
                break;
        case CEPH_MSG_WATCH_NOTIFY:
                handle_watch_notify(osdc, msg);
@@ -2849,9 +2850,6 @@ static struct ceph_msg *get_reply(struct ceph_connection *con,
                goto out;
        }
 
-       if (req->r_reply->con)
-               dout("%s revoking msg %p from old con %p\n", __func__,
-                    req->r_reply, req->r_reply->con);
        ceph_msg_revoke_incoming(req->r_reply);
 
        if (front_len > req->r_reply->front_alloc_len) {
@@ -2978,17 +2976,19 @@ static int invalidate_authorizer(struct ceph_connection *con)
        return ceph_monc_validate_auth(&osdc->client->monc);
 }
 
-static int sign_message(struct ceph_connection *con, struct ceph_msg *msg)
+static int osd_sign_message(struct ceph_msg *msg)
 {
-       struct ceph_osd *o = con->private;
+       struct ceph_osd *o = msg->con->private;
        struct ceph_auth_handshake *auth = &o->o_auth;
+
        return ceph_auth_sign_message(auth, msg);
 }
 
-static int check_message_signature(struct ceph_connection *con, struct ceph_msg *msg)
+static int osd_check_message_signature(struct ceph_msg *msg)
 {
-       struct ceph_osd *o = con->private;
+       struct ceph_osd *o = msg->con->private;
        struct ceph_auth_handshake *auth = &o->o_auth;
+
        return ceph_auth_check_message_signature(auth, msg);
 }
 
@@ -3000,7 +3000,7 @@ static const struct ceph_connection_operations osd_con_ops = {
        .verify_authorizer_reply = verify_authorizer_reply,
        .invalidate_authorizer = invalidate_authorizer,
        .alloc_msg = alloc_msg,
-       .sign_message = sign_message,
-       .check_message_signature = check_message_signature,
+       .sign_message = osd_sign_message,
+       .check_message_signature = osd_check_message_signature,
        .fault = osd_reset,
 };
index 5dbc86ea6b580e851f80bcdef68da80bc64b2cd2..ae00b894e67555257b1ba81dd57cecec72eed161 100644 (file)
@@ -6436,7 +6436,10 @@ int __netdev_update_features(struct net_device *dev)
                netdev_err(dev,
                        "set_features() failed (%d); wanted %pNF, left %pNF\n",
                        err, &features, &dev->features);
-               return 0;
+               /* return non-0 since some features might have changed and
+                * it's better to fire a spurious notification than miss it
+                */
+               return -1;
        }
 
 sync_lower:
index 1aa8437ed6c4437d196ad513f0d3619198914416..e6af42da28d9552643751a1af7dfcd96cad05c3d 100644 (file)
@@ -857,7 +857,7 @@ static void neigh_probe(struct neighbour *neigh)
        struct sk_buff *skb = skb_peek_tail(&neigh->arp_queue);
        /* keep skb alive even if arp_queue overflows */
        if (skb)
-               skb = skb_copy(skb, GFP_ATOMIC);
+               skb = skb_clone(skb, GFP_ATOMIC);
        write_unlock(&neigh->lock);
        neigh->ops->solicit(neigh, skb);
        atomic_inc(&neigh->probes);
index 504bd17b7456c3a16a0832ed28ede040c41ff316..34ba7a08876de74409ea5d2ad3af6f78124ff0a7 100644 (file)
@@ -1045,15 +1045,156 @@ static int rtnl_phys_switch_id_fill(struct sk_buff *skb, struct net_device *dev)
        return 0;
 }
 
+static noinline_for_stack int rtnl_fill_stats(struct sk_buff *skb,
+                                             struct net_device *dev)
+{
+       const struct rtnl_link_stats64 *stats;
+       struct rtnl_link_stats64 temp;
+       struct nlattr *attr;
+
+       stats = dev_get_stats(dev, &temp);
+
+       attr = nla_reserve(skb, IFLA_STATS,
+                          sizeof(struct rtnl_link_stats));
+       if (!attr)
+               return -EMSGSIZE;
+
+       copy_rtnl_link_stats(nla_data(attr), stats);
+
+       attr = nla_reserve(skb, IFLA_STATS64,
+                          sizeof(struct rtnl_link_stats64));
+       if (!attr)
+               return -EMSGSIZE;
+
+       copy_rtnl_link_stats64(nla_data(attr), stats);
+
+       return 0;
+}
+
+static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb,
+                                              struct net_device *dev,
+                                              int vfs_num,
+                                              struct nlattr *vfinfo)
+{
+       struct ifla_vf_rss_query_en vf_rss_query_en;
+       struct ifla_vf_link_state vf_linkstate;
+       struct ifla_vf_spoofchk vf_spoofchk;
+       struct ifla_vf_tx_rate vf_tx_rate;
+       struct ifla_vf_stats vf_stats;
+       struct ifla_vf_trust vf_trust;
+       struct ifla_vf_vlan vf_vlan;
+       struct ifla_vf_rate vf_rate;
+       struct nlattr *vf, *vfstats;
+       struct ifla_vf_mac vf_mac;
+       struct ifla_vf_info ivi;
+
+       /* Not all SR-IOV capable drivers support the
+        * spoofcheck and "RSS query enable" query.  Preset to
+        * -1 so the user space tool can detect that the driver
+        * didn't report anything.
+        */
+       ivi.spoofchk = -1;
+       ivi.rss_query_en = -1;
+       ivi.trusted = -1;
+       memset(ivi.mac, 0, sizeof(ivi.mac));
+       /* The default value for VF link state is "auto"
+        * IFLA_VF_LINK_STATE_AUTO which equals zero
+        */
+       ivi.linkstate = 0;
+       if (dev->netdev_ops->ndo_get_vf_config(dev, vfs_num, &ivi))
+               return 0;
+
+       vf_mac.vf =
+               vf_vlan.vf =
+               vf_rate.vf =
+               vf_tx_rate.vf =
+               vf_spoofchk.vf =
+               vf_linkstate.vf =
+               vf_rss_query_en.vf =
+               vf_trust.vf = ivi.vf;
+
+       memcpy(vf_mac.mac, ivi.mac, sizeof(ivi.mac));
+       vf_vlan.vlan = ivi.vlan;
+       vf_vlan.qos = ivi.qos;
+       vf_tx_rate.rate = ivi.max_tx_rate;
+       vf_rate.min_tx_rate = ivi.min_tx_rate;
+       vf_rate.max_tx_rate = ivi.max_tx_rate;
+       vf_spoofchk.setting = ivi.spoofchk;
+       vf_linkstate.link_state = ivi.linkstate;
+       vf_rss_query_en.setting = ivi.rss_query_en;
+       vf_trust.setting = ivi.trusted;
+       vf = nla_nest_start(skb, IFLA_VF_INFO);
+       if (!vf) {
+               nla_nest_cancel(skb, vfinfo);
+               return -EMSGSIZE;
+       }
+       if (nla_put(skb, IFLA_VF_MAC, sizeof(vf_mac), &vf_mac) ||
+           nla_put(skb, IFLA_VF_VLAN, sizeof(vf_vlan), &vf_vlan) ||
+           nla_put(skb, IFLA_VF_RATE, sizeof(vf_rate),
+                   &vf_rate) ||
+           nla_put(skb, IFLA_VF_TX_RATE, sizeof(vf_tx_rate),
+                   &vf_tx_rate) ||
+           nla_put(skb, IFLA_VF_SPOOFCHK, sizeof(vf_spoofchk),
+                   &vf_spoofchk) ||
+           nla_put(skb, IFLA_VF_LINK_STATE, sizeof(vf_linkstate),
+                   &vf_linkstate) ||
+           nla_put(skb, IFLA_VF_RSS_QUERY_EN,
+                   sizeof(vf_rss_query_en),
+                   &vf_rss_query_en) ||
+           nla_put(skb, IFLA_VF_TRUST,
+                   sizeof(vf_trust), &vf_trust))
+               return -EMSGSIZE;
+       memset(&vf_stats, 0, sizeof(vf_stats));
+       if (dev->netdev_ops->ndo_get_vf_stats)
+               dev->netdev_ops->ndo_get_vf_stats(dev, vfs_num,
+                                               &vf_stats);
+       vfstats = nla_nest_start(skb, IFLA_VF_STATS);
+       if (!vfstats) {
+               nla_nest_cancel(skb, vf);
+               nla_nest_cancel(skb, vfinfo);
+               return -EMSGSIZE;
+       }
+       if (nla_put_u64(skb, IFLA_VF_STATS_RX_PACKETS,
+                       vf_stats.rx_packets) ||
+           nla_put_u64(skb, IFLA_VF_STATS_TX_PACKETS,
+                       vf_stats.tx_packets) ||
+           nla_put_u64(skb, IFLA_VF_STATS_RX_BYTES,
+                       vf_stats.rx_bytes) ||
+           nla_put_u64(skb, IFLA_VF_STATS_TX_BYTES,
+                       vf_stats.tx_bytes) ||
+           nla_put_u64(skb, IFLA_VF_STATS_BROADCAST,
+                       vf_stats.broadcast) ||
+           nla_put_u64(skb, IFLA_VF_STATS_MULTICAST,
+                       vf_stats.multicast))
+               return -EMSGSIZE;
+       nla_nest_end(skb, vfstats);
+       nla_nest_end(skb, vf);
+       return 0;
+}
+
+static int rtnl_fill_link_ifmap(struct sk_buff *skb, struct net_device *dev)
+{
+       struct rtnl_link_ifmap map = {
+               .mem_start   = dev->mem_start,
+               .mem_end     = dev->mem_end,
+               .base_addr   = dev->base_addr,
+               .irq         = dev->irq,
+               .dma         = dev->dma,
+               .port        = dev->if_port,
+       };
+       if (nla_put(skb, IFLA_MAP, sizeof(map), &map))
+               return -EMSGSIZE;
+
+       return 0;
+}
+
 static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
                            int type, u32 pid, u32 seq, u32 change,
                            unsigned int flags, u32 ext_filter_mask)
 {
        struct ifinfomsg *ifm;
        struct nlmsghdr *nlh;
-       struct rtnl_link_stats64 temp;
-       const struct rtnl_link_stats64 *stats;
-       struct nlattr *attr, *af_spec;
+       struct nlattr *af_spec;
        struct rtnl_af_ops *af_ops;
        struct net_device *upper_dev = netdev_master_upper_dev_get(dev);
 
@@ -1096,18 +1237,8 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
            nla_put_u8(skb, IFLA_PROTO_DOWN, dev->proto_down))
                goto nla_put_failure;
 
-       if (1) {
-               struct rtnl_link_ifmap map = {
-                       .mem_start   = dev->mem_start,
-                       .mem_end     = dev->mem_end,
-                       .base_addr   = dev->base_addr,
-                       .irq         = dev->irq,
-                       .dma         = dev->dma,
-                       .port        = dev->if_port,
-               };
-               if (nla_put(skb, IFLA_MAP, sizeof(map), &map))
-                       goto nla_put_failure;
-       }
+       if (rtnl_fill_link_ifmap(skb, dev))
+               goto nla_put_failure;
 
        if (dev->addr_len) {
                if (nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr) ||
@@ -1124,128 +1255,27 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
        if (rtnl_phys_switch_id_fill(skb, dev))
                goto nla_put_failure;
 
-       attr = nla_reserve(skb, IFLA_STATS,
-                       sizeof(struct rtnl_link_stats));
-       if (attr == NULL)
-               goto nla_put_failure;
-
-       stats = dev_get_stats(dev, &temp);
-       copy_rtnl_link_stats(nla_data(attr), stats);
-
-       attr = nla_reserve(skb, IFLA_STATS64,
-                       sizeof(struct rtnl_link_stats64));
-       if (attr == NULL)
+       if (rtnl_fill_stats(skb, dev))
                goto nla_put_failure;
-       copy_rtnl_link_stats64(nla_data(attr), stats);
 
        if (dev->dev.parent && (ext_filter_mask & RTEXT_FILTER_VF) &&
            nla_put_u32(skb, IFLA_NUM_VF, dev_num_vf(dev->dev.parent)))
                goto nla_put_failure;
 
-       if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent
-           && (ext_filter_mask & RTEXT_FILTER_VF)) {
+       if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent &&
+           ext_filter_mask & RTEXT_FILTER_VF) {
                int i;
-
-               struct nlattr *vfinfo, *vf, *vfstats;
+               struct nlattr *vfinfo;
                int num_vfs = dev_num_vf(dev->dev.parent);
 
                vfinfo = nla_nest_start(skb, IFLA_VFINFO_LIST);
                if (!vfinfo)
                        goto nla_put_failure;
                for (i = 0; i < num_vfs; i++) {
-                       struct ifla_vf_info ivi;
-                       struct ifla_vf_mac vf_mac;
-                       struct ifla_vf_vlan vf_vlan;
-                       struct ifla_vf_rate vf_rate;
-                       struct ifla_vf_tx_rate vf_tx_rate;
-                       struct ifla_vf_spoofchk vf_spoofchk;
-                       struct ifla_vf_link_state vf_linkstate;
-                       struct ifla_vf_rss_query_en vf_rss_query_en;
-                       struct ifla_vf_stats vf_stats;
-                       struct ifla_vf_trust vf_trust;
-
-                       /*
-                        * Not all SR-IOV capable drivers support the
-                        * spoofcheck and "RSS query enable" query.  Preset to
-                        * -1 so the user space tool can detect that the driver
-                        * didn't report anything.
-                        */
-                       ivi.spoofchk = -1;
-                       ivi.rss_query_en = -1;
-                       ivi.trusted = -1;
-                       memset(ivi.mac, 0, sizeof(ivi.mac));
-                       /* The default value for VF link state is "auto"
-                        * IFLA_VF_LINK_STATE_AUTO which equals zero
-                        */
-                       ivi.linkstate = 0;
-                       if (dev->netdev_ops->ndo_get_vf_config(dev, i, &ivi))
-                               break;
-                       vf_mac.vf =
-                               vf_vlan.vf =
-                               vf_rate.vf =
-                               vf_tx_rate.vf =
-                               vf_spoofchk.vf =
-                               vf_linkstate.vf =
-                               vf_rss_query_en.vf =
-                               vf_trust.vf = ivi.vf;
-
-                       memcpy(vf_mac.mac, ivi.mac, sizeof(ivi.mac));
-                       vf_vlan.vlan = ivi.vlan;
-                       vf_vlan.qos = ivi.qos;
-                       vf_tx_rate.rate = ivi.max_tx_rate;
-                       vf_rate.min_tx_rate = ivi.min_tx_rate;
-                       vf_rate.max_tx_rate = ivi.max_tx_rate;
-                       vf_spoofchk.setting = ivi.spoofchk;
-                       vf_linkstate.link_state = ivi.linkstate;
-                       vf_rss_query_en.setting = ivi.rss_query_en;
-                       vf_trust.setting = ivi.trusted;
-                       vf = nla_nest_start(skb, IFLA_VF_INFO);
-                       if (!vf) {
-                               nla_nest_cancel(skb, vfinfo);
-                               goto nla_put_failure;
-                       }
-                       if (nla_put(skb, IFLA_VF_MAC, sizeof(vf_mac), &vf_mac) ||
-                           nla_put(skb, IFLA_VF_VLAN, sizeof(vf_vlan), &vf_vlan) ||
-                           nla_put(skb, IFLA_VF_RATE, sizeof(vf_rate),
-                                   &vf_rate) ||
-                           nla_put(skb, IFLA_VF_TX_RATE, sizeof(vf_tx_rate),
-                                   &vf_tx_rate) ||
-                           nla_put(skb, IFLA_VF_SPOOFCHK, sizeof(vf_spoofchk),
-                                   &vf_spoofchk) ||
-                           nla_put(skb, IFLA_VF_LINK_STATE, sizeof(vf_linkstate),
-                                   &vf_linkstate) ||
-                           nla_put(skb, IFLA_VF_RSS_QUERY_EN,
-                                   sizeof(vf_rss_query_en),
-                                   &vf_rss_query_en) ||
-                           nla_put(skb, IFLA_VF_TRUST,
-                                   sizeof(vf_trust), &vf_trust))
+                       if (rtnl_fill_vfinfo(skb, dev, i, vfinfo))
                                goto nla_put_failure;
-                       memset(&vf_stats, 0, sizeof(vf_stats));
-                       if (dev->netdev_ops->ndo_get_vf_stats)
-                               dev->netdev_ops->ndo_get_vf_stats(dev, i,
-                                                                 &vf_stats);
-                       vfstats = nla_nest_start(skb, IFLA_VF_STATS);
-                       if (!vfstats) {
-                               nla_nest_cancel(skb, vf);
-                               nla_nest_cancel(skb, vfinfo);
-                               goto nla_put_failure;
-                       }
-                       if (nla_put_u64(skb, IFLA_VF_STATS_RX_PACKETS,
-                                       vf_stats.rx_packets) ||
-                           nla_put_u64(skb, IFLA_VF_STATS_TX_PACKETS,
-                                       vf_stats.tx_packets) ||
-                           nla_put_u64(skb, IFLA_VF_STATS_RX_BYTES,
-                                       vf_stats.rx_bytes) ||
-                           nla_put_u64(skb, IFLA_VF_STATS_TX_BYTES,
-                                       vf_stats.tx_bytes) ||
-                           nla_put_u64(skb, IFLA_VF_STATS_BROADCAST,
-                                       vf_stats.broadcast) ||
-                           nla_put_u64(skb, IFLA_VF_STATS_MULTICAST,
-                                       vf_stats.multicast))
-                               goto nla_put_failure;
-                       nla_nest_end(skb, vfstats);
-                       nla_nest_end(skb, vf);
                }
+
                nla_nest_end(skb, vfinfo);
        }
 
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 aa41e6dd642913f2181832145e22ec1dad6fa7b8..152b9c70e25255f1c104c00db3867fd6b21bfa99 100644 (file)
@@ -4268,7 +4268,8 @@ static struct sk_buff *skb_reorder_vlan_header(struct sk_buff *skb)
                return NULL;
        }
 
-       memmove(skb->data - ETH_HLEN, skb->data - VLAN_ETH_HLEN, 2 * ETH_ALEN);
+       memmove(skb->data - ETH_HLEN, skb->data - skb->mac_len,
+               2 * ETH_ALEN);
        skb->mac_header += VLAN_HLEN;
        return skb;
 }
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 fdd88c3803a673881053039cdc8ff44bc1b8aa4a..a4a0b6b3bcf2a653ec75436e2a7a086c7a5bbe70 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)
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 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 242bce1cf0f3a66b1806469ab3e733363638cbf2..1cf928fb573e6769a4070327baa74adb300cde7e 100644 (file)
@@ -4109,7 +4109,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
                err = -EINVAL;
                if (unlikely((int)req->tp_block_size <= 0))
                        goto out;
-               if (unlikely(req->tp_block_size & (PAGE_SIZE - 1)))
+               if (unlikely(!PAGE_ALIGNED(req->tp_block_size)))
                        goto out;
                if (po->tp_version >= TPACKET_V3 &&
                    (int)(req->tp_block_size -
@@ -4121,8 +4121,8 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
                if (unlikely(req->tp_frame_size & (TPACKET_ALIGNMENT - 1)))
                        goto out;
 
-               rb->frames_per_block = req->tp_block_size/req->tp_frame_size;
-               if (unlikely(rb->frames_per_block <= 0))
+               rb->frames_per_block = req->tp_block_size / req->tp_frame_size;
+               if (unlikely(rb->frames_per_block == 0))
                        goto out;
                if (unlikely((rb->frames_per_block * req->tp_block_nr) !=
                                        req->tp_frame_nr))
index dace13d7638ee885729390838c97788721b75fc9..799e65b944b9019cf7eee177f90f6d67a0fb66dd 100644 (file)
@@ -1411,17 +1411,16 @@ gss_key_timeout(struct rpc_cred *rc)
 {
        struct gss_cred *gss_cred = container_of(rc, struct gss_cred, gc_base);
        struct gss_cl_ctx *ctx;
-       unsigned long now = jiffies;
-       unsigned long expire;
+       unsigned long timeout = jiffies + (gss_key_expire_timeo * HZ);
+       int ret = 0;
 
        rcu_read_lock();
        ctx = rcu_dereference(gss_cred->gc_ctx);
-       if (ctx)
-               expire = ctx->gc_expiry - (gss_key_expire_timeo * HZ);
+       if (!ctx || time_after(timeout, ctx->gc_expiry))
+               ret = -EACCES;
        rcu_read_unlock();
-       if (!ctx || time_after(now, expire))
-               return -EACCES;
-       return 0;
+
+       return ret;
 }
 
 static int
index 4a2340a5440115dd4b758d4490793306b2bb4641..5e4f815c2b34d22fba11ac2443e9d66bc27c779c 100644 (file)
 static bool cache_defer_req(struct cache_req *req, struct cache_head *item);
 static void cache_revisit_request(struct cache_head *item);
 
-static void cache_init(struct cache_head *h)
+static void cache_init(struct cache_head *h, struct cache_detail *detail)
 {
        time_t now = seconds_since_boot();
        INIT_HLIST_NODE(&h->cache_list);
        h->flags = 0;
        kref_init(&h->ref);
        h->expiry_time = now + CACHE_NEW_EXPIRY;
+       if (now <= detail->flush_time)
+               /* ensure it isn't already expired */
+               now = detail->flush_time + 1;
        h->last_refresh = now;
 }
 
@@ -81,7 +84,7 @@ struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail,
         * we might get lose if we need to
         * cache_put it soon.
         */
-       cache_init(new);
+       cache_init(new, detail);
        detail->init(new, key);
 
        write_lock(&detail->hash_lock);
@@ -116,10 +119,15 @@ EXPORT_SYMBOL_GPL(sunrpc_cache_lookup);
 
 static void cache_dequeue(struct cache_detail *detail, struct cache_head *ch);
 
-static void cache_fresh_locked(struct cache_head *head, time_t expiry)
+static void cache_fresh_locked(struct cache_head *head, time_t expiry,
+                              struct cache_detail *detail)
 {
+       time_t now = seconds_since_boot();
+       if (now <= detail->flush_time)
+               /* ensure it isn't immediately treated as expired */
+               now = detail->flush_time + 1;
        head->expiry_time = expiry;
-       head->last_refresh = seconds_since_boot();
+       head->last_refresh = now;
        smp_wmb(); /* paired with smp_rmb() in cache_is_valid() */
        set_bit(CACHE_VALID, &head->flags);
 }
@@ -149,7 +157,7 @@ struct cache_head *sunrpc_cache_update(struct cache_detail *detail,
                                set_bit(CACHE_NEGATIVE, &old->flags);
                        else
                                detail->update(old, new);
-                       cache_fresh_locked(old, new->expiry_time);
+                       cache_fresh_locked(old, new->expiry_time, detail);
                        write_unlock(&detail->hash_lock);
                        cache_fresh_unlocked(old, detail);
                        return old;
@@ -162,7 +170,7 @@ struct cache_head *sunrpc_cache_update(struct cache_detail *detail,
                cache_put(old, detail);
                return NULL;
        }
-       cache_init(tmp);
+       cache_init(tmp, detail);
        detail->init(tmp, old);
 
        write_lock(&detail->hash_lock);
@@ -173,8 +181,8 @@ struct cache_head *sunrpc_cache_update(struct cache_detail *detail,
        hlist_add_head(&tmp->cache_list, &detail->hash_table[hash]);
        detail->entries++;
        cache_get(tmp);
-       cache_fresh_locked(tmp, new->expiry_time);
-       cache_fresh_locked(old, 0);
+       cache_fresh_locked(tmp, new->expiry_time, detail);
+       cache_fresh_locked(old, 0, detail);
        write_unlock(&detail->hash_lock);
        cache_fresh_unlocked(tmp, detail);
        cache_fresh_unlocked(old, detail);
@@ -219,7 +227,8 @@ static int try_to_negate_entry(struct cache_detail *detail, struct cache_head *h
        rv = cache_is_valid(h);
        if (rv == -EAGAIN) {
                set_bit(CACHE_NEGATIVE, &h->flags);
-               cache_fresh_locked(h, seconds_since_boot()+CACHE_NEW_EXPIRY);
+               cache_fresh_locked(h, seconds_since_boot()+CACHE_NEW_EXPIRY,
+                                  detail);
                rv = -ENOENT;
        }
        write_unlock(&detail->hash_lock);
@@ -487,10 +496,13 @@ EXPORT_SYMBOL_GPL(cache_flush);
 
 void cache_purge(struct cache_detail *detail)
 {
-       detail->flush_time = LONG_MAX;
+       time_t now = seconds_since_boot();
+       if (detail->flush_time >= now)
+               now = detail->flush_time + 1;
+       /* 'now' is the maximum value any 'last_refresh' can have */
+       detail->flush_time = now;
        detail->nextcheck = seconds_since_boot();
        cache_flush();
-       detail->flush_time = 1;
 }
 EXPORT_SYMBOL_GPL(cache_purge);
 
@@ -1436,6 +1448,7 @@ static ssize_t write_flush(struct file *file, const char __user *buf,
 {
        char tbuf[20];
        char *bp, *ep;
+       time_t then, now;
 
        if (*ppos || count > sizeof(tbuf)-1)
                return -EINVAL;
@@ -1447,8 +1460,22 @@ static ssize_t write_flush(struct file *file, const char __user *buf,
                return -EINVAL;
 
        bp = tbuf;
-       cd->flush_time = get_expiry(&bp);
-       cd->nextcheck = seconds_since_boot();
+       then = get_expiry(&bp);
+       now = seconds_since_boot();
+       cd->nextcheck = now;
+       /* Can only set flush_time to 1 second beyond "now", or
+        * possibly 1 second beyond flushtime.  This is because
+        * flush_time never goes backwards so it mustn't get too far
+        * ahead of time.
+        */
+       if (then >= now) {
+               /* Want to flush everything, so behave like cache_purge() */
+               if (cd->flush_time >= now)
+                       now = cd->flush_time + 1;
+               then = now;
+       }
+
+       cd->flush_time = then;
        cache_flush();
 
        *ppos += count;
index 0c8120229a0353967138d20c5fe009a1c6e81d1f..1413cdcc131c4a7ed49487e4a19691644e0ca65c 100644 (file)
@@ -181,7 +181,7 @@ int svc_send_common(struct socket *sock, struct xdr_buf *xdr,
        struct page     **ppage = xdr->pages;
        size_t          base = xdr->page_base;
        unsigned int    pglen = xdr->page_len;
-       unsigned int    flags = MSG_MORE;
+       unsigned int    flags = MSG_MORE | MSG_SENDPAGE_NOTLAST;
        int             slen;
        int             len = 0;
 
@@ -399,6 +399,31 @@ static int svc_sock_secure_port(struct svc_rqst *rqstp)
        return svc_port_is_privileged(svc_addr(rqstp));
 }
 
+static bool sunrpc_waitqueue_active(wait_queue_head_t *wq)
+{
+       if (!wq)
+               return false;
+       /*
+        * There should normally be a memory * barrier here--see
+        * wq_has_sleeper().
+        *
+        * It appears that isn't currently necessary, though, basically
+        * because callers all appear to have sufficient memory barriers
+        * between the time the relevant change is made and the
+        * time they call these callbacks.
+        *
+        * The nfsd code itself doesn't actually explicitly wait on
+        * these waitqueues, but it may wait on them for example in
+        * sendpage() or sendmsg() calls.  (And those may be the only
+        * places, since it it uses nonblocking reads.)
+        *
+        * Maybe we should add the memory barriers anyway, but these are
+        * hot paths so we'd need to be convinced there's no sigificant
+        * penalty.
+        */
+       return waitqueue_active(wq);
+}
+
 /*
  * INET callback when data has been received on the socket.
  */
@@ -414,7 +439,7 @@ static void svc_udp_data_ready(struct sock *sk)
                set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
                svc_xprt_enqueue(&svsk->sk_xprt);
        }
-       if (wq && waitqueue_active(wq))
+       if (sunrpc_waitqueue_active(wq))
                wake_up_interruptible(wq);
 }
 
@@ -432,7 +457,7 @@ static void svc_write_space(struct sock *sk)
                svc_xprt_enqueue(&svsk->sk_xprt);
        }
 
-       if (wq && waitqueue_active(wq)) {
+       if (sunrpc_waitqueue_active(wq)) {
                dprintk("RPC svc_write_space: someone sleeping on %p\n",
                       svsk);
                wake_up_interruptible(wq);
@@ -787,7 +812,7 @@ static void svc_tcp_listen_data_ready(struct sock *sk)
        }
 
        wq = sk_sleep(sk);
-       if (wq && waitqueue_active(wq))
+       if (sunrpc_waitqueue_active(wq))
                wake_up_interruptible_all(wq);
 }
 
@@ -808,7 +833,7 @@ static void svc_tcp_state_change(struct sock *sk)
                set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags);
                svc_xprt_enqueue(&svsk->sk_xprt);
        }
-       if (wq && waitqueue_active(wq))
+       if (sunrpc_waitqueue_active(wq))
                wake_up_interruptible_all(wq);
 }
 
@@ -823,7 +848,7 @@ static void svc_tcp_data_ready(struct sock *sk)
                set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
                svc_xprt_enqueue(&svsk->sk_xprt);
        }
-       if (wq && waitqueue_active(wq))
+       if (sunrpc_waitqueue_active(wq))
                wake_up_interruptible(wq);
 }
 
@@ -1367,7 +1392,6 @@ EXPORT_SYMBOL_GPL(svc_sock_update_bufs);
 
 /*
  * Initialize socket for RPC use and create svc_sock struct
- * XXX: May want to setsockopt SO_SNDBUF and SO_RCVBUF.
  */
 static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
                                                struct socket *sock,
@@ -1594,7 +1618,7 @@ static void svc_sock_detach(struct svc_xprt *xprt)
        sk->sk_write_space = svsk->sk_owspace;
 
        wq = sk_sleep(sk);
-       if (wq && waitqueue_active(wq))
+       if (sunrpc_waitqueue_active(wq))
                wake_up_interruptible(wq);
 }
 
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 a8352db5c5b54ca9d083a16400f41da5dd4ad871..955ec152cb71eac8c91e06f1c922d1df20f6e1f0 100644 (file)
@@ -1813,8 +1813,11 @@ alloc_skb:
        skb->truesize += size;
        atomic_add(size, &sk->sk_wmem_alloc);
 
-       if (newskb)
+       if (newskb) {
+               spin_lock(&other->sk_receive_queue.lock);
                __skb_queue_tail(&other->sk_receive_queue, newskb);
+               spin_unlock(&other->sk_receive_queue.lock);
+       }
 
        unix_state_unlock(other);
        mutex_unlock(&unix_sk(other)->readlock);
index 224ebb46bed5f8cf2965103f18ffa659d7629e76..d54f28c6dc5e5450595f1d5472f14cad3c42cee9 100644 (file)
@@ -70,4 +70,10 @@ config SAMPLE_LIVEPATCH
          Builds a sample live patch that replaces the procfs handler
          for /proc/cmdline to print "this has been live patched".
 
+config SAMPLE_CONFIGFS
+       tristate "Build configfs patching sample -- loadable modules only"
+       depends on CONFIGFS_FS && m
+       help
+         Builds a sample configfs interface.
+
 endif # SAMPLES
index f00257bcc5a73570013f5a25253ed8da3e2ee629..48001d7e23f042a7f777ec810ab2ff29e7db5f52 100644 (file)
@@ -1,4 +1,5 @@
 # Makefile for Linux samples code
 
 obj-$(CONFIG_SAMPLES)  += kobject/ kprobes/ trace_events/ livepatch/ \
-                          hw_breakpoint/ kfifo/ kdb/ hidraw/ rpmsg/ seccomp/
+                          hw_breakpoint/ kfifo/ kdb/ hidraw/ rpmsg/ seccomp/ \
+                          configfs/
diff --git a/samples/configfs/Makefile b/samples/configfs/Makefile
new file mode 100644 (file)
index 0000000..a9afd99
--- /dev/null
@@ -0,0 +1,2 @@
+
+obj-$(CONFIG_SAMPLE_CONFIGFS) += configfs_sample.o
diff --git a/samples/configfs/configfs_sample.c b/samples/configfs/configfs_sample.c
new file mode 100644 (file)
index 0000000..1ea3311
--- /dev/null
@@ -0,0 +1,404 @@
+/*
+ * vim: noexpandtab ts=8 sts=0 sw=8:
+ *
+ * configfs_example_macros.c - This file is a demonstration module
+ *      containing a number of configfs subsystems.  It uses the helper
+ *      macros defined by configfs.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ * Based on sysfs:
+ *     sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
+ *
+ * configfs Copyright (C) 2005 Oracle.  All rights reserved.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include <linux/configfs.h>
+
+
+
+/*
+ * 01-childless
+ *
+ * This first example is a childless subsystem.  It cannot create
+ * any config_items.  It just has attributes.
+ *
+ * Note that we are enclosing the configfs_subsystem inside a container.
+ * This is not necessary if a subsystem has no attributes directly
+ * on the subsystem.  See the next example, 02-simple-children, for
+ * such a subsystem.
+ */
+
+struct childless {
+       struct configfs_subsystem subsys;
+       int showme;
+       int storeme;
+};
+
+static inline struct childless *to_childless(struct config_item *item)
+{
+       return item ? container_of(to_configfs_subsystem(to_config_group(item)),
+                       struct childless, subsys) : NULL;
+}
+
+static ssize_t childless_showme_show(struct config_item *item, char *page)
+{
+       struct childless *childless = to_childless(item);
+       ssize_t pos;
+
+       pos = sprintf(page, "%d\n", childless->showme);
+       childless->showme++;
+
+       return pos;
+}
+
+static ssize_t childless_storeme_show(struct config_item *item, char *page)
+{
+       return sprintf(page, "%d\n", to_childless(item)->storeme);
+}
+
+static ssize_t childless_storeme_store(struct config_item *item,
+               const char *page, size_t count)
+{
+       struct childless *childless = to_childless(item);
+       unsigned long tmp;
+       char *p = (char *) page;
+
+       tmp = simple_strtoul(p, &p, 10);
+       if (!p || (*p && (*p != '\n')))
+               return -EINVAL;
+
+       if (tmp > INT_MAX)
+               return -ERANGE;
+
+       childless->storeme = tmp;
+
+       return count;
+}
+
+static ssize_t childless_description_show(struct config_item *item, char *page)
+{
+       return sprintf(page,
+"[01-childless]\n"
+"\n"
+"The childless subsystem is the simplest possible subsystem in\n"
+"configfs.  It does not support the creation of child config_items.\n"
+"It only has a few attributes.  In fact, it isn't much different\n"
+"than a directory in /proc.\n");
+}
+
+CONFIGFS_ATTR_RO(childless_, showme);
+CONFIGFS_ATTR(childless_, storeme);
+CONFIGFS_ATTR_RO(childless_, description);
+
+static struct configfs_attribute *childless_attrs[] = {
+       &childless_attr_showme,
+       &childless_attr_storeme,
+       &childless_attr_description,
+       NULL,
+};
+
+static struct config_item_type childless_type = {
+       .ct_attrs       = childless_attrs,
+       .ct_owner       = THIS_MODULE,
+};
+
+static struct childless childless_subsys = {
+       .subsys = {
+               .su_group = {
+                       .cg_item = {
+                               .ci_namebuf = "01-childless",
+                               .ci_type = &childless_type,
+                       },
+               },
+       },
+};
+
+
+/* ----------------------------------------------------------------- */
+
+/*
+ * 02-simple-children
+ *
+ * This example merely has a simple one-attribute child.  Note that
+ * there is no extra attribute structure, as the child's attribute is
+ * known from the get-go.  Also, there is no container for the
+ * subsystem, as it has no attributes of its own.
+ */
+
+struct simple_child {
+       struct config_item item;
+       int storeme;
+};
+
+static inline struct simple_child *to_simple_child(struct config_item *item)
+{
+       return item ? container_of(item, struct simple_child, item) : NULL;
+}
+
+static ssize_t simple_child_storeme_show(struct config_item *item, char *page)
+{
+       return sprintf(page, "%d\n", to_simple_child(item)->storeme);
+}
+
+static ssize_t simple_child_storeme_store(struct config_item *item,
+               const char *page, size_t count)
+{
+       struct simple_child *simple_child = to_simple_child(item);
+       unsigned long tmp;
+       char *p = (char *) page;
+
+       tmp = simple_strtoul(p, &p, 10);
+       if (!p || (*p && (*p != '\n')))
+               return -EINVAL;
+
+       if (tmp > INT_MAX)
+               return -ERANGE;
+
+       simple_child->storeme = tmp;
+
+       return count;
+}
+
+CONFIGFS_ATTR(simple_child_, storeme);
+
+static struct configfs_attribute *simple_child_attrs[] = {
+       &simple_child_attr_storeme,
+       NULL,
+};
+
+static void simple_child_release(struct config_item *item)
+{
+       kfree(to_simple_child(item));
+}
+
+static struct configfs_item_operations simple_child_item_ops = {
+       .release                = simple_child_release,
+};
+
+static struct config_item_type simple_child_type = {
+       .ct_item_ops    = &simple_child_item_ops,
+       .ct_attrs       = simple_child_attrs,
+       .ct_owner       = THIS_MODULE,
+};
+
+
+struct simple_children {
+       struct config_group group;
+};
+
+static inline struct simple_children *to_simple_children(struct config_item *item)
+{
+       return item ? container_of(to_config_group(item),
+                       struct simple_children, group) : NULL;
+}
+
+static struct config_item *simple_children_make_item(struct config_group *group,
+               const char *name)
+{
+       struct simple_child *simple_child;
+
+       simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL);
+       if (!simple_child)
+               return ERR_PTR(-ENOMEM);
+
+       config_item_init_type_name(&simple_child->item, name,
+                                  &simple_child_type);
+
+       simple_child->storeme = 0;
+
+       return &simple_child->item;
+}
+
+static ssize_t simple_children_description_show(struct config_item *item,
+               char *page)
+{
+       return sprintf(page,
+"[02-simple-children]\n"
+"\n"
+"This subsystem allows the creation of child config_items.  These\n"
+"items have only one attribute that is readable and writeable.\n");
+}
+
+CONFIGFS_ATTR_RO(simple_children_, description);
+
+static struct configfs_attribute *simple_children_attrs[] = {
+       &simple_children_attr_description,
+       NULL,
+};
+
+static void simple_children_release(struct config_item *item)
+{
+       kfree(to_simple_children(item));
+}
+
+static struct configfs_item_operations simple_children_item_ops = {
+       .release        = simple_children_release,
+};
+
+/*
+ * Note that, since no extra work is required on ->drop_item(),
+ * no ->drop_item() is provided.
+ */
+static struct configfs_group_operations simple_children_group_ops = {
+       .make_item      = simple_children_make_item,
+};
+
+static struct config_item_type simple_children_type = {
+       .ct_item_ops    = &simple_children_item_ops,
+       .ct_group_ops   = &simple_children_group_ops,
+       .ct_attrs       = simple_children_attrs,
+       .ct_owner       = THIS_MODULE,
+};
+
+static struct configfs_subsystem simple_children_subsys = {
+       .su_group = {
+               .cg_item = {
+                       .ci_namebuf = "02-simple-children",
+                       .ci_type = &simple_children_type,
+               },
+       },
+};
+
+
+/* ----------------------------------------------------------------- */
+
+/*
+ * 03-group-children
+ *
+ * This example reuses the simple_children group from above.  However,
+ * the simple_children group is not the subsystem itself, it is a
+ * child of the subsystem.  Creation of a group in the subsystem creates
+ * a new simple_children group.  That group can then have simple_child
+ * children of its own.
+ */
+
+static struct config_group *group_children_make_group(
+               struct config_group *group, const char *name)
+{
+       struct simple_children *simple_children;
+
+       simple_children = kzalloc(sizeof(struct simple_children),
+                                 GFP_KERNEL);
+       if (!simple_children)
+               return ERR_PTR(-ENOMEM);
+
+       config_group_init_type_name(&simple_children->group, name,
+                                   &simple_children_type);
+
+       return &simple_children->group;
+}
+
+static ssize_t group_children_description_show(struct config_item *item,
+               char *page)
+{
+       return sprintf(page,
+"[03-group-children]\n"
+"\n"
+"This subsystem allows the creation of child config_groups.  These\n"
+"groups are like the subsystem simple-children.\n");
+}
+
+CONFIGFS_ATTR_RO(group_children_, description);
+
+static struct configfs_attribute *group_children_attrs[] = {
+       &group_children_attr_description,
+       NULL,
+};
+
+/*
+ * Note that, since no extra work is required on ->drop_item(),
+ * no ->drop_item() is provided.
+ */
+static struct configfs_group_operations group_children_group_ops = {
+       .make_group     = group_children_make_group,
+};
+
+static struct config_item_type group_children_type = {
+       .ct_group_ops   = &group_children_group_ops,
+       .ct_attrs       = group_children_attrs,
+       .ct_owner       = THIS_MODULE,
+};
+
+static struct configfs_subsystem group_children_subsys = {
+       .su_group = {
+               .cg_item = {
+                       .ci_namebuf = "03-group-children",
+                       .ci_type = &group_children_type,
+               },
+       },
+};
+
+/* ----------------------------------------------------------------- */
+
+/*
+ * We're now done with our subsystem definitions.
+ * For convenience in this module, here's a list of them all.  It
+ * allows the init function to easily register them.  Most modules
+ * will only have one subsystem, and will only call register_subsystem
+ * on it directly.
+ */
+static struct configfs_subsystem *example_subsys[] = {
+       &childless_subsys.subsys,
+       &simple_children_subsys,
+       &group_children_subsys,
+       NULL,
+};
+
+static int __init configfs_example_init(void)
+{
+       int ret;
+       int i;
+       struct configfs_subsystem *subsys;
+
+       for (i = 0; example_subsys[i]; i++) {
+               subsys = example_subsys[i];
+
+               config_group_init(&subsys->su_group);
+               mutex_init(&subsys->su_mutex);
+               ret = configfs_register_subsystem(subsys);
+               if (ret) {
+                       printk(KERN_ERR "Error %d while registering subsystem %s\n",
+                              ret,
+                              subsys->su_group.cg_item.ci_namebuf);
+                       goto out_unregister;
+               }
+       }
+
+       return 0;
+
+out_unregister:
+       for (i--; i >= 0; i--)
+               configfs_unregister_subsystem(example_subsys[i]);
+
+       return ret;
+}
+
+static void __exit configfs_example_exit(void)
+{
+       int i;
+
+       for (i = 0; example_subsys[i]; i++)
+               configfs_unregister_subsystem(example_subsys[i]);
+}
+
+module_init(configfs_example_init);
+module_exit(configfs_example_exit);
+MODULE_LICENSE("GPL");
index bee0e5f1a1166d18e443f8294754f01bf55101ca..e92a6d949847a3fbc3de4ad7edc2ecd6026fbae3 100644 (file)
@@ -38,6 +38,7 @@ config SND_OXFW
           * Mackie(Loud) Tapco Link.Firewire
           * Mackie(Loud) d.2 pro/d.4 pro
           * Mackie(Loud) U.420/U.420d
+          * TASCAM FireOne
 
          To compile this driver as a module, choose M here: the module
          will be called snd-oxfw.
index edfc1b8d553ee3c6e1ad4bfd4d424fce7631b292..656ce39bddbc531c27d5a15b6d07e899e17f1cd6 100644 (file)
@@ -25,7 +25,7 @@ config SND_ALS300
        select SND_PCM
        select SND_AC97_CODEC
        select SND_OPL3_LIB
-       select ZONE_DMA
+       depends on ZONE_DMA
        help
          Say 'Y' or 'M' to include support for Avance Logic ALS300/ALS300+
 
@@ -50,7 +50,7 @@ config SND_ALI5451
        tristate "ALi M5451 PCI Audio Controller"
        select SND_MPU401_UART
        select SND_AC97_CODEC
-       select ZONE_DMA
+       depends on ZONE_DMA
        help
          Say Y here to include support for the integrated AC97 sound
          device on motherboards using the ALi M5451 Audio Controller
@@ -155,7 +155,7 @@ config SND_AZT3328
        select SND_PCM
        select SND_RAWMIDI
        select SND_AC97_CODEC
-       select ZONE_DMA
+       depends on ZONE_DMA
        help
          Say Y here to include support for Aztech AZF3328 (PCI168)
          soundcards.
@@ -463,7 +463,7 @@ config SND_EMU10K1
        select SND_HWDEP
        select SND_RAWMIDI
        select SND_AC97_CODEC
-       select ZONE_DMA
+       depends on ZONE_DMA
        help
          Say Y to include support for Sound Blaster PCI 512, Live!,
          Audigy and E-mu APS (partially supported) soundcards.
@@ -479,7 +479,7 @@ config SND_EMU10K1X
        tristate "Emu10k1X (Dell OEM Version)"
        select SND_AC97_CODEC
        select SND_RAWMIDI
-       select ZONE_DMA
+       depends on ZONE_DMA
        help
          Say Y here to include support for the Dell OEM version of the
          Sound Blaster Live!.
@@ -513,7 +513,7 @@ config SND_ES1938
        select SND_OPL3_LIB
        select SND_MPU401_UART
        select SND_AC97_CODEC
-       select ZONE_DMA
+       depends on ZONE_DMA
        help
          Say Y here to include support for soundcards based on ESS Solo-1
          (ES1938, ES1946, ES1969) chips.
@@ -525,7 +525,7 @@ config SND_ES1968
        tristate "ESS ES1968/1978 (Maestro-1/2/2E)"
        select SND_MPU401_UART
        select SND_AC97_CODEC
-       select ZONE_DMA
+       depends on ZONE_DMA
        help
          Say Y here to include support for soundcards based on ESS Maestro
          1/2/2E chips.
@@ -612,7 +612,7 @@ config SND_ICE1712
        select SND_MPU401_UART
        select SND_AC97_CODEC
        select BITREVERSE
-       select ZONE_DMA
+       depends on ZONE_DMA
        help
          Say Y here to include support for soundcards based on the
          ICE1712 (Envy24) chip.
@@ -700,7 +700,7 @@ config SND_LX6464ES
 config SND_MAESTRO3
        tristate "ESS Allegro/Maestro3"
        select SND_AC97_CODEC
-       select ZONE_DMA
+       depends on ZONE_DMA
        help
          Say Y here to include support for soundcards based on ESS Maestro 3
          (Allegro) chips.
@@ -806,7 +806,7 @@ config SND_SIS7019
        tristate "SiS 7019 Audio Accelerator"
        depends on X86_32
        select SND_AC97_CODEC
-       select ZONE_DMA
+       depends on ZONE_DMA
        help
          Say Y here to include support for the SiS 7019 Audio Accelerator.
 
@@ -818,7 +818,7 @@ config SND_SONICVIBES
        select SND_OPL3_LIB
        select SND_MPU401_UART
        select SND_AC97_CODEC
-       select ZONE_DMA
+       depends on ZONE_DMA
        help
          Say Y here to include support for soundcards based on the S3
          SonicVibes chip.
@@ -830,7 +830,7 @@ config SND_TRIDENT
        tristate "Trident 4D-Wave DX/NX; SiS 7018"
        select SND_MPU401_UART
        select SND_AC97_CODEC
-       select ZONE_DMA
+       depends on ZONE_DMA
        help
          Say Y here to include support for soundcards based on Trident
          4D-Wave DX/NX or SiS 7018 chips.
index c7dc38d41b7f4678691e5a492b93b5087bddddce..5fcbb065d8702bd051b3a69789bcfe5b3b5d4da2 100644 (file)
@@ -49,7 +49,7 @@ static int amixer_output_slot(const struct rsc *rsc)
        return (amixer_index(rsc) << 4) + 0x4;
 }
 
-static struct rsc_ops amixer_basic_rsc_ops = {
+static const struct rsc_ops amixer_basic_rsc_ops = {
        .master         = amixer_master,
        .next_conj      = amixer_next_conj,
        .index          = amixer_index,
@@ -186,7 +186,7 @@ static int amixer_setup(struct amixer *amixer, struct rsc *input,
        return 0;
 }
 
-static struct amixer_rsc_ops amixer_ops = {
+static const struct amixer_rsc_ops amixer_ops = {
        .set_input              = amixer_set_input,
        .set_invalid_squash     = amixer_set_invalid_squash,
        .set_scale              = amixer_set_y,
@@ -357,7 +357,7 @@ static int sum_output_slot(const struct rsc *rsc)
        return (sum_index(rsc) << 4) + 0xc;
 }
 
-static struct rsc_ops sum_basic_rsc_ops = {
+static const struct rsc_ops sum_basic_rsc_ops = {
        .master         = sum_master,
        .next_conj      = sum_next_conj,
        .index          = sum_index,
index 72f42f27434eb7f4dcada14fe737be047d03d7f0..2de18aa6508dbd4b9a363e2f760c2fdb4cd6bf63 100644 (file)
@@ -58,7 +58,7 @@ struct amixer {
        unsigned char idx[8];
        struct rsc *input;      /* pointer to a resource acting as source */
        struct sum *sum;        /* Put amixer output to this summation node */
-       struct amixer_rsc_ops *ops;     /* AMixer specific operations */
+       const struct amixer_rsc_ops *ops;       /* AMixer specific operations */
 };
 
 struct amixer_rsc_ops {
index 9b87dd28de8349f38adf4cfc572019abe82cd156..7f089cb433e17d6c9dde341d09b328aa471ec0c1 100644 (file)
@@ -83,21 +83,21 @@ static int daio_in_next_conj_20k2(struct rsc *rsc)
        return rsc->conj += 0x100;
 }
 
-static struct rsc_ops daio_out_rsc_ops = {
+static const struct rsc_ops daio_out_rsc_ops = {
        .master         = daio_master,
        .next_conj      = daio_out_next_conj,
        .index          = daio_index,
        .output_slot    = NULL,
 };
 
-static struct rsc_ops daio_in_rsc_ops_20k1 = {
+static const struct rsc_ops daio_in_rsc_ops_20k1 = {
        .master         = daio_master,
        .next_conj      = daio_in_next_conj_20k1,
        .index          = NULL,
        .output_slot    = daio_index,
 };
 
-static struct rsc_ops daio_in_rsc_ops_20k2 = {
+static const struct rsc_ops daio_in_rsc_ops_20k2 = {
        .master         = daio_master,
        .next_conj      = daio_in_next_conj_20k2,
        .index          = NULL,
@@ -263,7 +263,7 @@ static int dao_clear_right_input(struct dao *dao)
        return 0;
 }
 
-static struct dao_rsc_ops dao_ops = {
+static const struct dao_rsc_ops dao_ops = {
        .set_spos               = dao_spdif_set_spos,
        .commit_write           = dao_commit_write,
        .get_spos               = dao_spdif_get_spos,
@@ -318,7 +318,7 @@ static int dai_commit_write(struct dai *dai)
        return 0;
 }
 
-static struct dai_rsc_ops dai_ops = {
+static const struct dai_rsc_ops dai_ops = {
        .set_srt_srcl           = dai_set_srt_srcl,
        .set_srt_srcr           = dai_set_srt_srcr,
        .set_srt_msr            = dai_set_srt_msr,
index 0ebbf350f51aa8a6b3a64e91aa3a278e0b44ebf0..a30be73b08ea6c4bb50cb5735d6fa7d0978d0a9d 100644 (file)
@@ -51,7 +51,7 @@ struct daio {
 
 struct dao {
        struct daio daio;
-       struct dao_rsc_ops *ops;        /* DAO specific operations */
+       const struct dao_rsc_ops *ops;  /* DAO specific operations */
        struct imapper **imappers;
        struct daio_mgr *mgr;
        struct hw *hw;
@@ -60,7 +60,7 @@ struct dao {
 
 struct dai {
        struct daio daio;
-       struct dai_rsc_ops *ops;        /* DAI specific operations */
+       const struct dai_rsc_ops *ops;  /* DAI specific operations */
        struct hw *hw;
        void *ctrl_blk;
 };
index 1a97e406d8ec00aaa36b430a8d8d02419cb30fca..c5124c3c0fd192bb8d25528f779b7755d748d057 100644 (file)
@@ -127,7 +127,7 @@ static int rsc_master(struct rsc *rsc)
        return rsc->conj = rsc->idx;
 }
 
-static struct rsc_ops rsc_generic_ops = {
+static const struct rsc_ops rsc_generic_ops = {
        .index          = rsc_index,
        .output_slot    = audio_ring_slot,
        .master         = rsc_master,
index 9b746c3719e6219faa30b116b762675376867631..736d9f7e9e165844fe75419a5e063ad02565814b 100644 (file)
@@ -39,7 +39,7 @@ struct rsc {
        u32 msr:4;      /* The Master Sample Rate a resource working on */
        void *ctrl_blk; /* Chip specific control info block for a resource */
        struct hw *hw;  /* Chip specific object for hardware access means */
-       struct rsc_ops *ops;    /* Generic resource operations */
+       const struct rsc_ops *ops;      /* Generic resource operations */
 };
 
 struct rsc_ops {
index ec1f08464d938ce0adc3660f3ae8efbb799d7cde..a5a72df298013faae602f1cdcb95a7b4cda3d865 100644 (file)
@@ -335,7 +335,7 @@ static int src_default_config_arcrw(struct src *src)
        return 0;
 }
 
-static struct src_rsc_ops src_rsc_ops = {
+static const struct src_rsc_ops src_rsc_ops = {
        .set_state              = src_set_state,
        .set_bm                 = src_set_bm,
        .set_sf                 = src_set_sf,
@@ -611,7 +611,7 @@ static int srcimp_index(const struct rsc *rsc)
        return container_of(rsc, struct srcimp, rsc)->idx[rsc->conj];
 }
 
-static struct rsc_ops srcimp_basic_rsc_ops = {
+static const struct rsc_ops srcimp_basic_rsc_ops = {
        .master         = srcimp_master,
        .next_conj      = srcimp_next_conj,
        .index          = srcimp_index,
@@ -662,7 +662,7 @@ static int srcimp_unmap(struct srcimp *srcimp)
        return 0;
 }
 
-static struct srcimp_rsc_ops srcimp_ops = {
+static const struct srcimp_rsc_ops srcimp_ops = {
        .map = srcimp_map,
        .unmap = srcimp_unmap
 };
index da7573c5db9bb6bdfd974c03c758a33c32170e65..92944a012bc4b6dc8bc4d2a6a448bbc2933947c0 100644 (file)
@@ -48,7 +48,7 @@ struct src_rsc_ops;
 struct src {
        struct rsc rsc; /* Basic resource info */
        struct src *intlv; /* Pointer to next interleaved SRC in a series */
-       struct src_rsc_ops *ops; /* SRC specific operations */
+       const struct src_rsc_ops *ops; /* SRC specific operations */
        /* Number of contiguous srcs for interleaved usage */
        unsigned char multi;
        unsigned char mode; /* Working mode of this SRC resource */
@@ -110,7 +110,7 @@ struct srcimp {
        struct imapper *imappers;
        unsigned int mapped; /* A bit-map indicating which conj rsc is mapped */
        struct srcimp_mgr *mgr;
-       struct srcimp_rsc_ops *ops;
+       const struct srcimp_rsc_ops *ops;
 };
 
 struct srcimp_rsc_ops {
index 366efbf87d41c7d5a3e3826bbb74d25fcf09e5fd..c945e257d368890bcd3f72037568e566c0ba9221 100644 (file)
@@ -383,7 +383,7 @@ static void hda_free_jack_priv(struct snd_jack *jack)
  * This assigns a jack-detection kctl to the given pin.  The kcontrol
  * will have the given name and index.
  */
-static int __snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
+int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
                          const char *name, bool phantom_jack)
 {
        struct hda_jack_tbl *jack;
@@ -410,20 +410,6 @@ static int __snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
 
        return 0;
 }
-
-/**
- * snd_hda_jack_add_kctl - Add a jack kctl for the given pin
- * @codec: the HDA codec
- * @nid: pin NID
- * @name: the name string for the jack ctl
- *
- * This is a simple helper calling __snd_hda_jack_add_kctl().
- */
-int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
-                         const char *name)
-{
-       return __snd_hda_jack_add_kctl(codec, nid, name, false);
-}
 EXPORT_SYMBOL_GPL(snd_hda_jack_add_kctl);
 
 static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
@@ -451,7 +437,7 @@ static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
        if (phantom_jack)
                /* Example final name: "Internal Mic Phantom Jack" */
                strncat(name, " Phantom", sizeof(name) - strlen(name) - 1);
-       err = __snd_hda_jack_add_kctl(codec, nid, name, phantom_jack);
+       err = snd_hda_jack_add_kctl(codec, nid, name, phantom_jack);
        if (err < 0)
                return err;
 
index 387d30984dfe3dd496e6a247ef34c221dce12981..858708a044f57ef563d79a100c5a92e5f3adaa3d 100644 (file)
@@ -82,7 +82,7 @@ static inline bool snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)
 bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid);
 
 int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
-                         const char *name);
+                         const char *name, bool phantom_jack);
 int snd_hda_jack_add_kctls(struct hda_codec *codec,
                           const struct auto_pin_cfg *cfg);
 
index f503a883bef31d0fd55a38dd816f70609edcaf82..60cd9e70090981076fcaec5bcb55cfd92ececdc9 100644 (file)
@@ -50,8 +50,9 @@ MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info");
 #define is_haswell(codec)  ((codec)->core.vendor_id == 0x80862807)
 #define is_broadwell(codec)    ((codec)->core.vendor_id == 0x80862808)
 #define is_skylake(codec) ((codec)->core.vendor_id == 0x80862809)
+#define is_broxton(codec) ((codec)->core.vendor_id == 0x8086280a)
 #define is_haswell_plus(codec) (is_haswell(codec) || is_broadwell(codec) \
-                                       || is_skylake(codec))
+                               || is_skylake(codec) || is_broxton(codec))
 
 #define is_valleyview(codec) ((codec)->core.vendor_id == 0x80862882)
 #define is_cherryview(codec) ((codec)->core.vendor_id == 0x80862883)
@@ -2096,14 +2097,17 @@ static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx)
        struct hdmi_spec *spec = codec->spec;
        struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
        int pcmdev = get_pcm_rec(spec, pin_idx)->device;
+       bool phantom_jack;
 
        if (pcmdev > 0)
                sprintf(hdmi_str + strlen(hdmi_str), ",pcm=%d", pcmdev);
-       if (!is_jack_detectable(codec, per_pin->pin_nid))
+       phantom_jack = !is_jack_detectable(codec, per_pin->pin_nid);
+       if (phantom_jack)
                strncat(hdmi_str, " Phantom",
                        sizeof(hdmi_str) - strlen(hdmi_str) - 1);
 
-       return snd_hda_jack_add_kctl(codec, per_pin->pin_nid, hdmi_str);
+       return snd_hda_jack_add_kctl(codec, per_pin->pin_nid, hdmi_str,
+                                    phantom_jack);
 }
 
 static int generic_hdmi_build_controls(struct hda_codec *codec)
index 11e953a1fa45a06ab9243eca4d99d5b3f16ea9ef..99b73c675743661318ac5cf4bd3000e26e3627a7 100644 (file)
@@ -655,7 +655,7 @@ static void cleanup_oss_soundcore(void)
 static int __init init_oss_soundcore(void)
 {
        if (preclaim_oss &&
-           register_chrdev(SOUND_MAJOR, "sound", &soundcore_fops) == -1) {
+           register_chrdev(SOUND_MAJOR, "sound", &soundcore_fops) < 0) {
                printk(KERN_ERR "soundcore: sound device already in use.\n");
                return -EBUSY;
        }
index 4897ea171194f474c352c45579f62aa036d219ea..5ca80e7d30cd25bcc67cdf88509f46d39eec42e6 100644 (file)
@@ -1274,6 +1274,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
        case USB_ID(0x20b1, 0x000a): /* Gustard DAC-X20U */
        case USB_ID(0x20b1, 0x2009): /* DIYINHK DSD DXD 384kHz USB to I2S/DSD */
        case USB_ID(0x20b1, 0x2023): /* JLsounds I2SoverUSB */
+       case USB_ID(0x20b1, 0x3023): /* Aune X1S 32BIT/384 DSD DAC */
                if (fp->altsetting == 3)
                        return SNDRV_PCM_FMTBIT_DSD_U32_BE;
                break;
index 76b014c968935aa028f2bc6cb78bfdfbd2a1def7..a017f1595676d32b5cd28ed4f6ab75b9d2278934 100644 (file)
@@ -1,3 +1,4 @@
+#include <linux/compiler.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 
index 812aeedaea387d23197061bc20bd2abeeb281c7e..f81e549ddfdb18e6e3c86d063bb131cfcbadb810 100644 (file)
@@ -1,2 +1,2 @@
 libbpf_version.h
-FEATURE-DUMP
+FEATURE-DUMP.libbpf
index fc9af57b666e244b6b1c06cd163738068190b6f8..a3caaf3eafbdbc6c7afda606cbf35b6888324ef4 100644 (file)
@@ -180,7 +180,7 @@ config-clean:
 clean:
        $(call QUIET_CLEAN, libbpf) $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d \
                $(RM) LIBBPF-CFLAGS
-       $(call QUIET_CLEAN, core-gen) $(RM) $(OUTPUT)FEATURE-DUMP
+       $(call QUIET_CLEAN, core-gen) $(RM) $(OUTPUT)FEATURE-DUMP.libbpf
 
 
 
index 4252fc22f78f4f8fd4c204975b5464f5bbc192e0..e176bad19bcb73689665ea9bd083075dff0e73fa 100644 (file)
@@ -61,6 +61,60 @@ void libbpf_set_print(libbpf_print_fn_t warn,
        __pr_debug = debug;
 }
 
+#define STRERR_BUFSIZE  128
+
+#define ERRNO_OFFSET(e)                ((e) - __LIBBPF_ERRNO__START)
+#define ERRCODE_OFFSET(c)      ERRNO_OFFSET(LIBBPF_ERRNO__##c)
+#define NR_ERRNO       (__LIBBPF_ERRNO__END - __LIBBPF_ERRNO__START)
+
+static const char *libbpf_strerror_table[NR_ERRNO] = {
+       [ERRCODE_OFFSET(LIBELF)]        = "Something wrong in libelf",
+       [ERRCODE_OFFSET(FORMAT)]        = "BPF object format invalid",
+       [ERRCODE_OFFSET(KVERSION)]      = "'version' section incorrect or lost",
+       [ERRCODE_OFFSET(ENDIAN)]        = "Endian missmatch",
+       [ERRCODE_OFFSET(INTERNAL)]      = "Internal error in libbpf",
+       [ERRCODE_OFFSET(RELOC)]         = "Relocation failed",
+       [ERRCODE_OFFSET(VERIFY)]        = "Kernel verifier blocks program loading",
+       [ERRCODE_OFFSET(PROG2BIG)]      = "Program too big",
+       [ERRCODE_OFFSET(KVER)]          = "Incorrect kernel version",
+};
+
+int libbpf_strerror(int err, char *buf, size_t size)
+{
+       if (!buf || !size)
+               return -1;
+
+       err = err > 0 ? err : -err;
+
+       if (err < __LIBBPF_ERRNO__START) {
+               int ret;
+
+               ret = strerror_r(err, buf, size);
+               buf[size - 1] = '\0';
+               return ret;
+       }
+
+       if (err < __LIBBPF_ERRNO__END) {
+               const char *msg;
+
+               msg = libbpf_strerror_table[ERRNO_OFFSET(err)];
+               snprintf(buf, size, "%s", msg);
+               buf[size - 1] = '\0';
+               return 0;
+       }
+
+       snprintf(buf, size, "Unknown libbpf error %d", err);
+       buf[size - 1] = '\0';
+       return -1;
+}
+
+#define CHECK_ERR(action, err, out) do {       \
+       err = action;                   \
+       if (err)                        \
+               goto out;               \
+} while(0)
+
+
 /* Copied from tools/perf/util/util.h */
 #ifndef zfree
 # define zfree(ptr) ({ free(*ptr); *ptr = NULL; })
@@ -258,7 +312,7 @@ static struct bpf_object *bpf_object__new(const char *path,
        obj = calloc(1, sizeof(struct bpf_object) + strlen(path) + 1);
        if (!obj) {
                pr_warning("alloc memory failed for %s\n", path);
-               return NULL;
+               return ERR_PTR(-ENOMEM);
        }
 
        strcpy(obj->path, path);
@@ -305,7 +359,7 @@ static int bpf_object__elf_init(struct bpf_object *obj)
 
        if (obj_elf_valid(obj)) {
                pr_warning("elf init: internal error\n");
-               return -EEXIST;
+               return -LIBBPF_ERRNO__LIBELF;
        }
 
        if (obj->efile.obj_buf_sz > 0) {
@@ -331,14 +385,14 @@ static int bpf_object__elf_init(struct bpf_object *obj)
        if (!obj->efile.elf) {
                pr_warning("failed to open %s as ELF file\n",
                                obj->path);
-               err = -EINVAL;
+               err = -LIBBPF_ERRNO__LIBELF;
                goto errout;
        }
 
        if (!gelf_getehdr(obj->efile.elf, &obj->efile.ehdr)) {
                pr_warning("failed to get EHDR from %s\n",
                                obj->path);
-               err = -EINVAL;
+               err = -LIBBPF_ERRNO__FORMAT;
                goto errout;
        }
        ep = &obj->efile.ehdr;
@@ -346,7 +400,7 @@ static int bpf_object__elf_init(struct bpf_object *obj)
        if ((ep->e_type != ET_REL) || (ep->e_machine != 0)) {
                pr_warning("%s is not an eBPF object file\n",
                        obj->path);
-               err = -EINVAL;
+               err = -LIBBPF_ERRNO__FORMAT;
                goto errout;
        }
 
@@ -374,14 +428,14 @@ bpf_object__check_endianness(struct bpf_object *obj)
                        goto mismatch;
                break;
        default:
-               return -EINVAL;
+               return -LIBBPF_ERRNO__ENDIAN;
        }
 
        return 0;
 
 mismatch:
        pr_warning("Error: endianness mismatch.\n");
-       return -EINVAL;
+       return -LIBBPF_ERRNO__ENDIAN;
 }
 
 static int
@@ -402,7 +456,7 @@ bpf_object__init_kversion(struct bpf_object *obj,
 
        if (size != sizeof(kver)) {
                pr_warning("invalid kver section in %s\n", obj->path);
-               return -EINVAL;
+               return -LIBBPF_ERRNO__FORMAT;
        }
        memcpy(&kver, data, sizeof(kver));
        obj->kern_version = kver;
@@ -444,7 +498,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
        if (!elf_rawdata(elf_getscn(elf, ep->e_shstrndx), NULL)) {
                pr_warning("failed to get e_shstrndx from %s\n",
                           obj->path);
-               return -EINVAL;
+               return -LIBBPF_ERRNO__FORMAT;
        }
 
        while ((scn = elf_nextscn(elf, scn)) != NULL) {
@@ -456,7 +510,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
                if (gelf_getshdr(scn, &sh) != &sh) {
                        pr_warning("failed to get section header from %s\n",
                                   obj->path);
-                       err = -EINVAL;
+                       err = -LIBBPF_ERRNO__FORMAT;
                        goto out;
                }
 
@@ -464,7 +518,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
                if (!name) {
                        pr_warning("failed to get section name from %s\n",
                                   obj->path);
-                       err = -EINVAL;
+                       err = -LIBBPF_ERRNO__FORMAT;
                        goto out;
                }
 
@@ -472,7 +526,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
                if (!data) {
                        pr_warning("failed to get section data from %s(%s)\n",
                                   name, obj->path);
-                       err = -EINVAL;
+                       err = -LIBBPF_ERRNO__FORMAT;
                        goto out;
                }
                pr_debug("section %s, size %ld, link %d, flags %lx, type=%d\n",
@@ -495,7 +549,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
                        if (obj->efile.symbols) {
                                pr_warning("bpf: multiple SYMTAB in %s\n",
                                           obj->path);
-                               err = -EEXIST;
+                               err = -LIBBPF_ERRNO__FORMAT;
                        } else
                                obj->efile.symbols = data;
                } else if ((sh.sh_type == SHT_PROGBITS) &&
@@ -504,7 +558,8 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
                        err = bpf_object__add_program(obj, data->d_buf,
                                                      data->d_size, name, idx);
                        if (err) {
-                               char errmsg[128];
+                               char errmsg[STRERR_BUFSIZE];
+
                                strerror_r(-err, errmsg, sizeof(errmsg));
                                pr_warning("failed to alloc program %s (%s): %s",
                                           name, obj->path, errmsg);
@@ -576,7 +631,7 @@ bpf_program__collect_reloc(struct bpf_program *prog,
 
                if (!gelf_getrel(data, i, &rel)) {
                        pr_warning("relocation: failed to get %d reloc\n", i);
-                       return -EINVAL;
+                       return -LIBBPF_ERRNO__FORMAT;
                }
 
                insn_idx = rel.r_offset / sizeof(struct bpf_insn);
@@ -587,20 +642,20 @@ bpf_program__collect_reloc(struct bpf_program *prog,
                                 &sym)) {
                        pr_warning("relocation: symbol %"PRIx64" not found\n",
                                   GELF_R_SYM(rel.r_info));
-                       return -EINVAL;
+                       return -LIBBPF_ERRNO__FORMAT;
                }
 
                if (insns[insn_idx].code != (BPF_LD | BPF_IMM | BPF_DW)) {
                        pr_warning("bpf: relocation: invalid relo for insns[%d].code 0x%x\n",
                                   insn_idx, insns[insn_idx].code);
-                       return -EINVAL;
+                       return -LIBBPF_ERRNO__RELOC;
                }
 
                map_idx = sym.st_value / sizeof(struct bpf_map_def);
                if (map_idx >= nr_maps) {
                        pr_warning("bpf relocation: map_idx %d large than %d\n",
                                   (int)map_idx, (int)nr_maps - 1);
-                       return -EINVAL;
+                       return -LIBBPF_ERRNO__RELOC;
                }
 
                prog->reloc_desc[i].insn_idx = insn_idx;
@@ -683,7 +738,7 @@ bpf_program__relocate(struct bpf_program *prog, int *map_fds)
                if (insn_idx >= (int)prog->insns_cnt) {
                        pr_warning("relocation out of range: '%s'\n",
                                   prog->section_name);
-                       return -ERANGE;
+                       return -LIBBPF_ERRNO__RELOC;
                }
                insns[insn_idx].src_reg = BPF_PSEUDO_MAP_FD;
                insns[insn_idx].imm = map_fds[map_idx];
@@ -721,7 +776,7 @@ static int bpf_object__collect_reloc(struct bpf_object *obj)
 
        if (!obj_elf_valid(obj)) {
                pr_warning("Internal error: elf object is closed\n");
-               return -EINVAL;
+               return -LIBBPF_ERRNO__INTERNAL;
        }
 
        for (i = 0; i < obj->efile.nr_reloc; i++) {
@@ -734,21 +789,21 @@ static int bpf_object__collect_reloc(struct bpf_object *obj)
 
                if (shdr->sh_type != SHT_REL) {
                        pr_warning("internal error at %d\n", __LINE__);
-                       return -EINVAL;
+                       return -LIBBPF_ERRNO__INTERNAL;
                }
 
                prog = bpf_object__find_prog_by_idx(obj, idx);
                if (!prog) {
                        pr_warning("relocation failed: no %d section\n",
                                   idx);
-                       return -ENOENT;
+                       return -LIBBPF_ERRNO__RELOC;
                }
 
                err = bpf_program__collect_reloc(prog, nr_maps,
                                                 shdr, data,
                                                 obj->efile.symbols);
                if (err)
-                       return -EINVAL;
+                       return err;
        }
        return 0;
 }
@@ -777,13 +832,23 @@ load_program(struct bpf_insn *insns, int insns_cnt,
                goto out;
        }
 
-       ret = -EINVAL;
+       ret = -LIBBPF_ERRNO__LOAD;
        pr_warning("load bpf program failed: %s\n", strerror(errno));
 
-       if (log_buf) {
+       if (log_buf && log_buf[0] != '\0') {
+               ret = -LIBBPF_ERRNO__VERIFY;
                pr_warning("-- BEGIN DUMP LOG ---\n");
                pr_warning("\n%s\n", log_buf);
                pr_warning("-- END LOG --\n");
+       } else {
+               if (insns_cnt >= BPF_MAXINSNS) {
+                       pr_warning("Program too large (%d insns), at most %d insns\n",
+                                  insns_cnt, BPF_MAXINSNS);
+                       ret = -LIBBPF_ERRNO__PROG2BIG;
+               } else if (log_buf) {
+                       pr_warning("log buffer is empty\n");
+                       ret = -LIBBPF_ERRNO__KVER;
+               }
        }
 
 out:
@@ -831,7 +896,7 @@ static int bpf_object__validate(struct bpf_object *obj)
        if (obj->kern_version == 0) {
                pr_warning("%s doesn't provide kernel version\n",
                           obj->path);
-               return -EINVAL;
+               return -LIBBPF_ERRNO__KVERSION;
        }
        return 0;
 }
@@ -840,32 +905,28 @@ static struct bpf_object *
 __bpf_object__open(const char *path, void *obj_buf, size_t obj_buf_sz)
 {
        struct bpf_object *obj;
+       int err;
 
        if (elf_version(EV_CURRENT) == EV_NONE) {
                pr_warning("failed to init libelf for %s\n", path);
-               return NULL;
+               return ERR_PTR(-LIBBPF_ERRNO__LIBELF);
        }
 
        obj = bpf_object__new(path, obj_buf, obj_buf_sz);
-       if (!obj)
-               return NULL;
+       if (IS_ERR(obj))
+               return obj;
 
-       if (bpf_object__elf_init(obj))
-               goto out;
-       if (bpf_object__check_endianness(obj))
-               goto out;
-       if (bpf_object__elf_collect(obj))
-               goto out;
-       if (bpf_object__collect_reloc(obj))
-               goto out;
-       if (bpf_object__validate(obj))
-               goto out;
+       CHECK_ERR(bpf_object__elf_init(obj), err, out);
+       CHECK_ERR(bpf_object__check_endianness(obj), err, out);
+       CHECK_ERR(bpf_object__elf_collect(obj), err, out);
+       CHECK_ERR(bpf_object__collect_reloc(obj), err, out);
+       CHECK_ERR(bpf_object__validate(obj), err, out);
 
        bpf_object__elf_finish(obj);
        return obj;
 out:
        bpf_object__close(obj);
-       return NULL;
+       return ERR_PTR(err);
 }
 
 struct bpf_object *bpf_object__open(const char *path)
@@ -922,6 +983,8 @@ int bpf_object__unload(struct bpf_object *obj)
 
 int bpf_object__load(struct bpf_object *obj)
 {
+       int err;
+
        if (!obj)
                return -EINVAL;
 
@@ -931,18 +994,16 @@ int bpf_object__load(struct bpf_object *obj)
        }
 
        obj->loaded = true;
-       if (bpf_object__create_maps(obj))
-               goto out;
-       if (bpf_object__relocate(obj))
-               goto out;
-       if (bpf_object__load_progs(obj))
-               goto out;
+
+       CHECK_ERR(bpf_object__create_maps(obj), err, out);
+       CHECK_ERR(bpf_object__relocate(obj), err, out);
+       CHECK_ERR(bpf_object__load_progs(obj), err, out);
 
        return 0;
 out:
        bpf_object__unload(obj);
        pr_warning("failed to load object '%s'\n", obj->path);
-       return -EINVAL;
+       return err;
 }
 
 void bpf_object__close(struct bpf_object *obj)
@@ -990,10 +1051,18 @@ const char *
 bpf_object__get_name(struct bpf_object *obj)
 {
        if (!obj)
-               return NULL;
+               return ERR_PTR(-EINVAL);
        return obj->path;
 }
 
+unsigned int
+bpf_object__get_kversion(struct bpf_object *obj)
+{
+       if (!obj)
+               return 0;
+       return obj->kern_version;
+}
+
 struct bpf_program *
 bpf_program__next(struct bpf_program *prev, struct bpf_object *obj)
 {
@@ -1034,16 +1103,16 @@ int bpf_program__get_private(struct bpf_program *prog, void **ppriv)
        return 0;
 }
 
-const char *bpf_program__title(struct bpf_program *prog, bool dup)
+const char *bpf_program__title(struct bpf_program *prog, bool needs_copy)
 {
        const char *title;
 
        title = prog->section_name;
-       if (dup) {
+       if (needs_copy) {
                title = strdup(title);
                if (!title) {
                        pr_warning("failed to strdup program title\n");
-                       return NULL;
+                       return ERR_PTR(-ENOMEM);
                }
        }
 
index f16170c95ffdc2306aa02f836092661b2673408e..c9a9aef2806cbfbef033668920ab8cae02ca2e8d 100644 (file)
 
 #include <stdio.h>
 #include <stdbool.h>
+#include <linux/err.h>
+
+enum libbpf_errno {
+       __LIBBPF_ERRNO__START = 4000,
+
+       /* Something wrong in libelf */
+       LIBBPF_ERRNO__LIBELF = __LIBBPF_ERRNO__START,
+       LIBBPF_ERRNO__FORMAT,   /* BPF object format invalid */
+       LIBBPF_ERRNO__KVERSION, /* Incorrect or no 'version' section */
+       LIBBPF_ERRNO__ENDIAN,   /* Endian missmatch */
+       LIBBPF_ERRNO__INTERNAL, /* Internal error in libbpf */
+       LIBBPF_ERRNO__RELOC,    /* Relocation failed */
+       LIBBPF_ERRNO__LOAD,     /* Load program failure for unknown reason */
+       LIBBPF_ERRNO__VERIFY,   /* Kernel verifier blocks program loading */
+       LIBBPF_ERRNO__PROG2BIG, /* Program too big */
+       LIBBPF_ERRNO__KVER,     /* Incorrect kernel version */
+       __LIBBPF_ERRNO__END,
+};
+
+int libbpf_strerror(int err, char *buf, size_t size);
 
 /*
  * In include/linux/compiler-gcc.h, __printf is defined. However
@@ -36,6 +56,7 @@ void bpf_object__close(struct bpf_object *object);
 int bpf_object__load(struct bpf_object *obj);
 int bpf_object__unload(struct bpf_object *obj);
 const char *bpf_object__get_name(struct bpf_object *obj);
+unsigned int bpf_object__get_kversion(struct bpf_object *obj);
 
 struct bpf_object *bpf_object__next(struct bpf_object *prev);
 #define bpf_object__for_each_safe(pos, tmp)                    \
@@ -63,7 +84,7 @@ int bpf_program__set_private(struct bpf_program *prog, void *priv,
 int bpf_program__get_private(struct bpf_program *prog,
                             void **ppriv);
 
-const char *bpf_program__title(struct bpf_program *prog, bool dup);
+const char *bpf_program__title(struct bpf_program *prog, bool needs_copy);
 
 int bpf_program__fd(struct bpf_program *prog);
 
index 8ef602f18a32b9a19c7645488bd2bc8c757c30c6..9be663340f0a4c48e9ec51c996b13c3a8b596fdc 100644 (file)
@@ -18,7 +18,7 @@ __attribute__((constructor)) static void liblockdep_init(void)
 
 __attribute__((destructor)) static void liblockdep_exit(void)
 {
-       debug_check_no_locks_held(&current_obj);
+       debug_check_no_locks_held();
 }
 
 struct task_struct *__curr(void)
index 0bda630027c30324ddf74c021ab8465c749b6833..a60c14b9662aefd6f17b47dec534bce2f53d9f03 100644 (file)
@@ -43,6 +43,8 @@ void lock_acquire(struct lockdep_map *lock, unsigned int subclass,
                        struct lockdep_map *nest_lock, unsigned long ip);
 void lock_release(struct lockdep_map *lock, int nested,
                        unsigned long ip);
+extern void debug_check_no_locks_freed(const void *from, unsigned long len);
+extern void lockdep_init(void);
 
 #define STATIC_LOCKDEP_MAP_INIT(_name, _key) \
        { .name = (_name), .key = (void *)(_key), }
index 7ac838a1f196ca673b441341f5c3976a32b30fdb..6386dc3182a0985a40551d0af980e53102e04c2a 100644 (file)
@@ -3,5 +3,7 @@
 
 #define __used         __attribute__((__unused__))
 #define unlikely
+#define WRITE_ONCE(x, val) x=(val)
+#define RCU_INIT_POINTER(p, v) p=(v)
 
 #endif
index c1552c28507e472159ebd3fecee88811e51ff263..c808c7d02d21c86732c2aab981ccebd0dad71aad 100644 (file)
@@ -6,7 +6,7 @@
 #include <string.h>
 #include <limits.h>
 #include <linux/utsname.h>
-
+#include <linux/compiler.h>
 
 #define MAX_LOCK_DEPTH 2000UL
 
@@ -54,5 +54,6 @@ static struct new_utsname *init_utsname(void)
 #define static_obj(x) 1
 
 #define debug_show_all_locks()
+extern void debug_check_no_locks_held(void);
 
 #endif
index 7ea078658a875029fb0ad03101bacdbe45e31564..13293de8869fe932c9610f3a3c5612c838a65bc4 100644 (file)
@@ -62,7 +62,6 @@ OPTIONS
 --verbose=::
         Verbosity level.
 
--i::
 --no-inherit::
        Child tasks do not inherit counters.
 
index 480546d5f13b205b85790c9512d51f33693e73a1..dcd9a70c7193b43b5791058b01a3773da6e0d870 100644 (file)
@@ -78,7 +78,7 @@ clean:
 # The build-test target is not really parallel, don't print the jobs info:
 #
 build-test:
-       @$(MAKE) -f tests/make --no-print-directory
+       @$(MAKE) SHUF=1 -f tests/make --no-print-directory
 
 #
 # All other targets get passed through:
index 0ee6d900e100a29ceeb3cacf7e97d81dce8f8d17..e3d3e32c0a934dc8fd5ce207073f3b80ecf4361a 100644 (file)
@@ -1203,12 +1203,13 @@ static void output_lat_thread(struct perf_sched *sched, struct work_atoms *work_
 
 static int pid_cmp(struct work_atoms *l, struct work_atoms *r)
 {
+       if (l->thread == r->thread)
+               return 0;
        if (l->thread->tid < r->thread->tid)
                return -1;
        if (l->thread->tid > r->thread->tid)
                return 1;
-
-       return 0;
+       return (int)(l->thread - r->thread);
 }
 
 static int avg_cmp(struct work_atoms *l, struct work_atoms *r)
index 2f438f76cceb2cb1681c30d62324e6a03c4b2108..e77880b5094ded75ac4975d4212f9e35bb9cfa2f 100644 (file)
@@ -122,6 +122,9 @@ static bool                 forever                         = false;
 static struct timespec         ref_time;
 static struct cpu_map          *aggr_map;
 static aggr_get_id_t           aggr_get_id;
+static bool                    append_file;
+static const char              *output_name;
+static int                     output_fd;
 
 static volatile int done = 0;
 
@@ -513,15 +516,6 @@ static void nsec_printout(int id, int nr, struct perf_evsel *evsel, double avg)
 
        if (evsel->cgrp)
                fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
-
-       if (csv_output || stat_config.interval)
-               return;
-
-       if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK))
-               fprintf(output, " # %8.3f CPUs utilized          ",
-                       avg / avg_stats(&walltime_nsecs_stats));
-       else
-               fprintf(output, "                                   ");
 }
 
 static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
@@ -529,7 +523,6 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
        FILE *output = stat_config.output;
        double sc =  evsel->scale;
        const char *fmt;
-       int cpu = cpu_map__id_to_cpu(id);
 
        if (csv_output) {
                fmt = sc != 1.0 ?  "%.2f%s" : "%.0f%s";
@@ -542,9 +535,6 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
 
        aggr_printout(evsel, id, nr);
 
-       if (stat_config.aggr_mode == AGGR_GLOBAL)
-               cpu = 0;
-
        fprintf(output, fmt, avg, csv_sep);
 
        if (evsel->unit)
@@ -556,12 +546,24 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
 
        if (evsel->cgrp)
                fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
+}
 
-       if (csv_output || stat_config.interval)
-               return;
+static void printout(int id, int nr, struct perf_evsel *counter, double uval)
+{
+       int cpu = cpu_map__id_to_cpu(id);
+
+       if (stat_config.aggr_mode == AGGR_GLOBAL)
+               cpu = 0;
 
-       perf_stat__print_shadow_stats(output, evsel, avg, cpu,
-                                     stat_config.aggr_mode);
+       if (nsec_counter(counter))
+               nsec_printout(id, nr, counter, uval);
+       else
+               abs_printout(id, nr, counter, uval);
+
+       if (!csv_output && !stat_config.interval)
+               perf_stat__print_shadow_stats(stat_config.output, counter,
+                                             uval, cpu,
+                                             stat_config.aggr_mode);
 }
 
 static void print_aggr(char *prefix)
@@ -617,12 +619,7 @@ static void print_aggr(char *prefix)
                                continue;
                        }
                        uval = val * counter->scale;
-
-                       if (nsec_counter(counter))
-                               nsec_printout(id, nr, counter, uval);
-                       else
-                               abs_printout(id, nr, counter, uval);
-
+                       printout(id, nr, counter, uval);
                        if (!csv_output)
                                print_noise(counter, 1.0);
 
@@ -653,11 +650,7 @@ static void print_aggr_thread(struct perf_evsel *counter, char *prefix)
                        fprintf(output, "%s", prefix);
 
                uval = val * counter->scale;
-
-               if (nsec_counter(counter))
-                       nsec_printout(thread, 0, counter, uval);
-               else
-                       abs_printout(thread, 0, counter, uval);
+               printout(thread, 0, counter, uval);
 
                if (!csv_output)
                        print_noise(counter, 1.0);
@@ -707,11 +700,7 @@ static void print_counter_aggr(struct perf_evsel *counter, char *prefix)
        }
 
        uval = avg * counter->scale;
-
-       if (nsec_counter(counter))
-               nsec_printout(-1, 0, counter, uval);
-       else
-               abs_printout(-1, 0, counter, uval);
+       printout(-1, 0, counter, uval);
 
        print_noise(counter, avg);
 
@@ -764,12 +753,7 @@ static void print_counter(struct perf_evsel *counter, char *prefix)
                }
 
                uval = val * counter->scale;
-
-               if (nsec_counter(counter))
-                       nsec_printout(cpu, 0, counter, uval);
-               else
-                       abs_printout(cpu, 0, counter, uval);
-
+               printout(cpu, 0, counter, uval);
                if (!csv_output)
                        print_noise(counter, 1.0);
                print_running(run, ena);
@@ -946,6 +930,67 @@ static int stat__set_big_num(const struct option *opt __maybe_unused,
        return 0;
 }
 
+static const struct option stat_options[] = {
+       OPT_BOOLEAN('T', "transaction", &transaction_run,
+                   "hardware transaction statistics"),
+       OPT_CALLBACK('e', "event", &evsel_list, "event",
+                    "event selector. use 'perf list' to list available events",
+                    parse_events_option),
+       OPT_CALLBACK(0, "filter", &evsel_list, "filter",
+                    "event filter", parse_filter),
+       OPT_BOOLEAN('i', "no-inherit", &no_inherit,
+                   "child tasks do not inherit counters"),
+       OPT_STRING('p', "pid", &target.pid, "pid",
+                  "stat events on existing process id"),
+       OPT_STRING('t', "tid", &target.tid, "tid",
+                  "stat events on existing thread id"),
+       OPT_BOOLEAN('a', "all-cpus", &target.system_wide,
+                   "system-wide collection from all CPUs"),
+       OPT_BOOLEAN('g', "group", &group,
+                   "put the counters into a counter group"),
+       OPT_BOOLEAN('c', "scale", &stat_config.scale, "scale/normalize counters"),
+       OPT_INCR('v', "verbose", &verbose,
+                   "be more verbose (show counter open errors, etc)"),
+       OPT_INTEGER('r', "repeat", &run_count,
+                   "repeat command and print average + stddev (max: 100, forever: 0)"),
+       OPT_BOOLEAN('n', "null", &null_run,
+                   "null run - dont start any counters"),
+       OPT_INCR('d', "detailed", &detailed_run,
+                   "detailed run - start a lot of events"),
+       OPT_BOOLEAN('S', "sync", &sync_run,
+                   "call sync() before starting a run"),
+       OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL,
+                          "print large numbers with thousands\' separators",
+                          stat__set_big_num),
+       OPT_STRING('C', "cpu", &target.cpu_list, "cpu",
+                   "list of cpus to monitor in system-wide"),
+       OPT_SET_UINT('A', "no-aggr", &stat_config.aggr_mode,
+                   "disable CPU count aggregation", AGGR_NONE),
+       OPT_STRING('x', "field-separator", &csv_sep, "separator",
+                  "print counts with custom separator"),
+       OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
+                    "monitor event in cgroup name only", parse_cgroups),
+       OPT_STRING('o', "output", &output_name, "file", "output file name"),
+       OPT_BOOLEAN(0, "append", &append_file, "append to the output file"),
+       OPT_INTEGER(0, "log-fd", &output_fd,
+                   "log output to fd, instead of stderr"),
+       OPT_STRING(0, "pre", &pre_cmd, "command",
+                       "command to run prior to the measured command"),
+       OPT_STRING(0, "post", &post_cmd, "command",
+                       "command to run after to the measured command"),
+       OPT_UINTEGER('I', "interval-print", &stat_config.interval,
+                   "print counts at regular interval in ms (>= 10)"),
+       OPT_SET_UINT(0, "per-socket", &stat_config.aggr_mode,
+                    "aggregate counts per processor socket", AGGR_SOCKET),
+       OPT_SET_UINT(0, "per-core", &stat_config.aggr_mode,
+                    "aggregate counts per physical processor core", AGGR_CORE),
+       OPT_SET_UINT(0, "per-thread", &stat_config.aggr_mode,
+                    "aggregate counts per thread", AGGR_THREAD),
+       OPT_UINTEGER('D', "delay", &initial_delay,
+                    "ms to wait before starting measurement after program start"),
+       OPT_END()
+};
+
 static int perf_stat__get_socket(struct cpu_map *map, int cpu)
 {
        return cpu_map__get_socket(map, cpu, NULL);
@@ -1193,69 +1238,6 @@ static int add_default_attributes(void)
 
 int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
 {
-       bool append_file = false;
-       int output_fd = 0;
-       const char *output_name = NULL;
-       const struct option options[] = {
-       OPT_BOOLEAN('T', "transaction", &transaction_run,
-                   "hardware transaction statistics"),
-       OPT_CALLBACK('e', "event", &evsel_list, "event",
-                    "event selector. use 'perf list' to list available events",
-                    parse_events_option),
-       OPT_CALLBACK(0, "filter", &evsel_list, "filter",
-                    "event filter", parse_filter),
-       OPT_BOOLEAN('i', "no-inherit", &no_inherit,
-                   "child tasks do not inherit counters"),
-       OPT_STRING('p', "pid", &target.pid, "pid",
-                  "stat events on existing process id"),
-       OPT_STRING('t', "tid", &target.tid, "tid",
-                  "stat events on existing thread id"),
-       OPT_BOOLEAN('a', "all-cpus", &target.system_wide,
-                   "system-wide collection from all CPUs"),
-       OPT_BOOLEAN('g', "group", &group,
-                   "put the counters into a counter group"),
-       OPT_BOOLEAN('c', "scale", &stat_config.scale, "scale/normalize counters"),
-       OPT_INCR('v', "verbose", &verbose,
-                   "be more verbose (show counter open errors, etc)"),
-       OPT_INTEGER('r', "repeat", &run_count,
-                   "repeat command and print average + stddev (max: 100, forever: 0)"),
-       OPT_BOOLEAN('n', "null", &null_run,
-                   "null run - dont start any counters"),
-       OPT_INCR('d', "detailed", &detailed_run,
-                   "detailed run - start a lot of events"),
-       OPT_BOOLEAN('S', "sync", &sync_run,
-                   "call sync() before starting a run"),
-       OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL,
-                          "print large numbers with thousands\' separators",
-                          stat__set_big_num),
-       OPT_STRING('C', "cpu", &target.cpu_list, "cpu",
-                   "list of cpus to monitor in system-wide"),
-       OPT_SET_UINT('A', "no-aggr", &stat_config.aggr_mode,
-                   "disable CPU count aggregation", AGGR_NONE),
-       OPT_STRING('x', "field-separator", &csv_sep, "separator",
-                  "print counts with custom separator"),
-       OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
-                    "monitor event in cgroup name only", parse_cgroups),
-       OPT_STRING('o', "output", &output_name, "file", "output file name"),
-       OPT_BOOLEAN(0, "append", &append_file, "append to the output file"),
-       OPT_INTEGER(0, "log-fd", &output_fd,
-                   "log output to fd, instead of stderr"),
-       OPT_STRING(0, "pre", &pre_cmd, "command",
-                       "command to run prior to the measured command"),
-       OPT_STRING(0, "post", &post_cmd, "command",
-                       "command to run after to the measured command"),
-       OPT_UINTEGER('I', "interval-print", &stat_config.interval,
-                   "print counts at regular interval in ms (>= 10)"),
-       OPT_SET_UINT(0, "per-socket", &stat_config.aggr_mode,
-                    "aggregate counts per processor socket", AGGR_SOCKET),
-       OPT_SET_UINT(0, "per-core", &stat_config.aggr_mode,
-                    "aggregate counts per physical processor core", AGGR_CORE),
-       OPT_SET_UINT(0, "per-thread", &stat_config.aggr_mode,
-                    "aggregate counts per thread", AGGR_THREAD),
-       OPT_UINTEGER('D', "delay", &initial_delay,
-                    "ms to wait before starting measurement after program start"),
-       OPT_END()
-       };
        const char * const stat_usage[] = {
                "perf stat [<options>] [<command>]",
                NULL
@@ -1271,7 +1253,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
        if (evsel_list == NULL)
                return -ENOMEM;
 
-       argc = parse_options(argc, argv, options, stat_usage,
+       argc = parse_options(argc, argv, stat_options, stat_usage,
                PARSE_OPT_STOP_AT_NON_OPTION);
 
        interval = stat_config.interval;
@@ -1281,14 +1263,14 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
 
        if (output_name && output_fd) {
                fprintf(stderr, "cannot use both --output and --log-fd\n");
-               parse_options_usage(stat_usage, options, "o", 1);
-               parse_options_usage(NULL, options, "log-fd", 0);
+               parse_options_usage(stat_usage, stat_options, "o", 1);
+               parse_options_usage(NULL, stat_options, "log-fd", 0);
                goto out;
        }
 
        if (output_fd < 0) {
                fprintf(stderr, "argument to --log-fd must be a > 0\n");
-               parse_options_usage(stat_usage, options, "log-fd", 0);
+               parse_options_usage(stat_usage, stat_options, "log-fd", 0);
                goto out;
        }
 
@@ -1328,8 +1310,8 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
                /* User explicitly passed -B? */
                if (big_num_opt == 1) {
                        fprintf(stderr, "-B option not supported with -x\n");
-                       parse_options_usage(stat_usage, options, "B", 1);
-                       parse_options_usage(NULL, options, "x", 1);
+                       parse_options_usage(stat_usage, stat_options, "B", 1);
+                       parse_options_usage(NULL, stat_options, "x", 1);
                        goto out;
                } else /* Nope, so disable big number formatting */
                        big_num = false;
@@ -1337,11 +1319,11 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
                big_num = false;
 
        if (!argc && target__none(&target))
-               usage_with_options(stat_usage, options);
+               usage_with_options(stat_usage, stat_options);
 
        if (run_count < 0) {
                pr_err("Run count must be a positive number\n");
-               parse_options_usage(stat_usage, options, "r", 1);
+               parse_options_usage(stat_usage, stat_options, "r", 1);
                goto out;
        } else if (run_count == 0) {
                forever = true;
@@ -1351,8 +1333,8 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
        if ((stat_config.aggr_mode == AGGR_THREAD) && !target__has_task(&target)) {
                fprintf(stderr, "The --per-thread option is only available "
                        "when monitoring via -p -t options.\n");
-               parse_options_usage(NULL, options, "p", 1);
-               parse_options_usage(NULL, options, "t", 1);
+               parse_options_usage(NULL, stat_options, "p", 1);
+               parse_options_usage(NULL, stat_options, "t", 1);
                goto out;
        }
 
@@ -1366,9 +1348,9 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
                fprintf(stderr, "both cgroup and no-aggregation "
                        "modes only available in system-wide mode\n");
 
-               parse_options_usage(stat_usage, options, "G", 1);
-               parse_options_usage(NULL, options, "A", 1);
-               parse_options_usage(NULL, options, "a", 1);
+               parse_options_usage(stat_usage, stat_options, "G", 1);
+               parse_options_usage(NULL, stat_options, "A", 1);
+               parse_options_usage(NULL, stat_options, "a", 1);
                goto out;
        }
 
@@ -1380,12 +1362,12 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
        if (perf_evlist__create_maps(evsel_list, &target) < 0) {
                if (target__has_task(&target)) {
                        pr_err("Problems finding threads of monitor\n");
-                       parse_options_usage(stat_usage, options, "p", 1);
-                       parse_options_usage(NULL, options, "t", 1);
+                       parse_options_usage(stat_usage, stat_options, "p", 1);
+                       parse_options_usage(NULL, stat_options, "t", 1);
                } else if (target__has_cpu(&target)) {
                        perror("failed to parse CPUs map");
-                       parse_options_usage(stat_usage, options, "C", 1);
-                       parse_options_usage(NULL, options, "a", 1);
+                       parse_options_usage(stat_usage, stat_options, "C", 1);
+                       parse_options_usage(NULL, stat_options, "a", 1);
                }
                goto out;
        }
@@ -1400,7 +1382,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
        if (interval && interval < 100) {
                if (interval < 10) {
                        pr_err("print interval must be >= 10ms\n");
-                       parse_options_usage(stat_usage, options, "I", 1);
+                       parse_options_usage(stat_usage, stat_options, "I", 1);
                        goto out;
                } else
                        pr_warning("print interval < 100ms. "
diff --git a/tools/perf/tests/.gitignore b/tools/perf/tests/.gitignore
new file mode 100644 (file)
index 0000000..489fc9f
--- /dev/null
@@ -0,0 +1,2 @@
+llvm-src-base.c
+llvm-src-kbuild.c
index 50de2253cff6c64450a23d0332d22c43c802dd8f..f41ebf8849feb1d5fe20e2601de952c85e3bac8c 100644 (file)
@@ -31,9 +31,24 @@ perf-y += sample-parsing.o
 perf-y += parse-no-sample-id-all.o
 perf-y += kmod-path.o
 perf-y += thread-map.o
-perf-y += llvm.o
+perf-y += llvm.o llvm-src-base.o llvm-src-kbuild.o
+perf-y += bpf.o
 perf-y += topology.o
 
+$(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c
+       $(call rule_mkdir)
+       $(Q)echo '#include <tests/llvm.h>' > $@
+       $(Q)echo 'const char test_llvm__bpf_base_prog[] =' >> $@
+       $(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@
+       $(Q)echo ';' >> $@
+
+$(OUTPUT)tests/llvm-src-kbuild.c: tests/bpf-script-test-kbuild.c
+       $(call rule_mkdir)
+       $(Q)echo '#include <tests/llvm.h>' > $@
+       $(Q)echo 'const char test_llvm__bpf_test_kbuild_prog[] =' >> $@
+       $(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@
+       $(Q)echo ';' >> $@
+
 ifeq ($(ARCH),$(filter $(ARCH),x86 arm arm64))
 perf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o
 endif
index 2dfc9ad0e6f2487d730008fac56988f9b408666d..638875a0960a1e8d8b786a4b7c73dab463050857 100644 (file)
@@ -171,6 +171,5 @@ int test__attr(void)
            !lstat(path_perf, &st))
                return run_dir(path_dir, path_perf);
 
-       fprintf(stderr, " (omitted)");
-       return 0;
+       return TEST_SKIP;
 }
index 410a70b93b934e0632cedeb7b42f4526198e7220..0ec9c2c031649377a2523deda904ea1a7c9284c0 100644 (file)
@@ -1,3 +1,7 @@
+/*
+ * bpf-script-example.c
+ * Test basic LLVM building
+ */
 #ifndef LINUX_VERSION_CODE
 # error Need LINUX_VERSION_CODE
 # error Example: for 4.2 kernel, put 'clang-opt="-DLINUX_VERSION_CODE=0x40200" into llvm section of ~/.perfconfig'
diff --git a/tools/perf/tests/bpf-script-test-kbuild.c b/tools/perf/tests/bpf-script-test-kbuild.c
new file mode 100644 (file)
index 0000000..3626924
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * bpf-script-test-kbuild.c
+ * Test include from kernel header
+ */
+#ifndef LINUX_VERSION_CODE
+# error Need LINUX_VERSION_CODE
+# error Example: for 4.2 kernel, put 'clang-opt="-DLINUX_VERSION_CODE=0x40200" into llvm section of ~/.perfconfig'
+#endif
+#define SEC(NAME) __attribute__((section(NAME), used))
+
+#include <uapi/linux/fs.h>
+#include <uapi/asm/ptrace.h>
+
+SEC("func=vfs_llseek")
+int bpf_func__vfs_llseek(void *ctx)
+{
+       return 0;
+}
+
+char _license[] SEC("license") = "GPL";
+int _version SEC("version") = LINUX_VERSION_CODE;
diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c
new file mode 100644 (file)
index 0000000..ec16f78
--- /dev/null
@@ -0,0 +1,209 @@
+#include <stdio.h>
+#include <sys/epoll.h>
+#include <util/bpf-loader.h>
+#include <util/evlist.h>
+#include "tests.h"
+#include "llvm.h"
+#include "debug.h"
+#define NR_ITERS       111
+
+#ifdef HAVE_LIBBPF_SUPPORT
+
+static int epoll_pwait_loop(void)
+{
+       int i;
+
+       /* Should fail NR_ITERS times */
+       for (i = 0; i < NR_ITERS; i++)
+               epoll_pwait(-(i + 1), NULL, 0, 0, NULL);
+       return 0;
+}
+
+static struct {
+       enum test_llvm__testcase prog_id;
+       const char *desc;
+       const char *name;
+       const char *msg_compile_fail;
+       const char *msg_load_fail;
+       int (*target_func)(void);
+       int expect_result;
+} bpf_testcase_table[] = {
+       {
+               LLVM_TESTCASE_BASE,
+               "Test basic BPF filtering",
+               "[basic_bpf_test]",
+               "fix 'perf test LLVM' first",
+               "load bpf object failed",
+               &epoll_pwait_loop,
+               (NR_ITERS + 1) / 2,
+       },
+};
+
+static int do_test(struct bpf_object *obj, int (*func)(void),
+                  int expect)
+{
+       struct record_opts opts = {
+               .target = {
+                       .uid = UINT_MAX,
+                       .uses_mmap = true,
+               },
+               .freq         = 0,
+               .mmap_pages   = 256,
+               .default_interval = 1,
+       };
+
+       char pid[16];
+       char sbuf[STRERR_BUFSIZE];
+       struct perf_evlist *evlist;
+       int i, ret = TEST_FAIL, err = 0, count = 0;
+
+       struct parse_events_evlist parse_evlist;
+       struct parse_events_error parse_error;
+
+       bzero(&parse_error, sizeof(parse_error));
+       bzero(&parse_evlist, sizeof(parse_evlist));
+       parse_evlist.error = &parse_error;
+       INIT_LIST_HEAD(&parse_evlist.list);
+
+       err = parse_events_load_bpf_obj(&parse_evlist, &parse_evlist.list, obj);
+       if (err || list_empty(&parse_evlist.list)) {
+               pr_debug("Failed to add events selected by BPF\n");
+               if (!err)
+                       return TEST_FAIL;
+       }
+
+       snprintf(pid, sizeof(pid), "%d", getpid());
+       pid[sizeof(pid) - 1] = '\0';
+       opts.target.tid = opts.target.pid = pid;
+
+       /* Instead of perf_evlist__new_default, don't add default events */
+       evlist = perf_evlist__new();
+       if (!evlist) {
+               pr_debug("No ehough memory to create evlist\n");
+               return TEST_FAIL;
+       }
+
+       err = perf_evlist__create_maps(evlist, &opts.target);
+       if (err < 0) {
+               pr_debug("Not enough memory to create thread/cpu maps\n");
+               goto out_delete_evlist;
+       }
+
+       perf_evlist__splice_list_tail(evlist, &parse_evlist.list);
+       evlist->nr_groups = parse_evlist.nr_groups;
+
+       perf_evlist__config(evlist, &opts);
+
+       err = perf_evlist__open(evlist);
+       if (err < 0) {
+               pr_debug("perf_evlist__open: %s\n",
+                        strerror_r(errno, sbuf, sizeof(sbuf)));
+               goto out_delete_evlist;
+       }
+
+       err = perf_evlist__mmap(evlist, opts.mmap_pages, false);
+       if (err < 0) {
+               pr_debug("perf_evlist__mmap: %s\n",
+                        strerror_r(errno, sbuf, sizeof(sbuf)));
+               goto out_delete_evlist;
+       }
+
+       perf_evlist__enable(evlist);
+       (*func)();
+       perf_evlist__disable(evlist);
+
+       for (i = 0; i < evlist->nr_mmaps; i++) {
+               union perf_event *event;
+
+               while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) {
+                       const u32 type = event->header.type;
+
+                       if (type == PERF_RECORD_SAMPLE)
+                               count ++;
+               }
+       }
+
+       if (count != expect)
+               pr_debug("BPF filter result incorrect\n");
+
+       ret = TEST_OK;
+
+out_delete_evlist:
+       perf_evlist__delete(evlist);
+       return ret;
+}
+
+static struct bpf_object *
+prepare_bpf(void *obj_buf, size_t obj_buf_sz, const char *name)
+{
+       struct bpf_object *obj;
+
+       obj = bpf__prepare_load_buffer(obj_buf, obj_buf_sz, name);
+       if (IS_ERR(obj)) {
+               pr_debug("Compile BPF program failed.\n");
+               return NULL;
+       }
+       return obj;
+}
+
+static int __test__bpf(int index)
+{
+       int ret;
+       void *obj_buf;
+       size_t obj_buf_sz;
+       struct bpf_object *obj;
+
+       ret = test_llvm__fetch_bpf_obj(&obj_buf, &obj_buf_sz,
+                                      bpf_testcase_table[index].prog_id,
+                                      true);
+       if (ret != TEST_OK || !obj_buf || !obj_buf_sz) {
+               pr_debug("Unable to get BPF object, %s\n",
+                        bpf_testcase_table[index].msg_compile_fail);
+               if (index == 0)
+                       return TEST_SKIP;
+               else
+                       return TEST_FAIL;
+       }
+
+       obj = prepare_bpf(obj_buf, obj_buf_sz,
+                         bpf_testcase_table[index].name);
+       if (!obj) {
+               ret = TEST_FAIL;
+               goto out;
+       }
+
+       ret = do_test(obj,
+                     bpf_testcase_table[index].target_func,
+                     bpf_testcase_table[index].expect_result);
+out:
+       bpf__clear();
+       return ret;
+}
+
+int test__bpf(void)
+{
+       unsigned int i;
+       int err;
+
+       if (geteuid() != 0) {
+               pr_debug("Only root can run BPF test\n");
+               return TEST_SKIP;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(bpf_testcase_table); i++) {
+               err = __test__bpf(i);
+
+               if (err != TEST_OK)
+                       return err;
+       }
+
+       return TEST_OK;
+}
+
+#else
+int test__bpf(void)
+{
+       pr_debug("Skip BPF test because BPF support is not compiled\n");
+       return TEST_SKIP;
+}
+#endif
index 66f72d3d66771ab4c9ad1cec7a53b92d8bcb8f1b..80c442eab767d0c333408c8daecbc32d3a120d0e 100644 (file)
@@ -165,6 +165,10 @@ static struct test generic_tests[] = {
                .desc = "Test topology in session",
                .func = test_session_topology,
        },
+       {
+               .desc = "Test BPF filter",
+               .func = test__bpf,
+       },
        {
                .func = NULL,
        },
@@ -192,7 +196,7 @@ static bool perf_test__matches(struct test *test, int curr, int argc, const char
                        continue;
                }
 
-               if (strstr(test->desc, argv[i]))
+               if (strcasestr(test->desc, argv[i]))
                        return true;
        }
 
index 49b1959dda41f0ceb5bc248f3c3e90b558ce9169..a767a6400c5ced49b16b9b4be7a3ea638799998d 100644 (file)
@@ -613,16 +613,16 @@ int test__code_reading(void)
        case TEST_CODE_READING_OK:
                return 0;
        case TEST_CODE_READING_NO_VMLINUX:
-               fprintf(stderr, " (no vmlinux)");
+               pr_debug("no vmlinux\n");
                return 0;
        case TEST_CODE_READING_NO_KCORE:
-               fprintf(stderr, " (no kcore)");
+               pr_debug("no kcore\n");
                return 0;
        case TEST_CODE_READING_NO_ACCESS:
-               fprintf(stderr, " (no access)");
+               pr_debug("no access\n");
                return 0;
        case TEST_CODE_READING_NO_KERNEL_OBJ:
-               fprintf(stderr, " (no kernel obj)");
+               pr_debug("no kernel obj\n");
                return 0;
        default:
                return -1;
index 4d4b9837b630ae9fd72cb0a404a4bae0e3864e14..a2e2269aa093a902f4810304d4af7e2fb8767b5c 100644 (file)
@@ -90,8 +90,8 @@ int test__keep_tracking(void)
        evsel->attr.enable_on_exec = 0;
 
        if (perf_evlist__open(evlist) < 0) {
-               fprintf(stderr, " (not supported)");
-               err = 0;
+               pr_debug("Unable to open dummy and cycles event\n");
+               err = TEST_SKIP;
                goto out_err;
        }
 
index 52d55971f66f6f569db38db00b87101e7aa61507..bc4cf507cde50b7018bac107e152ba9f23ab007d 100644 (file)
@@ -2,6 +2,7 @@
 #include <bpf/libbpf.h>
 #include <util/llvm-utils.h>
 #include <util/cache.h>
+#include "llvm.h"
 #include "tests.h"
 #include "debug.h"
 
@@ -11,42 +12,58 @@ static int perf_config_cb(const char *var, const char *val,
        return perf_default_config(var, val, arg);
 }
 
-/*
- * Randomly give it a "version" section since we don't really load it
- * into kernel
- */
-static const char test_bpf_prog[] =
-       "__attribute__((section(\"do_fork\"), used)) "
-       "int fork(void *ctx) {return 0;} "
-       "char _license[] __attribute__((section(\"license\"), used)) = \"GPL\";"
-       "int _version __attribute__((section(\"version\"), used)) = 0x40100;";
-
 #ifdef HAVE_LIBBPF_SUPPORT
 static int test__bpf_parsing(void *obj_buf, size_t obj_buf_sz)
 {
        struct bpf_object *obj;
 
        obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, NULL);
-       if (!obj)
-               return -1;
+       if (IS_ERR(obj))
+               return TEST_FAIL;
        bpf_object__close(obj);
-       return 0;
+       return TEST_OK;
 }
 #else
 static int test__bpf_parsing(void *obj_buf __maybe_unused,
                             size_t obj_buf_sz __maybe_unused)
 {
-       fprintf(stderr, " (skip bpf parsing)");
-       return 0;
+       pr_debug("Skip bpf parsing\n");
+       return TEST_OK;
 }
 #endif
 
-int test__llvm(void)
+static struct {
+       const char *source;
+       const char *desc;
+} bpf_source_table[__LLVM_TESTCASE_MAX] = {
+       [LLVM_TESTCASE_BASE] = {
+               .source = test_llvm__bpf_base_prog,
+               .desc = "Basic BPF llvm compiling test",
+       },
+       [LLVM_TESTCASE_KBUILD] = {
+               .source = test_llvm__bpf_test_kbuild_prog,
+               .desc = "Test kbuild searching",
+       },
+};
+
+
+int
+test_llvm__fetch_bpf_obj(void **p_obj_buf,
+                        size_t *p_obj_buf_sz,
+                        enum test_llvm__testcase index,
+                        bool force)
 {
-       char *tmpl_new, *clang_opt_new;
-       void *obj_buf;
-       size_t obj_buf_sz;
-       int err, old_verbose;
+       const char *source;
+       const char *desc;
+       const char *tmpl_old, *clang_opt_old;
+       char *tmpl_new = NULL, *clang_opt_new = NULL;
+       int err, old_verbose, ret = TEST_FAIL;
+
+       if (index >= __LLVM_TESTCASE_MAX)
+               return TEST_FAIL;
+
+       source = bpf_source_table[index].source;
+       desc = bpf_source_table[index].desc;
 
        perf_config(perf_config_cb, NULL);
 
@@ -54,45 +71,100 @@ int test__llvm(void)
         * Skip this test if user's .perfconfig doesn't set [llvm] section
         * and clang is not found in $PATH, and this is not perf test -v
         */
-       if (verbose == 0 && !llvm_param.user_set_param && llvm__search_clang()) {
-               fprintf(stderr, " (no clang, try 'perf test -v LLVM')");
+       if (!force && (verbose == 0 &&
+                      !llvm_param.user_set_param &&
+                      llvm__search_clang())) {
+               pr_debug("No clang and no verbosive, skip this test\n");
                return TEST_SKIP;
        }
 
-       old_verbose = verbose;
        /*
         * llvm is verbosity when error. Suppress all error output if
         * not 'perf test -v'.
         */
+       old_verbose = verbose;
        if (verbose == 0)
                verbose = -1;
 
+       *p_obj_buf = NULL;
+       *p_obj_buf_sz = 0;
+
        if (!llvm_param.clang_bpf_cmd_template)
-               return -1;
+               goto out;
 
        if (!llvm_param.clang_opt)
                llvm_param.clang_opt = strdup("");
 
-       err = asprintf(&tmpl_new, "echo '%s' | %s", test_bpf_prog,
-                      llvm_param.clang_bpf_cmd_template);
+       err = asprintf(&tmpl_new, "echo '%s' | %s%s", source,
+                      llvm_param.clang_bpf_cmd_template,
+                      old_verbose ? "" : " 2>/dev/null");
        if (err < 0)
-               return -1;
+               goto out;
        err = asprintf(&clang_opt_new, "-xc %s", llvm_param.clang_opt);
        if (err < 0)
-               return -1;
+               goto out;
 
+       tmpl_old = llvm_param.clang_bpf_cmd_template;
        llvm_param.clang_bpf_cmd_template = tmpl_new;
+       clang_opt_old = llvm_param.clang_opt;
        llvm_param.clang_opt = clang_opt_new;
-       err = llvm__compile_bpf("-", &obj_buf, &obj_buf_sz);
+
+       err = llvm__compile_bpf("-", p_obj_buf, p_obj_buf_sz);
+
+       llvm_param.clang_bpf_cmd_template = tmpl_old;
+       llvm_param.clang_opt = clang_opt_old;
 
        verbose = old_verbose;
-       if (err) {
-               if (!verbose)
-                       fprintf(stderr, " (use -v to see error message)");
-               return -1;
-       }
+       if (err)
+               goto out;
+
+       ret = TEST_OK;
+out:
+       free(tmpl_new);
+       free(clang_opt_new);
+       if (ret != TEST_OK)
+               pr_debug("Failed to compile test case: '%s'\n", desc);
+       return ret;
+}
+
+int test__llvm(void)
+{
+       enum test_llvm__testcase i;
+
+       for (i = 0; i < __LLVM_TESTCASE_MAX; i++) {
+               int ret;
+               void *obj_buf = NULL;
+               size_t obj_buf_sz = 0;
+
+               ret = test_llvm__fetch_bpf_obj(&obj_buf, &obj_buf_sz,
+                                              i, false);
 
-       err = test__bpf_parsing(obj_buf, obj_buf_sz);
-       free(obj_buf);
-       return err;
+               if (ret == TEST_OK) {
+                       ret = test__bpf_parsing(obj_buf, obj_buf_sz);
+                       if (ret != TEST_OK)
+                               pr_debug("Failed to parse test case '%s'\n",
+                                        bpf_source_table[i].desc);
+               }
+               free(obj_buf);
+
+               switch (ret) {
+               case TEST_SKIP:
+                       return TEST_SKIP;
+               case TEST_OK:
+                       break;
+               default:
+                       /*
+                        * Test 0 is the basic LLVM test. If test 0
+                        * fail, the basic LLVM support not functional
+                        * so the whole test should fail. If other test
+                        * case fail, it can be fixed by adjusting
+                        * config so don't report error.
+                        */
+                       if (i == 0)
+                               return TEST_FAIL;
+                       else
+                               return TEST_SKIP;
+               }
+       }
+       return TEST_OK;
 }
diff --git a/tools/perf/tests/llvm.h b/tools/perf/tests/llvm.h
new file mode 100644 (file)
index 0000000..d91d8f4
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef PERF_TEST_LLVM_H
+#define PERF_TEST_LLVM_H
+
+#include <stddef.h> /* for size_t */
+#include <stdbool.h> /* for bool */
+
+extern const char test_llvm__bpf_base_prog[];
+extern const char test_llvm__bpf_test_kbuild_prog[];
+
+enum test_llvm__testcase {
+       LLVM_TESTCASE_BASE,
+       LLVM_TESTCASE_KBUILD,
+       __LLVM_TESTCASE_MAX,
+};
+
+int test_llvm__fetch_bpf_obj(void **p_obj_buf, size_t *p_obj_buf_sz,
+                            enum test_llvm__testcase index, bool force);
+#endif
index 2cbd0c6901e35ff3954bf06892bb02b3c9f92cef..8ea3dffc5065fbc532ebfe5a170d64f33f18ed3d 100644 (file)
@@ -221,6 +221,11 @@ test_O = $(if $(test_$1),$(test_$1),$(test_default_O))
 
 all:
 
+ifdef SHUF
+run := $(shell shuf -e $(run))
+run_O := $(shell shuf -e $(run_O))
+endif
+
 ifdef DEBUG
 d := $(info run   $(run))
 d := $(info run_O $(run_O))
index e698742d4fec3300ac6c6b00bf55696414567dd4..a02af503100c9c51c1f961c9e089546ccdcfd000 100644 (file)
@@ -366,7 +366,7 @@ int test__switch_tracking(void)
 
        /* Third event */
        if (!perf_evlist__can_select_event(evlist, sched_switch)) {
-               fprintf(stderr, " (no sched_switch)");
+               pr_debug("No sched_switch\n");
                err = 0;
                goto out;
        }
@@ -442,7 +442,7 @@ int test__switch_tracking(void)
        }
 
        if (perf_evlist__open(evlist) < 0) {
-               fprintf(stderr, " (not supported)");
+               pr_debug("Not supported\n");
                err = 0;
                goto out;
        }
index c80486969f83412621336a33ee95edef87d2fb31..3c8734a3abbc5ba24c9feb90c3cbdf3c5c1dfc7e 100644 (file)
@@ -66,6 +66,7 @@ int test__fdarray__add(void);
 int test__kmod_path__parse(void);
 int test__thread_map(void);
 int test__llvm(void);
+int test__bpf(void);
 int test_session_topology(void);
 
 #if defined(__arm__) || defined(__aarch64__)
index 0fc8d7a2fea5f2ddee03789c3c0b442278f0fb0a..1dd1949b0e7995e43f0fa216fee0db583803ed5c 100644 (file)
@@ -1084,6 +1084,7 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize)
        struct kcore_extract kce;
        bool delete_extract = false;
        int lineno = 0;
+       int nline;
 
        if (filename)
                symbol__join_symfs(symfs_filename, filename);
@@ -1179,6 +1180,9 @@ fallback:
 
                ret = decompress_to_file(m.ext, symfs_filename, fd);
 
+               if (ret)
+                       pr_err("Cannot decompress %s %s\n", m.ext, symfs_filename);
+
                free(m.ext);
                close(fd);
 
@@ -1204,13 +1208,25 @@ fallback:
        pr_debug("Executing: %s\n", command);
 
        file = popen(command, "r");
-       if (!file)
+       if (!file) {
+               pr_err("Failure running %s\n", command);
+               /*
+                * If we were using debug info should retry with
+                * original binary.
+                */
                goto out_remove_tmp;
+       }
 
-       while (!feof(file))
+       nline = 0;
+       while (!feof(file)) {
                if (symbol__parse_objdump_line(sym, map, file, privsize,
                            &lineno) < 0)
                        break;
+               nline++;
+       }
+
+       if (nline == 0)
+               pr_err("No output from %s\n", command);
 
        /*
         * kallsyms does not have symbol sizes so there may a nop at the end.
@@ -1604,6 +1620,7 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map,
        len = symbol__size(sym);
 
        if (print_lines) {
+               srcline_full_filename = full_paths;
                symbol__get_source_line(sym, map, evsel, &source_line, len);
                print_summary(&source_line, dso->long_name);
        }
index ba6f7526b282805c62337479926256949fe09bfc..4c50411371db31208c361115331695571fe545b7 100644 (file)
@@ -26,18 +26,40 @@ static int libbpf_##name(const char *fmt, ...)      \
        return ret;                             \
 }
 
-DEFINE_PRINT_FN(warning, 0)
-DEFINE_PRINT_FN(info, 0)
+DEFINE_PRINT_FN(warning, 1)
+DEFINE_PRINT_FN(info, 1)
 DEFINE_PRINT_FN(debug, 1)
 
 struct bpf_prog_priv {
        struct perf_probe_event pev;
 };
 
+static bool libbpf_initialized;
+
+struct bpf_object *
+bpf__prepare_load_buffer(void *obj_buf, size_t obj_buf_sz, const char *name)
+{
+       struct bpf_object *obj;
+
+       if (!libbpf_initialized) {
+               libbpf_set_print(libbpf_warning,
+                                libbpf_info,
+                                libbpf_debug);
+               libbpf_initialized = true;
+       }
+
+       obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, name);
+       if (IS_ERR(obj)) {
+               pr_debug("bpf: failed to load buffer\n");
+               return ERR_PTR(-EINVAL);
+       }
+
+       return obj;
+}
+
 struct bpf_object *bpf__prepare_load(const char *filename, bool source)
 {
        struct bpf_object *obj;
-       static bool libbpf_initialized;
 
        if (!libbpf_initialized) {
                libbpf_set_print(libbpf_warning,
@@ -53,15 +75,15 @@ struct bpf_object *bpf__prepare_load(const char *filename, bool source)
 
                err = llvm__compile_bpf(filename, &obj_buf, &obj_buf_sz);
                if (err)
-                       return ERR_PTR(err);
+                       return ERR_PTR(-BPF_LOADER_ERRNO__COMPILE);
                obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, filename);
                free(obj_buf);
        } else
                obj = bpf_object__open(filename);
 
-       if (!obj) {
+       if (IS_ERR(obj)) {
                pr_debug("bpf: failed to load %s\n", filename);
-               return ERR_PTR(-EINVAL);
+               return obj;
        }
 
        return obj;
@@ -96,9 +118,9 @@ config_bpf_program(struct bpf_program *prog)
        int err;
 
        config_str = bpf_program__title(prog, false);
-       if (!config_str) {
+       if (IS_ERR(config_str)) {
                pr_debug("bpf: unable to get title for program\n");
-               return -EINVAL;
+               return PTR_ERR(config_str);
        }
 
        priv = calloc(sizeof(*priv), 1);
@@ -113,14 +135,14 @@ config_bpf_program(struct bpf_program *prog)
        if (err < 0) {
                pr_debug("bpf: '%s' is not a valid config string\n",
                         config_str);
-               err = -EINVAL;
+               err = -BPF_LOADER_ERRNO__CONFIG;
                goto errout;
        }
 
        if (pev->group && strcmp(pev->group, PERF_BPF_PROBE_GROUP)) {
                pr_debug("bpf: '%s': group for event is set and not '%s'.\n",
                         config_str, PERF_BPF_PROBE_GROUP);
-               err = -EINVAL;
+               err = -BPF_LOADER_ERRNO__GROUP;
                goto errout;
        } else if (!pev->group)
                pev->group = strdup(PERF_BPF_PROBE_GROUP);
@@ -132,9 +154,9 @@ config_bpf_program(struct bpf_program *prog)
        }
 
        if (!pev->event) {
-               pr_debug("bpf: '%s': event name is missing\n",
+               pr_debug("bpf: '%s': event name is missing. Section name should be 'key=value'\n",
                         config_str);
-               err = -EINVAL;
+               err = -BPF_LOADER_ERRNO__EVENTNAME;
                goto errout;
        }
        pr_debug("bpf: config '%s' is ok\n", config_str);
@@ -285,7 +307,7 @@ int bpf__foreach_tev(struct bpf_object *obj,
                                (void **)&priv);
                if (err || !priv) {
                        pr_debug("bpf: failed to get private field\n");
-                       return -EINVAL;
+                       return -BPF_LOADER_ERRNO__INTERNAL;
                }
 
                pev = &priv->pev;
@@ -308,13 +330,57 @@ int bpf__foreach_tev(struct bpf_object *obj,
        return 0;
 }
 
+#define ERRNO_OFFSET(e)                ((e) - __BPF_LOADER_ERRNO__START)
+#define ERRCODE_OFFSET(c)      ERRNO_OFFSET(BPF_LOADER_ERRNO__##c)
+#define NR_ERRNO       (__BPF_LOADER_ERRNO__END - __BPF_LOADER_ERRNO__START)
+
+static const char *bpf_loader_strerror_table[NR_ERRNO] = {
+       [ERRCODE_OFFSET(CONFIG)]        = "Invalid config string",
+       [ERRCODE_OFFSET(GROUP)]         = "Invalid group name",
+       [ERRCODE_OFFSET(EVENTNAME)]     = "No event name found in config string",
+       [ERRCODE_OFFSET(INTERNAL)]      = "BPF loader internal error",
+       [ERRCODE_OFFSET(COMPILE)]       = "Error when compiling BPF scriptlet",
+};
+
+static int
+bpf_loader_strerror(int err, char *buf, size_t size)
+{
+       char sbuf[STRERR_BUFSIZE];
+       const char *msg;
+
+       if (!buf || !size)
+               return -1;
+
+       err = err > 0 ? err : -err;
+
+       if (err >= __LIBBPF_ERRNO__START)
+               return libbpf_strerror(err, buf, size);
+
+       if (err >= __BPF_LOADER_ERRNO__START && err < __BPF_LOADER_ERRNO__END) {
+               msg = bpf_loader_strerror_table[ERRNO_OFFSET(err)];
+               snprintf(buf, size, "%s", msg);
+               buf[size - 1] = '\0';
+               return 0;
+       }
+
+       if (err >= __BPF_LOADER_ERRNO__END)
+               snprintf(buf, size, "Unknown bpf loader error %d", err);
+       else
+               snprintf(buf, size, "%s",
+                        strerror_r(err, sbuf, sizeof(sbuf)));
+
+       buf[size - 1] = '\0';
+       return -1;
+}
+
 #define bpf__strerror_head(err, buf, size) \
        char sbuf[STRERR_BUFSIZE], *emsg;\
        if (!size)\
                return 0;\
        if (err < 0)\
                err = -err;\
-       emsg = strerror_r(err, sbuf, sizeof(sbuf));\
+       bpf_loader_strerror(err, sbuf, sizeof(sbuf));\
+       emsg = sbuf;\
        switch (err) {\
        default:\
                scnprintf(buf, size, "%s", emsg);\
@@ -330,23 +396,62 @@ int bpf__foreach_tev(struct bpf_object *obj,
        }\
        buf[size - 1] = '\0';
 
+int bpf__strerror_prepare_load(const char *filename, bool source,
+                              int err, char *buf, size_t size)
+{
+       size_t n;
+       int ret;
+
+       n = snprintf(buf, size, "Failed to load %s%s: ",
+                        filename, source ? " from source" : "");
+       if (n >= size) {
+               buf[size - 1] = '\0';
+               return 0;
+       }
+       buf += n;
+       size -= n;
+
+       ret = bpf_loader_strerror(err, buf, size);
+       buf[size - 1] = '\0';
+       return ret;
+}
+
 int bpf__strerror_probe(struct bpf_object *obj __maybe_unused,
                        int err, char *buf, size_t size)
 {
        bpf__strerror_head(err, buf, size);
        bpf__strerror_entry(EEXIST, "Probe point exist. Try use 'perf probe -d \"*\"'");
-       bpf__strerror_entry(EPERM, "You need to be root, and /proc/sys/kernel/kptr_restrict should be 0\n");
-       bpf__strerror_entry(ENOENT, "You need to check probing points in BPF file\n");
+       bpf__strerror_entry(EACCES, "You need to be root");
+       bpf__strerror_entry(EPERM, "You need to be root, and /proc/sys/kernel/kptr_restrict should be 0");
+       bpf__strerror_entry(ENOENT, "You need to check probing points in BPF file");
        bpf__strerror_end(buf, size);
        return 0;
 }
 
-int bpf__strerror_load(struct bpf_object *obj __maybe_unused,
+int bpf__strerror_load(struct bpf_object *obj,
                       int err, char *buf, size_t size)
 {
        bpf__strerror_head(err, buf, size);
-       bpf__strerror_entry(EINVAL, "%s: Are you root and runing a CONFIG_BPF_SYSCALL kernel?",
-                           emsg)
+       case LIBBPF_ERRNO__KVER: {
+               unsigned int obj_kver = bpf_object__get_kversion(obj);
+               unsigned int real_kver;
+
+               if (fetch_kernel_version(&real_kver, NULL, 0)) {
+                       scnprintf(buf, size, "Unable to fetch kernel version");
+                       break;
+               }
+
+               if (obj_kver != real_kver) {
+                       scnprintf(buf, size,
+                                 "'version' ("KVER_FMT") doesn't match running kernel ("KVER_FMT")",
+                                 KVER_PARAM(obj_kver),
+                                 KVER_PARAM(real_kver));
+                       break;
+               }
+
+               scnprintf(buf, size, "Failed to load program for unknown reason");
+               break;
+       }
        bpf__strerror_end(buf, size);
        return 0;
 }
index ccd8d7fd79d3443bde634534580883a19adde53e..9caf3ae4acf3d018a87d92bb62f16c4337bd6388 100644 (file)
@@ -8,9 +8,21 @@
 #include <linux/compiler.h>
 #include <linux/err.h>
 #include <string.h>
+#include <bpf/libbpf.h>
 #include "probe-event.h"
 #include "debug.h"
 
+enum bpf_loader_errno {
+       __BPF_LOADER_ERRNO__START = __LIBBPF_ERRNO__START - 100,
+       /* Invalid config string */
+       BPF_LOADER_ERRNO__CONFIG = __BPF_LOADER_ERRNO__START,
+       BPF_LOADER_ERRNO__GROUP,        /* Invalid group name */
+       BPF_LOADER_ERRNO__EVENTNAME,    /* Event name is missing */
+       BPF_LOADER_ERRNO__INTERNAL,     /* BPF loader internal error */
+       BPF_LOADER_ERRNO__COMPILE,      /* Error when compiling BPF scriptlet */
+       __BPF_LOADER_ERRNO__END,
+};
+
 struct bpf_object;
 #define PERF_BPF_PROBE_GROUP "perf_bpf_probe"
 
@@ -19,6 +31,11 @@ typedef int (*bpf_prog_iter_callback_t)(struct probe_trace_event *tev,
 
 #ifdef HAVE_LIBBPF_SUPPORT
 struct bpf_object *bpf__prepare_load(const char *filename, bool source);
+int bpf__strerror_prepare_load(const char *filename, bool source,
+                              int err, char *buf, size_t size);
+
+struct bpf_object *bpf__prepare_load_buffer(void *obj_buf, size_t obj_buf_sz,
+                                           const char *name);
 
 void bpf__clear(void);
 
@@ -41,6 +58,13 @@ bpf__prepare_load(const char *filename __maybe_unused,
        return ERR_PTR(-ENOTSUP);
 }
 
+static inline struct bpf_object *
+bpf__prepare_load_buffer(void *obj_buf __maybe_unused,
+                                          size_t obj_buf_sz __maybe_unused)
+{
+       return ERR_PTR(-ENOTSUP);
+}
+
 static inline void bpf__clear(void) { }
 
 static inline int bpf__probe(struct bpf_object *obj __maybe_unused) { return 0;}
@@ -67,6 +91,15 @@ __bpf_strerror(char *buf, size_t size)
        return 0;
 }
 
+static inline
+int bpf__strerror_prepare_load(const char *filename __maybe_unused,
+                              bool source __maybe_unused,
+                              int err __maybe_unused,
+                              char *buf, size_t size)
+{
+       return __bpf_strerror(buf, size);
+}
+
 static inline int
 bpf__strerror_probe(struct bpf_object *obj __maybe_unused,
                    int err __maybe_unused,
index 4f6a4780bd5feebcae44a480599dea6453ed557b..00724d496d38c41483d074b52ff84768441151b3 100644 (file)
@@ -4,17 +4,18 @@
  */
 
 #include <stdio.h>
-#include <sys/utsname.h>
 #include "util.h"
 #include "debug.h"
 #include "llvm-utils.h"
 #include "cache.h"
 
 #define CLANG_BPF_CMD_DEFAULT_TEMPLATE                         \
-               "$CLANG_EXEC -D__KERNEL__ $CLANG_OPTIONS "      \
-               "$KERNEL_INC_OPTIONS -Wno-unused-value "        \
-               "-Wno-pointer-sign -working-directory "         \
-               "$WORKING_DIR -c \"$CLANG_SOURCE\" -target bpf -O2 -o -"
+               "$CLANG_EXEC -D__KERNEL__ -D__NR_CPUS__=$NR_CPUS "\
+               "-DLINUX_VERSION_CODE=$LINUX_VERSION_CODE "     \
+               "$CLANG_OPTIONS $KERNEL_INC_OPTIONS "           \
+               "-Wno-unused-value -Wno-pointer-sign "          \
+               "-working-directory $WORKING_DIR "              \
+               "-c \"$CLANG_SOURCE\" -target bpf -O2 -o -"
 
 struct llvm_param llvm_param = {
        .clang_path = "clang",
@@ -214,18 +215,19 @@ static int detect_kbuild_dir(char **kbuild_dir)
        const char *suffix_dir = "";
 
        char *autoconf_path;
-       struct utsname utsname;
 
        int err;
 
        if (!test_dir) {
-               err = uname(&utsname);
-               if (err) {
-                       pr_warning("uname failed: %s\n", strerror(errno));
+               /* _UTSNAME_LENGTH is 65 */
+               char release[128];
+
+               err = fetch_kernel_version(NULL, release,
+                                          sizeof(release));
+               if (err)
                        return -EINVAL;
-               }
 
-               test_dir = utsname.release;
+               test_dir = release;
                prefix_dir = "/lib/modules/";
                suffix_dir = "/build";
        }
@@ -326,13 +328,15 @@ get_kbuild_opts(char **kbuild_dir, char **kbuild_include_opts)
 int llvm__compile_bpf(const char *path, void **p_obj_buf,
                      size_t *p_obj_buf_sz)
 {
-       int err;
-       char clang_path[PATH_MAX];
+       size_t obj_buf_sz;
+       void *obj_buf = NULL;
+       int err, nr_cpus_avail;
+       unsigned int kernel_version;
+       char linux_version_code_str[64];
        const char *clang_opt = llvm_param.clang_opt;
-       const char *template = llvm_param.clang_bpf_cmd_template;
+       char clang_path[PATH_MAX], nr_cpus_avail_str[64];
        char *kbuild_dir = NULL, *kbuild_include_opts = NULL;
-       void *obj_buf = NULL;
-       size_t obj_buf_sz;
+       const char *template = llvm_param.clang_bpf_cmd_template;
 
        if (!template)
                template = CLANG_BPF_CMD_DEFAULT_TEMPLATE;
@@ -354,6 +358,24 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,
         */
        get_kbuild_opts(&kbuild_dir, &kbuild_include_opts);
 
+       nr_cpus_avail = sysconf(_SC_NPROCESSORS_CONF);
+       if (nr_cpus_avail <= 0) {
+               pr_err(
+"WARNING:\tunable to get available CPUs in this system: %s\n"
+"        \tUse 128 instead.\n", strerror(errno));
+               nr_cpus_avail = 128;
+       }
+       snprintf(nr_cpus_avail_str, sizeof(nr_cpus_avail_str), "%d",
+                nr_cpus_avail);
+
+       if (fetch_kernel_version(&kernel_version, NULL, 0))
+               kernel_version = 0;
+
+       snprintf(linux_version_code_str, sizeof(linux_version_code_str),
+                "0x%x", kernel_version);
+
+       force_set_env("NR_CPUS", nr_cpus_avail_str);
+       force_set_env("LINUX_VERSION_CODE", linux_version_code_str);
        force_set_env("CLANG_EXEC", clang_path);
        force_set_env("CLANG_OPTIONS", clang_opt);
        force_set_env("KERNEL_INC_OPTIONS", kbuild_include_opts);
index 4e38c396a897ad9599d1addb1fb464b5cdfa4129..afc6b56cf749b687c297018dcae986fef977859c 100644 (file)
@@ -644,6 +644,12 @@ size_t map_groups__fprintf(struct map_groups *mg, FILE *fp)
        return printed;
 }
 
+static void __map_groups__insert(struct map_groups *mg, struct map *map)
+{
+       __maps__insert(&mg->maps[map->type], map);
+       map->groups = mg;
+}
+
 static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp)
 {
        struct rb_root *root;
@@ -682,7 +688,7 @@ static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp
                        }
 
                        before->end = map->start;
-                       __maps__insert(maps, before);
+                       __map_groups__insert(pos->groups, before);
                        if (verbose >= 2)
                                map__fprintf(before, fp);
                }
@@ -696,7 +702,7 @@ static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp
                        }
 
                        after->start = map->end;
-                       __maps__insert(maps, after);
+                       __map_groups__insert(pos->groups, after);
                        if (verbose >= 2)
                                map__fprintf(after, fp);
                }
index bee60583839a7cdae0dd44f5c48dd818d53cb5e4..e48d9da757078f0c35afae590ce87ac7892dafab 100644 (file)
@@ -632,19 +632,20 @@ int parse_events_load_bpf(struct parse_events_evlist *data,
        struct bpf_object *obj;
 
        obj = bpf__prepare_load(bpf_file_name, source);
-       if (IS_ERR(obj) || !obj) {
+       if (IS_ERR(obj)) {
                char errbuf[BUFSIZ];
                int err;
 
-               err = obj ? PTR_ERR(obj) : -EINVAL;
+               err = PTR_ERR(obj);
 
                if (err == -ENOTSUP)
                        snprintf(errbuf, sizeof(errbuf),
                                 "BPF support is not compiled");
                else
-                       snprintf(errbuf, sizeof(errbuf),
-                                "BPF object file '%s' is invalid",
-                                bpf_file_name);
+                       bpf__strerror_prepare_load(bpf_file_name,
+                                                  source,
+                                                  -err, errbuf,
+                                                  sizeof(errbuf));
 
                data->error->help = strdup("(add -v to see detail)");
                data->error->str = strdup(errbuf);
index b51a8bfb40f92cd861d0954ed84e71e15ee50784..03875f9154e7562c060e5935d30bc65d6ba0973b 100644 (file)
@@ -1895,9 +1895,8 @@ static int find_perf_probe_point_from_map(struct probe_trace_point *tp,
                sym = map__find_symbol(map, addr, NULL);
        } else {
                if (tp->symbol && !addr) {
-                       ret = kernel_get_symbol_address_by_name(tp->symbol,
-                                                       &addr, true, false);
-                       if (ret < 0)
+                       if (kernel_get_symbol_address_by_name(tp->symbol,
+                                               &addr, true, false) < 0)
                                goto out;
                }
                if (addr) {
@@ -1905,6 +1904,7 @@ static int find_perf_probe_point_from_map(struct probe_trace_point *tp,
                        sym = __find_kernel_function(addr, &map);
                }
        }
+
        if (!sym)
                goto out;
 
index 89dbeb92c68e9de1bc001edddd902940700ab4f2..e3b3b92e44587350b86797e93e57900afd71f94e 100644 (file)
@@ -138,6 +138,9 @@ struct strlist *probe_file__get_rawlist(int fd)
        char *p;
        struct strlist *sl;
 
+       if (fd < 0)
+               return NULL;
+
        sl = strlist__new(NULL, NULL);
 
        fp = fdopen(dup(fd), "r");
@@ -271,6 +274,9 @@ int probe_file__get_events(int fd, struct strfilter *filter,
        const char *p;
        int ret = -ENOENT;
 
+       if (!plist)
+               return -EINVAL;
+
        namelist = __probe_file__get_namelist(fd, true);
        if (!namelist)
                return -ENOENT;
index 428149bc64d23c6a12e9c141fb3070809090ad36..c35ffdd360fe13e1590559217365e0f78414e91c 100644 (file)
@@ -29,7 +29,7 @@ static int perf_session__open(struct perf_session *session)
        struct perf_data_file *file = session->file;
 
        if (perf_session__read_header(session) < 0) {
-               pr_err("incompatible file format (rerun with -v to learn more)");
+               pr_err("incompatible file format (rerun with -v to learn more)\n");
                return -1;
        }
 
@@ -37,17 +37,17 @@ static int perf_session__open(struct perf_session *session)
                return 0;
 
        if (!perf_evlist__valid_sample_type(session->evlist)) {
-               pr_err("non matching sample_type");
+               pr_err("non matching sample_type\n");
                return -1;
        }
 
        if (!perf_evlist__valid_sample_id_all(session->evlist)) {
-               pr_err("non matching sample_id_all");
+               pr_err("non matching sample_id_all\n");
                return -1;
        }
 
        if (!perf_evlist__valid_read_format(session->evlist)) {
-               pr_err("non matching read_format");
+               pr_err("non matching read_format\n");
                return -1;
        }
 
index 2a5d8d7698aedb8c82bdf8488f1fb62ded5b438a..6ac03146889d29be60707efd6e04c27c919f64de 100644 (file)
@@ -413,6 +413,11 @@ void perf_stat__print_shadow_stats(FILE *out, struct perf_evsel *evsel,
                        ratio = total / avg;
 
                fprintf(out, " # %8.0f cycles / elision       ", ratio);
+       } else if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK)) {
+               if ((ratio = avg_stats(&walltime_nsecs_stats)) != 0)
+                       fprintf(out, " # %8.3f CPUs utilized          ", avg / ratio);
+               else
+                       fprintf(out, "                                   ");
        } else if (runtime_nsecs_stats[cpu].n != 0) {
                char unit = 'M';
 
index cd12c25e4ea408b1b873d8368f5081d3e2a72113..47b1e36c7ea0c948b0fc9cd247c4a29cf61464a8 100644 (file)
@@ -3,6 +3,7 @@
 #include "debug.h"
 #include <api/fs/fs.h>
 #include <sys/mman.h>
+#include <sys/utsname.h>
 #ifdef HAVE_BACKTRACE_SUPPORT
 #include <execinfo.h>
 #endif
@@ -665,3 +666,32 @@ bool find_process(const char *name)
        closedir(dir);
        return ret ? false : true;
 }
+
+int
+fetch_kernel_version(unsigned int *puint, char *str,
+                    size_t str_size)
+{
+       struct utsname utsname;
+       int version, patchlevel, sublevel, err;
+
+       if (uname(&utsname))
+               return -1;
+
+       if (str && str_size) {
+               strncpy(str, utsname.release, str_size);
+               str[str_size - 1] = '\0';
+       }
+
+       err = sscanf(utsname.release, "%d.%d.%d",
+                    &version, &patchlevel, &sublevel);
+
+       if (err != 3) {
+               pr_debug("Unablt to get kernel version from uname '%s'\n",
+                        utsname.release);
+               return -1;
+       }
+
+       if (puint)
+               *puint = (version << 16) + (patchlevel << 8) + sublevel;
+       return 0;
+}
index 4cfb913aa9e04bffd94286ac426bac4c1221e9c4..dcc659017976da2a90ae67e51b922bcb7bb99a51 100644 (file)
@@ -350,4 +350,12 @@ static inline char *asprintf_expr_not_in_ints(const char *var, size_t nints, int
 
 int get_stack_size(const char *str, unsigned long *_size);
 
+int fetch_kernel_version(unsigned int *puint,
+                        char *str, size_t str_sz);
+#define KVER_VERSION(x)                (((x) >> 16) & 0xff)
+#define KVER_PATCHLEVEL(x)     (((x) >> 8) & 0xff)
+#define KVER_SUBLEVEL(x)       ((x) & 0xff)
+#define KVER_FMT       "%d.%d.%d"
+#define KVER_PARAM(x)  KVER_VERSION(x), KVER_PATCHLEVEL(x), KVER_SUBLEVEL(x)
+
 #endif /* GIT_COMPAT_UTIL_H */
index 8d6a47514253822bb0673968707bc4ecc6a7749e..2c768cf70128cb2d8bbd6a151b6ec51414dafc65 100644 (file)
@@ -134,7 +134,7 @@ next_one:
 }
 
 static struct option info_opts[] = {
-       {.name = "numpst",      .has_arg=no_argument,   .flag=NULL, .val='n'},
+     {"numpst", no_argument, NULL, 'n'},
 };
 
 void print_help(void)
index 3e6799d7a79f1d951f1d6e95f65f337663c8f286..580c4e3ea92ad5425cb0b0c458c2d3fbfa23983c 100644 (file)
@@ -20,7 +20,9 @@ Disable a specific processor sleep state.
 Enable a specific processor sleep state.
 .TP
 \fB\-D\fR \fB\-\-disable-by-latency\fR <LATENCY>
-Disable all idle states with a equal or higher latency than <LATENCY>
+Disable all idle states with a equal or higher latency than <LATENCY>.
+
+Enable all idle states with a latency lower than <LATENCY>.
 .TP
 \fB\-E\fR \fB\-\-enable-all\fR
 Enable all idle states if not enabled already.
index b4b90a97662cda4abe72c82419c815888231235b..0e676433024109bef6d9a87e08709c40be37b2df 100644 (file)
@@ -536,21 +536,21 @@ static int get_latency(unsigned int cpu, unsigned int human)
 }
 
 static struct option info_opts[] = {
-       { .name = "debug",      .has_arg = no_argument,         .flag = NULL,   .val = 'e'},
-       { .name = "boost",      .has_arg = no_argument,         .flag = NULL,   .val = 'b'},
-       { .name = "freq",       .has_arg = no_argument,         .flag = NULL,   .val = 'f'},
-       { .name = "hwfreq",     .has_arg = no_argument,         .flag = NULL,   .val = 'w'},
-       { .name = "hwlimits",   .has_arg = no_argument,         .flag = NULL,   .val = 'l'},
-       { .name = "driver",     .has_arg = no_argument,         .flag = NULL,   .val = 'd'},
-       { .name = "policy",     .has_arg = no_argument,         .flag = NULL,   .val = 'p'},
-       { .name = "governors",  .has_arg = no_argument,         .flag = NULL,   .val = 'g'},
-       { .name = "related-cpus", .has_arg = no_argument,       .flag = NULL,   .val = 'r'},
-       { .name = "affected-cpus",.has_arg = no_argument,       .flag = NULL,   .val = 'a'},
-       { .name = "stats",      .has_arg = no_argument,         .flag = NULL,   .val = 's'},
-       { .name = "latency",    .has_arg = no_argument,         .flag = NULL,   .val = 'y'},
-       { .name = "proc",       .has_arg = no_argument,         .flag = NULL,   .val = 'o'},
-       { .name = "human",      .has_arg = no_argument,         .flag = NULL,   .val = 'm'},
-       { .name = "no-rounding", .has_arg = no_argument,        .flag = NULL,   .val = 'n'},
+       {"debug",        no_argument,            NULL,   'e'},
+       {"boost",        no_argument,            NULL,   'b'},
+       {"freq",         no_argument,            NULL,   'f'},
+       {"hwfreq",       no_argument,            NULL,   'w'},
+       {"hwlimits",     no_argument,            NULL,   'l'},
+       {"driver",       no_argument,            NULL,   'd'},
+       {"policy",       no_argument,            NULL,   'p'},
+       {"governors",    no_argument,            NULL,   'g'},
+       {"related-cpus",  no_argument,   NULL,   'r'},
+       {"affected-cpus", no_argument,   NULL,   'a'},
+       {"stats",        no_argument,            NULL,   's'},
+       {"latency",      no_argument,            NULL,   'y'},
+       {"proc",         no_argument,            NULL,   'o'},
+       {"human",        no_argument,            NULL,   'm'},
+       {"no-rounding", no_argument,     NULL,   'n'},
        { },
 };
 
index 4e213576381eab03c64444b6acee614e9c84f874..0fbd1a22c0a984c0ceac2f832ca791058c0d1524 100644 (file)
 #define NORM_FREQ_LEN 32
 
 static struct option set_opts[] = {
-       { .name = "min",        .has_arg = required_argument,   .flag = NULL,   .val = 'd'},
-       { .name = "max",        .has_arg = required_argument,   .flag = NULL,   .val = 'u'},
-       { .name = "governor",   .has_arg = required_argument,   .flag = NULL,   .val = 'g'},
-       { .name = "freq",       .has_arg = required_argument,   .flag = NULL,   .val = 'f'},
-       { .name = "related",    .has_arg = no_argument,         .flag = NULL,   .val='r'},
+       {"min",         required_argument,      NULL, 'd'},
+       {"max",         required_argument,      NULL, 'u'},
+       {"governor",    required_argument,      NULL, 'g'},
+       {"freq",        required_argument,      NULL, 'f'},
+       {"related",     no_argument,            NULL, 'r'},
        { },
 };
 
index 75e66de7e7a7fc9934ec005667c6857cff42ff04..750c1d82c3f7b7f16a3eea71df3c9d6e7a4ceb7d 100644 (file)
@@ -126,8 +126,8 @@ static void proc_cpuidle_cpu_output(unsigned int cpu)
 }
 
 static struct option info_opts[] = {
-       { .name = "silent",     .has_arg = no_argument, .flag = NULL,   .val = 's'},
-       { .name = "proc",       .has_arg = no_argument, .flag = NULL,   .val = 'o'},
+       {"silent", no_argument, NULL, 's'},
+       {"proc", no_argument, NULL, 'o'},
        { },
 };
 
index d45d8d775c021482ab7a4d113351c7f6abd9a9ac..d6b6ae44b8c247ffdb6378d8dcd3cb36f0265142 100644 (file)
 #include "helpers/sysfs.h"
 
 static struct option info_opts[] = {
-       { .name = "disable",
-         .has_arg = required_argument, .flag = NULL,   .val = 'd'},
-       { .name = "enable",
-         .has_arg = required_argument, .flag = NULL,   .val = 'e'},
-       { .name = "disable-by-latency",
-         .has_arg = required_argument, .flag = NULL,   .val = 'D'},
-       { .name = "enable-all",
-         .has_arg = no_argument,       .flag = NULL,   .val = 'E'},
-       { },
+     {"disable",       required_argument,              NULL, 'd'},
+     {"enable",                required_argument,              NULL, 'e'},
+     {"disable-by-latency", required_argument,         NULL, 'D'},
+     {"enable-all",    no_argument,                    NULL, 'E'},
+     { },
 };
 
 
@@ -148,14 +144,21 @@ int cmd_idle_set(int argc, char **argv)
                                        (cpu, idlestate);
                                state_latency = sysfs_get_idlestate_latency
                                        (cpu, idlestate);
-                               printf("CPU: %u - idlestate %u - state_latency: %llu - latency: %llu\n",
-                                      cpu, idlestate, state_latency, latency);
-                               if (disabled == 1 || latency > state_latency)
+                               if (disabled == 1) {
+                                       if (latency > state_latency){
+                                               ret = sysfs_idlestate_disable
+                                                       (cpu, idlestate, 0);
+                                               if (ret == 0)
+               printf(_("Idlestate %u enabled on CPU %u\n"),  idlestate, cpu);
+                                       }
                                        continue;
-                               ret = sysfs_idlestate_disable
-                                       (cpu, idlestate, 1);
-                               if (ret == 0)
+                               }
+                               if (latency <= state_latency){
+                                       ret = sysfs_idlestate_disable
+                                               (cpu, idlestate, 1);
+                                       if (ret == 0)
                printf(_("Idlestate %u disabled on CPU %u\n"), idlestate, cpu);
+                               }
                        }
                        break;
                case 'E':
index 136d979e958634b83a3f2cd007a7d192036ee152..10299f2e9d2a6917f0601dd07eedb0ff03c6bc92 100644 (file)
@@ -17,8 +17,8 @@
 #include "helpers/sysfs.h"
 
 static struct option set_opts[] = {
-       { .name = "perf-bias",  .has_arg = optional_argument,   .flag = NULL,   .val = 'b'},
-       { },
+     {"perf-bias", optional_argument, NULL, 'b'},
+     { },
 };
 
 static void print_wrong_arg_exit(void)
index 573c75f8e3f5da78afdfd4b2e22dff9cde18d01e..3e6f374f8dd73ddc1fd1b6d3b30f175fcc7f9e4b 100644 (file)
@@ -18,7 +18,7 @@
 #include "helpers/bitmask.h"
 
 static struct option set_opts[] = {
-       { .name = "perf-bias",  .has_arg = required_argument,   .flag = NULL,   .val = 'b'},
+       {"perf-bias", required_argument, NULL, 'b'},
        { },
 };
 
index cea398c176e7f29057a24463f296300f8ce5f23f..9cbb7fd7517122c423d316efb5e736a52c799d3a 100644 (file)
@@ -73,18 +73,22 @@ int get_cpu_topology(struct cpupower_topology *cpu_top)
        for (cpu = 0; cpu < cpus; cpu++) {
                cpu_top->core_info[cpu].cpu = cpu;
                cpu_top->core_info[cpu].is_online = sysfs_is_cpu_online(cpu);
-               if (!cpu_top->core_info[cpu].is_online)
-                       continue;
                if(sysfs_topology_read_file(
                        cpu,
                        "physical_package_id",
-                       &(cpu_top->core_info[cpu].pkg)) < 0)
-                       return -1;
+                       &(cpu_top->core_info[cpu].pkg)) < 0) {
+                       cpu_top->core_info[cpu].pkg = -1;
+                       cpu_top->core_info[cpu].core = -1;
+                       continue;
+               }
                if(sysfs_topology_read_file(
                        cpu,
                        "core_id",
-                       &(cpu_top->core_info[cpu].core)) < 0)
-                       return -1;
+                       &(cpu_top->core_info[cpu].core)) < 0) {
+                       cpu_top->core_info[cpu].pkg = -1;
+                       cpu_top->core_info[cpu].core = -1;
+                       continue;
+               }
        }
 
        qsort(cpu_top->core_info, cpus, sizeof(struct cpuid_core_info),
@@ -95,12 +99,15 @@ int get_cpu_topology(struct cpupower_topology *cpu_top)
           done by pkg value. */
        last_pkg = cpu_top->core_info[0].pkg;
        for(cpu = 1; cpu < cpus; cpu++) {
-               if(cpu_top->core_info[cpu].pkg != last_pkg) {
+               if (cpu_top->core_info[cpu].pkg != last_pkg &&
+                               cpu_top->core_info[cpu].pkg != -1) {
+
                        last_pkg = cpu_top->core_info[cpu].pkg;
                        cpu_top->pkgs++;
                }
        }
-       cpu_top->pkgs++;
+       if (!cpu_top->core_info[0].pkg == -1)
+               cpu_top->pkgs++;
 
        /* Intel's cores count is not consecutively numbered, there may
         * be a core_id of 3, but none of 2. Assume there always is 0
index c4bae9203a692f2065ee9ec4f8d747c0912d8a94..05f953f0f0a0cf2b3d479ce6a6dcbc9c0d9a8c28 100644 (file)
@@ -143,6 +143,9 @@ void print_results(int topology_depth, int cpu)
        /* Be careful CPUs may got resorted for pkg value do not just use cpu */
        if (!bitmask_isbitset(cpus_chosen, cpu_top.core_info[cpu].cpu))
                return;
+       if (!cpu_top.core_info[cpu].is_online &&
+           cpu_top.core_info[cpu].pkg == -1)
+               return;
 
        if (topology_depth > 2)
                printf("%4d|", cpu_top.core_info[cpu].pkg);
@@ -191,7 +194,8 @@ void print_results(int topology_depth, int cpu)
         * It's up to the monitor plug-in to check .is_online, this one
         * is just for additional info.
         */
-       if (!cpu_top.core_info[cpu].is_online) {
+       if (!cpu_top.core_info[cpu].is_online &&
+           cpu_top.core_info[cpu].pkg != -1) {
                printf(_(" *is offline\n"));
                return;
        } else
@@ -388,6 +392,9 @@ int cmd_monitor(int argc, char **argv)
                return EXIT_FAILURE;
        }
 
+       if (!cpu_top.core_info[0].is_online)
+               printf("WARNING: at least one cpu is offline\n");
+
        /* Default is: monitor all CPUs */
        if (bitmask_isallclear(cpus_chosen))
                bitmask_setall(cpus_chosen);
index bde0ef1a63df4876d5149c85f4083eb92561dbb4..d8e4b20b6d54cc14c25482279a2a652fe483a2f3 100644 (file)
@@ -75,6 +75,7 @@ unsigned int aperf_mperf_multiplier = 1;
 int do_smi;
 double bclk;
 double base_hz;
+unsigned int has_base_hz;
 double tsc_tweak = 1.0;
 unsigned int show_pkg;
 unsigned int show_core;
@@ -96,6 +97,7 @@ unsigned int do_ring_perf_limit_reasons;
 unsigned int crystal_hz;
 unsigned long long tsc_hz;
 int base_cpu;
+double discover_bclk(unsigned int family, unsigned int model);
 
 #define RAPL_PKG               (1 << 0)
                                        /* 0x610 MSR_PKG_POWER_LIMIT */
@@ -511,9 +513,13 @@ int format_counters(struct thread_data *t, struct core_data *c,
        }
 
        /* Bzy_MHz */
-       if (has_aperf)
-               outp += sprintf(outp, "%8.0f",
-                       1.0 * t->tsc * tsc_tweak / units * t->aperf / t->mperf / interval_float);
+       if (has_aperf) {
+               if (has_base_hz)
+                       outp += sprintf(outp, "%8.0f", base_hz / units * t->aperf / t->mperf);
+               else
+                       outp += sprintf(outp, "%8.0f",
+                               1.0 * t->tsc / units * t->aperf / t->mperf / interval_float);
+       }
 
        /* TSC_MHz */
        outp += sprintf(outp, "%8.0f", 1.0 * t->tsc/units/interval_float);
@@ -1158,12 +1164,6 @@ int phi_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV,
 static void
 calculate_tsc_tweak()
 {
-       unsigned long long msr;
-       unsigned int base_ratio;
-
-       get_msr(base_cpu, MSR_NHM_PLATFORM_INFO, &msr);
-       base_ratio = (msr >> 8) & 0xFF;
-       base_hz = base_ratio * bclk * 1000000;
        tsc_tweak = base_hz / tsc_hz;
 }
 
@@ -1440,7 +1440,7 @@ dump_config_tdp(void)
        
        get_msr(base_cpu, MSR_TURBO_ACTIVATION_RATIO, &msr);
        fprintf(stderr, "cpu%d: MSR_TURBO_ACTIVATION_RATIO: 0x%08llx (", base_cpu, msr);
-       fprintf(stderr, "MAX_NON_TURBO_RATIO=%d", (unsigned int)(msr) & 0xEF);
+       fprintf(stderr, "MAX_NON_TURBO_RATIO=%d", (unsigned int)(msr) & 0x7F);
        fprintf(stderr, " lock=%d", (unsigned int)(msr >> 31) & 1);
        fprintf(stderr, ")\n");
 }
@@ -1821,6 +1821,7 @@ void check_permissions()
 int probe_nhm_msrs(unsigned int family, unsigned int model)
 {
        unsigned long long msr;
+       unsigned int base_ratio;
        int *pkg_cstate_limits;
 
        if (!genuine_intel)
@@ -1829,6 +1830,8 @@ int probe_nhm_msrs(unsigned int family, unsigned int model)
        if (family != 6)
                return 0;
 
+       bclk = discover_bclk(family, model);
+
        switch (model) {
        case 0x1A:      /* Core i7, Xeon 5500 series - Bloomfield, Gainstown NHM-EP */
        case 0x1E:      /* Core i7 and i5 Processor - Clarksfield, Lynnfield, Jasper Forest */
@@ -1871,9 +1874,13 @@ int probe_nhm_msrs(unsigned int family, unsigned int model)
                return 0;
        }
        get_msr(base_cpu, MSR_NHM_SNB_PKG_CST_CFG_CTL, &msr);
-
        pkg_cstate_limit = pkg_cstate_limits[msr & 0xF];
 
+       get_msr(base_cpu, MSR_NHM_PLATFORM_INFO, &msr);
+       base_ratio = (msr >> 8) & 0xFF;
+
+       base_hz = base_ratio * bclk * 1000000;
+       has_base_hz = 1;
        return 1;
 }
 int has_nhm_turbo_ratio_limit(unsigned int family, unsigned int model)
@@ -2780,7 +2787,6 @@ void process_cpuid()
        do_skl_residency = has_skl_msrs(family, model);
        do_slm_cstates = is_slm(family, model);
        do_knl_cstates  = is_knl(family, model);
-       bclk = discover_bclk(family, model);
 
        rapl_probe(family, model);
        perf_limit_reasons_probe(family, model);
index dce346aa94eabbd3544189af7e3de528da960cb6..40ab4476c80a2039ab543cc94b09725789b2fe57 100644 (file)
@@ -1135,7 +1135,7 @@ static void nfit_test1_setup(struct nfit_test *t)
        memdev->interleave_ways = 1;
        memdev->flags = ACPI_NFIT_MEM_SAVE_FAILED | ACPI_NFIT_MEM_RESTORE_FAILED
                | ACPI_NFIT_MEM_FLUSH_FAILED | ACPI_NFIT_MEM_HEALTH_OBSERVED
-               | ACPI_NFIT_MEM_ARMED;
+               | ACPI_NFIT_MEM_NOT_ARMED;
 
        offset += sizeof(*memdev);
        /* dcr-descriptor0 */
index 2e83dd3655a28ae606a0a2c8c4b80a58331ef24e..3a961e998281b776a9e2e13e8995d99bd738217c 100644 (file)
@@ -22,6 +22,9 @@ TMON_LIBS += $(shell pkg-config --libs $(STATIC) panelw ncursesw 2> /dev/null ||
                     pkg-config --libs $(STATIC) panel ncurses 2> /dev/null || \
                     echo -lpanel -lncurses)
 
+CFLAGS    += $(shell pkg-config --cflags $(STATIC) panelw ncursesw 2> /dev/null || \
+                    pkg-config --cflags $(STATIC) panel ncurses 2> /dev/null)
+
 OBJS = tmon.o tui.o sysfs.o pid.o
 OBJS +=