GCC Code Coverage Report


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

fx_media_open.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_system.h"
30 #include "fx_media.h"
31 #include "fx_utility.h"
32
33
34 /**************************************************************************/
35 /* */
36 /* FUNCTION RELEASE */
37 /* */
38 /* _fx_media_open PORTABLE C */
39 /* 6.2.0 */
40 /* AUTHOR */
41 /* */
42 /* William E. Lamie, Microsoft Corporation */
43 /* */
44 /* DESCRIPTION */
45 /* */
46 /* This function opens the specified media with the supplied device */
47 /* driver. The specified media must conform to the FAT compatible */
48 /* file format, which is verified during the media open process. In */
49 /* addition, the supplied FileX device driver must also conform to */
50 /* the FileX device driver specification. */
51 /* */
52 /* The FAT boot sector (512 bytes) that is verified by this */
53 /* function must look like the following: */
54 /* */
55 /* Byte Offset Meaning Size */
56 /* */
57 /* 0x000 Jump Instructions 3 */
58 /* 0x003 OEM Name 8 */
59 /* 0x00B *Bytes per Sector 2 */
60 /* 0x00D *Sectors per Cluster 1 */
61 /* 0x00E *Reserved Sectors 2 */
62 /* 0x010 *Number of FATs 1 */
63 /* 0x011 *Max Root Dir Entries 2 */
64 /* 0x013 *Number of Sectors 2 */
65 /* 0x015 Media Type 1 */
66 /* 0x016 *Sectors per FAT 2 */
67 /* 0x018 *Sectors per Track 2 */
68 /* 0x01A *Number of Heads 2 */
69 /* 0x01C *Hidden Sectors 4 */
70 /* 0x020 *Huge Sectors 4 */
71 /* 0x024 Drive Number 1 */
72 /* 0x025 Reserved 1 */
73 /* 0x026 Boot Signature 1 */
74 /* 0x027 Volume ID 4 */
75 /* 0x02B Volume Label 11 */
76 /* 0x036 File System Type 8 */
77 /* ... ... ... */
78 /* 0x1FE **Signature (0x55aa) 2 */
79 /* */
80 /* * Denotes which elements of the boot record */
81 /* FileX uses. */
82 /* */
83 /* **Denotes the element is checked by the I/O */
84 /* driver. This eliminates the need for a minimum */
85 /* 512-byte buffer for FileX. */
86 /* */
87 /* Note: All values above are in little endian format, i.e. the LSB is */
88 /* in the lowest address. */
89 /* */
90 /* INPUT */
91 /* */
92 /* media_ptr Media control block pointer */
93 /* media_name Pointer to media name string */
94 /* media_driver Media driver entry function */
95 /* driver_info_ptr Optional information pointer */
96 /* supplied to media driver */
97 /* memory_ptr Pointer to memory used by the */
98 /* FileX for this media. */
99 /* memory_size Size of media memory - must */
100 /* at least 512 bytes and */
101 /* one sector size. */
102 /* */
103 /* OUTPUT */
104 /* */
105 /* return status */
106 /* */
107 /* CALLS */
108 /* */
109 /* I/O Driver */
110 /* _fx_utility_16_unsigned_read Read 16-bit unsigned value */
111 /* _fx_utility_32_unsigned_read Read 32-bit unsigned value */
112 /* _fx_utility_logical_sector_flush Invalidate log sector cache */
113 /* _fx_media_boot_info_extract Extract media information */
114 /* _fx_utility_FAT_entry_read Pickup FAT entry contents */
115 /* tx_mutex_create Create protection mutex */
116 /* */
117 /* CALLED BY */
118 /* */
119 /* Application Code */
120 /* */
121 /**************************************************************************/
122 67818 UINT _fx_media_open(FX_MEDIA *media_ptr, CHAR *media_name,
123 VOID (*media_driver)(FX_MEDIA *), VOID *driver_info_ptr,
124 VOID *memory_ptr, ULONG memory_size)
125 {
126
127 FX_MEDIA_PTR tail_ptr;
128 ULONG cluster_number;
129 ULONG FAT_entry, FAT_sector, FAT_read_sectors;
130 ULONG i, j;
131 #ifndef FX_DISABLE_CACHE
132 FX_CACHED_SECTOR *cache_entry_ptr;
133 #endif /* FX_DISABLE_CACHE */
134 UINT status;
135 UINT additional_info_sector;
136 UCHAR *original_memory_ptr;
137 ULONG bytes_in_buffer;
138 FX_INT_SAVE_AREA
139
140
141 #ifndef FX_DISABLE_BUILD_OPTIONS
142 /* Reference the version ID and option words to ensure they are linked in. */
143
2/2
✓ Branch 2 → 3 taken 67809 times.
✓ Branch 2 → 4 taken 9 times.
67818 if ((_fx_system_build_options_1 | _fx_system_build_options_2 | _fx_system_build_options_3) == 0 ||
144
2/2
✓ Branch 3 → 4 taken 9 times.
✓ Branch 3 → 5 taken 67800 times.
67809 _fx_version_id[0] == 0)
145 {
146
147 /* We should never get here! */
148 18 return(FX_NOT_IMPLEMENTED);
149 }
150 #endif /* FX_DISABLE_BUILD_OPTIONS */
151
152 #ifdef FX_DISABLE_FORCE_MEMORY_OPERATION
153 _fx_utility_memory_set((UCHAR *)media_ptr, 0, sizeof(FX_MEDIA));
154 #endif /* FX_DISABLE_FORCE_MEMORY_OPERATION */
155 #ifdef FX_DISABLE_CACHE
156 30238 media_ptr -> fx_media_memory_buffer_sector = (ULONG64)-1;
157 #endif /* FX_DISABLE_CACHE */
158
159 /* Save the basic information in the media control block. */
160 67800 media_ptr -> fx_media_name = media_name;
161 67800 media_ptr -> fx_media_driver_entry = media_driver;
162 67800 media_ptr -> fx_media_memory_buffer = (UCHAR *)memory_ptr;
163 67800 media_ptr -> fx_media_memory_size = memory_size;
164 #ifndef FX_DISABLE_FORCE_MEMORY_OPERATION
165 67800 media_ptr -> fx_media_disable_burst_cache = FX_FALSE;
166 67800 media_ptr -> fx_media_FAT_type = 0;
167 #endif /* FX_DISABLE_FORCE_MEMORY_OPERATION */
168
169 /* Save the original memory pointer. */
170 67800 original_memory_ptr = (UCHAR *)memory_ptr;
171
172 #ifndef FX_MEDIA_STATISTICS_DISABLE
173
174 /* Clear the optional media statistics. */
175 67800 media_ptr -> fx_media_directory_attributes_reads = 0;
176 67800 media_ptr -> fx_media_directory_attributes_sets = 0;
177 67800 media_ptr -> fx_media_directory_creates = 0;
178 67800 media_ptr -> fx_media_directory_default_gets = 0;
179 67800 media_ptr -> fx_media_directory_default_sets = 0;
180 67800 media_ptr -> fx_media_directory_deletes = 0;
181 67800 media_ptr -> fx_media_directory_first_entry_finds = 0;
182 67800 media_ptr -> fx_media_directory_first_full_entry_finds = 0;
183 67800 media_ptr -> fx_media_directory_information_gets = 0;
184 67800 media_ptr -> fx_media_directory_local_path_clears = 0;
185 67800 media_ptr -> fx_media_directory_local_path_gets = 0;
186 67800 media_ptr -> fx_media_directory_local_path_restores = 0;
187 67800 media_ptr -> fx_media_directory_local_path_sets = 0;
188 67800 media_ptr -> fx_media_directory_name_tests = 0;
189 67800 media_ptr -> fx_media_directory_next_entry_finds = 0;
190 67800 media_ptr -> fx_media_directory_next_full_entry_finds = 0;
191 67800 media_ptr -> fx_media_directory_renames = 0;
192 67800 media_ptr -> fx_media_file_allocates = 0;
193 67800 media_ptr -> fx_media_file_attributes_reads = 0;
194 67800 media_ptr -> fx_media_file_attributes_sets = 0;
195 67800 media_ptr -> fx_media_file_best_effort_allocates = 0;
196 67800 media_ptr -> fx_media_file_closes = 0;
197 67800 media_ptr -> fx_media_file_creates = 0;
198 67800 media_ptr -> fx_media_file_deletes = 0;
199 67800 media_ptr -> fx_media_file_opens = 0;
200 67800 media_ptr -> fx_media_file_reads = 0;
201 67800 media_ptr -> fx_media_file_relative_seeks = 0;
202 67800 media_ptr -> fx_media_file_renames = 0;
203 67800 media_ptr -> fx_media_file_seeks = 0;
204 67800 media_ptr -> fx_media_file_truncates = 0;
205 67800 media_ptr -> fx_media_file_truncate_releases = 0;
206 67800 media_ptr -> fx_media_file_writes = 0;
207 67800 media_ptr -> fx_media_aborts = 0;
208 67800 media_ptr -> fx_media_flushes = 0;
209 67800 media_ptr -> fx_media_reads = 0;
210 67800 media_ptr -> fx_media_writes = 0;
211 67800 media_ptr -> fx_media_directory_entry_reads = 0;
212 67800 media_ptr -> fx_media_directory_entry_writes = 0;
213 67800 media_ptr -> fx_media_directory_searches = 0;
214 #ifndef FX_MEDIA_DISABLE_SEARCH_CACHE
215 67800 media_ptr -> fx_media_directory_search_cache_hits = 0;
216 #endif
217 67800 media_ptr -> fx_media_directory_free_searches = 0;
218 67800 media_ptr -> fx_media_fat_entry_reads = 0;
219 67800 media_ptr -> fx_media_fat_entry_writes = 0;
220 67800 media_ptr -> fx_media_fat_entry_cache_read_hits = 0;
221 67800 media_ptr -> fx_media_fat_entry_cache_read_misses = 0;
222 67800 media_ptr -> fx_media_fat_entry_cache_write_hits = 0;
223 67800 media_ptr -> fx_media_fat_entry_cache_write_misses = 0;
224 67800 media_ptr -> fx_media_fat_cache_flushes = 0;
225 67800 media_ptr -> fx_media_fat_sector_reads = 0;
226 67800 media_ptr -> fx_media_fat_sector_writes = 0;
227 67800 media_ptr -> fx_media_logical_sector_reads = 0;
228 67800 media_ptr -> fx_media_logical_sector_writes = 0;
229 67800 media_ptr -> fx_media_logical_sector_cache_read_hits = 0;
230 67800 media_ptr -> fx_media_logical_sector_cache_read_misses = 0;
231 67800 media_ptr -> fx_media_driver_read_requests = 0;
232 67800 media_ptr -> fx_media_driver_write_requests = 0;
233 67800 media_ptr -> fx_media_driver_boot_read_requests = 0;
234 67800 media_ptr -> fx_media_driver_boot_write_requests = 0;
235 67800 media_ptr -> fx_media_driver_release_sectors_requests = 0;
236 67800 media_ptr -> fx_media_driver_flush_requests = 0;
237 #endif
238 #ifdef FX_ENABLE_FAULT_TOLERANT
239 31582 media_ptr -> fx_media_fault_tolerant_enabled = FX_FALSE;
240 31582 media_ptr -> fx_media_fault_tolerant_state = 0;
241 #endif /* FX_ENABLE_FAULT_TOLERANT */
242
243 /* If trace is enabled, insert this event into the trace buffer. */
244 FX_TRACE_IN_LINE_INSERT(FX_TRACE_MEDIA_OPEN, media_ptr, media_driver, memory_ptr, memory_size, FX_TRACE_MEDIA_EVENTS, 0, 0)
245
246 /* Initialize the supplied media I/O driver. First, build the
247 initialize driver request. Set the fx_media_driver_status to FX_MEDIA_NOT_OPEN
248 to let the driver understand that the request is issued from a fx_media_open() call.
249 */
250 67800 media_ptr -> fx_media_driver_request = FX_DRIVER_INIT;
251 67800 media_ptr -> fx_media_driver_status = FX_MEDIA_NOT_OPEN;
252 67800 media_ptr -> fx_media_driver_info = driver_info_ptr;
253 67800 media_ptr -> fx_media_driver_write_protect = FX_FALSE;
254 67800 media_ptr -> fx_media_driver_free_sector_update = FX_FALSE;
255 67800 media_ptr -> fx_media_driver_data_sector_read = FX_FALSE;
256
257 /* If trace is enabled, insert this event into the trace buffer. */
258 FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_INIT, media_ptr, 0, 0, 0, FX_TRACE_INTERNAL_EVENTS, 0, 0)
259
260 /* Call the specified I/O driver with the initialize request. */
261 67800 (media_ptr -> fx_media_driver_entry) (media_ptr);
262
263 /* Determine if the I/O driver initialized successfully. */
264
2/2
✓ Branch 6 → 7 taken 7524 times.
✓ Branch 6 → 8 taken 60276 times.
67800 if (media_ptr -> fx_media_driver_status != FX_SUCCESS)
265 {
266
267 /* Return the driver error status. */
268 7524 return(FX_IO_ERROR);
269 }
270
271 #ifndef FX_MEDIA_STATISTICS_DISABLE
272
273 /* Increment the number of driver boot read requests. */
274 60276 media_ptr -> fx_media_driver_boot_read_requests++;
275 #endif
276
277 /* Read the boot sector from the device. Build the read boot sector
278 command. */
279 60276 media_ptr -> fx_media_driver_request = FX_DRIVER_BOOT_READ;
280 60276 media_ptr -> fx_media_driver_status = FX_IO_ERROR;
281 60276 media_ptr -> fx_media_driver_buffer = memory_ptr;
282 60276 media_ptr -> fx_media_driver_sectors = 1;
283 60276 media_ptr -> fx_media_driver_sector_type = FX_BOOT_SECTOR;
284
285 /* If trace is enabled, insert this event into the trace buffer. */
286 FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_BOOT_READ, media_ptr, memory_ptr, 0, 0, FX_TRACE_INTERNAL_EVENTS, 0, 0)
287
288 /* Invoke the driver to read the boot sector. */
289 60276 (media_ptr -> fx_media_driver_entry) (media_ptr);
290
291 /* Determine if the boot sector was read correctly. */
292
2/2
✓ Branch 9 → 10 taken 3492 times.
✓ Branch 9 → 12 taken 56784 times.
60276 if (media_ptr -> fx_media_driver_status != FX_SUCCESS)
293 {
294
295 /* Build the "uninitialize" I/O driver request. */
296 3492 media_ptr -> fx_media_driver_request = FX_DRIVER_UNINIT;
297 3492 media_ptr -> fx_media_driver_status = FX_IO_ERROR;
298
299 /* If trace is enabled, insert this event into the trace buffer. */
300 FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_UNINIT, media_ptr, 0, 0, 0, FX_TRACE_INTERNAL_EVENTS, 0, 0)
301
302 /* Call the specified I/O driver with the uninitialize request. */
303 3492 (media_ptr -> fx_media_driver_entry) (media_ptr);
304
305 /* Return the boot sector error status. */
306 3492 return(FX_BOOT_ERROR);
307 }
308
309 /* Extract and validate the media parameters from the boot sector. */
310
2/2
✓ Branch 13 → 14 taken 54 times.
✓ Branch 13 → 16 taken 56730 times.
56784 if (_fx_media_boot_info_extract(media_ptr) != FX_SUCCESS)
311 {
312
313 /* Build the "uninitialize" I/O driver request. */
314 54 media_ptr -> fx_media_driver_request = FX_DRIVER_UNINIT;
315 54 media_ptr -> fx_media_driver_status = FX_IO_ERROR;
316
317 /* If trace is enabled, insert this event into the trace buffer. */
318 FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_UNINIT, media_ptr, 0, 0, 0, FX_TRACE_INTERNAL_EVENTS, 0, 0)
319
320 /* Call the specified I/O driver with the uninitialize request. */
321 54 (media_ptr -> fx_media_driver_entry) (media_ptr);
322
323 /* Return the invalid media error status. */
324 54 return(FX_MEDIA_INVALID);
325 }
326
327 /* Pickup the additional info sector number. This will only be used in FAT32 situations. */
328 56730 additional_info_sector = _fx_utility_16_unsigned_read(&media_ptr -> fx_media_driver_buffer[48]);
329
330 /* Is there at least one? */
331
2/2
✓ Branch 17 → 18 taken 5 times.
✓ Branch 17 → 20 taken 56725 times.
56730 if (memory_size < media_ptr -> fx_media_bytes_per_sector)
332 {
333
334 /* Build the "uninitialize" I/O driver request. */
335 5 media_ptr -> fx_media_driver_request = FX_DRIVER_UNINIT;
336 5 media_ptr -> fx_media_driver_status = FX_IO_ERROR;
337
338 /* If trace is enabled, insert this event into the trace buffer. */
339 FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_UNINIT, media_ptr, 0, 0, 0, FX_TRACE_INTERNAL_EVENTS, 0, 0)
340
341 /* Call the specified I/O driver with the uninitialize request. */
342 5 (media_ptr -> fx_media_driver_entry) (media_ptr);
343
344 /* Error in the buffer size supplied by user. */
345 5 return(FX_BUFFER_ERROR);
346 }
347
348 #ifndef FX_DISABLE_CACHE
349 /* Determine how many logical sectors can be cached with user's supplied
350 buffer area - there must be at least enough for one sector! */
351 31407 media_ptr -> fx_media_sector_cache_size = memory_size / media_ptr -> fx_media_bytes_per_sector;
352
353 /* If trace is enabled, register this object. */
354 FX_TRACE_OBJECT_REGISTER(FX_TRACE_OBJECT_TYPE_MEDIA, media_ptr, media_name, FX_MAX_FAT_CACHE, media_ptr -> fx_media_sector_cache_size)
355
356 /* Adjust the internal cache to fit the fixed number of sector cache control blocks
357 built into the media control block. */
358
2/2
✓ Branch 20 → 21 taken 5 times.
✓ Branch 20 → 22 taken 31402 times.
31407 if (media_ptr -> fx_media_sector_cache_size > FX_MAX_SECTOR_CACHE)
359 {
360
361 /* Adjust the number of cache sectors downward. If this is insufficient,
362 the FX_MAX_SECTOR_CACHE constant in FX_API.H must be changed and the FileX
363 library must be rebuilt. */
364 5 media_ptr -> fx_media_sector_cache_size = FX_MAX_SECTOR_CACHE;
365 }
366
367 /* Otherwise, everything is okay. Initialize the data structures for managing the
368 logical sector cache. */
369 31407 i = (UINT)media_ptr -> fx_media_sector_cache_size;
370 31407 cache_entry_ptr = media_ptr -> fx_media_sector_cache;
371
2/2
✓ Branch 24 → 23 taken 89508 times.
✓ Branch 24 → 25 taken 31407 times.
120915 while (i--)
372 {
373
374 /* Initialize each of the cache entries. */
375 89508 cache_entry_ptr -> fx_cached_sector_memory_buffer = (UCHAR *)memory_ptr;
376 89508 cache_entry_ptr -> fx_cached_sector = (~(ULONG64)0);
377 89508 cache_entry_ptr -> fx_cached_sector_buffer_dirty = FX_FALSE;
378 89508 cache_entry_ptr -> fx_cached_sector_valid = FX_FALSE;
379 89508 cache_entry_ptr -> fx_cached_sector_next_used = cache_entry_ptr + 1;
380
381 /* Move to the next cache sector entry. */
382 89508 cache_entry_ptr++;
383
384 /* Update the memory pointer to the next buffer slot. */
385 89508 memory_ptr = (VOID *)(((UCHAR *)memory_ptr) + media_ptr -> fx_media_bytes_per_sector);
386 }
387
388 /* Backup to the last cache entry to set its next pointer to NULL. */
389 31407 cache_entry_ptr--;
390 31407 cache_entry_ptr -> fx_cached_sector_next_used = FX_NULL;
391
392 /* Remember the last memory address used by the caching logic. */
393 31407 media_ptr -> fx_media_sector_cache_end = ((UCHAR *)memory_ptr) - 1;
394
395 /* Setup the head pointer of the list. */
396 31407 media_ptr -> fx_media_sector_cache_list_ptr = media_ptr -> fx_media_sector_cache;
397
398 /* Setup the bit map that keeps track of the valid hashed cache logical sectors. */
399 31407 media_ptr -> fx_media_sector_cache_hashed_sector_valid = 0;
400
401 /* Clear the counter of the number of outstanding dirty sectors. */
402 31407 media_ptr -> fx_media_sector_cache_dirty_count = 0;
403
404 /* Determine if the logical sector cache should be managed by the hash function
405 instead of the linear search. The cache must be a power of 2 that is between the
406 minimum and maximum cache size. */
407
2/2
✓ Branch 25 → 26 taken 698 times.
✓ Branch 25 → 28 taken 30709 times.
31407 if ((media_ptr -> fx_media_sector_cache_size >= FX_SECTOR_CACHE_HASH_ENABLE) &&
408 698 ((media_ptr -> fx_media_sector_cache_size ^ (media_ptr -> fx_media_sector_cache_size - 1)) ==
409
2/2
✓ Branch 26 → 27 taken 686 times.
✓ Branch 26 → 28 taken 12 times.
698 (media_ptr -> fx_media_sector_cache_size | (media_ptr -> fx_media_sector_cache_size - 1))))
410 {
411
412
413 /* Set the logical sector cache hash flag. When this flag is set, the logical
414 sector cache is accessed with a hash function instead of a linear search. */
415 686 media_ptr -> fx_media_sector_cache_hashed = FX_TRUE;
416 686 media_ptr -> fx_media_sector_cache_hash_mask =
417 686 ((media_ptr -> fx_media_sector_cache_size / FX_SECTOR_CACHE_DEPTH) - 1);
418 }
419 else
420 {
421
422 /* Clear the logical sector cache flag. */
423 30721 media_ptr -> fx_media_sector_cache_hashed = FX_FALSE;
424 }
425 #else
426 25318 media_ptr -> fx_media_memory_buffer = memory_ptr;
427 #endif /* FX_DISABLE_CACHE */
428
429 #ifndef FX_DISABLE_FORCE_MEMORY_OPERATION
430 /* Initialize the FAT cache entry array. */
431
4/4
✓ Branch 22 → 21 taken 1620352 times.
✓ Branch 22 → 23 taken 25318 times.
✓ Branch 31 → 30 taken 2010048 times.
✓ Branch 31 → 32 taken 31407 times.
3687125 for (i = 0; i < FX_MAX_FAT_CACHE; i++)
432 {
433
434 /* Clear entry in the FAT cache. */
435 3630400 media_ptr -> fx_media_fat_cache[i].fx_fat_cache_entry_cluster = 0;
436 3630400 media_ptr -> fx_media_fat_cache[i].fx_fat_cache_entry_value = 0;
437 3630400 media_ptr -> fx_media_fat_cache[i].fx_fat_cache_entry_dirty = 0;
438 }
439
440 /* Initialize the secondary FAT update map. */
441
4/4
✓ Branch 25 → 24 taken 25318 times.
✓ Branch 25 → 26 taken 25318 times.
✓ Branch 34 → 33 taken 31407 times.
✓ Branch 34 → 35 taken 31407 times.
113450 for (i = 0; i < FX_FAT_MAP_SIZE; i++)
442 {
443
444 /* Clear bit map entry for secondary FAT update. */
445 56725 media_ptr -> fx_media_fat_secondary_update_map[i] = 0;
446 }
447 #endif /* FX_DISABLE_FORCE_MEMORY_OPERATION */
448
449
450 /* Root_sector_start has been computed */
451 56725 media_ptr -> fx_media_root_sector_start = media_ptr -> fx_media_reserved_sectors +
452 56725 (media_ptr -> fx_media_number_of_FATs *
453 56725 media_ptr -> fx_media_sectors_per_FAT);
454
455 /* Calculate the number of directory sectors. */
456 56725 media_ptr -> fx_media_root_sectors =
457 56725 ((media_ptr -> fx_media_root_directory_entries * FX_DIR_ENTRY_SIZE) +
458 56725 media_ptr -> fx_media_bytes_per_sector - 1) /
459 56725 media_ptr -> fx_media_bytes_per_sector;
460
461 /* Calculate the starting data sector. */
462 56725 media_ptr -> fx_media_data_sector_start = media_ptr -> fx_media_root_sector_start +
463 56725 media_ptr -> fx_media_root_sectors;
464
465 /* Calculate the total number of clusters. */
466 56725 media_ptr -> fx_media_total_clusters = (ULONG)((media_ptr -> fx_media_total_sectors - media_ptr -> fx_media_data_sector_start) /
467 56725 media_ptr -> fx_media_sectors_per_cluster);
468
469 /* Determine if a 12-bit FAT is in use. */
470
4/4
✓ Branch 26 → 27 taken 792 times.
✓ Branch 26 → 28 taken 24526 times.
✓ Branch 35 → 36 taken 942 times.
✓ Branch 35 → 37 taken 30465 times.
56725 if (media_ptr -> fx_media_total_clusters < FX_12_BIT_FAT_SIZE)
471 {
472
473 /* Yes, 12-bit FAT is present. Set flag accordingly. */
474 1734 media_ptr -> fx_media_12_bit_FAT = FX_TRUE;
475 1734 media_ptr -> fx_media_32_bit_FAT = FX_FALSE;
476
477 /* No additional information sector in FAT12. */
478 1734 media_ptr -> fx_media_FAT32_additional_info_sector = 0;
479
480 /* Set FAT last and FAT reserved. */
481 1734 media_ptr -> fx_media_fat_reserved = FX_RESERVED_1;
482 1734 media_ptr -> fx_media_fat_last = FX_LAST_CLUSTER_2;
483 }
484
4/4
✓ Branch 28 → 29 taken 8760 times.
✓ Branch 28 → 30 taken 15766 times.
✓ Branch 37 → 38 taken 10861 times.
✓ Branch 37 → 39 taken 19604 times.
54991 else if (media_ptr -> fx_media_total_clusters < FX_16_BIT_FAT_SIZE)
485 {
486
487 /* A 16-bit FAT is present. Set flag accordingly. */
488 19621 media_ptr -> fx_media_12_bit_FAT = FX_FALSE;
489 19621 media_ptr -> fx_media_32_bit_FAT = FX_FALSE;
490
491 /* No additional information sector in FAT16. */
492 19621 media_ptr -> fx_media_FAT32_additional_info_sector = 0;
493
494 /* Set FAT last and FAT reserved. */
495 19621 media_ptr -> fx_media_fat_reserved = FX_RESERVED_1;
496 19621 media_ptr -> fx_media_fat_last = FX_LAST_CLUSTER_2;
497 }
498 else
499 {
500
501 /* Yes, a 32-bit FAT is present. */
502 35370 media_ptr -> fx_media_12_bit_FAT = FX_FALSE;
503 35370 media_ptr -> fx_media_32_bit_FAT = FX_TRUE;
504
505 /* Save the additional information sector FAT32. This was read from the boot
506 sector earlier in this routine. */
507 35370 media_ptr -> fx_media_FAT32_additional_info_sector = additional_info_sector;
508
509 /* Set FAT last and FAT reserved. */
510 35370 media_ptr -> fx_media_fat_reserved = FX_RESERVED_1_32;
511 35370 media_ptr -> fx_media_fat_last = FX_LAST_CLUSTER_2_32;
512 }
513
514 /* Determine if a 32-bit FAT is present. If so, calculate the size of the root directory (since
515 it is variable in FAT32. */
516
4/4
✓ Branch 31 → 32 taken 15766 times.
✓ Branch 31 → 47 taken 9552 times.
✓ Branch 40 → 41 taken 19604 times.
✓ Branch 40 → 56 taken 11803 times.
56725 if (media_ptr -> fx_media_32_bit_FAT == FX_TRUE)
517 {
518
519 /* Root First cluster starts from at least cluster 2, or higher. */
520
4/4
✓ Branch 32 → 33 taken 4 times.
✓ Branch 32 → 34 taken 15762 times.
✓ Branch 41 → 42 taken 5 times.
✓ Branch 41 → 43 taken 19599 times.
35370 if (media_ptr -> fx_media_root_cluster_32 < FX_FAT_ENTRY_START)
521 {
522 9 return(FX_MEDIA_INVALID);
523 }
524
525 /* Calculate logical number of root dir sector. */
526 35361 media_ptr -> fx_media_root_sector_start = media_ptr -> fx_media_data_sector_start +
527 35361 (media_ptr -> fx_media_root_cluster_32 - FX_FAT_ENTRY_START) *
528 35361 media_ptr -> fx_media_sectors_per_cluster;
529
530 /* Calculate maximum possible value for fx_media_root_directory_entries */
531 35361 i = 0;
532 35361 for (cluster_number = media_ptr -> fx_media_root_cluster_32;;)
533 {
534
535 660492 status = _fx_utility_FAT_entry_read(media_ptr, cluster_number, &FAT_entry);
536 660492 i++;
537 /* Determine if the read was successful. */
538
4/4
✓ Branch 36 → 37 taken 1504 times.
✓ Branch 36 → 39 taken 292094 times.
✓ Branch 45 → 46 taken 1880 times.
✓ Branch 45 → 48 taken 365014 times.
660492 if (status != FX_SUCCESS)
539 {
540
541 /* Build the "uninitialize" I/O driver request. */
542 3384 media_ptr -> fx_media_driver_request = FX_DRIVER_UNINIT;
543 3384 media_ptr -> fx_media_driver_status = FX_IO_ERROR;
544
545 /* If trace is enabled, insert this event into the trace buffer. */
546 FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_UNINIT, media_ptr, 0, 0, 0, FX_TRACE_INTERNAL_EVENTS, 0, 0)
547
548 /* Call the specified I/O driver with the uninitialize request. */
549 3384 (media_ptr -> fx_media_driver_entry) (media_ptr);
550
551 3384 return(FX_FAT_READ_ERROR);
552 }
553
554
8/8
✓ Branch 39 → 40 taken 292088 times.
✓ Branch 39 → 41 taken 6 times.
✓ Branch 40 → 41 taken 4 times.
✓ Branch 40 → 43 taken 292084 times.
✓ Branch 48 → 49 taken 365007 times.
✓ Branch 48 → 50 taken 7 times.
✓ Branch 49 → 50 taken 5 times.
✓ Branch 49 → 52 taken 365002 times.
657108 if ((cluster_number == FAT_entry) || (i > media_ptr -> fx_media_total_clusters))
555 {
556
557 /* Build the "uninitialize" I/O driver request. */
558 22 media_ptr -> fx_media_driver_request = FX_DRIVER_UNINIT;
559 22 media_ptr -> fx_media_driver_status = FX_IO_ERROR;
560
561 /* If trace is enabled, insert this event into the trace buffer. */
562 FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_UNINIT, media_ptr, 0, 0, 0, FX_TRACE_INTERNAL_EVENTS, 0, 0)
563
564 /* Call the specified I/O driver with the uninitialize request. */
565 22 (media_ptr -> fx_media_driver_entry) (media_ptr);
566
567 22 return(FX_FAT_READ_ERROR);
568 }
569
4/4
✓ Branch 43 → 44 taken 14248 times.
✓ Branch 43 → 45 taken 277836 times.
✓ Branch 52 → 53 taken 17707 times.
✓ Branch 52 → 54 taken 347295 times.
657086 if (FAT_entry >= FX_RESERVED_1_32)
570 {
571 31955 break;
572 }
573 625131 cluster_number = FAT_entry;
574 }
575
576 /* Calculate the number of directory entries. */
577 31955 media_ptr -> fx_media_root_directory_entries = (i * media_ptr -> fx_media_sectors_per_cluster *
578 31955 media_ptr -> fx_media_bytes_per_sector) / FX_DIR_ENTRY_SIZE;
579 }
580
581 #ifndef FX_DISABLE_FORCE_MEMORY_OPERATION
582 /* Calculate the number of available clusters. */
583 53310 media_ptr -> fx_media_available_clusters = 0;
584
585 /* Set the cluster search start to an invalid value. */
586 53310 media_ptr -> fx_media_cluster_search_start = 0;
587 #endif /* FX_DISABLE_FORCE_MEMORY_OPERATION */
588
589 /* Determine if there is 32-bit FAT additional information sector. */
590
4/4
✓ Branch 47 → 48 taken 14248 times.
✓ Branch 47 → 63 taken 9552 times.
✓ Branch 56 → 57 taken 17707 times.
✓ Branch 56 → 72 taken 11803 times.
53310 if (media_ptr -> fx_media_FAT32_additional_info_sector)
591 {
592
593 UCHAR *buffer_ptr;
594 ULONG signature;
595
596
597 /* Yes, read the FAT32 additional information sector to get the available cluster count and
598 the hint for the first available cluster. */
599
600 #ifndef FX_DISABLE_CACHE
601 /* Setup a pointer to the first cached entry's buffer. */
602 17707 buffer_ptr = (media_ptr -> fx_media_sector_cache_list_ptr) -> fx_cached_sector_memory_buffer;
603
604 /* Invalidate this cache entry. */
605 17707 (media_ptr -> fx_media_sector_cache_list_ptr) -> fx_cached_sector = (~((ULONG64) 0));
606 17707 (media_ptr -> fx_media_sector_cache_list_ptr) -> fx_cached_sector_valid = FX_FALSE;
607 #else
608 14248 buffer_ptr = media_ptr -> fx_media_memory_buffer;
609 14248 media_ptr -> fx_media_memory_buffer_sector = (ULONG64)-1;
610 #endif /* FX_DISABLE_CACHE */
611
612 /* Read the FAT32 additional information sector from the device. */
613 31955 media_ptr -> fx_media_driver_request = FX_DRIVER_READ;
614 31955 media_ptr -> fx_media_driver_status = FX_IO_ERROR;
615 31955 media_ptr -> fx_media_driver_buffer = buffer_ptr;
616 31955 media_ptr -> fx_media_driver_logical_sector = media_ptr -> fx_media_FAT32_additional_info_sector;
617 31955 media_ptr -> fx_media_driver_sectors = 1;
618 31955 media_ptr -> fx_media_driver_sector_type = FX_DIRECTORY_SECTOR;
619
620 #ifndef FX_MEDIA_STATISTICS_DISABLE
621
622 /* Increment the number of driver read sector(s) requests. */
623 31955 media_ptr -> fx_media_driver_read_requests++;
624 #endif
625
626 /* If trace is enabled, insert this event into the trace buffer. */
627 FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_READ, media_ptr, media_ptr -> fx_media_FAT32_additional_info_sector, 1, buffer_ptr, FX_TRACE_INTERNAL_EVENTS, 0, 0)
628
629 /* Invoke the driver to read the FAT32 additional information sector. */
630 31955 (media_ptr -> fx_media_driver_entry) (media_ptr);
631
632 /* Determine if the FAT32 sector was read correctly. */
633
4/4
✓ Branch 49 → 50 taken 12688 times.
✓ Branch 49 → 62 taken 1560 times.
✓ Branch 58 → 59 taken 15757 times.
✓ Branch 58 → 71 taken 1950 times.
31955 if (media_ptr -> fx_media_driver_status == FX_SUCCESS)
634 {
635
636 /* Yes, setup a pointer into the FAT32 additional information sector. */
637 28445 buffer_ptr = media_ptr -> fx_media_driver_buffer;
638
639 /* Pickup the first signature long word. */
640 28445 signature = _fx_utility_32_unsigned_read(&buffer_ptr[0]);
641
642 /* Determine if the signature is correct. */
643
4/4
✓ Branch 51 → 52 taken 8156 times.
✓ Branch 51 → 61 taken 4532 times.
✓ Branch 60 → 61 taken 10181 times.
✓ Branch 60 → 70 taken 5576 times.
28445 if (signature == 0x41615252)
644 {
645
646 /* Yes, the first signature is correct, now pickup the next signature. */
647 18337 signature = _fx_utility_32_unsigned_read(&buffer_ptr[484]);
648
649 /* Determine if this signature is correct. */
650
4/4
✓ Branch 53 → 54 taken 8152 times.
✓ Branch 53 → 60 taken 4 times.
✓ Branch 62 → 63 taken 10176 times.
✓ Branch 62 → 69 taken 5 times.
18337 if (signature == 0x61417272)
651 {
652
653 /* Yes, we have a good FAT32 additional information sector. */
654
655 /* Pickup the current available cluster count on the media. */
656 18328 media_ptr -> fx_media_available_clusters = _fx_utility_32_unsigned_read(&buffer_ptr[488]);
657
658 /* Initialize the last reported available cluster count to the same value. */
659 18328 media_ptr -> fx_media_FAT32_additional_info_last_available = media_ptr -> fx_media_available_clusters;
660
661 /* Pickup the hint for the starting free cluster search. */
662 18328 media_ptr -> fx_media_cluster_search_start = _fx_utility_32_unsigned_read(&buffer_ptr[492]);
663
664 /* Perform a quick sanity check on the available cluster count and the starting free
665 cluster search. */
666
4/4
✓ Branch 56 → 57 taken 8148 times.
✓ Branch 56 → 59 taken 4 times.
✓ Branch 65 → 66 taken 10171 times.
✓ Branch 65 → 68 taken 5 times.
18328 if ((media_ptr -> fx_media_available_clusters > media_ptr -> fx_media_total_clusters) ||
667
4/4
✓ Branch 57 → 58 taken 8144 times.
✓ Branch 57 → 59 taken 4 times.
✓ Branch 66 → 67 taken 10166 times.
✓ Branch 66 → 68 taken 5 times.
18319 (media_ptr -> fx_media_cluster_search_start > media_ptr -> fx_media_total_clusters + FX_FAT_ENTRY_START) ||
668
4/4
✓ Branch 58 → 59 taken 4 times.
✓ Branch 58 → 63 taken 8140 times.
✓ Branch 67 → 68 taken 5 times.
✓ Branch 67 → 72 taken 10161 times.
18310 (media_ptr -> fx_media_cluster_search_start < FX_FAT_ENTRY_START))
669 {
670
671 /* Something is wrong, clear the available cluster count and search so the regular processing
672 is used. */
673 27 media_ptr -> fx_media_available_clusters = 0;
674 27 media_ptr -> fx_media_cluster_search_start = 0;
675
676 /* We don't invalidate the additional info sector here because only the data is bad. */
677 }
678 }
679 else
680 {
681
682 /* Signature is bad, invalidate the additional info sector. */
683 9 media_ptr -> fx_media_FAT32_additional_info_sector = 0;
684 }
685 }
686 else
687 {
688
689 /* Signature is bad, invalidate the additional info sector. */
690 10108 media_ptr -> fx_media_FAT32_additional_info_sector = 0;
691 }
692 }
693 else
694 {
695
696 /* IO error trying to read additional information sector, invalidate the additional info sector. */
697 3510 media_ptr -> fx_media_FAT32_additional_info_sector = 0;
698 }
699 }
700
701 /* Search the media to find the first available cluster as well as the total
702 available clusters. */
703
704 /* Determine what type of FAT is present. */
705
4/4
✓ Branch 63 → 64 taken 792 times.
✓ Branch 63 → 74 taken 23008 times.
✓ Branch 72 → 73 taken 942 times.
✓ Branch 72 → 83 taken 28568 times.
53310 if (media_ptr -> fx_media_12_bit_FAT)
706 {
707
708 /* A 12-bit FAT is present. Utilize the FAT entry read utility to pickup
709 each FAT entry's contents. */
710
711 /* Loop to read each cluster entry in the first FAT. */
712 1734 for (cluster_number = FX_FAT_ENTRY_START;
713
4/4
✓ Branch 73 → 65 taken 414586 times.
✓ Branch 73 → 94 taken 788 times.
✓ Branch 82 → 74 taken 515722 times.
✓ Branch 82 → 105 taken 937 times.
932033 cluster_number < (media_ptr -> fx_media_total_clusters) + FX_FAT_ENTRY_START;
714 930299 cluster_number++)
715 {
716
717 /* Read a FAT entry. */
718 930308 status = _fx_utility_FAT_entry_read(media_ptr, cluster_number, &FAT_entry);
719
720 /* Determine if the read was successful. */
721
4/4
✓ Branch 66 → 67 taken 4 times.
✓ Branch 66 → 69 taken 414582 times.
✓ Branch 75 → 76 taken 5 times.
✓ Branch 75 → 78 taken 515717 times.
930308 if (status != FX_SUCCESS)
722 {
723
724 /* Build the "uninitialize" I/O driver request. */
725 9 media_ptr -> fx_media_driver_request = FX_DRIVER_UNINIT;
726 9 media_ptr -> fx_media_driver_status = FX_IO_ERROR;
727
728 /* If trace is enabled, insert this event into the trace buffer. */
729 FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_UNINIT, media_ptr, 0, 0, 0, FX_TRACE_INTERNAL_EVENTS, 0, 0)
730
731 /* Call the specified I/O driver with the uninitialize request. */
732 9 (media_ptr -> fx_media_driver_entry) (media_ptr);
733
734 9 return(FX_FAT_READ_ERROR);
735 }
736
737 /* Now determine if the FAT entry is available. */
738
4/4
✓ Branch 69 → 70 taken 378372 times.
✓ Branch 69 → 72 taken 36210 times.
✓ Branch 78 → 79 taken 478934 times.
✓ Branch 78 → 81 taken 36783 times.
930299 if (FAT_entry == FX_FREE_CLUSTER)
739 {
740
741 /* Increment the number of available clusters. */
742 857306 media_ptr -> fx_media_available_clusters++;
743
744 /* Determine if the starting free cluster has been found yet. */
745
4/4
✓ Branch 70 → 71 taken 780 times.
✓ Branch 70 → 72 taken 377592 times.
✓ Branch 79 → 80 taken 929 times.
✓ Branch 79 → 81 taken 478005 times.
857306 if (media_ptr -> fx_media_cluster_search_start == 0)
746 {
747
748 /* Remember the first free cluster to start further searches from. */
749 1709 media_ptr -> fx_media_cluster_search_start = cluster_number;
750 }
751 }
752 }
753 }
754
4/4
✓ Branch 74 → 75 taken 14868 times.
✓ Branch 74 → 94 taken 8140 times.
✓ Branch 83 → 84 taken 18407 times.
✓ Branch 83 → 105 taken 10161 times.
51576 else if (media_ptr -> fx_media_available_clusters == 0)
755 {
756
757 /* A 16 or 32-bit FAT is present. Read directly into the logical sector
758 cache memory to optimize I/O on larger devices. Since we are looking for
759 values of zero, endian issues are not important. */
760
761 /* Invalidate the current logical sector cache. */
762 33275 _fx_utility_logical_sector_flush(media_ptr, ((ULONG64) 1), (ULONG64) (media_ptr -> fx_media_total_sectors), FX_TRUE);
763
764 /* Reset the memory pointer. */
765 33275 media_ptr -> fx_media_memory_buffer = original_memory_ptr;
766
767 /* Loop through all FAT sectors in the primary FAT. The first two entries are
768 examined in this loop, but they are always unavailable. */
769 33275 cluster_number = 0;
770 #ifndef FX_DISABLE_CACHE
771
2/2
✓ Branch 104 → 86 taken 12627392 times.
✓ Branch 104 → 105 taken 18402 times.
12645794 for (i = 0; i < media_ptr -> fx_media_sectors_per_FAT; i = i + media_ptr -> fx_media_sector_cache_size)
772 {
773
774 /* Calculate the starting next FAT sector. */
775 12627392 FAT_sector = media_ptr -> fx_media_reserved_sectors + i;
776
777 /* Calculate how many sectors to read. */
778 12627392 FAT_read_sectors = media_ptr -> fx_media_sectors_per_FAT - i;
779
780 /* Determine if there is not enough memory to read the remaining FAT sectors. */
781
2/2
✓ Branch 86 → 87 taken 12621296 times.
✓ Branch 86 → 88 taken 6096 times.
12627392 if (FAT_read_sectors > media_ptr -> fx_media_sector_cache_size)
782 {
783 12621296 FAT_read_sectors = media_ptr -> fx_media_sector_cache_size;
784 }
785 #else
786
2/2
✓ Branch 93 → 77 taken 10725134 times.
✓ Branch 93 → 94 taken 14864 times.
10739998 for (i = 0; i < media_ptr -> fx_media_sectors_per_FAT; i++)
787 {
788
789 /* Calculate the starting next FAT sector. */
790 10725134 FAT_sector = media_ptr -> fx_media_reserved_sectors + i;
791
792 /* Calculate how many sectors to read. */
793 10725134 FAT_read_sectors = 1;
794 #endif /* FX_DISABLE_CACHE */
795
796 /* Read the FAT sectors directly from the driver. */
797 23352526 media_ptr -> fx_media_driver_request = FX_DRIVER_READ;
798 23352526 media_ptr -> fx_media_driver_status = FX_IO_ERROR;
799 23352526 media_ptr -> fx_media_driver_buffer = media_ptr -> fx_media_memory_buffer;
800 23352526 media_ptr -> fx_media_driver_logical_sector = FAT_sector;
801 23352526 media_ptr -> fx_media_driver_sectors = FAT_read_sectors;
802 23352526 media_ptr -> fx_media_driver_sector_type = FX_FAT_SECTOR;
803
804 /* If trace is enabled, insert this event into the trace buffer. */
805 FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_READ, media_ptr, FAT_sector, FAT_read_sectors, media_ptr -> fx_media_memory_buffer, FX_TRACE_INTERNAL_EVENTS, 0, 0)
806
807 /* Invoke the driver to read the FAT sectors. */
808 23352526 (media_ptr -> fx_media_driver_entry) (media_ptr);
809
810 /* Determine if the read was successful. */
811
4/4
✓ Branch 78 → 79 taken 4 times.
✓ Branch 78 → 81 taken 10725130 times.
✓ Branch 89 → 90 taken 5 times.
✓ Branch 89 → 92 taken 12627387 times.
23352526 if (media_ptr -> fx_media_driver_status != FX_SUCCESS)
812 {
813
814 /* Build the "uninitialize" I/O driver request. */
815 9 media_ptr -> fx_media_driver_request = FX_DRIVER_UNINIT;
816 9 media_ptr -> fx_media_driver_status = FX_IO_ERROR;
817
818 /* If trace is enabled, insert this event into the trace buffer. */
819 FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_UNINIT, media_ptr, 0, 0, 0, FX_TRACE_INTERNAL_EVENTS, 0, 0)
820
821 /* Call the specified I/O driver with the uninitialize request. */
822 9 (media_ptr -> fx_media_driver_entry) (media_ptr);
823
824 9 return(FX_FAT_READ_ERROR);
825 }
826
827 /* Calculate the number of bytes in the buffer. */
828 23352517 bytes_in_buffer = (media_ptr -> fx_media_bytes_per_sector * FAT_read_sectors);
829
830 /* Walk through the sector cache memory to search for available clusters and the first
831 available if not already found. */
832
4/4
✓ Branch 91 → 82 taken 483938770 times.
✓ Branch 91 → 92 taken 10710266 times.
✓ Branch 102 → 93 taken 595139731 times.
✓ Branch 102 → 103 taken 12608985 times.
1102397752 for (j = 0; j < bytes_in_buffer;)
833 {
834
835 /* Check for a 32-bit FAT. */
836
4/4
✓ Branch 82 → 83 taken 430001532 times.
✓ Branch 82 → 84 taken 53937238 times.
✓ Branch 93 → 94 taken 528488569 times.
✓ Branch 93 → 95 taken 66651162 times.
1079078501 if (media_ptr -> fx_media_32_bit_FAT)
837 {
838
839 /* Pickup 32-bit FAT entry. */
840 958490101 FAT_entry = *((ULONG *)&(media_ptr -> fx_media_memory_buffer[j]));
841
842 /* Advance to next FAT entry. */
843 958490101 j = j + 4;
844 }
845 else
846 {
847
848 /* Process a 16-bit FAT entry. */
849 120588400 FAT_entry = (((ULONG)(media_ptr -> fx_media_memory_buffer[j])) & 0xFF) |
850 120588400 ((((ULONG)(media_ptr -> fx_media_memory_buffer[j + 1])) & 0xFF) << 8);
851
852 /* Advance to next FAT entry. */
853 120588400 j = j + 2;
854 }
855
856 /* Determine if the FAT entry is free. */
857
4/4
✓ Branch 85 → 86 taken 480149502 times.
✓ Branch 85 → 88 taken 3789268 times.
✓ Branch 96 → 97 taken 591323018 times.
✓ Branch 96 → 99 taken 3816713 times.
1079078501 if (FAT_entry == FX_FREE_CLUSTER)
858 {
859
860 /* Entry is free, increment available clusters. */
861 1071472520 media_ptr -> fx_media_available_clusters++;
862
863 /* Determine if the starting free cluster has been found yet. */
864
4/4
✓ Branch 86 → 87 taken 14856 times.
✓ Branch 86 → 88 taken 480134646 times.
✓ Branch 97 → 98 taken 18396 times.
✓ Branch 97 → 99 taken 591304622 times.
1071472520 if (media_ptr -> fx_media_cluster_search_start == 0)
865 {
866
867 /* Remember the first free cluster to start further searches from. */
868 33252 media_ptr -> fx_media_cluster_search_start = cluster_number;
869 }
870 }
871
872 /* Increment the cluster number. */
873 1079078501 cluster_number++;
874
875 /* Determine if we have reviewed all FAT entries. */
876
4/4
✓ Branch 88 → 89 taken 14864 times.
✓ Branch 88 → 90 taken 483923906 times.
✓ Branch 99 → 100 taken 18402 times.
✓ Branch 99 → 101 taken 595121329 times.
1079078501 if (cluster_number >= (media_ptr -> fx_media_total_clusters + FX_FAT_ENTRY_START))
877 {
878
879 /* Yes, we have looked at all the FAT entries. */
880
881 /* Ensure that the outer loop terminates as well. */
882 33266 i = media_ptr -> fx_media_sectors_per_FAT;
883 33266 break;
884 }
885 }
886 }
887 }
888
889 /* If there were no free clusters, just set the search pointer to the
890 first cluster number. */
891
4/4
✓ Branch 94 → 95 taken 28 times.
✓ Branch 94 → 96 taken 23764 times.
✓ Branch 105 → 106 taken 29 times.
✓ Branch 105 → 107 taken 29471 times.
53292 if (media_ptr -> fx_media_cluster_search_start == 0)
892 {
893 57 media_ptr -> fx_media_cluster_search_start = FX_FAT_ENTRY_START;
894 }
895
896 /* Setup the current working directory fields to default to the root
897 directory. */
898 53292 media_ptr -> fx_media_default_path.fx_path_directory.fx_dir_entry_name =
899 53292 media_ptr -> fx_media_default_path.fx_path_name_buffer;
900 53292 media_ptr -> fx_media_default_path.fx_path_directory.fx_dir_entry_short_name[0] = 0;
901 53292 media_ptr -> fx_media_default_path.fx_path_directory.fx_dir_entry_name[0] = 0;
902 53292 media_ptr -> fx_media_default_path.fx_path_string[0] = (CHAR)0;
903 53292 media_ptr -> fx_media_default_path.fx_path_string[FX_MAXIMUM_PATH - 1] = (CHAR)0;
904 53292 media_ptr -> fx_media_default_path.fx_path_current_entry = 0;
905
906 #ifndef FX_MEDIA_DISABLE_SEARCH_CACHE
907
908 /* Invalidate the previously found directory entry. */
909 53292 media_ptr -> fx_media_last_found_name[0] = 0;
910 #endif
911
912 #ifndef FX_DISABLE_FORCE_MEMORY_OPERATION
913 /* Initialize the opened file linked list and associated counter. */
914 53292 media_ptr -> fx_media_opened_file_list = FX_NULL;
915 53292 media_ptr -> fx_media_opened_file_count = 0;
916 #endif /* FX_DISABLE_FORCE_MEMORY_OPERATION */
917
918 /* Create the media protection structure if FX_SINGLE_THREAD is not
919 defined. */
920 #ifndef FX_SINGLE_THREAD
921
922 #ifndef FX_DONT_CREATE_MUTEX
923
924 /* Create ThreadX mutex for protection. */
925 29510 tx_mutex_create(&(media_ptr -> fx_media_protect), "FileX Media Mutex", TX_NO_INHERIT);
926 #endif
927
928 #endif
929
930 #ifdef FX_DONT_CREATE_MUTEX
931
932 /* Load the media ID field in the media control block. This allows the FX_PROTECT
933 call to succeed. */
934 media_ptr -> fx_media_id = (ULONG)FX_MEDIA_ID;
935
936 /* Protect against other threads accessing the media. */
937 FX_PROTECT
938 #endif
939
940 /* Lockout interrupts. */
941 29510 FX_DISABLE_INTS
942
943 /* At this point, the media has been opened successfully. Place the
944 media on the linked list of currently opened media. */
945
946 /* Load the media ID field in the media control block. */
947 53292 media_ptr -> fx_media_id = (ULONG)FX_MEDIA_ID;
948
949 /* Place the thread on the list of opened media. First,
950 check for an empty list. */
951
8/8
✓ Branch 96 → 97 taken 6 times.
✓ Branch 96 → 98 taken 11868 times.
✓ Branch 98 → 99 taken 6 times.
✓ Branch 98 → 100 taken 11912 times.
✓ Branch 107 → 108 taken 10 times.
✓ Branch 107 → 109 taken 11898 times.
✓ Branch 109 → 110 taken 15 times.
✓ Branch 109 → 111 taken 17577 times.
53292 if (_fx_system_media_opened_ptr)
952 {
953
954 /* Pickup tail pointer. */
955 37 tail_ptr = _fx_system_media_opened_ptr -> fx_media_opened_previous;
956
957 /* Place the new media in the list. */
958 37 _fx_system_media_opened_ptr -> fx_media_opened_previous = media_ptr;
959 37 tail_ptr -> fx_media_opened_next = media_ptr;
960
961 /* Setup this media's opened links. */
962 37 media_ptr -> fx_media_opened_previous = tail_ptr;
963 37 media_ptr -> fx_media_opened_next = _fx_system_media_opened_ptr;
964 }
965 else
966 {
967
968 /* The opened media list is empty. Add the media to empty list. */
969 53255 _fx_system_media_opened_ptr = media_ptr;
970 53255 media_ptr -> fx_media_opened_next = media_ptr;
971 53255 media_ptr -> fx_media_opened_previous = media_ptr;
972 }
973
974 /* Increment the opened media counter. */
975 53292 _fx_system_media_opened_count++;
976
977 /* Invoke media open callback. */
978
8/8
✓ Branch 99 → 100 taken 2 times.
✓ Branch 99 → 101 taken 11872 times.
✓ Branch 101 → 102 taken 2 times.
✓ Branch 101 → 103 taken 11916 times.
✓ Branch 110 → 111 taken 2 times.
✓ Branch 110 → 112 taken 11906 times.
✓ Branch 112 → 113 taken 3 times.
✓ Branch 112 → 114 taken 17589 times.
53292 if (media_ptr -> fx_media_open_notify)
979 {
980 9 media_ptr -> fx_media_open_notify(media_ptr);
981 }
982
983 /* Restore interrupts. */
984 29510 FX_RESTORE_INTS
985
986 #ifdef FX_DONT_CREATE_MUTEX
987
988 /* Release media protection. */
989 FX_UNPROTECT
990 #endif
991
992 /* Return a successful status. */
993 53292 return(FX_SUCCESS);
994 }
995
996