scsi: ufs: Refine error history functions
The UFS error history does not only have "history of errors" but also a log of some other events which are not defined as errors. This patch fixes the confused naming of related functions and changes the approach for updating and printing history in preparation of next patch. This patch does not change any functionality. Link: https://lore.kernel.org/r/20201205115901.26815-3-stanley.chu@mediatek.com Reviewed-by: Asutosh Das <asutoshd@codeaurora.org> Reviewed-by: Can Guo <cang@codeaurora.org> Signed-off-by: Stanley Chu <stanley.chu@mediatek.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
eb3d2611df
commit
e965e5e00b
@ -411,20 +411,25 @@ static void ufshcd_print_clk_freqs(struct ufs_hba *hba)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ufshcd_print_err_hist(struct ufs_hba *hba,
|
static void ufshcd_print_evt(struct ufs_hba *hba, u32 id,
|
||||||
struct ufs_err_reg_hist *err_hist,
|
char *err_name)
|
||||||
char *err_name)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
struct ufs_event_hist *e;
|
||||||
|
|
||||||
for (i = 0; i < UFS_ERR_REG_HIST_LENGTH; i++) {
|
if (id >= UFS_EVT_CNT)
|
||||||
int p = (i + err_hist->pos) % UFS_ERR_REG_HIST_LENGTH;
|
return;
|
||||||
|
|
||||||
if (err_hist->tstamp[p] == 0)
|
e = &hba->ufs_stats.event[id];
|
||||||
|
|
||||||
|
for (i = 0; i < UFS_EVENT_HIST_LENGTH; i++) {
|
||||||
|
int p = (i + e->pos) % UFS_EVENT_HIST_LENGTH;
|
||||||
|
|
||||||
|
if (e->tstamp[p] == 0)
|
||||||
continue;
|
continue;
|
||||||
dev_err(hba->dev, "%s[%d] = 0x%x at %lld us\n", err_name, p,
|
dev_err(hba->dev, "%s[%d] = 0x%x at %lld us\n", err_name, p,
|
||||||
err_hist->reg[p], ktime_to_us(err_hist->tstamp[p]));
|
e->val[p], ktime_to_us(e->tstamp[p]));
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -432,26 +437,26 @@ static void ufshcd_print_err_hist(struct ufs_hba *hba,
|
|||||||
dev_err(hba->dev, "No record of %s\n", err_name);
|
dev_err(hba->dev, "No record of %s\n", err_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ufshcd_print_host_regs(struct ufs_hba *hba)
|
static void ufshcd_print_evt_hist(struct ufs_hba *hba)
|
||||||
{
|
{
|
||||||
ufshcd_dump_regs(hba, 0, UFSHCI_REG_SPACE_SIZE, "host_regs: ");
|
ufshcd_dump_regs(hba, 0, UFSHCI_REG_SPACE_SIZE, "host_regs: ");
|
||||||
|
|
||||||
ufshcd_print_err_hist(hba, &hba->ufs_stats.pa_err, "pa_err");
|
ufshcd_print_evt(hba, UFS_EVT_PA_ERR, "pa_err");
|
||||||
ufshcd_print_err_hist(hba, &hba->ufs_stats.dl_err, "dl_err");
|
ufshcd_print_evt(hba, UFS_EVT_DL_ERR, "dl_err");
|
||||||
ufshcd_print_err_hist(hba, &hba->ufs_stats.nl_err, "nl_err");
|
ufshcd_print_evt(hba, UFS_EVT_NL_ERR, "nl_err");
|
||||||
ufshcd_print_err_hist(hba, &hba->ufs_stats.tl_err, "tl_err");
|
ufshcd_print_evt(hba, UFS_EVT_TL_ERR, "tl_err");
|
||||||
ufshcd_print_err_hist(hba, &hba->ufs_stats.dme_err, "dme_err");
|
ufshcd_print_evt(hba, UFS_EVT_DME_ERR, "dme_err");
|
||||||
ufshcd_print_err_hist(hba, &hba->ufs_stats.auto_hibern8_err,
|
ufshcd_print_evt(hba, UFS_EVT_AUTO_HIBERN8_ERR,
|
||||||
"auto_hibern8_err");
|
"auto_hibern8_err");
|
||||||
ufshcd_print_err_hist(hba, &hba->ufs_stats.fatal_err, "fatal_err");
|
ufshcd_print_evt(hba, UFS_EVT_FATAL_ERR, "fatal_err");
|
||||||
ufshcd_print_err_hist(hba, &hba->ufs_stats.link_startup_err,
|
ufshcd_print_evt(hba, UFS_EVT_LINK_STARTUP_FAIL,
|
||||||
"link_startup_fail");
|
"link_startup_fail");
|
||||||
ufshcd_print_err_hist(hba, &hba->ufs_stats.resume_err, "resume_fail");
|
ufshcd_print_evt(hba, UFS_EVT_RESUME_ERR, "resume_fail");
|
||||||
ufshcd_print_err_hist(hba, &hba->ufs_stats.suspend_err,
|
ufshcd_print_evt(hba, UFS_EVT_SUSPEND_ERR,
|
||||||
"suspend_fail");
|
"suspend_fail");
|
||||||
ufshcd_print_err_hist(hba, &hba->ufs_stats.dev_reset, "dev_reset");
|
ufshcd_print_evt(hba, UFS_EVT_DEV_RESET, "dev_reset");
|
||||||
ufshcd_print_err_hist(hba, &hba->ufs_stats.host_reset, "host_reset");
|
ufshcd_print_evt(hba, UFS_EVT_HOST_RESET, "host_reset");
|
||||||
ufshcd_print_err_hist(hba, &hba->ufs_stats.task_abort, "task_abort");
|
ufshcd_print_evt(hba, UFS_EVT_ABORT, "task_abort");
|
||||||
|
|
||||||
ufshcd_vops_dbg_register_dump(hba);
|
ufshcd_vops_dbg_register_dump(hba);
|
||||||
}
|
}
|
||||||
@ -3852,7 +3857,7 @@ out:
|
|||||||
if (ret) {
|
if (ret) {
|
||||||
ufshcd_print_host_state(hba);
|
ufshcd_print_host_state(hba);
|
||||||
ufshcd_print_pwr_info(hba);
|
ufshcd_print_pwr_info(hba);
|
||||||
ufshcd_print_host_regs(hba);
|
ufshcd_print_evt_hist(hba);
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock_irqsave(hba->host->host_lock, flags);
|
spin_lock_irqsave(hba->host->host_lock, flags);
|
||||||
@ -4464,14 +4469,19 @@ static inline int ufshcd_disable_device_tx_lcc(struct ufs_hba *hba)
|
|||||||
return ufshcd_disable_tx_lcc(hba, true);
|
return ufshcd_disable_tx_lcc(hba, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ufshcd_update_reg_hist(struct ufs_err_reg_hist *reg_hist,
|
void ufshcd_update_evt_hist(struct ufs_hba *hba, u32 id, u32 val)
|
||||||
u32 reg)
|
|
||||||
{
|
{
|
||||||
reg_hist->reg[reg_hist->pos] = reg;
|
struct ufs_event_hist *e;
|
||||||
reg_hist->tstamp[reg_hist->pos] = ktime_get();
|
|
||||||
reg_hist->pos = (reg_hist->pos + 1) % UFS_ERR_REG_HIST_LENGTH;
|
if (id >= UFS_EVT_CNT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
e = &hba->ufs_stats.event[id];
|
||||||
|
e->val[e->pos] = val;
|
||||||
|
e->tstamp[e->pos] = ktime_get();
|
||||||
|
e->pos = (e->pos + 1) % UFS_EVENT_HIST_LENGTH;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(ufshcd_update_reg_hist);
|
EXPORT_SYMBOL_GPL(ufshcd_update_evt_hist);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ufshcd_link_startup - Initialize unipro link startup
|
* ufshcd_link_startup - Initialize unipro link startup
|
||||||
@ -4500,7 +4510,8 @@ link_startup:
|
|||||||
|
|
||||||
/* check if device is detected by inter-connect layer */
|
/* check if device is detected by inter-connect layer */
|
||||||
if (!ret && !ufshcd_is_device_present(hba)) {
|
if (!ret && !ufshcd_is_device_present(hba)) {
|
||||||
ufshcd_update_reg_hist(&hba->ufs_stats.link_startup_err,
|
ufshcd_update_evt_hist(hba,
|
||||||
|
UFS_EVT_LINK_STARTUP_FAIL,
|
||||||
0);
|
0);
|
||||||
dev_err(hba->dev, "%s: Device not present\n", __func__);
|
dev_err(hba->dev, "%s: Device not present\n", __func__);
|
||||||
ret = -ENXIO;
|
ret = -ENXIO;
|
||||||
@ -4513,7 +4524,8 @@ link_startup:
|
|||||||
* succeeds. So reset the local Uni-Pro and try again.
|
* succeeds. So reset the local Uni-Pro and try again.
|
||||||
*/
|
*/
|
||||||
if (ret && ufshcd_hba_enable(hba)) {
|
if (ret && ufshcd_hba_enable(hba)) {
|
||||||
ufshcd_update_reg_hist(&hba->ufs_stats.link_startup_err,
|
ufshcd_update_evt_hist(hba,
|
||||||
|
UFS_EVT_LINK_STARTUP_FAIL,
|
||||||
(u32)ret);
|
(u32)ret);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -4521,7 +4533,8 @@ link_startup:
|
|||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
/* failed to get the link up... retire */
|
/* failed to get the link up... retire */
|
||||||
ufshcd_update_reg_hist(&hba->ufs_stats.link_startup_err,
|
ufshcd_update_evt_hist(hba,
|
||||||
|
UFS_EVT_LINK_STARTUP_FAIL,
|
||||||
(u32)ret);
|
(u32)ret);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -4555,7 +4568,7 @@ out:
|
|||||||
dev_err(hba->dev, "link startup failed %d\n", ret);
|
dev_err(hba->dev, "link startup failed %d\n", ret);
|
||||||
ufshcd_print_host_state(hba);
|
ufshcd_print_host_state(hba);
|
||||||
ufshcd_print_pwr_info(hba);
|
ufshcd_print_pwr_info(hba);
|
||||||
ufshcd_print_host_regs(hba);
|
ufshcd_print_evt_hist(hba);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -4910,7 +4923,7 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
|
|||||||
dev_err(hba->dev,
|
dev_err(hba->dev,
|
||||||
"OCS error from controller = %x for tag %d\n",
|
"OCS error from controller = %x for tag %d\n",
|
||||||
ocs, lrbp->task_tag);
|
ocs, lrbp->task_tag);
|
||||||
ufshcd_print_host_regs(hba);
|
ufshcd_print_evt_hist(hba);
|
||||||
ufshcd_print_host_state(hba);
|
ufshcd_print_host_state(hba);
|
||||||
break;
|
break;
|
||||||
} /* end of switch */
|
} /* end of switch */
|
||||||
@ -5792,7 +5805,7 @@ static void ufshcd_err_handler(struct work_struct *work)
|
|||||||
spin_unlock_irqrestore(hba->host->host_lock, flags);
|
spin_unlock_irqrestore(hba->host->host_lock, flags);
|
||||||
ufshcd_print_host_state(hba);
|
ufshcd_print_host_state(hba);
|
||||||
ufshcd_print_pwr_info(hba);
|
ufshcd_print_pwr_info(hba);
|
||||||
ufshcd_print_host_regs(hba);
|
ufshcd_print_evt_hist(hba);
|
||||||
ufshcd_print_tmrs(hba, hba->outstanding_tasks);
|
ufshcd_print_tmrs(hba, hba->outstanding_tasks);
|
||||||
ufshcd_print_trs(hba, hba->outstanding_reqs, pr_prdt);
|
ufshcd_print_trs(hba, hba->outstanding_reqs, pr_prdt);
|
||||||
spin_lock_irqsave(hba->host->host_lock, flags);
|
spin_lock_irqsave(hba->host->host_lock, flags);
|
||||||
@ -5937,7 +5950,7 @@ static irqreturn_t ufshcd_update_uic_error(struct ufs_hba *hba)
|
|||||||
reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_PHY_ADAPTER_LAYER);
|
reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_PHY_ADAPTER_LAYER);
|
||||||
if ((reg & UIC_PHY_ADAPTER_LAYER_ERROR) &&
|
if ((reg & UIC_PHY_ADAPTER_LAYER_ERROR) &&
|
||||||
(reg & UIC_PHY_ADAPTER_LAYER_ERROR_CODE_MASK)) {
|
(reg & UIC_PHY_ADAPTER_LAYER_ERROR_CODE_MASK)) {
|
||||||
ufshcd_update_reg_hist(&hba->ufs_stats.pa_err, reg);
|
ufshcd_update_evt_hist(hba, UFS_EVT_PA_ERR, reg);
|
||||||
/*
|
/*
|
||||||
* To know whether this error is fatal or not, DB timeout
|
* To know whether this error is fatal or not, DB timeout
|
||||||
* must be checked but this error is handled separately.
|
* must be checked but this error is handled separately.
|
||||||
@ -5967,7 +5980,7 @@ static irqreturn_t ufshcd_update_uic_error(struct ufs_hba *hba)
|
|||||||
reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_DATA_LINK_LAYER);
|
reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_DATA_LINK_LAYER);
|
||||||
if ((reg & UIC_DATA_LINK_LAYER_ERROR) &&
|
if ((reg & UIC_DATA_LINK_LAYER_ERROR) &&
|
||||||
(reg & UIC_DATA_LINK_LAYER_ERROR_CODE_MASK)) {
|
(reg & UIC_DATA_LINK_LAYER_ERROR_CODE_MASK)) {
|
||||||
ufshcd_update_reg_hist(&hba->ufs_stats.dl_err, reg);
|
ufshcd_update_evt_hist(hba, UFS_EVT_DL_ERR, reg);
|
||||||
|
|
||||||
if (reg & UIC_DATA_LINK_LAYER_ERROR_PA_INIT)
|
if (reg & UIC_DATA_LINK_LAYER_ERROR_PA_INIT)
|
||||||
hba->uic_error |= UFSHCD_UIC_DL_PA_INIT_ERROR;
|
hba->uic_error |= UFSHCD_UIC_DL_PA_INIT_ERROR;
|
||||||
@ -5986,7 +5999,7 @@ static irqreturn_t ufshcd_update_uic_error(struct ufs_hba *hba)
|
|||||||
reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_NETWORK_LAYER);
|
reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_NETWORK_LAYER);
|
||||||
if ((reg & UIC_NETWORK_LAYER_ERROR) &&
|
if ((reg & UIC_NETWORK_LAYER_ERROR) &&
|
||||||
(reg & UIC_NETWORK_LAYER_ERROR_CODE_MASK)) {
|
(reg & UIC_NETWORK_LAYER_ERROR_CODE_MASK)) {
|
||||||
ufshcd_update_reg_hist(&hba->ufs_stats.nl_err, reg);
|
ufshcd_update_evt_hist(hba, UFS_EVT_NL_ERR, reg);
|
||||||
hba->uic_error |= UFSHCD_UIC_NL_ERROR;
|
hba->uic_error |= UFSHCD_UIC_NL_ERROR;
|
||||||
retval |= IRQ_HANDLED;
|
retval |= IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
@ -5994,7 +6007,7 @@ static irqreturn_t ufshcd_update_uic_error(struct ufs_hba *hba)
|
|||||||
reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_TRANSPORT_LAYER);
|
reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_TRANSPORT_LAYER);
|
||||||
if ((reg & UIC_TRANSPORT_LAYER_ERROR) &&
|
if ((reg & UIC_TRANSPORT_LAYER_ERROR) &&
|
||||||
(reg & UIC_TRANSPORT_LAYER_ERROR_CODE_MASK)) {
|
(reg & UIC_TRANSPORT_LAYER_ERROR_CODE_MASK)) {
|
||||||
ufshcd_update_reg_hist(&hba->ufs_stats.tl_err, reg);
|
ufshcd_update_evt_hist(hba, UFS_EVT_TL_ERR, reg);
|
||||||
hba->uic_error |= UFSHCD_UIC_TL_ERROR;
|
hba->uic_error |= UFSHCD_UIC_TL_ERROR;
|
||||||
retval |= IRQ_HANDLED;
|
retval |= IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
@ -6002,7 +6015,7 @@ static irqreturn_t ufshcd_update_uic_error(struct ufs_hba *hba)
|
|||||||
reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_DME);
|
reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_DME);
|
||||||
if ((reg & UIC_DME_ERROR) &&
|
if ((reg & UIC_DME_ERROR) &&
|
||||||
(reg & UIC_DME_ERROR_CODE_MASK)) {
|
(reg & UIC_DME_ERROR_CODE_MASK)) {
|
||||||
ufshcd_update_reg_hist(&hba->ufs_stats.dme_err, reg);
|
ufshcd_update_evt_hist(hba, UFS_EVT_DME_ERR, reg);
|
||||||
hba->uic_error |= UFSHCD_UIC_DME_ERROR;
|
hba->uic_error |= UFSHCD_UIC_DME_ERROR;
|
||||||
retval |= IRQ_HANDLED;
|
retval |= IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
@ -6044,7 +6057,8 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba)
|
|||||||
irqreturn_t retval = IRQ_NONE;
|
irqreturn_t retval = IRQ_NONE;
|
||||||
|
|
||||||
if (hba->errors & INT_FATAL_ERRORS) {
|
if (hba->errors & INT_FATAL_ERRORS) {
|
||||||
ufshcd_update_reg_hist(&hba->ufs_stats.fatal_err, hba->errors);
|
ufshcd_update_evt_hist(hba, UFS_EVT_FATAL_ERR,
|
||||||
|
hba->errors);
|
||||||
queue_eh_work = true;
|
queue_eh_work = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6061,7 +6075,7 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba)
|
|||||||
__func__, (hba->errors & UIC_HIBERNATE_ENTER) ?
|
__func__, (hba->errors & UIC_HIBERNATE_ENTER) ?
|
||||||
"Enter" : "Exit",
|
"Enter" : "Exit",
|
||||||
hba->errors, ufshcd_get_upmcrs(hba));
|
hba->errors, ufshcd_get_upmcrs(hba));
|
||||||
ufshcd_update_reg_hist(&hba->ufs_stats.auto_hibern8_err,
|
ufshcd_update_evt_hist(hba, UFS_EVT_AUTO_HIBERN8_ERR,
|
||||||
hba->errors);
|
hba->errors);
|
||||||
ufshcd_set_link_broken(hba);
|
ufshcd_set_link_broken(hba);
|
||||||
queue_eh_work = true;
|
queue_eh_work = true;
|
||||||
@ -6602,7 +6616,7 @@ static int ufshcd_eh_device_reset_handler(struct scsi_cmnd *cmd)
|
|||||||
|
|
||||||
out:
|
out:
|
||||||
hba->req_abort_count = 0;
|
hba->req_abort_count = 0;
|
||||||
ufshcd_update_reg_hist(&hba->ufs_stats.dev_reset, (u32)err);
|
ufshcd_update_evt_hist(hba, UFS_EVT_DEV_RESET, (u32)err);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
err = SUCCESS;
|
err = SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
@ -6739,7 +6753,7 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
|
|||||||
* handling stage: reset and restore.
|
* handling stage: reset and restore.
|
||||||
*/
|
*/
|
||||||
if (lrbp->lun == UFS_UPIU_UFS_DEVICE_WLUN) {
|
if (lrbp->lun == UFS_UPIU_UFS_DEVICE_WLUN) {
|
||||||
ufshcd_update_reg_hist(&hba->ufs_stats.task_abort, lrbp->lun);
|
ufshcd_update_evt_hist(hba, UFS_EVT_ABORT, lrbp->lun);
|
||||||
return ufshcd_eh_host_reset_handler(cmd);
|
return ufshcd_eh_host_reset_handler(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6765,8 +6779,8 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
|
|||||||
*/
|
*/
|
||||||
scsi_print_command(hba->lrb[tag].cmd);
|
scsi_print_command(hba->lrb[tag].cmd);
|
||||||
if (!hba->req_abort_count) {
|
if (!hba->req_abort_count) {
|
||||||
ufshcd_update_reg_hist(&hba->ufs_stats.task_abort, tag);
|
ufshcd_update_evt_hist(hba, UFS_EVT_ABORT, tag);
|
||||||
ufshcd_print_host_regs(hba);
|
ufshcd_print_evt_hist(hba);
|
||||||
ufshcd_print_host_state(hba);
|
ufshcd_print_host_state(hba);
|
||||||
ufshcd_print_pwr_info(hba);
|
ufshcd_print_pwr_info(hba);
|
||||||
ufshcd_print_trs(hba, 1 << tag, true);
|
ufshcd_print_trs(hba, 1 << tag, true);
|
||||||
@ -6849,7 +6863,7 @@ static int ufshcd_host_reset_and_restore(struct ufs_hba *hba)
|
|||||||
out:
|
out:
|
||||||
if (err)
|
if (err)
|
||||||
dev_err(hba->dev, "%s: Host init failed %d\n", __func__, err);
|
dev_err(hba->dev, "%s: Host init failed %d\n", __func__, err);
|
||||||
ufshcd_update_reg_hist(&hba->ufs_stats.host_reset, (u32)err);
|
ufshcd_update_evt_hist(hba, UFS_EVT_HOST_RESET, (u32)err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8697,7 +8711,7 @@ out:
|
|||||||
hba->pm_op_in_progress = 0;
|
hba->pm_op_in_progress = 0;
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
ufshcd_update_reg_hist(&hba->ufs_stats.suspend_err, (u32)ret);
|
ufshcd_update_evt_hist(hba, UFS_EVT_SUSPEND_ERR, (u32)ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8821,7 +8835,7 @@ disable_irq_and_vops_clks:
|
|||||||
out:
|
out:
|
||||||
hba->pm_op_in_progress = 0;
|
hba->pm_op_in_progress = 0;
|
||||||
if (ret)
|
if (ret)
|
||||||
ufshcd_update_reg_hist(&hba->ufs_stats.resume_err, (u32)ret);
|
ufshcd_update_evt_hist(hba, UFS_EVT_RESUME_ERR, (u32)ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9273,7 +9287,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
|
|||||||
err = ufshcd_hba_enable(hba);
|
err = ufshcd_hba_enable(hba);
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_err(hba->dev, "Host controller enable failed\n");
|
dev_err(hba->dev, "Host controller enable failed\n");
|
||||||
ufshcd_print_host_regs(hba);
|
ufshcd_print_evt_hist(hba);
|
||||||
ufshcd_print_host_state(hba);
|
ufshcd_print_host_state(hba);
|
||||||
goto free_tmf_queue;
|
goto free_tmf_queue;
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,29 @@ enum dev_cmd_type {
|
|||||||
DEV_CMD_TYPE_QUERY = 0x1,
|
DEV_CMD_TYPE_QUERY = 0x1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ufs_event_type {
|
||||||
|
/* uic specific errors */
|
||||||
|
UFS_EVT_PA_ERR = 0,
|
||||||
|
UFS_EVT_DL_ERR,
|
||||||
|
UFS_EVT_NL_ERR,
|
||||||
|
UFS_EVT_TL_ERR,
|
||||||
|
UFS_EVT_DME_ERR,
|
||||||
|
|
||||||
|
/* fatal errors */
|
||||||
|
UFS_EVT_AUTO_HIBERN8_ERR,
|
||||||
|
UFS_EVT_FATAL_ERR,
|
||||||
|
UFS_EVT_LINK_STARTUP_FAIL,
|
||||||
|
UFS_EVT_RESUME_ERR,
|
||||||
|
UFS_EVT_SUSPEND_ERR,
|
||||||
|
|
||||||
|
/* abnormal events */
|
||||||
|
UFS_EVT_DEV_RESET,
|
||||||
|
UFS_EVT_HOST_RESET,
|
||||||
|
UFS_EVT_ABORT,
|
||||||
|
|
||||||
|
UFS_EVT_CNT,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct uic_command - UIC command structure
|
* struct uic_command - UIC command structure
|
||||||
* @command: UIC command
|
* @command: UIC command
|
||||||
@ -411,17 +434,17 @@ struct ufs_clk_scaling {
|
|||||||
bool is_suspended;
|
bool is_suspended;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define UFS_ERR_REG_HIST_LENGTH 8
|
#define UFS_EVENT_HIST_LENGTH 8
|
||||||
/**
|
/**
|
||||||
* struct ufs_err_reg_hist - keeps history of errors
|
* struct ufs_event_hist - keeps history of errors
|
||||||
* @pos: index to indicate cyclic buffer position
|
* @pos: index to indicate cyclic buffer position
|
||||||
* @reg: cyclic buffer for registers value
|
* @reg: cyclic buffer for registers value
|
||||||
* @tstamp: cyclic buffer for time stamp
|
* @tstamp: cyclic buffer for time stamp
|
||||||
*/
|
*/
|
||||||
struct ufs_err_reg_hist {
|
struct ufs_event_hist {
|
||||||
int pos;
|
int pos;
|
||||||
u32 reg[UFS_ERR_REG_HIST_LENGTH];
|
u32 val[UFS_EVENT_HIST_LENGTH];
|
||||||
ktime_t tstamp[UFS_ERR_REG_HIST_LENGTH];
|
ktime_t tstamp[UFS_EVENT_HIST_LENGTH];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -432,19 +455,6 @@ struct ufs_err_reg_hist {
|
|||||||
* reset this after link-startup.
|
* reset this after link-startup.
|
||||||
* @last_hibern8_exit_tstamp: Set time after the hibern8 exit.
|
* @last_hibern8_exit_tstamp: Set time after the hibern8 exit.
|
||||||
* Clear after the first successful command completion.
|
* Clear after the first successful command completion.
|
||||||
* @pa_err: tracks pa-uic errors
|
|
||||||
* @dl_err: tracks dl-uic errors
|
|
||||||
* @nl_err: tracks nl-uic errors
|
|
||||||
* @tl_err: tracks tl-uic errors
|
|
||||||
* @dme_err: tracks dme errors
|
|
||||||
* @auto_hibern8_err: tracks auto-hibernate errors
|
|
||||||
* @fatal_err: tracks fatal errors
|
|
||||||
* @linkup_err: tracks link-startup errors
|
|
||||||
* @resume_err: tracks resume errors
|
|
||||||
* @suspend_err: tracks suspend errors
|
|
||||||
* @dev_reset: tracks device reset events
|
|
||||||
* @host_reset: tracks host reset events
|
|
||||||
* @tsk_abort: tracks task abort events
|
|
||||||
*/
|
*/
|
||||||
struct ufs_stats {
|
struct ufs_stats {
|
||||||
u32 last_intr_status;
|
u32 last_intr_status;
|
||||||
@ -452,25 +462,7 @@ struct ufs_stats {
|
|||||||
|
|
||||||
u32 hibern8_exit_cnt;
|
u32 hibern8_exit_cnt;
|
||||||
ktime_t last_hibern8_exit_tstamp;
|
ktime_t last_hibern8_exit_tstamp;
|
||||||
|
struct ufs_event_hist event[UFS_EVT_CNT];
|
||||||
/* uic specific errors */
|
|
||||||
struct ufs_err_reg_hist pa_err;
|
|
||||||
struct ufs_err_reg_hist dl_err;
|
|
||||||
struct ufs_err_reg_hist nl_err;
|
|
||||||
struct ufs_err_reg_hist tl_err;
|
|
||||||
struct ufs_err_reg_hist dme_err;
|
|
||||||
|
|
||||||
/* fatal errors */
|
|
||||||
struct ufs_err_reg_hist auto_hibern8_err;
|
|
||||||
struct ufs_err_reg_hist fatal_err;
|
|
||||||
struct ufs_err_reg_hist link_startup_err;
|
|
||||||
struct ufs_err_reg_hist resume_err;
|
|
||||||
struct ufs_err_reg_hist suspend_err;
|
|
||||||
|
|
||||||
/* abnormal events */
|
|
||||||
struct ufs_err_reg_hist dev_reset;
|
|
||||||
struct ufs_err_reg_hist host_reset;
|
|
||||||
struct ufs_err_reg_hist task_abort;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ufshcd_quirks {
|
enum ufshcd_quirks {
|
||||||
@ -914,8 +906,7 @@ int ufshcd_wait_for_register(struct ufs_hba *hba, u32 reg, u32 mask,
|
|||||||
u32 val, unsigned long interval_us,
|
u32 val, unsigned long interval_us,
|
||||||
unsigned long timeout_ms);
|
unsigned long timeout_ms);
|
||||||
void ufshcd_parse_dev_ref_clk_freq(struct ufs_hba *hba, struct clk *refclk);
|
void ufshcd_parse_dev_ref_clk_freq(struct ufs_hba *hba, struct clk *refclk);
|
||||||
void ufshcd_update_reg_hist(struct ufs_err_reg_hist *reg_hist,
|
void ufshcd_update_evt_hist(struct ufs_hba *hba, u32 id, u32 val);
|
||||||
u32 reg);
|
|
||||||
|
|
||||||
static inline void check_upiu_size(void)
|
static inline void check_upiu_size(void)
|
||||||
{
|
{
|
||||||
@ -1221,7 +1212,7 @@ static inline void ufshcd_vops_device_reset(struct ufs_hba *hba)
|
|||||||
if (!err)
|
if (!err)
|
||||||
ufshcd_set_ufs_dev_active(hba);
|
ufshcd_set_ufs_dev_active(hba);
|
||||||
if (err != -EOPNOTSUPP)
|
if (err != -EOPNOTSUPP)
|
||||||
ufshcd_update_reg_hist(&hba->ufs_stats.dev_reset, err);
|
ufshcd_update_evt_hist(hba, UFS_EVT_DEV_RESET, err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user