diff mbox series

[01/10] qla2xxx: Add support for mailbox passthru

Message ID 20210908072846.10011-2-njavali@marvell.com (mailing list archive)
State Superseded
Headers show
Series qla2xxx driver bug fixes | expand

Commit Message

Nilesh Javali Sept. 8, 2021, 7:28 a.m. UTC
From: Bikash Hazarika <bhazarika@marvell.com>

This interface will allow user space application(s) to send a mailbox
command to the FW.

Signed-off-by: Bikash Hazarika <bhazarika@marvell.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
---
 drivers/scsi/qla2xxx/qla_bsg.c | 48 ++++++++++++++++++++++++++++++++++
 drivers/scsi/qla2xxx/qla_bsg.h |  7 +++++
 drivers/scsi/qla2xxx/qla_gbl.h |  4 +++
 drivers/scsi/qla2xxx/qla_mbx.c | 33 +++++++++++++++++++++++
 4 files changed, 92 insertions(+)

Comments

Himanshu Madhani Sept. 8, 2021, 1:44 p.m. UTC | #1
> On Sep 8, 2021, at 2:28 AM, Nilesh Javali <njavali@marvell.com> wrote:
> 
> From: Bikash Hazarika <bhazarika@marvell.com>
> 
> This interface will allow user space application(s) to send a mailbox
> command to the FW.
> 
> Signed-off-by: Bikash Hazarika <bhazarika@marvell.com>
> Signed-off-by: Nilesh Javali <njavali@marvell.com>
> ---
> drivers/scsi/qla2xxx/qla_bsg.c | 48 ++++++++++++++++++++++++++++++++++
> drivers/scsi/qla2xxx/qla_bsg.h |  7 +++++
> drivers/scsi/qla2xxx/qla_gbl.h |  4 +++
> drivers/scsi/qla2xxx/qla_mbx.c | 33 +++++++++++++++++++++++
> 4 files changed, 92 insertions(+)
> 
> diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
> index 4b5d28d89d69..0c33fb0de21a 100644
> --- a/drivers/scsi/qla2xxx/qla_bsg.c
> +++ b/drivers/scsi/qla2xxx/qla_bsg.c
> @@ -2877,6 +2877,9 @@ qla2x00_process_vendor_specific(struct scsi_qla_host *vha, struct bsg_job *bsg_j
> 	case QL_VND_MANAGE_HOST_PORT:
> 		return qla2x00_manage_host_port(bsg_job);
> 
> +	case QL_VND_MBX_PASSTHRU:
> +		return qla2x00_mailbox_passthru(bsg_job);
> +
> 	default:
> 		return -ENOSYS;
> 	}
> @@ -3013,3 +3016,48 @@ qla24xx_bsg_timeout(struct bsg_job *bsg_job)
> 	sp->free(sp);
> 	return 0;
> }
> +
> +int qla2x00_mailbox_passthru(struct bsg_job *bsg_job)
> +{
> +	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
> +	scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
> +	int ret = -EINVAL;
> +	int ptsize = sizeof(struct qla_mbx_passthru);
> +	struct qla_mbx_passthru *req_data = NULL;
> +	uint32_t req_data_len;
> +
> +	req_data_len = bsg_job->request_payload.payload_len;
> +	if (req_data_len != ptsize) {
> +		ql_log(ql_log_warn, vha, 0xf0a3, "req_data_len invalid.\n");
> +		return -EIO;
> +	}
> +	req_data = kzalloc(ptsize, GFP_KERNEL);
> +	if (!req_data) {
> +		ql_log(ql_log_warn, vha, 0xf0a4,
> +		       "req_data memory allocation failure.\n");
> +		return -ENOMEM;
> +	}
> +
> +	/* Copy the request buffer in req_data */
> +	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
> +			  bsg_job->request_payload.sg_cnt, req_data, ptsize);
> +	ret = qla_mailbox_passthru(vha, req_data->mbx_in, req_data->mbx_out);
> +
> +	/* Copy the req_data in  request buffer */
> +	sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
> +			    bsg_job->reply_payload.sg_cnt, req_data, ptsize);
> +
> +	bsg_reply->reply_payload_rcv_len = ptsize;
> +	if (ret == QLA_SUCCESS)
> +		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
> +	else
> +		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_ERR;
> +
> +	bsg_job->reply_len = sizeof(*bsg_job->reply);
> +	bsg_reply->result = DID_OK << 16;
> +	bsg_job_done(bsg_job, bsg_reply->result, bsg_reply->reply_payload_rcv_len);
> +
> +	kfree(req_data);
> +
> +	return ret;
> +}
> diff --git a/drivers/scsi/qla2xxx/qla_bsg.h b/drivers/scsi/qla2xxx/qla_bsg.h
> index dd793cf8bc1e..0f8a4c7e52a2 100644
> --- a/drivers/scsi/qla2xxx/qla_bsg.h
> +++ b/drivers/scsi/qla2xxx/qla_bsg.h
> @@ -36,6 +36,7 @@
> #define QL_VND_GET_HOST_STATS		0x24
> #define QL_VND_GET_TGT_STATS		0x25
> #define QL_VND_MANAGE_HOST_PORT		0x26
> +#define QL_VND_MBX_PASSTHRU		0x2B
> 
> /* BSG Vendor specific subcode returns */
> #define EXT_STATUS_OK			0
> @@ -187,6 +188,12 @@ struct qla_port_param {
> 	uint16_t speed;
> } __attribute__ ((packed));
> 
> +struct qla_mbx_passthru {
> +	uint16_t reserved1[2];
> +	uint16_t mbx_in[32];
> +	uint16_t mbx_out[32];
> +	uint32_t reserved2[16];
> +} __packed;
> 
> /* FRU VPD */
> 
> diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
> index 1c3f055d41b8..8aadcdeca6cb 100644
> --- a/drivers/scsi/qla2xxx/qla_gbl.h
> +++ b/drivers/scsi/qla2xxx/qla_gbl.h
> @@ -662,9 +662,13 @@ extern int qla2xxx_get_vpd_field(scsi_qla_host_t *, char *, char *, size_t);
> 
> extern void qla2xxx_flash_npiv_conf(scsi_qla_host_t *);
> extern int qla24xx_read_fcp_prio_cfg(scsi_qla_host_t *);
> +extern int qla2x00_mailbox_passthru(struct bsg_job *bsg_job);
> int __qla_copy_purex_to_buffer(struct scsi_qla_host *vha, void **pkt,
> 	struct rsp_que **rsp, u8 *buf, u32 buf_len);
> 
> +int qla_mailbox_passthru(scsi_qla_host_t *vha, uint16_t *mbx_in,
> +			 uint16_t *mbx_out);
> +
> /*
>  * Global Function Prototypes in qla_dbg.c source file.
>  */
> diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
> index 7811c4952035..9eb41dd39043 100644
> --- a/drivers/scsi/qla2xxx/qla_mbx.c
> +++ b/drivers/scsi/qla2xxx/qla_mbx.c
> @@ -7011,3 +7011,36 @@ void qla_no_op_mb(struct scsi_qla_host *vha)
> 			"Failed %s %x\n", __func__, rval);
> 	}
> }
> +
> +int qla_mailbox_passthru(scsi_qla_host_t *vha,
> +			 uint16_t *mbx_in, uint16_t *mbx_out)
> +{
> +	mbx_cmd_t mc;
> +	mbx_cmd_t *mcp = &mc;
> +	int rval = -EINVAL;
> +
> +	memset(&mc, 0, sizeof(mc));
> +	/* Receiving all 32 register's contents */
> +	memcpy(&mcp->mb, (char *)mbx_in, (32 * sizeof(uint16_t)));
> +
> +	mcp->out_mb = 0xFFFFFFFF;
> +	mcp->in_mb = 0xFFFFFFFF;
> +
> +	mcp->tov = MBX_TOV_SECONDS;
> +	mcp->flags = 0;
> +	mcp->bufp = NULL;
> +
> +	rval = qla2x00_mailbox_command(vha, mcp);
> +
> +	if (rval != QLA_SUCCESS) {
> +		ql_dbg(ql_dbg_mbx, vha, 0xf0a2,
> +			"Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
> +	} else {
> +		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xf0a3, "Done %s.\n",
> +		       __func__);
> +		/* passing all 32 register's contents */
> +		memcpy(mbx_out, &mcp->mb, 32 * sizeof(uint16_t));
> +	}
> +
> +	return rval;
> +}
> -- 
> 2.19.0.rc0
> 

