Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 5 Nov 2021 15:42:02 +0000 (08:42 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 5 Nov 2021 15:42:02 +0000 (08:42 -0700)
Pull SCSI updates from James Bottomley:
 "This consists of the usual driver updates (ufs, smartpqi, lpfc,
  target, megaraid_sas, hisi_sas, qla2xxx) and minor updates and bug
  fixes.

  Notable core changes are the removal of scsi->tag which caused some
  churn in obsolete drivers and a sweep through all drivers to call
  scsi_done() directly instead of scsi->done() which removes a pointer
  indirection from the hot path and a move to register core sysfs files
  earlier, which means they're available to KOBJ_ADD processing, which
  necessitates switching all drivers to using attribute groups"

* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (279 commits)
  scsi: lpfc: Update lpfc version to 14.0.0.3
  scsi: lpfc: Allow fabric node recovery if recovery is in progress before devloss
  scsi: lpfc: Fix link down processing to address NULL pointer dereference
  scsi: lpfc: Allow PLOGI retry if previous PLOGI was aborted
  scsi: lpfc: Fix use-after-free in lpfc_unreg_rpi() routine
  scsi: lpfc: Correct sysfs reporting of loop support after SFP status change
  scsi: lpfc: Wait for successful restart of SLI3 adapter during host sg_reset
  scsi: lpfc: Revert LOG_TRACE_EVENT back to LOG_INIT prior to driver_resource_setup()
  scsi: ufs: ufshcd-pltfrm: Fix memory leak due to probe defer
  scsi: ufs: mediatek: Avoid sched_clock() misuse
  scsi: mpt3sas: Make mpt3sas_dev_attrs static
  scsi: scsi_transport_sas: Add 22.5 Gbps link rate definitions
  scsi: target: core: Stop using bdevname()
  scsi: aha1542: Use memcpy_{from,to}_bvec()
  scsi: sr: Add error handling support for add_disk()
  scsi: sd: Add error handling support for add_disk()
  scsi: target: Perform ALUA group changes in one step
  scsi: target: Replace lun_tg_pt_gp_lock with rcu in I/O path
  scsi: target: Fix alua_tg_pt_gps_count tracking
  scsi: target: Fix ordered tag handling
  ...

35 files changed:
1  2 
Documentation/ABI/testing/sysfs-driver-ufs
drivers/ata/libata-scsi.c
drivers/ata/sata_mv.c
drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
drivers/scsi/hosts.c
drivers/scsi/ibmvscsi/ibmvfc.c
drivers/scsi/ibmvscsi/ibmvscsi.c
drivers/scsi/lpfc/lpfc.h
drivers/scsi/mpi3mr/mpi3mr_os.c
drivers/scsi/mpt3sas/mpt3sas_scsih.c
drivers/scsi/qedf/qedf.h
drivers/scsi/qedf/qedf_io.c
drivers/scsi/qedf/qedf_main.c
drivers/scsi/qla2xxx/qla_bsg.c
drivers/scsi/qla2xxx/qla_nvme.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/scsi.c
drivers/scsi/scsi_debug.c
drivers/scsi/scsi_error.c
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_scan.c
drivers/scsi/scsi_sysfs.c
drivers/scsi/sd.c
drivers/scsi/sr.c
drivers/scsi/storvsc_drv.c
drivers/scsi/ufs/ufs-exynos.c
drivers/scsi/ufs/ufshcd.c
drivers/scsi/ufs/ufshcd.h
drivers/scsi/ufs/ufshpb.c
drivers/scsi/virtio_scsi.c
drivers/staging/rts5208/rtsx.c
drivers/target/target_core_iblock.c
include/linux/libata.h
include/scsi/scsi_cmnd.h
include/scsi/scsi_device.h

@@@ -13,7 -13,6 +13,7 @@@ Description
                Interface specification for more details.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_type
 +What:         /sys/bus/platform/devices/*.ufs/device_descriptor/device_type
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the device type. This is one of the UFS
@@@ -23,7 -22,6 +23,7 @@@
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_class
 +What:         /sys/bus/platform/devices/*.ufs/device_descriptor/device_class
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the device class. This is one of the UFS
@@@ -33,7 -31,6 +33,7 @@@
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_sub_class
 +What:         /sys/bus/platform/devices/*.ufs/device_descriptor/device_sub_class
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the UFS storage subclass. This is one of
@@@ -43,7 -40,6 +43,7 @@@
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/device_descriptor/protocol
 +What:         /sys/bus/platform/devices/*.ufs/device_descriptor/protocol
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the protocol supported by an UFS device.
@@@ -54,7 -50,6 +54,7 @@@
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/device_descriptor/number_of_luns
 +What:         /sys/bus/platform/devices/*.ufs/device_descriptor/number_of_luns
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows number of logical units. This is one of
@@@ -64,7 -59,6 +64,7 @@@
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/device_descriptor/number_of_wluns
 +What:         /sys/bus/platform/devices/*.ufs/device_descriptor/number_of_wluns
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows number of well known logical units.
@@@ -75,7 -69,6 +75,7 @@@
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/device_descriptor/boot_enable
 +What:         /sys/bus/platform/devices/*.ufs/device_descriptor/boot_enable
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows value that indicates whether the device is
@@@ -86,7 -79,6 +86,7 @@@
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/device_descriptor/descriptor_access_enable
 +What:         /sys/bus/platform/devices/*.ufs/device_descriptor/descriptor_access_enable
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows value that indicates whether the device
@@@ -98,7 -90,6 +98,7 @@@
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/device_descriptor/initial_power_mode
 +What:         /sys/bus/platform/devices/*.ufs/device_descriptor/initial_power_mode
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows value that defines the power mode after
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/device_descriptor/high_priority_lun
 +What:         /sys/bus/platform/devices/*.ufs/device_descriptor/high_priority_lun
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the high priority lun. This is one of
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/device_descriptor/secure_removal_type
 +What:         /sys/bus/platform/devices/*.ufs/device_descriptor/secure_removal_type
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the secure removal type. This is one of
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/device_descriptor/support_security_lun
 +What:         /sys/bus/platform/devices/*.ufs/device_descriptor/support_security_lun
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows whether the security lun is supported.
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/device_descriptor/bkops_termination_latency
 +What:         /sys/bus/platform/devices/*.ufs/device_descriptor/bkops_termination_latency
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the background operations termination
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/device_descriptor/initial_active_icc_level
 +What:         /sys/bus/platform/devices/*.ufs/device_descriptor/initial_active_icc_level
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the initial active ICC level. This is one
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/device_descriptor/specification_version
 +What:         /sys/bus/platform/devices/*.ufs/device_descriptor/specification_version
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the specification version. This is one
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/device_descriptor/manufacturing_date
 +What:         /sys/bus/platform/devices/*.ufs/device_descriptor/manufacturing_date
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the manufacturing date in BCD format.
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/device_descriptor/manufacturer_id
 +What:         /sys/bus/platform/devices/*.ufs/device_descriptor/manufacturer_id
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the manufacturer ID. This is one of the
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/device_descriptor/rtt_capability
 +What:         /sys/bus/platform/devices/*.ufs/device_descriptor/rtt_capability
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the maximum number of outstanding RTTs
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/device_descriptor/rtc_update
 +What:         /sys/bus/platform/devices/*.ufs/device_descriptor/rtc_update
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the frequency and method of the realtime
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/device_descriptor/ufs_features
 +What:         /sys/bus/platform/devices/*.ufs/device_descriptor/ufs_features
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows which features are supported by the device.
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/device_descriptor/ffu_timeout
 +What:         /sys/bus/platform/devices/*.ufs/device_descriptor/ffu_timeout
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the FFU timeout. This is one of the
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/device_descriptor/queue_depth
 +What:         /sys/bus/platform/devices/*.ufs/device_descriptor/queue_depth
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the device queue depth. This is one of the
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_version
 +What:         /sys/bus/platform/devices/*.ufs/device_descriptor/device_version
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the device version. This is one of the
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/device_descriptor/number_of_secure_wpa
 +What:         /sys/bus/platform/devices/*.ufs/device_descriptor/number_of_secure_wpa
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows number of secure write protect areas
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/device_descriptor/psa_max_data_size
 +What:         /sys/bus/platform/devices/*.ufs/device_descriptor/psa_max_data_size
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the maximum amount of data that may be
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/device_descriptor/psa_state_timeout
 +What:         /sys/bus/platform/devices/*.ufs/device_descriptor/psa_state_timeout
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the command maximum timeout for a change
  
  
  What:         /sys/bus/platform/drivers/ufshcd/*/interconnect_descriptor/unipro_version
 +What:         /sys/bus/platform/devices/*.ufs/interconnect_descriptor/unipro_version
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the MIPI UniPro version number in BCD format.
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/interconnect_descriptor/mphy_version
 +What:         /sys/bus/platform/devices/*.ufs/interconnect_descriptor/mphy_version
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the MIPI M-PHY version number in BCD format.
  
  
  What:         /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/raw_device_capacity
 +What:         /sys/bus/platform/devices/*.ufs/geometry_descriptor/raw_device_capacity
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the total memory quantity available to
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/max_number_of_luns
 +What:         /sys/bus/platform/devices/*.ufs/geometry_descriptor/max_number_of_luns
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the maximum number of logical units
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/segment_size
 +What:         /sys/bus/platform/devices/*.ufs/geometry_descriptor/segment_size
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the segment size. This is one of the UFS
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/allocation_unit_size
 +What:         /sys/bus/platform/devices/*.ufs/geometry_descriptor/allocation_unit_size
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the allocation unit size. This is one of
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/min_addressable_block_size
 +What:         /sys/bus/platform/devices/*.ufs/geometry_descriptor/min_addressable_block_size
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the minimum addressable block size. This
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/optimal_read_block_size
 +What:         /sys/bus/platform/devices/*.ufs/geometry_descriptor/optimal_read_block_size
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the optimal read block size. This is one
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/optimal_write_block_size
 +What:         /sys/bus/platform/devices/*.ufs/geometry_descriptor/optimal_write_block_size
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the optimal write block size. This is one
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/max_in_buffer_size
 +What:         /sys/bus/platform/devices/*.ufs/geometry_descriptor/max_in_buffer_size
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the maximum data-in buffer size. This
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/max_out_buffer_size
 +What:         /sys/bus/platform/devices/*.ufs/geometry_descriptor/max_out_buffer_size
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the maximum data-out buffer size. This
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/rpmb_rw_size
 +What:         /sys/bus/platform/devices/*.ufs/geometry_descriptor/rpmb_rw_size
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the maximum number of RPMB frames allowed
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/dyn_capacity_resource_policy
 +What:         /sys/bus/platform/devices/*.ufs/geometry_descriptor/dyn_capacity_resource_policy
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the dynamic capacity resource policy. This
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/data_ordering
 +What:         /sys/bus/platform/devices/*.ufs/geometry_descriptor/data_ordering
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows support for out-of-order data transfer.
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/max_number_of_contexts
 +What:         /sys/bus/platform/devices/*.ufs/geometry_descriptor/max_number_of_contexts
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows maximum available number of contexts which
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/sys_data_tag_unit_size
 +What:         /sys/bus/platform/devices/*.ufs/geometry_descriptor/sys_data_tag_unit_size
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows system data tag unit size. This is one of
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/sys_data_tag_resource_size
 +What:         /sys/bus/platform/devices/*.ufs/geometry_descriptor/sys_data_tag_resource_size
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows maximum storage area size allocated by
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/secure_removal_types
 +What:         /sys/bus/platform/devices/*.ufs/geometry_descriptor/secure_removal_types
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows supported secure removal types. This is
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/memory_types
 +What:         /sys/bus/platform/devices/*.ufs/geometry_descriptor/memory_types
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows supported memory types. This is one of
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/*_memory_max_alloc_units
 +What:         /sys/bus/platform/devices/*.ufs/geometry_descriptor/*_memory_max_alloc_units
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the maximum number of allocation units for
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/*_memory_capacity_adjustment_factor
 +What:         /sys/bus/platform/devices/*.ufs/geometry_descriptor/*_memory_capacity_adjustment_factor
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the memory capacity adjustment factor for
  
  
  What:         /sys/bus/platform/drivers/ufshcd/*/health_descriptor/eol_info
 +What:         /sys/bus/platform/devices/*.ufs/health_descriptor/eol_info
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows preend of life information. This is one
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/health_descriptor/life_time_estimation_a
 +What:         /sys/bus/platform/devices/*.ufs/health_descriptor/life_time_estimation_a
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows indication of the device life time
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/health_descriptor/life_time_estimation_b
 +What:         /sys/bus/platform/devices/*.ufs/health_descriptor/life_time_estimation_b
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows indication of the device life time
  
  
  What:         /sys/bus/platform/drivers/ufshcd/*/power_descriptor/active_icc_levels_vcc*
 +What:         /sys/bus/platform/devices/*.ufs/power_descriptor/active_icc_levels_vcc*
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows maximum VCC, VCCQ and VCCQ2 value for
  
  
  What:         /sys/bus/platform/drivers/ufshcd/*/string_descriptors/manufacturer_name
 +What:         /sys/bus/platform/devices/*.ufs/string_descriptors/manufacturer_name
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file contains a device manufacturer name string.
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/string_descriptors/product_name
 +What:         /sys/bus/platform/devices/*.ufs/string_descriptors/product_name
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file contains a product name string. The full information
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/string_descriptors/oem_id
 +What:         /sys/bus/platform/devices/*.ufs/string_descriptors/oem_id
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file contains a OEM ID string. The full information
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/string_descriptors/serial_number
 +What:         /sys/bus/platform/devices/*.ufs/string_descriptors/serial_number
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file contains a device serial number string. The full
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/string_descriptors/product_revision
 +What:         /sys/bus/platform/devices/*.ufs/string_descriptors/product_revision
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file contains a product revision string. The full
@@@ -740,7 -684,6 +740,7 @@@ Description:       This file shows the granul
  
  
  What:         /sys/bus/platform/drivers/ufshcd/*/flags/device_init
 +What:         /sys/bus/platform/devices/*.ufs/flags/device_init
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the device init status. The full information
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/flags/permanent_wpe
 +What:         /sys/bus/platform/devices/*.ufs/flags/permanent_wpe
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows whether permanent write protection is enabled.
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/flags/power_on_wpe
 +What:         /sys/bus/platform/devices/*.ufs/flags/power_on_wpe
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows whether write protection is enabled on all
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/flags/bkops_enable
 +What:         /sys/bus/platform/devices/*.ufs/flags/bkops_enable
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows whether the device background operations are
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/flags/life_span_mode_enable
 +What:         /sys/bus/platform/devices/*.ufs/flags/life_span_mode_enable
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows whether the device life span mode is enabled.
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/flags/phy_resource_removal
 +What:         /sys/bus/platform/devices/*.ufs/flags/phy_resource_removal
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows whether physical resource removal is enable.
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/flags/busy_rtc
 +What:         /sys/bus/platform/devices/*.ufs/flags/busy_rtc
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows whether the device is executing internal
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/flags/disable_fw_update
 +What:         /sys/bus/platform/devices/*.ufs/flags/disable_fw_update
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows whether the device FW update is permanently
  
  
  What:         /sys/bus/platform/drivers/ufshcd/*/attributes/boot_lun_enabled
 +What:         /sys/bus/platform/devices/*.ufs/attributes/boot_lun_enabled
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file provides the boot lun enabled UFS device attribute.
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/attributes/current_power_mode
 +What:         /sys/bus/platform/devices/*.ufs/attributes/current_power_mode
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file provides the current power mode UFS device attribute.
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/attributes/active_icc_level
 +What:         /sys/bus/platform/devices/*.ufs/attributes/active_icc_level
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file provides the active icc level UFS device attribute.
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/attributes/ooo_data_enabled
 +What:         /sys/bus/platform/devices/*.ufs/attributes/ooo_data_enabled
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file provides the out of order data transfer enabled UFS
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/attributes/bkops_status
 +What:         /sys/bus/platform/devices/*.ufs/attributes/bkops_status
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file provides the background operations status UFS device
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/attributes/purge_status
 +What:         /sys/bus/platform/devices/*.ufs/attributes/purge_status
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file provides the purge operation status UFS device
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/attributes/max_data_in_size
 +What:         /sys/bus/platform/devices/*.ufs/attributes/max_data_in_size
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the maximum data size in a DATA IN
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/attributes/max_data_out_size
 +What:         /sys/bus/platform/devices/*.ufs/attributes/max_data_out_size
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the maximum number of bytes that can be
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/attributes/reference_clock_frequency
 +What:         /sys/bus/platform/devices/*.ufs/attributes/reference_clock_frequency
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file provides the reference clock frequency UFS device
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/attributes/configuration_descriptor_lock
 +What:         /sys/bus/platform/devices/*.ufs/attributes/configuration_descriptor_lock
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows whether the configuration descriptor is locked.
                UFS specifications 2.1. The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/attributes/max_number_of_rtt
 +What:         /sys/bus/platform/devices/*.ufs/attributes/max_number_of_rtt
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file provides the maximum current number of
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/attributes/exception_event_control
 +What:         /sys/bus/platform/devices/*.ufs/attributes/exception_event_control
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file provides the exception event control UFS device
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/attributes/exception_event_status
 +What:         /sys/bus/platform/devices/*.ufs/attributes/exception_event_status
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file provides the exception event status UFS device
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/attributes/ffu_status
 +What:         /sys/bus/platform/devices/*.ufs/attributes/ffu_status
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file provides the ffu status UFS device attribute.
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/attributes/psa_state
 +What:         /sys/bus/platform/devices/*.ufs/attributes/psa_state
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file show the PSA feature status. The full information
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/attributes/psa_data_size
 +What:         /sys/bus/platform/devices/*.ufs/attributes/psa_data_size
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
  Description:  This file shows the amount of data that the host plans to
  What:         /sys/class/scsi_device/*/device/dyn_cap_needed
  Date:         February 2018
  Contact:      Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
