GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: fx_media_format.c Lines: 181 181 100.0 %
Date: 2024-01-10 21:53:23 Branches: 72 72 100.0 %

Line Branch Exec Source
1
/**************************************************************************/
2
/*                                                                        */
3
/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
4
/*                                                                        */
5
/*       This software is licensed under the Microsoft Software License   */
6
/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
7
/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
8
/*       and in the root directory of this software.                      */
9
/*                                                                        */
10
/**************************************************************************/
11
12
13
/**************************************************************************/
14
/**************************************************************************/
15
/**                                                                       */
16
/** FileX Component                                                       */
17
/**                                                                       */
18
/**   Media                                                               */
19
/**                                                                       */
20
/**************************************************************************/
21
/**************************************************************************/
22
23
#define FX_SOURCE_CODE
24
25
26
/* Include necessary system files.  */
27
28
#include "fx_api.h"
29
#include "fx_media.h"
30
#include "fx_utility.h"
31
32
33
/* Define global variables necessary for formatting.  */
34
35
/* Define OEM Name. This name must be 8 characters long and be blank padded.
36
   The default may be changed by modifying this file or calling the
37
   fx_media_format_oem_name_set utility prior to calling fx_media_format.  */
38
39
UCHAR   _fx_media_format_oem_name[8] = "EL FILEX";
40
41
42
/* Define the default media type.  This default may be changed by modifying
43
   this file or calling the fx_media_format_type_set utility prior to calling
44
   fx_media_format.  */
45
46
UCHAR _fx_media_format_media_type =  0xF8;
47
48
49
/* Define the default volume ID.  This default may be changed by modifying
50
   this file or calling the fx_media_format_volume_id_set utility prior to calling
51
   fx_media_format.  */
52
53
ULONG _fx_media_format_volume_id =  1;
54
55
56
/**************************************************************************/
57
/*                                                                        */
58
/*  FUNCTION                                               RELEASE        */
59
/*                                                                        */
60
/*    _fx_media_format                                    PORTABLE C      */
61
/*                                                           6.1.11       */
62
/*  AUTHOR                                                                */
63
/*                                                                        */
64
/*    William E. Lamie, Microsoft Corporation                             */
65
/*                                                                        */
66
/*  DESCRIPTION                                                           */
67
/*                                                                        */
68
/*    This function creates a FAT12/16/32 format with raw calls to the    */
69
/*    I/O driver. It can and must be called before the fx_media_open      */
70
/*    and is designed to utilize the same underlying FileX driver.        */
71
/*                                                                        */
72
/*  INPUT                                                                 */
73
/*                                                                        */
74
/*    media_ptr                             Pointer to media control block*/
75
/*                                            (does not need to be opened)*/
76
/*    driver                                Pointer to FileX driver (must */
77
/*                                            be able to field requests   */
78
/*                                            prior to opening)           */
79
/*    driver_info_ptr                       Optional information pointer  */
80
/*    memory_ptr                            Pointer to memory used by the */
81
/*                                            FileX for this media.       */
82
/*    memory_size                           Size of media memory - must   */
83
/*                                            at least 512 bytes and      */
84
/*                                            one sector size.            */
85
/*    volume_name                           Name of the volume            */
86
/*    number_of_fats                        Number of FAT tables          */
87
/*    directory_entries                     Number of directory entries   */
88
/*    hidden_sectors                        Number of hidden sectors      */
89
/*    total_sectors                         Total number of sectors       */
90
/*    bytes_per_sector                      Number of bytes per sector    */
91
/*    sectors_per_cluster                   Number of sectors per cluster */
92
/*    heads                                 Number of heads               */
93
/*    sectors_per_track                     Number of sectors per track   */
94
/*                                                                        */
95
/*  OUTPUT                                                                */
96
/*                                                                        */
97
/*    Completion Status                                                   */
98
/*                                                                        */
99
/*  CALLS                                                                 */
100
/*                                                                        */
101
/*    Media driver                                                        */
102
/*    _fx_utility_16_unsigned_write         Write 16-bit unsigned         */
103
/*    _fx_utility_32_unsigned_write         Write 32-bit unsigned         */
104
/*                                                                        */
105
/*  CALLED BY                                                             */
106
/*                                                                        */
107
/*    Application Code                                                    */
108
/*                                                                        */
109
/*  RELEASE HISTORY                                                       */
110
/*                                                                        */
111
/*    DATE              NAME                      DESCRIPTION             */
112
/*                                                                        */
113
/*  05-19-2020     William E. Lamie         Initial Version 6.0           */
114
/*  09-30-2020     William E. Lamie         Modified comment(s), and      */
115
/*                                            added conditional to        */
116
/*                                            disable force memset,       */
117
/*                                            resulting in version 6.1    */
118
/*  03-02-2021     William E. Lamie         Modified comment(s),          */
119
/*                                            resulting in version 6.1.5  */
120
/*  08-02-2021     Bhupendra Naphade        Modified comment(s), and      */
121
/*                                            updated boot write logic,   */
122
/*                                            resulting in version 6.1.8  */
123
/*  04-25-2022     Bhupendra Naphade        Modified comment(s), and      */
124
/*                                            updated reserved FAT entry  */
125
/*                                            value,                      */
126
/*                                            resulting in version 6.1.11 */
127
/*                                                                        */
128
/**************************************************************************/
129
6213
UINT  _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size,
130
                       CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors,
