提交 583194c8 编写于 作者: L Luo Jiaxing 提交者: Xie XiuQi

scsi: hisi_sas: Add DFX Feature: Take snapshot for all regs and add snapshot trig

This patch take snapshot for global regs, port regs,
CQ, DQ, IOST, ITCT.

Then, Add code for snapshot trig and generate dump
directory.
Signed-off-by: NLuo Jiaxing <luojiaxing@huawei.com>
Signed-off-by: NJohn Garry <john.garry@huawei.com>
上级 4efd66fc
...@@ -225,6 +225,13 @@ struct hisi_sas_slot { ...@@ -225,6 +225,13 @@ struct hisi_sas_slot {
struct hisi_sas_debugfs_reg { struct hisi_sas_debugfs_reg {
int count; int count;
int base_off;
union {
u32 (*read_global_reg)(struct hisi_hba *hisi_hba, u32 off);
u32 (*read_port_reg)(struct hisi_hba *hisi_hba,
int port,
u32 off);
};
}; };
struct hisi_sas_hw { struct hisi_sas_hw {
...@@ -526,4 +533,5 @@ extern void hisi_sas_controller_reset_prepare(struct hisi_hba *hisi_hba); ...@@ -526,4 +533,5 @@ extern void hisi_sas_controller_reset_prepare(struct hisi_hba *hisi_hba);
extern void hisi_sas_controller_reset_done(struct hisi_hba *hisi_hba); extern void hisi_sas_controller_reset_done(struct hisi_hba *hisi_hba);
extern void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba); extern void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba);
extern void hisi_sas_debugfs_exit(struct hisi_hba *hisi_hba); extern void hisi_sas_debugfs_exit(struct hisi_hba *hisi_hba);
extern void hisi_sas_snapshot_regs(struct hisi_hba *hisi_hba);
#endif #endif
...@@ -1526,6 +1526,9 @@ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba) ...@@ -1526,6 +1526,9 @@ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba)
struct Scsi_Host *shost = hisi_hba->shost; struct Scsi_Host *shost = hisi_hba->shost;
int rc; int rc;
if (hisi_sas_debugfs_enable && hisi_hba->itct_debugfs)
hisi_sas_snapshot_regs(hisi_hba);
if (!hisi_hba->hw->soft_reset) if (!hisi_hba->hw->soft_reset)
return -1; return -1;
...@@ -2020,6 +2023,7 @@ hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba, ...@@ -2020,6 +2023,7 @@ hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba,
slot->task = NULL; slot->task = NULL;
} }
dev_err(dev, "internal task abort: timeout and not done.\n"); dev_err(dev, "internal task abort: timeout and not done.\n");
res = -EIO; res = -EIO;
goto exit; goto exit;
} else } else
...@@ -2574,6 +2578,116 @@ EXPORT_SYMBOL_GPL(hisi_sas_probe); ...@@ -2574,6 +2578,116 @@ EXPORT_SYMBOL_GPL(hisi_sas_probe);
struct dentry *hisi_sas_dbg_dir; struct dentry *hisi_sas_dbg_dir;
static void hisi_sas_snapshot_cq_reg(struct hisi_hba *hisi_hba)
{
int queue_entry_size = hisi_hba->hw->complete_hdr_size;
int i;
for (i = 0; i < hisi_hba->queue_count; i++)
memcpy(hisi_hba->complete_hdr_debugfs[i],
hisi_hba->complete_hdr[i],
HISI_SAS_QUEUE_SLOTS * queue_entry_size);
}
static void hisi_sas_snapshot_dq_reg(struct hisi_hba *hisi_hba)
{
int queue_entry_size = hisi_hba->hw->complete_hdr_size;
int i;
for (i = 0; i < hisi_hba->queue_count; i++)
memcpy(hisi_hba->cmd_hdr_debugfs[i],
hisi_hba->cmd_hdr[i],
HISI_SAS_QUEUE_SLOTS * queue_entry_size);
}
static void hisi_sas_snapshot_port_reg(struct hisi_hba *hisi_hba)
{
const struct hisi_sas_debugfs_reg *port =
hisi_hba->hw->debugfs_reg_port;
int i, phy_cnt;
u32 offset;
u32 *databuf;
for (phy_cnt = 0; phy_cnt < hisi_hba->n_phy; phy_cnt++) {
databuf = (u32 *)hisi_hba->port_reg_debugfs[phy_cnt];
for (i = 0; i < port->count; i++, databuf++) {
offset = port->base_off + 4 * i;
*databuf = port->read_port_reg(hisi_hba,
phy_cnt,
offset);
}
}
}
static void hisi_sas_snapshot_global_reg(struct hisi_hba *hisi_hba)
{
u32 *databuf = (u32 *)hisi_hba->global_reg_debugfs;
const struct hisi_sas_debugfs_reg *global =
hisi_hba->hw->debugfs_reg_global;
int i;
for (i = 0; i < global->count; i++, databuf++)
*databuf = global->read_global_reg(hisi_hba,
4 * i);
}
static void hisi_sas_snapshot_itct_reg(struct hisi_hba *hisi_hba)
{
void *databuf = hisi_hba->itct_debugfs;
struct hisi_sas_itct *itct;
int i;
itct = hisi_hba->itct;
for (i = 0; i < HISI_SAS_MAX_ITCT_ENTRIES; i++, itct++) {
memcpy(databuf, itct, sizeof(struct hisi_sas_itct));
databuf += sizeof(struct hisi_sas_itct);
}
}
static void hisi_sas_snapshot_iost_reg(struct hisi_hba *hisi_hba)
{
int max_command_entries = hisi_hba->hw->max_command_entries;
void *databuf = hisi_hba->iost_debugfs;
struct hisi_sas_iost *iost;
int i;
iost = hisi_hba->iost;
for (i = 0; i < max_command_entries; i++, iost++) {
memcpy(databuf, iost, sizeof(struct hisi_sas_iost));
databuf += sizeof(struct hisi_sas_iost);
}
}
static void hisi_sas_create_folder_structure(struct hisi_hba *hisi_hba)
{
struct dentry *dump_dentry;
/* Create dump dir inside device dir */
dump_dentry = debugfs_create_dir("dump", hisi_hba->debugfs_dir);
if (!dump_dentry)
goto fail;
return;
fail:
debugfs_remove_recursive(hisi_hba->debugfs_dir);
}
void hisi_sas_snapshot_regs(struct hisi_hba *hisi_hba)
{
hisi_sas_snapshot_global_reg(hisi_hba);
hisi_sas_snapshot_port_reg(hisi_hba);
hisi_sas_snapshot_cq_reg(hisi_hba);
hisi_sas_snapshot_dq_reg(hisi_hba);
hisi_sas_snapshot_itct_reg(hisi_hba);
hisi_sas_snapshot_iost_reg(hisi_hba);
hisi_sas_create_folder_structure(hisi_hba);
}
EXPORT_SYMBOL_GPL(hisi_sas_snapshot_regs);
void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba) void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba)
{ {
int max_command_entries = hisi_hba->hw->max_command_entries; int max_command_entries = hisi_hba->hw->max_command_entries;
......
...@@ -2401,9 +2401,12 @@ static ssize_t intr_coal_count_store(struct device *dev, ...@@ -2401,9 +2401,12 @@ static ssize_t intr_coal_count_store(struct device *dev,
static DEVICE_ATTR_RW(intr_coal_count); static DEVICE_ATTR_RW(intr_coal_count);
static const struct hisi_sas_debugfs_reg debugfs_port_reg = { static const struct hisi_sas_debugfs_reg debugfs_port_reg = {
.base_off = PORT_BASE,
.read_port_reg = hisi_sas_phy_read32,
}; };
static const struct hisi_sas_debugfs_reg debugfs_global_reg = { static const struct hisi_sas_debugfs_reg debugfs_global_reg = {
.read_global_reg = hisi_sas_read32,
}; };
struct device_attribute *host_attrs_v3_hw[] = { struct device_attribute *host_attrs_v3_hw[] = {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册