@@ -100,9 +100,9 @@ int nvme_get_nsid(struct nvme_transport_handle *hdl, __u32 *nsid)
100100}
101101
102102__attribute__((weak ))
103- int nvme_submit_passthru64 (struct nvme_transport_handle * hdl , unsigned long ioctl_cmd ,
104- struct nvme_passthru_cmd64 * cmd ,
105- __u64 * result )
103+ int nvme_submit_passthru (struct nvme_transport_handle * hdl ,
104+ unsigned long ioctl_cmd , struct nvme_passthru_cmd * cmd ,
105+ __u64 * result )
106106{
107107 int err = ioctl (hdl -> fd , ioctl_cmd , cmd );
108108
@@ -113,132 +113,77 @@ int nvme_submit_passthru64(struct nvme_transport_handle *hdl, unsigned long ioct
113113 return err ;
114114}
115115
116- __attribute__((weak ))
117- int nvme_submit_passthru (struct nvme_transport_handle * hdl , unsigned long ioctl_cmd ,
118- struct nvme_passthru_cmd * cmd , __u32 * result )
116+ /*
117+ * The 64 bit version is the preferred version to use, but for backwards
118+ * compatibility keep a 32 version.
119+ */
120+ static int nvme_submit_passthru32 (struct nvme_transport_handle * hdl ,
121+ unsigned long ioctl_cmd , struct nvme_passthru_cmd * cmd ,
122+ __u64 * result )
119123{
120- int err = ioctl (hdl -> fd , ioctl_cmd , cmd );
124+ struct linux_passthru_cmd32 cmd32 ;
125+ int err ;
126+
127+ memcpy (& cmd32 , cmd , offsetof(struct linux_passthru_cmd32 , result ));
128+ cmd32 .result = 0 ;
121129
130+ err = ioctl (hdl -> fd , ioctl_cmd , & cmd32 );
131+ cmd -> result = cmd32 .result ;
122132 if (err >= 0 && result )
123133 * result = cmd -> result ;
124134 if (err < 0 )
125135 return - errno ;
126136 return err ;
127137}
128138
129- static int nvme_passthru64 (struct nvme_transport_handle * hdl , unsigned long ioctl_cmd , __u8 opcode ,
130- __u8 flags , __u16 rsvd , __u32 nsid , __u32 cdw2 ,
131- __u32 cdw3 , __u32 cdw10 , __u32 cdw11 , __u32 cdw12 ,
132- __u32 cdw13 , __u32 cdw14 , __u32 cdw15 ,
133- __u32 data_len , void * data , __u32 metadata_len ,
134- void * metadata , __u32 timeout_ms , __u64 * result )
135- {
136- struct nvme_passthru_cmd64 cmd = {
137- .opcode = opcode ,
138- .flags = flags ,
139- .rsvd1 = rsvd ,
140- .nsid = nsid ,
141- .cdw2 = cdw2 ,
142- .cdw3 = cdw3 ,
143- .metadata = (__u64 )(uintptr_t )metadata ,
144- .addr = (__u64 )(uintptr_t )data ,
145- .metadata_len = metadata_len ,
146- .data_len = data_len ,
147- .cdw10 = cdw10 ,
148- .cdw11 = cdw11 ,
149- .cdw12 = cdw12 ,
150- .cdw13 = cdw13 ,
151- .cdw14 = cdw14 ,
152- .cdw15 = cdw15 ,
153- .timeout_ms = timeout_ms ,
154- };
155-
156- return nvme_submit_passthru64 (hdl , ioctl_cmd , & cmd , result );
157- }
158-
159- static int nvme_passthru (struct nvme_transport_handle * hdl , unsigned long ioctl_cmd , __u8 opcode ,
160- __u8 flags , __u16 rsvd , __u32 nsid , __u32 cdw2 ,
161- __u32 cdw3 , __u32 cdw10 , __u32 cdw11 , __u32 cdw12 ,
162- __u32 cdw13 , __u32 cdw14 , __u32 cdw15 , __u32 data_len ,
163- void * data , __u32 metadata_len , void * metadata ,
164- __u32 timeout_ms , __u32 * result )
139+ /*
140+ * supported since kernel 5.4, see
141+ * 65e68edce0db ("nvme: allow 64-bit results in passthru commands")
142+ */
143+ static int nvme_submit_passthru64 (struct nvme_transport_handle * hdl ,
144+ unsigned long ioctl_cmd , struct nvme_passthru_cmd * cmd ,
145+ __u64 * result )
165146{
166- struct nvme_passthru_cmd cmd = {
167- .opcode = opcode ,
168- .flags = flags ,
169- .rsvd1 = rsvd ,
170- .nsid = nsid ,
171- .cdw2 = cdw2 ,
172- .cdw3 = cdw3 ,
173- .metadata = (__u64 )(uintptr_t )metadata ,
174- .addr = (__u64 )(uintptr_t )data ,
175- .metadata_len = metadata_len ,
176- .data_len = data_len ,
177- .cdw10 = cdw10 ,
178- .cdw11 = cdw11 ,
179- .cdw12 = cdw12 ,
180- .cdw13 = cdw13 ,
181- .cdw14 = cdw14 ,
182- .cdw15 = cdw15 ,
183- .timeout_ms = timeout_ms ,
184- };
185-
186- return nvme_submit_passthru (hdl , ioctl_cmd , & cmd , result );
187- }
147+ int err ;
188148
189- int nvme_submit_admin_passthru64 (struct nvme_transport_handle * hdl , struct nvme_passthru_cmd64 * cmd ,
190- __u64 * result )
191- {
192- return nvme_submit_passthru64 (hdl , NVME_IOCTL_ADMIN64_CMD , cmd , result );
149+ err = ioctl (hdl -> fd , ioctl_cmd , cmd );
150+ if (err >= 0 && result )
151+ * result = cmd -> result ;
152+ if (err < 0 )
153+ return - errno ;
154+ return err ;
193155}
194156
195- int nvme_admin_passthru64 (struct nvme_transport_handle * hdl , __u8 opcode , __u8 flags , __u16 rsvd ,
196- __u32 nsid , __u32 cdw2 , __u32 cdw3 , __u32 cdw10 ,
197- __u32 cdw11 , __u32 cdw12 , __u32 cdw13 , __u32 cdw14 ,
198- __u32 cdw15 , __u32 data_len , void * data ,
199- __u32 metadata_len , void * metadata , __u32 timeout_ms ,
200- __u64 * result )
157+ int nvme_submit_io_passthru (struct nvme_transport_handle * hdl ,
158+ struct nvme_passthru_cmd * cmd , __u64 * result )
201159{
202- return nvme_passthru64 (hdl , NVME_IOCTL_ADMIN64_CMD , opcode , flags , rsvd ,
203- nsid , cdw2 , cdw3 , cdw10 , cdw11 , cdw12 , cdw13 ,
204- cdw14 , cdw15 , data_len , data , metadata_len ,
205- metadata , timeout_ms , result );
160+ if (hdl -> ioctl64 )
161+ return nvme_submit_passthru64 ( hdl ,
162+ NVME_IOCTL_IO64_CMD , cmd , result );
163+ return nvme_submit_passthru32 ( hdl , NVME_IOCTL_IO_CMD , cmd , result );
206164}
207165
208- int nvme_submit_admin_passthru (struct nvme_transport_handle * hdl , struct nvme_passthru_cmd * cmd , __u32 * result )
166+ int nvme_submit_admin_passthru (struct nvme_transport_handle * hdl ,
167+ struct nvme_passthru_cmd * cmd , __u64 * result )
209168{
210169 switch (hdl -> type ) {
211170 case NVME_TRANSPORT_HANDLE_TYPE_DIRECT :
212- return nvme_submit_passthru (hdl , NVME_IOCTL_ADMIN_CMD , cmd , result );
171+ if (hdl -> ioctl64 )
172+ return nvme_submit_passthru64 (hdl ,
173+ NVME_IOCTL_ADMIN64_CMD , cmd , result );
174+ if (cmd -> opcode == nvme_admin_fabrics )
175+ return - ENOTSUP ;
176+ return nvme_submit_passthru32 (hdl ,
177+ NVME_IOCTL_ADMIN_CMD , cmd , result );
213178 case NVME_TRANSPORT_HANDLE_TYPE_MI :
214- return nvme_mi_admin_admin_passthru (
215- hdl , cmd -> opcode , cmd -> flags , cmd -> rsvd1 ,
216- cmd -> nsid , cmd -> cdw2 , cmd -> cdw3 , cmd -> cdw10 ,
217- cmd -> cdw11 , cmd -> cdw12 , cmd -> cdw13 ,
218- cmd -> cdw14 , cmd -> cdw15 ,
219- cmd -> data_len , (void * )(uintptr_t )cmd -> addr ,
220- cmd -> metadata_len , (void * )(uintptr_t )cmd -> metadata ,
221- cmd -> timeout_ms , result );
179+ return nvme_mi_admin_admin_passthru (hdl , cmd , result );
222180 default :
223181 break ;
224182 }
225183
226184 return - ENOTSUP ;
227185}
228186
229- int nvme_admin_passthru (struct nvme_transport_handle * hdl , __u8 opcode , __u8 flags , __u16 rsvd ,
230- __u32 nsid , __u32 cdw2 , __u32 cdw3 , __u32 cdw10 ,
231- __u32 cdw11 , __u32 cdw12 , __u32 cdw13 , __u32 cdw14 ,
232- __u32 cdw15 , __u32 data_len , void * data ,
233- __u32 metadata_len , void * metadata , __u32 timeout_ms ,
234- __u32 * result )
235- {
236- return nvme_passthru (hdl , NVME_IOCTL_ADMIN_CMD , opcode , flags , rsvd ,
237- nsid , cdw2 , cdw3 , cdw10 , cdw11 , cdw12 , cdw13 ,
238- cdw14 , cdw15 , data_len , data , metadata_len ,
239- metadata , timeout_ms , result );
240- }
241-
242187static bool force_4k ;
243188
244189__attribute__((constructor ))
@@ -264,6 +209,8 @@ enum {
264209/*
265210 * gcc specific attribute, call automatically on the library loading.
266211 * if IORING_OP_URING_CMD is not supported, fallback to ioctl interface.
212+ *
213+ * The uring API expects the command of type struct nvme_passthru_cmd64.
267214 */
268215__attribute__((constructor ))
269216static void nvme_uring_cmd_probe ()
@@ -356,7 +303,7 @@ static bool nvme_uring_is_usable(struct nvme_transport_handle *hdl)
356303
357304int nvme_get_log (struct nvme_transport_handle * hdl ,
358305 struct nvme_passthru_cmd * cmd , bool rae ,
359- __u32 xfer_len , __u32 * result )
306+ __u32 xfer_len , __u64 * result )
360307{
361308 __u64 offset = 0 , xfer , data_len = cmd -> data_len ;
362309 __u64 start = (__u64 )cmd -> cdw13 << 32 | cmd -> cdw12 ;
@@ -580,38 +527,3 @@ int nvme_get_ana_log_atomic(struct nvme_transport_handle *hdl, bool rae, bool rg
580527
581528 return - EAGAIN ;
582529}
583-
584- int nvme_submit_io_passthru64 (struct nvme_transport_handle * hdl , struct nvme_passthru_cmd64 * cmd ,
585- __u64 * result )
586- {
587- return nvme_submit_passthru64 (hdl , NVME_IOCTL_IO64_CMD , cmd , result );
588- }
589-
590- int nvme_io_passthru64 (struct nvme_transport_handle * hdl , __u8 opcode , __u8 flags , __u16 rsvd ,
591- __u32 nsid , __u32 cdw2 , __u32 cdw3 , __u32 cdw10 ,
592- __u32 cdw11 , __u32 cdw12 , __u32 cdw13 , __u32 cdw14 ,
593- __u32 cdw15 , __u32 data_len , void * data , __u32 metadata_len ,
594- void * metadata , __u32 timeout_ms , __u64 * result )
595- {
596- return nvme_passthru64 (hdl , NVME_IOCTL_IO64_CMD , opcode , flags , rsvd ,
597- nsid , cdw2 , cdw3 , cdw10 , cdw11 , cdw12 , cdw13 ,
598- cdw14 , cdw15 , data_len , data , metadata_len , metadata ,
599- timeout_ms , result );
600- }
601-
602- int nvme_submit_io_passthru (struct nvme_transport_handle * hdl , struct nvme_passthru_cmd * cmd , __u32 * result )
603- {
604- return nvme_submit_passthru (hdl , NVME_IOCTL_IO_CMD , cmd , result );
605- }
606-
607- int nvme_io_passthru (struct nvme_transport_handle * hdl , __u8 opcode , __u8 flags , __u16 rsvd ,
608- __u32 nsid , __u32 cdw2 , __u32 cdw3 , __u32 cdw10 ,
609- __u32 cdw11 , __u32 cdw12 , __u32 cdw13 , __u32 cdw14 ,
610- __u32 cdw15 , __u32 data_len , void * data , __u32 metadata_len ,
611- void * metadata , __u32 timeout_ms , __u32 * result )
612- {
613- return nvme_passthru (hdl , NVME_IOCTL_IO_CMD , opcode , flags , rsvd , nsid ,
614- cdw2 , cdw3 , cdw10 , cdw11 , cdw12 , cdw13 , cdw14 ,
615- cdw15 , data_len , data , metadata_len , metadata ,
616- timeout_ms , result );
617- }
0 commit comments