diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 445e6d4a802761d8727dc8dd826e2201df81b6b2..4818b7bc220aa1ab949f4d92418012639b7adb73 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -223,6 +223,10 @@ struct hisi_sas_slot { int 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, @@ -267,6 +271,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 { @@ -335,6 +342,14 @@ struct hisi_hba { u32 intr_coal_count; /* count of interrupt coalesce */ int enable_dix_dif; + /* debugfs memories */ + void *global_reg_debugfs; + void *port_reg_debugfs[HISI_SAS_MAX_PHYS]; + void *complete_hdr_debugfs[HISI_SAS_MAX_QUEUES]; + struct hisi_sas_cmd_hdr *cmd_hdr_debugfs[HISI_SAS_MAX_QUEUES]; + struct hisi_sas_iost *iost_debugfs; + struct hisi_sas_itct *itct_debugfs; + 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 ab0c56d71e7758127f1f6c077b96f19f2d33c1e5..ba0530f8cc98e9f1248eec833472a6eb1602e69e 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -2576,10 +2576,85 @@ struct dentry *hisi_sas_dbg_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_dbg_dir); + if (!hisi_hba->debugfs_dir) + return; + + /* Alloc buffer for global */ + sz = hisi_hba->hw->debugfs_reg_global->count * 4; + hisi_hba->global_reg_debugfs = + devm_kmalloc(dev, sz, GFP_KERNEL); + + if (!hisi_hba->global_reg_debugfs) + 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->port_reg_debugfs[p] = + devm_kmalloc(dev, sz, GFP_KERNEL); + + if (!hisi_hba->port_reg_debugfs[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->complete_hdr_debugfs[c] = + devm_kmalloc(dev, sz, GFP_KERNEL); + + if (!hisi_hba->complete_hdr_debugfs[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->cmd_hdr_debugfs[d] = + devm_kmalloc(dev, sz, GFP_KERNEL); + + if (!hisi_hba->cmd_hdr_debugfs[d]) + goto fail_iost_dq; + } + + /* Alloc buffer for iost */ + sz = max_command_entries * sizeof(struct hisi_sas_iost); + + hisi_hba->iost_debugfs = devm_kmalloc(dev, sz, GFP_KERNEL); + if (!hisi_hba->iost_debugfs) + 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->itct_debugfs = devm_kmalloc(dev, sz, GFP_KERNEL); + if (!hisi_hba->itct_debugfs) + goto fail_itct; + + return; +fail_itct: + devm_kfree(dev, hisi_hba->iost_debugfs); +fail_iost_dq: + for (i = 0; i < d; i++) + devm_kfree(dev, hisi_hba->cmd_hdr_debugfs[i]); +fail_cq: + for (i = 0; i < c; i++) + devm_kfree(dev, hisi_hba->complete_hdr_debugfs[i]); +fail_port: + for (i = 0; i < p; i++) + devm_kfree(dev, hisi_hba->port_reg_debugfs[i]); + devm_kfree(dev, hisi_hba->global_reg_debugfs); +fail_global: + debugfs_remove_recursive(hisi_hba->debugfs_dir); + dev_err(dev, "Dev: %s fail to init Debugfs!", dev_name(dev)); } 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 699f62581bde75f04f093d2dcac09f0c69c9f669..986f69d5ad8fc6b12f3dccffe401fccf2ebeb522 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -2400,6 +2400,12 @@ static ssize_t intr_coal_count_store(struct device *dev, } 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_global_reg = { +}; + struct device_attribute *host_attrs_v3_hw[] = { &dev_attr_phy_event_threshold, &dev_attr_intr_conv, @@ -2459,6 +2465,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 *