@@ -715,85 +715,80 @@ int nvme_mi_admin_xfer(nvme_mi_ctrl_t ctrl,
715715 return 0 ;
716716}
717717
718- int nvme_mi_admin_admin_passthru (nvme_mi_ctrl_t ctrl , __u8 opcode , __u8 flags ,
719- __u16 rsvd , __u32 nsid , __u32 cdw2 , __u32 cdw3 ,
720- __u32 cdw10 , __u32 cdw11 , __u32 cdw12 ,
721- __u32 cdw13 , __u32 cdw14 , __u32 cdw15 ,
722- __u32 data_len , void * data , __u32 metadata_len ,
723- void * metadata , __u32 timeout_ms , __u32 * result )
718+ int nvme_mi_admin_passthru (nvme_mi_ctrl_t ctrl , struct nvme_passthru_cmd * cmd , __u32 * result )
724719{
725- /* Input parameters flags, rsvd, metadata, metadata_len are not used */
726720 struct nvme_mi_admin_resp_hdr resp_hdr ;
727721 struct nvme_mi_admin_req_hdr req_hdr ;
728722 struct nvme_mi_resp resp ;
729723 struct nvme_mi_req req ;
730- unsigned int timeout_save ;
724+ unsigned int timeout_save = 0 ;
731725 int rc ;
732- int direction = opcode & 0x3 ;
726+ int direction = cmd -> opcode & 0x3 ;
733727 bool has_write_data = false;
734728 bool has_read_data = false;
735729
736730 if (direction == NVME_DATA_TFR_BIDIRECTIONAL ) {
737731 nvme_msg (ctrl -> ep -> root , LOG_ERR ,
738- "nvme_mi_admin_admin_passthru doesn't support bidirectional commands\n" );
732+ "%s doesn't support bidirectional commands\n", __func__ );
739733 errno = EINVAL ;
740734 return -1 ;
741735 }
742736
743- if (data_len > 4096 ) {
737+ if (cmd -> data_len > 4096 ) {
744738 nvme_msg (ctrl -> ep -> root , LOG_ERR ,
745- "nvme_mi_admin_admin_passthru doesn't support data_len over 4096 bytes.\n" );
739+ "%s doesn't support data_len over 4096 bytes.\n", __func__ );
746740 errno = EINVAL ;
747741 return -1 ;
748742 }
749743
750- if (data != NULL && data_len != 0 ) {
744+ if (cmd -> addr && cmd -> data_len ) {
751745 if (direction == NVME_DATA_TFR_HOST_TO_CTRL )
752746 has_write_data = true;
753747 if (direction == NVME_DATA_TFR_CTRL_TO_HOST )
754748 has_read_data = true;
755749 }
756750
757- nvme_mi_admin_init_req (& req , & req_hdr , ctrl -> id , opcode );
758- req_hdr .cdw1 = cpu_to_le32 (nsid );
759- req_hdr .cdw2 = cpu_to_le32 (cdw2 );
760- req_hdr .cdw3 = cpu_to_le32 (cdw3 );
761- req_hdr .cdw10 = cpu_to_le32 (cdw10 );
762- req_hdr .cdw11 = cpu_to_le32 (cdw11 );
763- req_hdr .cdw12 = cpu_to_le32 (cdw12 );
764- req_hdr .cdw13 = cpu_to_le32 (cdw13 );
765- req_hdr .cdw14 = cpu_to_le32 (cdw14 );
766- req_hdr .cdw15 = cpu_to_le32 (cdw15 );
751+ nvme_mi_admin_init_req (& req , & req_hdr , ctrl -> id , cmd -> opcode );
752+ req_hdr .cdw1 = cpu_to_le32 (cmd -> nsid );
753+ req_hdr .cdw2 = cpu_to_le32 (cmd -> cdw2 );
754+ req_hdr .cdw3 = cpu_to_le32 (cmd -> cdw3 );
755+ req_hdr .cdw10 = cpu_to_le32 (cmd -> cdw10 );
756+ req_hdr .cdw11 = cpu_to_le32 (cmd -> cdw11 );
757+ req_hdr .cdw12 = cpu_to_le32 (cmd -> cdw12 );
758+ req_hdr .cdw13 = cpu_to_le32 (cmd -> cdw13 );
759+ req_hdr .cdw14 = cpu_to_le32 (cmd -> cdw14 );
760+ req_hdr .cdw15 = cpu_to_le32 (cmd -> cdw15 );
767761 req_hdr .doff = 0 ;
768- if (data_len != 0 ) {
769- req_hdr .dlen = cpu_to_le32 (data_len );
762+ if (cmd -> data_len ) {
763+ req_hdr .dlen = cpu_to_le32 (cmd -> data_len );
770764 /* Bit 0 set to 1 means DLEN contains a value */
771765 req_hdr .flags = 0x1 ;
772766 }
773767
774768 if (has_write_data ) {
775- req .data = data ;
776- req .data_len = data_len ;
769+ req .data = ( void * ) cmd -> addr ;
770+ req .data_len = cmd -> data_len ;
777771 }
778772
779773 nvme_mi_calc_req_mic (& req );
780774
781775 nvme_mi_admin_init_resp (& resp , & resp_hdr );
782776
783777 if (has_read_data ) {
784- resp .data = data ;
785- resp .data_len = data_len ;
778+ resp .data = ( void * ) cmd -> addr ;
779+ resp .data_len = cmd -> data_len ;
786780 }
787781
788- /* if the user has specified a custom timeout, save the current
782+ /*
783+ * if the user has specified a custom timeout, save the current
789784 * timeout and override
790785 */
791- if (timeout_ms != 0 ) {
786+ if (cmd -> timeout_ms ) {
792787 timeout_save = nvme_mi_ep_get_timeout (ctrl -> ep );
793- nvme_mi_ep_set_timeout (ctrl -> ep , timeout_ms );
788+ nvme_mi_ep_set_timeout (ctrl -> ep , cmd -> timeout_ms );
794789 }
795790 rc = nvme_mi_submit (ctrl -> ep , & req , & resp );
796- if (timeout_ms != 0 )
791+ if (cmd -> timeout_ms )
797792 nvme_mi_ep_set_timeout (ctrl -> ep , timeout_save );
798793
799794 if (rc )
@@ -803,14 +798,43 @@ int nvme_mi_admin_admin_passthru(nvme_mi_ctrl_t ctrl, __u8 opcode, __u8 flags,
803798 if (rc )
804799 return rc ;
805800
806- if (has_read_data && (resp .data_len != data_len )) {
801+ if (has_read_data && (resp .data_len != cmd -> data_len )) {
807802 errno = EPROTO ;
808803 return -1 ;
809804 }
810805
811806 return 0 ;
812807}
813808
809+ __attribute__((weak ))
810+ int nvme_mi_admin_admin_passthru (nvme_mi_ctrl_t ctrl , __u8 opcode , __u8 flags , __u16 rsvd ,
811+ __u32 nsid , __u32 cdw2 , __u32 cdw3 , __u32 cdw10 , __u32 cdw11 ,
812+ __u32 cdw12 , __u32 cdw13 , __u32 cdw14 , __u32 cdw15 , __u32 data_len ,
813+ void * data , __u32 metadata_len , void * metadata , __u32 timeout_ms ,
814+ __u32 * result )
815+ {
816+ /* Input parameters flags, rsvd, metadata, metadata_len are not used */
817+ struct nvme_passthru_cmd cmd = {
818+ .opcode = opcode ,
819+ .flags = flags ,
820+ .rsvd1 = rsvd ,
821+ .nsid = nsid ,
822+ .cdw2 = cdw2 ,
823+ .cdw3 = cdw3 ,
824+ .addr = (__u64 )(uintptr_t )data ,
825+ .data_len = data_len ,
826+ .cdw10 = cdw10 ,
827+ .cdw11 = cdw11 ,
828+ .cdw12 = cdw12 ,
829+ .cdw13 = cdw13 ,
830+ .cdw14 = cdw14 ,
831+ .cdw15 = cdw15 ,
832+ .timeout_ms = timeout_ms ,
833+ };
834+
835+ return nvme_mi_admin_passthru (ctrl , & cmd , result );
836+ }
837+
814838int nvme_mi_admin_identify_partial (nvme_mi_ctrl_t ctrl ,
815839 struct nvme_identify_args * args ,
816840 off_t offset , size_t size )
0 commit comments