Commit 9fd26c63 authored by Quinn Tran's avatar Quinn Tran Committed by Martin K. Petersen
Browse files

scsi: qla2xxx: edif: Fix EDIF bsg

Various EDIF bsgs did not properly fill out the reply_payload_rcv_len
field. This causes app to parse empty data in the return payload.

Link: https://lore.kernel.org/r/20211026115412.27691-13-njavali@marvell.com


Fixes: 7ebb336e ("scsi: qla2xxx: edif: Add start + stop bsgs")
Reviewed-by: default avatarHimanshu Madhani <himanshu.madhani@oracle.com>
Signed-off-by: default avatarQuinn Tran <qutran@marvell.com>
Signed-off-by: default avatarNilesh Javali <njavali@marvell.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 36f468bf
Loading
Loading
Loading
Loading
+23 −26
Original line number Diff line number Diff line
@@ -544,13 +544,13 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
	appreply.edif_enode_active = vha->pur_cinfo.enode_flags;
	appreply.edif_edb_active = vha->e_dbell.db_flags;

	bsg_job->reply_len = sizeof(struct fc_bsg_reply) +
	    sizeof(struct app_start_reply);
	bsg_job->reply_len = sizeof(struct fc_bsg_reply);

	SET_DID_STATUS(bsg_reply->result, DID_OK);

	sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
	    bsg_job->reply_payload.sg_cnt, &appreply,
	bsg_reply->reply_payload_rcv_len = sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
							       bsg_job->reply_payload.sg_cnt,
							       &appreply,
							       sizeof(struct app_start_reply));

	ql_dbg(ql_dbg_edif, vha, 0x911d,
@@ -748,8 +748,9 @@ qla_edif_app_authok(scsi_qla_host_t *vha, struct bsg_job *bsg_job)

errstate_exit:
	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
	sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
	    bsg_job->reply_payload.sg_cnt, &appplogireply,
	bsg_reply->reply_payload_rcv_len = sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
							       bsg_job->reply_payload.sg_cnt,
							       &appplogireply,
							       sizeof(struct app_plogi_reply));

	return rval;
@@ -833,7 +834,7 @@ static int
qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
{
	int32_t			rval = 0;
	int32_t			num_cnt;
	int32_t			pcnt = 0;
	struct fc_bsg_reply	*bsg_reply = bsg_job->reply;
	struct app_pinfo_req	app_req;
	struct app_pinfo_reply	*app_reply;
@@ -845,16 +846,14 @@ qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
	    bsg_job->request_payload.sg_cnt, &app_req,
	    sizeof(struct app_pinfo_req));

	num_cnt = app_req.num_ports;	/* num of ports alloc'd by app */

	app_reply = kzalloc((sizeof(struct app_pinfo_reply) +
	    sizeof(struct app_pinfo) * num_cnt), GFP_KERNEL);
	    sizeof(struct app_pinfo) * app_req.num_ports), GFP_KERNEL);

	if (!app_reply) {
		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
		rval = -1;
	} else {
		struct fc_port	*fcport = NULL, *tf;
		uint32_t	pcnt = 0;

		list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) {
			if (!(fcport->flags & FCF_FCSP_DEVICE))
@@ -923,9 +922,11 @@ qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
		SET_DID_STATUS(bsg_reply->result, DID_OK);
	}

	sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
	    bsg_job->reply_payload.sg_cnt, app_reply,
	    sizeof(struct app_pinfo_reply) + sizeof(struct app_pinfo) * num_cnt);
	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
	bsg_reply->reply_payload_rcv_len = sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
							       bsg_job->reply_payload.sg_cnt,
							       app_reply,
							       sizeof(struct app_pinfo_reply) + sizeof(struct app_pinfo) * pcnt);

	kfree(app_reply);

@@ -942,10 +943,11 @@ qla_edif_app_getstats(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
{
	int32_t			rval = 0;
	struct fc_bsg_reply	*bsg_reply = bsg_job->reply;
	uint32_t ret_size, size;
	uint32_t size;

	struct app_sinfo_req	app_req;
	struct app_stats_reply	*app_reply;
	uint32_t pcnt = 0;

	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
	    bsg_job->request_payload.sg_cnt, &app_req,
@@ -961,18 +963,12 @@ qla_edif_app_getstats(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
	size = sizeof(struct app_stats_reply) +
	    (sizeof(struct app_sinfo) * app_req.num_ports);

	if (size > bsg_job->reply_payload.payload_len)
		ret_size = bsg_job->reply_payload.payload_len;
	else
		ret_size = size;

	app_reply = kzalloc(size, GFP_KERNEL);
	if (!app_reply) {
		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
		rval = -1;
	} else {
		struct fc_port	*fcport = NULL, *tf;
		uint32_t	pcnt = 0;

		list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) {
			if (fcport->edif.enable) {
@@ -996,9 +992,11 @@ qla_edif_app_getstats(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
		SET_DID_STATUS(bsg_reply->result, DID_OK);
	}

	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
	bsg_reply->reply_payload_rcv_len =
	    sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
	       bsg_job->reply_payload.sg_cnt, app_reply, ret_size);
	       bsg_job->reply_payload.sg_cnt, app_reply,
	       sizeof(struct app_stats_reply) + (sizeof(struct app_sinfo) * pcnt));

	kfree(app_reply);

@@ -1072,8 +1070,7 @@ qla_edif_app_mgmt(struct bsg_job *bsg_job)
		    __func__,
		    bsg_request->rqst_data.h_vendor.vendor_cmd[1]);
		rval = EXT_STATUS_INVALID_PARAM;
		bsg_job->reply_len = sizeof(struct fc_bsg_reply);
		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
		done = false;
		break;
	}