Unverified Commit d89ddc49 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!13809 scsi: hisi_sas: Some fixes for hisi_sas

Merge Pull Request from: @xia-bing1 
 
hisi_sas:
This series contains some fixes including:
Adjust priority of registering and exiting debugfs for security;
Create trigger_dump at the end of the debugfs initialization;
Add firmware information check;
Enable all PHYs that are not disabled by user during controller reset;
Reset PHY again if phyup timeout;
Check usage count only when the runtime PM status is RPM_SUSPENDING;
Add cond_resched() for no forced preemption model;
Default enable interrupt coalescing;
Update disk locked timeout to 7 seconds;
Add time interval between two H2D FIS following soft reset spec;
Update v3 hw STP_LINK_TIMER setting;
Create all dump files during debugfs initialization;
Add latest_dump for the debugfs dump;
Xingui Yang (3):
  scsi: hisi_sas: Update disk locked timeout to 7 seconds
  scsi: hisi_sas: Add time interval between two H2D FIS following soft
    reset spec
  scsi: hisi_sas: Update v3 hw STP_LINK_TIMER setting

Yihang Li (10):
  scsi: hisi_sas: Adjust priority of registering and exiting debugfs for
    security
  scsi: hisi_sas: Create trigger_dump at the end of the debugfs
    initialization
  scsi: hisi_sas: Add firmware information check
  scsi: hisi_sas: Enable all PHYs that are not disabled by user during
    controller reset
  scsi: hisi_sas: Reset PHY again if phyup timeout
  scsi: hisi_sas: Check usage count only when the runtime PM status is
    RPM_SUSPENDING
  scsi: hisi_sas: Add cond_resched() for no forced preemption model
  scsi: hisi_sas: Default enable interrupt coalescing
  scsi: hisi_sas: Create all dump files during debugfs initialization
  scsi: hisi_sas: Add latest_dump for the debugfs dump

libsas:
This series is to solve the problem of a BUG() when adding phy with zero
address to a new port.
  scsi: libsas: Add helper for port add ex_phy
  scsi: libsas: Move sas_add_parent_port() to sas_expander.c
  scsi: libsas: Set port when ex_phy is added or deleted
  scsi: libsas: Fix the failure of adding phy with zero-address to port 

scsi:
Make the SCSI core retry the START STOP UNIT command if the device
reports that it has been powered on or that it has been reset.
  scsi: sd: Retry START STOP UNIT commands
  scsi: core: Allow passthrough to request midlayer retries
 
 
Link:https://gitee.com/openeuler/kernel/pulls/13809

 

