scsi: ufs: add additional error injection scenarios
This change adds the following additional error scenarios: - power mode change error - link start-up error - send UIC command error - get/set DME command error (to host and device) - send invalid query (flag/attribute/descriptor) Change-Id: I440519c385a5da269b85ed2cdad66565ed3e6d7e Signed-off-by: Yaniv Gardi <ygardi@codeaurora.org> [subhashj@codeaurora.org: resolved trivial merge conflicts] Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
This commit is contained in:
parent
d3715e11f7
commit
3f8adb02aa
3 changed files with 86 additions and 24 deletions
|
@ -67,12 +67,46 @@ struct ufsdbg_err_scenario {
|
|||
u32 num_err_codes;
|
||||
};
|
||||
|
||||
/*
|
||||
* the following static arrays are aggregation of possible errors
|
||||
* that might occur during the relevant error scenario
|
||||
*/
|
||||
static const int err_inject_intr_err_codes[] = {
|
||||
CONTROLLER_FATAL_ERROR,
|
||||
SYSTEM_BUS_FATAL_ERROR,
|
||||
INJECT_COMMAND_HANG,
|
||||
};
|
||||
|
||||
static const int err_inject_pwr_change_err_codes[] = {
|
||||
-EIO,
|
||||
-ETIMEDOUT,
|
||||
-1,
|
||||
PWR_REMOTE,
|
||||
PWR_BUSY,
|
||||
PWR_ERROR_CAP,
|
||||
PWR_FATAL_ERROR,
|
||||
};
|
||||
|
||||
static const int err_inject_link_startup_err_codes[] = {
|
||||
-EIO,
|
||||
-ETIMEDOUT,
|
||||
};
|
||||
|
||||
static const int err_inject_uic_err_codes[] = {
|
||||
-EIO,
|
||||
-ETIMEDOUT,
|
||||
};
|
||||
|
||||
static const int err_inject_dme_attr_err_codes[] = {
|
||||
/* an invalid DME attribute for host and device */
|
||||
0x1600,
|
||||
};
|
||||
|
||||
static const int err_inject_query_err_codes[] = {
|
||||
/* an invalid idn for flag/attribute/descriptor query request */
|
||||
0xFF,
|
||||
};
|
||||
|
||||
static struct ufsdbg_err_scenario err_scen_arr[] = {
|
||||
{
|
||||
"ERR_INJECT_INTR",
|
||||
|
@ -93,34 +127,34 @@ static struct ufsdbg_err_scenario err_scen_arr[] = {
|
|||
0,
|
||||
},
|
||||
{
|
||||
"ERR_INJECT_GEAR_CHANGE",
|
||||
"ERR_INJECT_PWR_CHANGE",
|
||||
ERR_CODES_ALL_ENABLED,
|
||||
NULL,
|
||||
0,
|
||||
err_inject_pwr_change_err_codes,
|
||||
ARRAY_SIZE(err_inject_pwr_change_err_codes),
|
||||
},
|
||||
{
|
||||
"ERR_INJECT_LINK_STARTUP",
|
||||
ERR_CODES_ALL_ENABLED,
|
||||
NULL,
|
||||
0,
|
||||
err_inject_link_startup_err_codes,
|
||||
ARRAY_SIZE(err_inject_link_startup_err_codes),
|
||||
},
|
||||
{
|
||||
"ERR_INJECT_UIC",
|
||||
ERR_CODES_ALL_ENABLED,
|
||||
err_inject_uic_err_codes,
|
||||
ARRAY_SIZE(err_inject_uic_err_codes),
|
||||
},
|
||||
{
|
||||
"ERR_INJECT_DME_ATTR",
|
||||
ERR_CODES_ALL_ENABLED,
|
||||
NULL,
|
||||
0,
|
||||
},
|
||||
{
|
||||
"ERR_INJECT_DME_PEER_ATTR",
|
||||
ERR_CODES_ALL_ENABLED,
|
||||
NULL,
|
||||
0,
|
||||
err_inject_dme_attr_err_codes,
|
||||
ARRAY_SIZE(err_inject_dme_attr_err_codes),
|
||||
},
|
||||
{
|
||||
"ERR_INJECT_QUERY",
|
||||
ERR_CODES_ALL_ENABLED,
|
||||
NULL,
|
||||
0,
|
||||
err_inject_query_err_codes,
|
||||
ARRAY_SIZE(err_inject_query_err_codes),
|
||||
},
|
||||
{
|
||||
"ERR_INJECT_RUNTIME_PM",
|
||||
|
@ -264,7 +298,7 @@ ufsdbg_find_err_code(enum ufsdbg_err_inject_scenario usecase, int *ret)
|
|||
|
||||
void ufsdbg_error_inject_dispatcher(struct ufs_hba *hba,
|
||||
enum ufsdbg_err_inject_scenario usecase,
|
||||
int *ret_value)
|
||||
int success_value, int *ret_value)
|
||||
{
|
||||
int opt_ret = 0;
|
||||
|
||||
|
@ -280,16 +314,24 @@ void ufsdbg_error_inject_dispatcher(struct ufs_hba *hba,
|
|||
if (!should_fail(&hba->debugfs_files.fail_attr, 1))
|
||||
goto out;
|
||||
|
||||
/* if an error already occurred/injected */
|
||||
if (*ret_value != success_value)
|
||||
goto out;
|
||||
|
||||
switch (usecase) {
|
||||
case ERR_INJECT_INTR:
|
||||
ufsdbg_intr_fail_request(hba, &opt_ret);
|
||||
/* an error already occurred */
|
||||
if (*ret_value & UFSHCD_ERROR_MASK)
|
||||
goto out;
|
||||
|
||||
ufsdbg_intr_fail_request(hba, (u32 *)&opt_ret);
|
||||
/* fall through */
|
||||
case ERR_INJECT_HIBERN8_ENTER:
|
||||
case ERR_INJECT_HIBERN8_EXIT:
|
||||
case ERR_INJECT_GEAR_CHANGE:
|
||||
case ERR_INJECT_PWR_CHANGE:
|
||||
case ERR_INJECT_LINK_STARTUP:
|
||||
case ERR_INJECT_UIC:
|
||||
case ERR_INJECT_DME_ATTR:
|
||||
case ERR_INJECT_DME_PEER_ATTR:
|
||||
case ERR_INJECT_QUERY:
|
||||
case ERR_INJECT_RUNTIME_PM:
|
||||
case ERR_INJECT_SYSTEM_PM:
|
||||
|
|
|
@ -27,10 +27,10 @@ enum ufsdbg_err_inject_scenario {
|
|||
ERR_INJECT_INTR,
|
||||
ERR_INJECT_HIBERN8_ENTER,
|
||||
ERR_INJECT_HIBERN8_EXIT,
|
||||
ERR_INJECT_GEAR_CHANGE,
|
||||
ERR_INJECT_PWR_CHANGE,
|
||||
ERR_INJECT_LINK_STARTUP,
|
||||
ERR_INJECT_UIC,
|
||||
ERR_INJECT_DME_ATTR,
|
||||
ERR_INJECT_DME_PEER_ATTR,
|
||||
ERR_INJECT_QUERY,
|
||||
ERR_INJECT_RUNTIME_PM,
|
||||
ERR_INJECT_SYSTEM_PM,
|
||||
|
@ -60,11 +60,11 @@ static inline void ufsdbg_pr_buf_to_std(struct ufs_hba *hba, int offset,
|
|||
#ifdef CONFIG_UFS_FAULT_INJECTION
|
||||
void ufsdbg_error_inject_dispatcher(struct ufs_hba *hba,
|
||||
enum ufsdbg_err_inject_scenario err_scenario,
|
||||
int *ret_value);
|
||||
int success_value, int *ret_value);
|
||||
#else
|
||||
static inline void ufsdbg_error_inject_dispatcher(struct ufs_hba *hba,
|
||||
enum ufsdbg_err_inject_scenario err_scenario,
|
||||
int *ret_value)
|
||||
int success_value, int *ret_value)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -2199,6 +2199,10 @@ ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd)
|
|||
ufshcd_save_tstamp_of_last_dme_cmd(hba);
|
||||
mutex_unlock(&hba->uic_cmd_mutex);
|
||||
ufshcd_release_all(hba);
|
||||
|
||||
ufsdbg_error_inject_dispatcher(hba,
|
||||
ERR_INJECT_UIC, 0, &ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -2861,6 +2865,9 @@ static inline void ufshcd_init_query(struct ufs_hba *hba,
|
|||
struct ufs_query_req **request, struct ufs_query_res **response,
|
||||
enum query_opcode opcode, u8 idn, u8 index, u8 selector)
|
||||
{
|
||||
ufsdbg_error_inject_dispatcher(hba,
|
||||
ERR_INJECT_QUERY, idn, (int *)&idn);
|
||||
|
||||
*request = &hba->dev_cmd.query.request;
|
||||
*response = &hba->dev_cmd.query.response;
|
||||
memset(*request, 0, sizeof(struct ufs_query_req));
|
||||
|
@ -3624,6 +3631,9 @@ int ufshcd_dme_set_attr(struct ufs_hba *hba, u32 attr_sel,
|
|||
int ret;
|
||||
int retries = UFS_UIC_COMMAND_RETRIES;
|
||||
|
||||
ufsdbg_error_inject_dispatcher(hba,
|
||||
ERR_INJECT_DME_ATTR, attr_sel, &attr_sel);
|
||||
|
||||
uic_cmd.command = peer ?
|
||||
UIC_CMD_DME_PEER_SET : UIC_CMD_DME_SET;
|
||||
uic_cmd.argument1 = attr_sel;
|
||||
|
@ -3695,6 +3705,10 @@ int ufshcd_dme_get_attr(struct ufs_hba *hba, u32 attr_sel,
|
|||
|
||||
uic_cmd.command = peer ?
|
||||
UIC_CMD_DME_PEER_GET : UIC_CMD_DME_GET;
|
||||
|
||||
ufsdbg_error_inject_dispatcher(hba,
|
||||
ERR_INJECT_DME_ATTR, attr_sel, &attr_sel);
|
||||
|
||||
uic_cmd.argument1 = attr_sel;
|
||||
|
||||
do {
|
||||
|
@ -4114,6 +4128,9 @@ int ufshcd_change_power_mode(struct ufs_hba *hba,
|
|||
sizeof(struct ufs_pa_layer_attr));
|
||||
}
|
||||
|
||||
ufsdbg_error_inject_dispatcher(hba,
|
||||
ERR_INJECT_PWR_CHANGE, 0, &ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -4430,6 +4447,9 @@ static int ufshcd_link_startup(struct ufs_hba *hba)
|
|||
|
||||
ret = ufshcd_make_hba_operational(hba);
|
||||
out:
|
||||
ufsdbg_error_inject_dispatcher(hba,
|
||||
ERR_INJECT_LINK_STARTUP, 0, &ret);
|
||||
|
||||
if (ret)
|
||||
dev_err(hba->dev, "link startup failed %d\n", ret);
|
||||
return ret;
|
||||
|
@ -5669,7 +5689,7 @@ 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);
|
||||
ERR_INJECT_INTR, intr_status, &intr_status);
|
||||
|
||||
if (hba->vops && hba->vops->crypto_engine_eh)
|
||||
crypto_engine_err = hba->vops->crypto_engine_eh(hba);
|
||||
|
|
Loading…
Add table
Reference in a new issue