diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c index a3061cd7da0c..3a29c03ced69 100644 --- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/scsi/ufs/ufs-qcom.c @@ -708,53 +708,14 @@ out: return err; } -static int ufs_qcom_crypto_engine_eh(struct ufs_hba *hba) -{ - struct ufs_qcom_host *host = ufshcd_get_variant(hba); - int ice_status = 0; - int err = 0; - - host->ice.crypto_engine_err = 0; - - if (host->ice.quirks & - UFS_QCOM_ICE_QUIRK_HANDLE_CRYPTO_ENGINE_ERRORS) { - err = ufs_qcom_ice_get_status(host, &ice_status); - if (!err) - host->ice.crypto_engine_err = ice_status; - - if (host->ice.crypto_engine_err) { - dev_err(hba->dev, "%s handling crypto engine error\n", - __func__); - /* - * block commands from scsi mid-layer. - * As crypto error is a fatal error and will result in - * a host reset we should leave scsi mid layer blocked - * until host reset is completed. - * Host reset will be handled in a seperate workqueue - * and will be triggered from ufshcd_check_errors. - */ - ufshcd_scsi_block_requests(hba); - - ufshcd_abort_outstanding_transfer_requests(hba, - DID_TARGET_FAILURE); - } - } - - return host->ice.crypto_engine_err; -} - -static int ufs_qcom_crypto_engine_get_err(struct ufs_hba *hba) +static int ufs_qcom_crypto_engine_get_status(struct ufs_hba *hba, u32 *status) { struct ufs_qcom_host *host = ufshcd_get_variant(hba); - return host->ice.crypto_engine_err; -} + if (!status) + return -EINVAL; -static void ufs_qcom_crypto_engine_reset_err(struct ufs_hba *hba) -{ - struct ufs_qcom_host *host = ufshcd_get_variant(hba); - - host->ice.crypto_engine_err = 0; + return ufs_qcom_ice_get_status(host, status); } struct ufs_qcom_dev_params { @@ -2285,11 +2246,9 @@ static struct ufs_hba_variant_ops ufs_hba_qcom_vops = { }; static struct ufs_hba_crypto_variant_ops ufs_hba_crypto_variant_ops = { - .crypto_engine_cfg = ufs_qcom_crytpo_engine_cfg, - .crypto_engine_reset = ufs_qcom_crytpo_engine_reset, - .crypto_engine_eh = ufs_qcom_crypto_engine_eh, - .crypto_engine_get_err = ufs_qcom_crypto_engine_get_err, - .crypto_engine_reset_err = ufs_qcom_crypto_engine_reset_err, + .crypto_engine_cfg = ufs_qcom_crytpo_engine_cfg, + .crypto_engine_reset = ufs_qcom_crytpo_engine_reset, + .crypto_engine_get_status = ufs_qcom_crypto_engine_get_status, }; static struct ufs_hba_pm_qos_variant_ops ufs_hba_pm_qos_variant_ops = { diff --git a/drivers/scsi/ufs/ufs-qcom.h b/drivers/scsi/ufs/ufs-qcom.h index bd060ee58935..956ee8a9c13f 100644 --- a/drivers/scsi/ufs/ufs-qcom.h +++ b/drivers/scsi/ufs/ufs-qcom.h @@ -213,12 +213,6 @@ struct ufs_qcom_ice_data { struct platform_device *pdev; int state; - /* - * If UFS host controller should handle cryptographic engine's - * errors, enables this quirk. - */ - #define UFS_QCOM_ICE_QUIRK_HANDLE_CRYPTO_ENGINE_ERRORS UFS_BIT(0) - u16 quirks; bool crypto_engine_err; diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 6f0dc5b3ee0f..6c8ceb219ef3 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -629,8 +629,8 @@ static void ufshcd_print_host_state(struct ufs_hba *hba) dev_err(hba->dev, "UFS Host state=%d\n", hba->ufshcd_state); dev_err(hba->dev, "lrb in use=0x%lx, outstanding reqs=0x%lx tasks=0x%lx\n", hba->lrb_in_use, hba->outstanding_tasks, hba->outstanding_reqs); - dev_err(hba->dev, "saved_err=0x%x, saved_uic_err=0x%x\n", - hba->saved_err, hba->saved_uic_err); + dev_err(hba->dev, "saved_err=0x%x, saved_uic_err=0x%x, saved_ce_err=0x%x\n", + hba->saved_err, hba->saved_uic_err, hba->saved_ce_err); dev_err(hba->dev, "Device power mode=%d, UIC link state=%d\n", hba->curr_dev_pwr_mode, hba->uic_link_state); dev_err(hba->dev, "PM in progress=%d, sys. suspended=%d\n", @@ -5398,7 +5398,6 @@ static void ufshcd_err_handler(struct work_struct *work) bool err_xfer = false, err_tm = false; int err = 0; int tag; - int crypto_engine_err = 0; bool needs_reset = false; hba = container_of(work, struct ufs_hba, eh_work); @@ -5442,9 +5441,7 @@ static void ufshcd_err_handler(struct work_struct *work) } } - crypto_engine_err = ufshcd_vops_crypto_engine_get_err(hba); - - if ((hba->saved_err & INT_FATAL_ERRORS) || crypto_engine_err || + if ((hba->saved_err & INT_FATAL_ERRORS) || hba->saved_ce_err || ((hba->saved_err & UIC_ERROR) && (hba->saved_uic_err & (UFSHCD_UIC_DL_PA_INIT_ERROR | UFSHCD_UIC_DL_NAC_RECEIVED_ERROR | @@ -5491,9 +5488,11 @@ skip_pending_xfer_clear: if (needs_reset) { unsigned long max_doorbells = (1UL << hba->nutrs) - 1; - if (hba->saved_err & INT_FATAL_ERRORS || crypto_engine_err) + if (hba->saved_err & INT_FATAL_ERRORS) ufshcd_update_error_stats(hba, UFS_ERR_INT_FATAL_ERRORS); + if (hba->saved_ce_err) + ufshcd_update_error_stats(hba, UFS_ERR_CRYPTO_ENGINE); if (hba->saved_err & UIC_ERROR) ufshcd_update_error_stats(hba, @@ -5529,7 +5528,7 @@ skip_pending_xfer_clear: scsi_report_bus_reset(hba->host, 0); hba->saved_err = 0; hba->saved_uic_err = 0; - ufshcd_vops_crypto_engine_reset_err(hba); + hba->saved_ce_err = 0; } skip_err_handling: @@ -5625,11 +5624,8 @@ static void ufshcd_update_uic_error(struct ufs_hba *hba) static void ufshcd_check_errors(struct ufs_hba *hba) { bool queue_eh_work = false; - int crypto_engine_err = 0; - crypto_engine_err = ufshcd_vops_crypto_engine_get_err(hba); - - if (hba->errors & INT_FATAL_ERRORS || crypto_engine_err) + if (hba->errors & INT_FATAL_ERRORS || hba->ce_error) queue_eh_work = true; if (hba->errors & UIC_ERROR) { @@ -5646,6 +5642,7 @@ static void ufshcd_check_errors(struct ufs_hba *hba) */ hba->saved_err |= hba->errors; hba->saved_uic_err |= hba->uic_error; + hba->saved_ce_err |= hba->ce_error; /* handle fatal errors only when link is functional */ if (hba->ufshcd_state == UFSHCD_STATE_OPERATIONAL) { @@ -5684,15 +5681,13 @@ static void ufshcd_tmc_handler(struct ufs_hba *hba) */ static void ufshcd_sl_intr(struct ufs_hba *hba, u32 intr_status) { - bool crypto_engine_err = false; - ufsdbg_error_inject_dispatcher(hba, ERR_INJECT_INTR, intr_status, &intr_status); - ufshcd_vops_crypto_engine_eh(hba); + ufshcd_vops_crypto_engine_get_status(hba, &hba->ce_error); hba->errors = UFSHCD_ERROR_MASK & intr_status; - if (hba->errors || crypto_engine_err) + if (hba->errors || hba->ce_error) ufshcd_check_errors(hba); if (intr_status & UFSHCD_UIC_MASK) diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index c36ab80989bd..f6b396a73e55 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -139,6 +139,7 @@ enum { UFS_ERR_CLEAR_PEND_XFER_TM, UFS_ERR_INT_FATAL_ERRORS, UFS_ERR_INT_UIC_ERROR, + UFS_ERR_CRYPTO_ENGINE, /* other errors */ UFS_ERR_HIBERN8_ENTER, @@ -351,9 +352,7 @@ struct ufs_hba_variant_ops { struct ufs_hba_crypto_variant_ops { int (*crypto_engine_cfg)(struct ufs_hba *, unsigned int); int (*crypto_engine_reset)(struct ufs_hba *); - int (*crypto_engine_eh)(struct ufs_hba *); - int (*crypto_engine_get_err)(struct ufs_hba *); - void (*crypto_engine_reset_err)(struct ufs_hba *); + int (*crypto_engine_get_status)(struct ufs_hba *, u32 *); }; /** @@ -797,8 +796,10 @@ struct ufs_hba { /* HBA Errors */ u32 errors; u32 uic_error; + u32 ce_error; /* crypto engine errors */ u32 saved_err; u32 saved_uic_err; + u32 saved_ce_err; bool silence_err_logs; /* Device management request data */ @@ -1229,29 +1230,16 @@ static inline int ufshcd_vops_crypto_engine_reset(struct ufs_hba *hba) return 0; } -static inline int ufshcd_vops_crypto_engine_eh(struct ufs_hba *hba) +static inline int ufshcd_vops_crypto_engine_get_status(struct ufs_hba *hba, + u32 *status) { if (hba->var && hba->var->crypto_vops && - hba->var->crypto_vops->crypto_engine_eh) - return hba->var->crypto_vops->crypto_engine_eh(hba); + hba->var->crypto_vops->crypto_engine_get_status) + return hba->var->crypto_vops->crypto_engine_get_status(hba, + status); return 0; } -static inline int ufshcd_vops_crypto_engine_get_err(struct ufs_hba *hba) -{ - if (hba->var && hba->var->crypto_vops && - hba->var->crypto_vops->crypto_engine_get_err) - return hba->var->crypto_vops->crypto_engine_get_err(hba); - return 0; -} - -static inline void ufshcd_vops_crypto_engine_reset_err(struct ufs_hba *hba) -{ - if (hba->var && hba->var->crypto_vops && - hba->var->crypto_vops->crypto_engine_reset_err) - hba->var->crypto_vops->crypto_engine_reset_err(hba); -} - static inline void ufshcd_vops_pm_qos_req_start(struct ufs_hba *hba, struct request *req) {