@@ -120,6 +120,16 @@ enum ELX_LOOPBACK_CMD {
120
120
#define ELX_LOOPBACK_HEADER_SZ \
121
121
(size_t)(&((struct lpfc_sli_ct_request *)NULL)->un)
122
122
123
+ /* For non-embedded read object command */
124
+ #define READ_OBJ_EMB0_SCHEME_0 {1, 10, 256, 128}
125
+ #define READ_OBJ_EMB0_SCHEME_1 {11, LPFC_EMB0_MAX_RD_OBJ_HBD_CNT, 512, 192}
126
+ static const struct lpfc_read_object_cmd_scheme {
127
+ u32 min_hbd_cnt ;
128
+ u32 max_hbd_cnt ;
129
+ u32 cmd_size ;
130
+ u32 payload_word_offset ;
131
+ } rd_obj_scheme [2 ] = {READ_OBJ_EMB0_SCHEME_0 , READ_OBJ_EMB0_SCHEME_1 };
132
+
123
133
struct lpfc_dmabufext {
124
134
struct lpfc_dmabuf dma ;
125
135
uint32_t size ;
@@ -3538,6 +3548,103 @@ lpfc_bsg_mbox_ext_session_reset(struct lpfc_hba *phba)
3538
3548
return ;
3539
3549
}
3540
3550
3551
+ /**
3552
+ * lpfc_rd_obj_emb0_handle_job - Handles completion for non-embedded
3553
+ * READ_OBJECT_V0 mailbox commands
3554
+ * @phba: pointer to lpfc_hba data struct
3555
+ * @pmb_buf: pointer to mailbox buffer
3556
+ * @sli_cfg_mbx: pointer to SLI_CONFIG mailbox memory region
3557
+ * @job: pointer to bsg_job struct
3558
+ * @bsg_reply: point to bsg_reply struct
3559
+ *
3560
+ * Given a non-embedded READ_OBJECT_V0's HBD_CNT, this routine copies
3561
+ * a READ_OBJECT_V0 mailbox command's read data payload into a bsg_job
3562
+ * structure for passing back to application layer.
3563
+ *
3564
+ * Return codes
3565
+ * 0 - successful
3566
+ * -EINVAL - invalid HBD_CNT
3567
+ * -ENODEV - pointer to bsg_job struct is NULL
3568
+ **/
3569
+ static int
3570
+ lpfc_rd_obj_emb0_handle_job (struct lpfc_hba * phba , u8 * pmb_buf ,
3571
+ struct lpfc_sli_config_mbox * sli_cfg_mbx ,
3572
+ struct bsg_job * job ,
3573
+ struct fc_bsg_reply * bsg_reply )
3574
+ {
3575
+ struct lpfc_dmabuf * curr_dmabuf , * next_dmabuf ;
3576
+ struct lpfc_sli_config_emb0_subsys * emb0_subsys ;
3577
+ u32 hbd_cnt ;
3578
+ u32 dma_buf_len ;
3579
+ u8 i = 0 ;
3580
+ size_t extra_bytes ;
3581
+ off_t skip = 0 ;
3582
+
3583
+ if (!job ) {
3584
+ lpfc_printf_log (phba , KERN_INFO , LOG_LIBDFC ,
3585
+ "2496 NULL job\n" );
3586
+ return - ENODEV ;
3587
+ }
3588
+
3589
+ if (!bsg_reply ) {
3590
+ lpfc_printf_log (phba , KERN_INFO , LOG_LIBDFC ,
3591
+ "2498 NULL bsg_reply\n" );
3592
+ return - ENODEV ;
3593
+ }
3594
+
3595
+ emb0_subsys = & sli_cfg_mbx -> un .sli_config_emb0_subsys ;
3596
+
3597
+ hbd_cnt = bsg_bf_get (lpfc_emb0_subcmnd_rd_obj_hbd_cnt ,
3598
+ emb0_subsys );
3599
+
3600
+ /* Calculate where the read object's read data payload is located based
3601
+ * on HBD count scheme.
3602
+ */
3603
+ if (hbd_cnt >= rd_obj_scheme [0 ].min_hbd_cnt &&
3604
+ hbd_cnt <= rd_obj_scheme [0 ].max_hbd_cnt ) {
3605
+ skip = rd_obj_scheme [0 ].payload_word_offset * 4 ;
3606
+ } else if (hbd_cnt >= rd_obj_scheme [1 ].min_hbd_cnt &&
3607
+ hbd_cnt <= rd_obj_scheme [1 ].max_hbd_cnt ) {
3608
+ skip = rd_obj_scheme [1 ].payload_word_offset * 4 ;
3609
+ } else {
3610
+ lpfc_printf_log (phba , KERN_INFO , LOG_LIBDFC ,
3611
+ "2497 bad hbd_count 0x%08x\n" ,
3612
+ hbd_cnt );
3613
+ return - EINVAL ;
3614
+ }
3615
+
3616
+ /* Copy SLI_CONFIG command and READ_OBJECT response first */
3617
+ bsg_reply -> reply_payload_rcv_len =
3618
+ sg_copy_from_buffer (job -> reply_payload .sg_list ,
3619
+ job -> reply_payload .sg_cnt ,
3620
+ pmb_buf , skip );
3621
+
3622
+ /* Copy data from hbds */
3623
+ list_for_each_entry_safe (curr_dmabuf , next_dmabuf ,
3624
+ & phba -> mbox_ext_buf_ctx .ext_dmabuf_list ,
3625
+ list ) {
3626
+ dma_buf_len = emb0_subsys -> hbd [i ].buf_len ;
3627
+
3628
+ /* Use sg_copy_buffer to specify a skip offset */
3629
+ extra_bytes = sg_copy_buffer (job -> reply_payload .sg_list ,
3630
+ job -> reply_payload .sg_cnt ,
3631
+ curr_dmabuf -> virt ,
3632
+ dma_buf_len , skip , false);
3633
+
3634
+ bsg_reply -> reply_payload_rcv_len += extra_bytes ;
3635
+
3636
+ skip += extra_bytes ;
3637
+
3638
+ lpfc_printf_log (phba , KERN_INFO , LOG_LIBDFC ,
3639
+ "2499 copied hbd[%d] "
3640
+ "0x%zx bytes\n" ,
3641
+ i , extra_bytes );
3642
+ i ++ ;
3643
+ }
3644
+
3645
+ return 0 ;
3646
+ }
3647
+
3541
3648
/**
3542
3649
* lpfc_bsg_issue_mbox_ext_handle_job - job handler for multi-buffer mbox cmpl
3543
3650
* @phba: Pointer to HBA context object.
@@ -3551,10 +3658,10 @@ lpfc_bsg_issue_mbox_ext_handle_job(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
3551
3658
{
3552
3659
struct bsg_job_data * dd_data ;
3553
3660
struct bsg_job * job ;
3554
- struct fc_bsg_reply * bsg_reply ;
3661
+ struct fc_bsg_reply * bsg_reply = NULL ;
3555
3662
uint8_t * pmb , * pmb_buf ;
3556
3663
unsigned long flags ;
3557
- uint32_t size ;
3664
+ u32 size , opcode ;
3558
3665
int rc = 0 ;
3559
3666
struct lpfc_dmabuf * dmabuf ;
3560
3667
struct lpfc_sli_config_mbox * sli_cfg_mbx ;
@@ -3591,6 +3698,24 @@ lpfc_bsg_issue_mbox_ext_handle_job(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
3591
3698
lpfc_sli_pcimem_bcopy (& pmbx [sizeof (MAILBOX_t )],
3592
3699
& pmbx [sizeof (MAILBOX_t )],
3593
3700
sli_cfg_mbx -> un .sli_config_emb0_subsys .mse [0 ].buf_len );
3701
+
3702
+ /* Special handling for non-embedded READ_OBJECT */
3703
+ opcode = bsg_bf_get (lpfc_emb0_subcmnd_opcode ,
3704
+ & sli_cfg_mbx -> un .sli_config_emb0_subsys );
3705
+ switch (opcode ) {
3706
+ case COMN_OPCODE_READ_OBJECT :
3707
+ if (job ) {
3708
+ rc = lpfc_rd_obj_emb0_handle_job (phba , pmb_buf ,
3709
+ sli_cfg_mbx ,
3710
+ job ,
3711
+ bsg_reply );
3712
+ bsg_reply -> result = rc ;
3713
+ goto done ;
3714
+ }
3715
+ break ;
3716
+ default :
3717
+ break ;
3718
+ }
3594
3719
}
3595
3720
3596
3721
/* Complete the job if the job is still active */
@@ -3604,12 +3729,14 @@ lpfc_bsg_issue_mbox_ext_handle_job(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
3604
3729
3605
3730
/* result for successful */
3606
3731
bsg_reply -> result = 0 ;
3732
+ done :
3607
3733
3608
3734
lpfc_printf_log (phba , KERN_INFO , LOG_LIBDFC ,
3609
3735
"2937 SLI_CONFIG ext-buffer mailbox command "
3610
3736
"(x%x/x%x) complete bsg job done, bsize:%d\n" ,
3611
3737
phba -> mbox_ext_buf_ctx .nembType ,
3612
- phba -> mbox_ext_buf_ctx .mboxType , size );
3738
+ phba -> mbox_ext_buf_ctx .mboxType ,
3739
+ job -> reply_payload .payload_len );
3613
3740
lpfc_idiag_mbxacc_dump_bsg_mbox (phba ,
3614
3741
phba -> mbox_ext_buf_ctx .nembType ,
3615
3742
phba -> mbox_ext_buf_ctx .mboxType ,
@@ -3819,14 +3946,16 @@ lpfc_bsg_sli_cfg_read_cmd_ext(struct lpfc_hba *phba, struct bsg_job *job,
3819
3946
{
3820
3947
struct fc_bsg_request * bsg_request = job -> request ;
3821
3948
struct lpfc_sli_config_mbox * sli_cfg_mbx ;
3949
+ struct lpfc_sli_config_emb0_subsys * emb0_subsys ;
3950
+ struct list_head * ext_dmabuf_list ;
3822
3951
struct dfc_mbox_req * mbox_req ;
3823
3952
struct lpfc_dmabuf * curr_dmabuf , * next_dmabuf ;
3824
- uint32_t ext_buf_cnt , ext_buf_index ;
3953
+ u32 ext_buf_cnt , ext_buf_index , hbd_cnt ;
3825
3954
struct lpfc_dmabuf * ext_dmabuf = NULL ;
3826
3955
struct bsg_job_data * dd_data = NULL ;
3827
3956
LPFC_MBOXQ_t * pmboxq = NULL ;
3828
3957
MAILBOX_t * pmb ;
3829
- uint8_t * pmbx ;
3958
+ u8 * pmbx , opcode ;
3830
3959
int rc , i ;
3831
3960
3832
3961
mbox_req =
@@ -3836,8 +3965,9 @@ lpfc_bsg_sli_cfg_read_cmd_ext(struct lpfc_hba *phba, struct bsg_job *job,
3836
3965
sli_cfg_mbx = (struct lpfc_sli_config_mbox * )dmabuf -> virt ;
3837
3966
3838
3967
if (nemb_tp == nemb_mse ) {
3968
+ emb0_subsys = & sli_cfg_mbx -> un .sli_config_emb0_subsys ;
3839
3969
ext_buf_cnt = bsg_bf_get (lpfc_mbox_hdr_mse_cnt ,
3840
- & sli_cfg_mbx -> un . sli_config_emb0_subsys . sli_config_hdr );
3970
+ & emb0_subsys -> sli_config_hdr );
3841
3971
if (ext_buf_cnt > LPFC_MBX_SLI_CONFIG_MAX_MSE ) {
3842
3972
lpfc_printf_log (phba , KERN_ERR , LOG_LIBDFC ,
3843
3973
"2945 Handled SLI_CONFIG(mse) rd, "
@@ -3847,6 +3977,57 @@ lpfc_bsg_sli_cfg_read_cmd_ext(struct lpfc_hba *phba, struct bsg_job *job,
3847
3977
rc = - ERANGE ;
3848
3978
goto job_error ;
3849
3979
}
3980
+
3981
+ /* Special handling for non-embedded READ_OBJECT */
3982
+ opcode = bsg_bf_get (lpfc_emb0_subcmnd_opcode , emb0_subsys );
3983
+ switch (opcode ) {
3984
+ case COMN_OPCODE_READ_OBJECT :
3985
+ hbd_cnt = bsg_bf_get (lpfc_emb0_subcmnd_rd_obj_hbd_cnt ,
3986
+ emb0_subsys );
3987
+ lpfc_printf_log (phba , KERN_INFO , LOG_LIBDFC ,
3988
+ "2449 SLI_CONFIG(mse) rd non-embedded "
3989
+ "hbd count = %d\n" ,
3990
+ hbd_cnt );
3991
+
3992
+ ext_dmabuf_list =
3993
+ & phba -> mbox_ext_buf_ctx .ext_dmabuf_list ;
3994
+
3995
+ /* Allocate hbds */
3996
+ for (i = 0 ; i < hbd_cnt ; i ++ ) {
3997
+ ext_dmabuf = lpfc_bsg_dma_page_alloc (phba );
3998
+ if (!ext_dmabuf ) {
3999
+ rc = - ENOMEM ;
4000
+ goto job_error ;
4001
+ }
4002
+ list_add_tail (& ext_dmabuf -> list ,
4003
+ ext_dmabuf_list );
4004
+ }
4005
+
4006
+ /* Fill out the physical memory addresses for the
4007
+ * hbds
4008
+ */
4009
+ i = 0 ;
4010
+ list_for_each_entry_safe (curr_dmabuf , next_dmabuf ,
4011
+ ext_dmabuf_list , list ) {
4012
+ emb0_subsys -> hbd [i ].pa_hi =
4013
+ putPaddrHigh (curr_dmabuf -> phys );
4014
+ emb0_subsys -> hbd [i ].pa_lo =
4015
+ putPaddrLow (curr_dmabuf -> phys );
4016
+
4017
+ lpfc_printf_log (phba , KERN_INFO , LOG_LIBDFC ,
4018
+ "2495 SLI_CONFIG(hbd)[%d], "
4019
+ "bufLen:%d, addrHi:x%x, "
4020
+ "addrLo:x%x\n" , i ,
4021
+ emb0_subsys -> hbd [i ].buf_len ,
4022
+ emb0_subsys -> hbd [i ].pa_hi ,
4023
+ emb0_subsys -> hbd [i ].pa_lo );
4024
+ i ++ ;
4025
+ }
4026
+ break ;
4027
+ default :
4028
+ break ;
4029
+ }
4030
+
3850
4031
lpfc_printf_log (phba , KERN_INFO , LOG_LIBDFC ,
3851
4032
"2941 Handled SLI_CONFIG(mse) rd, "
3852
4033
"ext_buf_cnt:%d\n" , ext_buf_cnt );
@@ -4223,6 +4404,7 @@ lpfc_bsg_handle_sli_cfg_mbox(struct lpfc_hba *phba, struct bsg_job *job,
4223
4404
case COMN_OPCODE_GET_CNTL_ATTRIBUTES :
4224
4405
case COMN_OPCODE_GET_PROFILE_CONFIG :
4225
4406
case COMN_OPCODE_SET_FEATURES :
4407
+ case COMN_OPCODE_READ_OBJECT :
4226
4408
lpfc_printf_log (phba , KERN_INFO , LOG_LIBDFC ,
4227
4409
"3106 Handled SLI_CONFIG "
4228
4410
"subsys_comn, opcode:x%x\n" ,
@@ -4665,8 +4847,7 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct bsg_job *job,
4665
4847
bsg_reply -> reply_payload_rcv_len = 0 ;
4666
4848
4667
4849
/* sanity check to protect driver */
4668
- if (job -> reply_payload .payload_len > BSG_MBOX_SIZE ||
4669
- job -> request_payload .payload_len > BSG_MBOX_SIZE ) {
4850
+ if (job -> request_payload .payload_len > BSG_MBOX_SIZE ) {
4670
4851
rc = - ERANGE ;
4671
4852
goto job_done ;
4672
4853
}
@@ -4737,6 +4918,19 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct bsg_job *job,
4737
4918
pmb -> mbxOwner = OWN_HOST ;
4738
4919
pmboxq -> vport = vport ;
4739
4920
4921
+ /* non-embedded SLI_CONFIG requests already parsed, check others */
4922
+ if (unlikely (job -> reply_payload .payload_len > BSG_MBOX_SIZE )) {
4923
+ lpfc_printf_log (phba , KERN_WARNING , LOG_LIBDFC ,
4924
+ "2729 Cmd x%x (x%x/x%x) request has "
4925
+ "out-of-range reply payload length x%x\n" ,
4926
+ pmb -> mbxCommand ,
4927
+ lpfc_sli_config_mbox_subsys_get (phba , pmboxq ),
4928
+ lpfc_sli_config_mbox_opcode_get (phba , pmboxq ),
4929
+ job -> reply_payload .payload_len );
4930
+ rc = - ERANGE ;
4931
+ goto job_done ;
4932
+ }
4933
+
4740
4934
/* If HBA encountered an error attention, allow only DUMP
4741
4935
* or RESTART mailbox commands until the HBA is restarted.
4742
4936
*/
0 commit comments