131
                       ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster,
132
                       UINT heads, UINT sectors_per_track)
133
{
134
135
UCHAR *byte_ptr;
136
UINT   reserved_sectors, i, j, root_sectors, total_clusters, bytes_needed;
137
UINT   sectors_per_fat, f, s;
138
139
140
    /* Create & write bootrecord from drive geometry information.  */
141
142
    /* If trace is enabled, insert this event into the trace buffer.  */
143
    FX_TRACE_IN_LINE_INSERT(FX_TRACE_MEDIA_FORMAT, media_ptr, directory_entries, total_sectors, sectors_per_cluster, FX_TRACE_MEDIA_EVENTS, 0, 0)
144
145
    /* Validate bytes per sector value: greater than zero and no more than 4096.  */
146

6213
    if((bytes_per_sector == 0) || (bytes_per_sector > 4096))
147
2
        return(FX_SECTOR_INVALID);
148
149
    /* Validate sectors per cluster value: greater than zero and no more than 128.  */
150

6211
    if((sectors_per_cluster == 0) || (sectors_per_cluster > 128))
151
2
        return(FX_SECTOR_INVALID);
152
153
    /* Setup driver pointer and memory information.  */
154
6209
    media_ptr -> fx_media_driver_entry =                driver;
155
6209
    media_ptr -> fx_media_memory_buffer =               (UCHAR *)memory_ptr;
156
6209
    media_ptr -> fx_media_memory_size =                 memory_size;
157
158
    /* Store geometry information in media record - driver needs this.  */
159
6209
    media_ptr -> fx_media_bytes_per_sector =            bytes_per_sector;
160
6209
    media_ptr -> fx_media_sectors_per_track =           sectors_per_track;
161
6209
    media_ptr -> fx_media_heads =                       heads;
162
6209
    media_ptr -> fx_media_hidden_sectors =              hidden_sectors;
163
164
    /* Initialize the supplied media I/O driver.  First, build the
165
       initialize driver request.  */
166
6209
    media_ptr -> fx_media_driver_request =              FX_DRIVER_INIT;
167
6209
    media_ptr -> fx_media_driver_status =               FX_IO_ERROR;
168
6209
    media_ptr -> fx_media_driver_info =                 driver_info_ptr;
169
6209
    media_ptr -> fx_media_driver_write_protect =        FX_FALSE;
170
6209
    media_ptr -> fx_media_driver_free_sector_update =   FX_FALSE;
171
6209
    media_ptr -> fx_media_driver_data_sector_read =     FX_FALSE;
172
173
    /* If trace is enabled, insert this event into the trace buffer.  */
174
    FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_INIT, media_ptr, 0, 0, 0, FX_TRACE_INTERNAL_EVENTS, 0, 0)
175
176
    /* Call the specified I/O driver with the initialize request.  */
