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 |