Looks Good. 

Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>

--
Himanshu Madhani	 Oracle Linux Engineering
diff mbox series

Patch

diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index 4b5d28d89d69..0c33fb0de21a 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -2877,6 +2877,9 @@  qla2x00_process_vendor_specific(struct scsi_qla_host *vha, struct bsg_job *bsg_j
 	case QL_VND_MANAGE_HOST_PORT:
 		return qla2x00_manage_host_port(bsg_job);
 
+	case QL_VND_MBX_PASSTHRU:
+		return qla2x00_mailbox_passthru(bsg_job);
+
 	default:
 		return -ENOSYS;
 	}
@@ -3013,3 +3016,48 @@  qla24xx_bsg_timeout(struct bsg_job *bsg_job)
 	sp->free(sp);
 	return 0;
 }
+
+int qla2x00_mailbox_passthru(struct bsg_job *bsg_job)
+{
+	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
+	scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
+	int ret = -EINVAL;
+	int ptsize = sizeof(struct qla_mbx_passthru);
+	struct qla_mbx_passthru *req_data = NULL;
+	uint32_t req_data_len;
+
+	req_data_len = bsg_job->request_payload.payload_len;
+	if (req_data_len != ptsize) {
+		ql_log(ql_log_warn, vha, 0xf0a3, "req_data_len invalid.\n");
+		return -EIO;
+	}
+	req_data = kzalloc(ptsize, GFP_KERNEL);
+	if (!req_data) {
+		ql_log(ql_log_warn, vha, 0xf0a4,
+		       "req_data memory allocation failure.\n");
+		return -ENOMEM;
+	}
+
+	/* Copy the request buffer in req_data */
+	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
+			  bsg_job->request_payload.sg_cnt, req_data, ptsize);
+	ret = qla_mailbox_passthru(vha, req_data->mbx_in, req_data->mbx_out);
+
+	/* Copy the req_data in  request buffer */
+	sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
+			    bsg_job->reply_payload.sg_cnt, req_data, ptsize);
+
+	bsg_reply->reply_payload_rcv_len = ptsize;
+	if (ret == QLA_SUCCESS)
+		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
+	else
+		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_ERR;
+
+	bsg_job->reply_len = sizeof(*bsg_job->reply);
+	bsg_reply->result = DID_OK << 16;
+	bsg_job_done(bsg_job, bsg_reply->result, bsg_reply->reply_payload_rcv_len);
+
+	kfree(req_data);
+
+	return ret;
+}
diff --git a/drivers/scsi/qla2xxx/qla_bsg.h b/drivers/scsi/qla2xxx/qla_bsg.h
index dd793cf8bc1e..0f8a4c7e52a2 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.h
+++ b/drivers/scsi/qla2xxx/qla_bsg.h
@@ -36,6 +36,7 @@ 
 #define QL_VND_GET_HOST_STATS		0x24
 #define QL_VND_GET_TGT_STATS		0x25
 #define QL_VND_MANAGE_HOST_PORT		0x26