177
6209
    (media_ptr -> fx_media_driver_entry) (media_ptr);
178
179
    /* Determine if the I/O driver initialized successfully.  */
180
6209
    if (media_ptr -> fx_media_driver_status != FX_SUCCESS)
181
    {
182
183
        /* Return the driver error status.  */
184
774
        return(FX_IO_ERROR);
185
    }
186
187
    /* Setup driver buffer memory.  */
188
5435
    media_ptr -> fx_media_driver_buffer =  memory_ptr;
189
190
    /* Move the buffer pointer into a local copy.  */
191
5435
    byte_ptr =  media_ptr -> fx_media_driver_buffer;
192
193
#ifndef FX_DISABLE_FORCE_MEMORY_OPERATION
194
    /* Clear the buffer record out, assuming it is large enough for one sector.   */
195
1949947
    for (i = 0; i < bytes_per_sector; i++)
196
    {
197
198
        /* Clear each byte of the boot record.  */
199
1944512
        byte_ptr[i] =  (UCHAR)0;
200
    }
201
#else
202
    _fx_utility_memory_set(byte_ptr, 0, bytes_per_sector);
203
#endif /* FX_DISABLE_FORCE_MEMORY_OPERATION */
204
205
    /* Set jump instruction at the beginning of the sector.  */
206
5435
    byte_ptr[0] =  (UCHAR)0xEB;
207
5435
    byte_ptr[1] =  (UCHAR)0x34;
208
5435
    byte_ptr[2] =  (UCHAR)0x90;
209
210
    /* Set the OEM name in the boot record.  */
211
48915
    for (i = 0; i < 8; i++)
212
    {
213
214
        /* Copy a character from the OEM name.  */
215
43480
        byte_ptr[i + 3] =  _fx_media_format_oem_name[i];
216
    }
217
218
    /* Set the media type in the boot record.  */
219
5435
    byte_ptr[FX_MEDIA_TYPE] =  _fx_media_format_media_type;
220
221
    /* Set the number of bytes per sector.  */
222
5435
    _fx_utility_16_unsigned_write(&byte_ptr[FX_BYTES_SECTOR], bytes_per_sector);
223
224
    /* Set the number of sectors per track.  */
225
5435
    _fx_utility_16_unsigned_write(&byte_ptr[FX_SECTORS_PER_TRK], sectors_per_track);
226
227
    /* Set the number of heads.  */
228
5435
    _fx_utility_16_unsigned_write(&byte_ptr[FX_HEADS], heads);
229
230
#ifdef FX_FORCE_512_BYTE_BOOT_SECTOR
231
232
    /* Calculate the number of reserved sectors. If sector size is smaller than 512 bytes, there will be
233
       reserved sectors, otherwise assumed that only the sector containing bootrecord is reserved.  */
234
    if (bytes_per_sector < 512)
235
    {
236
        reserved_sectors =  512 / bytes_per_sector;
237
    }
238
    else
239
    {
240
        reserved_sectors =  1;
241
    }
242
#else
243
244
    /* The boot sector is the only reserved sector.  */
245
5435
    reserved_sectors =  1;
246
#endif
247
248
249
    /* Calculate the maximum clusters.... This is actually greater than the actual since the FAT
250
       sectors have yet to be accounted for.  */
251
5435
    total_clusters =  (total_sectors - reserved_sectors - ((directory_entries * FX_DIR_ENTRY_SIZE) + (bytes_per_sector - 1)) / bytes_per_sector) / sectors_per_cluster;
252
253
    /* Calculate the maximum number of FAT sectors necessary for FAT12.  */
254
5435
    if (total_clusters % 2)
255
    {
256
5417
        bytes_needed = (total_clusters + total_clusters / 2) + 1;
257
    }
258
    else
259
    {
260
18
        bytes_needed = (total_clusters + total_clusters / 2);
261
    }
262
5435
    sectors_per_fat =  bytes_needed / bytes_per_sector;
263
5435
    if (bytes_needed % bytes_per_sector)
264
    {
265
5426
        sectors_per_fat++;
266
    }
267
268
    /* Now adjust the total clusters by the number of sectors per FAT.  */
