2
0
mirror of https://git.missingno.dev/kolibrios-nvme-driver/ synced 2025-01-22 05:08:16 +01:00

fix PRP list allocation regression

This commit is contained in:
Abdur-Rahman Mansoor 2024-08-01 13:49:18 -04:00
parent 365ccac9eb
commit 404f451e0c

View File

@ -348,6 +348,7 @@ proc alloc_dptr stdcall, ns:dword, prps_ptr:dword, numsectors:dword, prp_list_pt
mov eax, [buf] mov eax, [buf]
mov ecx, eax mov ecx, eax
and eax, PAGE_SIZE - 1 and eax, PAGE_SIZE - 1
mov eax, ebx
jnz @f jnz @f
; is the number of sectors less than or equal to one memory page? ; is the number of sectors less than or equal to one memory page?
@ -369,11 +370,11 @@ proc alloc_dptr stdcall, ns:dword, prps_ptr:dword, numsectors:dword, prp_list_pt
jmp .success jmp .success
.build_prp_list: .build_prp_list:
xchg ecx, ebx mov ebx, ecx
mov ecx, eax
and ebx, not (PAGE_SIZE - 1) and ebx, not (PAGE_SIZE - 1)
add ebx, PAGE_SIZE add ebx, PAGE_SIZE
mov eax, [numsectors] mov eax, [numsectors]
mov ecx, ebx
xor edx, edx xor edx, edx
div ecx div ecx
stdcall build_prp_list, eax, ebx, [prp_list_ptr] stdcall build_prp_list, eax, ebx, [prp_list_ptr]
@ -421,7 +422,7 @@ proc nvme_readwrite stdcall, ns:dword, buf:dword, start_sector:qword, numsectors
mov eax, [numsectors_ptr] mov eax, [numsectors_ptr]
mov eax, dword [eax] mov eax, dword [eax]
DEBUGF DBG_INFO, "buf: %x, start_sector: %u:%u, numsectors: %u\n", [buf], [start_sector + 4], [start_sector], eax ;DEBUGF DBG_INFO, "buf: %x, start_sector: %u:%u, numsectors: %u\n", [buf], [start_sector + 4], [start_sector], eax
mov dword [ebx + 4], 0 ; PRP2 entry (0 by default) mov dword [ebx + 4], 0 ; PRP2 entry (0 by default)
mov dword [ebx + 8], edx ; command type (read or write) mov dword [ebx + 8], edx ; command type (read or write)
mov dword [ebx + 12], eax ; save original numsectors value mov dword [ebx + 12], eax ; save original numsectors value
@ -462,22 +463,30 @@ proc nvme_readwrite stdcall, ns:dword, buf:dword, start_sector:qword, numsectors
ecx, \ ecx, \
dword [ebx + 8] dword [ebx + 8]
; free PRP list (if allocated)
mov edx, dword [ebx + 16]
test edx, edx
jz @f
invoke KernelFree, edx
@@:
stdcall nvme_poll, [esi + NSINFO.pci] stdcall nvme_poll, [esi + NSINFO.pci]
test eax, eax test eax, eax
jz .fail jz .fail
; free PRP list (if allocated)
mov eax, dword [ebx + 16]
test eax, eax
jz @f
invoke KernelFree, eax
@@:
xor eax, eax xor eax, eax
add esp, 20 add esp, 20
pop edi esi ebx pop edi esi ebx
ret ret
.fail: .fail:
; free PRP list (if allocated)
mov eax, dword [ebx + 16]
test eax, eax
jz @f
invoke KernelFree, eax
@@:
mov ebx, [numsectors_ptr] mov ebx, [numsectors_ptr]
mov dword [ebx], 0 mov dword [ebx], 0
or eax, -1 ; generic disk error or eax, -1 ; generic disk error
@ -931,10 +940,10 @@ proc nvme_init stdcall, pci:dword
test eax, eax test eax, eax
jz .exit_fail jz .exit_fail
mov edx, NVM_CMD_READ mov edx, NVM_CMD_READ
mov dword [eax], 25 mov dword [eax], 6
add edi, 0x5 add edi, 0x5
mov dword [esi + pcidev.spinlock], 1 mov dword [esi + pcidev.spinlock], 1
stdcall nvme_readwrite, [esi + pcidev.nsinfo], edi, 0x1000, 0, eax stdcall nvme_readwrite, [esi + pcidev.nsinfo], edi, 0x0, 0, eax
stdcall nvme_poll, esi stdcall nvme_poll, esi
test eax, eax test eax, eax
jz .exit_fail jz .exit_fail
@ -1063,9 +1072,9 @@ proc cqyhdbl_write stdcall, pci:dword, y:dword, cqh:dword
imul ecx, sizeof.NVM_QUEUE_ENTRY imul ecx, sizeof.NVM_QUEUE_ENTRY
mov edi, dword [esi + pcidev.queue_entries] mov edi, dword [esi + pcidev.queue_entries]
lea edi, dword [edi + ecx] lea edi, dword [edi + ecx]
mov esi, dword [esi + pcidev.io_addr]
mov eax, [cqh] mov eax, [cqh]
;DEBUGF DBG_INFO, "Writing to completion queue doorbell register 0x%x: %u\n", edx, ax ;DEBUGF DBG_INFO, "nvme%u: Writing to CQ%u doorbell register 0x%x: %u\n", [esi + pcidev.num], [y], dx, ax
mov esi, dword [esi + pcidev.io_addr]
mov word [esi + edx], ax ; Write to CQyHDBL mov word [esi + edx], ax ; Write to CQyHDBL
mov word [edi + NVM_QUEUE_ENTRY.head], ax mov word [edi + NVM_QUEUE_ENTRY.head], ax
pop edi esi pop edi esi
@ -1112,7 +1121,7 @@ proc sqytdbl_write stdcall, pci:dword, y:word, cmd:dword
shl edx, cl shl edx, cl
imul edx, ebx imul edx, ebx
add edx, 0x1000 add edx, 0x1000
DEBUGF DBG_INFO, "nvme%u: Writing to submission queue tail doorbell 0x%x: %u\n", [esi + pcidev.num], edx, ax ;DEBUGF DBG_INFO, "nvme%u: Writing to SQ%u doorbell register 0x%x: %u\n", [esi + pcidev.num], [y], dx, ax
mov word [edi + NVM_QUEUE_ENTRY.tail], ax mov word [edi + NVM_QUEUE_ENTRY.tail], ax
mov esi, dword [esi + pcidev.io_addr] mov esi, dword [esi + pcidev.io_addr]
mov word [esi + edx], ax mov word [esi + edx], ax
@ -1216,9 +1225,9 @@ proc irq_handler
mov edi, dword [esi + pcidev.io_addr] mov edi, dword [esi + pcidev.io_addr]
mov dword [edi + NVME_MMIO.INTMS], 0x3 mov dword [edi + NVME_MMIO.INTMS], 0x3
mov eax, dword [esi + pcidev.spinlock] ;mov eax, dword [esi + pcidev.spinlock]
test eax, eax ;test eax, eax
jz @f ; not locked, so it must be an I/O command ;jz @f ; not locked, so it must be an I/O command
stdcall consume_cq_entries, esi, 0 stdcall consume_cq_entries, esi, 0
@@: @@: