From ada96960c126fb9fe6d4d4fb92122c6cbaf625a8 Mon Sep 17 00:00:00 2001 From: Gilad Broner Date: Thu, 8 Oct 2015 15:20:04 +0300 Subject: [PATCH] scsi: ufs-ice: fix ICE error handler Current code does not actually handle ICE errors as the relevant quirk is not set. Also, ICE errors are checked only if some host controller error occurred. Removed the quirk and fixed the check for ICE errors. Also, removed redundant API crypto_engine_get_err() and crypto_engine_reset_err(). Change-Id: Ic7f4e9a2cd3771f1f52dff97b2be90d12e32d2e5 Signed-off-by: Gilad Broner [venkatg@codeaurora.org: dropped msm/ice.c changes] Signed-off-by: Venkat Gopalakrishnan --- drivers/scsi/ufs/ufs-qcom.c | 55 +++++-------------------------------- drivers/scsi/ufs/ufs-qcom.h | 6 ---- drivers/scsi/ufs/ufshcd.c | 27 ++++++++---------- drivers/scsi/ufs/ufshcd.h | 30 ++++++-------------- 4 files changed, 27 insertions(+), 91 deletions(-) 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) {