269
5435
    total_clusters =  total_clusters - ((sectors_per_fat * number_of_fats) + (sectors_per_cluster - 1)) / sectors_per_cluster;
270
271
    /* Is the total cluster count greater than the FAT12 maximum?  */
272
5435
    if (total_clusters >= FX_12_BIT_FAT_SIZE)
273
    {
274
275
        /* Yes, too big for FAT12, we need to evaluate for FAT16.  */
276
277
        /* Reset the maximum clusters.... This is actually greater than the actual since the FAT
278
           sectors have yet to be accounted for.  */
279
5343
        total_clusters =  (total_sectors - reserved_sectors -  ((directory_entries * FX_DIR_ENTRY_SIZE) + (bytes_per_sector - 1)) / bytes_per_sector) / sectors_per_cluster;
280
281
        /* Calculate 16-bit FAT is present. Each cluster requires a 2 byte entry in the FAT table.  */
282
5343
        sectors_per_fat =  (total_clusters * 2) / bytes_per_sector;
283
5343
        if ((total_clusters * 2) % bytes_per_sector)
284
        {
285
5338
            sectors_per_fat++;
286
        }
287
288
        /* Now adjust the total clusters by the number of sectors per FAT.  */
289
5343
        total_clusters =  total_clusters - ((sectors_per_fat * number_of_fats) + (sectors_per_cluster - 1)) / sectors_per_cluster;
290
291
        /* Is the total cluster count greater than the FAT16 maximum?  */
292
5343
        if (total_clusters >= FX_16_BIT_FAT_SIZE)
293
        {
294
295
            /* Yes, FAT32 is present.  */
296
297
            /* Allocate room for the FAT32 additional information sector. This contains useful information
298
               such as the number of available clusters between successive mounting of the media.  */
299
4279
            if (bytes_per_sector == 512)
300
            {
301
302
                /* Write sector number 1 to the additional information sector.  */
303
3237
                _fx_utility_16_unsigned_write(&byte_ptr[48], 1);
304
305
                /* Increment the reserved sectors count, since this will count as a reserved sector.  */
306
3237
                reserved_sectors++;
307
            }
308
            else
309
            {
310
311
                /* Write value to indicate there is no additional information sector.  */
312
1042
                _fx_utility_16_unsigned_write(&byte_ptr[48], 0xFFFF);
313
            }
314
315
            /* Allocate the first cluster to the root directory.  */
316
4279
            _fx_utility_32_unsigned_write(&byte_ptr[FX_ROOT_CLUSTER_32], FX_FAT_ENTRY_START);
317
318
            /* Determine if the number of root directory entries should be modified.  */
319
4279
            directory_entries =  (sectors_per_cluster * bytes_per_sector) / FX_DIR_ENTRY_SIZE;
320
321
            /* Reset the total_clusters for the FAT32 calculation.  */
322
4279
            total_clusters =  (total_sectors - reserved_sectors) / sectors_per_cluster;
323
324
            /* 32-bit FAT is present. Each cluster requires a 4 byte entry in the FAT table.  */
325
4279
            sectors_per_fat =  (total_clusters * 4) / bytes_per_sector;
326
4279
            if ((total_clusters * 4) % bytes_per_sector)
327
            {
328
4278
                sectors_per_fat++;
329
            }
330
331
            /* Now adjust the total clusters by the number of sectors per FAT.  */
332
4279
            total_clusters =  total_clusters - ((sectors_per_fat * number_of_fats) + (sectors_per_cluster - 1)) / sectors_per_cluster;
333
        }
334
    }
335
336
    /* Set sectors per FAT type.  */
337
5435
    if (total_clusters < FX_16_BIT_FAT_SIZE)
338
    {
339
340
        /* Set the number of sectors per FAT12/16.  */
341
1156
        _fx_utility_16_unsigned_write(&byte_ptr[FX_SECTORS_PER_FAT], sectors_per_fat);
342
343
        /* Set the signature.  */
344
1156
        byte_ptr[FX_BOOT_SIG] =  0x29;
345
346
        /* Setup the volume ID.  */
347
1156
        _fx_utility_32_unsigned_write(&byte_ptr[FX_VOLUME_ID], _fx_media_format_volume_id);
348
    }
