diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 3ad87462593b..eca7e474ea01 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -221,6 +221,10 @@ struct hisi_sas_slot { u16 idx; }; +struct hisi_sas_debugfs_reg { + int count; +}; + struct hisi_sas_hw { int (*hw_init)(struct hisi_hba *hisi_hba); void (*setup_itct)(struct hisi_hba *hisi_hba, @@ -265,6 +269,9 @@ struct hisi_sas_hw { int max_command_entries; int complete_hdr_size; struct scsi_host_template *sht; + + const struct hisi_sas_debugfs_reg *debugfs_reg_global; + const struct hisi_sas_debugfs_reg *debugfs_reg_port; }; struct hisi_hba { @@ -334,6 +341,14 @@ struct hisi_hba { u32 intr_coal_ticks; /* Time of interrupt coalesce in us */ u32 intr_coal_count; /* Interrupt count to coalesce */ + /* debugfs memories */ + void *debugfs_global_reg; + void *debugfs_port_reg[HISI_SAS_MAX_PHYS]; + void *debugfs_complete_hdr[HISI_SAS_MAX_QUEUES]; + struct hisi_sas_cmd_hdr *debugfs_cmd_hdr[HISI_SAS_MAX_QUEUES]; + struct hisi_sas_iost *debugfs_iost; + struct hisi_sas_itct *debugfs_itct; + struct dentry *debugfs_dir; }; diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 919cd3bd746a..0b0dbaabcce8 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -2461,10 +2461,86 @@ struct dentry *hisi_sas_debugfs_dir; void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba) { + int max_command_entries = hisi_hba->hw->max_command_entries; struct device *dev = hisi_hba->dev; + int p, i, c, d; + size_t sz; hisi_hba->debugfs_dir = debugfs_create_dir(dev_name(dev), hisi_sas_debugfs_dir); + + if (!hisi_hba->debugfs_dir) + return; + + /* Alloc buffer for global */ + sz = hisi_hba->hw->debugfs_reg_global->count * 4; + hisi_hba->debugfs_global_reg = + devm_kmalloc(dev, sz, GFP_KERNEL); + + if (!hisi_hba->debugfs_global_reg) + goto fail_global; + + /* Alloc buffer for port */ + sz = hisi_hba->hw->debugfs_reg_port->count * 4; + for (p = 0; p < hisi_hba->n_phy; p++) { + hisi_hba->debugfs_port_reg[p] = + devm_kmalloc(dev, sz, GFP_KERNEL); + + if (!hisi_hba->debugfs_port_reg[p]) + goto fail_port; + } + + /* Alloc buffer for cq */ + sz = hisi_hba->hw->complete_hdr_size * HISI_SAS_QUEUE_SLOTS; + for (c = 0; c < hisi_hba->queue_count; c++) { + hisi_hba->debugfs_complete_hdr[c] = + devm_kmalloc(dev, sz, GFP_KERNEL); + + if (!hisi_hba->debugfs_complete_hdr[c]) + goto fail_cq; + } + + /* Alloc buffer for dq */ + sz = hisi_hba->hw->complete_hdr_size * HISI_SAS_QUEUE_SLOTS; + for (d = 0; d < hisi_hba->queue_count; d++) { + hisi_hba->debugfs_cmd_hdr[d] = + devm_kmalloc(dev, sz, GFP_KERNEL); + + if (!hisi_hba->debugfs_cmd_hdr[d]) + 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 */ + /* New memory allocation must be locate before itct */ + sz = HISI_SAS_MAX_ITCT_ENTRIES * sizeof(struct hisi_sas_itct); + + hisi_hba->debugfs_itct = devm_kmalloc(dev, sz, GFP_KERNEL); + if (!hisi_hba->debugfs_itct) + goto fail_itct; + + return; +fail_itct: + devm_kfree(dev, hisi_hba->debugfs_iost); +fail_iost_dq: + for (i = 0; i < d; i++) + devm_kfree(dev, hisi_hba->debugfs_cmd_hdr[i]); +fail_cq: + for (i = 0; i < c; i++) + devm_kfree(dev, hisi_hba->debugfs_complete_hdr[i]); +fail_port: + for (i = 0; i < p; i++) + devm_kfree(dev, hisi_hba->debugfs_port_reg[i]); + devm_kfree(dev, hisi_hba->debugfs_global_reg); +fail_global: + debugfs_remove_recursive(hisi_hba->debugfs_dir); + dev_dbg(dev, "failed to init debugfs!\n"); } EXPORT_SYMBOL_GPL(hisi_sas_debugfs_init); diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index a7d9651d1ec3..c1b47022d6fd 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -2332,6 +2332,12 @@ static struct device_attribute *host_attrs_v3_hw[] = { NULL }; +static const struct hisi_sas_debugfs_reg debugfs_port_reg = { +}; + +static const struct hisi_sas_debugfs_reg debugfs_global_reg = { +}; + static struct scsi_host_template sht_v3_hw = { .name = DRV_NAME, .module = THIS_MODULE, @@ -2380,6 +2386,8 @@ static const struct hisi_sas_hw hisi_sas_v3_hw = { .get_events = phy_get_events_v3_hw, .write_gpio = write_gpio_v3_hw, .wait_cmds_complete_timeout = wait_cmds_complete_timeout_v3_hw, + .debugfs_reg_global = &debugfs_global_reg, + .debugfs_reg_port = &debugfs_port_reg, }; static struct Scsi_Host *