2727#include <ccan/endian/endian.h>
2828
2929#include "ioctl.h"
30- #include "util.h"
31- #include "log.h"
3230#include "private.h"
3331
3432static int nvme_verify_chr (struct nvme_transport_handle * hdl )
@@ -100,17 +98,23 @@ int nvme_get_nsid(struct nvme_transport_handle *hdl, __u32 *nsid)
10098}
10199
102100__attribute__((weak ))
103- int nvme_submit_passthru (struct nvme_transport_handle * hdl ,
104- unsigned long ioctl_cmd , struct nvme_passthru_cmd * cmd ,
105- __u64 * result )
101+ void * nvme_submit_entry (struct nvme_transport_handle * hdl ,
102+ struct nvme_passthru_cmd * cmd )
106103{
107- int err = ioctl (hdl -> fd , ioctl_cmd , cmd );
104+ return NULL ;
105+ }
108106
109- if (err >= 0 && result )
110- * result = cmd -> result ;
111- if (err < 0 )
112- return - errno ;
113- return err ;
107+ __attribute__((weak ))
108+ void nvme_submit_exit (struct nvme_transport_handle * hdl ,
109+ struct nvme_passthru_cmd * cmd , int err , void * user_data )
110+ {
111+ }
112+
113+ __attribute__((weak ))
114+ bool nvme_decide_retry (struct nvme_transport_handle * hdl ,
115+ struct nvme_passthru_cmd * cmd , int err )
116+ {
117+ return false;
114118}
115119
116120/*
@@ -122,17 +126,30 @@ static int nvme_submit_passthru32(struct nvme_transport_handle *hdl,
122126 __u64 * result )
123127{
124128 struct linux_passthru_cmd32 cmd32 ;
125- int err ;
129+ void * user_data ;
130+ int err = 0 ;
131+
132+ user_data = nvme_submit_entry (hdl , cmd );
133+ if (hdl -> ctx -> dry_run )
134+ goto out ;
126135
127136 memcpy (& cmd32 , cmd , offsetof(struct linux_passthru_cmd32 , result ));
128137 cmd32 .result = 0 ;
129138
130- err = ioctl (hdl -> fd , ioctl_cmd , cmd );
139+ do {
140+ err = ioctl (hdl -> fd , ioctl_cmd , & cmd32 );
141+ if (err >= 0 )
142+ break ;
143+ } while (nvme_decide_retry (hdl , cmd , - errno ));
144+
131145 cmd -> result = cmd32 .result ;
132146 if (err >= 0 && result )
133147 * result = cmd -> result ;
134148 if (err < 0 )
135- return - errno ;
149+ err = - errno ;
150+
151+ out :
152+ nvme_submit_exit (hdl , cmd , err , user_data );
136153 return err ;
137154}
138155
@@ -144,9 +161,26 @@ static int nvme_submit_passthru64(struct nvme_transport_handle *hdl,
144161 unsigned long ioctl_cmd , struct nvme_passthru_cmd * cmd ,
145162 __u64 * result )
146163{
147- int err ;
164+ void * user_data ;
165+ int err = 0 ;
166+
167+ user_data = nvme_submit_entry (hdl , cmd );
168+ if (hdl -> ctx -> dry_run )
169+ goto out ;
170+
171+ do {
172+ /*
173+ * struct nvme_passtrhu_cmd is identically to struct
174+ * linux_passthru_cmd64, thus just pass it in directly.
175+ */
176+ err = ioctl (hdl -> fd , ioctl_cmd , cmd );
177+ if (err >= 0 )
178+ break ;
179+ } while (nvme_decide_retry (hdl , cmd , - errno ));
180+
181+ out :
182+ nvme_submit_exit (hdl , cmd , err , user_data );
148183
149- err = ioctl (hdl -> fd , ioctl_cmd , cmd );
150184 if (err >= 0 && result )
151185 * result = cmd -> result ;
152186 if (err < 0 )
0 commit comments