mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 09:20:13 -04:00
scsi: ibmvfc: add NVMe/FC Process Login support
Extend PRLI handling code to support NVMe/FC targets. When the target protocol is NVMe/FC, issue the NVMe process login MAD, set the NVMe FC-4 type, and populate NVMe-specific service parameters. On completion, decode the returned PRLI service parameters and derive the appropriate remote-port roles for NVMe initiator, target, and discovery ports. Keep the existing SCSI PRLI flow unchanged while allowing the common target state machine to complete login for NVMe/FC targets. Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com> Link: https://patch.msgid.link/20260723000149.969416-19-tyreld@linux.ibm.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
committed by
Martin K. Petersen
parent
4bc896bf09
commit
d11c05ddc2
@@ -4090,11 +4090,12 @@ static void ibmvfc_tgt_prli_done(struct ibmvfc_event *evt)
|
||||
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE);
|
||||
switch (status) {
|
||||
case IBMVFC_MAD_SUCCESS:
|
||||
tgt_dbg(tgt, "Process Login succeeded: %X %02X %04X\n",
|
||||
parms->type, parms->flags, parms->service_parms);
|
||||
tgt_dbg(tgt, "%s Process Login succeeded: %X %02X %04X\n",
|
||||
proto_type[tgt->protocol], parms->type, parms->flags,
|
||||
parms->service_parms);
|
||||
|
||||
index = ibmvfc_get_prli_rsp(be16_to_cpu(parms->flags));
|
||||
if (parms->type == IBMVFC_SCSI_FCP_TYPE) {
|
||||
index = ibmvfc_get_prli_rsp(be16_to_cpu(parms->flags));
|
||||
if (prli_rsp[index].logged_in) {
|
||||
if (be16_to_cpu(parms->flags) & IBMVFC_PRLI_EST_IMG_PAIR) {
|
||||
tgt->need_login = 0;
|
||||
@@ -4110,6 +4111,22 @@ static void ibmvfc_tgt_prli_done(struct ibmvfc_event *evt)
|
||||
ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_prli);
|
||||
else
|
||||
ibmvfc_del_tgt(tgt);
|
||||
} else if (parms->type == IBMVFC_NVME_FCP_TYPE) {
|
||||
if (prli_rsp[index].logged_in) {
|
||||
/* For FC-NVMe PRLI the Image Pair field is always set to zero (see 6.3.3) */
|
||||
tgt->need_login = 0;
|
||||
tgt->ids.roles = 0;
|
||||
if (be32_to_cpu(parms->service_parms) & IBMVFC_PRLI_NVME_TARGET)
|
||||
tgt->ids.roles |= FC_PORT_ROLE_NVME_TARGET;
|
||||
if (be32_to_cpu(parms->service_parms) & IBMVFC_PRLI_NVME_INITIATOR)
|
||||
tgt->ids.roles |= FC_PORT_ROLE_NVME_INITIATOR;
|
||||
if (be32_to_cpu(parms->service_parms) & IBMVFC_PRLI_NVME_DISCOVERY)
|
||||
tgt->ids.roles |= FC_PORT_ROLE_NVME_DISCOVERY;
|
||||
tgt->add_rport = 1;
|
||||
} else if (prli_rsp[index].retry)
|
||||
ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_prli);
|
||||
else
|
||||
ibmvfc_del_tgt(tgt);
|
||||
} else
|
||||
ibmvfc_del_tgt(tgt);
|
||||
break;
|
||||
@@ -4130,9 +4147,10 @@ static void ibmvfc_tgt_prli_done(struct ibmvfc_event *evt)
|
||||
else
|
||||
ibmvfc_del_tgt(tgt);
|
||||
|
||||
tgt_log(tgt, level, "Process Login failed: %s (%x:%x) rc=0x%02X\n",
|
||||
ibmvfc_get_cmd_error(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)),
|
||||
be16_to_cpu(rsp->status), be16_to_cpu(rsp->error), status);
|
||||
tgt_log(tgt, level, "%s Process Login failed: %s (%x:%x) rc=0x%02X\n",
|
||||
proto_type[tgt->protocol], ibmvfc_get_cmd_error(be16_to_cpu(rsp->status),
|
||||
be16_to_cpu(rsp->error)), be16_to_cpu(rsp->status),
|
||||
be16_to_cpu(rsp->error), status);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -4174,25 +4192,30 @@ static void ibmvfc_tgt_send_prli(struct ibmvfc_target *tgt)
|
||||
} else {
|
||||
prli->common.version = cpu_to_be32(1);
|
||||
}
|
||||
prli->common.opcode = cpu_to_be32(IBMVFC_PROCESS_LOGIN);
|
||||
if (tgt->protocol == IBMVFC_PROTO_SCSI) {
|
||||
prli->common.opcode = cpu_to_be32(IBMVFC_PROCESS_LOGIN);
|
||||
prli->parms.type = IBMVFC_SCSI_FCP_TYPE;
|
||||
prli->parms.flags = cpu_to_be16(IBMVFC_PRLI_EST_IMG_PAIR);
|
||||
prli->parms.service_parms = cpu_to_be32(IBMVFC_PRLI_INITIATOR_FUNC);
|
||||
prli->parms.service_parms |= cpu_to_be32(IBMVFC_PRLI_READ_FCP_XFER_RDY_DISABLED);
|
||||
|
||||
if (cls3_error)
|
||||
prli->parms.service_parms |= cpu_to_be32(IBMVFC_PRLI_RETRY);
|
||||
} else {
|
||||
prli->common.opcode = cpu_to_be32(IBMVFC_NVMF_PROCESS_LOGIN);
|
||||
prli->parms.type = IBMVFC_NVME_FCP_TYPE;
|
||||
prli->parms.service_parms = cpu_to_be32(IBMVFC_PRLI_NVME_INITIATOR);
|
||||
}
|
||||
prli->common.length = cpu_to_be16(sizeof(*prli));
|
||||
prli->scsi_id = cpu_to_be64(tgt->scsi_id);
|
||||
|
||||
prli->parms.type = IBMVFC_SCSI_FCP_TYPE;
|
||||
prli->parms.flags = cpu_to_be16(IBMVFC_PRLI_EST_IMG_PAIR);
|
||||
prli->parms.service_parms = cpu_to_be32(IBMVFC_PRLI_INITIATOR_FUNC);
|
||||
prli->parms.service_parms |= cpu_to_be32(IBMVFC_PRLI_READ_FCP_XFER_RDY_DISABLED);
|
||||
|
||||
if (cls3_error)
|
||||
prli->parms.service_parms |= cpu_to_be32(IBMVFC_PRLI_RETRY);
|
||||
|
||||
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT);
|
||||
if (ibmvfc_send_event(evt, vhost, default_timeout)) {
|
||||
vhost->discovery_threads--;
|
||||
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE);
|
||||
kref_put(&tgt->kref, ibmvfc_release_tgt);
|
||||
} else
|
||||
tgt_dbg(tgt, "Sent process login\n");
|
||||
tgt_dbg(tgt, "%s Sent process login\n", proto_type[tgt->protocol]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -381,6 +381,7 @@ struct ibmvfc_move_login {
|
||||
struct ibmvfc_prli_svc_parms {
|
||||
u8 type;
|
||||
#define IBMVFC_SCSI_FCP_TYPE 0x08
|
||||
#define IBMVFC_NVME_FCP_TYPE 0x28
|
||||
u8 type_ext;
|
||||
__be16 flags;
|
||||
#define IBMVFC_PRLI_ORIG_PA_VALID 0x8000
|
||||
@@ -396,6 +397,11 @@ struct ibmvfc_prli_svc_parms {
|
||||
#define IBMVFC_PRLI_TARGET_FUNC 0x00000010
|
||||
#define IBMVFC_PRLI_READ_FCP_XFER_RDY_DISABLED 0x00000002
|
||||
#define IBMVFC_PRLI_WR_FCP_XFER_RDY_DISABLED 0x00000001
|
||||
#define IBMVFC_PRLI_NVME_PI_CTRL 0x00000200
|
||||
#define IBMVFC_PRLI_NVME_SLER 0x00000100
|
||||
#define IBMVFC_PRLI_NVME_INITIATOR 0x00000020
|
||||
#define IBMVFC_PRLI_NVME_TARGET 0x00000010
|
||||
#define IBMVFC_PRLI_NVME_DISCOVERY 0x00000008
|
||||
} __packed __aligned(4);
|
||||
|
||||
struct ibmvfc_process_login {
|
||||
|
||||
Reference in New Issue
Block a user