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 <gbroner@codeaurora.org>
[venkatg@codeaurora.org: dropped msm/ice.c changes]
Signed-off-by: Venkat Gopalakrishnan <venkatg@codeaurora.org>
This commit is contained in:
Gilad Broner 2015-10-08 15:20:04 +03:00 committed by David Keitel
parent eefe2bc77e
commit ada96960c1
4 changed files with 27 additions and 91 deletions

View file

@ -708,53 +708,14 @@ out:
return err; return err;
} }
static int ufs_qcom_crypto_engine_eh(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);
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)
{ {
struct ufs_qcom_host *host = ufshcd_get_variant(hba); 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) return ufs_qcom_ice_get_status(host, status);
{
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
host->ice.crypto_engine_err = 0;
} }
struct ufs_qcom_dev_params { 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 = { static struct ufs_hba_crypto_variant_ops ufs_hba_crypto_variant_ops = {
.crypto_engine_cfg = ufs_qcom_crytpo_engine_cfg, .crypto_engine_cfg = ufs_qcom_crytpo_engine_cfg,
.crypto_engine_reset = ufs_qcom_crytpo_engine_reset, .crypto_engine_reset = ufs_qcom_crytpo_engine_reset,
.crypto_engine_eh = ufs_qcom_crypto_engine_eh, .crypto_engine_get_status = ufs_qcom_crypto_engine_get_status,
.crypto_engine_get_err = ufs_qcom_crypto_engine_get_err,
.crypto_engine_reset_err = ufs_qcom_crypto_engine_reset_err,
}; };
static struct ufs_hba_pm_qos_variant_ops ufs_hba_pm_qos_variant_ops = { static struct ufs_hba_pm_qos_variant_ops ufs_hba_pm_qos_variant_ops = {

View file

@ -213,12 +213,6 @@ struct ufs_qcom_ice_data {
struct platform_device *pdev; struct platform_device *pdev;
int state; 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; u16 quirks;
bool crypto_engine_err; bool crypto_engine_err;

View file

@ -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, "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", 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); hba->lrb_in_use, hba->outstanding_tasks, hba->outstanding_reqs);
dev_err(hba->dev, "saved_err=0x%x, saved_uic_err=0x%x\n", 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_err, hba->saved_uic_err, hba->saved_ce_err);
dev_err(hba->dev, "Device power mode=%d, UIC link state=%d\n", dev_err(hba->dev, "Device power mode=%d, UIC link state=%d\n",
hba->curr_dev_pwr_mode, hba->uic_link_state); hba->curr_dev_pwr_mode, hba->uic_link_state);
dev_err(hba->dev, "PM in progress=%d, sys. suspended=%d\n", 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; bool err_xfer = false, err_tm = false;
int err = 0; int err = 0;
int tag; int tag;
int crypto_engine_err = 0;
bool needs_reset = false; bool needs_reset = false;
hba = container_of(work, struct ufs_hba, eh_work); 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) || hba->saved_ce_err ||
if ((hba->saved_err & INT_FATAL_ERRORS) || crypto_engine_err ||
((hba->saved_err & UIC_ERROR) && ((hba->saved_err & UIC_ERROR) &&
(hba->saved_uic_err & (UFSHCD_UIC_DL_PA_INIT_ERROR | (hba->saved_uic_err & (UFSHCD_UIC_DL_PA_INIT_ERROR |
UFSHCD_UIC_DL_NAC_RECEIVED_ERROR | UFSHCD_UIC_DL_NAC_RECEIVED_ERROR |
@ -5491,9 +5488,11 @@ skip_pending_xfer_clear:
if (needs_reset) { if (needs_reset) {
unsigned long max_doorbells = (1UL << hba->nutrs) - 1; 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, ufshcd_update_error_stats(hba,
UFS_ERR_INT_FATAL_ERRORS); 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) if (hba->saved_err & UIC_ERROR)
ufshcd_update_error_stats(hba, ufshcd_update_error_stats(hba,
@ -5529,7 +5528,7 @@ skip_pending_xfer_clear:
scsi_report_bus_reset(hba->host, 0); scsi_report_bus_reset(hba->host, 0);
hba->saved_err = 0; hba->saved_err = 0;
hba->saved_uic_err = 0; hba->saved_uic_err = 0;
ufshcd_vops_crypto_engine_reset_err(hba); hba->saved_ce_err = 0;
} }
skip_err_handling: 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) static void ufshcd_check_errors(struct ufs_hba *hba)
{ {
bool queue_eh_work = false; 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 || hba->ce_error)
if (hba->errors & INT_FATAL_ERRORS || crypto_engine_err)
queue_eh_work = true; queue_eh_work = true;
if (hba->errors & UIC_ERROR) { 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_err |= hba->errors;
hba->saved_uic_err |= hba->uic_error; hba->saved_uic_err |= hba->uic_error;
hba->saved_ce_err |= hba->ce_error;
/* handle fatal errors only when link is functional */ /* handle fatal errors only when link is functional */
if (hba->ufshcd_state == UFSHCD_STATE_OPERATIONAL) { 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) static void ufshcd_sl_intr(struct ufs_hba *hba, u32 intr_status)
{ {
bool crypto_engine_err = false;
ufsdbg_error_inject_dispatcher(hba, ufsdbg_error_inject_dispatcher(hba,
ERR_INJECT_INTR, intr_status, &intr_status); 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; hba->errors = UFSHCD_ERROR_MASK & intr_status;
if (hba->errors || crypto_engine_err) if (hba->errors || hba->ce_error)
ufshcd_check_errors(hba); ufshcd_check_errors(hba);
if (intr_status & UFSHCD_UIC_MASK) if (intr_status & UFSHCD_UIC_MASK)

View file

@ -139,6 +139,7 @@ enum {
UFS_ERR_CLEAR_PEND_XFER_TM, UFS_ERR_CLEAR_PEND_XFER_TM,
UFS_ERR_INT_FATAL_ERRORS, UFS_ERR_INT_FATAL_ERRORS,
UFS_ERR_INT_UIC_ERROR, UFS_ERR_INT_UIC_ERROR,
UFS_ERR_CRYPTO_ENGINE,
/* other errors */ /* other errors */
UFS_ERR_HIBERN8_ENTER, UFS_ERR_HIBERN8_ENTER,
@ -351,9 +352,7 @@ struct ufs_hba_variant_ops {
struct ufs_hba_crypto_variant_ops { struct ufs_hba_crypto_variant_ops {
int (*crypto_engine_cfg)(struct ufs_hba *, unsigned int); int (*crypto_engine_cfg)(struct ufs_hba *, unsigned int);
int (*crypto_engine_reset)(struct ufs_hba *); int (*crypto_engine_reset)(struct ufs_hba *);
int (*crypto_engine_eh)(struct ufs_hba *); int (*crypto_engine_get_status)(struct ufs_hba *, u32 *);
int (*crypto_engine_get_err)(struct ufs_hba *);
void (*crypto_engine_reset_err)(struct ufs_hba *);
}; };
/** /**
@ -797,8 +796,10 @@ struct ufs_hba {
/* HBA Errors */ /* HBA Errors */
u32 errors; u32 errors;
u32 uic_error; u32 uic_error;
u32 ce_error; /* crypto engine errors */
u32 saved_err; u32 saved_err;
u32 saved_uic_err; u32 saved_uic_err;
u32 saved_ce_err;
bool silence_err_logs; bool silence_err_logs;
/* Device management request data */ /* Device management request data */
@ -1229,29 +1230,16 @@ static inline int ufshcd_vops_crypto_engine_reset(struct ufs_hba *hba)
return 0; 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 && if (hba->var && hba->var->crypto_vops &&
hba->var->crypto_vops->crypto_engine_eh) hba->var->crypto_vops->crypto_engine_get_status)
return hba->var->crypto_vops->crypto_engine_eh(hba); return hba->var->crypto_vops->crypto_engine_get_status(hba,
status);
return 0; 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, static inline void ufshcd_vops_pm_qos_req_start(struct ufs_hba *hba,
struct request *req) struct request *req)
{ {