Subversion Repositories Kolibri OS

Rev

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

Rev 4287 Rev 5201
Line 1... Line 1...
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2011-2012. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2011-2014. 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 7... Line 7...
7
 
7
 
Line 14... Line 14...
14
DISK_STATUS_OK              = 0 ; success
14
DISK_STATUS_OK              = 0 ; success
15
DISK_STATUS_GENERAL_ERROR   = -1; if no other code is suitable
15
DISK_STATUS_GENERAL_ERROR   = -1; if no other code is suitable
16
DISK_STATUS_INVALID_CALL    = 1 ; invalid input parameters
16
DISK_STATUS_INVALID_CALL    = 1 ; invalid input parameters
17
DISK_STATUS_NO_MEDIA        = 2 ; no media present
17
DISK_STATUS_NO_MEDIA        = 2 ; no media present
18
DISK_STATUS_END_OF_MEDIA    = 3 ; end of media while reading/writing data
18
DISK_STATUS_END_OF_MEDIA    = 3 ; end of media while reading/writing data
-
 
19
DISK_STATUS_NO_MEMORY       = 4 ; insufficient memory for driver operation
19
; Driver flags. Represent bits in DISK.DriverFlags.
20
; Driver flags. Represent bits in DISK.DriverFlags.
20
DISK_NO_INSERT_NOTIFICATION = 1
21
DISK_NO_INSERT_NOTIFICATION = 1
21
; Media flags. Represent bits in DISKMEDIAINFO.Flags.
22
; Media flags. Represent bits in DISKMEDIAINFO.Flags.
22
DISK_MEDIA_READONLY = 1
23
DISK_MEDIA_READONLY = 1
Line 99... Line 100...
99
 
100
 
100
; This structure represents the disk cache. To follow the old implementation,
101
; This structure represents the disk cache. To follow the old implementation,
101
; there are two distinct caches for a disk, one for "system" data,and the other
102
; there are two distinct caches for a disk, one for "system" data,and the other
102
; for "application" data.
103
; for "application" data.
103
struct  DISKCACHE
-
 
104
        mutex           MUTEX
-
 
105
; Lock to protect the cache.
104
struct  DISKCACHE
106
; The following fields are inherited from data32.inc:cache_ideX.
105
; The following fields are inherited from data32.inc:cache_ideX.
107
        pointer         dd ?
106
        pointer         dd ?
108
        data_size       dd ?    ; unused
107
        data_size       dd ?    ; unused
109
        data            dd ?
108
        data            dd ?
110
        sad_size        dd ?
109
        sad_size        dd ?
-
 
110
        search_start    dd ?
111
        search_start    dd ?
111
        sector_size_log dd ?
Line 112... Line 112...
112
ends
112
ends
113
 
113
 
114
; 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.
Line 167... Line 167...
167
; Number of partitions on this media.
167
; Number of partitions on this media.
168
        Partitions      dd ?
168
        Partitions      dd ?
169
; Pointer to array of .NumPartitions pointers to PARTITION structures.
169
; Pointer to array of .NumPartitions pointers to PARTITION structures.
170
        cache_size      dd ?
170
        cache_size      dd ?
171
; inherited from cache_ideX_size
171
; inherited from cache_ideX_size
-
 
172
        CacheLock       MUTEX
-
 
173
; Lock to protect both caches.
172
        SysCache        DISKCACHE
174
        SysCache        DISKCACHE
173
        AppCache        DISKCACHE
175
        AppCache        DISKCACHE
174
; Two caches for the disk.
176
; Two caches for the disk.
175
ends
177
ends
Line 268... Line 270...
268
;   filesystem operations are referencing the same filesystem data, this is
270
;   filesystem operations are referencing the same filesystem data, this is
269
;   better resolved at the level of the filesystem.
271
;   better resolved at the level of the filesystem.
270
endg
272
endg
Line 271... Line 273...
271
 
273
 