- Description:  This file shows the The amount of physical memory needed
+ Description:  This file shows the amount of physical memory needed
                to be removed from the physical memory resources pool of
                the particular logical unit. The full information about
                the attribute could be found at UFS specifications 2.1.
  
  
  What:         /sys/bus/platform/drivers/ufshcd/*/rpm_lvl
 +What:         /sys/bus/platform/devices/*.ufs/rpm_lvl
  Date:         September 2014
  Contact:      Subhash Jadavani <subhashj@codeaurora.org>
  Description:  This entry could be used to set or show the UFS device
                ==  ====================================================
  
  What:         /sys/bus/platform/drivers/ufshcd/*/rpm_target_dev_state
 +What:         /sys/bus/platform/devices/*.ufs/rpm_target_dev_state
  Date:         February 2018
  Contact:      Subhash Jadavani <subhashj@codeaurora.org>
  Description:  This entry shows the target power mode of an UFS device
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/rpm_target_link_state
 +What:         /sys/bus/platform/devices/*.ufs/rpm_target_link_state
  Date:         February 2018
  Contact:      Subhash Jadavani <subhashj@codeaurora.org>
  Description:  This entry shows the target state of an UFS UIC link
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/spm_lvl
 +What:         /sys/bus/platform/devices/*.ufs/spm_lvl
  Date:         September 2014
  Contact:      Subhash Jadavani <subhashj@codeaurora.org>
  Description:  This entry could be used to set or show the UFS device
                ==  ====================================================
  
  What:         /sys/bus/platform/drivers/ufshcd/*/spm_target_dev_state
 +What:         /sys/bus/platform/devices/*.ufs/spm_target_dev_state
  Date:         February 2018
  Contact:      Subhash Jadavani <subhashj@codeaurora.org>
  Description:  This entry shows the target power mode of an UFS device
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/spm_target_link_state
 +What:         /sys/bus/platform/devices/*.ufs/spm_target_link_state
  Date:         February 2018
  Contact:      Subhash Jadavani <subhashj@codeaurora.org>
  Description:  This entry shows the target state of an UFS UIC link
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/monitor/monitor_enable
 +What:         /sys/bus/platform/devices/*.ufs/monitor/monitor_enable
  Date:         January 2021
  Contact:      Can Guo <cang@codeaurora.org>
  Description:  This file shows the status of performance monitor enablement
                is stopped, the performance data collected is also cleared.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/monitor/monitor_chunk_size
 +What:         /sys/bus/platform/devices/*.ufs/monitor/monitor_chunk_size
  Date:         January 2021
  Contact:      Can Guo <cang@codeaurora.org>
  Description:  This file tells the monitor to focus on requests transferring
                It can only be changed when monitor is disabled.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/monitor/read_total_sectors
 +What:         /sys/bus/platform/devices/*.ufs/monitor/read_total_sectors
  Date:         January 2021
  Contact:      Can Guo <cang@codeaurora.org>
  Description:  This file shows how many sectors (in 512 Bytes) have been
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/monitor/read_total_busy
 +What:         /sys/bus/platform/devices/*.ufs/monitor/read_total_busy
  Date:         January 2021
  Contact:      Can Guo <cang@codeaurora.org>
  Description:  This file shows how long (in micro seconds) has been spent
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/monitor/read_nr_requests
 +What:         /sys/bus/platform/devices/*.ufs/monitor/read_nr_requests
  Date:         January 2021
  Contact:      Can Guo <cang@codeaurora.org>
  Description:  This file shows how many read requests have been sent after
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/monitor/read_req_latency_max
 +What:         /sys/bus/platform/devices/*.ufs/monitor/read_req_latency_max
  Date:         January 2021
  Contact:      Can Guo <cang@codeaurora.org>
  Description:  This file shows the maximum latency (in micro seconds) of
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/monitor/read_req_latency_min
 +What:         /sys/bus/platform/devices/*.ufs/monitor/read_req_latency_min
  Date:         January 2021
  Contact:      Can Guo <cang@codeaurora.org>
  Description:  This file shows the minimum latency (in micro seconds) of
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/monitor/read_req_latency_avg
 +What:         /sys/bus/platform/devices/*.ufs/monitor/read_req_latency_avg
  Date:         January 2021
  Contact:      Can Guo <cang@codeaurora.org>
  Description:  This file shows the average latency (in micro seconds) of
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/monitor/read_req_latency_sum
 +What:         /sys/bus/platform/devices/*.ufs/monitor/read_req_latency_sum
  Date:         January 2021
  Contact:      Can Guo <cang@codeaurora.org>
  Description:  This file shows the total latency (in micro seconds) of
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/monitor/write_total_sectors
 +What:         /sys/bus/platform/devices/*.ufs/monitor/write_total_sectors
  Date:         January 2021
  Contact:      Can Guo <cang@codeaurora.org>
  Description:  This file shows how many sectors (in 512 Bytes) have been sent
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/monitor/write_total_busy
 +What:         /sys/bus/platform/devices/*.ufs/monitor/write_total_busy
  Date:         January 2021
  Contact:      Can Guo <cang@codeaurora.org>
  Description:  This file shows how long (in micro seconds) has been spent
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/monitor/write_nr_requests
 +What:         /sys/bus/platform/devices/*.ufs/monitor/write_nr_requests
  Date:         January 2021
  Contact:      Can Guo <cang@codeaurora.org>
  Description:  This file shows how many write requests have been sent after
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/monitor/write_req_latency_max
 +What:         /sys/bus/platform/devices/*.ufs/monitor/write_req_latency_max
  Date:         January 2021
  Contact:      Can Guo <cang@codeaurora.org>
  Description:  This file shows the maximum latency (in micro seconds) of write
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/monitor/write_req_latency_min
 +What:         /sys/bus/platform/devices/*.ufs/monitor/write_req_latency_min
  Date:         January 2021
  Contact:      Can Guo <cang@codeaurora.org>
  Description:  This file shows the minimum latency (in micro seconds) of write
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/monitor/write_req_latency_avg
 +What:         /sys/bus/platform/devices/*.ufs/monitor/write_req_latency_avg
  Date:         January 2021
  Contact:      Can Guo <cang@codeaurora.org>
  Description:  This file shows the average latency (in micro seconds) of write
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/monitor/write_req_latency_sum
 +What:         /sys/bus/platform/devices/*.ufs/monitor/write_req_latency_sum
  Date:         January 2021
  Contact:      Can Guo <cang@codeaurora.org>
  Description:  This file shows the total latency (in micro seconds) of write
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/device_descriptor/wb_presv_us_en
 +What:         /sys/bus/platform/devices/*.ufs/device_descriptor/wb_presv_us_en
  Date:         June 2020
  Contact:      Asutosh Das <asutoshd@codeaurora.org>
  Description:  This entry shows if preserve user-space was configured
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/device_descriptor/wb_shared_alloc_units
 +What:         /sys/bus/platform/devices/*.ufs/device_descriptor/wb_shared_alloc_units
  Date:         June 2020
  Contact:      Asutosh Das <asutoshd@codeaurora.org>
  Description:  This entry shows the shared allocated units of WB buffer
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/device_descriptor/wb_type
 +What:         /sys/bus/platform/devices/*.ufs/device_descriptor/wb_type
  Date:         June 2020
  Contact:      Asutosh Das <asutoshd@codeaurora.org>
  Description:  This entry shows the configured WB type.
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/wb_buff_cap_adj
 +What:         /sys/bus/platform/devices/*.ufs/geometry_descriptor/wb_buff_cap_adj
  Date:         June 2020
  Contact:      Asutosh Das <asutoshd@codeaurora.org>
  Description:  This entry shows the total user-space decrease in shared
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/wb_max_alloc_units
 +What:         /sys/bus/platform/devices/*.ufs/geometry_descriptor/wb_max_alloc_units
  Date:         June 2020
  Contact:      Asutosh Das <asutoshd@codeaurora.org>
  Description:  This entry shows the Maximum total WriteBooster Buffer size
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/wb_max_wb_luns
 +What:         /sys/bus/platform/devices/*.ufs/geometry_descriptor/wb_max_wb_luns
  Date:         June 2020
  Contact:      Asutosh Das <asutoshd@codeaurora.org>
  Description:  This entry shows the maximum number of luns that can support
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/wb_sup_red_type
 +What:         /sys/bus/platform/devices/*.ufs/geometry_descriptor/wb_sup_red_type
  Date:         June 2020
  Contact:      Asutosh Das <asutoshd@codeaurora.org>
  Description:  The supportability of user space reduction mode
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/wb_sup_wb_type
 +What:         /sys/bus/platform/devices/*.ufs/geometry_descriptor/wb_sup_wb_type
  Date:         June 2020
  Contact:      Asutosh Das <asutoshd@codeaurora.org>
  Description:  The supportability of WriteBooster Buffer type.
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/flags/wb_enable
 +What:         /sys/bus/platform/devices/*.ufs/flags/wb_enable
  Date:         June 2020
  Contact:      Asutosh Das <asutoshd@codeaurora.org>
  Description:  This entry shows the status of WriteBooster.
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/flags/wb_flush_en
 +What:         /sys/bus/platform/devices/*.ufs/flags/wb_flush_en
  Date:         June 2020
  Contact:      Asutosh Das <asutoshd@codeaurora.org>
  Description:  This entry shows if flush is enabled.
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/flags/wb_flush_during_h8
 +What:         /sys/bus/platform/devices/*.ufs/flags/wb_flush_during_h8
  Date:         June 2020
  Contact:      Asutosh Das <asutoshd@codeaurora.org>
  Description:  Flush WriteBooster Buffer during hibernate state.
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/attributes/wb_avail_buf
 +What:         /sys/bus/platform/devices/*.ufs/attributes/wb_avail_buf
  Date:         June 2020
  Contact:      Asutosh Das <asutoshd@codeaurora.org>
  Description:  This entry shows the amount of unused WriteBooster buffer
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/attributes/wb_cur_buf
 +What:         /sys/bus/platform/devices/*.ufs/attributes/wb_cur_buf
  Date:         June 2020
  Contact:      Asutosh Das <asutoshd@codeaurora.org>
  Description:  This entry shows the amount of unused current buffer.
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/attributes/wb_flush_status
 +What:         /sys/bus/platform/devices/*.ufs/attributes/wb_flush_status
  Date:         June 2020
  Contact:      Asutosh Das <asutoshd@codeaurora.org>
  Description:  This entry shows the flush operation status.
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/attributes/wb_life_time_est
 +What:         /sys/bus/platform/devices/*.ufs/attributes/wb_life_time_est
  Date:         June 2020
  Contact:      Asutosh Das <asutoshd@codeaurora.org>
  Description:  This entry shows an indication of the WriteBooster Buffer
@@@ -1406,7 -1289,6 +1406,7 @@@ Description:    This entry shows the confi
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/wb_on
 +What:         /sys/bus/platform/devices/*.ufs/wb_on
  Date:         January 2021
  Contact:      Bean Huo <beanhuo@micron.com>
  Description:  This node is used to set or display whether UFS WriteBooster is
                disable/enable WriteBooster through this sysfs node.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/device_descriptor/hpb_version
 +What:         /sys/bus/platform/devices/*.ufs/device_descriptor/hpb_version
  Date:         June 2021
  Contact:      Daejun Park <daejun7.park@samsung.com>
  Description:  This entry shows the HPB specification version.
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/device_descriptor/hpb_control
 +What:         /sys/bus/platform/devices/*.ufs/device_descriptor/hpb_control
  Date:         June 2021
  Contact:      Daejun Park <daejun7.park@samsung.com>
  Description:  This entry shows an indication of the HPB control mode.
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/hpb_region_size
 +What:         /sys/bus/platform/devices/*.ufs/geometry_descriptor/hpb_region_size
  Date:         June 2021
  Contact:      Daejun Park <daejun7.park@samsung.com>
  Description:  This entry shows the bHPBRegionSize which can be calculated
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/hpb_number_lu
 +What:         /sys/bus/platform/devices/*.ufs/geometry_descriptor/hpb_number_lu
  Date:         June 2021
  Contact:      Daejun Park <daejun7.park@samsung.com>
  Description:  This entry shows the maximum number of HPB LU supported by
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/hpb_subregion_size
 +What:         /sys/bus/platform/devices/*.ufs/geometry_descriptor/hpb_subregion_size
  Date:         June 2021
  Contact:      Daejun Park <daejun7.park@samsung.com>
  Description:  This entry shows the bHPBSubRegionSize, which can be
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/hpb_max_active_regions
 +What:         /sys/bus/platform/devices/*.ufs/geometry_descriptor/hpb_max_active_regions
  Date:         June 2021
  Contact:      Daejun Park <daejun7.park@samsung.com>
  Description:  This entry shows the maximum number of active HPB regions that
@@@ -1558,7 -1434,6 +1558,7 @@@ Description:    This entry shows the reque
                this entry.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/attributes/max_data_size_hpb_single_cmd
 +What:         /sys/bus/platform/devices/*.ufs/attributes/max_data_size_hpb_single_cmd
  Date:         June 2021
  Contact:      Daejun Park <daejun7.park@samsung.com>
  Description:  This entry shows the maximum HPB data size for using a single HPB
                The file is read only.
  
  What:         /sys/bus/platform/drivers/ufshcd/*/flags/hpb_enable
 +What:         /sys/bus/platform/devices/*.ufs/flags/hpb_enable
  Date:         June 2021
  Contact:      Daejun Park <daejun7.park@samsung.com>
  Description:  This entry shows the status of HPB.
@@@ -234,11 -234,20 +234,20 @@@ static void ata_scsi_set_invalid_parame
                                     field, 0xff, 0);
  }
  
- struct device_attribute *ata_common_sdev_attrs[] = {
-       &dev_attr_unload_heads,
+ static struct attribute *ata_common_sdev_attrs[] = {
+       &dev_attr_unload_heads.attr,
        NULL
  };
- EXPORT_SYMBOL_GPL(ata_common_sdev_attrs);
+ static const struct attribute_group ata_common_sdev_attr_group = {
+       .attrs = ata_common_sdev_attrs
+ };
+ const struct attribute_group *ata_common_sdev_groups[] = {
+       &ata_common_sdev_attr_group,
+       NULL
+ };
+ EXPORT_SYMBOL_GPL(ata_common_sdev_groups);
  
  /**
   *    ata_std_bios_param - generic bios head/sector/cylinder calculator used by sd.
@@@ -634,7 -643,7 +643,7 @@@ static struct ata_queued_cmd *ata_scsi_
        qc = ata_qc_new_init(dev, scsi_cmd_to_rq(cmd)->tag);
        if (qc) {
                qc->scsicmd = cmd;
-               qc->scsidone = cmd->scsi_done;
+               qc->scsidone = scsi_done;
  
                qc->sg = scsi_sglist(cmd);
                qc->n_elem = scsi_sg_count(cmd);
                        qc->flags |= ATA_QCFLAG_QUIET;
        } else {
                cmd->result = (DID_OK << 16) | SAM_STAT_TASK_SET_FULL;
-               cmd->scsi_done(cmd);
+               scsi_done(cmd);
        }
  
        return qc;
@@@ -1738,14 -1747,14 +1747,14 @@@ static int ata_scsi_translate(struct at
  
  early_finish:
        ata_qc_free(qc);
-       cmd->scsi_done(cmd);
+       scsi_done(cmd);
        DPRINTK("EXIT - early finish (good or error)\n");
        return 0;
  
  err_did:
        ata_qc_free(qc);
        cmd->result = (DID_ERROR << 16);
-       cmd->scsi_done(cmd);
+       scsi_done(cmd);
  err_mem:
        DPRINTK("EXIT - internal\n");
        return 0;
@@@ -1895,7 -1904,7 +1904,7 @@@ static unsigned int ata_scsiop_inq_std(
   */
  static unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf)
  {
 -      int num_pages;
 +      int i, num_pages = 0;
        static const u8 pages[] = {
                0x00,   /* page 0x00, this page */
                0x80,   /* page 0x80, unit serial no page */
                0xb1,   /* page 0xb1, block device characteristics page */
                0xb2,   /* page 0xb2, thin provisioning page */
                0xb6,   /* page 0xb6, zoned block device characteristics */
 +              0xb9,   /* page 0xb9, concurrent positioning ranges */
        };
  
 -      num_pages = sizeof(pages);
 -      if (!(args->dev->flags & ATA_DFLAG_ZAC))
 -              num_pages--;
 +      for (i = 0; i < sizeof(pages); i++) {
 +              if (pages[i] == 0xb6 &&
 +                  !(args->dev->flags & ATA_DFLAG_ZAC))
 +                      continue;
 +              rbuf[num_pages + 4] = pages[i];
 +              num_pages++;
 +      }
        rbuf[3] = num_pages;    /* number of supported VPD pages */
 -      memcpy(rbuf + 4, pages, num_pages);
        return 0;
  }
  
@@@ -2125,26 -2130,6 +2134,26 @@@ static unsigned int ata_scsiop_inq_b6(s
        return 0;
  }
  
 +static unsigned int ata_scsiop_inq_b9(struct ata_scsi_args *args, u8 *rbuf)
 +{
 +      struct ata_cpr_log *cpr_log = args->dev->cpr_log;
 +      u8 *desc = &rbuf[64];
 +      int i;
 +
 +      /* SCSI Concurrent Positioning Ranges VPD page: SBC-5 rev 1 or later */
 +      rbuf[1] = 0xb9;
 +      put_unaligned_be16(64 + (int)cpr_log->nr_cpr * 32 - 4, &rbuf[3]);
 +
 +      for (i = 0; i < cpr_log->nr_cpr; i++, desc += 32) {
 +              desc[0] = cpr_log->cpr[i].num;
 +              desc[1] = cpr_log->cpr[i].num_storage_elements;
 +              put_unaligned_be64(cpr_log->cpr[i].start_lba, &desc[8]);
 +              put_unaligned_be64(cpr_log->cpr[i].num_lbas, &desc[16]);
 +      }
 +
 +      return 0;
 +}
 +
  /**
   *    modecpy - Prepare response for MODE SENSE
   *    @dest: output buffer
@@@ -3005,7 -2990,7 +3014,7 @@@ static unsigned int ata_scsi_pass_thru(
        ata_qc_set_pc_nbytes(qc);
  
        /* We may not issue DMA commands if no DMA mode is set */
 -      if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0) {
 +      if (tf->protocol == ATA_PROT_DMA && !ata_dma_enabled(dev)) {
                fp = 1;
                goto invalid_fld;
        }
@@@ -3155,7 -3140,7 +3164,7 @@@ static unsigned int ata_scsi_write_same
        u8 unmap = cdb[1] & 0x8;
  
        /* we may not issue DMA commands if no DMA mode is set */
 -      if (unlikely(!dev->dma_mode))
 +      if (unlikely(!ata_dma_enabled(dev)))
                goto invalid_opcode;
  
        /*
@@@ -4042,7 -4027,7 +4051,7 @@@ int __ata_scsi_queuecmd(struct scsi_cmn
        DPRINTK("bad CDB len=%u, scsi_op=0x%02x, max=%u\n",
                scmd->cmd_len, scsi_op, dev->cdb_len);
        scmd->result = DID_ERROR << 16;
-       scmd->scsi_done(scmd);
+       scsi_done(scmd);
        return 0;
  }
  
@@@ -4084,7 -4069,7 +4093,7 @@@ int ata_scsi_queuecmd(struct Scsi_Host 
                rc = __ata_scsi_queuecmd(cmd, dev);
        else {
                cmd->result = (DID_BAD_TARGET << 16);
-               cmd->scsi_done(cmd);
+               scsi_done(cmd);
        }
  
        spin_unlock_irqrestore(ap->lock, irq_flags);
@@@ -4144,17 -4129,11 +4153,17 @@@ void ata_scsi_simulate(struct ata_devic
                        ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b2);
                        break;
                case 0xb6:
 -                      if (dev->flags & ATA_DFLAG_ZAC) {
 +                      if (dev->flags & ATA_DFLAG_ZAC)
                                ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b6);
 -                              break;
 -                      }
 -                      fallthrough;
 +                      else
 +                              ata_scsi_set_invalid_field(dev, cmd, 2, 0xff);
 +                      break;
 +              case 0xb9:
 +                      if (dev->cpr_log)
 +                              ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b9);
 +                      else
 +                              ata_scsi_set_invalid_field(dev, cmd, 2, 0xff);
 +                      break;
                default:
                        ata_scsi_set_invalid_field(dev, cmd, 2, 0xff);
                        break;
                break;
        }
  
-       cmd->scsi_done(cmd);
+       scsi_done(cmd);
  }
  
  int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht)
diff --combined drivers/ata/sata_mv.c
@@@ -670,7 -670,7 +670,7 @@@ static struct scsi_host_template mv6_sh
        .can_queue              = MV_MAX_Q_DEPTH - 1,
        .sg_tablesize           = MV_MAX_SG_CT / 2,
        .dma_boundary           = MV_DMA_BOUNDARY,
-       .sdev_attrs             = ata_ncq_sdev_attrs,
+       .sdev_groups            = ata_ncq_sdev_groups,
        .change_queue_depth     = ata_scsi_change_queue_depth,
        .tag_alloc_policy       = BLK_TAG_ALLOC_RR,
        .slave_configure        = ata_scsi_slave_config
@@@ -3896,8 -3896,8 +3896,8 @@@ static int mv_chip_id(struct ata_host *
                break;
  
        default:
 -              dev_err(host->dev, "BUG: invalid board index %u\n", board_idx);
 -              return 1;
 +              dev_alert(host->dev, "BUG: invalid board index %u\n", board_idx);
 +              return -EINVAL;
        }
  
        hpriv->hp_flags = hp_flags;
@@@ -3,7 -3,6 +3,7 @@@
   * Copyright (c) 2017 Hisilicon Limited.
   */
  
 +#include <linux/sched/clock.h>
  #include "hisi_sas.h"
  #define DRV_NAME "hisi_sas_v3_hw"
  
@@@ -519,6 -518,8 +519,8 @@@ struct hisi_sas_err_record_v3 
  #define CHNL_INT_STS_INT2_MSK BIT(3)
  #define CHNL_WIDTH 4
  
+ #define BAR_NO_V3_HW  5
  enum {
        DSM_FUNC_ERR_HANDLE_MSI = 0,
  };
@@@ -1481,7 -1482,6 +1483,6 @@@ static irqreturn_t phy_up_v3_hw(int phy
        struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
        struct asd_sas_phy *sas_phy = &phy->sas_phy;
        struct device *dev = hisi_hba->dev;
-       unsigned long flags;
  
        del_timer(&phy->timer);
        hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 1);
        phy->phy_attached = 1;
        hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP);
        res = IRQ_HANDLED;
-       spin_lock_irqsave(&phy->lock, flags);
-       if (phy->reset_completion) {
-               phy->in_reset = 0;
-               complete(phy->reset_completion);
-       }
-       spin_unlock_irqrestore(&phy->lock, flags);
  end:
+       if (phy->reset_completion)
+               complete(phy->reset_completion);
        hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0,
                             CHL_INT0_SL_PHY_ENABLE_MSK);
        hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 0);
@@@ -1616,7 -1612,7 +1613,7 @@@ static irqreturn_t phy_bcast_v3_hw(int 
        hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 1);
        bcast_status = hisi_sas_phy_read32(hisi_hba, phy_no, RX_PRIMS_STATUS);
        if ((bcast_status & RX_BCAST_CHG_MSK) &&
-           !test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags))
+           !test_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags))
                sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD,
                                      GFP_ATOMIC);
        hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0,
@@@ -2770,14 -2766,16 +2767,16 @@@ static int slave_configure_v3_hw(struc
        return 0;
  }
  
- static struct device_attribute *host_attrs_v3_hw[] = {
-       &dev_attr_phy_event_threshold,
-       &dev_attr_intr_conv_v3_hw,
-       &dev_attr_intr_coal_ticks_v3_hw,
-       &dev_attr_intr_coal_count_v3_hw,
+ static struct attribute *host_v3_hw_attrs[] = {
+       &dev_attr_phy_event_threshold.attr,
+       &dev_attr_intr_conv_v3_hw.attr,
+       &dev_attr_intr_coal_ticks_v3_hw.attr,
+       &dev_attr_intr_coal_count_v3_hw.attr,
        NULL
  };
  
+ ATTRIBUTE_GROUPS(host_v3_hw);
  #define HISI_SAS_DEBUGFS_REG(x) {#x, x}
  
  struct hisi_sas_debugfs_reg_lu {
@@@ -3156,13 -3154,13 +3155,13 @@@ static struct scsi_host_template sht_v3
        .max_sectors            = SCSI_DEFAULT_MAX_SECTORS,
        .eh_device_reset_handler = sas_eh_device_reset_handler,
        .eh_target_reset_handler = sas_eh_target_reset_handler,
-       .slave_alloc            = sas_slave_alloc,
+       .slave_alloc            = hisi_sas_slave_alloc,
        .target_destroy         = sas_target_destroy,
        .ioctl                  = sas_ioctl,
  #ifdef CONFIG_COMPAT
        .compat_ioctl           = sas_ioctl,
  #endif
-       .shost_attrs            = host_attrs_v3_hw,
+       .shost_groups           = host_v3_hw_groups,
        .tag_alloc_policy       = BLK_TAG_ALLOC_RR,
        .host_reset             = hisi_sas_host_reset,
        .host_tagset            = 1,
@@@ -3687,7 -3685,6 +3686,6 @@@ static void debugfs_snapshot_regs_v3_hw
  
        do_div(timestamp, NSEC_PER_MSEC);
        hisi_hba->debugfs_timestamp[debugfs_dump_index] = timestamp;
-       hisi_hba->debugfs_dump_index++;
  
        debugfs_snapshot_prepare_v3_hw(hisi_hba);
  
        debugfs_create_files_v3_hw(hisi_hba);
  
        debugfs_snapshot_restore_v3_hw(hisi_hba);
+       hisi_hba->debugfs_dump_index++;
  }
  
  static ssize_t debugfs_trigger_dump_v3_hw_write(struct file *file,
@@@ -4677,15 -4675,15 +4676,15 @@@ hisi_sas_v3_probe(struct pci_dev *pdev
        struct sas_ha_struct *sha;
        int rc, phy_nr, port_nr, i;
  
-       rc = pci_enable_device(pdev);
+       rc = pcim_enable_device(pdev);
        if (rc)
                goto err_out;
  
        pci_set_master(pdev);
  
-       rc = pci_request_regions(pdev, DRV_NAME);
+       rc = pcim_iomap_regions(pdev, 1 << BAR_NO_V3_HW, DRV_NAME);
        if (rc)
-               goto err_out_disable_device;
+               goto err_out;
  
        rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
        if (rc)
        if (rc) {
                dev_err(dev, "No usable DMA addressing method\n");
                rc = -ENODEV;
-               goto err_out_regions;
+               goto err_out;
        }
  
        shost = hisi_sas_shost_alloc_pci(pdev);
        if (!shost) {
                rc = -ENOMEM;
-               goto err_out_regions;
+               goto err_out;
        }
  
        sha = SHOST_TO_SAS_HA(shost);
        hisi_hba = shost_priv(shost);
        dev_set_drvdata(dev, sha);
  
-       hisi_hba->regs = pcim_iomap(pdev, 5, 0);
+       hisi_hba->regs = pcim_iomap_table(pdev)[BAR_NO_V3_HW];
        if (!hisi_hba->regs) {
                dev_err(dev, "cannot map register\n");
                rc = -ENOMEM;
        rc = interrupt_preinit_v3_hw(hisi_hba);
        if (rc)
                goto err_out_debugfs;
-       dev_err(dev, "%d hw queues\n", shost->nr_hw_queues);
        rc = scsi_add_host(shost, dev);
        if (rc)
                goto err_out_free_irq_vectors;
@@@ -4800,10 -4798,6 +4799,6 @@@ err_out_debugfs
  err_out_ha:
        hisi_sas_free(hisi_hba);
        scsi_host_put(shost);
- err_out_regions:
-       pci_release_regions(pdev);
- err_out_disable_device:
-       pci_disable_device(pdev);
  err_out:
        return rc;
  }
@@@ -4833,16 -4827,13 +4828,13 @@@ static void hisi_sas_v3_remove(struct p
        struct Scsi_Host *shost = sha->core.shost;
  
        pm_runtime_get_noresume(dev);
-       if (timer_pending(&hisi_hba->timer))
-               del_timer(&hisi_hba->timer);
+       del_timer_sync(&hisi_hba->timer);
  
        sas_unregister_ha(sha);
        flush_workqueue(hisi_hba->wq);
        sas_remove_host(sha->core.shost);
  
        hisi_sas_v3_destroy_irqs(pdev, hisi_hba);
-       pci_release_regions(pdev);
-       pci_disable_device(pdev);
        hisi_sas_free(hisi_hba);
        debugfs_exit_v3_hw(hisi_hba);
        scsi_host_put(shost);
@@@ -4856,7 -4847,7 +4848,7 @@@ static void hisi_sas_reset_prepare_v3_h
        int rc;
  
        dev_info(dev, "FLR prepare\n");
-       set_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags);
+       set_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags);
        hisi_sas_controller_reset_prepare(hisi_hba);
  
        rc = disable_host_v3_hw(hisi_hba);
@@@ -4902,7 -4893,7 +4894,7 @@@ static int _suspend_v3_hw(struct devic
                return -ENODEV;
        }
  
-       if (test_and_set_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags))
+       if (test_and_set_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags))
                return -1;
  
        scsi_block_requests(shost);
        if (rc) {
                dev_err(dev, "PM suspend: disable host failed rc=%d\n", rc);
                clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags);
-               clear_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags);
+               clear_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags);
                scsi_unblock_requests(shost);
                return rc;
        }
@@@ -4952,7 -4943,7 +4944,7 @@@ static int _resume_v3_hw(struct device 
        }
        phys_init_v3_hw(hisi_hba);
        sas_resume_ha(sha);
-       clear_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags);
+       clear_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags);
  
        return 0;
  }
