diff --git a/drivers/nvme/nvme.asm b/drivers/nvme/nvme.asm index b609c25..0b3502c 100644 --- a/drivers/nvme/nvme.asm +++ b/drivers/nvme/nvme.asm @@ -36,9 +36,14 @@ proc START c, reason:dword .entry: DEBUGF DBG_INFO, "Detecting NVMe hardware...\n" call detect_nvme + test eax, eax + jz .err mov eax, dword [p_nvme_devices] test eax, eax - jz .err ; no NVMe device found? + jz .err + stdcall device_is_compat, dword [eax + pcidev.bus], dword [eax + pcidev.devfn] + test eax, eax + jz .err mov eax, dword [eax] stdcall nvme_init, dword [eax + pcidev.bus], dword [eax + pcidev.devfn] @@ -49,6 +54,7 @@ proc START c, reason:dword ret .err: + DEBUGF DBG_INFO, "(NVMe): driver failed to initialize" call nvme_cleanup xor eax, eax ret @@ -76,14 +82,14 @@ endp proc memset stdcall, p_data:dword, val:byte, sz:dword - mov bh, byte [val] + mov edx, [sz] + mov bh, [val] xor ecx, ecx @@: mov byte [p_data + ecx], bh inc ecx - cmp ecx, dword [sz] + cmp ecx, edx jne @b - xor eax, eax ret endp @@ -131,46 +137,46 @@ proc detect_nvme mov eax, dword [eax + PCIDEV.fd] cmp eax, edx jne .check_dev - ret + jmp .exit_success .found_dev: - PDEBUGF DBG_INFO, "PCI(%u.%u.%u): Detected NVMe device...\n", [eax + PCIDEV.bus], byte [eax + PCIDEV.devfn] - push eax - mov eax, dword [pcidevs_len] - cmp eax, MAX_NVM_PCIDEVS + push edx eax + PDEBUGF DBG_INFO, "PCI(%u.%u.%u): Detected NVMe device...\n", byte [eax + PCIDEV.bus], [eax + PCIDEV.devfn] + cmp dword [pcidevs_len], TOTAL_PCIDEVS jne @f - pop eax - ret + pop eax edx + jmp .exit_success @@: + inc dword [pcidevs_len] mov ebx, dword [p_nvme_devices] test ebx, ebx jnz @f - invoke KernelAlloc, MAX_NVM_PCIDEVS_BYTES + invoke KernelAlloc, TOTAL_PCIDEVS_MALLOC_SZ test eax, eax - jz .err - mov dword [ebx], eax + jz .err_no_mem + mov dword [p_nvme_devices], eax @@: + mov ebx, dword [p_nvme_devices] mov ecx, dword [pcidevs_len] - inc ecx - mov dword [pcidevs_len], ecx - invoke KernelAlloc, sizeof.pcidev - test eax, eax - jz .err - - mov dword [p_nvme_devices + ecx * 4], eax - mov ebx, eax + dec ecx pop eax - mov ecx, dword [eax + PCIDEV.bus] - mov dword [ebx + pcidev.bus], ecx - mov ecx, dword [eax + PCIDEV.devfn] - mov dword [ebx + pcidev.devfn], ecx - jmp .check_dev + movzx edx, byte [eax + PCIDEV.bus] + mov byte [ebx + ecx * sizeof.pcidev + pcidev.bus], dl + movzx edx, byte [eax + PCIDEV.devfn] + mov byte [ebx + ecx * sizeof.pcidev + pcidev.devfn], dl + pop edx + jmp .next_dev -.err: - pop eax - PDEBUGF DBG_INFO, "PCI(%u.%u.%u): error initializing NVMe driver, unable to allocate memory\n", [eax + PCIDEV.bus], byte [eax + PCIDEV.devfn] +.err_no_mem: + pop eax edx + xor eax, eax + ret + +.exit_success: + xor eax, eax + inc eax ret endp @@ -186,9 +192,12 @@ proc device_is_compat, bus:dword, devfn:dword test eax, eax jz .exit_fail mov [p_mmap], eax + xor eax, eax + inc eax + ret .exit_fail: - PDEBUGF DBG_INFO, "PCI(%u.%u.%u): incompatible NVMe device\n", [bus], byte [devfn] + PDEBUGF DBG_INFO, "PCI(%u.%u.%u): incompatible NVMe device\n", byte [bus], byte [devfn] xor eax, eax ret @@ -201,10 +210,10 @@ proc nvme_init, bus:dword, devfn:dword jz .exit_fail mov eax, dword [p_mmap] mov ebx, dword [eax + NVME_REG_MAP.CAP] - PDEBUGF DBG_INFO, "PCI(%u.%u.%u): NVMe maximum queue entries supported: %u\n", [bus], byte [devfn], bx + PDEBUGF DBG_INFO, "PCI(%u.%u.%u): NVMe maximum queue entries supported: %u\n", byte [bus], byte [devfn], bx test ebx, CAP_CQR jz .cqr_not_req - PDEBUGF DBG_INFO, "PCI(%u.%u.%u): NVMe contiguous queues required\n", [bus], byte [devfn] + PDEBUGF DBG_INFO, "PCI(%u.%u.%u): NVMe contiguous queues required\n", byte [bus], byte [devfn] .cqr_not_req: mov ebx, dword [eax + NVME_REG_MAP.CAP + 4] @@ -217,8 +226,8 @@ proc nvme_init, bus:dword, devfn:dword and ecx, CAP_MPSMAX shr ebx, 16 shr ecx, 16 - PDEBUGF DBG_INFO, "PCI(%u.%u.%u): NVMe memory page size minimum: %u\n", [bus], byte [devfn], ebx - PDEBUGF DBG_INFO, "PCI(%u.%u.%u): NVMe memory page size maximum: %u\n", [bus], byte [devfn], ecx + PDEBUGF DBG_INFO, "PCI(%u.%u.%u): NVMe memory page size minimum: %u\n", byte [bus], byte [devfn], ebx + PDEBUGF DBG_INFO, "PCI(%u.%u.%u): NVMe memory page size maximum: %u\n", byte [bus], byte [devfn], ecx mov ebx, dword [eax + NVME_REG_MAP.CC] mov ecx, ebx @@ -228,8 +237,8 @@ proc nvme_init, bus:dword, devfn:dword shl ecx, 16 ; TODO: Change entry sizes to their appropriate values - PDEBUGF DBG_INFO, "PCI(%u.%u.%u): NVMe I/O submission queue entry size: %u\n", [bus], byte [devfn], ebx - PDEBUGF DBG_INFO, "PCI(%u.%u.%u): NVMe I/O completion queue entry size: %u\n", [bus], byte [devfn], ecx + PDEBUGF DBG_INFO, "PCI(%u.%u.%u): NVMe I/O submission queue entry size: %u\n", byte [bus], byte [devfn], ebx + PDEBUGF DBG_INFO, "PCI(%u.%u.%u): NVMe I/O completion queue entry size: %u\n", byte [bus], byte [devfn], ecx end if xor eax, eax @@ -237,7 +246,7 @@ proc nvme_init, bus:dword, devfn:dword ret .exit_fail: - PDEBUGF DBG_INFO, "PCI(%u.%u.%u): failed to initialize NVMe controller\n", [bus], byte [devfn] + PDEBUGF DBG_INFO, "PCI(%u.%u.%u): failed to initialize NVMe controller\n", byte [bus], byte [devfn] xor eax, eax ret @@ -246,23 +255,8 @@ endp proc nvme_cleanup DEBUGF DBG_INFO, "(NVMe): Cleaning up...\n" - xor ecx, ecx - mov eax, dword [p_nvme_devices] - test eax, eax - jz .last - -@@: - mov ebx, dword [eax + ecx * 4] - invoke KernelFree, ebx - inc ecx - cmp ecx, dword [pcidevs_len] - jl @b - mov eax, dword [p_ident] - test eax, eax - jz .last - invoke KernelFree, eax - -.last: + invoke KernelFree, [p_nvme_devices] + invoke KernelFree, [p_ident] ret endp