Commit ebc7c74b authored by Tyrel Datwyler's avatar Tyrel Datwyler Committed by Martin K. Petersen

scsi: ibmvfc: Add support for target_wwpn field in v2 MADs and vfcFrame

Several version 2 MADs and the version 2 vfcFrame structures introduced a
new targetWWPN field for better identification of a target over the
scsi_id.

Set this field and MAD versioning fields when the VIOS advertises the
IBMVFC_HANDLE_VF_WWPN capability.

Link: https://lore.kernel.org/r/20201118011104.296999-6-tyreld@linux.ibm.comAcked-by: default avatarBrian King <brking@linux.vnet.ibm.com>
Signed-off-by: default avatarTyrel Datwyler <tyreld@linux.ibm.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 5a9d16f7
...@@ -1685,9 +1685,10 @@ static struct ibmvfc_cmd *ibmvfc_init_vfc_cmd(struct ibmvfc_event *evt, struct s ...@@ -1685,9 +1685,10 @@ static struct ibmvfc_cmd *ibmvfc_init_vfc_cmd(struct ibmvfc_event *evt, struct s
size_t offset; size_t offset;
memset(vfc_cmd, 0, sizeof(*vfc_cmd)); memset(vfc_cmd, 0, sizeof(*vfc_cmd));
if (ibmvfc_check_caps(vhost, IBMVFC_HANDLE_VF_WWPN)) if (ibmvfc_check_caps(vhost, IBMVFC_HANDLE_VF_WWPN)) {
offset = offsetof(struct ibmvfc_cmd, v2.rsp); offset = offsetof(struct ibmvfc_cmd, v2.rsp);
else vfc_cmd->target_wwpn = cpu_to_be64(rport->port_name);
} else
offset = offsetof(struct ibmvfc_cmd, v1.rsp); offset = offsetof(struct ibmvfc_cmd, v1.rsp);
vfc_cmd->resp.va = cpu_to_be64(be64_to_cpu(evt->crq.ioba) + offset); vfc_cmd->resp.va = cpu_to_be64(be64_to_cpu(evt->crq.ioba) + offset);
vfc_cmd->resp.len = cpu_to_be32(sizeof(*rsp)); vfc_cmd->resp.len = cpu_to_be32(sizeof(*rsp));
...@@ -2064,6 +2065,7 @@ static int ibmvfc_bsg_request(struct bsg_job *job) ...@@ -2064,6 +2065,7 @@ static int ibmvfc_bsg_request(struct bsg_job *job)
static int ibmvfc_reset_device(struct scsi_device *sdev, int type, char *desc) static int ibmvfc_reset_device(struct scsi_device *sdev, int type, char *desc)
{ {
struct ibmvfc_host *vhost = shost_priv(sdev->host); struct ibmvfc_host *vhost = shost_priv(sdev->host);
struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
struct ibmvfc_cmd *tmf; struct ibmvfc_cmd *tmf;
struct ibmvfc_event *evt = NULL; struct ibmvfc_event *evt = NULL;
union ibmvfc_iu rsp_iu; union ibmvfc_iu rsp_iu;
...@@ -2081,6 +2083,8 @@ static int ibmvfc_reset_device(struct scsi_device *sdev, int type, char *desc) ...@@ -2081,6 +2083,8 @@ static int ibmvfc_reset_device(struct scsi_device *sdev, int type, char *desc)
iu = ibmvfc_get_fcp_iu(vhost, tmf); iu = ibmvfc_get_fcp_iu(vhost, tmf);
tmf->flags = cpu_to_be16((IBMVFC_NO_MEM_DESC | IBMVFC_TMF)); tmf->flags = cpu_to_be16((IBMVFC_NO_MEM_DESC | IBMVFC_TMF));
if (ibmvfc_check_caps(vhost, IBMVFC_HANDLE_VF_WWPN))
tmf->target_wwpn = cpu_to_be64(rport->port_name);
iu->tmf_flags = type; iu->tmf_flags = type;
evt->sync_iu = &rsp_iu; evt->sync_iu = &rsp_iu;
...@@ -2271,7 +2275,12 @@ static int ibmvfc_cancel_all(struct scsi_device *sdev, int type) ...@@ -2271,7 +2275,12 @@ static int ibmvfc_cancel_all(struct scsi_device *sdev, int type)
tmf = &evt->iu.tmf; tmf = &evt->iu.tmf;
memset(tmf, 0, sizeof(*tmf)); memset(tmf, 0, sizeof(*tmf));
tmf->common.version = cpu_to_be32(1); if (ibmvfc_check_caps(vhost, IBMVFC_HANDLE_VF_WWPN)) {
tmf->common.version = cpu_to_be32(2);
tmf->target_wwpn = cpu_to_be64(rport->port_name);
} else {
tmf->common.version = cpu_to_be32(1);
}
tmf->common.opcode = cpu_to_be32(IBMVFC_TMF_MAD); tmf->common.opcode = cpu_to_be32(IBMVFC_TMF_MAD);
tmf->common.length = cpu_to_be16(sizeof(*tmf)); tmf->common.length = cpu_to_be16(sizeof(*tmf));
tmf->scsi_id = cpu_to_be64(rport->port_id); tmf->scsi_id = cpu_to_be64(rport->port_id);
...@@ -2371,6 +2380,7 @@ static int ibmvfc_match_evt(struct ibmvfc_event *evt, void *match) ...@@ -2371,6 +2380,7 @@ static int ibmvfc_match_evt(struct ibmvfc_event *evt, void *match)
static int ibmvfc_abort_task_set(struct scsi_device *sdev) static int ibmvfc_abort_task_set(struct scsi_device *sdev)
{ {
struct ibmvfc_host *vhost = shost_priv(sdev->host); struct ibmvfc_host *vhost = shost_priv(sdev->host);
struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
struct ibmvfc_cmd *tmf; struct ibmvfc_cmd *tmf;
struct ibmvfc_event *evt, *found_evt; struct ibmvfc_event *evt, *found_evt;
union ibmvfc_iu rsp_iu; union ibmvfc_iu rsp_iu;
...@@ -2402,6 +2412,8 @@ static int ibmvfc_abort_task_set(struct scsi_device *sdev) ...@@ -2402,6 +2412,8 @@ static int ibmvfc_abort_task_set(struct scsi_device *sdev)
tmf = ibmvfc_init_vfc_cmd(evt, sdev); tmf = ibmvfc_init_vfc_cmd(evt, sdev);
iu = ibmvfc_get_fcp_iu(vhost, tmf); iu = ibmvfc_get_fcp_iu(vhost, tmf);
if (ibmvfc_check_caps(vhost, IBMVFC_HANDLE_VF_WWPN))
tmf->target_wwpn = cpu_to_be64(rport->port_name);
iu->tmf_flags = IBMVFC_ABORT_TASK_SET; iu->tmf_flags = IBMVFC_ABORT_TASK_SET;
tmf->flags = cpu_to_be16((IBMVFC_NO_MEM_DESC | IBMVFC_TMF)); tmf->flags = cpu_to_be16((IBMVFC_NO_MEM_DESC | IBMVFC_TMF));
evt->sync_iu = &rsp_iu; evt->sync_iu = &rsp_iu;
...@@ -3483,7 +3495,12 @@ static void ibmvfc_tgt_send_prli(struct ibmvfc_target *tgt) ...@@ -3483,7 +3495,12 @@ static void ibmvfc_tgt_send_prli(struct ibmvfc_target *tgt)
evt->tgt = tgt; evt->tgt = tgt;
prli = &evt->iu.prli; prli = &evt->iu.prli;
memset(prli, 0, sizeof(*prli)); memset(prli, 0, sizeof(*prli));
prli->common.version = cpu_to_be32(1); if (ibmvfc_check_caps(vhost, IBMVFC_HANDLE_VF_WWPN)) {
prli->common.version = cpu_to_be32(2);
prli->target_wwpn = cpu_to_be64(tgt->wwpn);
} else {
prli->common.version = cpu_to_be32(1);
}
prli->common.opcode = cpu_to_be32(IBMVFC_PROCESS_LOGIN); prli->common.opcode = cpu_to_be32(IBMVFC_PROCESS_LOGIN);
prli->common.length = cpu_to_be16(sizeof(*prli)); prli->common.length = cpu_to_be16(sizeof(*prli));
prli->scsi_id = cpu_to_be64(tgt->scsi_id); prli->scsi_id = cpu_to_be64(tgt->scsi_id);
...@@ -3586,7 +3603,12 @@ static void ibmvfc_tgt_send_plogi(struct ibmvfc_target *tgt) ...@@ -3586,7 +3603,12 @@ static void ibmvfc_tgt_send_plogi(struct ibmvfc_target *tgt)
evt->tgt = tgt; evt->tgt = tgt;
plogi = &evt->iu.plogi; plogi = &evt->iu.plogi;
memset(plogi, 0, sizeof(*plogi)); memset(plogi, 0, sizeof(*plogi));
plogi->common.version = cpu_to_be32(1); if (ibmvfc_check_caps(vhost, IBMVFC_HANDLE_VF_WWPN)) {
plogi->common.version = cpu_to_be32(2);
plogi->target_wwpn = cpu_to_be64(tgt->wwpn);
} else {
plogi->common.version = cpu_to_be32(1);
}
plogi->common.opcode = cpu_to_be32(IBMVFC_PORT_LOGIN); plogi->common.opcode = cpu_to_be32(IBMVFC_PORT_LOGIN);
plogi->common.length = cpu_to_be16(sizeof(*plogi)); plogi->common.length = cpu_to_be16(sizeof(*plogi));
plogi->scsi_id = cpu_to_be64(tgt->scsi_id); plogi->scsi_id = cpu_to_be64(tgt->scsi_id);
...@@ -3986,7 +4008,12 @@ static void ibmvfc_adisc_timeout(struct timer_list *t) ...@@ -3986,7 +4008,12 @@ static void ibmvfc_adisc_timeout(struct timer_list *t)
evt->tgt = tgt; evt->tgt = tgt;
tmf = &evt->iu.tmf; tmf = &evt->iu.tmf;
memset(tmf, 0, sizeof(*tmf)); memset(tmf, 0, sizeof(*tmf));
tmf->common.version = cpu_to_be32(1); if (ibmvfc_check_caps(vhost, IBMVFC_HANDLE_VF_WWPN)) {
tmf->common.version = cpu_to_be32(2);
tmf->target_wwpn = cpu_to_be64(tgt->wwpn);
} else {
tmf->common.version = cpu_to_be32(1);
}
tmf->common.opcode = cpu_to_be32(IBMVFC_TMF_MAD); tmf->common.opcode = cpu_to_be32(IBMVFC_TMF_MAD);
tmf->common.length = cpu_to_be16(sizeof(*tmf)); tmf->common.length = cpu_to_be16(sizeof(*tmf));
tmf->scsi_id = cpu_to_be64(tgt->scsi_id); tmf->scsi_id = cpu_to_be64(tgt->scsi_id);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment