Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ef51074a authored by Matthew R. Ochs's avatar Matthew R. Ochs Committed by James Bottomley
Browse files

cxlflash: Fix host link up event handling



Following a link up event, the LUNs available to the host may
have changed. Without rescanning the host, the LUN topology is
unknown to the user. In such a state, the user would be unable
to locate provisioned resources.

To remedy, the host should be rescanned after a link up event.

Signed-off-by: default avatarMatthew R. Ochs <mrochs@linux.vnet.ibm.com>
Signed-off-by: default avatarManoj N. Kumar <manoj@linux.vnet.ibm.com>
Reviewed-by: default avatarBrian King <brking@linux.vnet.ibm.com>
Reviewed-by: default avatarTomas Henzl <thenzl@redhat.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Odin.com>
parent 8396012f
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -102,6 +102,7 @@ struct cxlflash_cfg {
	enum cxlflash_init_state init_state;
	enum cxlflash_init_state init_state;
	enum cxlflash_lr_state lr_state;
	enum cxlflash_lr_state lr_state;
	int lr_port;
	int lr_port;
	atomic_t scan_host_needed;


	struct cxl_afu *cxl_afu;
	struct cxl_afu *cxl_afu;


+13 −4
Original line number Original line Diff line number Diff line
@@ -1119,17 +1119,17 @@ static const struct asyc_intr_info ainfo[] = {
	{SISL_ASTATUS_FC0_CRC_T, "CRC threshold exceeded", 0, LINK_RESET},
	{SISL_ASTATUS_FC0_CRC_T, "CRC threshold exceeded", 0, LINK_RESET},
	{SISL_ASTATUS_FC0_LOGI_R, "login timed out, retrying", 0, 0},
	{SISL_ASTATUS_FC0_LOGI_R, "login timed out, retrying", 0, 0},
	{SISL_ASTATUS_FC0_LOGI_F, "login failed", 0, CLR_FC_ERROR},
	{SISL_ASTATUS_FC0_LOGI_F, "login failed", 0, CLR_FC_ERROR},
	{SISL_ASTATUS_FC0_LOGI_S, "login succeeded", 0, 0},
	{SISL_ASTATUS_FC0_LOGI_S, "login succeeded", 0, SCAN_HOST},
	{SISL_ASTATUS_FC0_LINK_DN, "link down", 0, 0},
	{SISL_ASTATUS_FC0_LINK_DN, "link down", 0, 0},
	{SISL_ASTATUS_FC0_LINK_UP, "link up", 0, 0},
	{SISL_ASTATUS_FC0_LINK_UP, "link up", 0, SCAN_HOST},
	{SISL_ASTATUS_FC1_OTHER, "other error", 1, CLR_FC_ERROR | LINK_RESET},
	{SISL_ASTATUS_FC1_OTHER, "other error", 1, CLR_FC_ERROR | LINK_RESET},
	{SISL_ASTATUS_FC1_LOGO, "target initiated LOGO", 1, 0},
	{SISL_ASTATUS_FC1_LOGO, "target initiated LOGO", 1, 0},
	{SISL_ASTATUS_FC1_CRC_T, "CRC threshold exceeded", 1, LINK_RESET},
	{SISL_ASTATUS_FC1_CRC_T, "CRC threshold exceeded", 1, LINK_RESET},
	{SISL_ASTATUS_FC1_LOGI_R, "login timed out, retrying", 1, 0},
	{SISL_ASTATUS_FC1_LOGI_R, "login timed out, retrying", 1, 0},
	{SISL_ASTATUS_FC1_LOGI_F, "login failed", 1, CLR_FC_ERROR},
	{SISL_ASTATUS_FC1_LOGI_F, "login failed", 1, CLR_FC_ERROR},
	{SISL_ASTATUS_FC1_LOGI_S, "login succeeded", 1, 0},
	{SISL_ASTATUS_FC1_LOGI_S, "login succeeded", 1, SCAN_HOST},
	{SISL_ASTATUS_FC1_LINK_DN, "link down", 1, 0},
	{SISL_ASTATUS_FC1_LINK_DN, "link down", 1, 0},
	{SISL_ASTATUS_FC1_LINK_UP, "link up", 1, 0},
	{SISL_ASTATUS_FC1_LINK_UP, "link up", 1, SCAN_HOST},
	{0x0, "", 0, 0}		/* terminator */
	{0x0, "", 0, 0}		/* terminator */
};
};


@@ -1350,6 +1350,11 @@ static irqreturn_t cxlflash_async_err_irq(int irq, void *data)
			writeq_be(reg, &global->fc_regs[port][FC_ERROR / 8]);
			writeq_be(reg, &global->fc_regs[port][FC_ERROR / 8]);
			writeq_be(0, &global->fc_regs[port][FC_ERRCAP / 8]);
			writeq_be(0, &global->fc_regs[port][FC_ERRCAP / 8]);
		}
		}

		if (info->action & SCAN_HOST) {
			atomic_inc(&cfg->scan_host_needed);
			schedule_work(&cfg->work_q);
		}
	}
	}


out:
out:
@@ -2309,6 +2314,7 @@ MODULE_DEVICE_TABLE(pci, cxlflash_pci_table);
 * - Link reset which cannot be performed on interrupt context due to
 * - Link reset which cannot be performed on interrupt context due to
 * blocking up to a few seconds
 * blocking up to a few seconds
 * - Read AFU command room
 * - Read AFU command room
 * - Rescan the host
 */
 */
static void cxlflash_worker_thread(struct work_struct *work)
static void cxlflash_worker_thread(struct work_struct *work)
{
{
@@ -2351,6 +2357,9 @@ static void cxlflash_worker_thread(struct work_struct *work)
	}
	}


	spin_unlock_irqrestore(cfg->host->host_lock, lock_flags);
	spin_unlock_irqrestore(cfg->host->host_lock, lock_flags);

	if (atomic_dec_if_positive(&cfg->scan_host_needed) >= 0)
		scsi_scan_host(cfg->host);
}
}


/**
/**
+1 −0
Original line number Original line Diff line number Diff line
@@ -99,6 +99,7 @@ struct asyc_intr_info {
	u8 action;
	u8 action;
#define CLR_FC_ERROR	0x01
#define CLR_FC_ERROR	0x01
#define LINK_RESET	0x02
#define LINK_RESET	0x02
#define SCAN_HOST	0x04
};
};


#ifndef CONFIG_CXL_EEH
#ifndef CONFIG_CXL_EEH