1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** FileX Component */
16 /** */
17 /** Media */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22 #define FX_SOURCE_CODE
23
24
25 /* Include necessary system files. */
26
27 #include "fx_api.h"
28 #include "fx_media.h"
29 #include "fx_utility.h"
30
31
32 /* Define global variables necessary for formatting. */
33
34 /* Define OEM Name. This name must be 8 characters long and be blank padded.
35 The default may be changed by modifying this file or calling the
36 fx_media_format_oem_name_set utility prior to calling fx_media_format. */
37
38 UCHAR _fx_media_format_oem_name[8] = "EL FILEX";
39
40
41 /* Define the default media type. This default may be changed by modifying
42 this file or calling the fx_media_format_type_set utility prior to calling
43 fx_media_format. */
44
45 UCHAR _fx_media_format_media_type = 0xF8;
46
47
48 /* Define the default volume ID. This default may be changed by modifying
49 this file or calling the fx_media_format_volume_id_set utility prior to calling
50 fx_media_format. */
51
52 ULONG _fx_media_format_volume_id = 1;
53
54
55 /**************************************************************************/
56 /* */
57 /* FUNCTION RELEASE */
58 /* */
59 /* _fx_media_format PORTABLE C */
60 /* 6.1.11 */
61 /* AUTHOR */
62 /* */
63 /* William E. Lamie, Microsoft Corporation */
64 /* */
65 /* DESCRIPTION */
66 /* */
67 /* This function creates a FAT12/16/32 format with raw calls to the */
68 /* I/O driver. It can and must be called before the fx_media_open */
69 /* and is designed to utilize the same underlying FileX driver. */
70 /* */
71 /* INPUT */
72 /* */
73 /* media_ptr Pointer to media control block*/
74 /* (does not need to be opened)*/
75 /* driver Pointer to FileX driver (must */
76 /* be able to field requests */
77 /* prior to opening) */
78 /* driver_info_ptr Optional information pointer */
79 /* memory_ptr Pointer to memory used by the */
80 /* FileX for this media. */
81 /* memory_size Size of media memory - must */
82 /* at least 512 bytes and */
83 /* one sector size. */
84 /* volume_name Name of the volume */
85 /* number_of_fats Number of FAT tables */
86 /* directory_entries Number of directory entries */
87 /* hidden_sectors Number of hidden sectors */
88 /* total_sectors Total number of sectors */
89 /* bytes_per_sector Number of bytes per sector */
90 /* sectors_per_cluster Number of sectors per cluster */
91 /* heads Number of heads */
92 /* sectors_per_track Number of sectors per track */
93 /* */
94 /* OUTPUT */
95 /* */
96 /* Completion Status */
97 /* */
98 /* CALLS */
99 /* */
100 /* Media driver */
101 /* _fx_utility_16_unsigned_write Write 16-bit unsigned */
102 /* _fx_utility_32_unsigned_write Write 32-bit unsigned */
103 /* */
104 /* CALLED BY */
105 /* */
106 /* Application Code */
107 /* */
108 /* RELEASE HISTORY */
109 /* */
110 /* DATE NAME DESCRIPTION */
111 /* */
112 /* 05-19-2020 William E. Lamie Initial Version 6.0 */
113 /* 09-30-2020 William E. Lamie Modified comment(s), and */
114 /* added conditional to */
115 /* disable force memset, */
116 /* resulting in version 6.1 */
117 /* 03-02-2021 William E. Lamie Modified comment(s), */
118 /* resulting in version 6.1.5 */
119 /* 08-02-2021 Bhupendra Naphade Modified comment(s), and */
120 /* updated boot write logic, */
121 /* resulting in version 6.1.8 */
122 /* 04-25-2022 Bhupendra Naphade Modified comment(s), and */
123 /* updated reserved FAT entry */
124 /* value, */
125 /* resulting in version 6.1.11 */
126 /* */
127 /**************************************************************************/
_fx_media_format(FX_MEDIA * media_ptr,VOID (* driver)(FX_MEDIA * media),VOID * driver_info_ptr,UCHAR * memory_ptr,UINT memory_size,CHAR * volume_name,UINT number_of_fats,UINT directory_entries,UINT hidden_sectors,ULONG total_sectors,UINT bytes_per_sector,UINT sectors_per_cluster,UINT heads,UINT sectors_per_track)128 UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size,
129 CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors,
130 ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster,
131 UINT heads, UINT sectors_per_track)
132 {
133
134 UCHAR *byte_ptr;
135 UINT reserved_sectors, i, j, root_sectors, total_clusters, bytes_needed;
136 UINT sectors_per_fat, f, s;
137
138
139 /* Create & write bootrecord from drive geometry information. */
140
141 /* If trace is enabled, insert this event into the trace buffer. */
142 FX_TRACE_IN_LINE_INSERT(FX_TRACE_MEDIA_FORMAT, media_ptr, directory_entries, total_sectors, sectors_per_cluster, FX_TRACE_MEDIA_EVENTS, 0, 0)
143
144 /* Validate bytes per sector value: greater than zero and no more than 4096. */
145 if((bytes_per_sector == 0) || (bytes_per_sector > 4096))
146 return(FX_SECTOR_INVALID);
147
148 /* Validate sectors per cluster value: greater than zero and no more than 128. */
149 if((sectors_per_cluster == 0) || (sectors_per_cluster > 128))
150 return(FX_SECTOR_INVALID);
151
152 /* Setup driver pointer and memory information. */
153 media_ptr -> fx_media_driver_entry = driver;
154 media_ptr -> fx_media_memory_buffer = (UCHAR *)memory_ptr;
155 media_ptr -> fx_media_memory_size = memory_size;
156
157 /* Store geometry information in media record - driver needs this. */
158 media_ptr -> fx_media_bytes_per_sector = bytes_per_sector;
159 media_ptr -> fx_media_sectors_per_track = sectors_per_track;
160 media_ptr -> fx_media_heads = heads;
161 media_ptr -> fx_media_hidden_sectors = hidden_sectors;
162
163 /* Initialize the supplied media I/O driver. First, build the
164 initialize driver request. */
165 media_ptr -> fx_media_driver_request = FX_DRIVER_INIT;
166 media_ptr -> fx_media_driver_status = FX_IO_ERROR;
167 media_ptr -> fx_media_driver_info = driver_info_ptr;
168 media_ptr -> fx_media_driver_write_protect = FX_FALSE;
169 media_ptr -> fx_media_driver_free_sector_update = FX_FALSE;
170 media_ptr -> fx_media_driver_data_sector_read = FX_FALSE;
171
172 /* If trace is enabled, insert this event into the trace buffer. */
173 FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_INIT, media_ptr, 0, 0, 0, FX_TRACE_INTERNAL_EVENTS, 0, 0)
174
175 /* Call the specified I/O driver with the initialize request. */
176 (media_ptr -> fx_media_driver_entry) (media_ptr);
177
178 /* Determine if the I/O driver initialized successfully. */
179 if (media_ptr -> fx_media_driver_status != FX_SUCCESS)
180 {
181
182 /* Return the driver error status. */
183 return(FX_IO_ERROR);
184 }
185
186 /* Setup driver buffer memory. */
187 media_ptr -> fx_media_driver_buffer = memory_ptr;
188
189 /* Move the buffer pointer into a local copy. */
190 byte_ptr = media_ptr -> fx_media_driver_buffer;
191
192 #ifndef FX_DISABLE_FORCE_MEMORY_OPERATION
193 /* Clear the buffer record out, assuming it is large enough for one sector. */
194 for (i = 0; i < bytes_per_sector; i++)
195 {
196
197 /* Clear each byte of the boot record. */
198 byte_ptr[i] = (UCHAR)0;
199 }
200 #else
201 _fx_utility_memory_set(byte_ptr, 0, bytes_per_sector);
202 #endif /* FX_DISABLE_FORCE_MEMORY_OPERATION */
203
204 /* Set jump instruction at the beginning of the sector. */
205 byte_ptr[0] = (UCHAR)0xEB;
206 byte_ptr[1] = (UCHAR)0x34;
207 byte_ptr[2] = (UCHAR)0x90;
208
209 /* Set the OEM name in the boot record. */
210 for (i = 0; i < 8; i++)
211 {
212
213 /* Copy a character from the OEM name. */
214 byte_ptr[i + 3] = _fx_media_format_oem_name[i];
215 }
216
217 /* Set the media type in the boot record. */
218 byte_ptr[FX_MEDIA_TYPE] = _fx_media_format_media_type;
219
220 /* Set the number of bytes per sector. */
221 _fx_utility_16_unsigned_write(&byte_ptr[FX_BYTES_SECTOR], bytes_per_sector);
222
223 /* Set the number of sectors per track. */
224 _fx_utility_16_unsigned_write(&byte_ptr[FX_SECTORS_PER_TRK], sectors_per_track);
225
226 /* Set the number of heads. */
227 _fx_utility_16_unsigned_write(&byte_ptr[FX_HEADS], heads);
228
229 #ifdef FX_FORCE_512_BYTE_BOOT_SECTOR
230
231 /* Calculate the number of reserved sectors. If sector size is smaller than 512 bytes, there will be
232 reserved sectors, otherwise assumed that only the sector containing bootrecord is reserved. */
233 if (bytes_per_sector < 512)
234 {
235 reserved_sectors = 512 / bytes_per_sector;
236 }
237 else
238 {
239 reserved_sectors = 1;
240 }
241 #else
242
243 /* The boot sector is the only reserved sector. */
244 reserved_sectors = 1;
245 #endif
246
247
248 /* Calculate the maximum clusters.... This is actually greater than the actual since the FAT
249 sectors have yet to be accounted for. */
250 total_clusters = (total_sectors - reserved_sectors - ((directory_entries * FX_DIR_ENTRY_SIZE) + (bytes_per_sector - 1)) / bytes_per_sector) / sectors_per_cluster;
251
252 /* Calculate the maximum number of FAT sectors necessary for FAT12. */
253 if (total_clusters % 2)
254 {
255 bytes_needed = (total_clusters + total_clusters / 2) + 1;
256 }
257 else
258 {
259 bytes_needed = (total_clusters + total_clusters / 2);
260 }
261 sectors_per_fat = bytes_needed / bytes_per_sector;
262 if (bytes_needed % bytes_per_sector)
263 {
264 sectors_per_fat++;
265 }
266
267 /* Now adjust the total clusters by the number of sectors per FAT. */
268 total_clusters = total_clusters - ((sectors_per_fat * number_of_fats) + (sectors_per_cluster - 1)) / sectors_per_cluster;
269
270 /* Is the total cluster count greater than the FAT12 maximum? */
271 if (total_clusters >= FX_12_BIT_FAT_SIZE)
272 {
273
274 /* Yes, too big for FAT12, we need to evaluate for FAT16. */
275
276 /* Reset the maximum clusters.... This is actually greater than the actual since the FAT
277 sectors have yet to be accounted for. */
278 total_clusters = (total_sectors - reserved_sectors - ((directory_entries * FX_DIR_ENTRY_SIZE) + (bytes_per_sector - 1)) / bytes_per_sector) / sectors_per_cluster;
279
280 /* Calculate 16-bit FAT is present. Each cluster requires a 2 byte entry in the FAT table. */
281 sectors_per_fat = (total_clusters * 2) / bytes_per_sector;
282 if ((total_clusters * 2) % bytes_per_sector)
283 {
284 sectors_per_fat++;
285 }
286
287 /* Now adjust the total clusters by the number of sectors per FAT. */
288 total_clusters = total_clusters - ((sectors_per_fat * number_of_fats) + (sectors_per_cluster - 1)) / sectors_per_cluster;
289
290 /* Is the total cluster count greater than the FAT16 maximum? */
291 if (total_clusters >= FX_16_BIT_FAT_SIZE)
292 {
293
294 /* Yes, FAT32 is present. */
295
296 /* Allocate room for the FAT32 additional information sector. This contains useful information
297 such as the number of available clusters between successive mounting of the media. */
298 if (bytes_per_sector == 512)
299 {
300
301 /* Write sector number 1 to the additional information sector. */
302 _fx_utility_16_unsigned_write(&byte_ptr[48], 1);
303
304 /* Increment the reserved sectors count, since this will count as a reserved sector. */
305 reserved_sectors++;
306 }
307 else
308 {
309
310 /* Write value to indicate there is no additional information sector. */
311 _fx_utility_16_unsigned_write(&byte_ptr[48], 0xFFFF);
312 }
313
314 /* Allocate the first cluster to the root directory. */
315 _fx_utility_32_unsigned_write(&byte_ptr[FX_ROOT_CLUSTER_32], FX_FAT_ENTRY_START);
316
317 /* Determine if the number of root directory entries should be modified. */
318 directory_entries = (sectors_per_cluster * bytes_per_sector) / FX_DIR_ENTRY_SIZE;
319
320 /* Reset the total_clusters for the FAT32 calculation. */
321 total_clusters = (total_sectors - reserved_sectors) / sectors_per_cluster;
322
323 /* 32-bit FAT is present. Each cluster requires a 4 byte entry in the FAT table. */
324 sectors_per_fat = (total_clusters * 4) / bytes_per_sector;
325 if ((total_clusters * 4) % bytes_per_sector)
326 {
327 sectors_per_fat++;
328 }
329
330 /* Now adjust the total clusters by the number of sectors per FAT. */
331 total_clusters = total_clusters - ((sectors_per_fat * number_of_fats) + (sectors_per_cluster - 1)) / sectors_per_cluster;
332 }
333 }
334
335 /* Set sectors per FAT type. */
336 if (total_clusters < FX_16_BIT_FAT_SIZE)
337 {
338
339 /* Set the number of sectors per FAT12/16. */
340 _fx_utility_16_unsigned_write(&byte_ptr[FX_SECTORS_PER_FAT], sectors_per_fat);
341
342 /* Set the signature. */
343 byte_ptr[FX_BOOT_SIG] = 0x29;
344
345 /* Setup the volume ID. */
346 _fx_utility_32_unsigned_write(&byte_ptr[FX_VOLUME_ID], _fx_media_format_volume_id);
347 }
348 else
349 {
350
351 /* Set the number of sectors per FAT32. */
352 _fx_utility_32_unsigned_write(&byte_ptr[FX_SECTORS_PER_FAT_32], sectors_per_fat);
353
354 /* Set the signature. */
355 byte_ptr[FX_BOOT_SIG_32] = 0x29;
356
357 /* Setup the volume ID. */
358 _fx_utility_32_unsigned_write(&byte_ptr[FX_VOLUME_ID_32], _fx_media_format_volume_id);
359 }
360
361 /* Set the total number of sectors. */
362 if (total_sectors < (ULONG)0xFFFF)
363 {
364
365 /* Write the 16-bit total sector field. */
366 _fx_utility_16_unsigned_write(&byte_ptr[FX_SECTORS], (UINT)(total_sectors));
367
368 /* Set the number of huge sectors. */
369 _fx_utility_32_unsigned_write(&byte_ptr[FX_HUGE_SECTORS], 0);
370 }
371 else
372 {
373
374 /* Write the 16-bit total sector field as 0. */
375 _fx_utility_16_unsigned_write(&byte_ptr[FX_SECTORS], (UINT)0);
376
377 /* Set the number of huge sectors. */
378 _fx_utility_32_unsigned_write(&byte_ptr[FX_HUGE_SECTORS], total_sectors);
379 }
380
381 /* Set the number of reserved sectors. */
382 _fx_utility_16_unsigned_write(&byte_ptr[FX_RESERVED_SECTORS], reserved_sectors);
383
384 /* Set the number of sectors per cluster */
385 byte_ptr[FX_SECTORS_CLUSTER] = (UCHAR)sectors_per_cluster;
386
387 /* Set the number of FATs. */
388 byte_ptr[FX_NUMBER_OF_FATS] = (UCHAR)number_of_fats;
389
390 /* Set the number of hidden sectors. */
391 _fx_utility_32_unsigned_write(&byte_ptr[FX_HIDDEN_SECTORS], hidden_sectors);
392
393 /* Determine if a FAT12 or FAT16 is present. If FAT32 is present, these fields are left alone! */
394 if (total_clusters < FX_16_BIT_FAT_SIZE)
395 {
396
397 /* Yes, set the number of root directory entries. */
398 _fx_utility_16_unsigned_write(&byte_ptr[FX_ROOT_DIR_ENTRIES], directory_entries);
399 }
400
401 /* Now setup the volume label. */
402 if (total_clusters < FX_16_BIT_FAT_SIZE)
403 {
404
405 /* FAT12/16 volume label offset. */
406 j = FX_VOLUME_LABEL;
407 }
408 else
409 {
410
411 /* FAT32 volume label offset. */
412 j = FX_VOLUME_LABEL_32;
413 }
414
415 i = 0;
416 while (i < 11)
417 {
418
419 /* Determine if it is NULL. */
420 if (volume_name[i] == 0)
421 {
422
423 /* Yes, the copying is finished. */
424 break;
425 }
426
427 /* Otherwise, copy byte of volume name into boot record. */
428 byte_ptr[j + i] = (UCHAR)volume_name[i];
429
430 /* Increment byte position. */
431 i++;
432 }
433
434 /* Now blank-pad the remainder of the volume name. */
435 #ifndef FX_DISABLE_FORCE_MEMORY_OPERATION
436 while (i < 11)
437 {
438
439 byte_ptr[j + i] = (UCHAR)' ';
440 i++;
441 }
442 #else
443 _fx_utility_memory_set(&byte_ptr[j + i], ' ', (11 - i));
444 #endif /* FX_DISABLE_FORCE_MEMORY_OPERATION */
445
446
447 #ifdef FX_FORCE_512_BYTE_BOOT_SECTOR
448
449 /* Set bootrecord signature. */
450 byte_ptr[510] = 0x55;
451 byte_ptr[511] = 0xAA;
452 #else
453
454 /* Set bootrecord signature. */
455 byte_ptr[bytes_per_sector - 2] = 0x55;
456 byte_ptr[bytes_per_sector - 1] = 0xAA;
457 #endif
458
459 /* Select the boot record write command. */
460 media_ptr -> fx_media_driver_request = FX_DRIVER_BOOT_WRITE;
461 media_ptr -> fx_media_driver_system_write = FX_TRUE;
462 media_ptr -> fx_media_driver_sectors = 1;
463 media_ptr -> fx_media_driver_sector_type = FX_BOOT_SECTOR;
464
465 /* If trace is enabled, insert this event into the trace buffer. */
466 FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_BOOT_WRITE, media_ptr, memory_ptr, 0, 0, FX_TRACE_INTERNAL_EVENTS, 0, 0)
467
468 /* Write out the bootrecord */
469 (driver)(media_ptr);
470
471 /* Clear the write flag. */
472 media_ptr -> fx_media_driver_system_write = FX_FALSE;
473
474 /* Determine if it was successful. */
475 if (media_ptr -> fx_media_driver_status != FX_SUCCESS)
476 {
477 return(FX_IO_ERROR);
478 }
479
480 /* Calculate the number of root sectors. */
481 root_sectors = ((directory_entries * FX_DIR_ENTRY_SIZE) + bytes_per_sector - 1) / bytes_per_sector;
482
483 /* Determine if FAT32 is present AND if the bytes per sector is large enough to have
484 a FSINFO sector. */
485 if ((total_clusters >= FX_16_BIT_FAT_SIZE) && (bytes_per_sector == 512))
486 {
487
488 #ifndef FX_DISABLE_FORCE_MEMORY_OPERATION
489 /* Clear sector buffer. */
490 for (i = 0; i < bytes_per_sector; i++)
491 {
492 byte_ptr[i] = (CHAR)0;
493 }
494 #else
495 _fx_utility_memory_set(byte_ptr, 0, bytes_per_sector);
496 #endif /* FX_DISABLE_FORCE_MEMORY_OPERATION */
497
498 /* Build the FSINFO fields. */
499
500 /* Build first signature word, used to help verify this is a FSINFO sector. */
501 byte_ptr[0] = 0x52;
502 byte_ptr[1] = 0x52;
503 byte_ptr[2] = 0x61;
504 byte_ptr[3] = 0x41;
505
506 /* Build the next signature word, this too is used to help verify that this is a FSINFO sector. */
507 byte_ptr[484] = 0x72;
508 byte_ptr[485] = 0x72;
509 byte_ptr[486] = 0x41;
510 byte_ptr[487] = 0x61;
511
512 /* Build the final signature word, this too is used to help verify that this is a FSINFO sector. */
513 byte_ptr[508] = 0x55;
514 byte_ptr[509] = 0xAA;
515
516 /* Setup the total available clusters on the media. We need to subtract 1 for the FAT32 root directory. */
517 _fx_utility_32_unsigned_write(&byte_ptr[488], (total_clusters - 1));
518
519 /* Setup the starting free cluster to 3, since cluster 2 is reserved for the FAT32 root directory. */
520 _fx_utility_32_unsigned_write(&byte_ptr[492], 3);
521
522 /* Now write the FSINFO sector to the media. */
523 media_ptr -> fx_media_driver_logical_sector = 1;
524 media_ptr -> fx_media_driver_request = FX_DRIVER_WRITE;
525 media_ptr -> fx_media_driver_sectors = 1;
526 media_ptr -> fx_media_driver_system_write = FX_TRUE;
527 media_ptr -> fx_media_driver_sector_type = FX_BOOT_SECTOR;
528
529 /* If trace is enabled, insert this event into the trace buffer. */
530 FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_WRITE, media_ptr, 1, 1, memory_ptr, FX_TRACE_INTERNAL_EVENTS, 0, 0)
531
532 /* Write out the sector. */
533 (driver)(media_ptr);
534
535 /* Clear the system write flag. */
536 media_ptr -> fx_media_driver_system_write = FX_FALSE;
537
538 /* Determine if it was successful. */
539 if (media_ptr -> fx_media_driver_status != FX_SUCCESS)
540 {
541 return(FX_IO_ERROR);
542 }
543 }
544
545 /* At this point we need set up first to FAT entries and clear the remaining FAT sectors area. */
546
547 /* Loop through number of FATs. The first is the only one used. */
548 for (f = 0; f < number_of_fats; f++)
549 {
550
551 /* Loop through all the sectors in this FAT. */
552 for (s = 0; s < sectors_per_fat; s++)
553 {
554
555 if (s == 0)
556 {
557
558 /* Reserve the first two FAT table entries. */
559 if (total_clusters < FX_12_BIT_FAT_SIZE)
560 {
561
562 /* Reserve the first two FAT-12 entries. */
563 byte_ptr[0] = _fx_media_format_media_type;
564 byte_ptr[1] = (UCHAR)0xFF;
565 byte_ptr[2] = (UCHAR)0xFF;
566
567 /* Start clearing at FAT entry 3. */
568 i = 3;
569 }
570 else if (total_clusters < FX_16_BIT_FAT_SIZE)
571 {
572
573 /* Reserve the first two FAT-16 entries. */
574 byte_ptr[0] = _fx_media_format_media_type;
575 byte_ptr[1] = (UCHAR)0xFF;
576 byte_ptr[2] = (UCHAR)0xFF;
577 byte_ptr[3] = (UCHAR)0xFF;
578
579 /* Start clearing at FAT entry 3. */
580 i = 4;
581 }
582 else
583 {
584
585 /* Reserve the first two FAT-32 entries. */
586 byte_ptr[0] = _fx_media_format_media_type;
587 byte_ptr[1] = (UCHAR)0xFF;
588 byte_ptr[2] = (UCHAR)0xFF;
589 byte_ptr[3] = (UCHAR)0x0F;
590 byte_ptr[4] = (UCHAR)0xFF;
591 byte_ptr[5] = (UCHAR)0xFF;
592 byte_ptr[6] = (UCHAR)0xFF;
593 byte_ptr[7] = (UCHAR)0x0F;
594
595 /* Preallocate the first cluster for the root directory. */
596 byte_ptr[8] = (UCHAR)0xFF;
597 byte_ptr[9] = (UCHAR)0xFF;
598 byte_ptr[10] = (UCHAR)0xFF;
599 byte_ptr[11] = (UCHAR)0x0F;
600
601 /* Start clearing at FAT entry 3. */
602 i = 12;
603 }
604 }
605 else
606 {
607 i = 0;
608 }
609
610 #ifndef FX_DISABLE_FORCE_MEMORY_OPERATION
611 /* Clear remainder of sector buffer. */
612 for (; i < bytes_per_sector; i++)
613 {
614 byte_ptr[i] = (CHAR)0;
615 }
616 #else
617 _fx_utility_memory_set(&byte_ptr[i], 0, (bytes_per_sector - i));
618 #endif /* FX_DISABLE_FORCE_MEMORY_OPERATION */
619
620 /* Build sector write command. */
621 media_ptr -> fx_media_driver_logical_sector = reserved_sectors + (f * sectors_per_fat) + s;
622 media_ptr -> fx_media_driver_request = FX_DRIVER_WRITE;
623 media_ptr -> fx_media_driver_sectors = 1;
624 media_ptr -> fx_media_driver_system_write = FX_TRUE;
625 media_ptr -> fx_media_driver_sector_type = FX_FAT_SECTOR;
626
627 /* If trace is enabled, insert this event into the trace buffer. */
628 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)
629
630 /* Write out the sector. */
631 (driver)(media_ptr);
632
633 /* Clear the system write flag. */
634 media_ptr -> fx_media_driver_system_write = FX_FALSE;
635
636 /* Determine if it was successful. */
637 if (media_ptr -> fx_media_driver_status != FX_SUCCESS)
638 {
639 return(FX_IO_ERROR);
640 }
641 }
642 }
643
644 #ifndef FX_DISABLE_FORCE_MEMORY_OPERATION
645 /* Clear sector buffer. */
646 for (i = 0; i < bytes_per_sector; i++)
647 {
648 byte_ptr[i] = (CHAR)0;
649 }
650 #else
651 _fx_utility_memory_set(byte_ptr, 0, bytes_per_sector);
652 #endif /* FX_DISABLE_FORCE_MEMORY_OPERATION */
653
654 /* Now clear the root directory sectors. */
655 for (s = 0; s < root_sectors; s++)
656 {
657
658 /* Build sector write command. */
659 media_ptr -> fx_media_driver_logical_sector = reserved_sectors + (number_of_fats * sectors_per_fat) + s;
660 media_ptr -> fx_media_driver_request = FX_DRIVER_WRITE;
661 media_ptr -> fx_media_driver_sectors = 1;
662 media_ptr -> fx_media_driver_system_write = FX_TRUE;
663 media_ptr -> fx_media_driver_sector_type = FX_DIRECTORY_SECTOR;
664
665 /* If trace is enabled, insert this event into the trace buffer. */
666 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)
667
668 /* Write out the sector. */
669 (driver)(media_ptr);
670
671 /* Clear the write flag. */
672 media_ptr -> fx_media_driver_system_write = FX_FALSE;
673
674 /* Determine if it was successful. */
675 if (media_ptr -> fx_media_driver_status != FX_SUCCESS)
676 {
677 return(FX_IO_ERROR);
678 }
679 }
680
681 /* Build the "uninitialize" I/O driver request. */
682 media_ptr -> fx_media_driver_request = FX_DRIVER_UNINIT;
683 media_ptr -> fx_media_driver_status = FX_IO_ERROR;
684
685 /* If trace is enabled, insert this event into the trace buffer. */
686 FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_UNINIT, media_ptr, 0, 0, 0, FX_TRACE_INTERNAL_EVENTS, 0, 0)
687
688 /* Call the specified I/O driver with the uninitialize request. */
689 (media_ptr -> fx_media_driver_entry) (media_ptr);
690
691 /* Return success! */
692 return(media_ptr -> fx_media_driver_status);
693 }
694
695