Subversion Repositories Kolibri OS

Rev

Rev 2129 | Rev 2145 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2129 Rev 2140
Line 3... Line 3...
3
;; Copyright (C) KolibriOS team 2011. All rights reserved.      ;;
3
;; Copyright (C) KolibriOS team 2011. All rights reserved.      ;;
4
;; Distributed under terms of the GNU General Public License    ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Line -... Line 7...
-
 
7
 
-
 
8
$Revision: 2140 $
7
 
9
 
8
; =============================================================================
10
; =============================================================================
9
; ================================= Constants =================================
11
; ================================= Constants =================================
10
; =============================================================================
12
; =============================================================================
11
; Error codes for callback functions.
13
; Error codes for callback functions.
Line 74... Line 76...
74
; int flush(void* userdata);
76
; int flush(void* userdata);
75
; Return value: one of DISK_STATUS_*
77
; Return value: one of DISK_STATUS_*
76
; Note that read/write are called by the cache manager, so a driver should not
78
; Note that read/write are called by the cache manager, so a driver should not
77
; create a software cache. This function is implemented for flushing a hardware
79
; create a software cache. This function is implemented for flushing a hardware
78
; cache, if it exists.
80
; cache, if it exists.
-
 
81
.adjust_cache_size      dd      ?
-
 
82
; The pointer to the function which returns the cache size for this device.
-
 
83
; Optional, may be NULL.
-
 
84
; unsigned int adjust_cache_size(unsigned int suggested_size);
-
 
85
; Return value: 0 = disable cache, otherwise = used cache size in bytes.
79
ends
86
ends
Line 80... Line 87...
80
 
87
 
81
; This structure holds an information about a media.
88
; This structure holds an information about a media.
82
; Objects with this structure are allocated by the kernel as a part of DISK
89
; Objects with this structure are allocated by the kernel as a part of DISK
Line 88... Line 95...
88
; Size of the sector.
95
; Size of the sector.
89
.Capacity       dq      ?
96
.Capacity       dq      ?
90
; Size of the media in sectors.
97
; Size of the media in sectors.
91
ends
98
ends
Line -... Line 99...
-
 
99
 
-
 
100
; This structure represents disk cache. To follow the old implementation,
-
 
101
; there are two distinct caches for a disk, one for "system" data, other
-
 
102
; for "application" data.
-
 
103
struct DISKCACHE
-
 
104
.Lock           MUTEX
-
 
105
; Lock to protect the cache.
-
 
106
; The following fields are inherited from data32.inc:cache_ideX.
-
 
107
.pointer     rd 1
-
 
108
.data_size   rd 1   ; not use
-
 
109
.data        rd 1
-
 
110
.sad_size    rd 1
-
 
111
.search_start       rd 1
-
 
112
ends
92
 
113
 
93
; This structure represents a disk device and its media for the kernel.
114
; This structure represents a disk device and its media for the kernel.
94
; This structure is allocated by the kernel in the 'disk_add' function,
115
; This structure is allocated by the kernel in the 'disk_add' function,
95
; freed in the 'disk_dereference' function.
116
; freed in the 'disk_dereference' function.
96
struct DISK
117
struct DISK
Line 144... Line 165...
144
; This field keeps an information about the current media.
165
; This field keeps an information about the current media.
145
.NumPartitions  dd      ?
166
.NumPartitions  dd      ?
146
; Number of partitions on this media.
167
; Number of partitions on this media.
147
.Partitions     dd      ?
168
.Partitions     dd      ?
148
; Pointer to array of .NumPartitions pointers to PARTITION structures.
169
; Pointer to array of .NumPartitions pointers to PARTITION structures.
-
 
170
.cache_size     dd      ?
-
 
171
; inherited from cache_ideX_size
-
 
172
.SysCache       DISKCACHE
-
 
173
.AppCache       DISKCACHE
-
 
174
; Two caches for the disk.
149
ends
175
ends
Line 150... Line 176...
150
 
176
 