diff --combined drivers/scsi/hosts.c
@@@ -220,8 -220,7 +220,8 @@@ int scsi_add_host_with_dma(struct Scsi_
                goto fail;
        }
  
 -      shost->cmd_per_lun = min_t(short, shost->cmd_per_lun,
 +      /* Use min_t(int, ...) in case shost->can_queue exceeds SHRT_MAX */
 +      shost->cmd_per_lun = min_t(int, shost->cmd_per_lun,
                                   shost->can_queue);
  
        error = scsi_init_sense_cache(shost);
@@@ -377,7 -376,7 +377,7 @@@ static struct device_type scsi_host_typ
  struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
  {
        struct Scsi_Host *shost;
-       int index;
+       int index, i, j = 0;
  
        shost = kzalloc(sizeof(struct Scsi_Host) + privsize, GFP_KERNEL);
        if (!shost)
        dev_set_name(&shost->shost_gendev, "host%d", shost->host_no);
        shost->shost_gendev.bus = &scsi_bus_type;
        shost->shost_gendev.type = &scsi_host_type;
+       scsi_enable_async_suspend(&shost->shost_gendev);
  
        device_initialize(&shost->shost_dev);
        shost->shost_dev.parent = &shost->shost_gendev;
        shost->shost_dev.class = &shost_class;
        dev_set_name(&shost->shost_dev, "host%d", shost->host_no);
-       shost->shost_dev.groups = scsi_sysfs_shost_attr_groups;
+       shost->shost_dev.groups = shost->shost_dev_attr_groups;
+       shost->shost_dev_attr_groups[j++] = &scsi_shost_attr_group;
+       if (sht->shost_groups) {
+               for (i = 0; sht->shost_groups[i] &&
+                            j < ARRAY_SIZE(shost->shost_dev_attr_groups);
+                    i++, j++) {
+                       shost->shost_dev_attr_groups[j] =
+                               sht->shost_groups[i];
+               }
+       }
+       WARN_ON_ONCE(j >= ARRAY_SIZE(shost->shost_dev_attr_groups));
  
        shost->ehandler = kthread_run(scsi_error_handler, shost,
                        "scsi_eh_%d", shost->host_no);
@@@ -667,7 -677,7 +678,7 @@@ static bool complete_all_cmds_iter(stru
        scsi_dma_unmap(scmd);
        scmd->result = 0;
        set_host_byte(scmd, status);
-       scmd->scsi_done(scmd);
+       scsi_done(scmd);
        return true;
  }
  
@@@ -1046,7 -1046,7 +1046,7 @@@ static void ibmvfc_scsi_eh_done(struct 
  
        if (cmnd) {
                scsi_dma_unmap(cmnd);
-               cmnd->scsi_done(cmnd);
+               scsi_done(cmnd);
        }
  
        ibmvfc_free_event(evt);
@@@ -1696,7 -1696,6 +1696,7 @@@ static int ibmvfc_send_event(struct ibm
  
        spin_lock_irqsave(&evt->queue->l_lock, flags);
        list_add_tail(&evt->queue_list, &evt->queue->sent);
 +      atomic_set(&evt->active, 1);
  
        mb();
  
                                     be64_to_cpu(crq_as_u64[1]));
  
        if (rc) {
 +              atomic_set(&evt->active, 0);
                list_del(&evt->queue_list);
                spin_unlock_irqrestore(&evt->queue->l_lock, flags);
                del_timer(&evt->timer);
  
                evt->done(evt);
        } else {
 -              atomic_set(&evt->active, 1);
                spin_unlock_irqrestore(&evt->queue->l_lock, flags);
                ibmvfc_trc_start(evt);
        }
@@@ -1849,7 -1848,7 +1849,7 @@@ static void ibmvfc_scsi_done(struct ibm
                        cmnd->result = (DID_ERROR << 16);
  
                scsi_dma_unmap(cmnd);
-               cmnd->scsi_done(cmnd);
+               scsi_done(cmnd);
        }
  
        ibmvfc_free_event(evt);
@@@ -1935,7 -1934,7 +1935,7 @@@ static int ibmvfc_queuecommand(struct S
        if (unlikely((rc = fc_remote_port_chkready(rport))) ||
            unlikely((rc = ibmvfc_host_chkready(vhost)))) {
                cmnd->result = rc;
-               cmnd->scsi_done(cmnd);
+               scsi_done(cmnd);
                return 0;
        }
  
                            "Failed to map DMA buffer for command. rc=%d\n", rc);
  
        cmnd->result = DID_ERROR << 16;
-       cmnd->scsi_done(cmnd);
+       scsi_done(cmnd);
        return 0;
  }
  
@@@ -3589,18 -3588,20 +3589,20 @@@ static struct bin_attribute ibmvfc_trac
  };
  #endif
  
- static struct device_attribute *ibmvfc_attrs[] = {
-       &dev_attr_partition_name,
-       &dev_attr_device_name,
-       &dev_attr_port_loc_code,
-       &dev_attr_drc_name,
-       &dev_attr_npiv_version,
-       &dev_attr_capabilities,
-       &dev_attr_log_level,
-       &dev_attr_nr_scsi_channels,
+ static struct attribute *ibmvfc_host_attrs[] = {
+       &dev_attr_partition_name.attr,
+       &dev_attr_device_name.attr,
+       &dev_attr_port_loc_code.attr,
+       &dev_attr_drc_name.attr,
+       &dev_attr_npiv_version.attr,
+       &dev_attr_capabilities.attr,
+       &dev_attr_log_level.attr,
+       &dev_attr_nr_scsi_channels.attr,
        NULL
  };
  
+ ATTRIBUTE_GROUPS(ibmvfc_host);
  static struct scsi_host_template driver_template = {
        .module = THIS_MODULE,
        .name = "IBM POWER Virtual FC Adapter",
        .this_id = -1,
        .sg_tablesize = SG_ALL,
        .max_sectors = IBMVFC_MAX_SECTORS,
-       .shost_attrs = ibmvfc_attrs,
+       .shost_groups = ibmvfc_host_groups,
        .track_queue_depth = 1,
        .host_tagset = 1,
  };
@@@ -454,7 -454,7 +454,7 @@@ static int initialize_event_pool(struc
        pool->iu_storage =
            dma_alloc_coherent(hostdata->dev,
                               pool->size * sizeof(*pool->iu_storage),
-                              &pool->iu_token, 0);
+                              &pool->iu_token, GFP_KERNEL);
        if (!pool->iu_storage) {
                kfree(pool->events);
                return -ENOMEM;
@@@ -1039,9 -1039,9 +1039,9 @@@ static inline u16 lun_from_dev(struct s
   * @cmnd:     struct scsi_cmnd to be executed
   * @done:     Callback function to be called when cmd is completed
  */
- static int ibmvscsi_queuecommand_lck(struct scsi_cmnd *cmnd,
-                                void (*done) (struct scsi_cmnd *))
+ static int ibmvscsi_queuecommand_lck(struct scsi_cmnd *cmnd)
  {
+       void (*done)(struct scsi_cmnd *) = scsi_done;
        struct srp_cmd *srp_cmd;
        struct srp_event_struct *evt_struct;
        struct srp_indirect_buf *indirect;
                return SCSI_MLQUEUE_HOST_BUSY;
  
        /* Set up the actual SRP IU */
 +      BUILD_BUG_ON(sizeof(evt_struct->iu.srp) != SRP_MAX_IU_LEN);
 +      memset(&evt_struct->iu.srp, 0x00, sizeof(evt_struct->iu.srp));
        srp_cmd = &evt_struct->iu.srp.cmd;
 -      memset(srp_cmd, 0x00, SRP_MAX_IU_LEN);
        srp_cmd->opcode = SRP_CMD;
        memcpy(srp_cmd->cdb, cmnd->cmnd, sizeof(srp_cmd->cdb));
        int_to_scsilun(lun, &srp_cmd->lun);
@@@ -2065,18 -2064,20 +2065,20 @@@ static int ibmvscsi_host_reset(struct S
        return 0;
  }
  
- static struct device_attribute *ibmvscsi_attrs[] = {
-       &ibmvscsi_host_vhost_loc,
-       &ibmvscsi_host_vhost_name,
-       &ibmvscsi_host_srp_version,
-       &ibmvscsi_host_partition_name,
-       &ibmvscsi_host_partition_number,
-       &ibmvscsi_host_mad_version,
-       &ibmvscsi_host_os_type,
-       &ibmvscsi_host_config,
+ static struct attribute *ibmvscsi_host_attrs[] = {
+       &ibmvscsi_host_vhost_loc.attr,
+       &ibmvscsi_host_vhost_name.attr,
+       &ibmvscsi_host_srp_version.attr,
+       &ibmvscsi_host_partition_name.attr,
+       &ibmvscsi_host_partition_number.attr,
+       &ibmvscsi_host_mad_version.attr,
+       &ibmvscsi_host_os_type.attr,
+       &ibmvscsi_host_config.attr,
        NULL
  };
  
+ ATTRIBUTE_GROUPS(ibmvscsi_host);
  /* ------------------------------------------------------------
   * SCSI driver registration
   */
@@@ -2096,7 -2097,7 +2098,7 @@@ static struct scsi_host_template driver
        .can_queue = IBMVSCSI_MAX_REQUESTS_DEFAULT,
        .this_id = -1,
        .sg_tablesize = SG_ALL,
-       .shost_attrs = ibmvscsi_attrs,
+       .shost_groups = ibmvscsi_host_groups,
  };
  
  /**
diff --combined drivers/scsi/lpfc/lpfc.h
@@@ -22,7 -22,6 +22,7 @@@
   *******************************************************************/
  
  #include <scsi/scsi_host.h>
 +#include <linux/hashtable.h>
  #include <linux/ktime.h>
  #include <linux/workqueue.h>
  
@@@ -1029,6 -1028,7 +1029,7 @@@ struct lpfc_hba 
                                         * Firmware supports Forced Link Speed
                                         * capability
                                         */
+ #define HBA_PCI_ERR           0x80000 /* The PCI slot is offline */
  #define HBA_FLOGI_ISSUED      0x100000 /* FLOGI was issued */
  #define HBA_CGN_RSVD1         0x200000 /* Reserved CGN flag */
  #define HBA_CGN_DAY_WRAP      0x400000 /* HBA Congestion info day wraps */
@@@ -409,7 -409,7 +409,7 @@@ static bool mpi3mr_flush_scmd(struct re
                scsi_dma_unmap(scmd);
                scmd->result = DID_RESET << 16;
                scsi_print_command(scmd);
-               scmd->scsi_done(scmd);
+               scsi_done(scmd);
                mrioc->flush_io_count++;
        }
  
@@@ -2312,7 -2312,7 +2312,7 @@@ out_success
        }
        mpi3mr_clear_scmd_priv(mrioc, scmd);
        scsi_dma_unmap(scmd);
-       scmd->scsi_done(scmd);
+       scsi_done(scmd);
  out:
        if (sense_buf)
                mpi3mr_repost_sense_buf(mrioc,
@@@ -3322,7 -3322,7 +3322,7 @@@ static bool mpi3mr_check_return_unmap(s
                    __func__);
                scsi_print_command(scmd);
                scmd->result = DID_OK << 16;
-               scmd->scsi_done(scmd);
+               scsi_done(scmd);
                return true;
        }
  
                scmd->result = SAM_STAT_CHECK_CONDITION;
                scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST,
                    0x1A, 0);
-               scmd->scsi_done(scmd);
+               scsi_done(scmd);
                return true;
        }
        if (param_len != scsi_bufflen(scmd)) {
                scmd->result = SAM_STAT_CHECK_CONDITION;
                scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST,
                    0x1A, 0);
-               scmd->scsi_done(scmd);
+               scsi_done(scmd);
                return true;
        }
        buf = kzalloc(scsi_bufflen(scmd), GFP_ATOMIC);
                scmd->result = SAM_STAT_CHECK_CONDITION;
                scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST,
                    0x55, 0x03);
-               scmd->scsi_done(scmd);
+               scsi_done(scmd);
                return true;
        }
        scsi_sg_copy_to_buffer(scmd, buf, scsi_bufflen(scmd));
                scmd->result = SAM_STAT_CHECK_CONDITION;
                scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST,
                    0x26, 0);
-               scmd->scsi_done(scmd);
+               scsi_done(scmd);
                kfree(buf);
                return true;
        }
@@@ -3438,14 -3438,14 +3438,14 @@@ static int mpi3mr_qcmd(struct Scsi_Hos
        sdev_priv_data = scmd->device->hostdata;
        if (!sdev_priv_data || !sdev_priv_data->tgt_priv_data) {
                scmd->result = DID_NO_CONNECT << 16;
-               scmd->scsi_done(scmd);
+               scsi_done(scmd);
                goto out;
        }
  
        if (mrioc->stop_drv_processing &&
            !(mpi3mr_allow_scmd_to_fw(scmd))) {
                scmd->result = DID_NO_CONNECT << 16;
-               scmd->scsi_done(scmd);
+               scsi_done(scmd);
                goto out;
        }
  
        dev_handle = stgt_priv_data->dev_handle;
        if (dev_handle == MPI3MR_INVALID_DEV_HANDLE) {
                scmd->result = DID_NO_CONNECT << 16;
-               scmd->scsi_done(scmd);
+               scsi_done(scmd);
                goto out;
        }
        if (stgt_priv_data->dev_removed) {
                scmd->result = DID_NO_CONNECT << 16;
-               scmd->scsi_done(scmd);
+               scsi_done(scmd);
                goto out;
        }
  
        if (atomic_read(&stgt_priv_data->block_io)) {
                if (mrioc->stop_drv_processing) {
                        scmd->result = DID_NO_CONNECT << 16;
-                       scmd->scsi_done(scmd);
+                       scsi_done(scmd);
                        goto out;
                }
                retval = SCSI_MLQUEUE_DEVICE_BUSY;
        host_tag = mpi3mr_host_tag_for_scmd(mrioc, scmd);
        if (host_tag == MPI3MR_HOSTTAG_INVALID) {
                scmd->result = DID_ERROR << 16;
-               scmd->scsi_done(scmd);
+               scsi_done(scmd);
                goto out;
        }
  
@@@ -3736,7 -3736,7 +3736,7 @@@ mpi3mr_probe(struct pci_dev *pdev, cons
        shost->max_lun = -1;
        shost->unique_id = mrioc->id;
  
 -      shost->max_channel = 1;
 +      shost->max_channel = 0;
        shost->max_id = 0xFFFFFFFF;
  
        if (prot_mask >= 0)
@@@ -3314,7 -3314,7 +3314,7 @@@ scsih_abort(struct scsi_cmnd *scmd
                sdev_printk(KERN_INFO, scmd->device,
                    "device been deleted! scmd(0x%p)\n", scmd);
                scmd->result = DID_NO_CONNECT << 16;
-               scmd->scsi_done(scmd);
+               scsi_done(scmd);
                r = SUCCESS;
                goto out;
        }
@@@ -3390,7 -3390,7 +3390,7 @@@ scsih_dev_reset(struct scsi_cmnd *scmd
                sdev_printk(KERN_INFO, scmd->device,
                    "device been deleted! scmd(0x%p)\n", scmd);
                scmd->result = DID_NO_CONNECT << 16;
-               scmd->scsi_done(scmd);
+               scsi_done(scmd);
                r = SUCCESS;
                goto out;
        }
@@@ -3470,7 -3470,7 +3470,7 @@@ scsih_target_reset(struct scsi_cmnd *sc
                starget_printk(KERN_INFO, starget,
                    "target been deleted! scmd(0x%p)\n", scmd);
                scmd->result = DID_NO_CONNECT << 16;
-               scmd->scsi_done(scmd);
+               scsi_done(scmd);
                r = SUCCESS;
                goto out;
        }
@@@ -5030,7 -5030,7 +5030,7 @@@ _scsih_flush_running_cmds(struct MPT3SA
                        scmd->result = DID_NO_CONNECT << 16;
                else
                        scmd->result = DID_RESET << 16;
-               scmd->scsi_done(scmd);
+               scsi_done(scmd);
        }
        dtmprintk(ioc, ioc_info(ioc, "completing %d cmds\n", count));
  }
@@@ -5065,12 -5065,9 +5065,12 @@@ _scsih_setup_eedp(struct MPT3SAS_ADAPTE
        if (scmd->prot_flags & SCSI_PROT_GUARD_CHECK)
                eedp_flags |= MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD;
  
 -      if (scmd->prot_flags & SCSI_PROT_REF_CHECK) {
 -              eedp_flags |= MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG |
 -                      MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG;
 +      if (scmd->prot_flags & SCSI_PROT_REF_CHECK)
 +              eedp_flags |= MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG;
 +
 +      if (scmd->prot_flags & SCSI_PROT_REF_INCREMENT) {
 +              eedp_flags |= MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG;
 +
                mpi_request->CDB.EEDP32.PrimaryReferenceTag =
                        cpu_to_be32(scsi_prot_ref_tag(scmd));
        }
@@@ -5142,13 -5139,13 +5142,13 @@@ scsih_qcmd(struct Scsi_Host *shost, str
        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);
+               scsi_done(scmd);
                return 0;
        }
  
        if (!(_scsih_allow_scmd_to_device(ioc, scmd))) {
                scmd->result = DID_NO_CONNECT << 16;
-               scmd->scsi_done(scmd);
+               scsi_done(scmd);
                return 0;
        }
  
        handle = sas_target_priv_data->handle;
        if (handle == MPT3SAS_INVALID_DEVICE_HANDLE) {
                scmd->result = DID_NO_CONNECT << 16;
-               scmd->scsi_done(scmd);
+               scsi_done(scmd);
                return 0;
        }
  
        } else if (sas_target_priv_data->deleted) {
                /* device has been deleted */
                scmd->result = DID_NO_CONNECT << 16;
-               scmd->scsi_done(scmd);
+               scsi_done(scmd);
                return 0;
        } else if (sas_target_priv_data->tm_busy ||
                   sas_device_priv_data->block) {
@@@ -5912,7 -5909,7 +5912,7 @@@ _scsih_io_done(struct MPT3SAS_ADAPTER *
  
        scsi_dma_unmap(scmd);
        mpt3sas_base_free_smid(ioc, smid);
-       scmd->scsi_done(scmd);
+       scsi_done(scmd);
        return 0;
  }
  
@@@ -11878,8 -11875,8 +11878,8 @@@ static struct scsi_host_template mpt2sa
        .sg_tablesize                   = MPT2SAS_SG_DEPTH,
        .max_sectors                    = 32767,
        .cmd_per_lun                    = 7,
-       .shost_attrs                    = mpt3sas_host_attrs,
-       .sdev_attrs                     = mpt3sas_dev_attrs,
+       .shost_groups                   = mpt3sas_host_groups,
+       .sdev_groups                    = mpt3sas_dev_groups,
        .track_queue_depth              = 1,
        .cmd_size                       = sizeof(struct scsiio_tracker),
  };
@@@ -11917,8 -11914,8 +11917,8 @@@ static struct scsi_host_template mpt3sa
        .max_sectors                    = 32767,
        .max_segment_size               = 0xffffffff,
        .cmd_per_lun                    = 7,
-       .shost_attrs                    = mpt3sas_host_attrs,
-       .sdev_attrs                     = mpt3sas_dev_attrs,
+       .shost_groups                   = mpt3sas_host_groups,
+       .sdev_groups                    = mpt3sas_dev_groups,
        .track_queue_depth              = 1,
        .cmd_size                       = sizeof(struct scsiio_tracker),
        .map_queues                     = scsih_map_queues,
diff --combined drivers/scsi/qedf/qedf.h
@@@ -141,7 -141,7 +141,7 @@@ struct qedf_ioreq 
        struct completion tm_done;
        struct completion abts_done;
        struct completion cleanup_done;
 -      struct e4_fcoe_task_context *task;
 +      struct fcoe_task_context *task;
        struct fcoe_task_params *task_params;
        struct scsi_sgl_task_params *sgl_task_params;
        int idx;
@@@ -498,12 -498,12 +498,12 @@@ extern void qedf_process_abts_compl(str
  extern struct qedf_ioreq *qedf_alloc_cmd(struct qedf_rport *fcport,
        u8 cmd_type);
  
- extern struct device_attribute *qedf_host_attrs[];
+ extern const struct attribute_group *qedf_host_groups[];
  extern void qedf_cmd_timer_set(struct qedf_ctx *qedf, struct qedf_ioreq *io_req,
        unsigned int timer_msec);
  extern int qedf_init_mp_req(struct qedf_ioreq *io_req);
  extern void qedf_init_mp_task(struct qedf_ioreq *io_req,
 -      struct e4_fcoe_task_context *task_ctx, struct fcoe_wqe *sqe);
 +      struct fcoe_task_context *task_ctx, struct fcoe_wqe *sqe);
  extern u16 qedf_get_sqe_idx(struct qedf_rport *fcport);
  extern void qedf_ring_doorbell(struct qedf_rport *fcport);
  extern void qedf_process_els_compl(struct qedf_ctx *qedf, struct fcoe_cqe *cqe,
@@@ -584,7 -584,7 +584,7 @@@ static void qedf_build_fcp_cmnd(struct 
  }
  
  static void  qedf_init_task(struct qedf_rport *fcport, struct fc_lport *lport,
 -      struct qedf_ioreq *io_req, struct e4_fcoe_task_context *task_ctx,
 +      struct qedf_ioreq *io_req, struct fcoe_task_context *task_ctx,
        struct fcoe_wqe *sqe)
  {
        enum fcoe_task_type task_type;
  
        /* Note init_initiator_rw_fcoe_task memsets the task context */
        io_req->task = task_ctx;
 -      memset(task_ctx, 0, sizeof(struct e4_fcoe_task_context));
 +      memset(task_ctx, 0, sizeof(struct fcoe_task_context));
        memset(io_req->task_params, 0, sizeof(struct fcoe_task_params));
        memset(io_req->sgl_task_params, 0, sizeof(struct scsi_sgl_task_params));
  
  }
  
  void qedf_init_mp_task(struct qedf_ioreq *io_req,
 -      struct e4_fcoe_task_context *task_ctx, struct fcoe_wqe *sqe)
 +      struct fcoe_task_context *task_ctx, struct fcoe_wqe *sqe)
  {
        struct qedf_mp_req *mp_req = &(io_req->mp_req);
        struct qedf_rport *fcport = io_req->fcport;
  
        memset(&tx_sgl_task_params, 0, sizeof(struct scsi_sgl_task_params));
        memset(&rx_sgl_task_params, 0, sizeof(struct scsi_sgl_task_params));
 -      memset(task_ctx, 0, sizeof(struct e4_fcoe_task_context));
 +      memset(task_ctx, 0, sizeof(struct fcoe_task_context));
        memset(&task_fc_hdr, 0, sizeof(struct fcoe_tx_mid_path_params));
  
        /* Setup the task from io_req for easy reference */
@@@ -850,7 -850,7 +850,7 @@@ int qedf_post_io_req(struct qedf_rport 
        struct Scsi_Host *host = sc_cmd->device->host;
        struct fc_lport *lport = shost_priv(host);
        struct qedf_ctx *qedf = lport_priv(lport);
 -      struct e4_fcoe_task_context *task_ctx;
 +      struct fcoe_task_context *task_ctx;
        u16 xid;
        struct fcoe_wqe *sqe;
        u16 sqe_idx;
@@@ -947,7 -947,7 +947,7 @@@ qedf_queuecommand(struct Scsi_Host *hos
                         "Number of SG elements %d exceeds what hardware limitation of %d.\n",
                         num_sgs, QEDF_MAX_BDS_PER_CMD);
                sc_cmd->result = DID_ERROR;
-               sc_cmd->scsi_done(sc_cmd);
+               scsi_done(sc_cmd);
                return 0;
        }
  
                          "Returning DNC as unloading or stop io, flags 0x%lx.\n",
                          qedf->flags);
                sc_cmd->result = DID_NO_CONNECT << 16;
-               sc_cmd->scsi_done(sc_cmd);
+               scsi_done(sc_cmd);
                return 0;
        }
  
                    "Completing sc_cmd=%p DID_NO_CONNECT as MSI-X is not enabled.\n",
                    sc_cmd);
                sc_cmd->result = DID_NO_CONNECT << 16;
-               sc_cmd->scsi_done(sc_cmd);
+               scsi_done(sc_cmd);
                return 0;
        }
  
                          "fc_remote_port_chkready failed=0x%x for port_id=0x%06x.\n",
                          rval, rport->port_id);
                sc_cmd->result = rval;
-               sc_cmd->scsi_done(sc_cmd);
+               scsi_done(sc_cmd);
                return 0;
        }
  
@@@ -1313,7 -1313,7 +1313,7 @@@ out
  
        io_req->sc_cmd = NULL;
        sc_cmd->SCp.ptr =  NULL;
-       sc_cmd->scsi_done(sc_cmd);
+       scsi_done(sc_cmd);
        kref_put(&io_req->refcount, qedf_release_cmd);
  }
  
@@@ -1386,13 -1386,6 +1386,6 @@@ void qedf_scsi_done(struct qedf_ctx *qe
                goto bad_scsi_ptr;
        }
  
-       if (!sc_cmd->scsi_done) {
-               QEDF_ERR(&qedf->dbg_ctx,
-                        "sc_cmd->scsi_done for sc_cmd %p is NULL.\n",
-                        sc_cmd);
-               goto bad_scsi_ptr;
-       }
        qedf_unmap_sg_list(qedf, io_req);
  
        sc_cmd->result = result << 16;
  
        io_req->sc_cmd = NULL;
        sc_cmd->SCp.ptr = NULL;