349
    else
350
    {
351
352
        /* Set the number of sectors per FAT32.  */
353
4279
        _fx_utility_32_unsigned_write(&byte_ptr[FX_SECTORS_PER_FAT_32], sectors_per_fat);
354
355
        /* Set the signature.  */
356
4279
        byte_ptr[FX_BOOT_SIG_32] =  0x29;
357
358
        /* Setup the volume ID.  */
359
4279
        _fx_utility_32_unsigned_write(&byte_ptr[FX_VOLUME_ID_32], _fx_media_format_volume_id);
360
    }
361
362
    /* Set the total number of sectors.  */
363
5435
    if (total_sectors < (ULONG)0xFFFF)
364
    {
365
366
        /* Write the 16-bit total sector field.  */
367
1155
        _fx_utility_16_unsigned_write(&byte_ptr[FX_SECTORS], (UINT)(total_sectors));
368
369
        /* Set the number of huge sectors.  */
370
1155
        _fx_utility_32_unsigned_write(&byte_ptr[FX_HUGE_SECTORS], 0);
371
    }
372
    else
373
    {
374
375
        /* Write the 16-bit total sector field as 0.  */
376
4280
        _fx_utility_16_unsigned_write(&byte_ptr[FX_SECTORS], (UINT)0);
377
378
        /* Set the number of huge sectors.  */
379
4280
        _fx_utility_32_unsigned_write(&byte_ptr[FX_HUGE_SECTORS], total_sectors);
380
    }
381
382
    /* Set the number of reserved sectors.  */
383
5435
    _fx_utility_16_unsigned_write(&byte_ptr[FX_RESERVED_SECTORS], reserved_sectors);
384
385
    /* Set the number of sectors per cluster */
386
5435
    byte_ptr[FX_SECTORS_CLUSTER] =  (UCHAR)sectors_per_cluster;
387
388
    /* Set the number of FATs.  */
389
5435
    byte_ptr[FX_NUMBER_OF_FATS] =  (UCHAR)number_of_fats;
390
391
    /* Set the number of hidden sectors.  */
392
5435
    _fx_utility_32_unsigned_write(&byte_ptr[FX_HIDDEN_SECTORS], hidden_sectors);
393
394
    /* Determine if a FAT12 or FAT16 is present.  If FAT32 is present, these fields are left alone!   */
395
5435
    if (total_clusters < FX_16_BIT_FAT_SIZE)
396
    {
397
398
        /* Yes, set the number of root directory entries.  */
399
1156
        _fx_utility_16_unsigned_write(&byte_ptr[FX_ROOT_DIR_ENTRIES], directory_entries);
400
    }
401
402
    /* Now setup the volume label. */
403
5435
    if (total_clusters < FX_16_BIT_FAT_SIZE)
404
    {
405
406
        /* FAT12/16 volume label offset.  */
407
1156
        j =  FX_VOLUME_LABEL;
408
    }
409
    else
410
    {
411
412
        /* FAT32 volume label offset.  */
413
4279
        j =  FX_VOLUME_LABEL_32;
414
    }
415
416
5435
    i = 0;
417
49082
    while (i < 11)
418
    {
419
420
        /* Determine if it is NULL.  */
421
46875
        if (volume_name[i] == 0)
422
        {
423
424
            /* Yes, the copying is finished.  */
425
3228
            break;
426
        }
427
428
        /* Otherwise, copy byte of volume name into boot record.  */
429
43647
        byte_ptr[j + i] =  (UCHAR)volume_name[i];
430
431
        /* Increment byte position.  */
432
43647
        i++;
433
    }
434
435
    /* Now blank-pad the remainder of the volume name.  */
436
#ifndef FX_DISABLE_FORCE_MEMORY_OPERATION
437
21573
    while (i < 11)
438
    {
439
440
16138
        byte_ptr[j + i] =  (UCHAR)' ';
441
16138
        i++;
442
    }
443
#else
444
    _fx_utility_memory_set(&byte_ptr[j + i], ' ', (11 - i));
