mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-13 04:48:21 -04:00
scsi: qla2xxx: Add support for mailbox passthru
This interface will allow user space applications to send a mailbox command to the firmware. Link: https://lore.kernel.org/r/20210908164622.19240-2-njavali@marvell.com Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com> Signed-off-by: Bikash Hazarika <bhazarika@marvell.com> Signed-off-by: Nilesh Javali <njavali@marvell.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
committed by
Martin K. Petersen
parent
51e6ed83bb
commit
9e1c320696
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user