forked from KolibriOS/kolibrios
Syncing net branch with trunk.
git-svn-id: svn://kolibrios.org@3187 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
@@ -15,15 +15,17 @@ $Revision: 2381 $
|
||||
; out: eax = error code; 0 = ok
|
||||
fs_read32_sys:
|
||||
; Compatibility hack: if PARTITION.Disk is 'old', there is no DISK structure,
|
||||
; this request should be processed by hd_read.
|
||||
cmp [ebp+PARTITION.Disk], 'old'
|
||||
jnz @f
|
||||
mov [hdd_appl_data], 0
|
||||
call hd_read
|
||||
mov [hdd_appl_data], 1 ; restore to default state
|
||||
ret
|
||||
@@:
|
||||
; In the normal case, save ecx, set ecx to SysCache and let the common part
|
||||
; this request should be processed by hd_read.
|
||||
cmp [ebp+PARTITION.Disk], 'old'
|
||||
jnz @f
|
||||
add eax, dword [ebp+PARTITION.FirstSector]
|
||||
mov [hdd_appl_data], 0
|
||||
call hd_read
|
||||
mov [hdd_appl_data], 1 ; restore to default state
|
||||
mov eax, [hd_error]
|
||||
ret
|
||||
@@:
|
||||
; In the normal case, save ecx, set ecx to SysCache and let the common part
|
||||
; do its work.
|
||||
push ecx
|
||||
mov ecx, [ebp+PARTITION.Disk]
|
||||
@@ -38,14 +40,17 @@ fs_read32_sys:
|
||||
; out: eax = error code; 0 = ok
|
||||
fs_read32_app:
|
||||
; Compatibility hack: if PARTITION.Disk is 'old', there is no DISK structure,
|
||||
; this request should be processed by hd_read.
|
||||
cmp [ebp+PARTITION.Disk], 'old'
|
||||
jnz @f
|
||||
mov [hdd_appl_data], 1
|
||||
jmp hd_read
|
||||
@@:
|
||||
; In the normal case, save ecx, set ecx to AppCache and let the common part
|
||||
; do its work.
|
||||
; this request should be processed by hd_read.
|
||||
cmp [ebp+PARTITION.Disk], 'old'
|
||||
jnz @f
|
||||
add eax, dword [ebp+PARTITION.FirstSector]
|
||||
mov [hdd_appl_data], 1
|
||||
call hd_read
|
||||
mov eax, [hd_error]
|
||||
ret
|
||||
@@:
|
||||
; In the normal case, save ecx, set ecx to AppCache and let the common part
|
||||
; do its work.
|
||||
push ecx
|
||||
mov ecx, [ebp+PARTITION.Disk]
|
||||
add ecx, DISK.AppCache
|
||||
@@ -60,33 +65,34 @@ fs_read32_common:
|
||||
ja @f
|
||||
mov eax, DISK_STATUS_END_OF_MEDIA
|
||||
pop ecx
|
||||
ret
|
||||
@@:
|
||||
; 2. Get the absolute sector on the disk.
|
||||
push edx
|
||||
xor edx, edx
|
||||
add eax, dword [ebp+PARTITION.FirstSector]
|
||||
adc edx, dword [ebp+PARTITION.FirstSector+4]
|
||||
ret
|
||||
@@:
|
||||
; 2. Get the absolute sector on the disk.
|
||||
push edx esi
|
||||
xor edx, edx
|
||||
add eax, dword [ebp+PARTITION.FirstSector]
|
||||
adc edx, dword [ebp+PARTITION.FirstSector+4]
|
||||
; 3. If there is no cache for this disk, just pass the request to the driver.
|
||||
cmp [ecx+DISKCACHE.pointer], 0
|
||||
jnz .scancache
|
||||
push 1
|
||||
push esp ; numsectors
|
||||
push edx ; startsector
|
||||
push eax ; startsector
|
||||
push ebx ; buffer
|
||||
mov al, DISKFUNC.read
|
||||
call disk_call_driver
|
||||
pop ecx
|
||||
pop edx
|
||||
pop ecx
|
||||
ret
|
||||
.scancache:
|
||||
; 4. Scan the cache.
|
||||
push esi edi ecx ; scan cache
|
||||
push edx eax
|
||||
virtual at esp
|
||||
.sector_lo dd ?
|
||||
push edx ; startsector
|
||||
push eax ; startsector
|
||||
push ebx ; buffer
|
||||
mov esi, [ebp+PARTITION.Disk]
|
||||
mov al, DISKFUNC.read
|
||||
call disk_call_driver
|
||||
pop ecx
|
||||
pop esi edx
|
||||
pop ecx
|
||||
ret
|
||||
.scancache:
|
||||
; 4. Scan the cache.
|
||||
push edi ecx ; scan cache
|
||||
push edx eax
|
||||
virtual at esp
|
||||
.sector_lo dd ?
|
||||
.sector_hi dd ?
|
||||
.cache dd ?
|
||||
end virtual
|
||||
@@ -126,13 +132,13 @@ end virtual
|
||||
jnz .read_done
|
||||
|
||||
push 1
|
||||
push esp
|
||||
push edx
|
||||
push [.sector_lo+12]
|
||||
mov ecx, [.cache]
|
||||
mov eax, edi
|
||||
shl eax, 9
|
||||
add eax, [ecx+DISKCACHE.data]
|
||||
push esp
|
||||
push edx
|
||||
push [.sector_lo+12]
|
||||
mov ecx, [.cache+16]
|
||||
mov eax, edi
|
||||
shl eax, 9
|
||||
add eax, [ecx+DISKCACHE.data]
|
||||
push eax
|
||||
mov esi, [ebp+PARTITION.Disk]
|
||||
mov al, DISKFUNC.read
|
||||
@@ -180,15 +186,17 @@ end virtual
|
||||
; out: eax = error code; 0 = ok
|
||||
fs_write32_sys:
|
||||
; Compatibility hack: if PARTITION.Disk is 'old', there is no DISK structure,
|
||||
; this request should be processed by hd_write.
|
||||
cmp [ebp+PARTITION.Disk], 'old'
|
||||
jnz @f
|
||||
mov [hdd_appl_data], 0
|
||||
call hd_write
|
||||
mov [hdd_appl_data], 1 ; restore to default state
|
||||
ret
|
||||
@@:
|
||||
; In the normal case, save ecx, set ecx to SysCache and let the common part
|
||||
; this request should be processed by hd_write.
|
||||
cmp [ebp+PARTITION.Disk], 'old'
|
||||
jnz @f
|
||||
add eax, dword [ebp+PARTITION.FirstSector]
|
||||
mov [hdd_appl_data], 0
|
||||
call hd_write
|
||||
mov [hdd_appl_data], 1 ; restore to default state
|
||||
mov eax, [hd_error]
|
||||
ret
|
||||
@@:
|
||||
; In the normal case, save ecx, set ecx to SysCache and let the common part
|
||||
; do its work.
|
||||
push ecx
|
||||
mov ecx, [ebp+PARTITION.Disk]
|
||||
@@ -203,14 +211,17 @@ fs_write32_sys:
|
||||
; out: eax = error code; 0 = ok
|
||||
fs_write32_app:
|
||||
; Compatibility hack: if PARTITION.Disk is 'old', there is no DISK structure,
|
||||
; this request should be processed by hd_write.
|
||||
cmp [ebp+PARTITION.Disk], 'old'
|
||||
jnz @f
|
||||
mov [hdd_appl_data], 1
|
||||
jmp hd_write
|
||||
@@:
|
||||
; In the normal case, save ecx, set ecx to AppCache and let the common part
|
||||
; do its work.
|
||||
; this request should be processed by hd_write.
|
||||
cmp [ebp+PARTITION.Disk], 'old'
|
||||
jnz @f
|
||||
add eax, dword [ebp+PARTITION.FirstSector]
|
||||
mov [hdd_appl_data], 1
|
||||
call hd_write
|
||||
mov eax, [hd_error]
|
||||
ret
|
||||
@@:
|
||||
; In the normal case, save ecx, set ecx to AppCache and let the common part
|
||||
; do its work.
|
||||
push ecx
|
||||
mov ecx, [ebp+PARTITION.Disk]
|
||||
add ecx, DISK.AppCache
|
||||
@@ -224,34 +235,35 @@ fs_write32_common:
|
||||
cmp dword [ebp+PARTITION.Length], eax
|
||||
ja @f
|
||||
mov eax, DISK_STATUS_END_OF_MEDIA
|
||||
pop ecx
|
||||
ret
|
||||
@@:
|
||||
push edx
|
||||
; 2. Get the absolute sector on the disk.
|
||||
xor edx, edx
|
||||
add eax, dword [ebp+PARTITION.FirstSector]
|
||||
pop ecx
|
||||
ret
|
||||
@@:
|
||||
push edx esi
|
||||
; 2. Get the absolute sector on the disk.
|
||||
xor edx, edx
|
||||
add eax, dword [ebp+PARTITION.FirstSector]
|
||||
adc edx, dword [ebp+PARTITION.FirstSector+4]
|
||||
; 3. If there is no cache for this disk, just pass request to the driver.
|
||||
cmp [ecx+DISKCACHE.pointer], 0
|
||||
jnz .scancache
|
||||
push 1
|
||||
push esp ; numsectors
|
||||
push edx ; startsector
|
||||
push eax ; startsector
|
||||
push ebx ; buffer
|
||||
mov al, DISKFUNC.write
|
||||
call disk_call_driver
|
||||
pop ecx
|
||||
pop edx
|
||||
pop ecx
|
||||
ret
|
||||
.scancache:
|
||||
; 4. Scan the cache.
|
||||
push esi edi ecx ; scan cache
|
||||
push edx eax
|
||||
virtual at esp
|
||||
.sector_lo dd ?
|
||||
push edx ; startsector
|
||||
push eax ; startsector
|
||||
push ebx ; buffer
|
||||
mov esi, [ebp+PARTITION.Disk]
|
||||
mov al, DISKFUNC.write
|
||||
call disk_call_driver
|
||||
pop ecx
|
||||
pop esi edx
|
||||
pop ecx
|
||||
ret
|
||||
.scancache:
|
||||
; 4. Scan the cache.
|
||||
push edi ecx ; scan cache
|
||||
push edx eax
|
||||
virtual at esp
|
||||
.sector_lo dd ?
|
||||
.sector_hi dd ?
|
||||
.cache dd ?
|
||||
end virtual
|
||||
@@ -302,13 +314,13 @@ end virtual
|
||||
mov edx, [.sector_hi]
|
||||
mov [esi], eax ; sector number
|
||||
mov [esi+4], edx ; sector number
|
||||
|
||||
.yes_in_cache_write:
|
||||
|
||||
mov dword [esi+4], 2 ; write - differs from hd
|
||||
|
||||
shl edi, 9
|
||||
mov ecx, [.cache]
|
||||
|
||||
.yes_in_cache_write:
|
||||
|
||||
mov dword [esi+8], 2 ; write - differs from hd
|
||||
|
||||
shl edi, 9
|
||||
mov ecx, [.cache]
|
||||
add edi, [ecx+DISKCACHE.data]
|
||||
|
||||
mov esi, ebx
|
||||
@@ -345,30 +357,31 @@ find_empty_slot64:
|
||||
shl eax, 2
|
||||
add eax, [esi+DISKCACHE.pointer]
|
||||
cmp dword [eax+8], 2
|
||||
jb .found_slot ; it's empty or read
|
||||
dec ecx
|
||||
jnz .search_for_empty
|
||||
call write_cache64 ; no empty slots found, write all
|
||||
test eax, eax
|
||||
jne .found_slot_access_denied
|
||||
jmp .search_again ; and start again
|
||||
jb .found_slot ; it's empty or read
|
||||
dec ecx
|
||||
jnz .search_for_empty
|
||||
stdcall write_cache64, [ebp+PARTITION.Disk] ; no empty slots found, write all
|
||||
test eax, eax
|
||||
jne .found_slot_access_denied
|
||||
jmp .search_again ; and start again
|
||||
.found_slot:
|
||||
mov [esi+DISKCACHE.search_start], edi
|
||||
xor eax, eax ; success
|
||||
.found_slot_access_denied:
|
||||
ret
|
||||
|
||||
; This function is intended to replace the old 'write_cache' function.
|
||||
proc write_cache64 uses ecx edx esi edi
|
||||
locals
|
||||
cache_chain_started dd ?
|
||||
cache_chain_size dd ?
|
||||
cache_chain_pos dd ?
|
||||
cache_chain_ptr dd ?
|
||||
endl
|
||||
; If there is no cache for this disk, nothing to do.
|
||||
cmp [esi+DISKCACHE.pointer], 0
|
||||
jz .flush
|
||||
ret
|
||||
|
||||
; This function is intended to replace the old 'write_cache' function.
|
||||
proc write_cache64 uses ecx edx esi edi, disk:dword
|
||||
locals
|
||||
cache_chain_started dd 0
|
||||
cache_chain_size dd ?
|
||||
cache_chain_pos dd ?
|
||||
cache_chain_ptr dd ?
|
||||
endl
|
||||
saved_esi_pos = 16+12 ; size of local variables + size of registers before esi
|
||||
; If there is no cache for this disk, nothing to do.
|
||||
cmp [esi+DISKCACHE.pointer], 0
|
||||
jz .flush
|
||||
;-----------------------------------------------------------
|
||||
; write all changed sectors to disk
|
||||
;-----------------------------------------------------------
|
||||
@@ -429,14 +442,13 @@ endl
|
||||
dec ecx
|
||||
jnz .write_cache_more
|
||||
call .flush_cache_chain
|
||||
test eax, eax
|
||||
jnz .nothing
|
||||
.flush:
|
||||
mov esi, [ebp]
|
||||
mov esi, [esi+PARTITION.Disk]
|
||||
mov al, DISKFUNC.flush
|
||||
call disk_call_driver
|
||||
.nothing:
|
||||
test eax, eax
|
||||
jnz .nothing
|
||||
.flush:
|
||||
mov esi, [disk]
|
||||
mov al, DISKFUNC.flush
|
||||
call disk_call_driver
|
||||
.nothing:
|
||||
ret
|
||||
|
||||
.flush_cache_chain:
|
||||
@@ -451,13 +463,13 @@ endl
|
||||
.write_cache_sector:
|
||||
mov [cache_chain_size], 1
|
||||
mov [cache_chain_pos], edi
|
||||
.write_cache_chain:
|
||||
pusha
|
||||
mov edi, [cache_chain_pos]
|
||||
mov ecx, [ebp-12]
|
||||
shl edi, 9
|
||||
add edi, [ecx+DISKCACHE.data]
|
||||
mov ecx, [cache_chain_size]
|
||||
.write_cache_chain:
|
||||
pusha
|
||||
mov edi, [cache_chain_pos]
|
||||
mov ecx, [ebp-saved_esi_pos]
|
||||
shl edi, 9
|
||||
add edi, [ecx+DISKCACHE.data]
|
||||
mov ecx, [cache_chain_size]
|
||||
push ecx
|
||||
push esp ; numsectors
|
||||
mov eax, [cache_chain_ptr]
|
||||
@@ -535,13 +547,13 @@ disk_init_cache:
|
||||
imul eax, 7
|
||||
mov [esi+DISK.AppCache.data_size], eax
|
||||
mov [esi+DISK.AppCache.pointer], edx
|
||||
|
||||
mov eax, [esi+DISK.SysCache.data_size]
|
||||
push ebx
|
||||
call calculate_for_hd
|
||||
pop ebx
|
||||
add eax, [esi+DISK.SysCache.pointer]
|
||||
mov [esi+DISK.SysCache.data], eax
|
||||
|
||||
mov eax, [esi+DISK.SysCache.data_size]
|
||||
push ebx
|
||||
call calculate_for_hd64
|
||||
pop ebx
|
||||
add eax, [esi+DISK.SysCache.pointer]
|
||||
mov [esi+DISK.SysCache.data], eax
|
||||
mov [esi+DISK.SysCache.sad_size], ecx
|
||||
|
||||
push edi
|
||||
@@ -550,13 +562,13 @@ disk_init_cache:
|
||||
xor eax, eax
|
||||
rep stosd
|
||||
pop edi
|
||||
|
||||
mov eax, [esi+DISK.AppCache.data_size]
|
||||
push ebx
|
||||
call calculate_for_hd
|
||||
pop ebx
|
||||
add eax, [esi+DISK.AppCache.pointer]
|
||||
mov [esi+DISK.AppCache.data], eax
|
||||
|
||||
mov eax, [esi+DISK.AppCache.data_size]
|
||||
push ebx
|
||||
call calculate_for_hd64
|
||||
pop ebx
|
||||
add eax, [esi+DISK.AppCache.pointer]
|
||||
mov [esi+DISK.AppCache.data], eax
|
||||
mov [esi+DISK.AppCache.sad_size], ecx
|
||||
|
||||
push edi
|
||||
@@ -576,17 +588,56 @@ disk_init_cache:
|
||||
.nocache:
|
||||
mov [esi+DISK.SysCache.pointer], eax
|
||||
mov [esi+DISK.AppCache.pointer], eax
|
||||
mov al, 1
|
||||
ret
|
||||
|
||||
; This internal function is called from disk_media_dereference to free the
|
||||
; allocated cache, if there is one.
|
||||
; esi = pointer to DISK structure
|
||||
mov al, 1
|
||||
ret
|
||||
|
||||
calculate_for_hd64:
|
||||
push eax
|
||||
mov ebx, eax
|
||||
shr eax, 9
|
||||
lea eax, [eax*3]
|
||||
shl eax, 2
|
||||
sub ebx, eax
|
||||
shr ebx, 9
|
||||
mov ecx, ebx
|
||||
shl ebx, 9
|
||||
pop eax
|
||||
sub eax, ebx
|
||||
dec ecx
|
||||
ret
|
||||
|
||||
|
||||
; This internal function is called from disk_media_dereference to free the
|
||||
; allocated cache, if there is one.
|
||||
; esi = pointer to DISK structure
|
||||
disk_free_cache:
|
||||
; The algorithm is straightforward.
|
||||
mov eax, [esi+DISK.SysCache.pointer]
|
||||
test eax, eax
|
||||
jz .nothing
|
||||
stdcall kernel_free, eax
|
||||
.nothing:
|
||||
ret
|
||||
stdcall kernel_free, eax
|
||||
.nothing:
|
||||
ret
|
||||
|
||||
; This function flushes all modified data from both caches for the given DISK.
|
||||
; esi = pointer to DISK
|
||||
disk_sync:
|
||||
; Compatibility hack: if PARTITION.Disk is 'old', there is no DISK structure,
|
||||
; this request should be processed by write_cache.
|
||||
cmp esi, 'old'
|
||||
jnz @f
|
||||
mov [hdd_appl_data], 0
|
||||
call write_cache
|
||||
mov [hdd_appl_data], 1
|
||||
jmp write_cache
|
||||
@@:
|
||||
; The algorithm is straightforward.
|
||||
push esi
|
||||
push esi ; for second write_cache64
|
||||
push esi ; for first write_cache64
|
||||
add esi, DISK.SysCache
|
||||
call write_cache64
|
||||
add esi, DISK.AppCache - DISK.SysCache
|
||||
call write_cache64
|
||||
pop esi
|
||||
ret
|
||||
|
Reference in New Issue
Block a user