hw->aq.asq_last_status);
                } else {
                        status = i40e_nvmupd_nvm_read(hw, cmd, bytes, perrno);
-                       hw->nvmupd_state = I40E_NVMUPD_STATE_READING;
+                       if (status)
+                               i40e_release_nvm(hw);
+                       else
+                               hw->nvmupd_state = I40E_NVMUPD_STATE_READING;
                }
                break;
 
                                                     hw->aq.asq_last_status);
                } else {
                        status = i40e_nvmupd_nvm_write(hw, cmd, bytes, perrno);
-                       hw->nvmupd_state = I40E_NVMUPD_STATE_WRITING;
+                       if (status)
+                               i40e_release_nvm(hw);
+                       else
+                               hw->nvmupd_state = I40E_NVMUPD_STATE_WRITING;
                }
                break;
 
                break;
 
        default:
+               i40e_debug(hw, I40E_DEBUG_NVM,
+                          "NVMUPD: bad cmd %s in init state\n",
+                          i40e_nvm_update_state_str[upd_cmd]);
                status = I40E_ERR_NVM;
                *perrno = -ESRCH;
                break;
 
        case I40E_NVMUPD_WRITE_LCB:
                status = i40e_nvmupd_nvm_write(hw, cmd, bytes, perrno);
-               if (!status) {
+               if (!status)
                        hw->aq.nvm_release_on_done = true;
-                       hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
-               }
+               hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
                break;
 
        case I40E_NVMUPD_CSUM_CON:
                status = i40e_update_nvm_checksum(hw);
-               if (status)
+               if (status) {
                        *perrno = hw->aq.asq_last_status ?
                                   i40e_aq_rc_to_posix(status,
                                                       hw->aq.asq_last_status) :
                                   -EIO;
+                       hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
+               }
                break;
 
        case I40E_NVMUPD_CSUM_LCB:
                status = i40e_update_nvm_checksum(hw);
-               if (status) {
+               if (status)
                        *perrno = hw->aq.asq_last_status ?
                                   i40e_aq_rc_to_posix(status,
                                                       hw->aq.asq_last_status) :
                                   -EIO;
-               } else {
+               else
                        hw->aq.nvm_release_on_done = true;
-                       hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
-               }
+               hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
                break;
 
        default:
+               i40e_debug(hw, I40E_DEBUG_NVM,
+                          "NVMUPD: bad cmd %s in writing state.\n",
+                          i40e_nvm_update_state_str[upd_cmd]);
                status = I40E_NOT_SUPPORTED;
                *perrno = -ESRCH;
                break;