/kernel/branches/Kolibri-acpi/blkdev/disk.inc |
---|
350,8 → 350,10 |
inc eax |
cmp byte [ebx+eax-1], 0 |
jnz @b |
; 2b. Call the heap manager. |
; 2b. Call the heap manager. Note that it can change ebx. |
push ebx |
call malloc |
pop ebx |
; 2c. Check the result. If allocation failed, go to 7. |
pop esi ; restore allocated pointer to DISK |
test eax, eax |
418,7 → 420,7 |
push esi ; save used registers to be stdcall |
; 1. Force media to be removed. If the media is already removed, the |
; call does nothing. |
mov esi, [esp+4+8] ; esi = handle of the disk |
mov esi, [esp+4+4] ; esi = handle of the disk |
stdcall disk_media_changed, esi, 0 |
; 2. Delete the structure from the global list. |
; 2a. Acquire the mutex. |
975,15 → 977,33 |
.start dq ? |
.length dq ? |
end virtual |
; Currently no file systems are supported, so just allocate the PARTITION |
; When disk_add_partition is called, ebx contains a pointer to |
; a two-sectors-sized buffer. This function saves ebx in the stack |
; immediately before ebp. |
virtual at ebp-4 |
.buffer dd ? |
end virtual |
; 1. Read the bootsector to the buffer. |
mov al, DISKFUNC.read |
mov ebx, [.buffer] |
add ebx, 512 |
push 1 |
stdcall disk_call_driver, ebx, dword [.start], dword [.start+4], esp |
; 2. Run tests for all supported filesystems. If at least one test succeeded, |
; go to 4. |
; For tests: qword [ebp+8] = partition start, qword [ebp+10h] = partition |
; length, [esp] = 0 if reading bootsector failed or 1 if succeeded, |
; ebx points to the buffer for bootsector. |
call fat_create_partition |
test eax, eax |
jnz .success |
; 3. No file system has recognized the volume, so just allocate the PARTITION |
; structure without extra fields. |
; 1. Allocate and check result. |
push sizeof.PARTITION |
pop eax |
call malloc |
test eax, eax |
jz .nothing |
; 2. Fill the common fields: copy .start and .length. |
mov edx, dword [.start] |
mov dword [eax+PARTITION.FirstSector], edx |
mov edx, dword [.start+4] |
992,8 → 1012,12 |
mov dword [eax+PARTITION.Length], edx |
mov edx, dword [.length+4] |
mov dword [eax+PARTITION.Length+4], edx |
mov [eax+PARTITION.Disk], esi |
and [eax+PARTITION.FSUserFunctions], 0 |
.success: |
.nothing: |
; 3. Return with eax = pointer to PARTITION or NULL. |
; 4. Return with eax = pointer to PARTITION or NULL. |
pop ecx |
ret |
; This function is called from file_system_lfn. |
1061,6 → 1085,7 |
; 6. Now we are sure that the DISK structure is not going to die at least |
; while we are working with it, so release the global mutex. |
call mutex_unlock |
pop ecx ; pop from the stack saved value of esi |
; 7. Acquire the mutex for media object. |
pop edi ; restore edi |
lea ecx, [ebx+DISK.MediaLock] |
1175,15 → 1200,36 |
.main: |
cmp ecx, [edx+DISK.NumPartitions] |
jae .notfound |
mov dword [esp+32], ERROR_UNKNOWN_FS |
mov eax, [edx+DISK.Partitions] |
mov eax, [eax+ecx*4] |
mov edi, [eax+PARTITION.FSUserFunctions] |
test edi, edi |
jz .nofs |
mov ecx, [ebx] |
cmp [edi], ecx |
jbe .unsupported |
push edx |
push ebp |
mov ebp, eax |
call dword [edi+4+ecx*4] |
pop ebp |
pop edx |
mov dword [esp+32], eax |
mov dword [esp+20], ebx |
.cleanup: |
mov esi, edx |
call disk_media_dereference |
call disk_dereference |
ret |
.nofs: |
mov dword [esp+32], ERROR_UNKNOWN_FS |
jmp .cleanup |
.notfound: |
mov dword [esp+32], ERROR_FILE_NOT_FOUND |
jmp .cleanup |
.unsupported: |
mov dword [esp+32], ERROR_UNSUPPORTED_FS |
jmp .cleanup |
.nomedia: |
test ecx, ecx |
jnz .notfound |
1192,7 → 1238,6 |
; if the driver does not support insert notifications and we are the only fs |
; operation with this disk, issue the fake insert notification; if media is |
; still not inserted, 'disk_media_changed' will detect this and do nothing |
;;; push ebx |
lea ecx, [edx+DISK.MediaLock] |
call mutex_lock |
cmp [edx+DISK.MediaRefCount], 1 |
/kernel/branches/Kolibri-acpi/blkdev/disk_cache.inc |
---|
18,9 → 18,11 |
; 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 |
41,8 → 43,11 |
; 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 |
jmp hd_read |
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. |
63,7 → 68,7 |
ret |
@@: |
; 2. Get the absolute sector on the disk. |
push edx |
push edx esi |
xor edx, edx |
add eax, dword [ebp+PARTITION.FirstSector] |
adc edx, dword [ebp+PARTITION.FirstSector+4] |
75,15 → 80,16 |
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 edx |
pop esi edx |
pop ecx |
ret |
.scancache: |
; 4. Scan the cache. |
push esi edi ecx ; scan cache |
push edi ecx ; scan cache |
push edx eax |
virtual at esp |
.sector_lo dd ? |
183,9 → 189,11 |
; 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 |
206,8 → 214,11 |
; 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 |
jmp hd_write |
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. |
227,7 → 238,7 |
pop ecx |
ret |
@@: |
push edx |
push edx esi |
; 2. Get the absolute sector on the disk. |
xor edx, edx |
add eax, dword [ebp+PARTITION.FirstSector] |
240,15 → 251,16 |
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 edx |
pop esi edx |
pop ecx |
ret |
.scancache: |
; 4. Scan the cache. |
push esi edi ecx ; scan cache |
push edi ecx ; scan cache |
push edx eax |
virtual at esp |
.sector_lo dd ? |
348,7 → 360,7 |
jb .found_slot ; it's empty or read |
dec ecx |
jnz .search_for_empty |
call write_cache64 ; no empty slots found, write all |
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 |
359,7 → 371,7 |
ret |
; This function is intended to replace the old 'write_cache' function. |
proc write_cache64 uses ecx edx esi edi |
proc write_cache64 uses ecx edx esi edi, disk:dword |
locals |
cache_chain_started dd ? |
cache_chain_size dd ? |
432,8 → 444,7 |
test eax, eax |
jnz .nothing |
.flush: |
mov esi, [ebp] |
mov esi, [esi+PARTITION.Disk] |
mov esi, [disk] |
mov al, DISKFUNC.flush |
call disk_call_driver |
.nothing: |
590,3 → 601,26 |
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 |
/kernel/branches/Kolibri-acpi/blkdev/hd_drv.inc |
---|
945,3 → 945,83 |
@@: |
ret |
; \end{diamond} |
reserve_hd1: |
cli |
cmp [hd1_status], 0 |
je reserve_ok1 |
sti |
call change_task |
jmp reserve_hd1 |
reserve_ok1: |
push eax |
mov eax, [CURRENT_TASK] |
shl eax, 5 |
mov eax, [eax+CURRENT_TASK+TASKDATA.pid] |
mov [hd1_status], eax |
pop eax |
sti |
ret |
;******************************************** |
uglobal |
hd_in_cache db ? |
endg |
reserve_hd_channel: |
; BIOS disk accesses are protected with common mutex hd1_status |
; This must be modified when hd1_status will not be valid! |
cmp [hdpos], 0x80 |
jae .ret |
cmp [hdbase], 0x1F0 |
jne .IDE_Channel_2 |
.IDE_Channel_1: |
cli |
cmp [IDE_Channel_1], 0 |
je .reserve_ok_1 |
sti |
call change_task |
jmp .IDE_Channel_1 |
.IDE_Channel_2: |
cli |
cmp [IDE_Channel_2], 0 |
je .reserve_ok_2 |
sti |
call change_task |
jmp .IDE_Channel_2 |
.reserve_ok_1: |
mov [IDE_Channel_1], 1 |
push eax |
mov al, 1 |
jmp @f |
.reserve_ok_2: |
mov [IDE_Channel_2], 1 |
push eax |
mov al, 3 |
@@: |
cmp [hdid], 1 |
sbb al, -1 |
mov [hd_in_cache], al |
pop eax |
sti |
.ret: |
ret |
free_hd_channel: |
; see comment at reserve_hd_channel |
cmp [hdpos], 0x80 |
jae .ret |
cmp [hdbase], 0x1F0 |
jne .IDE_Channel_2 |
.IDE_Channel_1: |
mov [IDE_Channel_1], 0 |
.ret: |
ret |
.IDE_Channel_2: |
mov [IDE_Channel_2], 0 |
ret |
;******************************************** |
/kernel/branches/Kolibri-acpi/blkdev/ide_cache.inc |
---|
137,8 → 137,6 |
;-------------------------------------------------------------------- |
align 4 |
clear_hd_cache: |
mov [fat_in_cache], -1 |
mov [fat_change], 0 |
ret |
;-------------------------------------------------------------------- |
align 4 |