summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/hisi_sas/hisi_sas_main.c
diff options
context:
space:
mode:
authorLuo Jiaxing <luojiaxing@huawei.com>2019-08-05 21:48:01 +0800
committerMartin K. Petersen <martin.petersen@oracle.com>2019-08-07 22:13:14 -0400
commitbbe0a7b348b336625292092c74fc7817aeb8d30b (patch)
tree7d8bacc8270fc99e25e91af17504695f1fe5b511 /drivers/scsi/hisi_sas/hisi_sas_main.c
parentbee0cf25c030776a8ecfc3c951d3b73259dc6839 (diff)
downloadlinux-bbe0a7b348b336625292092c74fc7817aeb8d30b.tar.gz
linux-bbe0a7b348b336625292092c74fc7817aeb8d30b.tar.bz2
linux-bbe0a7b348b336625292092c74fc7817aeb8d30b.zip
scsi: hisi_sas: Snapshot HW cache of IOST and ITCT at debugfs
The value of IOST/ITCT is updated to cache first, and then synchronize to DDR periodically. So the value in IOST/ITCT cache is the latest data and it's important for debugging. So, the HW cache of IOST and ITCT should be snapshot at debugfs. Signed-off-by: Luo Jiaxing <luojiaxing@huawei.com> Signed-off-by: John Garry <john.garry@huawei.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/hisi_sas/hisi_sas_main.c')
-rw-r--r--drivers/scsi/hisi_sas/hisi_sas_main.c114
1 files changed, 112 insertions, 2 deletions
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index 325ec4306794..240b6faaf25f 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -2763,10 +2763,14 @@ static void hisi_sas_debugfs_snapshot_global_reg(struct hisi_hba *hisi_hba)
static void hisi_sas_debugfs_snapshot_itct_reg(struct hisi_hba *hisi_hba)
{
+ void *cachebuf = hisi_hba->debugfs_itct_cache;
void *databuf = hisi_hba->debugfs_itct;
struct hisi_sas_itct *itct;
int i;
+ hisi_hba->hw->read_iost_itct_cache(hisi_hba, HISI_SAS_ITCT_CACHE,
+ cachebuf);
+
itct = hisi_hba->itct;
for (i = 0; i < HISI_SAS_MAX_ITCT_ENTRIES; i++, itct++) {
@@ -2778,10 +2782,14 @@ static void hisi_sas_debugfs_snapshot_itct_reg(struct hisi_hba *hisi_hba)
static void hisi_sas_debugfs_snapshot_iost_reg(struct hisi_hba *hisi_hba)
{
int max_command_entries = HISI_SAS_MAX_COMMANDS;
+ void *cachebuf = hisi_hba->debugfs_iost_cache;
void *databuf = hisi_hba->debugfs_iost;
struct hisi_sas_iost *iost;
int i;
+ hisi_hba->hw->read_iost_itct_cache(hisi_hba, HISI_SAS_IOST_CACHE,
+ cachebuf);
+
iost = hisi_hba->iost;
for (i = 0; i < max_command_entries; i++, iost++) {
@@ -3018,6 +3026,46 @@ static const struct file_operations hisi_sas_debugfs_iost_fops = {
.owner = THIS_MODULE,
};
+static int hisi_sas_debugfs_iost_cache_show(struct seq_file *s, void *p)
+{
+ struct hisi_hba *hisi_hba = s->private;
+ struct hisi_sas_iost_itct_cache *iost_cache =
+ (struct hisi_sas_iost_itct_cache *)hisi_hba->debugfs_iost_cache;
+ u32 cache_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * 4;
+ int i, tab_idx;
+ __le64 *iost;
+
+ for (i = 0; i < HISI_SAS_IOST_ITCT_CACHE_NUM; i++, iost_cache++) {
+ /*
+ * Data struct of IOST cache:
+ * Data[1]: BIT0~15: Table index
+ * Bit16: Valid mask
+ * Data[2]~[9]: IOST table
+ */
+ tab_idx = (iost_cache->data[1] & 0xffff);
+ iost = (__le64 *)iost_cache;
+
+ hisi_sas_show_row_64(s, tab_idx, cache_size, iost);
+ }
+
+ return 0;
+}
+
+static int hisi_sas_debugfs_iost_cache_open(struct inode *inode,
+ struct file *filp)
+{
+ return single_open(filp, hisi_sas_debugfs_iost_cache_show,
+ inode->i_private);
+}
+
+static const struct file_operations hisi_sas_debugfs_iost_cache_fops = {
+ .open = hisi_sas_debugfs_iost_cache_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
static int hisi_sas_debugfs_itct_show(struct seq_file *s, void *p)
{
int i, ret;
@@ -3049,6 +3097,46 @@ static const struct file_operations hisi_sas_debugfs_itct_fops = {
.owner = THIS_MODULE,
};
+static int hisi_sas_debugfs_itct_cache_show(struct seq_file *s, void *p)
+{
+ struct hisi_hba *hisi_hba = s->private;
+ struct hisi_sas_iost_itct_cache *itct_cache =
+ (struct hisi_sas_iost_itct_cache *)hisi_hba->debugfs_itct_cache;
+ u32 cache_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * 4;
+ int i, tab_idx;
+ __le64 *itct;
+
+ for (i = 0; i < HISI_SAS_IOST_ITCT_CACHE_NUM; i++, itct_cache++) {
+ /*
+ * Data struct of ITCT cache:
+ * Data[1]: BIT0~15: Table index
+ * Bit16: Valid mask
+ * Data[2]~[9]: ITCT table
+ */
+ tab_idx = itct_cache->data[1] & 0xffff;
+ itct = (__le64 *)itct_cache;
+
+ hisi_sas_show_row_64(s, tab_idx, cache_size, itct);
+ }
+
+ return 0;
+}
+
+static int hisi_sas_debugfs_itct_cache_open(struct inode *inode,
+ struct file *filp)
+{
+ return single_open(filp, hisi_sas_debugfs_itct_cache_show,
+ inode->i_private);
+}
+
+static const struct file_operations hisi_sas_debugfs_itct_cache_fops = {
+ .open = hisi_sas_debugfs_itct_cache_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba)
{
struct dentry *dump_dentry;
@@ -3095,9 +3183,15 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba)
debugfs_create_file("iost", 0400, dump_dentry, hisi_hba,
&hisi_sas_debugfs_iost_fops);
+ debugfs_create_file("iost_cache", 0400, dump_dentry, hisi_hba,
+ &hisi_sas_debugfs_iost_cache_fops);
+
debugfs_create_file("itct", 0400, dump_dentry, hisi_hba,
&hisi_sas_debugfs_itct_fops);
+ debugfs_create_file("itct_cache", 0400, dump_dentry, hisi_hba,
+ &hisi_sas_debugfs_itct_cache_fops);
+
return;
}
@@ -3212,14 +3306,26 @@ void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba)
goto fail_iost_dq;
}
- /* Alloc buffer for iost */
sz = max_command_entries * sizeof(struct hisi_sas_iost);
hisi_hba->debugfs_iost = devm_kmalloc(dev, sz, GFP_KERNEL);
if (!hisi_hba->debugfs_iost)
goto fail_iost_dq;
- /* Alloc buffer for itct */
+ sz = HISI_SAS_IOST_ITCT_CACHE_NUM *
+ sizeof(struct hisi_sas_iost_itct_cache);
+
+ hisi_hba->debugfs_iost_cache = devm_kmalloc(dev, sz, GFP_KERNEL);
+ if (!hisi_hba->debugfs_iost_cache)
+ goto fail_iost_cache;
+
+ sz = HISI_SAS_IOST_ITCT_CACHE_NUM *
+ sizeof(struct hisi_sas_iost_itct_cache);
+
+ hisi_hba->debugfs_itct_cache = devm_kmalloc(dev, sz, GFP_KERNEL);
+ if (!hisi_hba->debugfs_itct_cache)
+ goto fail_itct_cache;
+
/* New memory allocation must be locate before itct */
sz = HISI_SAS_MAX_ITCT_ENTRIES * sizeof(struct hisi_sas_itct);
@@ -3229,6 +3335,10 @@ void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba)
return;
fail_itct:
+ devm_kfree(dev, hisi_hba->debugfs_iost_cache);
+fail_itct_cache:
+ devm_kfree(dev, hisi_hba->debugfs_iost_cache);
+fail_iost_cache:
devm_kfree(dev, hisi_hba->debugfs_iost);
fail_iost_dq:
for (i = 0; i < d; i++)