272
iglobal
274
iglobal
273
; The function 'disk_scan_partitions' needs three 512-byte buffers for
275
; The function 'disk_scan_partitions' needs three sector-sized buffers for
274
; MBR, bootsector and fs-temporary sector data. It can not use the static
276
; MBR, bootsector and fs-temporary sector data. It can not use the static
275
; buffers always, since it can be called for two or more disks in parallel.
277
; buffers always, since it can be called for two or more disks in parallel.
276
; However, this case is not typical. We reserve three static 512-byte buffers
278
; However, this case is not typical. We reserve three static 512-byte buffers
277
; and a flag that these buffers are currently used. If 'disk_scan_partitions'
279
; 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
280
; detects that the buffers are currently used, it allocates buffers from the
279
; heap.
281
; heap. Also, the heap is used when sector size is other than 512.
280
; The flag is implemented as a global dword variable. When the static buffers
282
; The flag is implemented as a global dword variable. When the static buffers
281
; are not used, the value is -1. When the static buffers are used, the value
283
; are not used, the value is -1. When the static buffers are used, the value
282
; is normally 0 and temporarily can become greater. The function increments
284
; is normally 0 and temporarily can become greater. The function increments
283
; this value. If the resulting value is zero, it uses the buffers and
285
; this value. If the resulting value is zero, it uses the buffers and
Line 635... Line 637...
635
; esi = pointer to the DISK structure.
637
; esi = pointer to the DISK structure.
636
disk_scan_partitions:
638
disk_scan_partitions:
637
; 1. Initialize .NumPartitions and .Partitions fields as zeros: empty list.
639
; 1. Initialize .NumPartitions and .Partitions fields as zeros: empty list.
638
        and     [esi+DISK.NumPartitions], 0
640
        and     [esi+DISK.NumPartitions], 0
639
        and     [esi+DISK.Partitions], 0
641
        and     [esi+DISK.Partitions], 0
640
; 2. Currently we can work only with 512-bytes sectors. Check this restriction.
-
 
641
; The only exception is 2048-bytes CD/DVD, but they are not supported yet by
-
 
642
; this code.
-
 
643
        cmp     [esi+DISK.MediaInfo.SectorSize], 512
-
 
644
        jz      .doscan
-
 
645
        DEBUGF 1,'K : sector size is %d, only 512 is supported\n',[esi+DISK.MediaInfo.SectorSize]
-
 
646
        ret
-
 
647
.doscan:
-
 
648
; 3. Acquire the buffer for MBR and bootsector tests. See the comment before
642
; 2. Acquire the buffer for MBR and bootsector tests. See the comment before
649
; the 'partition_buffer_users' variable.
643
; the 'partition_buffer_users' variable.
-
 
644
        mov     eax, [esi+DISK.MediaInfo.SectorSize]
-
 
645
        cmp     eax, 512
-
 
646
        jnz     @f
650
        mov     ebx, mbr_buffer         ; assume the global buffer is free
647
        mov     ebx, mbr_buffer         ; assume the global buffer is free
651
        lock inc [partition_buffer_users]
648
        lock inc [partition_buffer_users]
652
        jz      .buffer_acquired        ; yes, it is free
649
        jz      .buffer_acquired        ; yes, it is free
653
        lock dec [partition_buffer_users]       ; no, we must allocate
650
        lock dec [partition_buffer_users]       ; no, we must allocate
-
 
651
@@:
-
 
652
        lea     eax, [eax*3]
654
        stdcall kernel_alloc, 512*3
653
        stdcall kernel_alloc, eax
655
        test    eax, eax
654
        test    eax, eax
656
        jz      .nothing
655
        jz      .nothing
657
        xchg    eax, ebx
656
        xchg    eax, ebx
