mirror of
https://git.missingno.dev/kolibrios-nvme-driver/
synced 2025-01-22 05:08:16 +01:00
bug fixes
This commit is contained in:
parent
dd4db45869
commit
c3901b163e
@ -27,9 +27,4 @@ macro PDEBUGF _level*, _fmt*, _bus*, _devfn*, [_args] {
|
||||
end if
|
||||
}
|
||||
|
||||
macro LOCK_SPINLOCK {
|
||||
common
|
||||
mov dword [spinlock], 1
|
||||
}
|
||||
|
||||
; vim: syntax=fasm
|
||||
|
@ -50,10 +50,10 @@ proc START c, reason:dword
|
||||
jz .err
|
||||
xor ebx, ebx
|
||||
mov esi, dword [p_nvme_devices]
|
||||
DEBUGF DBG_INFO, "p_nvme_devices: 0x%x\n", [p_nvme_devices]
|
||||
sub esi, sizeof.pcidev
|
||||
|
||||
.loop:
|
||||
lea esi, [esi + ebx * 4]
|
||||
add esi, sizeof.pcidev
|
||||
push esi ebx
|
||||
stdcall device_is_compat, esi
|
||||
test eax, eax
|
||||
@ -176,7 +176,9 @@ endp
|
||||
; See pages 161-205 of the NVMe 1.4 specification for reference
|
||||
proc nvme_identify stdcall, pci:dword, nsid:dword, prp1:dword, cns:byte
|
||||
|
||||
LOCK_SPINLOCK
|
||||
push esi
|
||||
mov esi, [pci]
|
||||
mov dword [esi + pcidev.spinlock], 1
|
||||
sub esp, sizeof.SQ_ENTRY
|
||||
stdcall memsetdz, esp, sizeof.SQ_ENTRY / 4
|
||||
|
||||
@ -184,14 +186,15 @@ proc nvme_identify stdcall, pci:dword, nsid:dword, prp1:dword, cns:byte
|
||||
mov dword [esp + SQ_ENTRY.nsid], eax
|
||||
mov eax, [prp1]
|
||||
mov dword [esp + SQ_ENTRY.prp1], eax
|
||||
stdcall set_cdw0, [pci], ADMIN_QUEUE, ADM_CMD_IDENTIFY
|
||||
stdcall set_cdw0, esi, ADMIN_QUEUE, ADM_CMD_IDENTIFY
|
||||
mov dword [esp + SQ_ENTRY.cdw0], eax
|
||||
mov al, [cns]
|
||||
mov byte [esp + SQ_ENTRY.cdw10], al
|
||||
stdcall sqytdbl_write, [pci], ADMIN_QUEUE, esp
|
||||
stdcall sqytdbl_write, esi, ADMIN_QUEUE, esp
|
||||
|
||||
add esp, sizeof.SQ_ENTRY
|
||||
call nvme_poll
|
||||
stdcall nvme_poll, esi
|
||||
pop esi
|
||||
ret
|
||||
|
||||
endp
|
||||
@ -294,10 +297,12 @@ endp
|
||||
; See page 101 of the NVMe 1.4 specification for reference
|
||||
proc create_io_completion_queue stdcall, pci:dword, prp1:dword, qid:dword, ien:byte
|
||||
|
||||
LOCK_SPINLOCK
|
||||
push esi
|
||||
mov esi, [pci]
|
||||
mov dword [esi + pcidev.spinlock], 1
|
||||
sub esp, sizeof.SQ_ENTRY
|
||||
stdcall memsetdz, esp, sizeof.SQ_ENTRY / 4
|
||||
stdcall set_cdw0, [pci], ADMIN_QUEUE, ADM_CMD_CRE_IO_COMPLETION_QUEUE
|
||||
stdcall set_cdw0, esi, ADMIN_QUEUE, ADM_CMD_CRE_IO_COMPLETION_QUEUE
|
||||
mov dword [esp + SQ_ENTRY.cdw0], eax
|
||||
mov eax, [prp1]
|
||||
mov dword [esp + SQ_ENTRY.prp1], eax
|
||||
@ -308,9 +313,10 @@ proc create_io_completion_queue stdcall, pci:dword, prp1:dword, qid:dword, ien:b
|
||||
or eax, 0x1 ; CDW11.PC
|
||||
; Don't set CDW11.IV since we're not using MSI-X or MSI vector
|
||||
mov dword [esp + SQ_ENTRY.cdw11], eax
|
||||
stdcall sqytdbl_write, [pci], ADMIN_QUEUE, esp
|
||||
stdcall sqytdbl_write, esi, ADMIN_QUEUE, esp
|
||||
add esp, sizeof.SQ_ENTRY
|
||||
call nvme_poll
|
||||
stdcall nvme_poll, esi
|
||||
pop esi
|
||||
ret
|
||||
|
||||
endp
|
||||
@ -318,7 +324,9 @@ endp
|
||||
; See page 103-104 of the NVMe 1.4 specification for reference
|
||||
proc create_io_submission_queue stdcall, pci:dword, prp1:dword, qid:dword, cqid:word
|
||||
|
||||
LOCK_SPINLOCK
|
||||
push esi
|
||||
mov esi, [pci]
|
||||
mov dword [esi + pcidev.spinlock], 1
|
||||
sub esp, sizeof.SQ_ENTRY
|
||||
stdcall memsetdz, esp, sizeof.SQ_ENTRY / 4
|
||||
stdcall set_cdw0, [pci], ADMIN_QUEUE, ADM_CMD_CRE_IO_SUBMISSION_QUEUE
|
||||
@ -333,9 +341,10 @@ proc create_io_submission_queue stdcall, pci:dword, prp1:dword, qid:dword, cqid:
|
||||
or eax, 0x1 ; CDW11.PC (always set this to 1 as some devices may not support non-contiguous pages)
|
||||
; TODO: Set CDW10.QPRIO
|
||||
mov dword [esp + SQ_ENTRY.cdw11], eax
|
||||
stdcall sqytdbl_write, [pci], ADMIN_QUEUE, esp
|
||||
stdcall sqytdbl_write, esi, ADMIN_QUEUE, esp
|
||||
add esp, sizeof.SQ_ENTRY
|
||||
call nvme_poll
|
||||
stdcall nvme_poll, esi
|
||||
pop esi
|
||||
ret
|
||||
|
||||
endp
|
||||
@ -343,6 +352,9 @@ endp
|
||||
; See page 95-96 of the NVMe 1.4 specification for reference
|
||||
proc abort stdcall, pci:dword, cid:word, sqid:word
|
||||
|
||||
push esi
|
||||
mov esi, [pci]
|
||||
mov dword [esi + pcidev.spinlock], 1
|
||||
sub esp, sizeof.SQ_ENTRY
|
||||
stdcall memsetdz, esp, sizeof.SQ_ENTRY / 4
|
||||
stdcall set_cdw0, [pci], ADMIN_QUEUE, ADM_CMD_ABORT
|
||||
@ -353,6 +365,8 @@ proc abort stdcall, pci:dword, cid:word, sqid:word
|
||||
mov dword [esp + SQ_ENTRY.cdw10], eax
|
||||
stdcall sqytdbl_write, [pci], ADMIN_QUEUE, esp
|
||||
add esp, sizeof.SQ_ENTRY
|
||||
stdcall nvme_poll, esi
|
||||
pop esi
|
||||
ret
|
||||
|
||||
endp
|
||||
@ -646,7 +660,10 @@ proc nvme_readwrite stdcall, ns:dword, buf:dword, start_sector:qword, numsectors
|
||||
dec ecx
|
||||
|
||||
; TODO: add non-blocking mechanisms later on
|
||||
LOCK_SPINLOCK
|
||||
push eax
|
||||
mov eax, dword [esi + NSINFO.pci]
|
||||
mov dword [eax + pcidev.spinlock], 1
|
||||
pop eax
|
||||
stdcall nvme_io_rw, [esi + NSINFO.pci], \
|
||||
1, \
|
||||
[esi + NSINFO.nsid], \
|
||||
@ -664,7 +681,7 @@ proc nvme_readwrite stdcall, ns:dword, buf:dword, start_sector:qword, numsectors
|
||||
invoke KernelFree, edx
|
||||
|
||||
@@:
|
||||
call nvme_poll
|
||||
stdcall nvme_poll, [esi + NSINFO.pci]
|
||||
test eax, eax
|
||||
jz .fail
|
||||
xor eax, eax
|
||||
@ -751,7 +768,9 @@ proc detect_nvme
|
||||
mov ecx, dword [pcidevs_len]
|
||||
dec ecx
|
||||
mov edi, dword [p_nvme_devices]
|
||||
lea edi, [edi + ecx * 4]
|
||||
mov edx, ecx
|
||||
imul edx, sizeof.pcidev
|
||||
lea edi, [edi + edx]
|
||||
|
||||
movzx eax, byte [esi + PCIDEV.bus]
|
||||
mov byte [edi + pcidev.bus], al
|
||||
@ -1039,12 +1058,12 @@ proc nvme_init stdcall, pci:dword
|
||||
invoke KernelFree, edi
|
||||
|
||||
mov eax, 1 or (1 shl 16) ; CDW11 (set the number of queues we want)
|
||||
LOCK_SPINLOCK
|
||||
mov esi, [pci]
|
||||
mov dword [esi + pcidev.spinlock], 1
|
||||
stdcall set_features, [pci], NULLPTR, FID_NUMBER_OF_QUEUES, eax
|
||||
call nvme_poll
|
||||
stdcall nvme_poll, esi
|
||||
test eax, eax
|
||||
jz .exit_fail
|
||||
mov esi, [pci]
|
||||
mov esi, dword [esi + pcidev.queue_entries]
|
||||
mov esi, dword [esi + NVM_QUEUE_ENTRY.cq_ptr]
|
||||
mov eax, dword [esi + sizeof.CQ_ENTRY + CQ_ENTRY.cdw0]
|
||||
@ -1130,9 +1149,9 @@ proc nvme_init stdcall, pci:dword
|
||||
mov edx, NVM_CMD_READ
|
||||
mov dword [eax], 25
|
||||
add edi, 0x5
|
||||
LOCK_SPINLOCK
|
||||
mov dword [esi + pcidev.spinlock], 1
|
||||
stdcall nvme_readwrite, [esi + pcidev.nsinfo], edi, 0x1000, 0, eax
|
||||
call nvme_poll
|
||||
stdcall nvme_poll, esi
|
||||
test eax, eax
|
||||
jz .exit_fail
|
||||
DEBUGF DBG_INFO, "STRING: %s\n", edi
|
||||
@ -1212,8 +1231,10 @@ proc nvme_controller_start stdcall, pci:dword
|
||||
|
||||
endp
|
||||
|
||||
proc nvme_poll
|
||||
proc nvme_poll stdcall, pci:dword
|
||||
|
||||
push esi
|
||||
mov esi, [pci]
|
||||
xor ecx, ecx
|
||||
|
||||
@@:
|
||||
@ -1222,17 +1243,19 @@ proc nvme_poll
|
||||
je @f
|
||||
xor eax, eax
|
||||
inc eax
|
||||
xchg eax, dword [spinlock]
|
||||
xchg eax, dword [esi + pcidev.spinlock]
|
||||
test eax, eax
|
||||
jnz @b
|
||||
|
||||
; lock was released, return 1
|
||||
pop esi
|
||||
xor eax, eax
|
||||
inc eax
|
||||
ret
|
||||
|
||||
@@:
|
||||
; timeout: lock wasn't released, return 0
|
||||
pop esi
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
@ -1414,7 +1437,7 @@ proc irq_handler
|
||||
mov edi, dword [esi + pcidev.io_addr]
|
||||
mov dword [edi + NVME_MMIO.INTMS], 0x3
|
||||
|
||||
mov eax, dword [spinlock]
|
||||
mov eax, dword [esi + pcidev.spinlock]
|
||||
test eax, eax
|
||||
jz @f ; not locked, so it must be an I/O command
|
||||
stdcall consume_cq_entries, esi, 0
|
||||
@ -1424,9 +1447,9 @@ proc irq_handler
|
||||
|
||||
; Interrupt handled by driver, return 1
|
||||
mov dword [edi + NVME_MMIO.INTMC], 0x3
|
||||
pop edi esi ebx
|
||||
xor eax, eax
|
||||
xchg eax, dword [spinlock] ; unlock spinlock
|
||||
xchg eax, dword [esi + pcidev.spinlock] ; unlock spinlock
|
||||
pop edi esi ebx
|
||||
mov eax, 1
|
||||
ret
|
||||
|
||||
@ -1463,7 +1486,6 @@ endp
|
||||
align 4
|
||||
p_nvme_devices dd 0
|
||||
pcidevs_len dd 0
|
||||
spinlock dd 0
|
||||
my_service db "NVMe",0 ;max 16 chars include zero
|
||||
disk_functions:
|
||||
dd disk_functions.end - disk_functions
|
||||
|
@ -332,6 +332,7 @@ struct pcidev
|
||||
queue_entries dd ?
|
||||
version dd ?
|
||||
nsid dd ?
|
||||
spinlock dd ?
|
||||
nsinfo dd ?
|
||||
nn dd ?
|
||||
dstrd db ?
|
||||
|
Loading…
Reference in New Issue
Block a user