Reviewed-by: default avatarYihang Li <liyihang9@huawei.com>
Reviewed-by: default avatarZhang Peng <zhangpeng362@huawei.com>
Signed-off-by: default avatarZhang Peng <zhangpeng362@huawei.com>
parents 2daf2dcd 4a2a0c0c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -307,6 +307,7 @@ enum {

struct hisi_sas_hw {
	int (*hw_init)(struct hisi_hba *hisi_hba);
	int (*fw_info_check)(struct hisi_hba *hisi_hba);
	int (*interrupt_preinit)(struct hisi_hba *hisi_hba);
	void (*setup_itct)(struct hisi_hba *hisi_hba,
			   struct hisi_sas_device *device);
+27 −4
Original line number Diff line number Diff line
@@ -1320,6 +1320,7 @@ static int hisi_sas_softreset_ata_disk(struct domain_device *device)
	}

	if (rc == TMF_RESP_FUNC_COMPLETE) {
		usleep_range(900, 1000);
		ata_for_each_link(link, ap, EDGE) {
			int pmp = sata_srst_pmp(link);

@@ -1383,6 +1384,7 @@ static void hisi_sas_refresh_port_id(struct hisi_hba *hisi_hba)

static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 state)
{
	u32 new_state = hisi_hba->hw->get_phys_state(hisi_hba);
	struct asd_sas_port *_sas_port = NULL;
	int phy_no;

@@ -1396,7 +1398,7 @@ static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 state)
			continue;

		/* Report PHY state change to libsas */
		if (state & BIT(phy_no)) {
		if (new_state & BIT(phy_no)) {
			if (do_port_check && sas_port && sas_port->port_dev) {
				struct domain_device *dev = sas_port->port_dev;

@@ -1409,6 +1411,16 @@ static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 state)
			}
		} else {
			hisi_sas_phy_down(hisi_hba, phy_no, 0, GFP_KERNEL);

			/*
			 * The new_state is not ready but old_state is ready,
			 * the two possible causes:
			 * 1. The connected device is removed
			 * 2. Device exists but phyup timed out
			 */
			if (state & BIT(phy_no))
				hisi_sas_notify_phy_event(phy,
							  HISI_PHYE_LINK_RESET);
		}
	}
}
@@ -1544,9 +1556,15 @@ void hisi_sas_controller_reset_done(struct hisi_hba *hisi_hba)
	/* Init and wait for PHYs to come up and all libsas event finished. */
	for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) {
		struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
		struct asd_sas_phy *sas_phy = &phy->sas_phy;

		if (!(hisi_hba->phy_state & BIT(phy_no)))
		if (!sas_phy->phy->enabled)
			continue;

		if (!(hisi_hba->phy_state & BIT(phy_no))) {
			hisi_sas_phy_enable(hisi_hba, phy_no, 1);
			continue;
		}

		async_schedule_domain(hisi_sas_async_init_wait_phyup,
				      phy, &async);
@@ -2431,6 +2449,11 @@ static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev,
	if (hisi_sas_get_fw_info(hisi_hba) < 0)
		goto err_out;

	if (hisi_hba->hw->fw_info_check) {
		if (hisi_hba->hw->fw_info_check(hisi_hba))
			goto err_out;
	}

	error = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
	if (error) {
		dev_err(dev, "No usable DMA addressing method\n");
@@ -2611,10 +2634,10 @@ static __init int hisi_sas_init(void)

static __exit void hisi_sas_exit(void)
{
	sas_release_transport(hisi_sas_stt);

	if (hisi_sas_debugfs_enable)
		debugfs_remove(hisi_sas_debugfs_dir);

	sas_release_transport(hisi_sas_stt);
}

module_init(hisi_sas_init);
+18 −0
Original line number Diff line number Diff line
@@ -1734,6 +1734,23 @@ static struct attribute *host_v1_hw_attrs[] = {

ATTRIBUTE_GROUPS(host_v1_hw);

static int check_fw_info_v1_hw(struct hisi_hba *hisi_hba)
{
	struct device *dev = hisi_hba->dev;

	if (hisi_hba->n_phy < 0 || hisi_hba->n_phy > 9) {
		dev_err(dev, "invalid phy number from FW\n");
		return -EINVAL;
	}

	if (hisi_hba->queue_count < 0 || hisi_hba->queue_count > 32) {
		dev_err(dev, "invalid queue count from FW\n");
		return -EINVAL;
	}

	return 0;
}

static const struct scsi_host_template sht_v1_hw = {
	.name			= DRV_NAME,
	.proc_name		= DRV_NAME,
@@ -1763,6 +1780,7 @@ static const struct scsi_host_template sht_v1_hw = {

static const struct hisi_sas_hw hisi_sas_v1_hw = {
	.hw_init = hisi_sas_v1_init,
	.fw_info_check = check_fw_info_v1_hw,
	.setup_itct = setup_itct_v1_hw,
	.sl_notify_ssp = sl_notify_ssp_v1_hw,
	.clear_itct = clear_itct_v1_hw,
+18 −0
Original line number Diff line number Diff line
@@ -3561,6 +3561,23 @@ static void map_queues_v2_hw(struct Scsi_Host *shost)
	}
}

static int check_fw_info_v2_hw(struct hisi_hba *hisi_hba)
{
	struct device *dev = hisi_hba->dev;

	if (hisi_hba->n_phy < 0 || hisi_hba->n_phy > 9) {
		dev_err(dev, "invalid phy number from FW\n");
		return -EINVAL;
	}

	if (hisi_hba->queue_count < 0 || hisi_hba->queue_count > 16) {
		dev_err(dev, "invalid queue count from FW\n");
		return -EINVAL;
	}

	return 0;
}

static const struct scsi_host_template sht_v2_hw = {
	.name			= DRV_NAME,
	.proc_name		= DRV_NAME,
@@ -3592,6 +3609,7 @@ static const struct scsi_host_template sht_v2_hw = {

static const struct hisi_sas_hw hisi_sas_v2_hw = {
	.hw_init = hisi_sas_v2_init,
	.fw_info_check = check_fw_info_v2_hw,
	.interrupt_preinit = hisi_sas_v2_interrupt_preinit,
	.setup_itct = setup_itct_v2_hw,
	.slot_index_alloc = slot_index_alloc_quirk_v2_hw,
+138 −46
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@
#define CQ_INT_CONVERGE_EN		0xb0
#define CFG_AGING_TIME			0xbc
#define HGC_DFX_CFG2			0xc0
#define CFG_ICT_TIMER_STEP_TRSH		0xc8
#define CFG_ABT_SET_QUERY_IPTT	0xd4
#define CFG_SET_ABORTED_IPTT_OFF	0
#define CFG_SET_ABORTED_IPTT_MSK	(0xfff << CFG_SET_ABORTED_IPTT_OFF)
@@ -638,9 +639,12 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
	hisi_sas_write32(hisi_hba, TRANS_LOCK_ICT_TIME, 0x4A817C80);
	hisi_sas_write32(hisi_hba, HGC_SAS_TXFAIL_RETRY_CTRL, 0x108);
	hisi_sas_write32(hisi_hba, CFG_AGING_TIME, 0x1);
	hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x1);
	hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, 0x1);
	hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, 0x1);
	hisi_sas_write32(hisi_hba, CFG_ICT_TIMER_STEP_TRSH, 0xf4240);
	hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x3);
	/* configure the interrupt coalescing timeout period 10us */
	hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, 0xa);
	/* configure the count of CQ entries 10 */
	hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, 0xa);
	hisi_sas_write32(hisi_hba, CQ_INT_CONVERGE_EN,
			 hisi_sas_intr_conv);
	hisi_sas_write32(hisi_hba, OQ_INT_SRC, 0xffff);
@@ -682,7 +686,7 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
		hisi_sas_phy_write32(hisi_hba, i, PHY_CTRL_RDY_MSK, 0x0);
		hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_DWS_RESET_MSK, 0x0);
		hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_OOB_RESTART_MSK, 0x1);
		hisi_sas_phy_write32(hisi_hba, i, STP_LINK_TIMER, 0x7f7a120);
		hisi_sas_phy_write32(hisi_hba, i, STP_LINK_TIMER, 0x7ffffff);
		hisi_sas_phy_write32(hisi_hba, i, CON_CFG_DRIVER, 0x2a0a01);
		hisi_sas_phy_write32(hisi_hba, i, SAS_EC_INT_COAL_TIME,
				     0x30f4240);