151
; This structure represents one partition for the kernel. This is a base
177
; This structure represents one partition for the kernel. This is a base
152
; template, the actual contents after common fields is determined by the
178
; template, the actual contents after common fields is determined by the
153
; file system code for this partition.
179
; file system code for this partition.
154
struct PARTITION
180
struct PARTITION
155
.FirstSector    dq      ?
181
.FirstSector    dq      ?
156
; First sector of the partition.
182
; First sector of the partition.
157
.Length         dq      ?
183
.Length         dq      ?
-
 
184
; Length of the partition in sectors.
-
 
185
.Disk           dd      ?
158
; Length of the partition in sectors.
186
; Pointer to parent DISK structure.
159
.FSUserFunctions        dd      ?
187
.FSUserFunctions        dd      ?
160
; Handlers for the sysfunction 70h. This field is a pointer to the following
188
; Handlers for the sysfunction 70h. This field is a pointer to the following
161
; array. The first dword is a number of supported subfunctions, other dwords
189
; array. The first dword is a number of supported subfunctions, other dwords
162
; point to handlers of corresponding subfunctions.
190
; point to handlers of corresponding subfunctions.
Line 240... Line 268...
240
;   filesystem operations are referencing the same filesystem data, this is
268
;   filesystem operations are referencing the same filesystem data, this is
241
;   better resolved at the level of the filesystem.
269
;   better resolved at the level of the filesystem.
242
endg
270
endg
Line 243... Line 271...
243
 
271
 
244
iglobal
272
iglobal
245
; The function 'disk_scan_partitions' needs two 512-byte buffers for
273
; The function 'disk_scan_partitions' needs three 512-byte buffers for
246
; MBR and bootsectors data. It can not use the static buffers always,
274
; MBR, bootsector and fs-temporary sector data. It can not use the static
247
; since it can be called for two or more disks in parallel. However, this
275
; buffers always, since it can be called for two or more disks in parallel.
248
; case is not typical. We reserve two static 512-byte buffers and a flag
276
; However, this case is not typical. We reserve three static 512-byte buffers
249
; that these buffers are currently used. If 'disk_scan_partitions' detects that
277
; and a flag that these buffers are currently used. If 'disk_scan_partitions'
-
 
278
; detects that the buffers are currently used, it allocates buffers from the
250
; the buffers are currently used, it allocates buffers from the heap.
279
; heap.
251
; The flag is implemented as a global dword variable. When the static buffers
280
; The flag is implemented as a global dword variable. When the static buffers
252
; are not used, the value is -1. When the static buffers are used, the value
281
; are not used, the value is -1. When the static buffers are used, the value
253
; is normally 0 and temporarily can become greater. The function increments
282
; is normally 0 and temporarily can become greater. The function increments
254
; this value. If the resulting value is zero, it uses the buffers and
283
; this value. If the resulting value is zero, it uses the buffers and
255
; decrements the value when the job is done. Otherwise, it immediately
284
; decrements the value when the job is done. Otherwise, it immediately
256
; decrements the value and uses buffers from the heap, allocated in the
285
; decrements the value and uses buffers from the heap, allocated in the
257
; beginning and freed in the end.
286
; beginning and freed in the end.
258
partition_buffer_users  dd      -1
287
partition_buffer_users  dd      -1
259
endg
288
endg
260
uglobal
289
uglobal
261
; The static buffers for MBR and bootsectors data.
290
; The static buffers for MBR, bootsector and fs-temporary sector data.
262
align 16
291
align 16
263
mbr_buffer      rb      512
292
mbr_buffer      rb      512
-
 
293
bootsect_buffer rb      512
264
bootsect_buffer rb      512
294
fs_tmp_buffer   rb      512
Line 265... Line 295...
265
endg
295
endg
266
 
296
 
267
iglobal
297
iglobal
Line 274... Line 304...
274
        dd      disk_default_closemedia
304
        dd      disk_default_closemedia
275
        dd      disk_default_querymedia
305
        dd      disk_default_querymedia
276
        dd      disk_default_read
306
        dd      disk_default_read
277
        dd      disk_default_write
307
        dd      disk_default_write
278
        dd      disk_default_flush
308
        dd      disk_default_flush
-
 
309
        dd      disk_default_adjust_cache_size
279
endg
310
endg
Line 280... Line 311...
280
 
311
 