445
#endif /* FX_DISABLE_FORCE_MEMORY_OPERATION */
446
447
448
#ifdef FX_FORCE_512_BYTE_BOOT_SECTOR
449
450
    /* Set bootrecord signature.  */
451
    byte_ptr[510] = 0x55;
452
    byte_ptr[511] = 0xAA;
453
#else
454
455
    /* Set bootrecord signature.  */
456
5435
    byte_ptr[bytes_per_sector - 2] = 0x55;
457
5435
    byte_ptr[bytes_per_sector - 1] = 0xAA;
458
#endif
459
460
    /* Select the boot record write command.  */
461
5435
    media_ptr -> fx_media_driver_request =       FX_DRIVER_BOOT_WRITE;
462
5435
    media_ptr -> fx_media_driver_system_write =  FX_TRUE;
463
5435
    media_ptr -> fx_media_driver_sectors =       1;
464
5435
    media_ptr -> fx_media_driver_sector_type =   FX_BOOT_SECTOR;
465
466
    /* If trace is enabled, insert this event into the trace buffer.  */
467
    FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_BOOT_WRITE, media_ptr, memory_ptr, 0, 0, FX_TRACE_INTERNAL_EVENTS, 0, 0)
468
469
    /* Write out the bootrecord */
470
5435
    (driver)(media_ptr);
471
472
    /* Clear the write flag.  */
473
5435
    media_ptr -> fx_media_driver_system_write =  FX_FALSE;
474
475
    /* Determine if it was successful.  */
476
5435
    if (media_ptr -> fx_media_driver_status != FX_SUCCESS)
477
    {
478
403
        return(FX_IO_ERROR);
479
    }
480
481
    /* Calculate the number of root sectors.  */
482
5032
    root_sectors =    ((directory_entries * FX_DIR_ENTRY_SIZE) + bytes_per_sector - 1) / bytes_per_sector;
483
484
    /* Determine if FAT32 is present AND if the bytes per sector is large enough to have
485
       a FSINFO sector.  */
486

5032
    if ((total_clusters >= FX_16_BIT_FAT_SIZE) && (bytes_per_sector == 512))
487
    {
488
489
#ifndef FX_DISABLE_FORCE_MEMORY_OPERATION
490
        /* Clear sector buffer.  */
491
1453842
        for (i = 0; i < bytes_per_sector; i++)
492
        {
493
1451008
            byte_ptr[i] =  (CHAR)0;
494
        }
495
#else
496
        _fx_utility_memory_set(byte_ptr, 0, bytes_per_sector);
497
#endif /* FX_DISABLE_FORCE_MEMORY_OPERATION */
498
499
        /* Build the FSINFO fields.  */
500
501
        /* Build first signature word, used to help verify this is a FSINFO sector.  */
502
2834
        byte_ptr[0] =  0x52;
503
2834
        byte_ptr[1] =  0x52;
504
2834
        byte_ptr[2] =  0x61;
505
2834
        byte_ptr[3] =  0x41;
506
507
        /* Build the next signature word, this too is used to help verify that this is a FSINFO sector.  */
508
2834
        byte_ptr[484] =  0x72;
509
2834
        byte_ptr[485] =  0x72;
510
2834
        byte_ptr[486] =  0x41;
511
2834
        byte_ptr[487] =  0x61;
512
513
        /* Build the final signature word, this too is used to help verify that this is a FSINFO sector.  */
514
2834
        byte_ptr[508] =  0x55;
515
2834
        byte_ptr[509] =  0xAA;
516
517
        /* Setup the total available clusters on the media. We need to subtract 1 for the FAT32 root directory.  */
518
2834
        _fx_utility_32_unsigned_write(&byte_ptr[488], (total_clusters - 1));
519
520
        /* Setup the starting free cluster to 3, since cluster 2 is reserved for the FAT32 root directory.  */
521
2834
        _fx_utility_32_unsigned_write(&byte_ptr[492], 3);
522
523
        /* Now write the FSINFO sector to the media.  */
524
2834
        media_ptr -> fx_media_driver_logical_sector =  1;
525
2834
        media_ptr -> fx_media_driver_request =         FX_DRIVER_WRITE;
526
2834
        media_ptr -> fx_media_driver_sectors =         1;
527
2834
        media_ptr -> fx_media_driver_system_write =    FX_TRUE;
528
2834
        media_ptr -> fx_media_driver_sector_type =     FX_BOOT_SECTOR;
529
530
        /* If trace is enabled, insert this event into the trace buffer.  */
531
        FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_WRITE, media_ptr, 1, 1, memory_ptr, FX_TRACE_INTERNAL_EVENTS, 0, 0)
