GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: fx_media_format.c Lines: 184 184 100.0 %
Date: 2026-03-06 18:49:02 Branches: 74 74 100.0 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 * Copyright (c) 2026-present Eclipse ThreadX contributors
4
 *
5
 * This program and the accompanying materials are made available under the
6
 * terms of the MIT License which is available at
7
 * https://opensource.org/licenses/MIT.
8
 *
9
 * SPDX-License-Identifier: MIT
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
/**************************************************************************/
110
6213
UINT  _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size,
111
                       CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors,
112
                       ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster,
113
                       UINT heads, UINT sectors_per_track)
114
{
115
116
UCHAR *byte_ptr;
117
UINT   reserved_sectors, i, j, root_sectors, total_clusters, bytes_needed;
118
UINT   sectors_per_fat, f, s;
119
120
121
    /* Create & write bootrecord from drive geometry information.  */
122
123
    /* If trace is enabled, insert this event into the trace buffer.  */
124
    FX_TRACE_IN_LINE_INSERT(FX_TRACE_MEDIA_FORMAT, media_ptr, directory_entries, total_sectors, sectors_per_cluster, FX_TRACE_MEDIA_EVENTS, 0, 0)
125
126
    /* Validate bytes per sector value: greater than zero and no more than 4096.  */
127

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

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

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