281
; =============================================================================
312
; =============================================================================
282
; ================================= Functions =================================
313
; ================================= Functions =================================
Line 310... Line 341...
310
; 1b. Check the result. If allocation failed, return (go to 9) with eax = 0.
341
; 1b. Check the result. If allocation failed, return (go to 9) with eax = 0.
311
        test    eax, eax
342
        test    eax, eax
312
        jz      .nothing
343
        jz      .nothing
313
; 2. Copy disk name to the DISK structure.
344
; 2. Copy disk name to the DISK structure.
314
; 2a. Get length of the name, including the terminating zero.
345
; 2a. Get length of the name, including the terminating zero.
315
        mov     esi, [esp+8+8]  ; esi = pointer to name
346
        mov     ebx, [esp+8+8]  ; ebx = pointer to name
316
        push    eax             ; save allocated pointer to DISK
347
        push    eax             ; save allocated pointer to DISK
317
        xor     eax, eax        ; the argument of malloc() is in eax
348
        xor     eax, eax        ; the argument of malloc() is in eax
318
@@:
349
@@:
319
        inc     eax
350
        inc     eax
320
        cmp     byte [esi+eax-1], 0
351
        cmp     byte [ebx+eax-1], 0
321
        jnz     @b
352
        jnz     @b
322
; 2b. Call the heap manager.
353
; 2b. Call the heap manager.
323
        call    malloc
354
        call    malloc
324
; 2c. Check the result. If allocation failed, go to 7.
355
; 2c. Check the result. If allocation failed, go to 7.
325
        pop     ebx             ; restore allocated pointer to DISK
356
        pop     esi             ; restore allocated pointer to DISK
326
        test    eax, eax
357
        test    eax, eax
327
        jz      .free
358
        jz      .free
328
; 2d. Store the allocated pointer to the DISK structure.
359
; 2d. Store the allocated pointer to the DISK structure.
329
        mov     [ebx+DISK.Name], eax
360
        mov     [esi+DISK.Name], eax
330
; 2e. Copy the name.
361
; 2e. Copy the name.
331
@@:
362
@@:
332
        mov     dl, [esi]
363
        mov     dl, [ebx]
333
        mov     [eax], dl
364
        mov     [eax], dl
334
        inc     esi
365
        inc     ebx
335
        inc     eax
366
        inc     eax
336
        test    dl, dl
367
        test    dl, dl
337
        jnz     @b
368
        jnz     @b
338
; 3. Copy other arguments of the function to the DISK structure.
369
; 3. Copy other arguments of the function to the DISK structure.
339
        mov     eax, [esp+4+8]
370
        mov     eax, [esp+4+8]
340
        mov     [ebx+DISK.Functions], eax
371
        mov     [esi+DISK.Functions], eax
341
        mov     eax, [esp+12+8]
372
        mov     eax, [esp+12+8]
342
        mov     [ebx+DISK.UserData], eax
373
        mov     [esi+DISK.UserData], eax
343
        mov     eax, [esp+16+8]
374
        mov     eax, [esp+16+8]
344
        mov     [ebx+DISK.DriverFlags], eax
375
        mov     [esi+DISK.DriverFlags], eax
345
; 4. Initialize other fields of the DISK structure.
376
; 4. Initialize other fields of the DISK structure.
346
; Media is not inserted, initialized state of mutex is zero,
377
; Media is not inserted, reference counter is 1.
347
; reference counter is 1.
-
 
348
        lea     ecx, [ebx+DISK.MediaLock]
378
        lea     ecx, [esi+DISK.MediaLock]
349
        call    mutex_init
379
        call    mutex_init
350
        xor     eax, eax
380
        xor     eax, eax
351
        mov     dword [ebx+DISK.MediaInserted], eax
381
        mov     dword [esi+DISK.MediaInserted], eax
352
        inc     eax
382
        inc     eax
353
        mov     [ebx+DISK.RefCount], eax
383
        mov     [esi+DISK.RefCount], eax
354
; The DISK structure is initialized.
384
; The DISK structure is initialized.
355
; 5. Insert the new structure to the global list.
385
; 5. Insert the new structure to the global list.
356
; 5a. Acquire the mutex.
386
; 5a. Acquire the mutex.
357
        mov     ecx, disk_list_mutex