-       sc_cmd->scsi_done(sc_cmd);
+       scsi_done(sc_cmd);
        kref_put(&io_req->refcount, qedf_release_cmd);
        return;
  
@@@ -2293,7 -2286,7 +2286,7 @@@ static int qedf_execute_tmf(struct qedf
        uint8_t tm_flags)
  {
        struct qedf_ioreq *io_req;
 -      struct e4_fcoe_task_context *task;
 +      struct fcoe_task_context *task;
        struct qedf_ctx *qedf = fcport->qedf;
        struct fc_lport *lport = qedf->lport;
        int rc = 0;
@@@ -986,7 -986,7 +986,7 @@@ static struct scsi_host_template qedf_h
        .cmd_per_lun    = 32,
        .max_sectors    = 0xffff,
        .queuecommand   = qedf_queuecommand,
-       .shost_attrs    = qedf_host_attrs,
+       .shost_groups   = qedf_host_groups,
        .eh_abort_handler       = qedf_eh_abort,
        .eh_device_reset_handler = qedf_eh_device_reset, /* lun reset */
        .eh_target_reset_handler = qedf_eh_target_reset, /* target reset */
@@@ -2170,7 -2170,7 +2170,7 @@@ static bool qedf_fp_has_work(struct qed
        struct qedf_ctx *qedf = fp->qedf;
        struct global_queue *que;
        struct qed_sb_info *sb_info = fp->sb_info;
 -      struct status_block_e4 *sb = sb_info->sb_virt;
 +      struct status_block *sb = sb_info->sb_virt;
        u16 prod_idx;
  
        /* Get the pointer to the global CQ this completion is on */
@@@ -2197,7 -2197,7 +2197,7 @@@ static bool qedf_process_completions(st
  {
        struct qedf_ctx *qedf = fp->qedf;
        struct qed_sb_info *sb_info = fp->sb_info;
 -      struct status_block_e4 *sb = sb_info->sb_virt;
 +      struct status_block *sb = sb_info->sb_virt;
        struct global_queue *que;
        u16 prod_idx;
        struct fcoe_cqe *cqe;
@@@ -2688,12 -2688,12 +2688,12 @@@ void qedf_fp_io_handler(struct work_str
  static int qedf_alloc_and_init_sb(struct qedf_ctx *qedf,
        struct qed_sb_info *sb_info, u16 sb_id)
  {
 -      struct status_block_e4 *sb_virt;
 +      struct status_block *sb_virt;
        dma_addr_t sb_phys;
        int ret;
  
        sb_virt = dma_alloc_coherent(&qedf->pdev->dev,
 -          sizeof(struct status_block_e4), &sb_phys, GFP_KERNEL);
 +          sizeof(struct status_block), &sb_phys, GFP_KERNEL);
  
        if (!sb_virt) {
                QEDF_ERR(&qedf->dbg_ctx,
@@@ -3416,9 -3416,7 +3416,9 @@@ retry_probe
                qedf->devlink = qed_ops->common->devlink_register(qedf->cdev);
                if (IS_ERR(qedf->devlink)) {
                        QEDF_ERR(&qedf->dbg_ctx, "Cannot register devlink\n");
 +                      rc = PTR_ERR(qedf->devlink);
                        qedf->devlink = NULL;
 +                      goto err2;
                }
        }
  
@@@ -431,7 -431,7 +431,7 @@@ done_unmap_sg
        goto done_free_fcport;
  
  done_free_fcport:
 -      if (bsg_request->msgcode == FC_BSG_RPT_ELS)
 +      if (bsg_request->msgcode != FC_BSG_RPT_ELS)
                qla2x00_free_fcport(fcport);
  done:
        return rval;
@@@ -2877,6 -2877,9 +2877,9 @@@ qla2x00_process_vendor_specific(struct 
        case QL_VND_MANAGE_HOST_PORT:
                return qla2x00_manage_host_port(bsg_job);
  
+       case QL_VND_MBX_PASSTHRU:
+               return qla2x00_mailbox_passthru(bsg_job);
        default:
                return -ENOSYS;
        }
@@@ -3013,3 -3016,48 +3016,48 @@@ done
        sp->free(sp);
        return 0;
  }
+ int qla2x00_mailbox_passthru(struct bsg_job *bsg_job)
+ {
+       struct fc_bsg_reply *bsg_reply = bsg_job->reply;
+       scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
+       int ret = -EINVAL;
+       int ptsize = sizeof(struct qla_mbx_passthru);
+       struct qla_mbx_passthru *req_data = NULL;
+       uint32_t req_data_len;
+       req_data_len = bsg_job->request_payload.payload_len;
+       if (req_data_len != ptsize) {
+               ql_log(ql_log_warn, vha, 0xf0a3, "req_data_len invalid.\n");
+               return -EIO;
+       }
+       req_data = kzalloc(ptsize, GFP_KERNEL);
+       if (!req_data) {
+               ql_log(ql_log_warn, vha, 0xf0a4,
+                      "req_data memory allocation failure.\n");
+               return -ENOMEM;
+       }
+       /* Copy the request buffer in req_data */
+       sg_copy_to_buffer(bsg_job->request_payload.sg_list,
+                         bsg_job->request_payload.sg_cnt, req_data, ptsize);
+       ret = qla_mailbox_passthru(vha, req_data->mbx_in, req_data->mbx_out);
+       /* Copy the req_data in  request buffer */
+       sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
+                           bsg_job->reply_payload.sg_cnt, req_data, ptsize);
+       bsg_reply->reply_payload_rcv_len = ptsize;
+       if (ret == QLA_SUCCESS)
+               bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
+       else
+               bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_ERR;
+       bsg_job->reply_len = sizeof(*bsg_job->reply);
+       bsg_reply->result = DID_OK << 16;
+       bsg_job_done(bsg_job, bsg_reply->result, bsg_reply->reply_payload_rcv_len);
+       kfree(req_data);
+       return ret;
+ }
@@@ -8,8 -8,6 +8,8 @@@
  #include <linux/delay.h>
  #include <linux/nvme.h>
  #include <linux/nvme-fc.h>
 +#include <linux/blk-mq-pci.h>
 +#include <linux/blk-mq.h>
  
  static struct nvme_fc_port_template qla_nvme_fc_transport;
  
@@@ -230,6 -228,8 +230,8 @@@ static void qla_nvme_abort_work(struct 
        fc_port_t *fcport = sp->fcport;
        struct qla_hw_data *ha = fcport->vha->hw;
        int rval, abts_done_called = 1;
+       bool io_wait_for_abort_done;
+       uint32_t handle;
  
        ql_dbg(ql_dbg_io, fcport->vha, 0xffff,
               "%s called for sp=%p, hndl=%x on fcport=%p desc=%p deleted=%d\n",
                goto out;
        }
  
+       /*
+        * sp may not be valid after abort_command if return code is either
+        * SUCCESS or ERR_FROM_FW codes, so cache the value here.
+        */
+       io_wait_for_abort_done = ql2xabts_wait_nvme &&
+                                       QLA_ABTS_WAIT_ENABLED(sp);
+       handle = sp->handle;
        rval = ha->isp_ops->abort_command(sp);
  
        ql_dbg(ql_dbg_io, fcport->vha, 0x212b,
            "%s: %s command for sp=%p, handle=%x on fcport=%p rval=%x\n",
            __func__, (rval != QLA_SUCCESS) ? "Failed to abort" : "Aborted",
-           sp, sp->handle, fcport, rval);
+           sp, handle, fcport, rval);
  
        /*
         * If async tmf is enabled, the abort callback is called only on
         * are waited until ABTS complete. This kref is decreased
         * at qla24xx_abort_sp_done function.
         */
-       if (abts_done_called && ql2xabts_wait_nvme && QLA_ABTS_WAIT_ENABLED(sp))
+       if (abts_done_called && io_wait_for_abort_done)
                return;
  out:
        /* kref_get was done before work was schedule. */
@@@ -391,6 -399,7 +401,7 @@@ static inline int qla2x00_start_nvme_mq
        uint16_t        avail_dsds;
        struct dsd64    *cur_dsd;
        struct req_que *req = NULL;
+       struct rsp_que *rsp = NULL;
        struct scsi_qla_host *vha = sp->fcport->vha;
        struct qla_hw_data *ha = vha->hw;
        struct qla_qpair *qpair = sp->qpair;
  
        /* Setup qpair pointers */
        req = qpair->req;
+       rsp = qpair->rsp;
        tot_dsds = fd->sg_cnt;
  
        /* Acquire qpair specific lock */
        /* Set chip new ring index. */
        wrt_reg_dword(req->req_q_in, req->ring_index);
  
+       if (vha->flags.process_response_queue &&
+           rsp->ring_ptr->signature != RESPONSE_PROCESSED)
+               qla24xx_process_response_queue(vha, rsp);
  queuing_error:
        spin_unlock_irqrestore(&qpair->qp_lock, flags);
  
@@@ -644,18 -658,6 +660,18 @@@ static int qla_nvme_post_cmd(struct nvm
        return rval;
  }
  
 +static void qla_nvme_map_queues(struct nvme_fc_local_port *lport,
 +              struct blk_mq_queue_map *map)
 +{
 +      struct scsi_qla_host *vha = lport->private;
 +      int rc;
 +
 +      rc = blk_mq_pci_map_queues(map, vha->hw->pdev, vha->irq_offset);
 +      if (rc)
 +              ql_log(ql_log_warn, vha, 0x21de,
 +                     "pci map queue failed 0x%x", rc);
 +}
 +
  static void qla_nvme_localport_delete(struct nvme_fc_local_port *lport)
  {
        struct scsi_qla_host *vha = lport->private;
@@@ -690,7 -692,6 +706,7 @@@ static struct nvme_fc_port_template qla
        .ls_abort       = qla_nvme_ls_abort,
        .fcp_io         = qla_nvme_post_cmd,
        .fcp_abort      = qla_nvme_fcp_abort,
 +      .map_queues     = qla_nvme_map_queues,
        .max_hw_queues  = 8,
        .max_sgl_segments = 1024,
        .max_dif_sgl_segments = 64,
@@@ -737,7 -737,7 +737,7 @@@ void qla2x00_sp_compl(srb_t *sp, int re
        sp->free(sp);
        cmd->result = res;
        CMD_SP(cmd) = NULL;
-       cmd->scsi_done(cmd);
+       scsi_done(cmd);
        if (comp)
                complete(comp);
  }
@@@ -828,7 -828,7 +828,7 @@@ void qla2xxx_qpair_sp_compl(srb_t *sp, 
        sp->free(sp);
        cmd->result = res;
        CMD_SP(cmd) = NULL;
-       cmd->scsi_done(cmd);
+       scsi_done(cmd);
        if (comp)
                complete(comp);
  }
@@@ -950,7 -950,7 +950,7 @@@ qc24_target_busy
        return SCSI_MLQUEUE_TARGET_BUSY;
  
  qc24_fail_command:
-       cmd->scsi_done(cmd);
+       scsi_done(cmd);
  
        return 0;
  }
@@@ -1038,7 -1038,7 +1038,7 @@@ qc24_target_busy
        return SCSI_MLQUEUE_TARGET_BUSY;
  
  qc24_fail_command:
-       cmd->scsi_done(cmd);
+       scsi_done(cmd);
  
        return 0;
  }
@@@ -1258,6 -1258,7 +1258,7 @@@ qla2xxx_eh_abort(struct scsi_cmnd *cmd
        uint32_t ratov_j;
        struct qla_qpair *qpair;
        unsigned long flags;
+       int fast_fail_status = SUCCESS;
  
        if (qla2x00_isp_reg_stat(ha)) {
                ql_log(ql_log_info, vha, 0x8042,
                return FAILED;
        }
  
+       /* Save any FAST_IO_FAIL value to return later if abort succeeds */
        ret = fc_block_scsi_eh(cmd);
        if (ret != 0)
-               return ret;
+               fast_fail_status = ret;
  
        sp = scsi_cmd_priv(cmd);
        qpair = sp->qpair;
        vha->cmd_timeout_cnt++;
  
        if ((sp->fcport && sp->fcport->deleted) || !qpair)
-               return SUCCESS;
+               return fast_fail_status != SUCCESS ? fast_fail_status : FAILED;
  
        spin_lock_irqsave(qpair->qp_lock_ptr, flags);
        sp->comp = &comp;
                            __func__, ha->r_a_tov/10);
                        ret = FAILED;
                } else {
-                       ret = SUCCESS;
+                       ret = fast_fail_status;
                }
                break;
        default:
@@@ -2794,6 -2796,16 +2796,16 @@@ qla2xxx_scan_finished(struct Scsi_Host 
        return atomic_read(&vha->loop_state) == LOOP_READY;
  }
  
+ static void qla_heartbeat_work_fn(struct work_struct *work)
+ {
+       struct qla_hw_data *ha = container_of(work,
+               struct qla_hw_data, heartbeat_work);
+       struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
+       if (!ha->flags.mbox_busy && base_vha->flags.init_done)
+               qla_no_op_mb(base_vha);
+ }
  static void qla2x00_iocb_work_fn(struct work_struct *work)
  {
        struct scsi_qla_host *vha = container_of(work,
@@@ -3232,6 -3244,7 +3244,7 @@@ qla2x00_probe_one(struct pci_dev *pdev
            host->transportt, sht->vendor_id);
  
        INIT_WORK(&base_vha->iocb_work, qla2x00_iocb_work_fn);
+       INIT_WORK(&ha->heartbeat_work, qla_heartbeat_work_fn);
  
        /* Set up the irqs */
        ret = qla2x00_request_irqs(ha, rsp);
            host->can_queue, base_vha->req,
            base_vha->mgmt_svr_loop_id, host->sg_tablesize);
  
+       /* Check if FW supports MQ or not for ISP25xx */
+       if (IS_QLA25XX(ha) && !(ha->fw_attributes & BIT_6))
+               ha->mqenable = 0;
        if (ha->mqenable) {
                bool startit = false;
  
@@@ -4157,7 -4174,7 +4174,7 @@@ qla2x00_mem_alloc(struct qla_hw_data *h
                                        ql_dbg_pci(ql_dbg_init, ha->pdev,
                                            0xe0ee, "%s: failed alloc dsd\n",
                                            __func__);
 -                                      return 1;
 +                                      return -ENOMEM;
                                }
                                ha->dif_bundle_kallocs++;
  
@@@ -7114,17 -7131,6 +7131,6 @@@ intr_on_check
                        qla2x00_lip_reset(base_vha);
                }
  
-               if (test_bit(HEARTBEAT_CHK, &base_vha->dpc_flags)) {
-                       /*
-                        * if there is a mb in progress then that's
-                        * enough of a check to see if fw is still ticking.
-                        */
-                       if (!ha->flags.mbox_busy && base_vha->flags.init_done)
-                               qla_no_op_mb(base_vha);
-                       clear_bit(HEARTBEAT_CHK, &base_vha->dpc_flags);
-               }
                ha->dpc_active = 0;
  end_loop:
                set_current_state(TASK_INTERRUPTIBLE);
@@@ -7183,57 -7189,51 +7189,51 @@@ qla2x00_rst_aen(scsi_qla_host_t *vha
  
  static bool qla_do_heartbeat(struct scsi_qla_host *vha)
  {
-       u64 cmd_cnt, prev_cmd_cnt;
-       bool do_hb = false;
        struct qla_hw_data *ha = vha->hw;
-       int i;
+       u32 cmpl_cnt;
+       u16 i;
+       bool do_heartbeat = false;
  
-       /* if cmds are still pending down in fw, then do hb */
-       if (ha->base_qpair->cmd_cnt != ha->base_qpair->cmd_completion_cnt) {
-               do_hb = true;
+       /*
+        * Allow do_heartbeat only if we don’t have any active interrupts,
+        * but there are still IOs outstanding with firmware.
+        */
+       cmpl_cnt = ha->base_qpair->cmd_completion_cnt;
+       if (cmpl_cnt == ha->base_qpair->prev_completion_cnt &&
+           cmpl_cnt != ha->base_qpair->cmd_cnt) {
+               do_heartbeat = true;
                goto skip;
        }
+       ha->base_qpair->prev_completion_cnt = cmpl_cnt;
  
        for (i = 0; i < ha->max_qpairs; i++) {
-               if (ha->queue_pair_map[i] &&
-                   ha->queue_pair_map[i]->cmd_cnt !=
-                   ha->queue_pair_map[i]->cmd_completion_cnt) {
-                       do_hb = true;
-                       break;
+               if (ha->queue_pair_map[i]) {
+                       cmpl_cnt = ha->queue_pair_map[i]->cmd_completion_cnt;
+                       if (cmpl_cnt == ha->queue_pair_map[i]->prev_completion_cnt &&
+                           cmpl_cnt != ha->queue_pair_map[i]->cmd_cnt) {
+                               do_heartbeat = true;
+                               break;
+                       }
+                       ha->queue_pair_map[i]->prev_completion_cnt = cmpl_cnt;
                }
        }
  
  skip:
-       prev_cmd_cnt = ha->prev_cmd_cnt;
-       cmd_cnt = ha->base_qpair->cmd_cnt;
-       for (i = 0; i < ha->max_qpairs; i++) {
-               if (ha->queue_pair_map[i])
-                       cmd_cnt += ha->queue_pair_map[i]->cmd_cnt;
-       }
-       ha->prev_cmd_cnt = cmd_cnt;
-       if (!do_hb && ((cmd_cnt - prev_cmd_cnt) > 50))
-               /*
-                * IOs are completing before periodic hb check.
-                * IOs seems to be running, do hb for sanity check.
-                */
-               do_hb = true;
-       return do_hb;
+       return do_heartbeat;
  }
  
  static void qla_heart_beat(struct scsi_qla_host *vha)
  {
+       struct qla_hw_data *ha = vha->hw;
        if (vha->vp_idx)
                return;
  
        if (vha->hw->flags.eeh_busy || qla2x00_chip_is_down(vha))
                return;
  
-       if (qla_do_heartbeat(vha)) {
-               set_bit(HEARTBEAT_CHK, &vha->dpc_flags);
-               qla2xxx_wake_dpc(vha);
-       }
+       if (qla_do_heartbeat(vha))
+               queue_work(ha->wq, &ha->heartbeat_work);
  }
  
  /**************************************************************************
@@@ -7943,7 -7943,7 +7943,7 @@@ struct scsi_host_template qla2xxx_drive
        .sg_tablesize           = SG_ALL,
  
        .max_sectors            = 0xFFFF,
-       .shost_attrs            = qla2x00_host_attrs,
+       .shost_groups           = qla2x00_host_groups,
  
        .supported_mode         = MODE_INITIATOR,
        .track_queue_depth      = 1,
@@@ -8131,9 -8131,6 +8131,6 @@@ qla2x00_module_init(void
        if (ql2xextended_error_logging == 1)
                ql2xextended_error_logging = QL_DBG_DEFAULT1_MASK;
  
-       if (ql2x_ini_mode == QLA2XXX_INI_MODE_DUAL)
-               qla_insert_tgt_attrs();
        qla2xxx_transport_template =
            fc_attach_transport(&qla2xxx_transport_functions);
        if (!qla2xxx_transport_template) {
diff --combined drivers/scsi/scsi.c
@@@ -86,14 -86,6 +86,6 @@@ unsigned int scsi_logging_level
  EXPORT_SYMBOL(scsi_logging_level);
  #endif
  
- /*
-  * Domain for asynchronous system resume operations.  It is marked 'exclusive'
-  * to avoid being included in the async_synchronize_full() that is invoked by
-  * dpm_resume().
-  */
- ASYNC_DOMAIN_EXCLUSIVE(scsi_sd_pm_domain);
- EXPORT_SYMBOL(scsi_sd_pm_domain);
  #ifdef CONFIG_SCSI_LOGGING
  void scsi_log_send(struct scsi_cmnd *cmd)
  {
@@@ -553,10 -545,8 +545,10 @@@ EXPORT_SYMBOL(scsi_device_get)
   */
  void scsi_device_put(struct scsi_device *sdev)
  {
 -      module_put(sdev->host->hostt->module);
 +      struct module *mod = sdev->host->hostt->module;
 +
        put_device(&sdev->sdev_gendev);
 +      module_put(mod);
  }
  EXPORT_SYMBOL(scsi_device_put);
  
@@@ -1856,7 -1856,7 +1856,7 @@@ static int resp_readcap16(struct scsi_c
  {
        unsigned char *cmd = scp->cmnd;
        unsigned char arr[SDEBUG_READCAP16_ARR_SZ];
-       int alloc_len;
+       u32 alloc_len;
  
        alloc_len = get_unaligned_be32(cmd + 10);
        /* following just in case virtual_gb changed */
        }
  
        return fill_from_dev_buffer(scp, arr,
-                           min_t(int, alloc_len, SDEBUG_READCAP16_ARR_SZ));
+                           min_t(u32, alloc_len, SDEBUG_READCAP16_ARR_SZ));
  }
  
  #define SDEBUG_MAX_TGTPGS_ARR_SZ 1412
@@@ -1896,8 -1896,9 +1896,9 @@@ static int resp_report_tgtpgs(struct sc
        unsigned char *cmd = scp->cmnd;
        unsigned char *arr;
        int host_no = devip->sdbg_host->shost->host_no;
-       int n, ret, alen, rlen;
        int port_group_a, port_group_b, port_a, port_b;
+       u32 alen, n, rlen;
+       int ret;
  
        alen = get_unaligned_be32(cmd + 6);
        arr = kzalloc(SDEBUG_MAX_TGTPGS_ARR_SZ, GFP_ATOMIC);
         * - The constructed command length
         * - The maximum array size
         */
-       rlen = min_t(int, alen, n);
+       rlen = min(alen, n);
        ret = fill_from_dev_buffer(scp, arr,
-                          min_t(int, rlen, SDEBUG_MAX_TGTPGS_ARR_SZ));
+                          min_t(u32, rlen, SDEBUG_MAX_TGTPGS_ARR_SZ));
        kfree(arr);
        return ret;
  }
@@@ -4809,7 -4810,7 +4810,7 @@@ static void sdebug_q_cmd_complete(struc
                        pr_info("bypassing scsi_done() due to aborted cmd\n");
                return;
        }
-       scp->scsi_done(scp); /* callback to mid level */
+       scsi_done(scp); /* callback to mid level */
  }
  
  /* When high resolution timer goes off this function is called. */
@@@ -5384,7 -5385,7 +5385,7 @@@ static int schedule_resp(struct scsi_cm
  {
        bool new_sd_dp;
        bool inject = false;
 -      bool hipri = scsi_cmd_to_rq(cmnd)->cmd_flags & REQ_HIPRI;
 +      bool polled = scsi_cmd_to_rq(cmnd)->cmd_flags & REQ_POLLED;
        int k, num_in_q, qdepth;
        unsigned long iflags;
        u64 ns_from_boot = 0;
        if (sdebug_host_max_queue)
                sd_dp->hc_idx = get_tag(cmnd);
  
 -      if (hipri)
 +      if (polled)
                ns_from_boot = ktime_get_boottime_ns();
  
        /* one of the resp_*() response functions is called here */
                                        if (new_sd_dp)
                                                kfree(sd_dp);
                                        /* call scsi_done() from this thread */
-                                       cmnd->scsi_done(cmnd);
+                                       scsi_done(cmnd);
                                        return 0;
                                }
                                /* otherwise reduce kt by elapsed time */
                                kt -= d;
                        }
                }
 -              if (hipri) {
 +              if (polled) {
                        sd_dp->cmpl_ts = ktime_add(ns_to_ktime(ns_from_boot), kt);
                        spin_lock_irqsave(&sqp->qc_lock, iflags);
                        if (!sd_dp->init_poll) {
                if (unlikely((sdebug_opts & SDEBUG_OPT_CMD_ABORT) &&
                             atomic_read(&sdeb_inject_pending)))
                        sd_dp->aborted = true;
 -              if (hipri) {
 +              if (polled) {
                        sd_dp->cmpl_ts = ns_to_ktime(ns_from_boot);
                        spin_lock_irqsave(&sqp->qc_lock, iflags);
                        if (!sd_dp->init_poll) {
@@@ -5604,7 -5605,7 +5605,7 @@@ respond_in_thread:      /* call back to mid-
        cmnd->result &= ~SDEG_RES_IMMED_MASK;
        if (cmnd->result == 0 && scsi_result != 0)
                cmnd->result = scsi_result;
-       cmnd->scsi_done(cmnd);
+       scsi_done(cmnd);
        return 0;
  }
  
@@@ -7331,7 -7332,7 +7332,7 @@@ static int sdebug_blk_mq_poll(struct Sc
                        if (kt_from_boot < sd_dp->cmpl_ts)
                                continue;
  
 -              } else          /* ignoring non REQ_HIPRI requests */
 +              } else          /* ignoring non REQ_POLLED requests */
                        continue;
                devip = (struct sdebug_dev_info *)scp->device->hostdata;
                if (likely(devip))
                }
                sd_dp->defer_t = SDEB_DEFER_NONE;
                spin_unlock_irqrestore(&sqp->qc_lock, iflags);
-               scp->scsi_done(scp); /* callback to mid level */
+               scsi_done(scp); /* callback to mid level */
                spin_lock_irqsave(&sqp->qc_lock, iflags);
                num_entries++;
        }
@@@ -50,8 -50,6 +50,6 @@@
  
  #include <asm/unaligned.h>
  
- static void scsi_eh_done(struct scsi_cmnd *scmd);
  /*
   * These should *probably* be handled by the host itself.
   * Since it is allowed to sleep, it probably should.
@@@ -520,7 -518,8 +518,8 @@@ enum scsi_disposition scsi_check_sense(
                /* handler does not care. Drop down to default handling */
        }
  
-       if (scmd->cmnd[0] == TEST_UNIT_READY && scmd->scsi_done != scsi_eh_done)
+       if (scmd->cmnd[0] == TEST_UNIT_READY &&
+           scmd->submitter != SUBMITTED_BY_SCSI_ERROR_HANDLER)
                /*
                 * nasty: for mid-layer issued TURs, we need to return the
                 * actual sense data without any recovery attempt.  For eh
@@@ -782,7 -781,7 +781,7 @@@ static enum scsi_disposition scsi_eh_co
   * scsi_eh_done - Completion function for error handling.
   * @scmd:     Cmd that is done.
   */
static void scsi_eh_done(struct scsi_cmnd *scmd)
+ void scsi_eh_done(struct scsi_cmnd *scmd)
  {
        struct completion *eh_action;
  
@@@ -1082,7 -1081,7 +1081,7 @@@ retry
        shost->eh_action = &done;
  
        scsi_log_send(scmd);
-       scmd->scsi_done = scsi_eh_done;
+       scmd->submitter = SUBMITTED_BY_SCSI_ERROR_HANDLER;
  
        /*
         * Lock sdev->state_mutex to avoid that scsi_device_quiesce() can
        if (rtn) {
                if (timeleft > stall_for) {
                        scsi_eh_restore_cmnd(scmd, &ses);
                        timeleft -= stall_for;
                        msleep(jiffies_to_msecs(stall_for));
                        goto retry;
@@@ -1979,7 -1979,7 +1979,7 @@@ maybe_retry
  
  static void eh_lock_door_done(struct request *req, blk_status_t status)
  {
 -      blk_put_request(req);
 +      blk_mq_free_request(req);
  }
  
  /**
@@@ -1998,7 -1998,7 +1998,7 @@@ static void scsi_eh_lock_door(struct sc
        struct request *req;
        struct scsi_request *rq;
  
 -      req = blk_get_request(sdev->request_queue, REQ_OP_DRV_IN, 0);
 +      req = scsi_alloc_request(sdev->request_queue, REQ_OP_DRV_IN, 0);
        if (IS_ERR(req))
                return;
        rq = scsi_req(req);
@@@ -2338,11 -2338,6 +2338,6 @@@ void scsi_report_device_reset(struct Sc
  }
  EXPORT_SYMBOL(scsi_report_device_reset);
  
- static void
- scsi_reset_provider_done_command(struct scsi_cmnd *scmd)
- {
- }
  /**
   * scsi_ioctl_reset: explicitly reset a host/bus/target/device
   * @dev:      scsi_device to operate on
@@@ -2379,7 -2374,7 +2374,7 @@@ scsi_ioctl_reset(struct scsi_device *de
        scsi_init_command(dev, scmd);
        scmd->cmnd = scsi_req(rq)->cmd;
  
-       scmd->scsi_done         = scsi_reset_provider_done_command;
+       scmd->submitter = SUBMITTED_BY_SCSI_RESET_IOCTL;
        memset(&scmd->sdb, 0, sizeof(scmd->sdb));
  
        scmd->cmd_len                   = 0;
diff --combined drivers/scsi/scsi_lib.c
@@@ -21,7 -21,6 +21,7 @@@
  #include <linux/hardirq.h>
  #include <linux/scatterlist.h>
  #include <linux/blk-mq.h>
 +#include <linux/blk-integrity.h>
  #include <linux/ratelimit.h>
  #include <asm/unaligned.h>
  
@@@ -216,7 -215,7 +216,7 @@@ int __scsi_execute(struct scsi_device *
        struct scsi_request *rq;
        int ret;
  
 -      req = blk_get_request(sdev->request_queue,
 +      req = scsi_alloc_request(sdev->request_queue,
                        data_direction == DMA_TO_DEVICE ?
                        REQ_OP_DRV_OUT : REQ_OP_DRV_IN,
                        rq_flags & RQF_PM ? BLK_MQ_REQ_PM : 0);
                scsi_normalize_sense(rq->sense, rq->sense_len, sshdr);
        ret = rq->result;
   out:
 -      blk_put_request(req);
 +      blk_mq_free_request(req);
  
        return ret;
  }
@@@ -950,7 -949,7 +950,7 @@@ void scsi_io_completion(struct scsi_cmn
  
        /*
         * If there had been no error, but we have leftover bytes in the
-        * requeues just queue the command up again.
+        * request just queue the command up again.
         */
        if (likely(result == 0))
                scsi_io_completion_reprep(cmd, q);
@@@ -1079,6 -1078,9 +1079,6 @@@ EXPORT_SYMBOL(scsi_alloc_sgtables)
   * This function initializes the members of struct scsi_cmnd that must be
   * initialized before request processing starts and that won't be
   * reinitialized if a SCSI command is requeued.
 - *
 - * Called from inside blk_get_request() for pass-through requests and from
 - * inside scsi_init_command() for filesystem requests.
   */
  static void scsi_initialize_rq(struct request *rq)
  {
        cmd->retries = 0;
  }
  
 +struct request *scsi_alloc_request(struct request_queue *q,
 +              unsigned int op, blk_mq_req_flags_t flags)
 +{
 +      struct request *rq;
 +
 +      rq = blk_mq_alloc_request(q, op, flags);
 +      if (!IS_ERR(rq))
 +              scsi_initialize_rq(rq);
 +      return rq;
 +}
 +EXPORT_SYMBOL_GPL(scsi_alloc_request);
 +
  /*
   * Only called when the request isn't completed by SCSI, and not freed by
   * SCSI
@@@ -1530,7 -1520,7 +1530,7 @@@ static int scsi_dispatch_cmd(struct scs
  
        return rtn;
   done:
-       cmd->scsi_done(cmd);
+       scsi_done(cmd);
        return 0;
  }
  
@@@ -1585,8 -1575,17 +1585,17 @@@ static blk_status_t scsi_prepare_cmd(st
        return scsi_cmd_to_driver(cmd)->init_command(cmd);
  }
  
static void scsi_mq_done(struct scsi_cmnd *cmd)
void scsi_done(struct scsi_cmnd *cmd)
  {
+       switch (cmd->submitter) {
+       case SUBMITTED_BY_BLOCK_LAYER:
+               break;
+       case SUBMITTED_BY_SCSI_ERROR_HANDLER:
+               return scsi_eh_done(cmd);
+       case SUBMITTED_BY_SCSI_RESET_IOCTL:
+               return;
+       }
        if (unlikely(blk_should_fake_timeout(scsi_cmd_to_rq(cmd)->q)))
                return;
        if (unlikely(test_and_set_bit(SCMD_STATE_COMPLETE, &cmd->state)))
        trace_scsi_dispatch_cmd_done(cmd);
        blk_mq_complete_request(scsi_cmd_to_rq(cmd));
  }
+ EXPORT_SYMBOL(scsi_done);
  
  static void scsi_mq_put_budget(struct request_queue *q, int budget_token)
  {
@@@ -1693,7 -1693,7 +1703,7 @@@ static blk_status_t scsi_queue_rq(struc
  
        scsi_set_resid(cmd, 0);
        memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
-       cmd->scsi_done = scsi_mq_done;
+       cmd->submitter = SUBMITTED_BY_BLOCK_LAYER;
  
        blk_mq_start_request(req);
        reason = scsi_dispatch_cmd(cmd);
@@@ -1793,7 -1793,7 +1803,7 @@@ static void scsi_mq_exit_request(struc
  }
  
  
 -static int scsi_mq_poll(struct blk_mq_hw_ctx *hctx)
 +static int scsi_mq_poll(struct blk_mq_hw_ctx *hctx, struct io_comp_batch *iob)
  {
        struct Scsi_Host *shost = hctx->driver_data;
  
@@@ -1873,6 -1873,7 +1883,6 @@@ static const struct blk_mq_ops scsi_mq_
  #endif
        .init_request   = scsi_mq_init_request,
        .exit_request   = scsi_mq_exit_request,
 -      .initialize_rq_fn = scsi_initialize_rq,
        .cleanup_rq     = scsi_cleanup_rq,
        .busy           = scsi_mq_lld_busy,
        .map_queues     = scsi_map_queues,
@@@ -1902,6 -1903,7 +1912,6 @@@ static const struct blk_mq_ops scsi_mq_
  #endif
        .init_request   = scsi_mq_init_request,
        .exit_request   = scsi_mq_exit_request,
 -      .initialize_rq_fn = scsi_initialize_rq,
        .cleanup_rq     = scsi_cleanup_rq,
        .busy           = scsi_mq_lld_busy,
        .map_queues     = scsi_map_queues,
@@@ -1967,14 -1969,6 +1977,14 @@@ struct scsi_device *scsi_device_from_qu
  
        return sdev;
  }
 +/*
 + * pktcdvd should have been integrated into the SCSI layers, but for historical
 + * reasons like the old IDE driver it isn't.  This export allows it to safely
 + * probe if a given device is a SCSI one and only attach to that.
 + */
 +#ifdef CONFIG_CDROM_PKTCDVD_MODULE
 +EXPORT_SYMBOL_GPL(scsi_device_from_queue);
 +#endif
  
  /**
   * scsi_block_requests - Utility function used by low-level drivers to prevent
@@@ -2042,8 -2036,15 +2052,15 @@@ scsi_mode_select(struct scsi_device *sd
        memset(cmd, 0, sizeof(cmd));
        cmd[1] = (pf ? 0x10 : 0) | (sp ? 0x01 : 0);
  
-       if (sdev->use_10_for_ms) {
-               if (len > 65535)
+       /*
+        * Use MODE SELECT(10) if the device asked for it or if the mode page
+        * and the mode select header cannot fit within the maximumm 255 bytes
+        * of the MODE SELECT(6) command.
+        */
+       if (sdev->use_10_for_ms ||
+           len + 4 > 255 ||
+           data->block_descriptor_length > 255) {
+               if (len > 65535 - 8)
                        return -EINVAL;
                real_buffer = kmalloc(8 + len, GFP_KERNEL);
                if (!real_buffer)
                real_buffer[3] = data->device_specific;
                real_buffer[4] = data->longlba ? 0x01 : 0;
                real_buffer[5] = 0;
-               real_buffer[6] = data->block_descriptor_length >> 8;
-               real_buffer[7] = data->block_descriptor_length;
+               put_unaligned_be16(data->block_descriptor_length,
+                                  &real_buffer[6]);
  
                cmd[0] = MODE_SELECT_10;
-               cmd[7] = len >> 8;
-               cmd[8] = len;
+               put_unaligned_be16(len, &cmd[7]);
        } else {
-               if (len > 255 || data->block_descriptor_length > 255 ||
-                   data->longlba)
+               if (data->longlba)
                        return -EINVAL;
  
                real_buffer = kmalloc(4 + len, GFP_KERNEL);
@@@ -2091,7 -2090,7 +2106,7 @@@ EXPORT_SYMBOL_GPL(scsi_mode_select)
  /**
   *    scsi_mode_sense - issue a mode sense, falling back from 10 to six bytes if necessary.
   *    @sdev:  SCSI device to be queried
-  *    @dbd:   set if mode sense will allow block descriptors to be returned
+  *    @dbd:   set to prevent mode sense from returning block descriptors
   *    @modepage: mode page being requested
   *    @buffer: request buffer (may not be smaller than eight bytes)
   *    @len:   length of request buffer.
@@@ -2126,18 -2125,18 +2141,18 @@@ scsi_mode_sense(struct scsi_device *sde
                sshdr = &my_sshdr;
  
   retry:
-       use_10_for_ms = sdev->use_10_for_ms;
+       use_10_for_ms = sdev->use_10_for_ms || len > 255;
  
        if (use_10_for_ms) {
-               if (len < 8)
-                       len = 8;
+               if (len < 8 || len > 65535)
+                       return -EINVAL;
  
                cmd[0] = MODE_SENSE_10;
-               cmd[8] = len;
+               put_unaligned_be16(len, &cmd[7]);
                header_length = 8;
        } else {
                if (len < 4)
-                       len = 4;
+                       return -EINVAL;
  
                cmd[0] = MODE_SENSE;
                cmd[4] = len;
                        if ((sshdr->sense_key == ILLEGAL_REQUEST) &&
                            (sshdr->asc == 0x20) && (sshdr->ascq == 0)) {
                                /*
-                                * Invalid command operation code
+                                * Invalid command operation code: retry using
+                                * MODE SENSE(6) if this was a MODE SENSE(10)
+                                * request, except if the request mode page is
+                                * too large for MODE SENSE single byte
+                                * allocation length field.
                                 */
                                if (use_10_for_ms) {
+                                       if (len > 255)
+                                               return -EIO;
                                        sdev->use_10_for_ms = 0;
                                        goto retry;
                                }
                data->longlba = 0;
                data->block_descriptor_length = 0;
        } else if (use_10_for_ms) {
-               data->length = buffer[0]*256 + buffer[1] + 2;
+               data->length = get_unaligned_be16(&buffer[0]) + 2;
                data->medium_type = buffer[2];
                data->device_specific = buffer[3];
                data->longlba = buffer[4] & 0x01;
-               data->block_descriptor_length = buffer[6]*256
-                       + buffer[7];
+               data->block_descriptor_length = get_unaligned_be16(&buffer[6]);
        } else {
                data->length = buffer[0] + 1;
                data->medium_type = buffer[1];
diff --combined drivers/scsi/scsi_scan.c
@@@ -122,6 -122,22 +122,22 @@@ struct async_scan_data 
        struct completion prev_finished;
  };
  
+ /**
+  * scsi_enable_async_suspend - Enable async suspend and resume
+  */
+ void scsi_enable_async_suspend(struct device *dev)
+ {
+       /*
+        * If a user has disabled async probing a likely reason is due to a
+        * storage enclosure that does not inject staggered spin-ups. For
+        * safety, make resume synchronous as well in that case.
+        */
+       if (strncmp(scsi_scan_type, "async", 5) != 0)
+               return;
+       /* Enable asynchronous suspend and resume. */
+       device_enable_async_suspend(dev);
+ }
  /**
   * scsi_complete_async_scans - Wait for asynchronous scans to complete
   *
@@@ -280,6 -296,7 +296,6 @@@ static struct scsi_device *scsi_alloc_s
        sdev->request_queue = q;
        q->queuedata = sdev;
        __scsi_init_queue(sdev->host, q);
 -      blk_queue_flag_set(QUEUE_FLAG_SCSI_PASSTHROUGH, q);
        WARN_ON_ONCE(!blk_get_queue(q));
  
        depth = sdev->host->cmd_per_lun ?: 1;
@@@ -453,6 -470,7 +469,7 @@@ static struct scsi_target *scsi_alloc_t
        dev_set_name(dev, "target%d:%d:%d", shost->host_no, channel, id);
        dev->bus = &scsi_bus_type;
        dev->type = &scsi_target_type;
+       scsi_enable_async_suspend(dev);
        starget->id = id;
        starget->channel = channel;
        starget->can_queue = 0;
@@@ -1901,60 -1919,3 +1918,3 @@@ void scsi_forget_host(struct Scsi_Host 
        spin_unlock_irqrestore(shost->host_lock, flags);
  }
  
- /**
-  * scsi_get_host_dev - Create a scsi_device that points to the host adapter itself
-  * @shost: Host that needs a scsi_device
-  *
-  * Lock status: None assumed.
-  *
-  * Returns:     The scsi_device or NULL
-  *
-  * Notes:
-  *    Attach a single scsi_device to the Scsi_Host - this should
-  *    be made to look like a "pseudo-device" that points to the
-  *    HA itself.
-  *
-  *    Note - this device is not accessible from any high-level
-  *    drivers (including generics), which is probably not
-  *    optimal.  We can add hooks later to attach.
-  */
- struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
- {
-       struct scsi_device *sdev = NULL;
-       struct scsi_target *starget;
-       mutex_lock(&shost->scan_mutex);
-       if (!scsi_host_scan_allowed(shost))
-               goto out;
-       starget = scsi_alloc_target(&shost->shost_gendev, 0, shost->this_id);
-       if (!starget)
-               goto out;
-       sdev = scsi_alloc_sdev(starget, 0, NULL);
-       if (sdev)
-               sdev->borken = 0;
-       else
-               scsi_target_reap(starget);
-       put_device(&starget->dev);
-  out:
-       mutex_unlock(&shost->scan_mutex);
-       return sdev;
- }
- EXPORT_SYMBOL(scsi_get_host_dev);
- /**
-  * scsi_free_host_dev - Free a scsi_device that points to the host adapter itself
-  * @sdev: Host device to be freed
-  *
-  * Lock status: None assumed.
-  *
-  * Returns:     Nothing
-  */
- void scsi_free_host_dev(struct scsi_device *sdev)
- {
-       BUG_ON(sdev->id != sdev->host->this_id);
-       __scsi_remove_device(sdev);
- }
- EXPORT_SYMBOL(scsi_free_host_dev);
@@@ -424,15 -424,10 +424,10 @@@ static struct attribute *scsi_sysfs_sho
        NULL
  };
  
static struct attribute_group scsi_shost_attr_group = {
const struct attribute_group scsi_shost_attr_group = {
        .attrs =        scsi_sysfs_shost_attrs,
  };
  
- const struct attribute_group *scsi_sysfs_shost_attr_groups[] = {
-       &scsi_shost_attr_group,
-       NULL
- };
  static void scsi_device_cls_release(struct device *class_dev)
  {
        struct scsi_device *sdev;
@@@ -449,12 -444,9 +444,12 @@@ static void scsi_device_dev_release_use
        struct scsi_vpd *vpd_pg80 = NULL, *vpd_pg83 = NULL;
        struct scsi_vpd *vpd_pg0 = NULL, *vpd_pg89 = NULL;
        unsigned long flags;
 +      struct module *mod;
  
        sdev = container_of(work, struct scsi_device, ew.work);
  
 +      mod = sdev->host->hostt->module;
 +
        scsi_dh_release_device(sdev);
  
        parent = sdev->sdev_gendev.parent;
  
        if (parent)
                put_device(parent);
 +      module_put(mod);
  }
  
  static void scsi_device_dev_release(struct device *dev)
  {
        struct scsi_device *sdp = to_scsi_device(dev);
 +
 +      /* Set module pointer as NULL in case of module unloading */
 +      if (!try_module_get(sdp->host->hostt->module))
 +              sdp->host->hostt->module = NULL;
 +
        execute_in_process_context(scsi_device_dev_release_usercontext,
                                   &sdp->ew);
  }
@@@ -1342,7 -1328,7 +1337,7 @@@ static int scsi_target_add(struct scsi_
   **/
  int scsi_sysfs_add_sdev(struct scsi_device *sdev)
  {
-       int error, i;
+       int error;
        struct scsi_target *starget = sdev->sdev_target;
  
        error = scsi_target_add(starget);
                }
        }
  
-       /* add additional host specific attributes */
-       if (sdev->host->hostt->sdev_attrs) {
-               for (i = 0; sdev->host->hostt->sdev_attrs[i]; i++) {
-                       error = device_create_file(&sdev->sdev_gendev,
-                                       sdev->host->hostt->sdev_attrs[i]);
-                       if (error)
-                               return error;
-               }
-       }
-       if (sdev->host->hostt->sdev_groups) {
-               error = sysfs_create_groups(&sdev->sdev_gendev.kobj,
-                               sdev->host->hostt->sdev_groups);
-               if (error)
-                       return error;
-       }
        scsi_autopm_put_device(sdev);
        return error;
  }
@@@ -1451,10 -1420,6 +1429,6 @@@ void __scsi_remove_device(struct scsi_d
                if (res != 0)
                        return;
  
-               if (sdev->host->hostt->sdev_groups)
-                       sysfs_remove_groups(&sdev->sdev_gendev.kobj,
-                                       sdev->host->hostt->sdev_groups);
                if (IS_ENABLED(CONFIG_BLK_DEV_BSG) && sdev->bsg_dev)
                        bsg_unregister_queue(sdev->bsg_dev);
                device_unregister(&sdev->sdev_dev);
@@@ -1593,18 -1558,6 +1567,6 @@@ EXPORT_SYMBOL(scsi_register_interface)
   **/
  int scsi_sysfs_add_host(struct Scsi_Host *shost)
  {
-       int error, i;
-       /* add host specific attributes */
-       if (shost->hostt->shost_attrs) {
-               for (i = 0; shost->hostt->shost_attrs[i]; i++) {
-                       error = device_create_file(&shost->shost_dev,
-                                       shost->hostt->shost_attrs[i]);
-                       if (error)
-                               return error;
-               }
-       }
        transport_register_device(&shost->shost_gendev);
        transport_configure_device(&shost->shost_gendev);
        return 0;
@@@ -1618,15 -1571,27 +1580,27 @@@ static struct device_type scsi_dev_typ
  
  void scsi_sysfs_device_initialize(struct scsi_device *sdev)
  {
+       int i, j = 0;
        unsigned long flags;
        struct Scsi_Host *shost = sdev->host;
+       struct scsi_host_template *hostt = shost->hostt;
        struct scsi_target  *starget = sdev->sdev_target;
  
        device_initialize(&sdev->sdev_gendev);
        sdev->sdev_gendev.bus = &scsi_bus_type;
        sdev->sdev_gendev.type = &scsi_dev_type;
+       scsi_enable_async_suspend(&sdev->sdev_gendev);
        dev_set_name(&sdev->sdev_gendev, "%d:%d:%d:%llu",
                     sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
+       sdev->gendev_attr_groups[j++] = &scsi_sdev_attr_group;
+       if (hostt->sdev_groups) {
+               for (i = 0; hostt->sdev_groups[i] &&
+                            j < ARRAY_SIZE(sdev->gendev_attr_groups);
+                    i++, j++) {
+                       sdev->gendev_attr_groups[j] = hostt->sdev_groups[i];
+               }
+       }
+       WARN_ON_ONCE(j >= ARRAY_SIZE(sdev->gendev_attr_groups));
  
        device_initialize(&sdev->sdev_dev);
        sdev->sdev_dev.parent = get_device(&sdev->sdev_gendev);
diff --combined drivers/scsi/sd.c
@@@ -48,7 -48,6 +48,7 @@@
  #include <linux/blkpg.h>
  #include <linux/blk-pm.h>
  #include <linux/delay.h>
 +#include <linux/major.h>
  #include <linux/mutex.h>
  #include <linux/string_helpers.h>
  #include <linux/async.h>
@@@ -110,7 -109,7 +110,7 @@@ static int  sd_remove(struct device *)
  static void sd_shutdown(struct device *);
  static int sd_suspend_system(struct device *);
  static int sd_suspend_runtime(struct device *);
- static int sd_resume(struct device *);
+ static int sd_resume_system(struct device *);
  static int sd_resume_runtime(struct device *);
  static void sd_rescan(struct device *);
  static blk_status_t sd_init_command(struct scsi_cmnd *SCpnt);
@@@ -603,9 -602,9 +603,9 @@@ static struct class sd_disk_class = 
  
  static const struct dev_pm_ops sd_pm_ops = {
        .suspend                = sd_suspend_system,
-       .resume                 = sd_resume,
+       .resume                 = sd_resume_system,
        .poweroff               = sd_suspend_system,
-       .restore                = sd_resume,
+       .restore                = sd_resume_system,
        .runtime_suspend        = sd_suspend_runtime,
        .runtime_resume         = sd_resume_runtime,
  };
@@@ -1757,44 -1756,6 +1757,44 @@@ static void sd_rescan(struct device *de
        sd_revalidate_disk(sdkp->disk);
  }
  
 +static int sd_get_unique_id(struct gendisk *disk, u8 id[16],
 +              enum blk_unique_id type)
 +{
 +      struct scsi_device *sdev = scsi_disk(disk)->device;
 +      const struct scsi_vpd *vpd;
 +      const unsigned char *d;
 +      int ret = -ENXIO, len;
 +
 +      rcu_read_lock();
 +      vpd = rcu_dereference(sdev->vpd_pg83);
 +      if (!vpd)
 +              goto out_unlock;
 +
 +      ret = -EINVAL;
 +      for (d = vpd->data + 4; d < vpd->data + vpd->len; d += d[3] + 4) {
 +              /* we only care about designators with LU association */
 +              if (((d[1] >> 4) & 0x3) != 0x00)
 +                      continue;
 +              if ((d[1] & 0xf) != type)
 +                      continue;
 +
 +              /*
 +               * Only exit early if a 16-byte descriptor was found.  Otherwise
 +               * keep looking as one with more entropy might still show up.
 +               */
 +              len = d[3];
 +              if (len != 8 && len != 12 && len != 16)
 +                      continue;
 +              ret = len;
 +              memcpy(id, d + 4, len);
 +              if (len == 16)
 +                      break;
 +      }
 +out_unlock:
 +      rcu_read_unlock();
 +      return ret;
 +}
 +
  static char sd_pr_type(enum pr_type type)
  {
        switch (type) {
@@@ -1899,7 -1860,6 +1899,7 @@@ static const struct block_device_operat
        .check_events           = sd_check_events,
        .unlock_native_capacity = sd_unlock_native_capacity,
        .report_zones           = sd_zbc_report_zones,
 +      .get_unique_id          = sd_get_unique_id,
        .pr_ops                 = &sd_pr_ops,
  };
  
@@@ -2647,6 -2607,13 +2647,13 @@@ sd_do_mode_sense(struct scsi_disk *sdkp
                 unsigned char *buffer, int len, struct scsi_mode_data *data,
                 struct scsi_sense_hdr *sshdr)
  {
+       /*
+        * If we must use MODE SENSE(10), make sure that the buffer length
+        * is at least 8 bytes so that the mode sense header fits.
+        */
+       if (sdkp->device->use_10_for_ms && len < 8)
+               len = 8;
        return scsi_mode_sense(sdkp->device, dbd, modepage, buffer, len,
                               SD_TIMEOUT, sdkp->max_retries, data,
                               sshdr);
@@@ -2825,7 -2792,8 +2832,8 @@@ sd_read_cache_type(struct scsi_disk *sd
                        }
                }
  
-               sd_first_printk(KERN_ERR, sdkp, "No Caching mode page found\n");
+               sd_first_printk(KERN_WARNING, sdkp,
+                               "No Caching mode page found\n");
                goto defaults;
  
        Page_found:
@@@ -2880,7 -2848,7 +2888,7 @@@ defaults
                                "Assuming drive cache: write back\n");
                sdkp->WCE = 1;
        } else {
-               sd_first_printk(KERN_ERR, sdkp,
+               sd_first_printk(KERN_WARNING, sdkp,
                                "Assuming drive cache: write through\n");
                sdkp->WCE = 0;
        }
@@@ -3127,86 -3095,6 +3135,86 @@@ static void sd_read_security(struct scs
                sdkp->security = 1;
  }
  
 +static inline sector_t sd64_to_sectors(struct scsi_disk *sdkp, u8 *buf)
 +{
 +      return logical_to_sectors(sdkp->device, get_unaligned_be64(buf));
 +}
 +
 +/**
 + * sd_read_cpr - Query concurrent positioning ranges
 + * @sdkp:     disk to query
 + */
 +static void sd_read_cpr(struct scsi_disk *sdkp)
 +{
 +      struct blk_independent_access_ranges *iars = NULL;
 +      unsigned char *buffer = NULL;
 +      unsigned int nr_cpr = 0;
 +      int i, vpd_len, buf_len = SD_BUF_SIZE;
 +      u8 *desc;
 +
 +      /*
 +       * We need to have the capacity set first for the block layer to be
 +       * able to check the ranges.
 +       */
 +      if (sdkp->first_scan)
 +              return;
 +
 +      if (!sdkp->capacity)
 +              goto out;
 +
 +      /*
 +       * Concurrent Positioning Ranges VPD: there can be at most 256 ranges,
 +       * leading to a maximum page size of 64 + 256*32 bytes.
 +       */
 +      buf_len = 64 + 256*32;
 +      buffer = kmalloc(buf_len, GFP_KERNEL);
 +      if (!buffer || scsi_get_vpd_page(sdkp->device, 0xb9, buffer, buf_len))
 +              goto out;
 +
 +      /* We must have at least a 64B header and one 32B range descriptor */
 +      vpd_len = get_unaligned_be16(&buffer[2]) + 3;
 +      if (vpd_len > buf_len || vpd_len < 64 + 32 || (vpd_len & 31)) {
 +              sd_printk(KERN_ERR, sdkp,
 +                        "Invalid Concurrent Positioning Ranges VPD page\n");
 +              goto out;
 +      }
 +
 +      nr_cpr = (vpd_len - 64) / 32;
 +      if (nr_cpr == 1) {
 +              nr_cpr = 0;
 +              goto out;
 +      }
 +
 +      iars = disk_alloc_independent_access_ranges(sdkp->disk, nr_cpr);
 +      if (!iars) {
 +              nr_cpr = 0;
 +              goto out;
 +      }
 +
 +      desc = &buffer[64];
 +      for (i = 0; i < nr_cpr; i++, desc += 32) {
 +              if (desc[0] != i) {
 +                      sd_printk(KERN_ERR, sdkp,
 +                              "Invalid Concurrent Positioning Range number\n");
 +                      nr_cpr = 0;
 +                      break;
 +              }
 +
 +              iars->ia_range[i].sector = sd64_to_sectors(sdkp, desc + 8);
 +              iars->ia_range[i].nr_sectors = sd64_to_sectors(sdkp, desc + 16);
 +      }
 +
 +out:
 +      disk_set_independent_access_ranges(sdkp->disk, iars);
 +      if (nr_cpr && sdkp->nr_actuators != nr_cpr) {
 +              sd_printk(KERN_NOTICE, sdkp,
 +                        "%u concurrent positioning ranges\n", nr_cpr);
 +              sdkp->nr_actuators = nr_cpr;
 +      }
 +
 +      kfree(buffer);
 +}
 +
  /*
   * Determine the device's preferred I/O size for reads and writes
   * unless the reported value is unreasonably small, large, not a
@@@ -3322,7 -3210,6 +3330,7 @@@ static int sd_revalidate_disk(struct ge
                sd_read_app_tag_own(sdkp, buffer);
                sd_read_write_same(sdkp, buffer);
                sd_read_security(sdkp, buffer);
 +              sd_read_cpr(sdkp);
        }
  
        /*
@@@ -3570,7 -3457,13 +3578,13 @@@ static int sd_probe(struct device *dev
                pm_runtime_set_autosuspend_delay(dev,
                        sdp->host->hostt->rpm_autosuspend_delay);
        }
-       device_add_disk(dev, gd, NULL);
+       error = device_add_disk(dev, gd, NULL);
+       if (error) {
+               put_device(&sdkp->dev);
+               goto out;
+       }
        if (sdkp->capacity)
                sd_dif_config_host(sdkp);
  
@@@ -3618,7 -3511,6 +3632,6 @@@ static int sd_remove(struct device *dev
        sdkp = dev_get_drvdata(dev);
        scsi_autopm_get_device(sdkp->device);
  
-       async_synchronize_full_domain(&scsi_sd_pm_domain);
        device_del(&sdkp->dev);
        del_gendisk(sdkp->disk);
        sd_shutdown(dev);
@@@ -3775,6 -3667,9 +3788,9 @@@ static int sd_suspend_common(struct dev
  
  static int sd_suspend_system(struct device *dev)
  {
+       if (pm_runtime_suspended(dev))
+               return 0;
        return sd_suspend_common(dev, true);
  }
  
@@@ -3801,15 -3696,18 +3817,23 @@@ static int sd_resume(struct device *dev
        return ret;
  }
  
+ static int sd_resume_system(struct device *dev)
+ {
+       if (pm_runtime_suspended(dev))
+               return 0;
+       return sd_resume(dev);
+ }
  static int sd_resume_runtime(struct device *dev)
  {
        struct scsi_disk *sdkp = dev_get_drvdata(dev);
 -      struct scsi_device *sdp = sdkp->device;
 +      struct scsi_device *sdp;
 +
 +      if (!sdkp)      /* E.g.: runtime resume at the start of sd_probe() */
 +              return 0;
 +
 +      sdp = sdkp->device;
  
        if (sdp->ignore_media_change) {
                /* clear the device's sense data */
diff --combined drivers/scsi/sr.c
@@@ -44,7 -44,6 +44,7 @@@
  #include <linux/cdrom.h>
  #include <linux/interrupt.h>
  #include <linux/init.h>
 +#include <linux/major.h>
  #include <linux/blkdev.h>
  #include <linux/blk-pm.h>
  #include <linux/mutex.h>
@@@ -728,7 -727,12 +728,12 @@@ static int sr_probe(struct device *dev
        dev_set_drvdata(dev, cd);
        disk->flags |= GENHD_FL_REMOVABLE;
        sr_revalidate_disk(cd);
-       device_add_disk(&sdev->sdev_gendev, disk, NULL);
+       error = device_add_disk(&sdev->sdev_gendev, disk, NULL);
+       if (error) {
+               kref_put(&cd->kref, sr_kref_release);
+               goto fail;
+       }
  
        sdev_printk(KERN_DEBUG, sdev,
                    "Attached scsi CD-ROM %s\n", cd->cdi.name);
@@@ -967,7 -971,7 +972,7 @@@ static int sr_read_cdda_bpc(struct cdro
        struct bio *bio;
        int ret;
  
 -      rq = blk_get_request(disk->queue, REQ_OP_DRV_IN, 0);
 +      rq = scsi_alloc_request(disk->queue, REQ_OP_DRV_IN, 0);
        if (IS_ERR(rq))
                return PTR_ERR(rq);
        req = scsi_req(rq);
        if (blk_rq_unmap_user(bio))
                ret = -EFAULT;
  out_put_request:
 -      blk_put_request(rq);
 +      blk_mq_free_request(rq);
        return ret;
  }
  
@@@ -1154,7 -1154,7 +1154,7 @@@ static void storvsc_command_completion(
        scsi_set_resid(scmnd,
                cmd_request->payload->range.len - data_transfer_length);
  
-       scmnd->scsi_done(scmnd);
+       scsi_done(scmnd);
  
        if (payload_sz >
                sizeof(struct vmbus_channel_packet_multipage_buffer))
@@@ -1285,15 -1285,11 +1285,15 @@@ static void storvsc_on_channel_callback
        foreach_vmbus_pkt(desc, channel) {
                struct vstor_packet *packet = hv_pkt_data(desc);
                struct storvsc_cmd_request *request = NULL;
 +              u32 pktlen = hv_pkt_datalen(desc);
                u64 rqst_id = desc->trans_id;
 +              u32 minlen = rqst_id ? sizeof(struct vstor_packet) -
 +                      stor_device->vmscsi_size_delta : sizeof(enum vstor_packet_operation);
  
 -              if (hv_pkt_datalen(desc) < sizeof(struct vstor_packet) -
 -                              stor_device->vmscsi_size_delta) {
 -                      dev_err(&device->device, "Invalid packet len\n");
 +              if (pktlen < minlen) {
 +                      dev_err(&device->device,
 +                              "Invalid pkt: id=%llu, len=%u, minlen=%u\n",
 +                              rqst_id, pktlen, minlen);
                        continue;
                }
  
                        if (rqst_id == 0) {
                                /*
                                 * storvsc_on_receive() looks at the vstor_packet in the message
 -                               * from the ring buffer.  If the operation in the vstor_packet is
 -                               * COMPLETE_IO, then we call storvsc_on_io_completion(), and
 -                               * dereference the guest memory address.  Make sure we don't call
 -                               * storvsc_on_io_completion() with a guest memory address that is
 -                               * zero if Hyper-V were to construct and send such a bogus packet.
 +                               * from the ring buffer.
 +                               *
 +                               * - If the operation in the vstor_packet is COMPLETE_IO, then
 +                               *   we call storvsc_on_io_completion(), and dereference the
 +                               *   guest memory address.  Make sure we don't call
 +                               *   storvsc_on_io_completion() with a guest memory address
 +                               *   that is zero if Hyper-V were to construct and send such
 +                               *   a bogus packet.
 +                               *
 +                               * - If the operation in the vstor_packet is FCHBA_DATA, then
 +                               *   we call cache_wwn(), and access the data payload area of
 +                               *   the packet (wwn_packet); however, there is no guarantee
 +                               *   that the packet is big enough to contain such area.
 +                               *   Future-proof the code by rejecting such a bogus packet.
                                 */
 -                              if (packet->operation == VSTOR_OPERATION_COMPLETE_IO) {
 +                              if (packet->operation == VSTOR_OPERATION_COMPLETE_IO ||
 +                                  packet->operation == VSTOR_OPERATION_FCHBA_DATA) {
                                        dev_err(&device->device, "Invalid packet with ID of 0\n");
                                        continue;
                                }
@@@ -1767,7 -1753,7 +1767,7 @@@ static int storvsc_queuecommand(struct 
                 * future versions of the host.
                 */
                if (!storvsc_scsi_cmd_ok(scmnd)) {
-                       scmnd->scsi_done(scmnd);
+                       scsi_done(scmnd);
                        return 0;
                }
        }
@@@ -642,9 -642,9 +642,9 @@@ static int exynos_ufs_pre_pwr_mode(stru
        }
  
        /* setting for three timeout values for traffic class #0 */
 -      ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA0), 8064);
 -      ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA1), 28224);
 -      ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA2), 20160);
 +      ufshcd_dme_set(hba, UIC_ARG_MIB(DL_FC0PROTTIMEOUTVAL), 8064);
 +      ufshcd_dme_set(hba, UIC_ARG_MIB(DL_TC0REPLAYTIMEOUTVAL), 28224);
 +      ufshcd_dme_set(hba, UIC_ARG_MIB(DL_AFC0REQTIMEOUTVAL), 20160);
  
        return 0;
  out:
@@@ -1176,10 -1176,14 +1176,14 @@@ static void exynos_ufs_hibern8_notify(s
        }
  }
  
- static int exynos_ufs_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
+ static int exynos_ufs_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op,
+       enum ufs_notify_change_status status)
  {
        struct exynos_ufs *ufs = ufshcd_get_variant(hba);
  
+       if (status == PRE_CHANGE)
+               return 0;
        if (!ufshcd_is_link_active(hba))
                phy_power_off(ufs->phy);
  
@@@ -62,6 -62,9 +62,9 @@@
  /* maximum number of reset retries before giving up */
  #define MAX_HOST_RESET_RETRIES 5
  
+ /* Maximum number of error handler retries before giving up */
+ #define MAX_ERR_HANDLER_RETRIES 5
  /* Expose the flag value from utp_upiu_query.value */
  #define MASK_QUERY_UPIU_FLAG_LOC 0xFF
  
@@@ -222,10 -225,8 +225,8 @@@ static int ufshcd_reset_and_restore(str
  static int ufshcd_eh_host_reset_handler(struct scsi_cmnd *cmd);
  static int ufshcd_clear_tm_cmd(struct ufs_hba *hba, int tag);
  static void ufshcd_hba_exit(struct ufs_hba *hba);
- static int ufshcd_clear_ua_wluns(struct ufs_hba *hba);
- static int ufshcd_probe_hba(struct ufs_hba *hba, bool async);
+ static int ufshcd_probe_hba(struct ufs_hba *hba, bool init_dev_params);
  static int ufshcd_setup_clocks(struct ufs_hba *hba, bool on);
- static int ufshcd_uic_hibern8_enter(struct ufs_hba *hba);
  static inline void ufshcd_add_delay_before_dme_cmd(struct ufs_hba *hba);
  static int ufshcd_host_reset_and_restore(struct ufs_hba *hba);
  static void ufshcd_resume_clkscaling(struct ufs_hba *hba);
@@@ -2685,7 -2686,19 +2686,19 @@@ static int ufshcd_queuecommand(struct S
  
        switch (hba->ufshcd_state) {
        case UFSHCD_STATE_OPERATIONAL:
+               break;
        case UFSHCD_STATE_EH_SCHEDULED_NON_FATAL:
+               /*
+                * SCSI error handler can call ->queuecommand() while UFS error
+                * handler is in progress. Error interrupts could change the
+                * state from UFSHCD_STATE_RESET to
+                * UFSHCD_STATE_EH_SCHEDULED_NON_FATAL. Prevent requests
+                * being issued in that case.
+                */
+               if (ufshcd_eh_in_progress(hba)) {
+                       err = SCSI_MLQUEUE_HOST_BUSY;
+                       goto out;
+               }
                break;
        case UFSHCD_STATE_EH_SCHEDULED_FATAL:
                /*
                if (hba->pm_op_in_progress) {
                        hba->force_reset = true;
                        set_host_byte(cmd, DID_BAD_TARGET);
-                       cmd->scsi_done(cmd);
+                       scsi_done(cmd);
                        goto out;
                }
                fallthrough;
                goto out;
        case UFSHCD_STATE_ERROR:
                set_host_byte(cmd, DID_ERROR);
-               cmd->scsi_done(cmd);
+               scsi_done(cmd);
                goto out;
        }
  
  
        lrbp->req_abort_skip = false;
  
 -      err = ufshpb_prep(hba, lrbp);
 -      if (err == -EAGAIN) {
 -              lrbp->cmd = NULL;
 -              ufshcd_release(hba);
 -              goto out;
 -      }
 +      ufshpb_prep(hba, lrbp);
  
        ufshcd_comp_scsi_upiu(hba, lrbp);
  
@@@ -2920,7 -2938,7 +2933,7 @@@ static int ufshcd_exec_dev_cmd(struct u
         * Even though we use wait_event() which sleeps indefinitely,
         * the maximum wait time is bounded by SCSI request timeout.
         */
 -      req = blk_get_request(q, REQ_OP_DRV_OUT, 0);
 +      req = blk_mq_alloc_request(q, REQ_OP_DRV_OUT, 0);
        if (IS_ERR(req)) {
                err = PTR_ERR(req);
                goto out_unlock;
                                    (struct utp_upiu_req *)lrbp->ucd_rsp_ptr);
  
  out:
 -      blk_put_request(req);
 +      blk_mq_free_request(req);
  out_unlock:
        up_read(&hba->clk_scaling_lock);
        return err;
@@@ -4073,14 -4091,12 +4086,12 @@@ int ufshcd_link_recovery(struct ufs_hb
        if (ret)
                dev_err(hba->dev, "%s: link recovery failed, err %d",
                        __func__, ret);
-       else
-               ufshcd_clear_ua_wluns(hba);
  
        return ret;
  }
  EXPORT_SYMBOL_GPL(ufshcd_link_recovery);
  
static int ufshcd_uic_hibern8_enter(struct ufs_hba *hba)
+ int ufshcd_uic_hibern8_enter(struct ufs_hba *hba)
  {
        int ret;
        struct uic_command uic_cmd = {0};
  
        return ret;
  }
+ EXPORT_SYMBOL_GPL(ufshcd_uic_hibern8_enter);
  
  int ufshcd_uic_hibern8_exit(struct ufs_hba *hba)
  {
@@@ -4981,7 -4998,7 +4993,7 @@@ static int ufshcd_slave_configure(struc
        else if (ufshcd_is_rpm_autosuspend_allowed(hba))
                sdev->rpm_autosuspend = 1;
  
 -      ufshcd_crypto_setup_rq_keyslot_manager(hba, q);
 +      ufshcd_crypto_register(hba, q);
  
        return 0;
  }
@@@ -5258,7 -5275,7 +5270,7 @@@ static void __ufshcd_transfer_req_compl
                        /* Mark completed command as NULL in LRB */
                        lrbp->cmd = NULL;
                        /* Do not touch lrbp after scsi done */
-                       cmd->scsi_done(cmd);
+                       scsi_done(cmd);
                        ufshcd_release(hba);
                        update_scaling = true;
                } else if (lrbp->command_type == UTP_CMD_TYPE_DEV_MANAGE ||
                                __func__, err);
  }
  
+ static void ufshcd_temp_exception_event_handler(struct ufs_hba *hba, u16 status)
+ {
+       u32 value;
+       if (ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_READ_ATTR,
+                               QUERY_ATTR_IDN_CASE_ROUGH_TEMP, 0, 0, &value))
+               return;
+       dev_info(hba->dev, "exception Tcase %d\n", value - 80);
+       ufs_hwmon_notify_event(hba, status & MASK_EE_URGENT_TEMP);
+       /*
+        * A placeholder for the platform vendors to add whatever additional
+        * steps required
+        */
+ }
  static int __ufshcd_wb_toggle(struct ufs_hba *hba, bool set, enum flag_idn idn)
  {
        u8 index;
@@@ -5785,10 -5820,12 +5815,12 @@@ static void ufshcd_exception_event_hand
        if (status & hba->ee_drv_mask & MASK_EE_URGENT_BKOPS)
                ufshcd_bkops_exception_event_handler(hba);
  
+       if (status & hba->ee_drv_mask & MASK_EE_URGENT_TEMP)
+               ufshcd_temp_exception_event_handler(hba, status);
        ufs_debugfs_exception_event(hba, status);
  out:
        ufshcd_scsi_unblock_requests(hba);
-       return;
  }
  
  /* Complete requests that have door-bell cleared */
@@@ -5959,7 -5996,6 +5991,6 @@@ static void ufshcd_err_handling_unprepa
        ufshcd_release(hba);
        if (ufshcd_is_clkscaling_supported(hba))
                ufshcd_clk_scaling_suspend(hba, false);
-       ufshcd_clear_ua_wluns(hba);
        ufshcd_rpm_put(hba);
  }
  
@@@ -6033,13 -6069,15 +6064,15 @@@ static bool ufshcd_is_pwr_mode_restore_
   */
  static void ufshcd_err_handler(struct work_struct *work)
  {
+       int retries = MAX_ERR_HANDLER_RETRIES;
        struct ufs_hba *hba;
        unsigned long flags;
-       bool err_xfer = false;
-       bool err_tm = false;
-       int err = 0, pmc_err;
+       bool needs_restore;
+       bool needs_reset;
+       bool err_xfer;
+       bool err_tm;
+       int pmc_err;
        int tag;
-       bool needs_reset = false, needs_restore = false;
  
        hba = container_of(work, struct ufs_hba, eh_work);
  
        /* Complete requests that have door-bell cleared by h/w */
        ufshcd_complete_requests(hba);
        spin_lock_irqsave(hba->host->host_lock, flags);
+ again:
+       needs_restore = false;
+       needs_reset = false;
+       err_xfer = false;
+       err_tm = false;
        if (hba->ufshcd_state != UFSHCD_STATE_ERROR)
                hba->ufshcd_state = UFSHCD_STATE_RESET;
        /*
@@@ -6178,6 -6222,8 +6217,8 @@@ lock_skip_pending_xfer_clear
  do_reset:
        /* Fatal errors need reset */
        if (needs_reset) {
+               int err;
                hba->force_reset = false;
                spin_unlock_irqrestore(hba->host->host_lock, flags);
                err = ufshcd_reset_and_restore(hba);
@@@ -6197,6 -6243,13 +6238,13 @@@ skip_err_handling
                        dev_err_ratelimited(hba->dev, "%s: exit: saved_err 0x%x saved_uic_err 0x%x",
                            __func__, hba->saved_err, hba->saved_uic_err);
        }
+       /* Exit in an operational state or dead */
+       if (hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL &&
+           hba->ufshcd_state != UFSHCD_STATE_ERROR) {
+               if (--retries)
+                       goto again;
+               hba->ufshcd_state = UFSHCD_STATE_ERROR;
+       }
        ufshcd_clear_eh_in_progress(hba);
        spin_unlock_irqrestore(hba->host->host_lock, flags);
        ufshcd_err_handling_unprepare(hba);
@@@ -6512,9 -6565,9 +6560,9 @@@ static int __ufshcd_issue_tm_cmd(struc
        int task_tag, err;
  
        /*
 -       * blk_get_request() is used here only to get a free tag.
 +       * blk_mq_alloc_request() is used here only to get a free tag.
         */
 -      req = blk_get_request(q, REQ_OP_DRV_OUT, 0);
 +      req = blk_mq_alloc_request(q, REQ_OP_DRV_OUT, 0);
        if (IS_ERR(req))
                return PTR_ERR(req);
  
        spin_unlock_irqrestore(hba->host->host_lock, flags);
  
        ufshcd_release(hba);
 -      blk_put_request(req);
 +      blk_mq_free_request(req);
  
        return err;
  }
@@@ -6655,7 -6708,7 +6703,7 @@@ static int ufshcd_issue_devman_upiu_cmd
  
        down_read(&hba->clk_scaling_lock);
  
 -      req = blk_get_request(q, REQ_OP_DRV_OUT, 0);
 +      req = blk_mq_alloc_request(q, REQ_OP_DRV_OUT, 0);
        if (IS_ERR(req)) {
                err = PTR_ERR(req);
                goto out_unlock;
                                    (struct utp_upiu_req *)lrbp->ucd_rsp_ptr);
  
  out:
 -      blk_put_request(req);
 +      blk_mq_free_request(req);
  out_unlock:
        up_read(&hba->clk_scaling_lock);
        return err;
@@@ -7102,31 -7155,41 +7150,41 @@@ static int ufshcd_host_reset_and_restor
   */
  static int ufshcd_reset_and_restore(struct ufs_hba *hba)
  {
-       u32 saved_err;
-       u32 saved_uic_err;
+       u32 saved_err = 0;
+       u32 saved_uic_err = 0;
        int err = 0;
        unsigned long flags;
        int retries = MAX_HOST_RESET_RETRIES;
  
-       /*
-        * This is a fresh start, cache and clear saved error first,
-        * in case new error generated during reset and restore.
-        */
        spin_lock_irqsave(hba->host->host_lock, flags);
-       saved_err = hba->saved_err;
-       saved_uic_err = hba->saved_uic_err;
-       hba->saved_err = 0;
-       hba->saved_uic_err = 0;
-       spin_unlock_irqrestore(hba->host->host_lock, flags);
        do {
+               /*
+                * This is a fresh start, cache and clear saved error first,
+                * in case new error generated during reset and restore.
+                */
+               saved_err |= hba->saved_err;
+               saved_uic_err |= hba->saved_uic_err;
+               hba->saved_err = 0;
+               hba->saved_uic_err = 0;
+               hba->force_reset = false;
+               hba->ufshcd_state = UFSHCD_STATE_RESET;
+               spin_unlock_irqrestore(hba->host->host_lock, flags);
                /* Reset the attached device */
                ufshcd_device_reset(hba);
  
                err = ufshcd_host_reset_and_restore(hba);
+               spin_lock_irqsave(hba->host->host_lock, flags);
+               if (err)
+                       continue;
+               /* Do not exit unless operational or dead */
+               if (hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL &&
+                   hba->ufshcd_state != UFSHCD_STATE_ERROR &&
+                   hba->ufshcd_state != UFSHCD_STATE_EH_SCHEDULED_NON_FATAL)
+                       err = -EAGAIN;
        } while (err && --retries);
  
-       spin_lock_irqsave(hba->host->host_lock, flags);
        /*
         * Inform scsi mid-layer that we did reset and allow to handle
         * Unit Attention properly.
@@@ -7437,6 -7500,29 +7495,29 @@@ wb_disabled
        hba->caps &= ~UFSHCD_CAP_WB_EN;
  }
  
+ static void ufshcd_temp_notif_probe(struct ufs_hba *hba, u8 *desc_buf)
+ {
+       struct ufs_dev_info *dev_info = &hba->dev_info;
+       u32 ext_ufs_feature;
+       u8 mask = 0;
+       if (!(hba->caps & UFSHCD_CAP_TEMP_NOTIF) || dev_info->wspecversion < 0x300)
+               return;
+       ext_ufs_feature = get_unaligned_be32(desc_buf + DEVICE_DESC_PARAM_EXT_UFS_FEATURE_SUP);
+       if (ext_ufs_feature & UFS_DEV_LOW_TEMP_NOTIF)
+               mask |= MASK_EE_TOO_LOW_TEMP;
+       if (ext_ufs_feature & UFS_DEV_HIGH_TEMP_NOTIF)
+               mask |= MASK_EE_TOO_HIGH_TEMP;
+       if (mask) {
+               ufshcd_enable_ee(hba, mask);
+               ufs_hwmon_probe(hba, mask);
+       }
+ }
  void ufshcd_fixup_dev_quirks(struct ufs_hba *hba, struct ufs_dev_fix *fixups)
  {
        struct ufs_dev_fix *f;
@@@ -7532,6 -7618,8 +7613,8 @@@ static int ufs_get_device_desc(struct u
  
        ufshcd_wb_probe(hba, desc_buf);
  
+       ufshcd_temp_notif_probe(hba, desc_buf);
        /*
         * ufshcd_read_string_desc returns size of the string
         * reset the error value
@@@ -7875,8 -7963,6 +7958,6 @@@ static int ufshcd_add_lus(struct ufs_hb
        if (ret)
                goto out;
  
-       ufshcd_clear_ua_wluns(hba);
        /* Initialize devfreq after UFS device is detected */
        if (ufshcd_is_clkscaling_supported(hba)) {
                memcpy(&hba->clk_scaling.saved_pwr_info.info,
        return ret;
  }
  
- static void ufshcd_request_sense_done(struct request *rq, blk_status_t error)
- {
-       if (error != BLK_STS_OK)
-               pr_err("%s: REQUEST SENSE failed (%d)\n", __func__, error);
-       kfree(rq->end_io_data);
-       blk_mq_free_request(rq);
- }
- static int
- ufshcd_request_sense_async(struct ufs_hba *hba, struct scsi_device *sdev)
- {
-       /*
-        * Some UFS devices clear unit attention condition only if the sense
-        * size used (UFS_SENSE_SIZE in this case) is non-zero.
-        */
-       static const u8 cmd[6] = {REQUEST_SENSE, 0, 0, 0, UFS_SENSE_SIZE, 0};
-       struct scsi_request *rq;
-       struct request *req;
-       char *buffer;
-       int ret;
-       buffer = kzalloc(UFS_SENSE_SIZE, GFP_KERNEL);
-       if (!buffer)
-               return -ENOMEM;
-       req = blk_mq_alloc_request(sdev->request_queue, REQ_OP_DRV_IN,
-                             /*flags=*/BLK_MQ_REQ_PM);
-       if (IS_ERR(req)) {
-               ret = PTR_ERR(req);
-               goto out_free;
-       }
-       ret = blk_rq_map_kern(sdev->request_queue, req,
-                             buffer, UFS_SENSE_SIZE, GFP_NOIO);
-       if (ret)
-               goto out_put;
-       rq = scsi_req(req);
-       rq->cmd_len = ARRAY_SIZE(cmd);
-       memcpy(rq->cmd, cmd, rq->cmd_len);
-       rq->retries = 3;
-       req->timeout = 1 * HZ;
-       req->rq_flags |= RQF_PM | RQF_QUIET;
-       req->end_io_data = buffer;
-       blk_execute_rq_nowait(/*bd_disk=*/NULL, req, /*at_head=*/true,
-                             ufshcd_request_sense_done);
-       return 0;
- out_put:
-       blk_mq_free_request(req);
- out_free:
-       kfree(buffer);
-       return ret;
- }
- static int ufshcd_clear_ua_wlun(struct ufs_hba *hba, u8 wlun)
- {
-       struct scsi_device *sdp;
-       unsigned long flags;
-       int ret = 0;
-       spin_lock_irqsave(hba->host->host_lock, flags);
-       if (wlun == UFS_UPIU_UFS_DEVICE_WLUN)
-               sdp = hba->sdev_ufs_device;
-       else if (wlun == UFS_UPIU_RPMB_WLUN)
-               sdp = hba->sdev_rpmb;
-       else
-               BUG();
-       if (sdp) {
-               ret = scsi_device_get(sdp);
-               if (!ret && !scsi_device_online(sdp)) {
-                       ret = -ENODEV;
-                       scsi_device_put(sdp);
-               }
-       } else {
-               ret = -ENODEV;
-       }
-       spin_unlock_irqrestore(hba->host->host_lock, flags);
-       if (ret)
-               goto out_err;
-       ret = ufshcd_request_sense_async(hba, sdp);
-       scsi_device_put(sdp);
- out_err:
-       if (ret)
-               dev_err(hba->dev, "%s: UAC clear LU=%x ret = %d\n",
-                               __func__, wlun, ret);
-       return ret;
- }
- static int ufshcd_clear_ua_wluns(struct ufs_hba *hba)
- {
-       int ret = 0;
-       if (!hba->wlun_dev_clr_ua)
-               goto out;
-       ret = ufshcd_clear_ua_wlun(hba, UFS_UPIU_UFS_DEVICE_WLUN);
-       if (!ret)
-               ret = ufshcd_clear_ua_wlun(hba, UFS_UPIU_RPMB_WLUN);
-       if (!ret)
-               hba->wlun_dev_clr_ua = false;
- out:
-       if (ret)
-               dev_err(hba->dev, "%s: Failed to clear UAC WLUNS ret = %d\n",
-                               __func__, ret);
-       return ret;
- }
  /**
   * ufshcd_probe_hba - probe hba to detect device and initialize it
   * @hba: per-adapter instance
@@@ -8062,8 -8038,6 +8033,6 @@@ static int ufshcd_probe_hba(struct ufs_
        /* UFS device is also active now */
        ufshcd_set_ufs_dev_active(hba);
        ufshcd_force_reset_auto_bkops(hba);
-       hba->wlun_dev_clr_ua = true;
-       hba->wlun_rpmb_clr_ua = true;
  
        /* Gear up to HS gear if supported */
        if (hba->max_pwr_info.is_valid) {
@@@ -8600,7 -8574,7 +8569,7 @@@ static int ufshcd_set_dev_pwr_mode(stru
        struct scsi_sense_hdr sshdr;
        struct scsi_device *sdp;
        unsigned long flags;
-       int ret;
+       int ret, retries;
  
        spin_lock_irqsave(hba->host->host_lock, flags);
        sdp = hba->sdev_ufs_device;
         * handling context.
         */
        hba->host->eh_noresume = 1;
-       if (hba->wlun_dev_clr_ua)
-               ufshcd_clear_ua_wlun(hba, UFS_UPIU_UFS_DEVICE_WLUN);
  
        cmd[4] = pwr_mode << 4;
  
         * callbacks hence set the RQF_PM flag so that it doesn't resume the
         * already suspended childs.
         */
-       ret = scsi_execute(sdp, cmd, DMA_NONE, NULL, 0, NULL, &sshdr,
-                       START_STOP_TIMEOUT, 0, 0, RQF_PM, NULL);
+       for (retries = 3; retries > 0; --retries) {
+               ret = scsi_execute(sdp, cmd, DMA_NONE, NULL, 0, NULL, &sshdr,
+                               START_STOP_TIMEOUT, 0, 0, RQF_PM, NULL);
+               if (!scsi_status_is_check_condition(ret) ||
+                               !scsi_sense_valid(&sshdr) ||
+                               sshdr.sense_key != UNIT_ATTENTION)
+                       break;
+       }
        if (ret) {
                sdev_printk(KERN_WARNING, sdp,
                            "START_STOP failed for power mode: %d, result %x\n",
@@@ -8878,6 -8856,10 +8851,10 @@@ static int __ufshcd_wl_suspend(struct u
  
        flush_work(&hba->eeh_work);
  
+       ret = ufshcd_vops_suspend(hba, pm_op, PRE_CHANGE);
+       if (ret)
+               goto enable_scaling;
        if (req_dev_pwr_mode != hba->curr_dev_pwr_mode) {
                if (pm_op != UFS_RUNTIME_PM)
                        /* ensure that bkops is disabled */
@@@ -8905,7 -8887,7 +8882,7 @@@ vops_suspend
         * vendor specific host controller register space call them before the
         * host clocks are ON.
         */
-       ret = ufshcd_vops_suspend(hba, pm_op);
+       ret = ufshcd_vops_suspend(hba, pm_op, POST_CHANGE);
        if (ret)
                goto set_link_active;
        goto out;
@@@ -9033,7 -9015,8 +9010,8 @@@ static int __ufshcd_wl_resume(struct uf
  set_old_link_state:
        ufshcd_link_state_transition(hba, old_link_state, 0);
  vendor_suspend:
-       ufshcd_vops_suspend(hba, pm_op);
+       ufshcd_vops_suspend(hba, pm_op, PRE_CHANGE);
+       ufshcd_vops_suspend(hba, pm_op, POST_CHANGE);
  out:
        if (ret)
                ufshcd_update_evt_hist(hba, UFS_EVT_WL_RES_ERR, (u32)ret);
@@@ -9378,6 -9361,7 +9356,7 @@@ void ufshcd_remove(struct ufs_hba *hba
  {
        if (hba->sdev_ufs_device)
                ufshcd_rpm_get_sync(hba);
+       ufs_hwmon_remove(hba);
        ufs_bsg_remove(hba);
        ufshpb_remove(hba);
        ufs_sysfs_remove_nodes(hba->dev);
@@@ -9699,10 -9683,6 +9678,6 @@@ void ufshcd_resume_complete(struct devi
                ufshcd_rpm_put(hba);
                hba->complete_put = false;
        }
-       if (hba->rpmb_complete_put) {
-               ufshcd_rpmb_rpm_put(hba);
-               hba->rpmb_complete_put = false;
-       }
  }
  EXPORT_SYMBOL_GPL(ufshcd_resume_complete);
  
@@@ -9725,10 -9705,6 +9700,6 @@@ int ufshcd_suspend_prepare(struct devic
                }
                hba->complete_put = true;
        }
-       if (hba->sdev_rpmb) {
-               ufshcd_rpmb_rpm_get_sync(hba);
-               hba->rpmb_complete_put = true;
-       }
        return 0;
  }
  EXPORT_SYMBOL_GPL(ufshcd_suspend_prepare);
@@@ -9797,49 -9773,6 +9768,6 @@@ static struct scsi_driver ufs_dev_wlun_
        },
  };
  
- static int ufshcd_rpmb_probe(struct device *dev)
- {
-       return is_rpmb_wlun(to_scsi_device(dev)) ? 0 : -ENODEV;
- }
- static inline int ufshcd_clear_rpmb_uac(struct ufs_hba *hba)
- {
-       int ret = 0;
-       if (!hba->wlun_rpmb_clr_ua)
-               return 0;
-       ret = ufshcd_clear_ua_wlun(hba, UFS_UPIU_RPMB_WLUN);
-       if (!ret)
-               hba->wlun_rpmb_clr_ua = 0;
-       return ret;
- }
- #ifdef CONFIG_PM
- static int ufshcd_rpmb_resume(struct device *dev)
- {
-       struct ufs_hba *hba = wlun_dev_to_hba(dev);
-       if (hba->sdev_rpmb)
-               ufshcd_clear_rpmb_uac(hba);
-       return 0;
- }
- #endif
- static const struct dev_pm_ops ufs_rpmb_pm_ops = {
-       SET_RUNTIME_PM_OPS(NULL, ufshcd_rpmb_resume, NULL)
-       SET_SYSTEM_SLEEP_PM_OPS(NULL, ufshcd_rpmb_resume)
- };
- /* ufs_rpmb_wlun_template - Describes UFS RPMB WLUN. Used only to send UAC. */
- static struct scsi_driver ufs_rpmb_wlun_template = {
-       .gendrv = {
-               .name = "ufs_rpmb_wlun",
-               .owner = THIS_MODULE,
-               .probe = ufshcd_rpmb_probe,
-               .pm = &ufs_rpmb_pm_ops,
-       },
- };
  static int __init ufshcd_core_init(void)
  {
        int ret;
  
        ret = scsi_register_driver(&ufs_dev_wlun_template.gendrv);
        if (ret)
-               goto debugfs_exit;
-       ret = scsi_register_driver(&ufs_rpmb_wlun_template.gendrv);
-       if (ret)
-               goto unregister;
-       return ret;
- unregister:
-       scsi_unregister_driver(&ufs_dev_wlun_template.gendrv);
- debugfs_exit:
-       ufs_debugfs_exit();
+               ufs_debugfs_exit();
        return ret;
  }
  
  static void __exit ufshcd_core_exit(void)
  {
        ufs_debugfs_exit();
-       scsi_unregister_driver(&ufs_rpmb_wlun_template.gendrv);
        scsi_unregister_driver(&ufs_dev_wlun_template.gendrv);
  }
  
@@@ -32,7 -32,7 +32,7 @@@
  #include <linux/regulator/consumer.h>
  #include <linux/bitfield.h>
  #include <linux/devfreq.h>
 -#include <linux/keyslot-manager.h>
 +#include <linux/blk-crypto-profile.h>
  #include "unipro.h"
  
  #include <asm/irq.h>
@@@ -344,7 -344,8 +344,8 @@@ struct ufs_hba_variant_ops 
                                        enum ufs_notify_change_status);
        int     (*apply_dev_quirks)(struct ufs_hba *hba);
        void    (*fixup_dev_quirks)(struct ufs_hba *hba);
-       int     (*suspend)(struct ufs_hba *, enum ufs_pm_op);
+       int     (*suspend)(struct ufs_hba *, enum ufs_pm_op,
+                                       enum ufs_notify_change_status);
        int     (*resume)(struct ufs_hba *, enum ufs_pm_op);
        void    (*dbg_register_dump)(struct ufs_hba *hba);
        int     (*phy_initialization)(struct ufs_hba *);
@@@ -653,6 -654,12 +654,12 @@@ enum ufshcd_caps 
         * in order to exit DeepSleep state.
         */
        UFSHCD_CAP_DEEPSLEEP                            = 1 << 10,
+       /*
+        * This capability allows the host controller driver to use temperature
+        * notification if it is supported by the UFS device.
+        */
+       UFSHCD_CAP_TEMP_NOTIF                           = 1 << 11,
  };
  
  struct ufs_hba_variant_params {
@@@ -766,7 -773,7 +773,7 @@@ struct ufs_hba_monitor 
   * @crypto_capabilities: Content of crypto capabilities register (0x100)
   * @crypto_cap_array: Array of crypto capabilities
   * @crypto_cfg_register: Start of the crypto cfg array
 - * @ksm: the keyslot manager tied to this hba
 + * @crypto_profile: the crypto profile of this hba (if applicable)
   */
  struct ufs_hba {
        void __iomem *mmio_base;
        struct scsi_device *sdev_ufs_device;
        struct scsi_device *sdev_rpmb;
  
+ #ifdef CONFIG_SCSI_UFS_HWMON
+       struct device *hwmon_device;
+ #endif
        enum ufs_dev_pwr_mode curr_dev_pwr_mode;
        enum uic_link_state uic_link_state;
        /* Desired UFS power management level during runtime PM */
        struct ufs_vreg_info vreg_info;
        struct list_head clk_list_head;
  
-       bool wlun_dev_clr_ua;
-       bool wlun_rpmb_clr_ua;
        /* Number of requests aborts */
        int req_abort_count;
  
        union ufs_crypto_capabilities crypto_capabilities;
        union ufs_crypto_cap_entry *crypto_cap_array;
        u32 crypto_cfg_register;
 -      struct blk_keyslot_manager ksm;
 +      struct blk_crypto_profile crypto_profile;
  #endif
  #ifdef CONFIG_DEBUG_FS
        struct dentry *debugfs_root;
  #endif
        u32 luns_avail;
        bool complete_put;
-       bool rpmb_complete_put;
  };
  
  /* Returns true if clocks can be gated. Otherwise false */
@@@ -1007,6 -1014,7 +1014,7 @@@ int ufshcd_init(struct ufs_hba *, void 
  int ufshcd_link_recovery(struct ufs_hba *hba);
  int ufshcd_make_hba_operational(struct ufs_hba *hba);
  void ufshcd_remove(struct ufs_hba *);
+ int ufshcd_uic_hibern8_enter(struct ufs_hba *hba);
  int ufshcd_uic_hibern8_exit(struct ufs_hba *hba);
  void ufshcd_delay_us(unsigned long us, unsigned long tolerance);
  int ufshcd_wait_for_register(struct ufs_hba *hba, u32 reg, u32 mask,
@@@ -1055,6 -1063,16 +1063,16 @@@ static inline u8 ufshcd_wb_get_query_in
        return 0;
  }
  
+ #ifdef CONFIG_SCSI_UFS_HWMON
+ void ufs_hwmon_probe(struct ufs_hba *hba, u8 mask);
+ void ufs_hwmon_remove(struct ufs_hba *hba);
+ void ufs_hwmon_notify_event(struct ufs_hba *hba, u8 ee_mask);
+ #else
+ static inline void ufs_hwmon_probe(struct ufs_hba *hba, u8 mask) {}
+ static inline void ufs_hwmon_remove(struct ufs_hba *hba) {}
+ static inline void ufs_hwmon_notify_event(struct ufs_hba *hba, u8 ee_mask) {}
+ #endif
  #ifdef CONFIG_PM
  extern int ufshcd_runtime_suspend(struct device *dev);
  extern int ufshcd_runtime_resume(struct device *dev);
@@@ -1301,10 -1319,11 +1319,11 @@@ static inline void ufshcd_vops_fixup_de
                hba->vops->fixup_dev_quirks(hba);
  }
  
- static inline int ufshcd_vops_suspend(struct ufs_hba *hba, enum ufs_pm_op op)
+ static inline int ufshcd_vops_suspend(struct ufs_hba *hba, enum ufs_pm_op op,
+                               enum ufs_notify_change_status status)
  {
        if (hba->vops && hba->vops->suspend)
-               return hba->vops->suspend(hba, op);
+               return hba->vops->suspend(hba, op, status);
  
        return 0;
  }
@@@ -1393,14 -1412,4 +1412,4 @@@ static inline int ufshcd_rpm_put(struc
        return pm_runtime_put(&hba->sdev_ufs_device->sdev_gendev);
  }
  
- static inline int ufshcd_rpmb_rpm_get_sync(struct ufs_hba *hba)
- {
-       return pm_runtime_get_sync(&hba->sdev_rpmb->sdev_gendev);
- }
- static inline int ufshcd_rpmb_rpm_put(struct ufs_hba *hba)
- {
-       return pm_runtime_put(&hba->sdev_rpmb->sdev_gendev);
- }
  #endif /* End of Header */
@@@ -84,6 -84,16 +84,6 @@@ static bool ufshpb_is_supported_chunk(s
        return transfer_len <= hpb->pre_req_max_tr_len;
  }
  
 -/*
 - * In this driver, WRITE_BUFFER CMD support 36KB (len=9) ~ 1MB (len=256) as
 - * default. It is possible to change range of transfer_len through sysfs.
 - */
 -static inline bool ufshpb_is_required_wb(struct ufshpb_lu *hpb, int len)
 -{
 -      return len > hpb->pre_req_min_tr_len &&
 -             len <= hpb->pre_req_max_tr_len;
 -}
 -
  static bool ufshpb_is_general_lun(int lun)
  {
        return lun < UFS_UPIU_MAX_UNIT_NUM_ID;
@@@ -324,7 -334,7 +324,7 @@@ ufshpb_get_pos_from_lpn(struct ufshpb_l
  
  static void
  ufshpb_set_hpb_read_to_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp,
 -                          __be64 ppn, u8 transfer_len, int read_id)
 +                          __be64 ppn, u8 transfer_len)
  {
        unsigned char *cdb = lrbp->cmd->cmnd;
        __be64 ppn_tmp = ppn;
        /* ppn value is stored as big-endian in the host memory */
        memcpy(&cdb[6], &ppn_tmp, sizeof(__be64));
        cdb[14] = transfer_len;
 -      cdb[15] = read_id;
 +      cdb[15] = 0;
  
        lrbp->cmd->cmd_len = UFS_CDB_SIZE;
  }
  
 -static inline void ufshpb_set_write_buf_cmd(unsigned char *cdb,
 -                                          unsigned long lpn, unsigned int len,
 -                                          int read_id)
 -{
 -      cdb[0] = UFSHPB_WRITE_BUFFER;
 -      cdb[1] = UFSHPB_WRITE_BUFFER_PREFETCH_ID;
 -
 -      put_unaligned_be32(lpn, &cdb[2]);
 -      cdb[6] = read_id;
 -      put_unaligned_be16(len * HPB_ENTRY_SIZE, &cdb[7]);
 -
 -      cdb[9] = 0x00;  /* Control = 0x00 */
 -}
 -
 -static struct ufshpb_req *ufshpb_get_pre_req(struct ufshpb_lu *hpb)
 -{
 -      struct ufshpb_req *pre_req;
 -
 -      if (hpb->num_inflight_pre_req >= hpb->throttle_pre_req) {
 -              dev_info(&hpb->sdev_ufs_lu->sdev_dev,
 -                       "pre_req throttle. inflight %d throttle %d",
 -                       hpb->num_inflight_pre_req, hpb->throttle_pre_req);
 -              return NULL;
 -      }
 -
 -      pre_req = list_first_entry_or_null(&hpb->lh_pre_req_free,
 -                                         struct ufshpb_req, list_req);
 -      if (!pre_req) {
 -              dev_info(&hpb->sdev_ufs_lu->sdev_dev, "There is no pre_req");
 -              return NULL;
 -      }
 -
 -      list_del_init(&pre_req->list_req);
 -      hpb->num_inflight_pre_req++;
 -
 -      return pre_req;
 -}
 -
 -static inline void ufshpb_put_pre_req(struct ufshpb_lu *hpb,
 -                                    struct ufshpb_req *pre_req)
 -{
 -      pre_req->req = NULL;
 -      bio_reset(pre_req->bio);
 -      list_add_tail(&pre_req->list_req, &hpb->lh_pre_req_free);
 -      hpb->num_inflight_pre_req--;
 -}
 -
 -static void ufshpb_pre_req_compl_fn(struct request *req, blk_status_t error)
 -{
 -      struct ufshpb_req *pre_req = (struct ufshpb_req *)req->end_io_data;
 -      struct ufshpb_lu *hpb = pre_req->hpb;
 -      unsigned long flags;
 -
 -      if (error) {
 -              struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(req);
 -              struct scsi_sense_hdr sshdr;
 -
 -              dev_err(&hpb->sdev_ufs_lu->sdev_dev, "block status %d", error);
 -              scsi_command_normalize_sense(cmd, &sshdr);
 -              dev_err(&hpb->sdev_ufs_lu->sdev_dev,
 -                      "code %x sense_key %x asc %x ascq %x",
 -                      sshdr.response_code,
 -                      sshdr.sense_key, sshdr.asc, sshdr.ascq);
 -              dev_err(&hpb->sdev_ufs_lu->sdev_dev,
 -                      "byte4 %x byte5 %x byte6 %x additional_len %x",
 -                      sshdr.byte4, sshdr.byte5,
 -                      sshdr.byte6, sshdr.additional_length);
 -      }
 -
 -      blk_mq_free_request(req);
 -      spin_lock_irqsave(&hpb->rgn_state_lock, flags);
 -      ufshpb_put_pre_req(pre_req->hpb, pre_req);
 -      spin_unlock_irqrestore(&hpb->rgn_state_lock, flags);
 -}
 -
 -static int ufshpb_prep_entry(struct ufshpb_req *pre_req, struct page *page)
 -{
 -      struct ufshpb_lu *hpb = pre_req->hpb;
 -      struct ufshpb_region *rgn;
 -      struct ufshpb_subregion *srgn;
 -      __be64 *addr;
 -      int offset = 0;
 -      int copied;
 -      unsigned long lpn = pre_req->wb.lpn;
 -      int rgn_idx, srgn_idx, srgn_offset;
 -      unsigned long flags;
 -
 -      addr = page_address(page);
 -      ufshpb_get_pos_from_lpn(hpb, lpn, &rgn_idx, &srgn_idx, &srgn_offset);
 -
 -      spin_lock_irqsave(&hpb->rgn_state_lock, flags);
 -
 -next_offset:
 -      rgn = hpb->rgn_tbl + rgn_idx;
 -      srgn = rgn->srgn_tbl + srgn_idx;
 -
 -      if (!ufshpb_is_valid_srgn(rgn, srgn))
 -              goto mctx_error;
 -
 -      if (!srgn->mctx)
 -              goto mctx_error;
 -
 -      copied = ufshpb_fill_ppn_from_page(hpb, srgn->mctx, srgn_offset,
 -                                         pre_req->wb.len - offset,
 -                                         &addr[offset]);
 -
 -      if (copied < 0)
 -              goto mctx_error;
 -
 -      offset += copied;
 -      srgn_offset += copied;
 -
 -      if (srgn_offset == hpb->entries_per_srgn) {
 -              srgn_offset = 0;
 -
 -              if (++srgn_idx == hpb->srgns_per_rgn) {
 -                      srgn_idx = 0;
 -                      rgn_idx++;
 -              }
 -      }
 -
 -      if (offset < pre_req->wb.len)
 -              goto next_offset;
 -
 -      spin_unlock_irqrestore(&hpb->rgn_state_lock, flags);
 -      return 0;
 -mctx_error:
 -      spin_unlock_irqrestore(&hpb->rgn_state_lock, flags);
 -      return -ENOMEM;
 -}
 -
 -static int ufshpb_pre_req_add_bio_page(struct ufshpb_lu *hpb,
 -                                     struct request_queue *q,
 -                                     struct ufshpb_req *pre_req)
 -{
 -      struct page *page = pre_req->wb.m_page;
 -      struct bio *bio = pre_req->bio;
 -      int entries_bytes, ret;
 -
 -      if (!page)
 -              return -ENOMEM;
 -
 -      if (ufshpb_prep_entry(pre_req, page))
 -              return -ENOMEM;
 -
 -      entries_bytes = pre_req->wb.len * sizeof(__be64);
 -
 -      ret = bio_add_pc_page(q, bio, page, entries_bytes, 0);
 -      if (ret != entries_bytes) {
 -              dev_err(&hpb->sdev_ufs_lu->sdev_dev,
 -                      "bio_add_pc_page fail: %d", ret);
 -              return -ENOMEM;
 -      }
 -      return 0;
 -}
 -
 -static inline int ufshpb_get_read_id(struct ufshpb_lu *hpb)
 -{
 -      if (++hpb->cur_read_id >= MAX_HPB_READ_ID)
 -              hpb->cur_read_id = 1;
 -      return hpb->cur_read_id;
 -}
 -
 -static int ufshpb_execute_pre_req(struct ufshpb_lu *hpb, struct scsi_cmnd *cmd,
 -                                struct ufshpb_req *pre_req, int read_id)
 -{
 -      struct scsi_device *sdev = cmd->device;
 -      struct request_queue *q = sdev->request_queue;
 -      struct request *req;
 -      struct scsi_request *rq;
 -      struct bio *bio = pre_req->bio;
 -
 -      pre_req->hpb = hpb;
 -      pre_req->wb.lpn = sectors_to_logical(cmd->device,
 -                                           blk_rq_pos(scsi_cmd_to_rq(cmd)));
 -      pre_req->wb.len = sectors_to_logical(cmd->device,
 -                                           blk_rq_sectors(scsi_cmd_to_rq(cmd)));
 -      if (ufshpb_pre_req_add_bio_page(hpb, q, pre_req))
 -              return -ENOMEM;
 -
 -      req = pre_req->req;
 -
 -      /* 1. request setup */
 -      blk_rq_append_bio(req, bio);
 -      req->rq_disk = NULL;
 -      req->end_io_data = (void *)pre_req;
 -      req->end_io = ufshpb_pre_req_compl_fn;
 -
 -      /* 2. scsi_request setup */
 -      rq = scsi_req(req);
 -      rq->retries = 1;
 -
 -      ufshpb_set_write_buf_cmd(rq->cmd, pre_req->wb.lpn, pre_req->wb.len,
 -                               read_id);
 -      rq->cmd_len = scsi_command_size(rq->cmd);
 -
 -      if (blk_insert_cloned_request(q, req) != BLK_STS_OK)
 -              return -EAGAIN;
 -
 -      hpb->stats.pre_req_cnt++;
 -
 -      return 0;
 -}
 -
 -static int ufshpb_issue_pre_req(struct ufshpb_lu *hpb, struct scsi_cmnd *cmd,
 -                              int *read_id)
 -{
 -      struct ufshpb_req *pre_req;
 -      struct request *req = NULL;
 -      unsigned long flags;
 -      int _read_id;
 -      int ret = 0;
 -
 -      req = blk_get_request(cmd->device->request_queue,
 -                            REQ_OP_DRV_OUT | REQ_SYNC, BLK_MQ_REQ_NOWAIT);
 -      if (IS_ERR(req))
 -              return -EAGAIN;
 -
 -      spin_lock_irqsave(&hpb->rgn_state_lock, flags);
 -      pre_req = ufshpb_get_pre_req(hpb);
 -      if (!pre_req) {
 -              ret = -EAGAIN;
 -              goto unlock_out;
 -      }
 -      _read_id = ufshpb_get_read_id(hpb);
 -      spin_unlock_irqrestore(&hpb->rgn_state_lock, flags);
 -
 -      pre_req->req = req;
 -
 -      ret = ufshpb_execute_pre_req(hpb, cmd, pre_req, _read_id);
 -      if (ret)
 -              goto free_pre_req;
 -
 -      *read_id = _read_id;
 -
 -      return ret;
 -free_pre_req:
 -      spin_lock_irqsave(&hpb->rgn_state_lock, flags);
 -      ufshpb_put_pre_req(hpb, pre_req);
 -unlock_out:
 -      spin_unlock_irqrestore(&hpb->rgn_state_lock, flags);
 -      blk_put_request(req);
 -      return ret;
 -}
 -
  /*
   * This function will set up HPB read command using host-side L2P map data.
   */
@@@ -354,6 -609,7 +354,6 @@@ int ufshpb_prep(struct ufs_hba *hba, st
        __be64 ppn;
        unsigned long flags;
        int transfer_len, rgn_idx, srgn_idx, srgn_offset;
 -      int read_id = 0;
        int err = 0;
  
        hpb = ufshpb_get_hpb_data(cmd->device);
                dev_err(hba->dev, "get ppn failed. err %d\n", err);
                return err;
        }
 -      if (!ufshpb_is_legacy(hba) &&
 -          ufshpb_is_required_wb(hpb, transfer_len)) {
 -              err = ufshpb_issue_pre_req(hpb, cmd, &read_id);
 -              if (err) {
 -                      unsigned long timeout;
  
 -                      timeout = cmd->jiffies_at_alloc + msecs_to_jiffies(
 -                                hpb->params.requeue_timeout_ms);
 -
 -                      if (time_before(jiffies, timeout))
 -                              return -EAGAIN;
 -
 -                      hpb->stats.miss_cnt++;
 -                      return 0;
 -              }
 -      }
 -
 -      ufshpb_set_hpb_read_to_upiu(hba, lrbp, ppn, transfer_len, read_id);
 +      ufshpb_set_hpb_read_to_upiu(hba, lrbp, ppn, transfer_len);
  
        hpb->stats.hit_cnt++;
        return 0;
@@@ -449,7 -721,7 +449,7 @@@ static struct ufshpb_req *ufshpb_get_re
                return NULL;
  
  retry:
 -      req = blk_get_request(hpb->sdev_ufs_lu->request_queue, dir,
 +      req = blk_mq_alloc_request(hpb->sdev_ufs_lu->request_queue, dir,
                              BLK_MQ_REQ_NOWAIT);
  
        if (!atomic && (PTR_ERR(req) == -EWOULDBLOCK) && (--retries > 0)) {
@@@ -473,7 -745,7 +473,7 @@@ free_rq
  
  static void ufshpb_put_req(struct ufshpb_lu *hpb, struct ufshpb_req *rq)
  {
 -      blk_put_request(rq->req);
 +      blk_mq_free_request(rq->req);
        kmem_cache_free(hpb->map_req_cache, rq);
  }
  
@@@ -1569,11 -1841,16 +1569,11 @@@ static void ufshpb_lu_parameter_init(st
        u32 entries_per_rgn;
        u64 rgn_mem_size, tmp;
  
 -      /* for pre_req */
 -      hpb->pre_req_min_tr_len = hpb_dev_info->max_hpb_single_cmd + 1;
 -
        if (ufshpb_is_legacy(hba))
                hpb->pre_req_max_tr_len = HPB_LEGACY_CHUNK_HIGH;
        else
                hpb->pre_req_max_tr_len = HPB_MULTI_CHUNK_HIGH;
  
 -      hpb->cur_read_id = 0;
 -
        hpb->lu_pinned_start = hpb_lu_info->pinned_start;
        hpb->lu_pinned_end = hpb_lu_info->num_pinned ?
                (hpb_lu_info->pinned_start + hpb_lu_info->num_pinned - 1)
@@@ -2371,11 -2648,11 +2371,11 @@@ static int ufshpb_get_lu_info(struct uf
  
        ufshcd_map_desc_id_to_length(hba, QUERY_DESC_IDN_UNIT, &size);
  
-       pm_runtime_get_sync(hba->dev);
+       ufshcd_rpm_get_sync(hba);
        ret = ufshcd_query_descriptor_retry(hba, UPIU_QUERY_OPCODE_READ_DESC,
                                            QUERY_DESC_IDN_UNIT, lun, 0,
                                            desc_buf, &size);
-       pm_runtime_put_sync(hba->dev);
+       ufshcd_rpm_put_sync(hba);
  
        if (ret) {
                dev_err(hba->dev,
@@@ -2598,11 -2875,8 +2598,8 @@@ void ufshpb_get_dev_info(struct ufs_hb
        if (version == HPB_SUPPORT_LEGACY_VERSION)
                hpb_dev_info->is_legacy = true;
  
-       pm_runtime_get_sync(hba->dev);
        ret = ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_READ_ATTR,
                QUERY_ATTR_IDN_MAX_HPB_SINGLE_CMD, 0, 0, &max_hpb_single_cmd);
-       pm_runtime_put_sync(hba->dev);
        if (ret)
                dev_err(hba->dev, "%s: idn: read max size of single hpb cmd query request failed",
                        __func__);
@@@ -22,7 -22,6 +22,7 @@@
  #include <linux/virtio_scsi.h>
  #include <linux/cpu.h>
  #include <linux/blkdev.h>
 +#include <linux/blk-integrity.h>
  #include <scsi/scsi_host.h>
  #include <scsi/scsi_device.h>
  #include <scsi/scsi_cmnd.h>
@@@ -164,7 -163,7 +164,7 @@@ static void virtscsi_complete_cmd(struc
                             VIRTIO_SCSI_SENSE_SIZE));
        }
  
-       sc->scsi_done(sc);
+       scsi_done(sc);
  }
  
  static void virtscsi_vq_done(struct virtio_scsi *vscsi,
@@@ -620,9 -619,8 +620,8 @@@ static int virtscsi_tmf(struct virtio_s
         * we're using independent interrupts (e.g. MSI).  Poll the
         * virtqueues once.
         *
-        * In the abort case, sc->scsi_done will do nothing, because
-        * the block layer must have detected a timeout and as a result
-        * REQ_ATOM_COMPLETE has been set.
+        * In the abort case, scsi_done() will do nothing, because the
+        * command timed out and hence SCMD_STATE_COMPLETE has been set.
         */
        virtscsi_poll_requests(vscsi);
  
@@@ -978,7 -976,6 +977,7 @@@ static unsigned int features[] = 
  static struct virtio_driver virtio_scsi_driver = {
        .feature_table = features,
        .feature_table_size = ARRAY_SIZE(features),
 +      .suppress_used_validation = true,
        .driver.name = KBUILD_MODNAME,
        .driver.owner = THIS_MODULE,
        .id_table = id_table,
@@@ -118,9 -118,9 +118,9 @@@ static int slave_configure(struct scsi_
  
  /* queue a command */
  /* This is always called with scsi_lock(host) held */
- static int queuecommand_lck(struct scsi_cmnd *srb,
-                           void (*done)(struct scsi_cmnd *))
+ static int queuecommand_lck(struct scsi_cmnd *srb)
  {
+       void (*done)(struct scsi_cmnd *) = scsi_done;
        struct rtsx_dev *dev = host_to_rtsx(srb->device->host);
        struct rtsx_chip *chip = dev->chip;
  
        }
  
        /* enqueue the command and wake up the control thread */
-       srb->scsi_done = done;
        chip->srb = srb;
        complete(&dev->cmnd_ready);
  
@@@ -423,7 -422,7 +422,7 @@@ static int rtsx_control_thread(void *__
  
                /* indicate that the command is done */
                else if (chip->srb->result != DID_ABORT << 16) {
-                       chip->srb->scsi_done(chip->srb);
+                       scsi_done(chip->srb);
                } else {
  skip_for_abort:
                        dev_err(&dev->pci->dev, "scsi command aborted\n");
@@@ -558,7 -557,7 +557,7 @@@ static irqreturn_t rtsx_interrupt(int i
                                complete(dev->done);
                } else if (status & DATA_DONE_INT) {
                        dev->trans_result = TRANS_NOT_READY;
 -                      if (dev->done && (dev->trans_state == STATE_TRANS_SG))
 +                      if (dev->done && dev->trans_state == STATE_TRANS_SG)
                                complete(dev->done);
                }
        }
@@@ -635,7 -634,7 +634,7 @@@ static void quiesce_and_remove_host(str
        if (chip->srb) {
                chip->srb->result = DID_NO_CONNECT << 16;
                scsi_lock(host);
-               chip->srb->scsi_done(dev->chip->srb);
+               scsi_done(dev->chip->srb);
                chip->srb = NULL;
                scsi_unlock(host);
        }
  #include <linux/timer.h>
  #include <linux/fs.h>
  #include <linux/blkdev.h>
 +#include <linux/blk-integrity.h>
  #include <linux/slab.h>
  #include <linux/spinlock.h>
  #include <linux/bio.h>
  #include <linux/genhd.h>
  #include <linux/file.h>
  #include <linux/module.h>
 +#include <linux/scatterlist.h>
  #include <scsi/scsi_proto.h>
  #include <asm/unaligned.h>
  
@@@ -232,9 -230,9 +232,9 @@@ static unsigned long long iblock_emulat
        struct block_device *bd,
        struct request_queue *q)
  {
 -      unsigned long long blocks_long = (div_u64(i_size_read(bd->bd_inode),
 -                                      bdev_logical_block_size(bd)) - 1);
        u32 block_size = bdev_logical_block_size(bd);
 +      unsigned long long blocks_long =
 +              div_u64(bdev_nr_bytes(bd), block_size) - 1;
  
        if (block_size == dev->dev_attrib.block_size)
                return blocks_long;
@@@ -636,12 -634,10 +636,10 @@@ static ssize_t iblock_show_configfs_dev
  {
        struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
        struct block_device *bd = ib_dev->ibd_bd;
-       char buf[BDEVNAME_SIZE];
        ssize_t bl = 0;
  
        if (bd)
-               bl += sprintf(b + bl, "iBlock device: %s",
-                               bdevname(bd, buf));
+               bl += sprintf(b + bl, "iBlock device: %pg", bd);
        if (ib_dev->ibd_flags & IBDF_HAS_UDEV_PATH)
                bl += sprintf(b + bl, "  UDEV PATH: %s",
                                ib_dev->ibd_udev_path);
diff --combined include/linux/libata.h
@@@ -676,18 -676,6 +676,18 @@@ struct ata_ering 
        struct ata_ering_entry  ring[ATA_ERING_SIZE];
  };
  
 +struct ata_cpr {
 +      u8                      num;
 +      u8                      num_storage_elements;
 +      u64                     start_lba;
 +      u64                     num_lbas;
 +};
 +
 +struct ata_cpr_log {
 +      u8                      nr_cpr;
 +      struct ata_cpr          cpr[];
 +};
 +
  struct ata_device {
        struct ata_link         *link;
        unsigned int            devno;          /* 0 or 1 */
        u32                     zac_zones_optimal_nonseq;
        u32                     zac_zones_max_open;
  
 +      /* Concurrent positioning ranges */
 +      struct ata_cpr_log      *cpr_log;
 +
        /* error history */
        int                     spdn_cnt;
        /* ering is CLEAR_END, read comment above CLEAR_END */
@@@ -1403,7 -1388,7 +1403,7 @@@ extern int ata_link_nr_enabled(struct a
   */
  extern const struct ata_port_operations ata_base_port_ops;
  extern const struct ata_port_operations sata_port_ops;
- extern struct device_attribute *ata_common_sdev_attrs[];
+ extern const struct attribute_group *ata_common_sdev_groups[];
  
  /*
   * All sht initializers (BASE, PIO, BMDMA, NCQ) must be instantiated
  
  #define ATA_BASE_SHT(drv_name)                                        \
        ATA_SUBBASE_SHT(drv_name),                              \
-       .sdev_attrs             = ata_common_sdev_attrs
+       .sdev_groups            = ata_common_sdev_groups
  
  #ifdef CONFIG_SATA_HOST
- extern struct device_attribute *ata_ncq_sdev_attrs[];
+ extern const struct attribute_group *ata_ncq_sdev_groups[];
  
  #define ATA_NCQ_SHT(drv_name)                                 \
        ATA_SUBBASE_SHT(drv_name),                              \
-       .sdev_attrs             = ata_ncq_sdev_attrs,           \
+       .sdev_groups            = ata_ncq_sdev_groups,          \
        .change_queue_depth     = ata_scsi_change_queue_depth
  #endif
  
diff --combined include/scsi/scsi_cmnd.h
@@@ -10,7 -10,6 +10,6 @@@
  #include <linux/timer.h>
  #include <linux/scatterlist.h>
  #include <scsi/scsi_device.h>
- #include <scsi/scsi_host.h>
  #include <scsi/scsi_request.h>
  
  struct Scsi_Host;
@@@ -65,6 -64,12 +64,12 @@@ struct scsi_pointer 
  #define SCMD_STATE_COMPLETE   0
  #define SCMD_STATE_INFLIGHT   1
  
+ enum scsi_cmnd_submitter {
+       SUBMITTED_BY_BLOCK_LAYER = 0,
+       SUBMITTED_BY_SCSI_ERROR_HANDLER = 1,
+       SUBMITTED_BY_SCSI_RESET_IOCTL = 2,
+ } __packed;
  struct scsi_cmnd {
        struct scsi_request req;
        struct scsi_device *device;
@@@ -90,6 -95,7 +95,7 @@@
        unsigned char prot_op;
        unsigned char prot_type;
        unsigned char prot_flags;
+       enum scsi_cmnd_submitter submitter;
  
        unsigned short cmd_len;
        enum dma_data_direction sc_data_direction;
                                 * command (auto-sense). Length must be
                                 * SCSI_SENSE_BUFFERSIZE bytes. */
  
-       /* Low-level done function - can be used by low-level driver to point
-        *        to completion function.  Not used by mid/upper level code. */
-       void (*scsi_done) (struct scsi_cmnd *);
        /*
         * The following fields can be written to by the host specific code. 
         * Everything else should be left alone. 
@@@ -165,6 -167,8 +167,8 @@@ static inline struct scsi_driver *scsi_
        return *(struct scsi_driver **)rq->rq_disk->private_data;
  }
  
+ void scsi_done(struct scsi_cmnd *cmd);
  extern void scsi_finish_command(struct scsi_cmnd *cmd);
  
  extern void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count,
@@@ -396,7 -400,4 +400,7 @@@ static inline unsigned scsi_transfer_le
  extern void scsi_build_sense(struct scsi_cmnd *scmd, int desc,
                             u8 key, u8 asc, u8 ascq);
  
 +struct request *scsi_alloc_request(struct request_queue *q,
 +              unsigned int op, blk_mq_req_flags_t flags);
 +
  #endif /* _SCSI_SCSI_CMND_H */
@@@ -5,7 -5,7 +5,7 @@@
  #include <linux/list.h>
  #include <linux/spinlock.h>
  #include <linux/workqueue.h>
 -#include <linux/blkdev.h>
 +#include <linux/blk-mq.h>
  #include <scsi/scsi.h>
  #include <linux/atomic.h>
  #include <linux/sbitmap.h>
@@@ -225,6 -225,12 +225,12 @@@ struct scsi_device 
  
        struct device           sdev_gendev,
                                sdev_dev;
+       /*
+        * The array size 6 provides space for one attribute group for the
+        * SCSI core, four attribute groups defined by SCSI LLDs and one
+        * terminating NULL pointer.
+        */
+       const struct attribute_group *gendev_attr_groups[6];
  
        struct execute_work     ew; /* used to get process context on put */
        struct work_struct      requeue_work;