@@ -2493,6 +2497,7 @@ static int complete_v3_hw(struct hisi_sas_cq *cq)
	/* update rd_point */
	cq->rd_point = rd_point;
	hisi_sas_write32(hisi_hba, COMPL_Q_0_RD_PTR + (0x14 * queue), rd_point);
	cond_resched();

	return completed;
}
@@ -2796,14 +2801,15 @@ static void config_intr_coal_v3_hw(struct hisi_hba *hisi_hba)
{
	/* config those registers between enable and disable PHYs */
	hisi_sas_stop_phys(hisi_hba);
	hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x3);

	if (hisi_hba->intr_coal_ticks == 0 ||
	    hisi_hba->intr_coal_count == 0) {
		hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x1);
		hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, 0x1);
		hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, 0x1);
		/* configure the interrupt coalescing timeout period 10us */
		hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, 0xa);
		/* configure the count of CQ entries 10 */
		hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, 0xa);
	} else {
		hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x3);
		hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME,
				 hisi_hba->intr_coal_ticks);
		hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT,
@@ -3390,6 +3396,23 @@ static const struct hisi_sas_hw hisi_sas_v3_hw = {
	.debugfs_snapshot_regs = debugfs_snapshot_regs_v3_hw,
};

static int check_fw_info_v3_hw(struct hisi_hba *hisi_hba)
{
	struct device *dev = hisi_hba->dev;

	if (hisi_hba->n_phy < 0 || hisi_hba->n_phy > 8) {
		dev_err(dev, "invalid phy number from FW\n");
		return -EINVAL;
	}

	if (hisi_hba->queue_count < 0 || hisi_hba->queue_count > 16) {
		dev_err(dev, "invalid queue count from FW\n");
		return -EINVAL;
	}

	return 0;
}