387
        mov     ecx, disk_list_mutex
358
        call    mutex_lock
388
        call    mutex_lock
359
; 5b. Insert item to the tail of double-linked list.
389
; 5b. Insert item to the tail of double-linked list.
360
        mov     edx, disk_list
390
        mov     edx, disk_list
361
        list_add_tail ebx, edx     ;ebx= new edx= list head
391
        list_add_tail esi, edx     ;esi= new edx= list head
362
; 5c. Release the mutex.
392
; 5c. Release the mutex.
363
        call mutex_unlock
393
        call    mutex_unlock
364
; 6. Return with eax = pointer to DISK.
394
; 6. Return with eax = pointer to DISK.
365
        xchg    eax, ebx
395
        xchg    eax, esi
366
        jmp     .nothing
396
        jmp     .nothing
367
.free:
397
.free:
368
; Memory allocation for DISK structure succeeded, but for disk name failed.
398
; Memory allocation for DISK structure succeeded, but for disk name failed.
369
; 7. Free the DISK structure.
399
; 7. Free the DISK structure.
370
        xchg    eax, ebx
400
        xchg    eax, esi
371
        call    free
401
        call    free
372
; 8. Return with eax = 0.
402
; 8. Return with eax = 0.
373
        xor     eax, eax
403
        xor     eax, eax
374
.nothing:
404
.nothing:
375
; 9. Return.
405
; 9. Return.
Line 472... Line 502...
472
        call    free
502
        call    free
473
        dec     edi
503
        dec     edi
474
        jnz     .freeloop
504
        jnz     .freeloop
475
.nofree:
505
.nofree:
476
        pop     edi esi
506
        pop     edi esi
-
 
507
; 3b. Free the cache.
-
 
508
        call    disk_free_cache
477
; 3b. Call the driver.
509
; 3c. Call the driver.
478
        mov     al, DISKFUNC.closemedia
510
        mov     al, DISKFUNC.closemedia
479
        stdcall disk_call_driver
511
        stdcall disk_call_driver
480
; 3c. Clear the flag.
512
; 3d. Clear the flag.
481
        mov     [esi+DISK.MediaUsed], 0
513
        mov     [esi+DISK.MediaUsed], 0
482
.nothing:
514
.nothing:
483
        ret
515
        ret
Line 484... Line 516...
484
 
516
 
Line 523... Line 555...
523
        mov     al, DISKFUNC.querymedia
555
        mov     al, DISKFUNC.querymedia
524
        stdcall disk_call_driver, edx
556
        stdcall disk_call_driver, edx
525
; 3b. Check the result of the callback. Abort if it failed.
557
; 3b. Check the result of the callback. Abort if it failed.
526
        test    eax, eax
558
        test    eax, eax
527
        jnz     .noinsert
559
        jnz     .noinsert
-
 
560
; 3c. Allocate the cache unless disabled by the driver. Abort if failed.
-
 
561
        call    disk_init_cache
-
 
562
        test    al, al
-
 
563
        jz      .noinsert
528
; 3c. Acquire the lifetime reference for the media object.
564
; 3d. Acquire the lifetime reference for the media object.
529
        inc     [esi+DISK.MediaRefCount]
565
        inc     [esi+DISK.MediaRefCount]
530
; 3d. Scan for partitions. Ignore result; the list of partitions is valid even
566
; 3e. Scan for partitions. Ignore result; the list of partitions is valid even
531
; on errors.
567
; on errors.
532
        call    disk_scan_partitions
568
        call    disk_scan_partitions
533
; 3e. Media is inserted and available for use.
569
; 3f. Media is inserted and available for use.
534
        inc     [esi+DISK.MediaInserted]
570
        inc     [esi+DISK.MediaInserted]
535
.noinsert:
571
.noinsert:
536
; 4. Return.
572
; 4. Return.
537
        pop     edi esi ebx             ; restore used registers to be stdcall
573
        pop     edi esi ebx             ; restore used registers to be stdcall
538
        ret     8                       ; purge 2 dword arguments to be stdcall
574
        ret     8                       ; purge 2 dword arguments to be stdcall
