diff --git a/drivers/nvme/nvme.asm b/drivers/nvme/nvme.asm index 652eb02..1ea821e 100644 --- a/drivers/nvme/nvme.asm +++ b/drivers/nvme/nvme.asm @@ -75,6 +75,7 @@ proc START c, reason:dword stdcall add_nvme_disk, [p_nvme_devices] test eax, eax jz .err + invoke RegService, my_service, service_proc ret @@ -119,6 +120,7 @@ proc add_nvme_disk stdcall, pci:dword add esp, 20 test eax, eax jz @f + invoke DiskMediaChanged, eax, 1 DEBUGF DBG_INFO, "nvme%u: Successfully registered disk\n", [esi + pcidev.num] xor eax, eax inc eax @@ -454,27 +456,20 @@ endp proc free_prp_list stdcall, prp_list_ptr:dword, nprps:dword - push edi - mov edi, [prp_list_ptr] - mov ecx, [nprps] - cmp ecx, PAGE_SIZE / 8 - 1 - jbe @f - mov eax, dword [edi + PAGE_SIZE - 8] - sub ecx, PAGE_SIZE / 8 - 1 - stdcall free_prp_list, eax, ecx, TRUE - -@@: - cmp [recursive], 0 - jz @f - invoke FreePage, edi - jmp .exit + push edi esi ebx + mov esi, [prp_list_ptr] + invoke KernelAlloc, PAGE_SIZE + test eax, eax + jz .exit + mov edi, eax + invoke MapPage, edi, esi, PG_SW+PG_NOCACHE + mov ebx, dword [edi + PAGE_SIZE / 8] + invoke FreePage, esi + sub [nprps], PAGE_SIZE / 8 -@@: - invoke KernelFree, edi - .exit: xor eax, eax - pop edi + pop ebx esi edi ret endp @@ -546,6 +541,7 @@ proc build_prp_list stdcall, nprps:dword .loop: mov dword [edi + ecx * 4], esi mov dword [edi + ecx * 4 + 4], 0 + DEBUGF DBG_INFO, "PRP: %x\n", esi add esi, PAGE_SIZE inc ecx cmp ecx, ebx @@ -583,7 +579,7 @@ proc build_prp_list stdcall, nprps:dword endp -proc alloc_dptr stdcall, ns:dword, prps_ptr:dword, numsectors:dword +proc alloc_dptr stdcall, ns:dword, prps_ptr:dword, numsectors:dword, nprps_ptr:dword push esi edi mov edi, [prps_ptr] @@ -605,7 +601,7 @@ proc alloc_dptr stdcall, ns:dword, prps_ptr:dword, numsectors:dword ; is the number of sectors greater than to two memory pages? shl eax, 1 cmp edx, eax - jae @f + jae .build_prp_list ; allocate a single PRP entry for PRP2 invoke AllocPage @@ -614,22 +610,28 @@ proc alloc_dptr stdcall, ns:dword, prps_ptr:dword, numsectors:dword mov dword [edi + 4], eax jmp .success -@@: +.build_prp_list: + DEBUGF DBG_INFO, "Allocating PRP list\n" ; allocate PRP list for PRP2 - shr eax, 1 - mov ecx, [numsectors] - xchg eax, ecx + mov eax, [numsectors] + mov ecx, dword [esi + NSINFO.pg_sectors] xor edx, edx div ecx + test edx, edx + jz @f + inc eax + +@@: + mov esi, [nprps_ptr] + dec eax + mov dword [esi], eax stdcall build_prp_list, eax test eax, eax - jz .free_prp_list + jz .err + DEBUGF DBG_INFO, "Successfully allocated PRP list at: %x\n", eax mov dword [edi + 4], eax jmp .success -.free_prp_list: - stdcall free_prp_list, edi, eax, FALSE - .err: mov eax, dword [edi] test eax, eax @@ -759,23 +761,27 @@ nvme_write: proc nvme_readwrite stdcall, ns:dword, buf:dword, start_sector:qword, numsectors_ptr:dword push ebx esi edi - sub esp, 16 + sub esp, 20 mov ebx, esp mov eax, [numsectors_ptr] mov eax, dword [eax] + DEBUGF DBG_INFO, "buf: %x, start_sector: %x%x\n, numsectors: %u", [buf], [start_sector + 4], [start_sector], eax mov dword [ebx + 8], edx ; command type (read or write) mov dword [ebx + 12], eax ; save original numsectors value + mov dword [ebx + 16], 0 ; nPRPs for PRP list mov esi, [ns] mov edi, [buf] mov edx, [numsectors_ptr] mov edx, [edx] + mov ecx, ebx + add ecx, 16 ; Note that [esp] will contain the value of PRP1 and [esp + 4] will ; contain the value of PRP2 (after this call, if it completes successfully) - stdcall alloc_dptr, esi, ebx, edx + stdcall alloc_dptr, esi, ebx, edx, ecx test eax, eax jz .dptr_fail - DEBUGF DBG_INFO, "PRP1: %x, PRP2: %x\n", [ebx], [ebx + 4] + DEBUGF DBG_INFO, "PRP1: %x, PRP2: %x, nPRPs for PRP list: %u\n", [ebx], [ebx + 4], [ebx + 16] stdcall nvme_io_rw, [esi + NSINFO.pci], \ 1, \ [esi + NSINFO.nsid], \ @@ -819,14 +825,8 @@ proc nvme_readwrite stdcall, ns:dword, buf:dword, start_sector:qword, numsectors jmp .end .is_prp_list: - ; TODO: Fix this - mov eax, ebx - xor edx, edx - mov ecx, dword [esi + NSINFO.lbads] - div ecx - mov ebx, eax - stdcall write_prp_list_buf, dword [ebx + 4], [buf], ebx - stdcall free_prp_list, dword [ebx + 4], ebx, FALSE + stdcall write_prp_list_buf, dword [ebx + 4], [buf], [ebx + 16] + ;stdcall free_prp_list, dword [ebx + 4], ebx jmp .end .dptr_fail: @@ -834,7 +834,7 @@ proc nvme_readwrite stdcall, ns:dword, buf:dword, start_sector:qword, numsectors mov dword [ebx], 0 .end: - add esp, 16 + add esp, 20 pop edi esi ebx ret @@ -1225,6 +1225,7 @@ proc nvme_init stdcall, pci:dword div ecx mov dword [ebx + NSINFO.pg_sectors], eax invoke KernelFree, edi + if 0 invoke KernelAlloc, 0x1000 test eax, eax jz .exit_fail @@ -1233,11 +1234,12 @@ proc nvme_init stdcall, pci:dword test eax, eax jz .exit_fail mov edx, NVM_CMD_READ - mov dword [eax], 0x9 + mov dword [eax], 0x11 stdcall nvme_readwrite, [esi + pcidev.nsinfo], edi, 0, 0, eax test eax, eax jz .exit_fail DEBUGF DBG_INFO, "%s\n", edi + end if DEBUGF DBG_INFO, "nvme%u: Successfully initialized driver\n", [esi + pcidev.num] xor eax, eax inc eax @@ -1583,7 +1585,7 @@ align 4 dd 0 ; no close function dd 0 ; no closemedia function dd nvme_query_media - dd 0 ; no read function (for now) + dd nvme_read dd 0 ; no write function (for now) dd 0 ; no flush function dd 0 ; use default cache size