532
533
        /* Write out the sector.  */
534
2834
        (driver)(media_ptr);
535
536
        /* Clear the system write flag.  */
537
2834
        media_ptr -> fx_media_driver_system_write =  FX_FALSE;
538
539
        /* Determine if it was successful.  */
540
2834
        if (media_ptr -> fx_media_driver_status != FX_SUCCESS)
541
        {
542
346
            return(FX_IO_ERROR);
543
        }
544
    }
545
546
    /* At this point we need set up first to FAT entries and clear the remaining FAT sectors area.  */
547
548
    /* Loop through number of FATs. The first is the only one used.  */
549
6901
    for (f = 0; f < number_of_fats; f++)
550
    {
551
552
        /* Loop through all the sectors in this FAT.  */
553
2406476
        for (s = 0; s < sectors_per_fat; s++)
554
        {
555
556
2404261
            if (s == 0)
557
            {
558
559
                /* Reserve the first two FAT table entries.  */
560
4692
                if (total_clusters < FX_12_BIT_FAT_SIZE)
561
                {
562
563
                    /* Reserve the first two FAT-12 entries.  */
564
94
                    byte_ptr[0] =  _fx_media_format_media_type;
565
94
                    byte_ptr[1] =  (UCHAR)0xFF;
566
94
                    byte_ptr[2] =  (UCHAR)0xFF;
567
568
                    /* Start clearing at FAT entry 3.  */
569
94
                    i =  3;
570
                }
571
4598
                else if (total_clusters < FX_16_BIT_FAT_SIZE)
572
                {
573
574
                    /* Reserve the first two FAT-16 entries.  */
575
1067
                    byte_ptr[0] =  _fx_media_format_media_type;
576
1067
                    byte_ptr[1] =  (UCHAR)0xFF;
577
1067
                    byte_ptr[2] =  (UCHAR)0xFF;
578
1067
                    byte_ptr[3] =  (UCHAR)0xFF;
579
580
                    /* Start clearing at FAT entry 3.  */
581
1067
                    i =  4;
582
                }
583
                else
584
                {
585
586
                    /* Reserve the first two FAT-32 entries.   */
587
3531
                    byte_ptr[0] =  _fx_media_format_media_type;
588
3531
                    byte_ptr[1] =  (UCHAR)0xFF;
589
3531
                    byte_ptr[2] =  (UCHAR)0xFF;
590
3531
                    byte_ptr[3] =  (UCHAR)0x0F;
591
3531
                    byte_ptr[4] =  (UCHAR)0xFF;
592
3531
                    byte_ptr[5] =  (UCHAR)0xFF;
593
3531
                    byte_ptr[6] =  (UCHAR)0xFF;
594
3531
                    byte_ptr[7] =  (UCHAR)0x0F;
595
596
                    /* Preallocate the first cluster for the root directory.  */
597
3531
                    byte_ptr[8] =   (UCHAR)0xFF;
598
3531
                    byte_ptr[9] =   (UCHAR)0xFF;
599
3531
                    byte_ptr[10] =  (UCHAR)0xFF;
600
3531
                    byte_ptr[11] =  (UCHAR)0x0F;
601
602
                    /* Start clearing at FAT entry 3.  */
603
3531
                    i =  12;
604
                }
605
            }
606
            else
607
            {
608
2399569
                i = 0;
609
            }
610
611
#ifndef FX_DISABLE_FORCE_MEMORY_OPERATION
612
            /* Clear remainder of sector buffer.  */
613
318601499
            for (; i < bytes_per_sector; i++)
614
            {
615
316197238
                byte_ptr[i] =  (CHAR)0;
616
            }
617
#else
618
            _fx_utility_memory_set(&byte_ptr[i], 0, (bytes_per_sector - i));
619
#endif  /* FX_DISABLE_FORCE_MEMORY_OPERATION */
620
621
            /* Build sector write command.  */
622
2404261
            media_ptr -> fx_media_driver_logical_sector =  reserved_sectors + (f * sectors_per_fat) + s;
623
2404261
            media_ptr -> fx_media_driver_request =         FX_DRIVER_WRITE;
624
2404261
            media_ptr -> fx_media_driver_sectors =         1;
625
2404261
            media_ptr -> fx_media_driver_system_write =    FX_TRUE;
626
2404261
            media_ptr -> fx_media_driver_sector_type =     FX_FAT_SECTOR;
627
628
            /* If trace is enabled, insert this event into the trace buffer.  */
629
            FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_WRITE, media_ptr, media_ptr -> fx_media_driver_logical_sector, 1, memory_ptr, FX_TRACE_INTERNAL_EVENTS, 0, 0)
630
631
            /* Write out the sector.  */
632
2404261
            (driver)(media_ptr);
633
634
            /* Clear the system write flag.  */
635
2404261
            media_ptr -> fx_media_driver_system_write =  FX_FALSE;
636
637
            /* Determine if it was successful.  */
638
2404261
            if (media_ptr -> fx_media_driver_status != FX_SUCCESS)
639
            {
640
2477
                return(FX_IO_ERROR);
641
            }
642
        }
