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

Commit 8fa4f177 authored by Matthew R. Ochs's avatar Matthew R. Ochs Committed by Martin K. Petersen
Browse files

scsi: cxlflash: Remove port configuration assumptions



At present, the cxlflash driver only supports hardware with two FC ports. The
code was initially designed with this assumption and is dependent on having
two FC ports - adding more ports will break logic within the driver.

To mitigate this issue, remove the existing port assumptions and transition
the code to support more than two ports. As a side effect, clarify the
interpretation of the DK_CXLFLASH_ALL_PORTS_ACTIVE flag.

Signed-off-by: default avatarMatthew R. Ochs <mrochs@linux.vnet.ibm.com>
Signed-off-by: default avatarUma Krishnan <ukrishn@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 78ae028e
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -239,6 +239,11 @@ DK_CXLFLASH_USER_VIRTUAL
    resource handle that is provided is already referencing provisioned
    storage. This is reflected by the last LBA being a non-zero value.

    When a LUN is accessible from more than one port, this ioctl will
    return with the DK_CXLFLASH_ALL_PORTS_ACTIVE return flag set. This
    provides the user with a hint that I/O can be retried in the event
    of an I/O error as the LUN can be reached over multiple paths.

DK_CXLFLASH_VLUN_RESIZE
-----------------------
    This ioctl is responsible for resizing a previously created virtual
+4 −0
Original line number Diff line number Diff line
@@ -29,6 +29,10 @@ extern const struct file_operations cxlflash_cxl_fops;
#define NUM_FC_PORTS	CXLFLASH_NUM_FC_PORTS	/* ports per AFU */
#define MAX_FC_PORTS	CXLFLASH_MAX_FC_PORTS	/* ports per AFU */

#define CHAN2PORTMASK(_x)	(1 << (_x))	/* channel to port mask */
#define PORTMASK2CHAN(_x)	(ilog2((_x)))	/* port mask to channel */
#define PORTNUM2CHAN(_x)	((_x) - 1)	/* port number to channel */

#define CXLFLASH_BLOCK_SIZE	4096	/* 4K blocks */
#define CXLFLASH_MAX_XFER_SIZE	16777216	/* 16MB transfer */
#define CXLFLASH_MAX_SECTORS	(CXLFLASH_MAX_XFER_SIZE/512)	/* SCSI wants
+2 −2
Original line number Diff line number Diff line
@@ -252,7 +252,7 @@ int cxlflash_manage_lun(struct scsi_device *sdev,
		 * in unpacked, AFU-friendly format, and hang LUN reference in
		 * the sdev.
		 */
		lli->port_sel |= CHAN2PORT(chan);
		lli->port_sel |= CHAN2PORTMASK(chan);
		lli->lun_id[chan] = lun_to_lunid(sdev->lun);
		sdev->hostdata = lli;
	} else if (flags & DK_CXLFLASH_MANAGE_LUN_DISABLE_SUPERPIPE) {
@@ -264,7 +264,7 @@ int cxlflash_manage_lun(struct scsi_device *sdev,
			 * tracking when no more references exist.
			 */
			sdev->hostdata = NULL;
			lli->port_sel &= ~CHAN2PORT(chan);
			lli->port_sel &= ~CHAN2PORTMASK(chan);
			if (lli->port_sel == 0U)
				lli->in_table = false;
		}
+6 −7
Original line number Diff line number Diff line
@@ -365,7 +365,6 @@ static int wait_resp(struct afu *afu, struct afu_cmd *cmd)
 */
static int send_tmf(struct afu *afu, struct scsi_cmnd *scp, u64 tmfcmd)
{
	u32 port_sel = scp->device->channel + 1;
	struct cxlflash_cfg *cfg = shost_priv(scp->device->host);
	struct afu_cmd *cmd = sc_to_afucz(scp);
	struct device *dev = &cfg->dev->dev;
@@ -388,7 +387,7 @@ static int send_tmf(struct afu *afu, struct scsi_cmnd *scp, u64 tmfcmd)

	cmd->rcb.ctx_id = afu->ctx_hndl;
	cmd->rcb.msi = SISL_MSI_RRQ_UPDATED;
	cmd->rcb.port_sel = port_sel;
	cmd->rcb.port_sel = CHAN2PORTMASK(scp->device->channel);
	cmd->rcb.lun_id = lun_to_lunid(scp->device->lun);
	cmd->rcb.req_flags = (SISL_REQ_FLAGS_PORT_LUN_ID |
			      SISL_REQ_FLAGS_SUP_UNDERRUN |
@@ -444,7 +443,6 @@ static int cxlflash_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scp)
	struct device *dev = &cfg->dev->dev;
	struct afu_cmd *cmd = sc_to_afucz(scp);
	struct scatterlist *sg = scsi_sglist(scp);
	u32 port_sel = scp->device->channel + 1;
	u16 req_flags = SISL_REQ_FLAGS_SUP_UNDERRUN;
	ulong lock_flags;
	int nseg = 0;
@@ -503,7 +501,7 @@ static int cxlflash_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scp)

	cmd->rcb.ctx_id = afu->ctx_hndl;
	cmd->rcb.msi = SISL_MSI_RRQ_UPDATED;
	cmd->rcb.port_sel = port_sel;
	cmd->rcb.port_sel = CHAN2PORTMASK(scp->device->channel);
	cmd->rcb.lun_id = lun_to_lunid(scp->device->lun);

	if (scp->sc_data_direction == DMA_TO_DEVICE)
@@ -1558,7 +1556,8 @@ static int init_global(struct cxlflash_cfg *cfg)
		writeq_be(PORT0, &afu->afu_map->global.regs.afu_port_sel);
		num_ports = 0;
	} else {
		writeq_be(BOTH_PORTS, &afu->afu_map->global.regs.afu_port_sel);
		writeq_be(PORT_MASK(cfg->num_fc_ports),
			  &afu->afu_map->global.regs.afu_port_sel);
		num_ports = cfg->num_fc_ports;
	}

@@ -2190,7 +2189,7 @@ static ssize_t lun_mode_store(struct device *dev,
		if (afu->internal_lun)
			shost->max_channel = 0;
		else
			shost->max_channel = cfg->num_fc_ports - 1;
			shost->max_channel = PORTNUM2CHAN(cfg->num_fc_ports);

		afu_reset(cfg);
		scsi_scan_host(cfg->host);
@@ -2529,7 +2528,7 @@ static int cxlflash_probe(struct pci_dev *pdev,

	host->max_id = CXLFLASH_MAX_NUM_TARGETS_PER_BUS;
	host->max_lun = CXLFLASH_MAX_NUM_LUNS_PER_TARGET;
	host->max_channel = NUM_FC_PORTS - 1;
	host->max_channel = PORTNUM2CHAN(NUM_FC_PORTS);
	host->unique_id = host->host_no;
	host->max_cmd_len = CXLFLASH_MAX_CDB_LEN;

+1 −1
Original line number Diff line number Diff line
@@ -479,7 +479,7 @@ struct sisl_rht_entry_f1 {

#define PORT0  0x01U
#define PORT1  0x02U
#define BOTH_PORTS    (PORT0 | PORT1)
#define PORT_MASK(_n)	((1 << (_n)) - 1)

/* AFU Sync Mode byte */
#define AFU_LW_SYNC 0x0U
Loading