static struct Scsi_Host *
hisi_sas_shost_alloc_pci(struct pci_dev *pdev)
{
@@ -3420,6 +3443,9 @@ hisi_sas_shost_alloc_pci(struct pci_dev *pdev)
	if (hisi_sas_get_fw_info(hisi_hba) < 0)
		goto err_out;

	if (check_fw_info_v3_hw(hisi_hba) < 0)
		goto err_out;

	if (experimental_iopoll_q_cnt < 0 ||
		experimental_iopoll_q_cnt >= hisi_hba->queue_count)
		dev_err(dev, "iopoll queue count %d cannot exceed or equal 16, using default 0\n",
@@ -3569,6 +3595,11 @@ debugfs_to_reg_name_v3_hw(int off, int base_off,
	return NULL;
}

static bool debugfs_dump_is_generated_v3_hw(void *p)
{
	return p ? true : false;
}

static void debugfs_print_reg_v3_hw(u32 *regs_val, struct seq_file *s,
				    const struct hisi_sas_debugfs_reg *reg)
{
@@ -3594,6 +3625,9 @@ static int debugfs_global_v3_hw_show(struct seq_file *s, void *p)
{
	struct hisi_sas_debugfs_regs *global = s->private;

	if (!debugfs_dump_is_generated_v3_hw(global->data))
		return -EPERM;

	debugfs_print_reg_v3_hw(global->data, s,
				&debugfs_global_reg);

@@ -3605,6 +3639,9 @@ static int debugfs_axi_v3_hw_show(struct seq_file *s, void *p)
{
	struct hisi_sas_debugfs_regs *axi = s->private;

	if (!debugfs_dump_is_generated_v3_hw(axi->data))
		return -EPERM;

	debugfs_print_reg_v3_hw(axi->data, s,
				&debugfs_axi_reg);

@@ -3616,6 +3653,9 @@ static int debugfs_ras_v3_hw_show(struct seq_file *s, void *p)
{
	struct hisi_sas_debugfs_regs *ras = s->private;

	if (!debugfs_dump_is_generated_v3_hw(ras->data))
		return -EPERM;

	debugfs_print_reg_v3_hw(ras->data, s,
				&debugfs_ras_reg);

@@ -3628,6 +3668,9 @@ static int debugfs_port_v3_hw_show(struct seq_file *s, void *p)
	struct hisi_sas_debugfs_port *port = s->private;
	const struct hisi_sas_debugfs_reg *reg_port = &debugfs_port_reg;

	if (!debugfs_dump_is_generated_v3_hw(port->data))
		return -EPERM;

	debugfs_print_reg_v3_hw(port->data, s, reg_port);

	return 0;
@@ -3683,6 +3726,9 @@ static int debugfs_cq_v3_hw_show(struct seq_file *s, void *p)
	struct hisi_sas_debugfs_cq *debugfs_cq = s->private;
	int slot;

	if (!debugfs_dump_is_generated_v3_hw(debugfs_cq->complete_hdr))
		return -EPERM;

	for (slot = 0; slot < HISI_SAS_QUEUE_SLOTS; slot++)
		debugfs_cq_show_slot_v3_hw(s, slot, debugfs_cq);

@@ -3704,8 +3750,12 @@ static void debugfs_dq_show_slot_v3_hw(struct seq_file *s, int slot,

static int debugfs_dq_v3_hw_show(struct seq_file *s, void *p)
{
	struct hisi_sas_debugfs_dq *debugfs_dq = s->private;
	int slot;

	if (!debugfs_dump_is_generated_v3_hw(debugfs_dq->hdr))
		return -EPERM;

	for (slot = 0; slot < HISI_SAS_QUEUE_SLOTS; slot++)
		debugfs_dq_show_slot_v3_hw(s, slot, s->private);

@@ -3719,6 +3769,9 @@ static int debugfs_iost_v3_hw_show(struct seq_file *s, void *p)
	struct hisi_sas_iost *iost = debugfs_iost->iost;
	int i, max_command_entries = HISI_SAS_MAX_COMMANDS;

	if (!debugfs_dump_is_generated_v3_hw(iost))
		return -EPERM;

	for (i = 0; i < max_command_entries; i++, iost++) {
		__le64 *data = &iost->qw0;

@@ -3738,6 +3791,9 @@ static int debugfs_iost_cache_v3_hw_show(struct seq_file *s, void *p)
	int i, tab_idx;
	__le64 *iost;

	if (!debugfs_dump_is_generated_v3_hw(iost_cache))
		return -EPERM;

	for (i = 0; i < HISI_SAS_IOST_ITCT_CACHE_NUM; i++, iost_cache++) {
		/*
		 * Data struct of IOST cache:
@@ -3761,6 +3817,9 @@ static int debugfs_itct_v3_hw_show(struct seq_file *s, void *p)
	struct hisi_sas_debugfs_itct *debugfs_itct = s->private;
	struct hisi_sas_itct *itct = debugfs_itct->itct;

	if (!debugfs_dump_is_generated_v3_hw(itct))
		return -EPERM;

	for (i = 0; i < HISI_SAS_MAX_ITCT_ENTRIES; i++, itct++) {
		__le64 *data = &itct->qw0;

@@ -3780,6 +3839,9 @@ static int debugfs_itct_cache_v3_hw_show(struct seq_file *s, void *p)
	int i, tab_idx;
	__le64 *itct;

	if (!debugfs_dump_is_generated_v3_hw(itct_cache))
		return -EPERM;

	for (i = 0; i < HISI_SAS_IOST_ITCT_CACHE_NUM; i++, itct_cache++) {
		/*
		 * Data struct of ITCT cache:
@@ -3797,10 +3859,9 @@ static int debugfs_itct_cache_v3_hw_show(struct seq_file *s, void *p)
}
DEFINE_SHOW_ATTRIBUTE(debugfs_itct_cache_v3_hw);

static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba)
static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba, int index)
{
	u64 *debugfs_timestamp;
	int dump_index = hisi_hba->debugfs_dump_index;
	struct dentry *dump_dentry;
	struct dentry *dentry;
	char name[256];
@@ -3808,17 +3869,17 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba)
	int c;
	int d;

	snprintf(name, 256, "%d", dump_index);
	snprintf(name, 256, "%d", index);

	dump_dentry = debugfs_create_dir(name, hisi_hba->debugfs_dump_dentry);

	debugfs_timestamp = &hisi_hba->debugfs_timestamp[dump_index];
	debugfs_timestamp = &hisi_hba->debugfs_timestamp[index];

	debugfs_create_u64("timestamp", 0400, dump_dentry,
			   debugfs_timestamp);

	debugfs_create_file("global", 0400, dump_dentry,
			    &hisi_hba->debugfs_regs[dump_index][DEBUGFS_GLOBAL],
			    &hisi_hba->debugfs_regs[index][DEBUGFS_GLOBAL],
			    &debugfs_global_v3_hw_fops);

	/* Create port dir and files */
@@ -3827,7 +3888,7 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba)
		snprintf(name, 256, "%d", p);

		debugfs_create_file(name, 0400, dentry,
				    &hisi_hba->debugfs_port_reg[dump_index][p],
				    &hisi_hba->debugfs_port_reg[index][p],
				    &debugfs_port_v3_hw_fops);
	}

@@ -3837,7 +3898,7 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba)
		snprintf(name, 256, "%d", c);

		debugfs_create_file(name, 0400, dentry,
				    &hisi_hba->debugfs_cq[dump_index][c],
				    &hisi_hba->debugfs_cq[index][c],
				    &debugfs_cq_v3_hw_fops);
	}

@@ -3847,32 +3908,32 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba)
		snprintf(name, 256, "%d", d);

		debugfs_create_file(name, 0400, dentry,
				    &hisi_hba->debugfs_dq[dump_index][d],
				    &hisi_hba->debugfs_dq[index][d],
				    &debugfs_dq_v3_hw_fops);
	}

	debugfs_create_file("iost", 0400, dump_dentry,
			    &hisi_hba->debugfs_iost[dump_index],
			    &hisi_hba->debugfs_iost[index],
			    &debugfs_iost_v3_hw_fops);

	debugfs_create_file("iost_cache", 0400, dump_dentry,
			    &hisi_hba->debugfs_iost_cache[dump_index],
			    &hisi_hba->debugfs_iost_cache[index],
			    &debugfs_iost_cache_v3_hw_fops);

	debugfs_create_file("itct", 0400, dump_dentry,
			    &hisi_hba->debugfs_itct[dump_index],
			    &hisi_hba->debugfs_itct[index],
			    &debugfs_itct_v3_hw_fops);

	debugfs_create_file("itct_cache", 0400, dump_dentry,
			    &hisi_hba->debugfs_itct_cache[dump_index],
			    &hisi_hba->debugfs_itct_cache[index],
			    &debugfs_itct_cache_v3_hw_fops);

	debugfs_create_file("axi", 0400, dump_dentry,
			    &hisi_hba->debugfs_regs[dump_index][DEBUGFS_AXI],
			    &hisi_hba->debugfs_regs[index][DEBUGFS_AXI],
			    &debugfs_axi_v3_hw_fops);

	debugfs_create_file("ras", 0400, dump_dentry,
			    &hisi_hba->debugfs_regs[dump_index][DEBUGFS_RAS],
			    &hisi_hba->debugfs_regs[index][DEBUGFS_RAS],
			    &debugfs_ras_v3_hw_fops);
}

@@ -4654,22 +4715,34 @@ static void debugfs_release_v3_hw(struct hisi_hba *hisi_hba, int dump_index)
	int i;

	devm_kfree(dev, hisi_hba->debugfs_iost_cache[dump_index].cache);
	hisi_hba->debugfs_iost_cache[dump_index].cache = NULL;
	devm_kfree(dev, hisi_hba->debugfs_itct_cache[dump_index].cache);
	hisi_hba->debugfs_itct_cache[dump_index].cache = NULL;
	devm_kfree(dev, hisi_hba->debugfs_iost[dump_index].iost);
	hisi_hba->debugfs_iost[dump_index].iost = NULL;
	devm_kfree(dev, hisi_hba->debugfs_itct[dump_index].itct);
	hisi_hba->debugfs_itct[dump_index].itct = NULL;

	for (i = 0; i < hisi_hba->queue_count; i++)
	for (i = 0; i < hisi_hba->queue_count; i++) {
		devm_kfree(dev, hisi_hba->debugfs_dq[dump_index][i].hdr);
		hisi_hba->debugfs_dq[dump_index][i].hdr = NULL;
	}

	for (i = 0; i < hisi_hba->queue_count; i++)
	for (i = 0; i < hisi_hba->queue_count; i++) {
		devm_kfree(dev,
			   hisi_hba->debugfs_cq[dump_index][i].complete_hdr);
		hisi_hba->debugfs_cq[dump_index][i].complete_hdr = NULL;
	}

	for (i = 0; i < DEBUGFS_REGS_NUM; i++)
	for (i = 0; i < DEBUGFS_REGS_NUM; i++) {
		devm_kfree(dev, hisi_hba->debugfs_regs[dump_index][i].data);
		hisi_hba->debugfs_regs[dump_index][i].data = NULL;
	}

	for (i = 0; i < hisi_hba->n_phy; i++)
	for (i = 0; i < hisi_hba->n_phy; i++) {
		devm_kfree(dev, hisi_hba->debugfs_port_reg[dump_index][i].data);
		hisi_hba->debugfs_port_reg[dump_index][i].data = NULL;
	}
}

static const struct hisi_sas_debugfs_reg *debugfs_reg_array_v3_hw[DEBUGFS_REGS_NUM] = {
@@ -4796,8 +4869,6 @@ static int debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba)
	debugfs_snapshot_itct_reg_v3_hw(hisi_hba);
	debugfs_snapshot_iost_reg_v3_hw(hisi_hba);

	debugfs_create_files_v3_hw(hisi_hba);

	debugfs_snapshot_restore_v3_hw(hisi_hba);
	hisi_hba->debugfs_dump_index++;

@@ -4881,6 +4952,34 @@ static void debugfs_bist_init_v3_hw(struct hisi_hba *hisi_hba)
	hisi_hba->debugfs_bist_linkrate = SAS_LINK_RATE_1_5_GBPS;
}

static int debugfs_dump_index_v3_hw_show(struct seq_file *s, void *p)
{
	int *debugfs_dump_index = s->private;

	if (*debugfs_dump_index > 0)
		seq_printf(s, "%d\n", *debugfs_dump_index - 1);
	else
		seq_puts(s, "dump not triggered\n");

	return 0;
}
DEFINE_SHOW_ATTRIBUTE(debugfs_dump_index_v3_hw);

static void debugfs_dump_init_v3_hw(struct hisi_hba *hisi_hba)
{
	int i;

	hisi_hba->debugfs_dump_dentry =
			debugfs_create_dir("dump", hisi_hba->debugfs_dir);

	debugfs_create_file("latest_dump", 0400, hisi_hba->debugfs_dump_dentry,
			    &hisi_hba->debugfs_dump_index,
			    &debugfs_dump_index_v3_hw_fops);

	for (i = 0; i < hisi_sas_debugfs_dump_count; i++)
		debugfs_create_files_v3_hw(hisi_hba, i);
}

static void debugfs_exit_v3_hw(struct hisi_hba *hisi_hba)
{
	debugfs_remove_recursive(hisi_hba->debugfs_dir);
@@ -4893,19 +4992,17 @@ static void debugfs_init_v3_hw(struct hisi_hba *hisi_hba)

	hisi_hba->debugfs_dir = debugfs_create_dir(dev_name(dev),
						   hisi_sas_debugfs_dir);
	debugfs_create_file("trigger_dump", 0200,
			    hisi_hba->debugfs_dir,
			    hisi_hba,
			    &debugfs_trigger_dump_v3_hw_fops);

	/* create bist structures */
	debugfs_bist_init_v3_hw(hisi_hba);

	hisi_hba->debugfs_dump_dentry =
			debugfs_create_dir("dump", hisi_hba->debugfs_dir);
	debugfs_dump_init_v3_hw(hisi_hba);

	debugfs_phy_down_cnt_init_v3_hw(hisi_hba);
	debugfs_fifo_init_v3_hw(hisi_hba);
	debugfs_create_file("trigger_dump", 0200,
			    hisi_hba->debugfs_dir,
			    hisi_hba,
			    &debugfs_trigger_dump_v3_hw_fops);
}

static int
@@ -4998,16 +5095,13 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
					    SHOST_DIX_GUARD_CRC);
	}

	if (hisi_sas_debugfs_enable)
		debugfs_init_v3_hw(hisi_hba);

	rc = interrupt_preinit_v3_hw(hisi_hba);
	if (rc)
		goto err_out_undo_debugfs;
		goto err_out_free_host;

	rc = scsi_add_host(shost, dev);
	if (rc)
		goto err_out_undo_debugfs;
		goto err_out_free_host;

	rc = sas_register_ha(sha);
	if (rc)
