diff --git a/drivers/nvme/nvme.asm b/drivers/nvme/nvme.asm index a0a2a4f..616d318 100644 --- a/drivers/nvme/nvme.asm +++ b/drivers/nvme/nvme.asm @@ -1250,21 +1250,60 @@ endp proc nvme_cleanup - DEBUGF DBG_INFO, "(NVMe): Cleaning up...\n" - mov ecx, dword [pcidevs_len] - mov eax, dword [p_nvme_devices] - test eax, eax - jnz .loop + mov esi, dword [p_nvme_devices] + test esi, esi + jnz @f ret -.loop: - ;invoke KernelFree, dword [p_nvme_devices + ecx * sizeof.pcidev + pcidev.ident_ptr] - dec ecx - test ecx, ecx - jnz .loop - invoke KernelFree, dword [p_nvme_devices] - @@: + mov ebx, dword [pcidevs_len] + sub esi, sizeof.pcidev + +.get_pcidev: + add esi, sizeof.pcidev + + ; Free the queues + mov edi, dword [esi + pcidev.queue_entries] + test edi, edi + jz .free_pcidevs + sub edi, sizeof.NVM_QUEUE_ENTRY + xor ecx, ecx + +.get_queue: + add edi, sizeof.NVM_QUEUE_ENTRY + + ; TODO: Delete the I/O completion and submission queue + ; Remember, we have to free the completion queue before + ; the submission queue + push ecx + invoke KernelFree, dword [edi + NVM_QUEUE_ENTRY.cq_ptr] + invoke KernelFree, dword [edi + NVM_QUEUE_ENTRY.sq_ptr] + pop ecx + + ; Free the commands and their respective mutexes + push edi ecx + xor ecx, ecx + mov edi, dword [edi + NVM_QUEUE_ENTRY.cmd_ptr] + sub edi, sizeof.NVMQCMD + +.get_cmd: + add edi, sizeof.NVMQCMD + push ecx + invoke KernelFree, dword [edi + NVMQCMD.mutex_ptr] + pop ecx + inc ecx + cmp ecx, SQ_ENTRIES + jne .get_cmd + pop ecx edi + + inc ecx + cmp ecx, LAST_QUEUE_ID + jne .get_queue + + invoke KernelFree, dword [esi + pcidev.queue_entries] + +.free_pcidevs: + invoke KernelFree, dword [p_nvme_devices] ret endp