Line 584... Line 620...
584
disk_default_closemedia:
620
disk_default_closemedia:
585
disk_default_flush:
621
disk_default_flush:
586
        xor     eax, eax
622
        xor     eax, eax
587
        ret     4
623
        ret     4
Line -... Line 624...
-
 
624
 
-
 
625
; The default implementation of DISKFUNC.adjust_cache_size.
-
 
626
disk_default_adjust_cache_size:
-
 
627
        mov     eax, [esp+4]
-
 
628
        ret     4
588
 
629
 
589
; This is an internal function called from 'disk_media_changed' when new media
630
; This is an internal function called from 'disk_media_changed' when new media
590
; is detected. It creates the list of partitions for the media.
631
; is detected. It creates the list of partitions for the media.
591
; If media is not partitioned, then the list consists of one partition which
632
; If media is not partitioned, then the list consists of one partition which
592
; covers all the media.
633
; covers all the media.
Line 607... Line 648...
607
; the 'partition_buffer_users' variable.
648
; the 'partition_buffer_users' variable.
608
        mov     ebx, mbr_buffer         ; assume the global buffer is free
649
        mov     ebx, mbr_buffer         ; assume the global buffer is free
609
lock    inc     [partition_buffer_users]
650
lock    inc     [partition_buffer_users]
610
        jz      .buffer_acquired        ; yes, it is free
651
        jz      .buffer_acquired        ; yes, it is free
611
lock    dec     [partition_buffer_users]        ; no, we must allocate
652
lock    dec     [partition_buffer_users]        ; no, we must allocate
612
        stdcall kernel_alloc, 1024
653
        stdcall kernel_alloc, 512*3
613
        test    eax, eax
654
        test    eax, eax
614
        jz      .nothing
655
        jz      .nothing
615
        xchg    eax, ebx
656
        xchg    eax, ebx
616
.buffer_acquired:
657
.buffer_acquired:
617
; MBR/EBRs are organized in the chain. We use a loop over MBR/EBRs, but no
658
; MBR/EBRs are organized in the chain. We use a loop over MBR/EBRs, but no
Line 710... Line 751...
710
; are most likely partitioned with GPT, not MBR scheme, since the precise
751
; are most likely partitioned with GPT, not MBR scheme, since the precise
711
; calculation here would increase limit just twice at the price of big
752
; calculation here would increase limit just twice at the price of big
712
; compatibility problems.
753
; compatibility problems.
713
        pop     eax     ; load extended partition
754
        pop     eax     ; load extended partition
714
        add     ebp, eax
755
        add     ebp, eax
-
 
756
        jc      .mbr_failed
715
; 12c. If extended partition has not yet started, start it.
757
; 12c. If extended partition has not yet started, start it.
716
        test    eax, eax
758
        test    eax, eax
717
        jnz     @f
759
        jnz     @f
718
        mov     eax, ebp
760
        mov     eax, ebp
719
@@:
761
@@:
Line 847... Line 889...
847
        mov     ecx, [edi]
889
        mov     ecx, [edi]
848
        add     edi, 4
890
        add     edi, 4
849
; The range [.FirstSector, .FirstSector+.Length) must be either entirely to
891
; The range [.FirstSector, .FirstSector+.Length) must be either entirely to
850
; the left of [start, start+length) or entirely to the right.
892
; the left of [start, start+length) or entirely to the right.
851
; 2c. Subtract .FirstSector - start. The possible overflow distinguish between
893
; 2c. Subtract .FirstSector - start. The possible overflow distinguish between
852
; cases "to the left" (2?) and "to the right" (2d).
894
; cases "to the left" (2e) and "to the right" (2d).
853
        mov     eax, dword [ecx+PARTITION.FirstSector]
895
        mov     eax, dword [ecx+PARTITION.FirstSector]
854
        mov     edx, dword [ecx+PARTITION.FirstSector+4]
896
        mov     edx, dword [ecx+PARTITION.FirstSector+4]
855
        sub     eax, dword [start]
897
        sub     eax, dword [start]
856
        sbb     edx, dword [start+4]
898
        sbb     edx, dword [start+4]
857
        jb      .less
899
        jb      .less