@@ -5018,6 +5112,8 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
		goto err_out_unregister_ha;

	scsi_scan_host(shost);
	if (hisi_sas_debugfs_enable)
		debugfs_init_v3_hw(hisi_hba);

	pm_runtime_set_autosuspend_delay(dev, 5000);
	pm_runtime_use_autosuspend(dev);
@@ -5038,9 +5134,6 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
	sas_unregister_ha(sha);
err_out_remove_host:
	scsi_remove_host(shost);
err_out_undo_debugfs:
	if (hisi_sas_debugfs_enable)
		debugfs_exit_v3_hw(hisi_hba);
err_out_free_host:
	hisi_sas_free(hisi_hba);
	scsi_host_put(shost);
@@ -5072,6 +5165,8 @@ static void hisi_sas_v3_remove(struct pci_dev *pdev)
	struct Scsi_Host *shost = sha->shost;

	pm_runtime_get_noresume(dev);
	if (hisi_sas_debugfs_enable)
		debugfs_exit_v3_hw(hisi_hba);

	sas_unregister_ha(sha);
	flush_workqueue(hisi_hba->wq);
@@ -5079,9 +5174,6 @@ static void hisi_sas_v3_remove(struct pci_dev *pdev)

	hisi_sas_v3_destroy_irqs(pdev, hisi_hba);
	hisi_sas_free(hisi_hba);
	if (hisi_sas_debugfs_enable)
		debugfs_exit_v3_hw(hisi_hba);

	scsi_host_put(shost);
}

Loading