Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

scsi: lpfc: Add bsg support for retrieving adapter cmf data

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>

authored by

James Smart and committed by
Martin K. Petersen
acbaa8c8 74a7baa2

+97
+89
drivers/scsi/lpfc/lpfc_bsg.c
··· 5751 5751 5752 5752 } 5753 5753 5754 + static int 5755 + lpfc_get_cgnbuf_info(struct bsg_job *job) 5756 + { 5757 + struct lpfc_vport *vport = shost_priv(fc_bsg_to_shost(job)); 5758 + struct lpfc_hba *phba = vport->phba; 5759 + struct fc_bsg_request *bsg_request = job->request; 5760 + struct fc_bsg_reply *bsg_reply = job->reply; 5761 + struct get_cgnbuf_info_req *cgnbuf_req; 5762 + struct lpfc_cgn_info *cp; 5763 + uint8_t *cgn_buff; 5764 + int size, cinfosz; 5765 + int rc = 0; 5766 + 5767 + if (job->request_len < sizeof(struct fc_bsg_request) + 5768 + sizeof(struct get_cgnbuf_info_req)) { 5769 + rc = -ENOMEM; 5770 + goto job_exit; 5771 + } 5772 + 5773 + if (!phba->sli4_hba.pc_sli4_params.cmf) { 5774 + rc = -ENOENT; 5775 + goto job_exit; 5776 + } 5777 + 5778 + if (!phba->cgn_i || !phba->cgn_i->virt) { 5779 + rc = -ENOENT; 5780 + goto job_exit; 5781 + } 5782 + 5783 + cp = phba->cgn_i->virt; 5784 + if (cp->cgn_info_version < LPFC_CGN_INFO_V3) { 5785 + rc = -EPERM; 5786 + goto job_exit; 5787 + } 5788 + 5789 + cgnbuf_req = (struct get_cgnbuf_info_req *) 5790 + bsg_request->rqst_data.h_vendor.vendor_cmd; 5791 + 5792 + /* For reset or size == 0 */ 5793 + bsg_reply->reply_payload_rcv_len = 0; 5794 + 5795 + if (cgnbuf_req->reset == LPFC_BSG_CGN_RESET_STAT) { 5796 + lpfc_init_congestion_stat(phba); 5797 + goto job_exit; 5798 + } 5799 + 5800 + /* We don't want to include the CRC at the end */ 5801 + cinfosz = sizeof(struct lpfc_cgn_info) - sizeof(uint32_t); 5802 + 5803 + size = cgnbuf_req->read_size; 5804 + if (!size) 5805 + goto job_exit; 5806 + 5807 + if (size < cinfosz) { 5808 + /* Just copy back what we can */ 5809 + cinfosz = size; 5810 + rc = -E2BIG; 5811 + } 5812 + 5813 + /* Allocate memory to read congestion info */ 5814 + cgn_buff = vmalloc(cinfosz); 5815 + if (!cgn_buff) { 5816 + rc = -ENOMEM; 5817 + goto job_exit; 5818 + } 5819 + 5820 + memcpy(cgn_buff, cp, cinfosz); 5821 + 5822 + bsg_reply->reply_payload_rcv_len = 5823 + sg_copy_from_buffer(job->reply_payload.sg_list, 5824 + job->reply_payload.sg_cnt, 5825 + cgn_buff, cinfosz); 5826 + 5827 + vfree(cgn_buff); 5828 + 5829 + job_exit: 5830 + bsg_reply->result = rc; 5831 + if (!rc) 5832 + bsg_job_done(job, bsg_reply->result, 5833 + bsg_reply->reply_payload_rcv_len); 5834 + else 5835 + lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, 5836 + "2724 GET CGNBUF error: %d\n", rc); 5837 + return rc; 5838 + } 5839 + 5754 5840 /** 5755 5841 * lpfc_bsg_hst_vendor - process a vendor-specific fc_bsg_job 5756 5842 * @job: fc_bsg_job to handle ··· 5898 5812 break; 5899 5813 case LPFC_BSG_VENDOR_GET_TRUNK_INFO: 5900 5814 rc = lpfc_get_trunk_info(job); 5815 + break; 5816 + case LPFC_BSG_VENDOR_GET_CGNBUF_INFO: 5817 + rc = lpfc_get_cgnbuf_info(job); 5901 5818 break; 5902 5819 default: 5903 5820 rc = -EINVAL;
+8
drivers/scsi/lpfc/lpfc_bsg.h
··· 43 43 #define LPFC_BSG_VENDOR_RAS_GET_CONFIG 18 44 44 #define LPFC_BSG_VENDOR_RAS_SET_CONFIG 19 45 45 #define LPFC_BSG_VENDOR_GET_TRUNK_INFO 20 46 + #define LPFC_BSG_VENDOR_GET_CGNBUF_INFO 21 46 47 47 48 struct set_ct_event { 48 49 uint32_t command; ··· 385 384 386 385 struct get_trunk_info_req { 387 386 uint32_t command; 387 + }; 388 + 389 + struct get_cgnbuf_info_req { 390 + uint32_t command; 391 + uint32_t read_size; 392 + uint32_t reset; 393 + #define LPFC_BSG_CGN_RESET_STAT 1 388 394 }; 389 395 390 396 /* driver only */