* Execute an NVM admin command. * Lock must be held when calling this function. */
| 269 | * Lock must be held when calling this function. |
| 270 | */ |
| 271 | static int execute_command(struct local_admin* admin, const nvm_cmd_t* cmd, nvm_cpl_t* cpl) |
| 272 | { |
| 273 | nvm_cmd_t local_copy; |
| 274 | nvm_cmd_t* in_queue_cmd; |
| 275 | nvm_cpl_t* in_queue_cpl; |
| 276 | |
| 277 | // Try to enqueue a message |
| 278 | if ((in_queue_cmd = nvm_sq_enqueue(&admin->asq)) == NULL) |
| 279 | { |
| 280 | // Queue was full, but we're holding the lock so no blocking |
| 281 | return EAGAIN; |
| 282 | } |
| 283 | |
| 284 | // Copy command into queue slot (but keep original id) |
| 285 | uint16_t in_queue_id = NVM_DEFAULT_CID(&admin->asq); |
| 286 | |
| 287 | memcpy(&local_copy, cmd, sizeof(nvm_cmd_t)); |
| 288 | |
| 289 | *NVM_CMD_CID(&local_copy) = in_queue_id; |
| 290 | *in_queue_cmd = local_copy; |
| 291 | |
| 292 | //for (int i = 0; i < 16; i++) { |
| 293 | // printf("cmd: %p\tdword[%d] = %x\n", in_queue_cmd, i, local_copy.dword[i]); |
| 294 | //} |
| 295 | std::atomic_thread_fence(std::memory_order_seq_cst); |
| 296 | // Submit command and wait for completion |
| 297 | nvm_sq_submit(&admin->asq); |
| 298 | std::atomic_thread_fence(std::memory_order_seq_cst); |
| 299 | in_queue_cpl = nvm_cq_dequeue_block(&admin->acq, admin->timeout); |
| 300 | if (in_queue_cpl == NULL) |
| 301 | { |
| 302 | dprintf("Waiting for admin queue completion timed out\n"); |
| 303 | return ETIME; |
| 304 | } |
| 305 | std::atomic_thread_fence(std::memory_order_seq_cst); |
| 306 | //for (int i = 0; i < 4; i++) { |
| 307 | // printf("cpl: %p\tdword[%d] = %x\n", in_queue_cpl, i, in_queue_cpl->dword[i]); |
| 308 | |
| 309 | //} |
| 310 | //printf("cpl cmd_id: %u\tstatus and phase: %x\n", in_queue_cpl->dword[3] & 0x0000ffff, in_queue_cpl->dword[3] >> 16); |
| 311 | |
| 312 | nvm_sq_update(&admin->asq); |
| 313 | std::atomic_thread_fence(std::memory_order_seq_cst); |
| 314 | // Copy completion and return |
| 315 | *cpl = *in_queue_cpl; |
| 316 | std::atomic_thread_fence(std::memory_order_seq_cst); |
| 317 | nvm_cq_update(&admin->acq); |
| 318 | |
| 319 | //*NVM_CPL_CID(cpl) = *NVM_CMD_CID(cmd); |
| 320 | |
| 321 | return 0; |
| 322 | } |
| 323 | |
| 324 | |
| 325 |
no test coverage detected