mirror of
https://git.missingno.dev/kolibrios-nvme-driver/
synced 2025-01-03 11:25:55 +01:00
refactor: tweak some things
First of all, the driver will now abort initialization if it encounters the first found namespace LBADS is not 512, since KolibriOS doesn't support a LBADS greater than 512 as of now. This commit also removes verbose debug logs and adds appropriate error codes to nvme_readwrite
This commit is contained in:
parent
c21376dde4
commit
0eea7a6130
@ -11,8 +11,8 @@
|
|||||||
format PE DLL native
|
format PE DLL native
|
||||||
entry START
|
entry START
|
||||||
|
|
||||||
API_VERSION equ 0 ;debug
|
API_VERSION = 0 ;debug
|
||||||
SRV_GETVERSION equ 0
|
SRV_GETVERSION = 0
|
||||||
__DEBUG__ = 1
|
__DEBUG__ = 1
|
||||||
__DEBUG_LEVEL__ = 1
|
__DEBUG_LEVEL__ = 1
|
||||||
DRIVER_VERSION = 1
|
DRIVER_VERSION = 1
|
||||||
@ -58,7 +58,7 @@ proc START c, reason:dword
|
|||||||
jne .err
|
jne .err
|
||||||
|
|
||||||
.entry:
|
.entry:
|
||||||
DEBUGF DBG_INFO, "Detecting NVMe hardware...\n"
|
DEBUGF DBG_INFO, "Detecting NVMe device...\n"
|
||||||
call detect_nvme
|
call detect_nvme
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .err
|
jz .err
|
||||||
@ -123,8 +123,7 @@ proc add_nvme_disk stdcall, pci:dword
|
|||||||
push "n"
|
push "n"
|
||||||
push dword [esi + pcidev.num]
|
push dword [esi + pcidev.num]
|
||||||
push "nvme"
|
push "nvme"
|
||||||
mov eax, esp
|
invoke DiskAdd, disk_functions, esp, [esi + pcidev.nsinfo], 0
|
||||||
invoke DiskAdd, disk_functions, eax, [esi + pcidev.nsinfo], 0
|
|
||||||
add esp, 20
|
add esp, 20
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz @f
|
jz @f
|
||||||
@ -145,18 +144,21 @@ endp
|
|||||||
|
|
||||||
proc nvme_query_media stdcall, userdata:dword, info:dword
|
proc nvme_query_media stdcall, userdata:dword, info:dword
|
||||||
|
|
||||||
push esi edi
|
push ebx esi edi
|
||||||
mov esi, [userdata]
|
mov esi, [userdata]
|
||||||
|
mov ebx, dword [esi + NSINFO.pci]
|
||||||
mov edi, [info]
|
mov edi, [info]
|
||||||
mov dword [edi + DISKMEDIAINFO.flags], 0
|
mov dword [edi + DISKMEDIAINFO.flags], 0
|
||||||
mov eax, dword [esi + NSINFO.lbads]
|
mov eax, dword [esi + NSINFO.lbads]
|
||||||
|
DEBUGF DBG_INFO, "nvme%un%u (Query Media): Sector size = %u\n", [ebx + pcidev.num], [esi + NSINFO.nsid], eax
|
||||||
mov dword [edi + DISKMEDIAINFO.sectorsize], eax
|
mov dword [edi + DISKMEDIAINFO.sectorsize], eax
|
||||||
mov eax, dword [esi + NSINFO.capacity]
|
mov eax, dword [esi + NSINFO.capacity]
|
||||||
mov dword [edi + DISKMEDIAINFO.capacity], eax
|
mov dword [edi + DISKMEDIAINFO.capacity], eax
|
||||||
mov eax, dword [esi + NSINFO.capacity + 4]
|
mov eax, dword [esi + NSINFO.capacity + 4]
|
||||||
mov dword [edi + DISKMEDIAINFO.capacity + 4], eax
|
mov dword [edi + DISKMEDIAINFO.capacity + 4], eax
|
||||||
|
DEBUGF DBG_INFO, "nvme%un%u (Query Media): Capacity = %u + %u sectors\n", [ebx + pcidev.num], [esi + NSINFO.nsid], [esi + NSINFO.capacity], [esi + NSINFO.capacity + 4]
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
pop edi esi
|
pop edi esi ebx
|
||||||
ret
|
ret
|
||||||
|
|
||||||
endp
|
endp
|
||||||
@ -692,14 +694,13 @@ proc nvme_readwrite stdcall, ns:dword, buf:dword, start_sector:qword, numsectors
|
|||||||
dword [ebx + 8]
|
dword [ebx + 8]
|
||||||
|
|
||||||
; assume command completes successfully for now
|
; assume command completes successfully for now
|
||||||
mov ecx, dword [ebx + 12]
|
xor eax, eax
|
||||||
mov eax, [numsectors_ptr]
|
|
||||||
mov dword [eax], ecx
|
|
||||||
jmp .end
|
jmp .end
|
||||||
|
|
||||||
.dptr_fail:
|
.dptr_fail:
|
||||||
mov ebx, [numsectors_ptr]
|
mov ebx, [numsectors_ptr]
|
||||||
mov dword [ebx], 0
|
mov dword [ebx], 0
|
||||||
|
or eax, -1 ; generic disk error
|
||||||
|
|
||||||
.end:
|
.end:
|
||||||
add esp, 20
|
add esp, 20
|
||||||
@ -758,7 +759,7 @@ proc detect_nvme
|
|||||||
|
|
||||||
.found_dev:
|
.found_dev:
|
||||||
push edx eax
|
push edx eax
|
||||||
PDEBUGF DBG_INFO, "PCI(%u.%u.%u): Detected NVMe device...\n", byte [eax + PCIDEV.bus], byte [eax + PCIDEV.devfn]
|
;PDEBUGF DBG_INFO, "PCI(%u.%u.%u): Detected NVMe device...\n", byte [eax + PCIDEV.bus], byte [eax + PCIDEV.devfn]
|
||||||
cmp dword [pcidevs_len], TOTAL_PCIDEVS
|
cmp dword [pcidevs_len], TOTAL_PCIDEVS
|
||||||
jne @f
|
jne @f
|
||||||
pop eax edx
|
pop eax edx
|
||||||
@ -773,7 +774,7 @@ proc detect_nvme
|
|||||||
test eax, eax
|
test eax, eax
|
||||||
jz .err_no_mem
|
jz .err_no_mem
|
||||||
mov dword [p_nvme_devices], eax
|
mov dword [p_nvme_devices], eax
|
||||||
DEBUGF DBG_INFO, "(NVMe) Allocated pcidev struct at 0x%x\n", [p_nvme_devices]
|
;DEBUGF DBG_INFO, "(NVMe) Allocated pcidev struct at 0x%x\n", [p_nvme_devices]
|
||||||
|
|
||||||
@@:
|
@@:
|
||||||
mov ecx, dword [pcidevs_len]
|
mov ecx, dword [pcidevs_len]
|
||||||
@ -837,7 +838,7 @@ proc device_is_compat stdcall, pci:dword
|
|||||||
invoke MapIoMem, edx, ecx, PG_SW+PG_NOCACHE
|
invoke MapIoMem, edx, ecx, PG_SW+PG_NOCACHE
|
||||||
mov dword [esi + pcidev.io_addr], eax
|
mov dword [esi + pcidev.io_addr], eax
|
||||||
mov eax, dword [eax + NVME_MMIO.VS]
|
mov eax, dword [eax + NVME_MMIO.VS]
|
||||||
DEBUGF DBG_INFO, "nvme%u: Controller version: 0x%x\n", [esi + pcidev.num], eax
|
;DEBUGF DBG_INFO, "nvme%u: Controller version: 0x%x\n", [esi + pcidev.num], eax
|
||||||
mov dword [esi + pcidev.version], eax
|
mov dword [esi + pcidev.version], eax
|
||||||
pop ecx edx esi
|
pop ecx edx esi
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
@ -963,11 +964,11 @@ proc nvme_init stdcall, pci:dword
|
|||||||
; Attach interrupt handler
|
; Attach interrupt handler
|
||||||
mov esi, [pci]
|
mov esi, [pci]
|
||||||
movzx eax, byte [esi + pcidev.iline]
|
movzx eax, byte [esi + pcidev.iline]
|
||||||
DEBUGF DBG_INFO, "nvme%u: Attaching interrupt handler to IRQ %u\n", [esi + pcidev.num], eax
|
;DEBUGF DBG_INFO, "nvme%u: Attaching interrupt handler to IRQ %u\n", [esi + pcidev.num], eax
|
||||||
invoke AttachIntHandler, eax, irq_handler, 0
|
invoke AttachIntHandler, eax, irq_handler, 0
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .exit_fail
|
jz .exit_fail
|
||||||
DEBUGF DBG_INFO, "nvme%u: Successfully attached interrupt handler\n", [esi + pcidev.num]
|
;DEBUGF DBG_INFO, "nvme%u: Successfully attached interrupt handler\n", [esi + pcidev.num]
|
||||||
|
|
||||||
; Restart the controller
|
; Restart the controller
|
||||||
stdcall nvme_controller_start, esi
|
stdcall nvme_controller_start, esi
|
||||||
@ -981,15 +982,15 @@ proc nvme_init stdcall, pci:dword
|
|||||||
stdcall nvme_identify, [pci], 0, eax, CNS_IDCS
|
stdcall nvme_identify, [pci], 0, eax, CNS_IDCS
|
||||||
mov eax, dword [edi + IDENTC.nn]
|
mov eax, dword [edi + IDENTC.nn]
|
||||||
mov dword [esi + pcidev.nn], eax
|
mov dword [esi + pcidev.nn], eax
|
||||||
DEBUGF DBG_INFO, "nvme%u: Namespace Count: %u\n", [esi + pcidev.num], eax
|
;DEBUGF DBG_INFO, "nvme%u: Namespace Count: %u\n", [esi + pcidev.num], eax
|
||||||
lea ebx, byte [edi + IDENTC.sn]
|
lea ebx, byte [edi + IDENTC.sn]
|
||||||
lea eax, byte [esi + pcidev.serial]
|
lea eax, byte [esi + pcidev.serial]
|
||||||
stdcall memcpy, eax, ebx, 20
|
stdcall memcpy, eax, ebx, 20
|
||||||
DEBUGF DBG_INFO, "nvme%u: Serial Number: %s\n", [esi + pcidev.num], eax
|
;DEBUGF DBG_INFO, "nvme%u: Serial Number: %s\n", [esi + pcidev.num], eax
|
||||||
add ebx, 20
|
add ebx, 20
|
||||||
lea eax, byte [esi + pcidev.model]
|
lea eax, byte [esi + pcidev.model]
|
||||||
stdcall memcpy, eax, ebx, 40
|
stdcall memcpy, eax, ebx, 40
|
||||||
DEBUGF DBG_INFO, "nvme%u: Model: %s\n", [esi + pcidev.num], eax
|
;DEBUGF DBG_INFO, "nvme%u: Model: %s\n", [esi + pcidev.num], eax
|
||||||
mov edx, dword [esi + pcidev.version]
|
mov edx, dword [esi + pcidev.version]
|
||||||
|
|
||||||
cmp edx, VS140
|
cmp edx, VS140
|
||||||
@ -998,7 +999,7 @@ proc nvme_init stdcall, pci:dword
|
|||||||
mov al, byte [edi + IDENTC.cntrltype]
|
mov al, byte [edi + IDENTC.cntrltype]
|
||||||
cmp al, CNTRLTYPE_IO_CONTROLLER
|
cmp al, CNTRLTYPE_IO_CONTROLLER
|
||||||
jne .exit_fail
|
jne .exit_fail
|
||||||
DEBUGF DBG_INFO, "nvme%u: I/O controller detected...\n", [esi + pcidev.num]
|
;DEBUGF DBG_INFO, "nvme%u: I/O controller detected...\n", [esi + pcidev.num]
|
||||||
|
|
||||||
@@:
|
@@:
|
||||||
; TODO: check IDENTC.AVSCC
|
; TODO: check IDENTC.AVSCC
|
||||||
@ -1019,7 +1020,7 @@ proc nvme_init stdcall, pci:dword
|
|||||||
mov esi, dword [esi + NVM_QUEUE_ENTRY.cq_ptr]
|
mov esi, dword [esi + NVM_QUEUE_ENTRY.cq_ptr]
|
||||||
mov eax, dword [esi + sizeof.CQ_ENTRY + CQ_ENTRY.cdw0]
|
mov eax, dword [esi + sizeof.CQ_ENTRY + CQ_ENTRY.cdw0]
|
||||||
if __DEBUG__
|
if __DEBUG__
|
||||||
DEBUGF DBG_INFO, "nvme%u: Set Features CDW0: 0x%x\n", [esi + pcidev.num], eax
|
;DEBUGF DBG_INFO, "nvme%u: Set Features CDW0: 0x%x\n", [esi + pcidev.num], eax
|
||||||
end if
|
end if
|
||||||
test ax, ax ; Number of I/O Submission Queues allocated
|
test ax, ax ; Number of I/O Submission Queues allocated
|
||||||
jz .exit_fail
|
jz .exit_fail
|
||||||
@ -1036,11 +1037,11 @@ proc nvme_init stdcall, pci:dword
|
|||||||
mov eax, dword [esi + NVM_QUEUE_ENTRY.cq_ptr]
|
mov eax, dword [esi + NVM_QUEUE_ENTRY.cq_ptr]
|
||||||
invoke GetPhysAddr
|
invoke GetPhysAddr
|
||||||
stdcall create_io_completion_queue, [pci], eax, 1, IEN_ON
|
stdcall create_io_completion_queue, [pci], eax, 1, IEN_ON
|
||||||
DEBUGF DBG_INFO, "nvme%u: Successfully created I/O completion queue 1\n", [edi + pcidev.num]
|
;DEBUGF DBG_INFO, "nvme%u: Successfully created I/O completion queue 1\n", [edi + pcidev.num]
|
||||||
mov eax, dword [esi + NVM_QUEUE_ENTRY.sq_ptr]
|
mov eax, dword [esi + NVM_QUEUE_ENTRY.sq_ptr]
|
||||||
invoke GetPhysAddr
|
invoke GetPhysAddr
|
||||||
stdcall create_io_submission_queue, [pci], eax, 1, 1
|
stdcall create_io_submission_queue, [pci], eax, 1, 1
|
||||||
DEBUGF DBG_INFO, "nvme%u: Successfully created I/O submission queue 1\n", [edi + pcidev.num]
|
;DEBUGF DBG_INFO, "nvme%u: Successfully created I/O submission queue 1\n", [edi + pcidev.num]
|
||||||
|
|
||||||
if 1
|
if 1
|
||||||
stdcall determine_active_nsids, [pci]
|
stdcall determine_active_nsids, [pci]
|
||||||
@ -1048,7 +1049,7 @@ proc nvme_init stdcall, pci:dword
|
|||||||
jz .exit_fail ; No active NSIDS
|
jz .exit_fail ; No active NSIDS
|
||||||
mov esi, [pci]
|
mov esi, [pci]
|
||||||
mov dword [esi + pcidev.nsid], eax
|
mov dword [esi + pcidev.nsid], eax
|
||||||
DEBUGF DBG_INFO, "nvme%u: Found active NSID: %u\n", [esi + pcidev.num], eax
|
;DEBUGF DBG_INFO, "nvme%u: Found active NSID: %u\n", [esi + pcidev.num], eax
|
||||||
else
|
else
|
||||||
mov esi, [pci]
|
mov esi, [pci]
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
@ -1069,7 +1070,7 @@ proc nvme_init stdcall, pci:dword
|
|||||||
mov dword [esi + pcidev.nsinfo], eax
|
mov dword [esi + pcidev.nsinfo], eax
|
||||||
mov al, byte [edi + IDENTN.nsfeat]
|
mov al, byte [edi + IDENTN.nsfeat]
|
||||||
mov byte [ebx + NSINFO.features], al
|
mov byte [ebx + NSINFO.features], al
|
||||||
DEBUGF DBG_INFO, "nvme%un%u: Namespace Features: 0x%x\n", [esi + pcidev.num], [esi + pcidev.nsid], al
|
;DEBUGF DBG_INFO, "nvme%un%u: Namespace Features: 0x%x\n", [esi + pcidev.num], [esi + pcidev.nsid], al
|
||||||
mov dword [ebx + NSINFO.pci], esi
|
mov dword [ebx + NSINFO.pci], esi
|
||||||
mov eax, dword [edi + IDENTN.nsze]
|
mov eax, dword [edi + IDENTN.nsze]
|
||||||
mov dword [ebx + NSINFO.size], eax
|
mov dword [ebx + NSINFO.size], eax
|
||||||
@ -1079,13 +1080,19 @@ proc nvme_init stdcall, pci:dword
|
|||||||
mov dword [ebx + NSINFO.capacity], eax
|
mov dword [ebx + NSINFO.capacity], eax
|
||||||
mov eax, dword [edi + IDENTN.ncap + 4]
|
mov eax, dword [edi + IDENTN.ncap + 4]
|
||||||
mov dword [ebx + NSINFO.capacity + 4], eax
|
mov dword [ebx + NSINFO.capacity + 4], eax
|
||||||
DEBUGF DBG_INFO, "nvme%un%u: Namespace Size: %u + %u logical blocks\n", [esi + pcidev.num], [esi + pcidev.nsid], [edi + IDENTN.nsze], [edi + IDENTN.nsze + 4]
|
;DEBUGF DBG_INFO, "nvme%un%u: Namespace Size: %u + %u logical blocks\n", [esi + pcidev.num], [esi + pcidev.nsid], [edi + IDENTN.nsze], [edi + IDENTN.nsze + 4]
|
||||||
DEBUGF DBG_INFO, "nvme%un%u: Namespace Capacity: %u + %u logical blocks\n", [esi + pcidev.num], [esi + pcidev.nsid], [edi + IDENTN.ncap], [edi + IDENTN.ncap + 4]
|
;DEBUGF DBG_INFO, "nvme%un%u: Namespace Capacity: %u + %u logical blocks\n", [esi + pcidev.num], [esi + pcidev.nsid], [edi + IDENTN.ncap], [edi + IDENTN.ncap + 4]
|
||||||
mov eax, dword [edi + IDENTN.lbaf0]
|
mov eax, dword [edi + IDENTN.lbaf0]
|
||||||
shr eax, 16 ; Get LBADS
|
shr eax, 16 ; Get LBADS
|
||||||
and eax, 0xff
|
and eax, 0xff
|
||||||
stdcall pow2, eax
|
stdcall pow2, eax
|
||||||
DEBUGF DBG_INFO, "nvme%un%u: Namespace LBA Data Size: %u\n", [esi + pcidev.num], [esi + pcidev.nsid], eax
|
;DEBUGF DBG_INFO, "nvme%un%u: Namespace LBA Data Size: %u\n", [esi + pcidev.num], [esi + pcidev.nsid], eax
|
||||||
|
|
||||||
|
; KolibriOS only supports a LBADS of 512, so if it's a higher value then we
|
||||||
|
; have to ignore this namespace
|
||||||
|
cmp eax, SUPPORTED_LBADS
|
||||||
|
jne .exit_fail
|
||||||
|
|
||||||
mov dword [ebx + NSINFO.lbads], eax
|
mov dword [ebx + NSINFO.lbads], eax
|
||||||
mov ecx, PAGE_SIZE
|
mov ecx, PAGE_SIZE
|
||||||
xchg eax, ecx
|
xchg eax, ecx
|
||||||
|
@ -24,6 +24,7 @@ LAST_QUEUE_ID = 1 ; Index of the last queue
|
|||||||
SQ_ENTRIES = NVM_ASQS ; I/O and Admin Submission Queue Size
|
SQ_ENTRIES = NVM_ASQS ; I/O and Admin Submission Queue Size
|
||||||
CQ_ENTRIES = NVM_ACQS ; I/O and Admin Completion Queue Size
|
CQ_ENTRIES = NVM_ACQS ; I/O and Admin Completion Queue Size
|
||||||
PAGE_SIZE = 4096 shl NVM_MPS
|
PAGE_SIZE = 4096 shl NVM_MPS
|
||||||
|
SUPPORTED_LBADS = 512 ; KolibriOS only supports LBADS of 512, later on we may remove this restriction
|
||||||
|
|
||||||
ADMIN_QUEUE = 0 ; Admin Queue ID
|
ADMIN_QUEUE = 0 ; Admin Queue ID
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user