2020-11-12 01:45:26

by Tyrel Datwyler

[permalink] [raw]
Subject: [PATCH 1/6] ibmvfc: byte swap login_buf.resp values in attribute show functions

Both ibmvfc_show_host_(capabilities|npiv_version) functions retrieve
values from vhost->login_buf.resp buffer. This is the MAD response
buffer from the VIOS and as such any multi-byte non-string values are in
big endian format.

Byte swap these values to host cpu endian format for better human
readability.

Signed-off-by: Tyrel Datwyler <[email protected]>
---
drivers/scsi/ibmvscsi/ibmvfc.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 070cf516b98f..01fe65de9086 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -3025,7 +3025,7 @@ static ssize_t ibmvfc_show_host_npiv_version(struct device *dev,
{
struct Scsi_Host *shost = class_to_shost(dev);
struct ibmvfc_host *vhost = shost_priv(shost);
- return snprintf(buf, PAGE_SIZE, "%d\n", vhost->login_buf->resp.version);
+ return snprintf(buf, PAGE_SIZE, "%d\n", be32_to_cpu(vhost->login_buf->resp.version));
}

static ssize_t ibmvfc_show_host_capabilities(struct device *dev,
@@ -3033,7 +3033,7 @@ static ssize_t ibmvfc_show_host_capabilities(struct device *dev,
{
struct Scsi_Host *shost = class_to_shost(dev);
struct ibmvfc_host *vhost = shost_priv(shost);
- return snprintf(buf, PAGE_SIZE, "%llx\n", vhost->login_buf->resp.capabilities);
+ return snprintf(buf, PAGE_SIZE, "%llx\n", be64_to_cpu(vhost->login_buf->resp.capabilities));
}

/**
--
2.27.0


2020-11-12 01:45:43

by Tyrel Datwyler

[permalink] [raw]
Subject: [PATCH 4/6] ibmvfc: add FC payload retrieval routines for versioned vfcFrames

The FC iu and response payloads are located at different offsets
depending on the ibmvfc_cmd version. This is a result of the version 2
vfcFrame definition adding an extra 64bytes of reserved space to the
structure prior to the payloads.

Add helper routines to determine the current vfcFrame version and
returning pointers to the proper iu or response structures within that
ibmvfc_cmd.

Signed-off-by: Tyrel Datwyler <[email protected]>
---
drivers/scsi/ibmvscsi/ibmvfc.c | 76 ++++++++++++++++++++++++----------
1 file changed, 53 insertions(+), 23 deletions(-)

diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index aa3445bec42c..5e666f7c9266 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -138,6 +138,22 @@ static void ibmvfc_tgt_move_login(struct ibmvfc_target *);

static const char *unknown_error = "unknown error";

+static struct ibmvfc_fcp_cmd_iu *ibmvfc_get_fcp_iu(struct ibmvfc_host *vhost, struct ibmvfc_cmd *vfc_cmd)
+{
+ if (be64_to_cpu(vhost->login_buf->resp.capabilities) & IBMVFC_HANDLE_VF_WWPN)
+ return &vfc_cmd->v2.iu;
+ else
+ return &vfc_cmd->v1.iu;
+}
+
+static struct ibmvfc_fcp_rsp *ibmvfc_get_fcp_rsp(struct ibmvfc_host *vhost, struct ibmvfc_cmd *vfc_cmd)
+{
+ if (be64_to_cpu(vhost->login_buf->resp.capabilities) & IBMVFC_HANDLE_VF_WWPN)
+ return &vfc_cmd->v2.rsp;
+ else
+ return &vfc_cmd->v1.rsp;
+}
+
#ifdef CONFIG_SCSI_IBMVFC_TRACE
/**
* ibmvfc_trc_start - Log a start trace entry
@@ -149,7 +165,7 @@ static void ibmvfc_trc_start(struct ibmvfc_event *evt)
struct ibmvfc_host *vhost = evt->vhost;
struct ibmvfc_cmd *vfc_cmd = &evt->iu.cmd;
struct ibmvfc_mad_common *mad = &evt->iu.mad_common;
- struct ibmvfc_fcp_cmd_iu *iu = &vfc_cmd->v1.iu;
+ struct ibmvfc_fcp_cmd_iu *iu = ibmvfc_get_fcp_iu(vhost, vfc_cmd);
struct ibmvfc_trace_entry *entry;

entry = &vhost->trace[vhost->trace_index++];
@@ -184,8 +200,8 @@ static void ibmvfc_trc_end(struct ibmvfc_event *evt)
struct ibmvfc_host *vhost = evt->vhost;
struct ibmvfc_cmd *vfc_cmd = &evt->xfer_iu->cmd;
struct ibmvfc_mad_common *mad = &evt->xfer_iu->mad_common;
- struct ibmvfc_fcp_cmd_iu *iu = &vfc_cmd->v1.iu;
- struct ibmvfc_fcp_rsp *rsp = &vfc_cmd->v1.rsp;
+ struct ibmvfc_fcp_cmd_iu *iu = ibmvfc_get_fcp_iu(vhost, vfc_cmd);
+ struct ibmvfc_fcp_rsp *rsp = ibmvfc_get_fcp_rsp(vhost, vfc_cmd);
struct ibmvfc_trace_entry *entry = &vhost->trace[vhost->trace_index++];

entry->evt = evt;
@@ -263,10 +279,10 @@ static const char *ibmvfc_get_cmd_error(u16 status, u16 error)
* Return value:
* SCSI result value to return for completed command
**/
-static int ibmvfc_get_err_result(struct ibmvfc_cmd *vfc_cmd)
+static int ibmvfc_get_err_result(struct ibmvfc_host *vhost, struct ibmvfc_cmd *vfc_cmd)
{
int err;
- struct ibmvfc_fcp_rsp *rsp = &vfc_cmd->v1.rsp;
+ struct ibmvfc_fcp_rsp *rsp = ibmvfc_get_fcp_rsp(vhost, vfc_cmd);
int fc_rsp_len = be32_to_cpu(rsp->fcp_rsp_len);

if ((rsp->flags & FCP_RSP_LEN_VALID) &&
@@ -1381,7 +1397,7 @@ static int ibmvfc_map_sg_data(struct scsi_cmnd *scmd,
int sg_mapped;
struct srp_direct_buf *data = &vfc_cmd->ioba;
struct ibmvfc_host *vhost = dev_get_drvdata(dev);
- struct ibmvfc_fcp_cmd_iu *iu = &vfc_cmd->v1.iu;
+ struct ibmvfc_fcp_cmd_iu *iu = ibmvfc_get_fcp_iu(evt->vhost, vfc_cmd);

if (cls3_error)
vfc_cmd->flags |= cpu_to_be16(IBMVFC_CLASS_3_ERR);
@@ -1520,7 +1536,7 @@ static void ibmvfc_log_error(struct ibmvfc_event *evt)
{
struct ibmvfc_cmd *vfc_cmd = &evt->xfer_iu->cmd;
struct ibmvfc_host *vhost = evt->vhost;
- struct ibmvfc_fcp_rsp *rsp = &vfc_cmd->v1.rsp;
+ struct ibmvfc_fcp_rsp *rsp = ibmvfc_get_fcp_rsp(vhost, vfc_cmd);
struct scsi_cmnd *cmnd = evt->cmnd;
const char *err = unknown_error;
int index = ibmvfc_get_err_index(be16_to_cpu(vfc_cmd->status), be16_to_cpu(vfc_cmd->error));
@@ -1574,7 +1590,7 @@ static void ibmvfc_relogin(struct scsi_device *sdev)
static void ibmvfc_scsi_done(struct ibmvfc_event *evt)
{
struct ibmvfc_cmd *vfc_cmd = &evt->xfer_iu->cmd;
- struct ibmvfc_fcp_rsp *rsp = &vfc_cmd->v1.rsp;
+ struct ibmvfc_fcp_rsp *rsp = ibmvfc_get_fcp_rsp(evt->vhost, vfc_cmd);
struct scsi_cmnd *cmnd = evt->cmnd;
u32 rsp_len = 0;
u32 sense_len = be32_to_cpu(rsp->fcp_sense_len);
@@ -1588,7 +1604,7 @@ static void ibmvfc_scsi_done(struct ibmvfc_event *evt)
scsi_set_resid(cmnd, 0);

if (vfc_cmd->status) {
- cmnd->result = ibmvfc_get_err_result(vfc_cmd);
+ cmnd->result = ibmvfc_get_err_result(evt->vhost, vfc_cmd);

if (rsp->flags & FCP_RSP_LEN_VALID)
rsp_len = be32_to_cpu(rsp->fcp_rsp_len);
@@ -1653,17 +1669,25 @@ static inline int ibmvfc_host_chkready(struct ibmvfc_host *vhost)
static struct ibmvfc_cmd *ibmvfc_init_vfc_cmd(struct ibmvfc_event *evt, struct scsi_device *sdev)
{
struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
+ struct ibmvfc_host *vhost = evt->vhost;
struct ibmvfc_cmd *vfc_cmd = &evt->iu.cmd;
+ struct ibmvfc_fcp_cmd_iu *iu = ibmvfc_get_fcp_iu(vhost, vfc_cmd);
+ struct ibmvfc_fcp_rsp *rsp = ibmvfc_get_fcp_rsp(vhost, vfc_cmd);
+ size_t offset;

memset(vfc_cmd, 0, sizeof(*vfc_cmd));
- vfc_cmd->resp.va = cpu_to_be64(be64_to_cpu(evt->crq.ioba) + offsetof(struct ibmvfc_cmd, v1.rsp));
- vfc_cmd->resp.len = cpu_to_be32(sizeof(vfc_cmd->v1.rsp));
+ if (be64_to_cpu(vhost->login_buf->resp.capabilities) & IBMVFC_HANDLE_VF_WWPN)
+ offset = offsetof(struct ibmvfc_cmd, v2.rsp);
+ else
+ offset = offsetof(struct ibmvfc_cmd, v1.rsp);
+ 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->frame_type = cpu_to_be32(IBMVFC_SCSI_FCP_TYPE);
- vfc_cmd->payload_len = cpu_to_be32(sizeof(vfc_cmd->v1.iu));
- vfc_cmd->resp_len = cpu_to_be32(sizeof(vfc_cmd->v1.rsp));
+ vfc_cmd->payload_len = cpu_to_be32(sizeof(*iu));
+ vfc_cmd->resp_len = cpu_to_be32(sizeof(*rsp));
vfc_cmd->cancel_key = cpu_to_be32((unsigned long)sdev->hostdata);
vfc_cmd->tgt_scsi_id = cpu_to_be64(rport->port_id);
- int_to_scsilun(sdev->lun, &vfc_cmd->v1.iu.lun);
+ int_to_scsilun(sdev->lun, &iu->lun);

return vfc_cmd;
}
@@ -1682,6 +1706,7 @@ static int ibmvfc_queuecommand_lck(struct scsi_cmnd *cmnd,
struct ibmvfc_host *vhost = shost_priv(cmnd->device->host);
struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
struct ibmvfc_cmd *vfc_cmd;
+ struct ibmvfc_fcp_cmd_iu *iu;
struct ibmvfc_event *evt;
int rc;

@@ -1699,13 +1724,14 @@ static int ibmvfc_queuecommand_lck(struct scsi_cmnd *cmnd,
cmnd->scsi_done = done;

vfc_cmd = ibmvfc_init_vfc_cmd(evt, cmnd->device);
+ iu = ibmvfc_get_fcp_iu(vhost, vfc_cmd);

- vfc_cmd->v1.iu.xfer_len = cpu_to_be32(scsi_bufflen(cmnd));
- memcpy(vfc_cmd->v1.iu.cdb, cmnd->cmnd, cmnd->cmd_len);
+ iu->xfer_len = cpu_to_be32(scsi_bufflen(cmnd));
+ memcpy(iu->cdb, cmnd->cmnd, cmnd->cmd_len);

if (cmnd->flags & SCMD_TAGGED) {
vfc_cmd->task_tag = cpu_to_be64(cmnd->tag);
- vfc_cmd->v1.iu.pri_task_attr = IBMVFC_SIMPLE_TASK;
+ iu->pri_task_attr = IBMVFC_SIMPLE_TASK;
}

if (likely(!(rc = ibmvfc_map_sg_data(cmnd, evt, vfc_cmd, vhost->dev))))
@@ -2030,7 +2056,8 @@ static int ibmvfc_reset_device(struct scsi_device *sdev, int type, char *desc)
struct ibmvfc_cmd *tmf;
struct ibmvfc_event *evt = NULL;
union ibmvfc_iu rsp_iu;
- struct ibmvfc_fcp_rsp *fc_rsp = &rsp_iu.cmd.v1.rsp;
+ struct ibmvfc_fcp_cmd_iu *iu;
+ struct ibmvfc_fcp_rsp *fc_rsp = ibmvfc_get_fcp_rsp(vhost, &rsp_iu.cmd);
int rsp_rc = -EBUSY;
unsigned long flags;
int rsp_code = 0;
@@ -2040,9 +2067,10 @@ static int ibmvfc_reset_device(struct scsi_device *sdev, int type, char *desc)
evt = ibmvfc_get_event(vhost);
ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_CMD_FORMAT);
tmf = ibmvfc_init_vfc_cmd(evt, sdev);
+ iu = ibmvfc_get_fcp_iu(vhost, tmf);

tmf->flags = cpu_to_be16((IBMVFC_NO_MEM_DESC | IBMVFC_TMF));
- tmf->v1.iu.tmf_flags = type;
+ iu->tmf_flags = type;
evt->sync_iu = &rsp_iu;

init_completion(&evt->comp);
@@ -2060,7 +2088,7 @@ static int ibmvfc_reset_device(struct scsi_device *sdev, int type, char *desc)
wait_for_completion(&evt->comp);

if (rsp_iu.cmd.status)
- rsp_code = ibmvfc_get_err_result(&rsp_iu.cmd);
+ rsp_code = ibmvfc_get_err_result(vhost, &rsp_iu.cmd);

if (rsp_code) {
if (fc_rsp->flags & FCP_RSP_LEN_VALID)
@@ -2335,7 +2363,8 @@ static int ibmvfc_abort_task_set(struct scsi_device *sdev)
struct ibmvfc_cmd *tmf;
struct ibmvfc_event *evt, *found_evt;
union ibmvfc_iu rsp_iu;
- struct ibmvfc_fcp_rsp *fc_rsp = &rsp_iu.cmd.v1.rsp;
+ struct ibmvfc_fcp_cmd_iu *iu;
+ struct ibmvfc_fcp_rsp *fc_rsp = ibmvfc_get_fcp_rsp(vhost, &rsp_iu.cmd);
int rc, rsp_rc = -EBUSY;
unsigned long flags, timeout = IBMVFC_ABORT_TIMEOUT;
int rsp_code = 0;
@@ -2360,9 +2389,10 @@ static int ibmvfc_abort_task_set(struct scsi_device *sdev)
evt = ibmvfc_get_event(vhost);
ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_CMD_FORMAT);
tmf = ibmvfc_init_vfc_cmd(evt, sdev);
+ iu = ibmvfc_get_fcp_iu(vhost, tmf);

+ iu->tmf_flags = IBMVFC_ABORT_TASK_SET;
tmf->flags = cpu_to_be16((IBMVFC_NO_MEM_DESC | IBMVFC_TMF));
- tmf->v1.iu.tmf_flags = IBMVFC_ABORT_TASK_SET;
evt->sync_iu = &rsp_iu;

init_completion(&evt->comp);
@@ -2409,7 +2439,7 @@ static int ibmvfc_abort_task_set(struct scsi_device *sdev)
}

if (rsp_iu.cmd.status)
- rsp_code = ibmvfc_get_err_result(&rsp_iu.cmd);
+ rsp_code = ibmvfc_get_err_result(vhost, &rsp_iu.cmd);

if (rsp_code) {
if (fc_rsp->flags & FCP_RSP_LEN_VALID)
--
2.27.0

2020-11-12 09:41:01

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH 1/6] ibmvfc: byte swap login_buf.resp values in attribute show functions

On Wed, Nov 11, 2020 at 07:04:37PM -0600, Tyrel Datwyler wrote:
> Both ibmvfc_show_host_(capabilities|npiv_version) functions retrieve
> values from vhost->login_buf.resp buffer. This is the MAD response
> buffer from the VIOS and as such any multi-byte non-string values are in
> big endian format.
>
> Byte swap these values to host cpu endian format for better human
> readability.

The whole series creates tons of pointlessly over 80 char lines.
Please do a quick fixup.

2020-11-13 19:42:02

by Tyrel Datwyler

[permalink] [raw]
Subject: Re: [PATCH 1/6] ibmvfc: byte swap login_buf.resp values in attribute show functions

On 11/12/20 1:37 AM, Christoph Hellwig wrote:
> On Wed, Nov 11, 2020 at 07:04:37PM -0600, Tyrel Datwyler wrote:
>> Both ibmvfc_show_host_(capabilities|npiv_version) functions retrieve
>> values from vhost->login_buf.resp buffer. This is the MAD response
>> buffer from the VIOS and as such any multi-byte non-string values are in
>> big endian format.
>>
>> Byte swap these values to host cpu endian format for better human
>> readability.
>
> The whole series creates tons of pointlessly over 80 char lines.
> Please do a quick fixup.
>

The checkpatch script only warns at 100 char lines these days. To be fair though
I did have two lines go over that limit by a couple characters, there are a
couple commit log typos, and I had an if keyword with no space after before the
opening parenthesis. So, I'll happily re-spin.

However, for my info going forward is the SCSI subsystem sticking to 80 char
lines as a hard limit?

-Tyrel

2020-11-17 03:28:19

by Martin K. Petersen

[permalink] [raw]
Subject: Re: [PATCH 1/6] ibmvfc: byte swap login_buf.resp values in attribute show functions


Tyrel,

> The checkpatch script only warns at 100 char lines these days. To be
> fair though I did have two lines go over that limit by a couple
> characters, there are a couple commit log typos, and I had an if
> keyword with no space after before the opening parenthesis. So, I'll
> happily re-spin.

Please tweak the little things that need fixing and resubmit.

> However, for my info going forward is the SCSI subsystem sticking to
> 80 char lines as a hard limit?

As far as I'm concerned the 80 char limit is mainly about ensuring that
the code is structured in a sensible way. Typesetting best practices
also suggest that longer lines are harder to read. So while I generally
don't strictly enforce the 80 char limit for drivers, I do push back if
I feel that readability could be improved by breaking the line or
restructuring the code.

Use your best judgment to optimize for readability.

Thanks!

--
Martin K. Petersen Oracle Linux Engineering

2020-11-17 22:25:18

by Brian King

[permalink] [raw]
Subject: Re: [PATCH 4/6] ibmvfc: add FC payload retrieval routines for versioned vfcFrames

On 11/17/20 4:14 PM, Brian King wrote:
> On 11/11/20 7:04 PM, Tyrel Datwyler wrote:
>> The FC iu and response payloads are located at different offsets
>> depending on the ibmvfc_cmd version. This is a result of the version 2
>> vfcFrame definition adding an extra 64bytes of reserved space to the
>> structure prior to the payloads.
>>
>> Add helper routines to determine the current vfcFrame version and
>> returning pointers to the proper iu or response structures within that
>> ibmvfc_cmd.
>>
>> Signed-off-by: Tyrel Datwyler <[email protected]>
>> ---
>> drivers/scsi/ibmvscsi/ibmvfc.c | 76 ++++++++++++++++++++++++----------
>> 1 file changed, 53 insertions(+), 23 deletions(-)
>>
>> diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
>> index aa3445bec42c..5e666f7c9266 100644
>> --- a/drivers/scsi/ibmvscsi/ibmvfc.c
>> +++ b/drivers/scsi/ibmvscsi/ibmvfc.c
>> @@ -138,6 +138,22 @@ static void ibmvfc_tgt_move_login(struct ibmvfc_target *);
>>
>> static const char *unknown_error = "unknown error";
>>
>> +static struct ibmvfc_fcp_cmd_iu *ibmvfc_get_fcp_iu(struct ibmvfc_host *vhost, struct ibmvfc_cmd *vfc_cmd)
>> +{
>> + if (be64_to_cpu(vhost->login_buf->resp.capabilities) & IBMVFC_HANDLE_VF_WWPN)
>
> Suggest adding a flag to the vhost structure that you setup after login in order to
> simplify this check and avoid chasing multiple pointers along with a byte swap.
>
> Maybe something like:
>
> vhost->is_v2

Even better might be vhost->version which you'd set to 1 or 2 and then you could directly
use that to set the field in the command structures later.


--
Brian King
Power Linux I/O
IBM Linux Technology Center

2020-11-17 22:35:46

by Brian King

[permalink] [raw]
Subject: Re: [PATCH 4/6] ibmvfc: add FC payload retrieval routines for versioned vfcFrames

On 11/11/20 7:04 PM, Tyrel Datwyler wrote:
> The FC iu and response payloads are located at different offsets
> depending on the ibmvfc_cmd version. This is a result of the version 2
> vfcFrame definition adding an extra 64bytes of reserved space to the
> structure prior to the payloads.
>
> Add helper routines to determine the current vfcFrame version and
> returning pointers to the proper iu or response structures within that
> ibmvfc_cmd.
>
> Signed-off-by: Tyrel Datwyler <[email protected]>
> ---
> drivers/scsi/ibmvscsi/ibmvfc.c | 76 ++++++++++++++++++++++++----------
> 1 file changed, 53 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
> index aa3445bec42c..5e666f7c9266 100644
> --- a/drivers/scsi/ibmvscsi/ibmvfc.c
> +++ b/drivers/scsi/ibmvscsi/ibmvfc.c
> @@ -138,6 +138,22 @@ static void ibmvfc_tgt_move_login(struct ibmvfc_target *);
>
> static const char *unknown_error = "unknown error";
>
> +static struct ibmvfc_fcp_cmd_iu *ibmvfc_get_fcp_iu(struct ibmvfc_host *vhost, struct ibmvfc_cmd *vfc_cmd)
> +{
> + if (be64_to_cpu(vhost->login_buf->resp.capabilities) & IBMVFC_HANDLE_VF_WWPN)

Suggest adding a flag to the vhost structure that you setup after login in order to
simplify this check and avoid chasing multiple pointers along with a byte swap.

Maybe something like:

vhost->is_v2

> + return &vfc_cmd->v2.iu;
> + else
> + return &vfc_cmd->v1.iu;
> +}
> +
> +static struct ibmvfc_fcp_rsp *ibmvfc_get_fcp_rsp(struct ibmvfc_host *vhost, struct ibmvfc_cmd *vfc_cmd)
> +{
> + if (be64_to_cpu(vhost->login_buf->resp.capabilities) & IBMVFC_HANDLE_VF_WWPN)

Same here

> + return &vfc_cmd->v2.rsp;
> + else
> + return &vfc_cmd->v1.rsp;
> +}
> +
> #ifdef CONFIG_SCSI_IBMVFC_TRACE
> /**
> * ibmvfc_trc_start - Log a start trace entry



--
Brian King
Power Linux I/O
IBM Linux Technology Center

2020-11-18 00:37:12

by Tyrel Datwyler

[permalink] [raw]
Subject: Re: [PATCH 4/6] ibmvfc: add FC payload retrieval routines for versioned vfcFrames

On 11/17/20 2:14 PM, Brian King wrote:
> On 11/11/20 7:04 PM, Tyrel Datwyler wrote:
>> The FC iu and response payloads are located at different offsets
>> depending on the ibmvfc_cmd version. This is a result of the version 2
>> vfcFrame definition adding an extra 64bytes of reserved space to the
>> structure prior to the payloads.
>>
>> Add helper routines to determine the current vfcFrame version and
>> returning pointers to the proper iu or response structures within that
>> ibmvfc_cmd.
>>
>> Signed-off-by: Tyrel Datwyler <[email protected]>
>> ---
>> drivers/scsi/ibmvscsi/ibmvfc.c | 76 ++++++++++++++++++++++++----------
>> 1 file changed, 53 insertions(+), 23 deletions(-)
>>
>> diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
>> index aa3445bec42c..5e666f7c9266 100644
>> --- a/drivers/scsi/ibmvscsi/ibmvfc.c
>> +++ b/drivers/scsi/ibmvscsi/ibmvfc.c
>> @@ -138,6 +138,22 @@ static void ibmvfc_tgt_move_login(struct ibmvfc_target *);
>>
>> static const char *unknown_error = "unknown error";
>>
>> +static struct ibmvfc_fcp_cmd_iu *ibmvfc_get_fcp_iu(struct ibmvfc_host *vhost, struct ibmvfc_cmd *vfc_cmd)
>> +{
>> + if (be64_to_cpu(vhost->login_buf->resp.capabilities) & IBMVFC_HANDLE_VF_WWPN)
>
> Suggest adding a flag to the vhost structure that you setup after login in order to
> simplify this check and avoid chasing multiple pointers along with a byte swap.
>
> Maybe something like:
>
> vhost->is_v2

I considered that, but opted instead in my v2 respin to add a helper routine to
test login response capabilities since we will also need to check for VIOS
channel support.

-Tyrel

>
>> + return &vfc_cmd->v2.iu;
>> + else
>> + return &vfc_cmd->v1.iu;
>> +}
>> +
>> +static struct ibmvfc_fcp_rsp *ibmvfc_get_fcp_rsp(struct ibmvfc_host *vhost, struct ibmvfc_cmd *vfc_cmd)
>> +{
>> + if (be64_to_cpu(vhost->login_buf->resp.capabilities) & IBMVFC_HANDLE_VF_WWPN)
>
> Same here
>
>> + return &vfc_cmd->v2.rsp;
>> + else
>> + return &vfc_cmd->v1.rsp;
>> +}
>> +
>> #ifdef CONFIG_SCSI_IBMVFC_TRACE
>> /**
>> * ibmvfc_trc_start - Log a start trace entry
>
>
>

2020-11-18 00:42:02

by Tyrel Datwyler

[permalink] [raw]
Subject: Re: [PATCH 4/6] ibmvfc: add FC payload retrieval routines for versioned vfcFrames

On 11/17/20 2:21 PM, Brian King wrote:
> On 11/17/20 4:14 PM, Brian King wrote:
>> On 11/11/20 7:04 PM, Tyrel Datwyler wrote:
>>> The FC iu and response payloads are located at different offsets
>>> depending on the ibmvfc_cmd version. This is a result of the version 2
>>> vfcFrame definition adding an extra 64bytes of reserved space to the
>>> structure prior to the payloads.
>>>
>>> Add helper routines to determine the current vfcFrame version and
>>> returning pointers to the proper iu or response structures within that
>>> ibmvfc_cmd.
>>>
>>> Signed-off-by: Tyrel Datwyler <[email protected]>
>>> ---
>>> drivers/scsi/ibmvscsi/ibmvfc.c | 76 ++++++++++++++++++++++++----------
>>> 1 file changed, 53 insertions(+), 23 deletions(-)
>>>
>>> diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
>>> index aa3445bec42c..5e666f7c9266 100644
>>> --- a/drivers/scsi/ibmvscsi/ibmvfc.c
>>> +++ b/drivers/scsi/ibmvscsi/ibmvfc.c
>>> @@ -138,6 +138,22 @@ static void ibmvfc_tgt_move_login(struct ibmvfc_target *);
>>>
>>> static const char *unknown_error = "unknown error";
>>>
>>> +static struct ibmvfc_fcp_cmd_iu *ibmvfc_get_fcp_iu(struct ibmvfc_host *vhost, struct ibmvfc_cmd *vfc_cmd)
>>> +{
>>> + if (be64_to_cpu(vhost->login_buf->resp.capabilities) & IBMVFC_HANDLE_VF_WWPN)
>>
>> Suggest adding a flag to the vhost structure that you setup after login in order to
>> simplify this check and avoid chasing multiple pointers along with a byte swap.
>>
>> Maybe something like:
>>
>> vhost->is_v2
>
> Even better might be vhost->version which you'd set to 1 or 2 and then you could directly
> use that to set the field in the command structures later.

So, the problem is that now a MADs version is determined by capability and not
an over arching protocol version. So, we will still have some MAD's that are v1
while other are v2 with a certain capability. The solution could work in the
short term since targetWWPN is the only feature that has v2 MADs, but I suspect
more versioning down the pipeline which may lead to some MADs whose v2 form has
nothing to do with targetWWPN support.

-Tyrel