643
    }
644
645
#ifndef FX_DISABLE_FORCE_MEMORY_OPERATION
646
    /* Clear sector buffer.  */
647
295009
    for (i = 0; i < bytes_per_sector; i++)
648
    {
649
292800
        byte_ptr[i] =  (CHAR)0;
650
    }
651
#else
652
    _fx_utility_memory_set(byte_ptr, 0, bytes_per_sector);
653
#endif /* FX_DISABLE_FORCE_MEMORY_OPERATION */
654
655
    /* Now clear the root directory sectors.  */
656
15980
    for (s = 0; s < root_sectors; s++)
657
    {
658
659
        /* Build sector write command.  */
660
13772
        media_ptr -> fx_media_driver_logical_sector =  reserved_sectors + (number_of_fats * sectors_per_fat) + s;
661
13772
        media_ptr -> fx_media_driver_request =         FX_DRIVER_WRITE;
662
13772
        media_ptr -> fx_media_driver_sectors =         1;
663
13772
        media_ptr -> fx_media_driver_system_write =    FX_TRUE;
664
13772
        media_ptr -> fx_media_driver_sector_type =     FX_DIRECTORY_SECTOR;
665
666
        /* If trace is enabled, insert this event into the trace buffer.  */
667
        FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_WRITE, media_ptr, media_ptr -> fx_media_driver_logical_sector, 1, memory_ptr, FX_TRACE_INTERNAL_EVENTS, 0, 0)
668
669
        /* Write out the sector.  */
670
13772
        (driver)(media_ptr);
671
672
        /* Clear the write flag.  */
673
13772
        media_ptr -> fx_media_driver_system_write =  FX_FALSE;
674
675
        /* Determine if it was successful.  */
676
13772
        if (media_ptr -> fx_media_driver_status != FX_SUCCESS)
677
        {
678
1
            return(FX_IO_ERROR);
679
        }
680
    }
681
682
    /* Build the "uninitialize" I/O driver request.  */
683
2208
    media_ptr -> fx_media_driver_request =      FX_DRIVER_UNINIT;
684
2208
    media_ptr -> fx_media_driver_status =       FX_IO_ERROR;
685
686
    /* If trace is enabled, insert this event into the trace buffer.  */
687
    FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_UNINIT, media_ptr, 0, 0, 0, FX_TRACE_INTERNAL_EVENTS, 0, 0)
688
689
    /* Call the specified I/O driver with the uninitialize request.  */
690
2208
    (media_ptr -> fx_media_driver_entry) (media_ptr);
691
692
    /* Return success!  */
693
2208
    return(media_ptr -> fx_media_driver_status);
694
}
695