[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20200615144805.6921-3-stanley.chu@mediatek.com>
Date: Mon, 15 Jun 2020 22:48:04 +0800
From: Stanley Chu <stanley.chu@...iatek.com>
To: <linux-scsi@...r.kernel.org>, <martin.petersen@...cle.com>,
<avri.altman@....com>, <alim.akhtar@...sung.com>,
<jejb@...ux.ibm.com>, <asutoshd@...eaurora.org>
CC: <beanhuo@...ron.com>, <cang@...eaurora.org>,
<matthias.bgg@...il.com>, <bvanassche@....org>,
<linux-mediatek@...ts.infradead.org>,
<linux-arm-kernel@...ts.infradead.org>,
<linux-kernel@...r.kernel.org>, <kuohong.wang@...iatek.com>,
<peter.wang@...iatek.com>, <chun-hung.wu@...iatek.com>,
<andy.teng@...iatek.com>, <cc.chou@...iatek.com>,
<chaotian.jing@...iatek.com>,
Stanley Chu <stanley.chu@...iatek.com>
Subject: [PATCH v2 2/3] scsi: ufs: Manage and export UFS debugging information dump
UFS has many functions to print different types of debugging
information. Some information is helpful for vendor drivers and
can be dumped if something wrong in vendor-specific flows.
To have minimum and most simple exported interface for vendor
drivers, create a single and unified entrance to most
debugging functions, and then export the entry function.
Signed-off-by: Stanley Chu <stanley.chu@...iatek.com>
---
drivers/scsi/ufs/ufshcd.c | 49 +++++++++++++++++++++++----------------
drivers/scsi/ufs/ufshcd.h | 8 +++++++
2 files changed, 37 insertions(+), 20 deletions(-)
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 152ae7f5ae86..5158c496cf95 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -573,6 +573,19 @@ static void ufshcd_print_pwr_info(struct ufs_hba *hba)
hba->pwr_info.hs_rate);
}
+void ufshcd_print_info(struct ufs_hba *hba, enum ufs_info_item flags)
+{
+ if (flags & UFS_INFO_HOST_STATE)
+ ufshcd_print_host_state(hba);
+ if (flags & UFS_INFO_HOST_REGS)
+ ufshcd_print_host_regs(hba);
+ if (flags & UFS_INFO_PWR)
+ ufshcd_print_pwr_info(hba);
+ if (flags & UFS_INFO_TMRS)
+ ufshcd_print_tmrs(hba, hba->outstanding_tasks);
+}
+EXPORT_SYMBOL_GPL(ufshcd_print_info);
+
void ufshcd_delay_us(unsigned long us, unsigned long tolerance)
{
if (!us)
@@ -3783,11 +3796,9 @@ static int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, struct uic_command *cmd)
ret = (status != PWR_OK) ? status : -1;
}
out:
- if (ret) {
- ufshcd_print_host_state(hba);
- ufshcd_print_pwr_info(hba);
- ufshcd_print_host_regs(hba);
- }
+ if (ret)
+ ufshcd_print_info(hba, UFS_INFO_HOST_STATE |
+ UFS_INFO_HOST_REGS | UFS_INFO_PWR);
spin_lock_irqsave(hba->host->host_lock, flags);
hba->active_uic_cmd = NULL;
@@ -4454,7 +4465,7 @@ static int ufshcd_link_startup(struct ufs_hba *hba)
/* Mark that link is up in PWM-G1, 1-lane, SLOW-AUTO mode */
ufshcd_init_pwr_info(hba);
- ufshcd_print_pwr_info(hba);
+ ufshcd_print_info(hba, UFS_INFO_PWR);
if (hba->quirks & UFSHCD_QUIRK_BROKEN_LCC) {
ret = ufshcd_disable_device_tx_lcc(hba);
@@ -4471,9 +4482,8 @@ static int ufshcd_link_startup(struct ufs_hba *hba)
out:
if (ret) {
dev_err(hba->dev, "link startup failed %d\n", ret);
- ufshcd_print_host_state(hba);
- ufshcd_print_pwr_info(hba);
- ufshcd_print_host_regs(hba);
+ ufshcd_print_info(hba, UFS_INFO_HOST_STATE |
+ UFS_INFO_HOST_REGS | UFS_INFO_PWR);
}
return ret;
}
@@ -4817,8 +4827,8 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
dev_err(hba->dev,
"OCS error from controller = %x for tag %d\n",
ocs, lrbp->task_tag);
- ufshcd_print_host_regs(hba);
- ufshcd_print_host_state(hba);
+ ufshcd_print_info(hba, UFS_INFO_HOST_STATE |
+ UFS_INFO_HOST_REGS);
break;
} /* end of switch */
@@ -5801,9 +5811,9 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba)
__func__, hba->saved_err,
hba->saved_uic_err);
- ufshcd_print_host_regs(hba);
- ufshcd_print_pwr_info(hba);
- ufshcd_print_tmrs(hba, hba->outstanding_tasks);
+ ufshcd_print_info(hba, UFS_INFO_HOST_REGS |
+ UFS_INFO_PWR |
+ UFS_INFO_TMRS);
ufshcd_print_trs(hba, hba->outstanding_reqs,
pr_prdt);
}
@@ -6416,9 +6426,8 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
scsi_print_command(hba->lrb[tag].cmd);
if (!hba->req_abort_count) {
ufshcd_update_reg_hist(&hba->ufs_stats.task_abort, 0);
- ufshcd_print_host_regs(hba);
- ufshcd_print_host_state(hba);
- ufshcd_print_pwr_info(hba);
+ ufshcd_print_info(hba, UFS_INFO_HOST_STATE |
+ UFS_INFO_HOST_REGS | UFS_INFO_PWR);
ufshcd_print_trs(hba, 1 << tag, true);
} else {
ufshcd_print_trs(hba, 1 << tag, false);
@@ -7444,7 +7453,7 @@ static int ufshcd_probe_hba(struct ufs_hba *hba, bool async)
__func__, ret);
goto out;
}
- ufshcd_print_pwr_info(hba);
+ ufshcd_print_info(hba, UFS_INFO_PWR);
}
/*
@@ -8897,8 +8906,8 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
err = ufshcd_hba_enable(hba);
if (err) {
dev_err(hba->dev, "Host controller enable failed\n");
- ufshcd_print_host_regs(hba);
- ufshcd_print_host_state(hba);
+ ufshcd_print_info(hba, UFS_INFO_HOST_STATE |
+ UFS_INFO_HOST_REGS);
goto free_tmf_queue;
}
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 7fa35c78342b..3450d9589602 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -817,6 +817,13 @@ static inline void ufshcd_rmwl(struct ufs_hba *hba, u32 mask, u32 val, u32 reg)
ufshcd_writel(hba, tmp, reg);
}
+enum ufs_info_item {
+ UFS_INFO_HOST_STATE = (1 << 0),
+ UFS_INFO_HOST_REGS = (1 << 1),
+ UFS_INFO_PWR = (1 << 2),
+ UFS_INFO_TMRS = (1 << 3)
+};
+
int ufshcd_alloc_host(struct device *, struct ufs_hba **);
void ufshcd_dealloc_host(struct ufs_hba *);
int ufshcd_hba_enable(struct ufs_hba *hba);
@@ -826,6 +833,7 @@ int ufshcd_make_hba_operational(struct ufs_hba *hba);
void ufshcd_remove(struct ufs_hba *);
int ufshcd_uic_hibern8_exit(struct ufs_hba *hba);
void ufshcd_delay_us(unsigned long us, unsigned long tolerance);
+void ufshcd_print_info(struct ufs_hba *hba, enum ufs_info_item flags);
int ufshcd_wait_for_register(struct ufs_hba *hba, u32 reg, u32 mask,
u32 val, unsigned long interval_us,
unsigned long timeout_ms);
--
2.18.0
Powered by blists - more mailing lists