658
.buffer_acquired:
657
.buffer_acquired:
659
; 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
660
; more than MAX_NUM_PARTITION times.
659
; more than MAX_NUM_PARTITION times.
661
; 4. Prepare things for the loop.
660
; 3. Prepare things for the loop.
662
; ebp will hold the sector number for current MBR/EBR.
661
; ebp will hold the sector number for current MBR/EBR.
663
; [esp] will hold the sector number for current extended partition, if there
662
; [esp] will hold the sector number for current extended partition, if there
664
; is one.
663
; is one.
665
; [esp+4] will hold the counter that prevents long loops.
664
; [esp+4] will hold the counter that prevents long loops.
666
        push    ebp             ; save ebp
665
        push    ebp             ; save ebp
667
        push    MAX_NUM_PARTITIONS      ; the counter of max MBRs to process
666
        push    MAX_NUM_PARTITIONS      ; the counter of max MBRs to process
668
        xor     ebp, ebp        ; start from sector zero
667
        xor     ebp, ebp        ; start from sector zero
669
        push    ebp             ; no extended partition yet
668
        push    ebp             ; no extended partition yet
-
 
669
; 4. MBR is 512 bytes long. If sector size is less than 512 bytes,
-
 
670
; assume no MBR, no partitions and go to 10.
-
 
671
        cmp     [esi+DISK.MediaInfo.SectorSize], 512
-
 
672
        jb      .notmbr
670
.new_mbr:
673
.new_mbr:
671
; 5. Read the current sector.
674
; 5. Read the current sector.
672
; Note that 'read' callback operates with 64-bit sector numbers, so we must
675
; Note that 'read' callback operates with 64-bit sector numbers, so we must
673
; push additional zero as a high dword of sector number.
676
; push additional zero as a high dword of sector number.
674
        mov     al, DISKFUNC.read
677
        mov     al, DISKFUNC.read
Line 983... Line 986...
983
; 1. Read the bootsector to the buffer.
986
; 1. Read the bootsector to the buffer.
984
; When disk_add_partition is called, ebx contains a pointer to
987
; When disk_add_partition is called, ebx contains a pointer to
985
; a three-sectors-sized buffer. This function saves ebx in the stack
988
; a three-sectors-sized buffer. This function saves ebx in the stack
986
; immediately before ebp.
989
; immediately before ebp.
987
        mov     ebx, [ebp-4] ; get buffer
990
        mov     ebx, [ebp-4] ; get buffer
988
        add     ebx, 512     ; advance over MBR data to bootsector data
991
        add     ebx, [esi+DISK.MediaInfo.SectorSize] ; advance over MBR data to bootsector data
989
        add     ebp, 8       ; ebp points to part of PARTITION structure
992
        add     ebp, 8       ; ebp points to part of PARTITION structure
990
        xor     eax, eax     ; first sector of the partition
993
        xor     eax, eax     ; first sector of the partition
991
        call    fs_read32_sys
994
        call    fs_read32_sys
992
        push    eax
995
        push    eax
993
; 2. Run tests for all supported filesystems. If at least one test succeeded,
996
; 2. Run tests for all supported filesystems. If at least one test succeeded,
994
; go to 4.
997
; go to 4.
995
; For tests:
998
; For tests:
996
; ebp -> first three fields of PARTITION structure, .start, .length, .disk;
999
; ebp -> first three fields of PARTITION structure, .start, .length, .disk;
997
; [esp] = error code after bootsector read: 0 = ok, otherwise = failed,
1000
; [esp] = error code after bootsector read: 0 = ok, otherwise = failed,
998
; ebx points to the buffer for bootsector,
1001
; ebx points to the buffer for bootsector,
999
; ebx+512 points to 512-bytes buffer that can be used for anything.
1002
; ebx+[esi+DISK.MediaInfo.SectorSize] points to sector-sized buffer that can be used for anything.
1000
        call    fat_create_partition
1003
        call    fat_create_partition
1001
        test    eax, eax
1004
        test    eax, eax
1002
        jnz     .success
1005
        jnz     .success
1003
        call    ntfs_create_partition
1006
        call    ntfs_create_partition
1004
        test    eax, eax
1007
        test    eax, eax