+#define QL_VND_MBX_PASSTHRU		0x2B
 
 /* BSG Vendor specific subcode returns */
 #define EXT_STATUS_OK			0
@@ -187,6 +188,12 @@  struct qla_port_param {
 	uint16_t speed;
 } __attribute__ ((packed));
 
+struct qla_mbx_passthru {
+	uint16_t reserved1[2];
+	uint16_t mbx_in[32];
+	uint16_t mbx_out[32];
+	uint32_t reserved2[16];
+} __packed;
 
 /* FRU VPD */
 
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 1c3f055d41b8..8aadcdeca6cb 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -662,9 +662,13 @@  extern int qla2xxx_get_vpd_field(scsi_qla_host_t *, char *, char *, size_t);
 
 extern void qla2xxx_flash_npiv_conf(scsi_qla_host_t *);
 extern int qla24xx_read_fcp_prio_cfg(scsi_qla_host_t *);
+extern int qla2x00_mailbox_passthru(struct bsg_job *bsg_job);
 int __qla_copy_purex_to_buffer(struct scsi_qla_host *vha, void **pkt,
 	struct rsp_que **rsp, u8 *buf, u32 buf_len);
 
+int qla_mailbox_passthru(scsi_qla_host_t *vha, uint16_t *mbx_in,
+			 uint16_t *mbx_out);
+
 /*
  * Global Function Prototypes in qla_dbg.c source file.
  */
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 7811c4952035..9eb41dd39043 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -7011,3 +7011,36 @@  void qla_no_op_mb(struct scsi_qla_host *vha)
 			"Failed %s %x\n", __func__, rval);
 	}
 }
+
+int qla_mailbox_passthru(scsi_qla_host_t *vha,
+			 uint16_t *mbx_in, uint16_t *mbx_out)
+{
+	mbx_cmd_t mc;
+	mbx_cmd_t *mcp = &mc;
+	int rval = -EINVAL;
+
+	memset(&mc, 0, sizeof(mc));
+	/* Receiving all 32 register's contents */
+	memcpy(&mcp->mb, (char *)mbx_in, (32 * sizeof(uint16_t)));
+
+	mcp->out_mb = 0xFFFFFFFF;
+	mcp->in_mb = 0xFFFFFFFF;
+
+	mcp->tov = MBX_TOV_SECONDS;
+	mcp->flags = 0;
+	mcp->bufp = NULL;
+
+	rval = qla2x00_mailbox_command(vha, mcp);
+
+	if (rval != QLA_SUCCESS) {
+		ql_dbg(ql_dbg_mbx, vha, 0xf0a2,
+			"Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
+	} else {
+		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xf0a3, "Done %s.\n",
+		       __func__);
+		/* passing all 32 register's contents */
+		memcpy(mbx_out, &mcp->mb, 32 * sizeof(uint16_t));
+	}
+
+	return rval;
+}