@@ -5751,6 +5751,92 @@ lpfc_get_trunk_info(struct bsg_job *job)
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
@@ -5813,6 +5899,9 @@ lpfc_bsg_hst_vendor(struct bsg_job *job)
5813
5899
case LPFC_BSG_VENDOR_GET_TRUNK_INFO :
5814
5900
rc = lpfc_get_trunk_info (job );
5815
5901
break ;
5902
+ case LPFC_BSG_VENDOR_GET_CGNBUF_INFO :
5903
+ rc = lpfc_get_cgnbuf_info (job );
5904
+ break ;
5816
5905
default :
5817
5906
rc = - EINVAL ;
5818
5907
bsg_reply -> reply_payload_rcv_len = 0 ;
0 commit comments