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;
|
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[] = {
|
static const int err_inject_intr_err_codes[] = {
|
||||||
CONTROLLER_FATAL_ERROR,
|
CONTROLLER_FATAL_ERROR,
|
||||||
SYSTEM_BUS_FATAL_ERROR,
|
SYSTEM_BUS_FATAL_ERROR,
|
||||||
INJECT_COMMAND_HANG,
|
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[] = {
|
static struct ufsdbg_err_scenario err_scen_arr[] = {
|
||||||
{
|
{
|
||||||
"ERR_INJECT_INTR",
|
"ERR_INJECT_INTR",
|
||||||
|
@ -93,34 +127,34 @@ static struct ufsdbg_err_scenario err_scen_arr[] = {
|
||||||
0,
|
0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ERR_INJECT_GEAR_CHANGE",
|
"ERR_INJECT_PWR_CHANGE",
|
||||||
ERR_CODES_ALL_ENABLED,
|
ERR_CODES_ALL_ENABLED,
|
||||||
NULL,
|
err_inject_pwr_change_err_codes,
|
||||||
0,
|
ARRAY_SIZE(err_inject_pwr_change_err_codes),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ERR_INJECT_LINK_STARTUP",
|
"ERR_INJECT_LINK_STARTUP",
|
||||||
ERR_CODES_ALL_ENABLED,
|
ERR_CODES_ALL_ENABLED,
|
||||||
NULL,
|
err_inject_link_startup_err_codes,
|
||||||
0,
|
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_INJECT_DME_ATTR",
|
||||||
ERR_CODES_ALL_ENABLED,
|
ERR_CODES_ALL_ENABLED,
|
||||||
NULL,
|
err_inject_dme_attr_err_codes,
|
||||||
0,
|
ARRAY_SIZE(err_inject_dme_attr_err_codes),
|
||||||
},
|
|
||||||
{
|
|
||||||
"ERR_INJECT_DME_PEER_ATTR",
|
|
||||||
ERR_CODES_ALL_ENABLED,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ERR_INJECT_QUERY",
|
"ERR_INJECT_QUERY",
|
||||||
ERR_CODES_ALL_ENABLED,
|
ERR_CODES_ALL_ENABLED,
|
||||||
NULL,
|
err_inject_query_err_codes,
|
||||||
0,
|
ARRAY_SIZE(err_inject_query_err_codes),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ERR_INJECT_RUNTIME_PM",
|
"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,
|
void ufsdbg_error_inject_dispatcher(struct ufs_hba *hba,
|
||||||
enum ufsdbg_err_inject_scenario usecase,
|
enum ufsdbg_err_inject_scenario usecase,
|
||||||
int *ret_value)
|
int success_value, int *ret_value)
|
||||||
{
|
{
|
||||||
int opt_ret = 0;
|
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))
|
if (!should_fail(&hba->debugfs_files.fail_attr, 1))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
/* if an error already occurred/injected */
|
||||||
|
if (*ret_value != success_value)
|
||||||
|
goto out;
|
||||||
|
|
||||||
switch (usecase) {
|
switch (usecase) {
|
||||||
case ERR_INJECT_INTR:
|
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 */
|
/* fall through */
|
||||||
case ERR_INJECT_HIBERN8_ENTER:
|
case ERR_INJECT_HIBERN8_ENTER:
|
||||||
case ERR_INJECT_HIBERN8_EXIT:
|
case ERR_INJECT_HIBERN8_EXIT:
|
||||||
case ERR_INJECT_GEAR_CHANGE:
|
case ERR_INJECT_PWR_CHANGE:
|
||||||
case ERR_INJECT_LINK_STARTUP:
|
case ERR_INJECT_LINK_STARTUP:
|
||||||
|
case ERR_INJECT_UIC:
|
||||||
case ERR_INJECT_DME_ATTR:
|
case ERR_INJECT_DME_ATTR:
|
||||||
case ERR_INJECT_DME_PEER_ATTR:
|
|
||||||
case ERR_INJECT_QUERY:
|
case ERR_INJECT_QUERY:
|
||||||
case ERR_INJECT_RUNTIME_PM:
|
case ERR_INJECT_RUNTIME_PM:
|
||||||
case ERR_INJECT_SYSTEM_PM:
|
case ERR_INJECT_SYSTEM_PM:
|
||||||
|
|
|
@ -27,10 +27,10 @@ enum ufsdbg_err_inject_scenario {
|
||||||
ERR_INJECT_INTR,
|
ERR_INJECT_INTR,
|
||||||
ERR_INJECT_HIBERN8_ENTER,
|
ERR_INJECT_HIBERN8_ENTER,
|
||||||
ERR_INJECT_HIBERN8_EXIT,
|
ERR_INJECT_HIBERN8_EXIT,
|
||||||
ERR_INJECT_GEAR_CHANGE,
|
ERR_INJECT_PWR_CHANGE,
|
||||||
ERR_INJECT_LINK_STARTUP,
|
ERR_INJECT_LINK_STARTUP,
|
||||||
|
ERR_INJECT_UIC,
|
||||||
ERR_INJECT_DME_ATTR,
|
ERR_INJECT_DME_ATTR,
|
||||||
ERR_INJECT_DME_PEER_ATTR,
|
|
||||||
ERR_INJECT_QUERY,
|
ERR_INJECT_QUERY,
|
||||||
ERR_INJECT_RUNTIME_PM,
|
ERR_INJECT_RUNTIME_PM,
|
||||||
ERR_INJECT_SYSTEM_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
|
#ifdef CONFIG_UFS_FAULT_INJECTION
|
||||||
void ufsdbg_error_inject_dispatcher(struct ufs_hba *hba,
|
void ufsdbg_error_inject_dispatcher(struct ufs_hba *hba,
|
||||||
enum ufsdbg_err_inject_scenario err_scenario,
|
enum ufsdbg_err_inject_scenario err_scenario,
|
||||||
int *ret_value);
|
int success_value, int *ret_value);
|
||||||
#else
|
#else
|
||||||
static inline void ufsdbg_error_inject_dispatcher(struct ufs_hba *hba,
|
static inline void ufsdbg_error_inject_dispatcher(struct ufs_hba *hba,
|
||||||
enum ufsdbg_err_inject_scenario err_scenario,
|
enum ufsdbg_err_inject_scenario err_scenario,
|
||||||
int *ret_value)
|
int success_value, int *ret_value)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
#endif
|
#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);
|
ufshcd_save_tstamp_of_last_dme_cmd(hba);
|
||||||
mutex_unlock(&hba->uic_cmd_mutex);
|
mutex_unlock(&hba->uic_cmd_mutex);
|
||||||
ufshcd_release_all(hba);
|
ufshcd_release_all(hba);
|
||||||
|
|
||||||
|
ufsdbg_error_inject_dispatcher(hba,
|
||||||
|
ERR_INJECT_UIC, 0, &ret);
|
||||||
|
|
||||||
return 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,
|
struct ufs_query_req **request, struct ufs_query_res **response,
|
||||||
enum query_opcode opcode, u8 idn, u8 index, u8 selector)
|
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;
|
*request = &hba->dev_cmd.query.request;
|
||||||
*response = &hba->dev_cmd.query.response;
|
*response = &hba->dev_cmd.query.response;
|
||||||
memset(*request, 0, sizeof(struct ufs_query_req));
|
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 ret;
|
||||||
int retries = UFS_UIC_COMMAND_RETRIES;
|
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.command = peer ?
|
||||||
UIC_CMD_DME_PEER_SET : UIC_CMD_DME_SET;
|
UIC_CMD_DME_PEER_SET : UIC_CMD_DME_SET;
|
||||||
uic_cmd.argument1 = attr_sel;
|
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.command = peer ?
|
||||||
UIC_CMD_DME_PEER_GET : UIC_CMD_DME_GET;
|
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;
|
uic_cmd.argument1 = attr_sel;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
@ -4114,6 +4128,9 @@ int ufshcd_change_power_mode(struct ufs_hba *hba,
|
||||||
sizeof(struct ufs_pa_layer_attr));
|
sizeof(struct ufs_pa_layer_attr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ufsdbg_error_inject_dispatcher(hba,
|
||||||
|
ERR_INJECT_PWR_CHANGE, 0, &ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4430,6 +4447,9 @@ static int ufshcd_link_startup(struct ufs_hba *hba)
|
||||||
|
|
||||||
ret = ufshcd_make_hba_operational(hba);
|
ret = ufshcd_make_hba_operational(hba);
|
||||||
out:
|
out:
|
||||||
|
ufsdbg_error_inject_dispatcher(hba,
|
||||||
|
ERR_INJECT_LINK_STARTUP, 0, &ret);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
dev_err(hba->dev, "link startup failed %d\n", ret);
|
dev_err(hba->dev, "link startup failed %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -5669,7 +5689,7 @@ static void ufshcd_sl_intr(struct ufs_hba *hba, u32 intr_status)
|
||||||
bool crypto_engine_err = false;
|
bool crypto_engine_err = false;
|
||||||
|
|
||||||
ufsdbg_error_inject_dispatcher(hba,
|
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)
|
if (hba->vops && hba->vops->crypto_engine_eh)
|
||||||
crypto_engine_err = hba->vops->crypto_engine_eh(hba);
|
crypto_engine_err = hba->vops->crypto_engine_eh(hba);
|
||||||
|
|
Loading…
Add table
Reference in a new issue