GCC Code Coverage Report


Directory: common/src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 188 / 0 / 188
Functions: 100.0% 1 / 0 / 1
Branches: 100.0% 74 / 0 / 74

fx_media_format.c
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 57291 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
4/4
✓ Branch 2 → 3 taken 57282 times.
✓ Branch 2 → 4 taken 9 times.
✓ Branch 3 → 4 taken 9 times.
✓ Branch 3 → 5 taken 57273 times.
57291 if((bytes_per_sector == 0) || (bytes_per_sector > 4096))
128 18 return(FX_SECTOR_INVALID);
129
130 /* Validate sectors per cluster value: greater than zero and no more than 128. */
131
4/4
✓ Branch 5 → 6 taken 57264 times.
✓ Branch 5 → 7 taken 9 times.
✓ Branch 6 → 7 taken 9 times.
✓ Branch 6 → 8 taken 57255 times.
57273 if((sectors_per_cluster == 0) || (sectors_per_cluster > 128))
132 18 return(FX_SECTOR_INVALID);
133
134 /* Setup driver pointer and memory information. */
135 57255 media_ptr -> fx_media_driver_entry = driver;
136 57255 media_ptr -> fx_media_memory_buffer = (UCHAR *)memory_ptr;
137 57255 media_ptr -> fx_media_memory_size = memory_size;
138
139 /* Store geometry information in media record - driver needs this. */
140 57255 media_ptr -> fx_media_bytes_per_sector = bytes_per_sector;
141 57255 media_ptr -> fx_media_sectors_per_track = sectors_per_track;
142 57255 media_ptr -> fx_media_heads = heads;
143 57255 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 57255 media_ptr -> fx_media_driver_request = FX_DRIVER_INIT;
150 57255 media_ptr -> fx_media_driver_status = FX_MEDIA_INVALID;
151 57255 media_ptr -> fx_media_driver_info = driver_info_ptr;
152 57255 media_ptr -> fx_media_driver_write_protect = FX_FALSE;
153 57255 media_ptr -> fx_media_driver_free_sector_update = FX_FALSE;
154 57255 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 57255 (media_ptr -> fx_media_driver_entry) (media_ptr);
161
162 /* Determine if the I/O driver initialized successfully. */
163
2/2
✓ Branch 9 → 10 taken 6966 times.
✓ Branch 9 → 11 taken 50289 times.
57255 if (media_ptr -> fx_media_driver_status != FX_SUCCESS)
164 {
165
166 /* Return the driver error status. */
167 6966 return(FX_IO_ERROR);
168 }
169
170 /* Setup driver buffer memory. */
171 50289 media_ptr -> fx_media_driver_buffer = memory_ptr;
172
173 /* Move the buffer pointer into a local copy. */
174 50289 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
2/2
✓ Branch 13 → 12 taken 17914304 times.
✓ Branch 13 → 14 taken 50289 times.
17964593 for (i = 0; i < bytes_per_sector; i++)
179 {
180
181 /* Clear each byte of the boot record. */
182 17914304 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 50289 byte_ptr[0] = (UCHAR)0xEB;
190 50289 byte_ptr[1] = (UCHAR)0x34;
191 50289 byte_ptr[2] = (UCHAR)0x90;
192
193 /* Set the OEM name in the boot record. */
194
2/2
✓ Branch 16 → 15 taken 402312 times.
✓ Branch 16 → 17 taken 50289 times.
452601 for (i = 0; i < 8; i++)
195 {
196
197 /* Copy a character from the OEM name. */
198 402312 byte_ptr[i + 3] = _fx_media_format_oem_name[i];
199 }
200
201 /* Set the media type in the boot record. */
202 50289 byte_ptr[FX_MEDIA_TYPE] = _fx_media_format_media_type;
203
204 /* Set the number of bytes per sector. */
205 50289 _fx_utility_16_unsigned_write(&byte_ptr[FX_BYTES_SECTOR], bytes_per_sector);
206
207 /* Set the number of sectors per track. */
208 50289 _fx_utility_16_unsigned_write(&byte_ptr[FX_SECTORS_PER_TRK], sectors_per_track);
209
210 /* Set the number of heads. */
211 50289 _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 50289 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 50289 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
2/2
✓ Branch 20 → 21 taken 50115 times.
✓ Branch 20 → 22 taken 174 times.
50289 if (total_clusters % 2)
238 {
239 50115 bytes_needed = (total_clusters + total_clusters / 2) + 1;
240 }
241 else
242 {
243 174 bytes_needed = (total_clusters + total_clusters / 2);
244 }
245 50289 sectors_per_fat = bytes_needed / bytes_per_sector;
246
2/2
✓ Branch 23 → 24 taken 50208 times.
✓ Branch 23 → 25 taken 81 times.
50289 if (bytes_needed % bytes_per_sector)
247 {
248 50208 sectors_per_fat++;
249 }
250
251 /* Now adjust the total clusters by the number of sectors per FAT. */
252 50289 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
2/2
✓ Branch 25 → 26 taken 49045 times.
✓ Branch 25 → 37 taken 1244 times.
50289 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 49045 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 49045 sectors_per_fat = (total_clusters * 2) / bytes_per_sector;
266
2/2
✓ Branch 26 → 27 taken 49000 times.
✓ Branch 26 → 28 taken 45 times.
49045 if ((total_clusters * 2) % bytes_per_sector)
267 {
268 49000 sectors_per_fat++;
269 }
270
271 /* Now adjust the total clusters by the number of sectors per FAT. */
272 49045 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
2/2
✓ Branch 28 → 29 taken 38967 times.
✓ Branch 28 → 37 taken 10078 times.
49045 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
2/2
✓ Branch 29 → 30 taken 29209 times.
✓ Branch 29 → 32 taken 9758 times.
38967 if (bytes_per_sector == 512)
283 {
284
285 /* Write sector number 1 to the additional information sector. */
286 29209 _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 29209 reserved_sectors++;
290 }
291 else
292 {
293
294 /* Write value to indicate there is no additional information sector. */
295 9758 _fx_utility_16_unsigned_write(&byte_ptr[48], 0xFFFF);
296 }
297
298 /* Allocate the first cluster to the root directory. */
299 38967 _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 38967 directory_entries = (sectors_per_cluster * bytes_per_sector) / FX_DIR_ENTRY_SIZE;
303
304 /* Reset the total_clusters for the FAT32 calculation. */
305 38967 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 38967 sectors_per_fat = (total_clusters * 4) / bytes_per_sector;
309
2/2
✓ Branch 34 → 35 taken 38958 times.
✓ Branch 34 → 36 taken 9 times.
38967 if ((total_clusters * 4) % bytes_per_sector)
310 {
311 38958 sectors_per_fat++;
312 }
313
314 /* Now adjust the total clusters by the number of sectors per FAT. */
315 38967 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
2/2
✓ Branch 37 → 38 taken 11322 times.
✓ Branch 37 → 40 taken 38967 times.
50289 if (total_clusters < FX_16_BIT_FAT_SIZE)
321 {
322
323 /* Set the number of sectors per FAT12/16. */
324 11322 _fx_utility_16_unsigned_write(&byte_ptr[FX_SECTORS_PER_FAT], sectors_per_fat);
325
326 /* Set the signature. */
327 11322 byte_ptr[FX_BOOT_SIG] = 0x29;
328
329 /* Setup the volume ID. */
330 11322 _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 38967 _fx_utility_32_unsigned_write(&byte_ptr[FX_SECTORS_PER_FAT_32], sectors_per_fat);
337
338 /* Set the signature. */
339 38967 byte_ptr[FX_BOOT_SIG_32] = 0x29;
340
341 /* Setup the volume ID. */
342 38967 _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
2/2
✓ Branch 42 → 43 taken 11273 times.
✓ Branch 42 → 45 taken 39016 times.
50289 if (total_sectors < (ULONG)0xFFFF)
347 {
348
349 /* Write the 16-bit total sector field. */
350 11273 _fx_utility_16_unsigned_write(&byte_ptr[FX_SECTORS], (UINT)(total_sectors));
351
352 /* Set the number of huge sectors. */
353 11273 _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 39016 _fx_utility_16_unsigned_write(&byte_ptr[FX_SECTORS], (UINT)0);
360
361 /* Set the number of huge sectors. */
362 39016 _fx_utility_32_unsigned_write(&byte_ptr[FX_HUGE_SECTORS], total_sectors);
363 }
364
365 /* Set the number of reserved sectors. */
366 50289 _fx_utility_16_unsigned_write(&byte_ptr[FX_RESERVED_SECTORS], reserved_sectors);
367
368 /* Set the number of sectors per cluster */
369 50289 byte_ptr[FX_SECTORS_CLUSTER] = (UCHAR)sectors_per_cluster;
370
371 /* Set the number of FATs. */
372 50289 byte_ptr[FX_NUMBER_OF_FATS] = (UCHAR)number_of_fats;
373
374 /* Set the number of hidden sectors. */
375 50289 _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
2/2
✓ Branch 49 → 50 taken 11322 times.
✓ Branch 49 → 51 taken 38967 times.
50289 if (total_clusters < FX_16_BIT_FAT_SIZE)
379 {
380
381 /* Yes, set the number of root directory entries. */
382 11322 _fx_utility_16_unsigned_write(&byte_ptr[FX_ROOT_DIR_ENTRIES], directory_entries);
383 }
384
385 /* Now setup the volume label. */
386
2/2
✓ Branch 51 → 52 taken 11322 times.
✓ Branch 51 → 53 taken 38967 times.
50289 if (total_clusters < FX_16_BIT_FAT_SIZE)
387 {
388
389 /* FAT12/16 volume label offset. */
390 11322 j = FX_VOLUME_LABEL;
391 }
392 else
393 {
394
395 /* FAT32 volume label offset. */
396 38967 j = FX_VOLUME_LABEL_32;
397 }
398
399 50289 i = 0;
400
2/2
✓ Branch 58 → 55 taken 436989 times.
✓ Branch 58 → 59 taken 21237 times.
458226 while (i < 11)
401 {
402
403 /* Determine if it is NULL. */
404
2/2
✓ Branch 55 → 56 taken 29052 times.
✓ Branch 55 → 57 taken 407937 times.
436989 if (volume_name[i] == 0)
405 {
406
407 /* Yes, the copying is finished. */
408 29052 break;
409 }
410
411 /* Otherwise, copy byte of volume name into boot record. */
412 407937 byte_ptr[j + i] = (UCHAR)volume_name[i];
413
414 /* Increment byte position. */
415 407937 i++;
416 }
417
418 /* Now blank-pad the remainder of the volume name. */
419 #ifndef FX_DISABLE_FORCE_MEMORY_OPERATION
420
2/2
✓ Branch 61 → 60 taken 145242 times.
✓ Branch 61 → 62 taken 50289 times.
195531 while (i < 11)
421 {
422
423 145242 byte_ptr[j + i] = (UCHAR)' ';
424 145242 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
2/2
✓ Branch 62 → 63 taken 20944 times.
✓ Branch 62 → 64 taken 29345 times.
50289 if (bytes_per_sector < 512)
437 {
438 /* Put the boot signature at the end of the sector. */
439 20944 byte_ptr[bytes_per_sector - 2] = FX_SIG_BYTE_1;
440 20944 byte_ptr[bytes_per_sector - 1] = FX_SIG_BYTE_2;
441 }
442 else
443 {
444 /* Put the boot signature in the standard position. */
445 29345 byte_ptr[FX_SIG_OFFSET] = FX_SIG_BYTE_1;
446 29345 byte_ptr[FX_SIG_OFFSET + 1] = FX_SIG_BYTE_2;
447 }
448 #endif
449
450 /* Select the boot record write command. */
451 50289 media_ptr -> fx_media_driver_request = FX_DRIVER_BOOT_WRITE;
452 50289 media_ptr -> fx_media_driver_system_write = FX_TRUE;
453 50289 media_ptr -> fx_media_driver_sectors = 1;
454 50289 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 50289 (driver)(media_ptr);
461
462 /* Clear the write flag. */
463 50289 media_ptr -> fx_media_driver_system_write = FX_FALSE;
464
465 /* Determine if it was successful. */
466
2/2
✓ Branch 66 → 67 taken 3627 times.
✓ Branch 66 → 68 taken 46662 times.
50289 if (media_ptr -> fx_media_driver_status != FX_SUCCESS)
467 {
468 3627 return(FX_IO_ERROR);
469 }
470
471 /* Calculate the number of root sectors. */
472 46662 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
4/4
✓ Branch 68 → 69 taken 35340 times.
✓ Branch 68 → 78 taken 11322 times.
✓ Branch 69 → 70 taken 25582 times.
✓ Branch 69 → 78 taken 9758 times.
46662 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
2/2
✓ Branch 72 → 71 taken 13097984 times.
✓ Branch 72 → 73 taken 25582 times.
13123566 for (i = 0; i < bytes_per_sector; i++)
482 {
483 13097984 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 25582 byte_ptr[0] = 0x52;
493 25582 byte_ptr[1] = 0x52;
494 25582 byte_ptr[2] = 0x61;
495 25582 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 25582 byte_ptr[484] = 0x72;
499 25582 byte_ptr[485] = 0x72;
500 25582 byte_ptr[486] = 0x41;
501 25582 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 25582 byte_ptr[FX_SIG_OFFSET] = FX_SIG_BYTE_1;
505 25582 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 25582 _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 25582 _fx_utility_32_unsigned_write(&byte_ptr[492], 3);
512
513 /* Now write the FSINFO sector to the media. */
514 25582 media_ptr -> fx_media_driver_logical_sector = 1;
515 25582 media_ptr -> fx_media_driver_request = FX_DRIVER_WRITE;
516 25582 media_ptr -> fx_media_driver_sectors = 1;
517 25582 media_ptr -> fx_media_driver_system_write = FX_TRUE;
518 25582 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 25582 (driver)(media_ptr);
525
526 /* Clear the system write flag. */
527 25582 media_ptr -> fx_media_driver_system_write = FX_FALSE;
528
529 /* Determine if it was successful. */
530
2/2
✓ Branch 76 → 77 taken 3114 times.
✓ Branch 76 → 78 taken 22468 times.
25582 if (media_ptr -> fx_media_driver_status != FX_SUCCESS)
531 {
532 3114 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
2/2
✓ Branch 96 → 79 taken 43590 times.
✓ Branch 96 → 97 taken 21255 times.
64845 for (f = 0; f < number_of_fats; f++)
540 {
541
542 /* Loop through all the sectors in this FAT. */
543
2/2
✓ Branch 94 → 80 taken 22291401 times.
✓ Branch 94 → 95 taken 21297 times.
22312698 for (s = 0; s < sectors_per_fat; s++)
544 {
545
546
2/2
✓ Branch 80 → 81 taken 43590 times.
✓ Branch 80 → 86 taken 22247811 times.
22291401 if (s == 0)
547 {
548
549 /* Reserve the first two FAT table entries. */
550
2/2
✓ Branch 81 → 82 taken 1258 times.
✓ Branch 81 → 83 taken 42332 times.
43590 if (total_clusters < FX_12_BIT_FAT_SIZE)
551 {
552
553 /* Reserve the first two FAT-12 entries. */
554 1258 byte_ptr[0] = _fx_media_format_media_type;
555 1258 byte_ptr[1] = (UCHAR)0xFF;
556 1258 byte_ptr[2] = (UCHAR)0xFF;
557
558 /* Start clearing at FAT entry 3. */
559 1258 i = 3;
560 }
561
2/2
✓ Branch 83 → 84 taken 10099 times.
✓ Branch 83 → 85 taken 32233 times.
42332 else if (total_clusters < FX_16_BIT_FAT_SIZE)
562 {
563
564 /* Reserve the first two FAT-16 entries. */
565 10099 byte_ptr[0] = _fx_media_format_media_type;
566 10099 byte_ptr[1] = (UCHAR)0xFF;
567 10099 byte_ptr[2] = (UCHAR)0xFF;
568 10099 byte_ptr[3] = (UCHAR)0xFF;
569
570 /* Start clearing at FAT entry 3. */
571 10099 i = 4;
572 }
573 else
574 {
575
576 /* Reserve the first two FAT-32 entries. */
577 32233 byte_ptr[0] = _fx_media_format_media_type;
578 32233 byte_ptr[1] = (UCHAR)0xFF;
579 32233 byte_ptr[2] = (UCHAR)0xFF;
580 32233 byte_ptr[3] = (UCHAR)0x0F;
581 32233 byte_ptr[4] = (UCHAR)0xFF;
582 32233 byte_ptr[5] = (UCHAR)0xFF;
583 32233 byte_ptr[6] = (UCHAR)0xFF;
584 32233 byte_ptr[7] = (UCHAR)0x0F;
585
586 /* Preallocate the first cluster for the root directory. */
587 32233 byte_ptr[8] = (UCHAR)0xFF;
588 32233 byte_ptr[9] = (UCHAR)0xFF;
589 32233 byte_ptr[10] = (UCHAR)0xFF;
590 32233 byte_ptr[11] = (UCHAR)0x0F;
591
592 /* Start clearing at FAT entry 3. */
593 32233 i = 12;
594 }
595 }
596 else
597 {
598 22247811 i = 0;
599 }
600
601 #ifndef FX_DISABLE_FORCE_MEMORY_OPERATION
602 /* Clear remainder of sector buffer. */
603
2/2
✓ Branch 89 → 88 taken 3024333130 times.
✓ Branch 89 → 90 taken 22291401 times.
3046624531 for (; i < bytes_per_sector; i++)
604 {
605 3024333130 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 22291401 media_ptr -> fx_media_driver_logical_sector = reserved_sectors + (f * sectors_per_fat) + s;
613 22291401 media_ptr -> fx_media_driver_request = FX_DRIVER_WRITE;
614 22291401 media_ptr -> fx_media_driver_sectors = 1;
615 22291401 media_ptr -> fx_media_driver_system_write = FX_TRUE;
616 22291401 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 22291401 (driver)(media_ptr);
623
624 /* Clear the system write flag. */
625 22291401 media_ptr -> fx_media_driver_system_write = FX_FALSE;
626
627 /* Determine if it was successful. */
628
2/2
✓ Branch 91 → 92 taken 22293 times.
✓ Branch 91 → 93 taken 22269108 times.
22291401 if (media_ptr -> fx_media_driver_status != FX_SUCCESS)
629 {
630 22293 return(FX_IO_ERROR);
631 }
632 }
633 }
634
635 #ifndef FX_DISABLE_FORCE_MEMORY_OPERATION
636 /* Clear sector buffer. */
637
2/2
✓ Branch 99 → 98 taken 3048896 times.
✓ Branch 99 → 100 taken 21255 times.
3070151 for (i = 0; i < bytes_per_sector; i++)
638 {
639 3048896 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
2/2
✓ Branch 105 → 101 taken 130468 times.
✓ Branch 105 → 106 taken 21246 times.
151714 for (s = 0; s < root_sectors; s++)
647 {
648
649 /* Build sector write command. */
650 130468 media_ptr -> fx_media_driver_logical_sector = reserved_sectors + (number_of_fats * sectors_per_fat) + s;
651 130468 media_ptr -> fx_media_driver_request = FX_DRIVER_WRITE;
652 130468 media_ptr -> fx_media_driver_sectors = 1;
653 130468 media_ptr -> fx_media_driver_system_write = FX_TRUE;
654 130468 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 130468 (driver)(media_ptr);
661
662 /* Clear the write flag. */
663 130468 media_ptr -> fx_media_driver_system_write = FX_FALSE;
664
665 /* Determine if it was successful. */
666
2/2
✓ Branch 102 → 103 taken 9 times.
✓ Branch 102 → 104 taken 130459 times.
130468 if (media_ptr -> fx_media_driver_status != FX_SUCCESS)
667 {
668 9 return(FX_IO_ERROR);
669 }
670 }
671
672 #ifndef FX_MEDIA_STATISTICS_DISABLE
673
674 /* Increment the number of driver flush requests. */
675 21246 media_ptr -> fx_media_driver_flush_requests++;
676 #endif
677
678 /* Build the "flush" I/O driver request. */
679 21246 media_ptr -> fx_media_driver_request = FX_DRIVER_FLUSH;
680 21246 media_ptr -> fx_media_driver_status = FX_IO_ERROR;
681
682 /* If trace is enabled, insert this event into the trace buffer. */
683 FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_FLUSH, media_ptr, 0, 0, 0, FX_TRACE_INTERNAL_EVENTS, 0, 0)
684
685 /* Call the specified I/O driver with the flush request. */
686 21246 (driver)(media_ptr);
687
688 /* Build the "uninitialize" I/O driver request. */
689 21246 media_ptr -> fx_media_driver_request = FX_DRIVER_UNINIT;
690 21246 media_ptr -> fx_media_driver_status = FX_IO_ERROR;
691
692 /* If trace is enabled, insert this event into the trace buffer. */
693 FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_UNINIT, media_ptr, 0, 0, 0, FX_TRACE_INTERNAL_EVENTS, 0, 0)
694
695 /* Call the specified I/O driver with the uninitialize request. */
696 21246 (media_ptr -> fx_media_driver_entry) (media_ptr);
697
698 /* Return success! */
699 21246 return(media_ptr -> fx_media_driver_status);
700 }
701
702