Skip to content

Commit

Permalink
scsi: lpfc: Add bsg support for retrieving adapter cmf data
Browse files Browse the repository at this point in the history
Add a bsg ioctl to allow user applications to retrieve the adapter
congestion management framework buffer.

Link: https://lore.kernel.org/r/20210816162901.121235-15-jsmart2021@gmail.com
Co-developed-by: Justin Tee <justin.tee@broadcom.com>
Signed-off-by: Justin Tee <justin.tee@broadcom.com>
Signed-off-by: James Smart <jsmart2021@gmail.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
  • Loading branch information
James Smart authored and Martin K. Petersen committed Aug 25, 2021
1 parent 74a7baa commit acbaa8c
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 0 deletions.
89 changes: 89 additions & 0 deletions drivers/scsi/lpfc/lpfc_bsg.c
Original file line number Diff line number Diff line change
Expand Up @@ -5751,6 +5751,92 @@ lpfc_get_trunk_info(struct bsg_job *job)

}

static int
lpfc_get_cgnbuf_info(struct bsg_job *job)
{
struct lpfc_vport *vport = shost_priv(fc_bsg_to_shost(job));
struct lpfc_hba *phba = vport->phba;
struct fc_bsg_request *bsg_request = job->request;
struct fc_bsg_reply *bsg_reply = job->reply;
struct get_cgnbuf_info_req *cgnbuf_req;
struct lpfc_cgn_info *cp;
uint8_t *cgn_buff;
int size, cinfosz;
int rc = 0;

if (job->request_len < sizeof(struct fc_bsg_request) +
sizeof(struct get_cgnbuf_info_req)) {
rc = -ENOMEM;
goto job_exit;
}

if (!phba->sli4_hba.pc_sli4_params.cmf) {
rc = -ENOENT;
goto job_exit;
}

if (!phba->cgn_i || !phba->cgn_i->virt) {
rc = -ENOENT;
goto job_exit;
}

cp = phba->cgn_i->virt;
if (cp->cgn_info_version < LPFC_CGN_INFO_V3) {
rc = -EPERM;
goto job_exit;
}

cgnbuf_req = (struct get_cgnbuf_info_req *)
bsg_request->rqst_data.h_vendor.vendor_cmd;

/* For reset or size == 0 */
bsg_reply->reply_payload_rcv_len = 0;

if (cgnbuf_req->reset == LPFC_BSG_CGN_RESET_STAT) {
lpfc_init_congestion_stat(phba);
goto job_exit;
}

/* We don't want to include the CRC at the end */
cinfosz = sizeof(struct lpfc_cgn_info) - sizeof(uint32_t);

size = cgnbuf_req->read_size;
if (!size)
goto job_exit;

if (size < cinfosz) {
/* Just copy back what we can */
cinfosz = size;
rc = -E2BIG;
}

/* Allocate memory to read congestion info */
cgn_buff = vmalloc(cinfosz);
if (!cgn_buff) {
rc = -ENOMEM;
goto job_exit;
}

memcpy(cgn_buff, cp, cinfosz);

bsg_reply->reply_payload_rcv_len =
sg_copy_from_buffer(job->reply_payload.sg_list,
job->reply_payload.sg_cnt,
cgn_buff, cinfosz);

vfree(cgn_buff);

job_exit:
bsg_reply->result = rc;
if (!rc)
bsg_job_done(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
else
lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
"2724 GET CGNBUF error: %d\n", rc);
return rc;
}

/**
* lpfc_bsg_hst_vendor - process a vendor-specific fc_bsg_job
* @job: fc_bsg_job to handle
Expand Down Expand Up @@ -5813,6 +5899,9 @@ lpfc_bsg_hst_vendor(struct bsg_job *job)
case LPFC_BSG_VENDOR_GET_TRUNK_INFO:
rc = lpfc_get_trunk_info(job);
break;
case LPFC_BSG_VENDOR_GET_CGNBUF_INFO:
rc = lpfc_get_cgnbuf_info(job);
break;
default:
rc = -EINVAL;
bsg_reply->reply_payload_rcv_len = 0;
Expand Down
8 changes: 8 additions & 0 deletions drivers/scsi/lpfc/lpfc_bsg.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#define LPFC_BSG_VENDOR_RAS_GET_CONFIG 18
#define LPFC_BSG_VENDOR_RAS_SET_CONFIG 19
#define LPFC_BSG_VENDOR_GET_TRUNK_INFO 20
#define LPFC_BSG_VENDOR_GET_CGNBUF_INFO 21

struct set_ct_event {
uint32_t command;
Expand Down Expand Up @@ -386,6 +387,13 @@ struct get_trunk_info_req {
uint32_t command;
};

struct get_cgnbuf_info_req {
uint32_t command;
uint32_t read_size;
uint32_t reset;
#define LPFC_BSG_CGN_RESET_STAT 1
};

/* driver only */
#define SLI_CONFIG_NOT_HANDLED 0
#define SLI_CONFIG_HANDLED 1

0 comments on commit acbaa8c

Please sign in to comment.