GCC Code Coverage Report


Directory: common/src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 99.3% 144 / 0 / 145
Functions: 100.0% 1 / 0 / 1
Branches: 98.1% 152 / 0 / 155

fx_utility_logical_sector_read.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 /** Utility */
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_utility.h"
31 #ifdef FX_ENABLE_FAULT_TOLERANT
32 #include "fx_fault_tolerant.h"
33 #endif /* FX_ENABLE_FAULT_TOLERANT */
34
35
36 /**************************************************************************/
37 /* */
38 /* FUNCTION RELEASE */
39 /* */
40 /* _fx_utility_logical_sector_read PORTABLE C */
41 /* 6.2.0 */
42 /* AUTHOR */
43 /* */
44 /* William E. Lamie, Microsoft Corporation */
45 /* */
46 /* DESCRIPTION */
47 /* */
48 /* This function handles logical sector read requests for all FileX */
49 /* components. If the logical sector is currently in the logical */
50 /* sector cache, the function simply sets the appropriate pointer and */
51 /* returns a successful status to the caller. Otherwise, physical I/O */
52 /* is requested through the corresponding I/O driver. */
53 /* */
54 /* Note: Conversion of the logical sector is done inside the driver. */
55 /* This results in a performance boost for FLASH or RAM media */
56 /* devices. */
57 /* */
58 /* INPUT */
59 /* */
60 /* media_ptr Media control block pointer */
61 /* logical_sector Logical sector number */
62 /* buffer_ptr Pointer of receiving buffer */
63 /* sectors Number of sectors to read */
64 /* sector_type Type of sector(s) to read */
65 /* */
66 /* OUTPUT */
67 /* */
68 /* return status */
69 /* */
70 /* CALLS */
71 /* */
72 /* _fx_utility_logical_sector_cache_entry_read */
73 /* Read logical sector cache */
74 /* _fx_utility_logical_sector_flush Flush and invalidate sectors */
75 /* that overlap with non-cache */
76 /* sector I/O. */
77 /* _fx_utility_memory_copy Copy cache sector */
78 /* _fx_fault_tolerant_read_directory_sector */
79 /* Read directory sector */
80 /* */
81 /* CALLED BY */
82 /* */
83 /* FileX System Functions */
84 /* */
85 /**************************************************************************/
86 937834648 UINT _fx_utility_logical_sector_read(FX_MEDIA *media_ptr, ULONG64 logical_sector,
87 VOID *buffer_ptr, ULONG sectors, UCHAR sector_type)
88 {
89 #ifndef FX_DISABLE_CACHE
90 FX_CACHED_SECTOR *cache_entry;
91 FX_CACHED_SECTOR *previous_cache_entry;
92 ULONG64 end_sector;
93 #endif /* FX_DISABLE_CACHE */
94
95 #ifdef FX_ENABLE_FAULT_TOLERANT
96 UINT status;
97 #endif /* FX_ENABLE_FAULT_TOLERANT */
98
99
100 #ifndef FX_MEDIA_STATISTICS_DISABLE
101
102 /* Determine if the request is for FAT sector. */
103
2/2
✓ Branch 2 → 3 taken 186336055 times.
✓ Branch 2 → 4 taken 751498593 times.
937834648 if (sector_type == FX_FAT_SECTOR)
104 {
105
106 /* Increment the number of FAT sector reads. */
107 186336055 media_ptr -> fx_media_fat_sector_reads++;
108 }
109
110 /* Increment the number of logical sectors read. */
111 937834648 media_ptr -> fx_media_logical_sector_reads++;
112 #endif
113
114 /* Extended port-specific processing macro, which is by default defined to white space. */
115
4/4
✓ Branch 4 → 5 taken 1042936 times.
✓ Branch 4 → 7 taken 936791712 times.
✓ Branch 5 → 6 taken 411180 times.
✓ Branch 5 → 7 taken 631756 times.
937834648 FX_UTILITY_LOGICAL_SECTOR_READ_EXTENSION
116
117 #ifndef FX_DISABLE_CACHE
118 /* Determine if the request is for the internal media buffer area. */
119
3/3
✓ Branch 7 → 8 taken 488933706 times.
✓ Branch 7 → 30 taken 15922 times.
✓ Branch 7 → 36 taken 1414310 times.
490363938 if ((((UCHAR *)buffer_ptr) >= media_ptr -> fx_media_memory_buffer) &&
120
3/3
✓ Branch 8 → 9 taken 486812679 times.
✓ Branch 8 → 30 taken 41 times.
✓ Branch 8 → 36 taken 2120986 times.
488933706 (((UCHAR *)buffer_ptr) <= media_ptr -> fx_media_sector_cache_end))
121 {
122
123 /* Internal cache buffer is requested. */
124
125 /* Examine the logical sector cache. */
126 486812679 cache_entry = _fx_utility_logical_sector_cache_entry_read(media_ptr, logical_sector, &previous_cache_entry);
127
128 /* Was the sector found? */
129
2/2
✓ Branch 10 → 11 taken 455973071 times.
✓ Branch 10 → 12 taken 30839608 times.
486812679 if (cache_entry == FX_NULL)
130 {
131
132 /* Yes, the sector was found. Return success! */
133 455973071 return(FX_SUCCESS);
134 }
135
136 /* At this point, we need to read in a sector from the media. */
137
138 #ifndef FX_MEDIA_STATISTICS_DISABLE
139
140 /* Increment the number of logical sectors cache read misses. */
141 30839608 media_ptr -> fx_media_logical_sector_cache_read_misses++;
142 #endif
143
144 #ifndef FX_MEDIA_STATISTICS_DISABLE
145
146 /* If trace is enabled, insert this event into the trace buffer. */
147 FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_LOG_SECTOR_CACHE_MISS, media_ptr, logical_sector, media_ptr -> fx_media_logical_sector_cache_read_misses, media_ptr -> fx_media_sector_cache_size, FX_TRACE_INTERNAL_EVENTS, 0, 0)
148 #else
149
150 /* If trace is enabled, insert this event into the trace buffer. */
151 FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_LOG_SECTOR_CACHE_MISS, media_ptr, logical_sector, 0, media_ptr -> fx_media_sector_cache_size, FX_TRACE_INTERNAL_EVENTS, 0, 0)
152 #endif
153
154 /* First, check and see if the last used entry has been
155 modified. */
156
2/2
✓ Branch 12 → 13 taken 14614298 times.
✓ Branch 12 → 20 taken 16225310 times.
30839608 if ((cache_entry -> fx_cached_sector_valid) &&
157
2/2
✓ Branch 13 → 14 taken 706309 times.
✓ Branch 13 → 20 taken 13907989 times.
14614298 (cache_entry -> fx_cached_sector_buffer_dirty))
158 {
159
160 /* Yes, we need to flush this buffer out to the physical media
161 before we read in the new buffer. */
162
163 #ifndef FX_MEDIA_STATISTICS_DISABLE
164
165 /* Increment the number of driver write sector(s) requests. */
166 706309 media_ptr -> fx_media_driver_write_requests++;
167 #endif
168
169 /* Build write request to the driver. */
170 706309 media_ptr -> fx_media_driver_request = FX_DRIVER_WRITE;
171 706309 media_ptr -> fx_media_driver_status = FX_IO_ERROR;
172 706309 media_ptr -> fx_media_driver_buffer = cache_entry -> fx_cached_sector_memory_buffer;
173 #ifdef FX_DRIVER_USE_64BIT_LBA
174 media_ptr -> fx_media_driver_logical_sector = cache_entry -> fx_cached_sector;
175 #else
176 706309 media_ptr -> fx_media_driver_logical_sector = (ULONG)cache_entry -> fx_cached_sector;
177 #endif
178 706309 media_ptr -> fx_media_driver_sectors = 1;
179 706309 media_ptr -> fx_media_driver_sector_type = cache_entry -> fx_cached_sector_type;
180
181 /* Determine if the sector is a data sector or a system sector. */
182
2/2
✓ Branch 14 → 15 taken 546617 times.
✓ Branch 14 → 16 taken 159692 times.
706309 if (cache_entry -> fx_cached_sector_type != FX_DATA_SECTOR)
183 {
184
185 /* System sector is present. */
186 546617 media_ptr -> fx_media_driver_system_write = FX_TRUE;
187 }
188
189 /* If trace is enabled, insert this event into the trace buffer. */
190 FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_WRITE, media_ptr, cache_entry -> fx_cached_sector, 1, cache_entry -> fx_cached_sector_memory_buffer, FX_TRACE_INTERNAL_EVENTS, 0, 0)
191
192 /* Invoke the driver to write the sector. */
193 706309 (media_ptr -> fx_media_driver_entry) (media_ptr);
194
195 /* Clear the system write flag. */
196 706309 media_ptr -> fx_media_driver_system_write = FX_FALSE;
197
198 /* Check for successful completion. */
199
2/2
✓ Branch 17 → 18 taken 65588 times.
✓ Branch 17 → 19 taken 640721 times.
706309 if (media_ptr -> fx_media_driver_status)
200 {
201
202 /* Error writing a cached sector out. Return the
203 error status. */
204 65588 return(media_ptr -> fx_media_driver_status);
205 }
206
207 /* Clear the buffer dirty flag since it has been flushed
208 out. */
209 640721 cache_entry -> fx_cached_sector_buffer_dirty = FX_FALSE;
210
211 /* Decrement the number of outstanding dirty cache entries. */
212 640721 media_ptr -> fx_media_sector_cache_dirty_count--;
213 }
214
215 /* At this point, we can go out and setup this cached sector
216 entry. */
217
218 /* Compare against logical sector to make sure it is valid. */
219
2/2
✓ Branch 20 → 21 taken 34 times.
✓ Branch 20 → 22 taken 30773986 times.
30774020 if (logical_sector >= media_ptr -> fx_media_total_sectors)
220 {
221 34 return(FX_SECTOR_INVALID);
222 }
223
224 #ifndef FX_MEDIA_STATISTICS_DISABLE
225
226 /* Increment the number of driver read sector(s) requests. */
227 30773986 media_ptr -> fx_media_driver_read_requests++;
228 #endif
229
230 /* Build Read request to the driver. */
231 30773986 media_ptr -> fx_media_driver_request = FX_DRIVER_READ;
232 30773986 media_ptr -> fx_media_driver_status = FX_IO_ERROR;
233 30773986 media_ptr -> fx_media_driver_buffer = cache_entry -> fx_cached_sector_memory_buffer;
234 #ifdef FX_DRIVER_USE_64BIT_LBA
235 media_ptr -> fx_media_driver_logical_sector = logical_sector;
236 #else
237 30773986 media_ptr -> fx_media_driver_logical_sector = (ULONG)logical_sector;
238 #endif
239 30773986 media_ptr -> fx_media_driver_sectors = 1;
240 30773986 media_ptr -> fx_media_driver_sector_type = sector_type;
241
242 /* Determine if the sector is a data sector or a system sector. */
243
2/2
✓ Branch 22 → 23 taken 9340719 times.
✓ Branch 22 → 24 taken 21433267 times.
30773986 if (sector_type == FX_DATA_SECTOR)
244 {
245
246 /* Data sector is present. */
247 9340719 media_ptr -> fx_media_driver_data_sector_read = FX_TRUE;
248 }
249
250 /* If trace is enabled, insert this event into the trace buffer. */
251 FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_READ, media_ptr, logical_sector, 1, cache_entry -> fx_cached_sector_memory_buffer, FX_TRACE_INTERNAL_EVENTS, 0, 0)
252
253 /* Invoke the driver to read the sector. */
254 30773986 (media_ptr -> fx_media_driver_entry) (media_ptr);
255
256 /* Clear data sector is present flag. */
257 30773986 media_ptr -> fx_media_driver_data_sector_read = FX_FALSE;
258
259 /* Determine if the read was successful. */
260
3/3
✓ Branch 25 → 26 taken 26238349 times.
✓ Branch 25 → 28 taken 1940619 times.
✓ Branch 25 → 34 taken 2595018 times.
30773986 if (media_ptr -> fx_media_driver_status == FX_SUCCESS)
261 {
262
263 /* Remember the sector number. */
264 26238349 cache_entry -> fx_cached_sector = logical_sector;
265
266 /* Make the cache entry valid. */
267 26238349 cache_entry -> fx_cached_sector_valid = FX_TRUE;
268
269 /* Remember the sector type. */
270 26238349 cache_entry -> fx_cached_sector_type = sector_type;
271
272 /* Place this entry that the head of the cached sector
273 list. */
274
275 /* Determine if we need to update the last used list. */
276
3/3
✓ Branch 26 → 27 taken 9637868 times.
✓ Branch 26 → 28 taken 10638239 times.
✓ Branch 26 → 29 taken 5962242 times.
26238349 if (previous_cache_entry)
277 {
278
279 /* Yes, the current entry is not at the front of the list
280 so we need to change the order. */
281
282 /* Link the previous entry to this entry's next pointer. */
283 9637868 previous_cache_entry -> fx_cached_sector_next_used =
284 9637868 cache_entry -> fx_cached_sector_next_used;
285
286 /* Place this entry at the head of the list. */
287 9637868 cache_entry -> fx_cached_sector_next_used =
288 9637868 media_ptr -> fx_media_sector_cache_list_ptr;
289 9637868 media_ptr -> fx_media_sector_cache_list_ptr = cache_entry;
290 }
291
292 #ifdef FX_ENABLE_FAULT_TOLERANT
293
2/2
✓ Branch 28 → 29 taken 13997913 times.
✓ Branch 28 → 35 taken 6255381 times.
20253294 if (media_ptr -> fx_media_fault_tolerant_enabled &&
294
4/4
✓ Branch 29 → 30 taken 8593567 times.
✓ Branch 29 → 35 taken 5404346 times.
✓ Branch 30 → 31 taken 1203125 times.
✓ Branch 30 → 35 taken 7390442 times.
13997913 (media_ptr -> fx_media_fault_tolerant_state & FX_FAULT_TOLERANT_STATE_STARTED) &&
295 (sector_type == FX_DIRECTORY_SECTOR))
296 {
297
298 /* Read sector from log file. */
299 1203125 status = _fx_fault_tolerant_read_directory_sector(media_ptr, logical_sector, cache_entry -> fx_cached_sector_memory_buffer, 1);
300
301 /* Check for successful completion. */
302
2/2
✓ Branch 32 → 33 taken 2 times.
✓ Branch 32 → 35 taken 1203123 times.
1203125 if (status)
303 {
304
305 /* Return the error status. */
306 2 return(status);
307 }
308 }
309 #endif /* FX_ENABLE_FAULT_TOLERANT */
310 }
311 else
312 {
313
314 /* Invalidate the cache entry on read errors. */
315 4535637 cache_entry -> fx_cached_sector_valid = FX_FALSE;
316
317 /* Put all ones in the sector value. */
318 4535637 cache_entry -> fx_cached_sector = (~(ULONG64)0);
319 }
320
321 /* Simply setup the pointer to this buffer and return. */
322 30773984 media_ptr -> fx_media_memory_buffer = cache_entry -> fx_cached_sector_memory_buffer;
323
324 /* Return the driver status. */
325 30773984 return(media_ptr -> fx_media_driver_status);
326 }
327 #else
328
7/9
✓ Branch 7 → 8 taken 255653799 times.
✓ Branch 7 → 11 taken 3382861 times.
✓ Branch 7 → 17 taken 188022870 times.
✓ Branch 8 → 9 taken 255653799 times.
✗ Branch 8 → 11 not taken.
✗ Branch 8 → 17 not taken.
✓ Branch 9 → 10 taken 255653779 times.
✓ Branch 9 → 11 taken 10 times.
✓ Branch 9 → 17 taken 10 times.
447059530 if ((logical_sector == media_ptr -> fx_media_memory_buffer_sector) && (sectors == 1) && (buffer_ptr == media_ptr -> fx_media_memory_buffer))
329 {
330 #ifdef FX_ENABLE_FAULT_TOLERANT
331
2/2
✓ Branch 10 → 11 taken 243900138 times.
✓ Branch 10 → 16 taken 6903234 times.
250803372 if (media_ptr -> fx_media_fault_tolerant_enabled &&
332
4/4
✓ Branch 11 → 12 taken 28486012 times.
✓ Branch 11 → 16 taken 215414126 times.
✓ Branch 12 → 13 taken 1747163 times.
✓ Branch 12 → 16 taken 26738849 times.
243900138 (media_ptr -> fx_media_fault_tolerant_state & FX_FAULT_TOLERANT_STATE_STARTED) &&
333 (sector_type == FX_DIRECTORY_SECTOR))
334 {
335
336 /* Read sector from log file. */
337 1747163 status = _fx_fault_tolerant_read_directory_sector(media_ptr, logical_sector, buffer_ptr, 1);
338
339 /* Check for successful completion. */
340
1/2
✗ Branch 14 → 15 not taken.
✓ Branch 14 → 16 taken 1747163 times.
1747163 if (status)
341 {
342
343 /* Return the error status. */
344 ✗ return(status);
345 }
346 }
347 #endif /* FX_ENABLE_FAULT_TOLERANT */
348 255653779 return(FX_SUCCESS);
349 }
350 #endif
351 else
352 {
353
354 /* Direct I/O to application buffer area. */
355
356 /* Compare against logical sector to make sure it is valid. */
357
8/8
✓ Branch 11 → 12 taken 4 times.
✓ Branch 11 → 13 taken 3382867 times.
✓ Branch 17 → 18 taken 14 times.
✓ Branch 17 → 19 taken 188022866 times.
✓ Branch 30 → 31 taken 3 times.
✓ Branch 30 → 32 taken 15960 times.
✓ Branch 36 → 37 taken 4 times.
✓ Branch 36 → 38 taken 3535292 times.
194957010 if ((logical_sector + sectors - 1) > (ULONG)media_ptr -> fx_media_total_sectors)
358 {
359 25 return(FX_SECTOR_INVALID);
360 }
361
362 #ifndef FX_DISABLE_CACHE
363 /* Attempt to fill the beginning of the buffer from cached sectors. */
364
4/4
✓ Branch 38 → 33 taken 15966 times.
✓ Branch 38 → 39 taken 30 times.
✓ Branch 44 → 39 taken 3784674 times.
✓ Branch 44 → 45 taken 63237 times.
3863907 while (sectors)
365 {
366
367 /* Determine if the sector is in the cache. */
368
4/4
✓ Branch 34 → 35 taken 15930 times.
✓ Branch 34 → 36 taken 36 times.
✓ Branch 40 → 41 taken 3472055 times.
✓ Branch 40 → 42 taken 312619 times.
3800640 if (_fx_utility_logical_sector_cache_entry_read(media_ptr, logical_sector, &previous_cache_entry))
369 {
370
371 /* Not in the cache - get out of the loop! */
372 3487985 break;
373 }
374
375 /* Yes, sector is in the cache. Copy the data from the cache to the destination buffer. */
376 312655 _fx_utility_memory_copy(media_ptr -> fx_media_memory_buffer, buffer_ptr, media_ptr -> fx_media_bytes_per_sector); /* Use case of memcpy is verified. */
377
378 /* Advance the destination buffer. */
379 312655 buffer_ptr = ((UCHAR *)buffer_ptr) + media_ptr -> fx_media_bytes_per_sector;
380
381 /* Advance the sector and decrement the number of sectors left. */
382 312655 logical_sector++;
383 312655 sectors--;
384 }
385
386 /* Calculate the end sector. */
387 3551252 end_sector = logical_sector + sectors - 1;
388
389 /* Attempt to fill the end of the buffer from the opposite direction. */
390
4/4
✓ Branch 45 → 40 taken 15963 times.
✓ Branch 45 → 46 taken 30 times.
✓ Branch 51 → 46 taken 3542730 times.
✓ Branch 51 → 52 taken 63237 times.
3621960 while (sectors)
391 {
392
393 /* Determine if the sector is in the cache. */
394
4/4
✓ Branch 41 → 42 taken 15930 times.
✓ Branch 41 → 43 taken 33 times.
✓ Branch 47 → 48 taken 3472055 times.
✓ Branch 47 → 49 taken 70675 times.
3558693 if (_fx_utility_logical_sector_cache_entry_read(media_ptr, end_sector, &previous_cache_entry))
395 {
396
397 /* Not in the cache - get out of the loop! */
398 3487985 break;
399 }
400
401 /* Yes, sector is in the cache. Copy the data from the cache to the destination buffer. */
402 70708 _fx_utility_memory_copy(media_ptr -> fx_media_memory_buffer, /* Use case of memcpy is verified. */
403 70708 ((UCHAR *)buffer_ptr) + ((sectors - 1) * media_ptr -> fx_media_bytes_per_sector),
404 70708 media_ptr -> fx_media_bytes_per_sector);
405
406 /* Move sector to previous sector and decrement the number of sectors left. */
407 70708 end_sector--;
408 70708 sectors--;
409 }
410
411 /* Determine if there are still sectors left to read. */
412
4/4
✓ Branch 46 → 47 taken 30 times.
✓ Branch 46 → 48 taken 15930 times.
✓ Branch 52 → 53 taken 63237 times.
✓ Branch 52 → 54 taken 3472055 times.
3551252 if (sectors == 0)
413 {
414
415 /* No more sectors to read - return success! */
416 63267 return(FX_SUCCESS);
417 }
418
419 /* Flush and invalidate any entries in the cache that are in this direct I/O read request range. */
420 3487985 _fx_utility_logical_sector_flush(media_ptr, logical_sector, (ULONG64) sectors, FX_TRUE);
421 #endif /* FX_DISABLE_CACHE */
422
423 #ifndef FX_MEDIA_STATISTICS_DISABLE
424
425 /* Increment the number of driver read sector(s) requests. */
426 194893718 media_ptr -> fx_media_driver_read_requests++;
427 #endif
428
429 /* Build read request to the driver. */
430 194893718 media_ptr -> fx_media_driver_request = FX_DRIVER_READ;
431 194893718 media_ptr -> fx_media_driver_status = FX_IO_ERROR;
432 194893718 media_ptr -> fx_media_driver_buffer = buffer_ptr;
433 #ifdef FX_DRIVER_USE_64BIT_LBA
434 media_ptr -> fx_media_driver_logical_sector = logical_sector;
435 #else
436 194893718 media_ptr -> fx_media_driver_logical_sector = (ULONG)logical_sector;
437 #endif
438 194893718 media_ptr -> fx_media_driver_sectors = sectors;
439 194893718 media_ptr -> fx_media_driver_sector_type = sector_type;
440
441 /* Determine if the sector is a data sector or a system sector. */
442
8/8
✓ Branch 13 → 14 taken 1334886 times.
✓ Branch 13 → 15 taken 2047981 times.
✓ Branch 19 → 20 taken 90414068 times.
✓ Branch 19 → 21 taken 97608798 times.
✓ Branch 49 → 50 taken 15903 times.
✓ Branch 49 → 51 taken 27 times.
✓ Branch 55 → 56 taken 3472015 times.
✓ Branch 55 → 57 taken 40 times.
194893718 if (sector_type == FX_DATA_SECTOR)
443 {
444
445 /* Data sector is present. */
446 95236872 media_ptr -> fx_media_driver_data_sector_read = FX_TRUE;
447 }
448
449 /* If trace is enabled, insert this event into the trace buffer. */
450 FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_READ, media_ptr, logical_sector, sectors, buffer_ptr, FX_TRACE_INTERNAL_EVENTS, 0, 0)
451
452 /* Invoke the driver to read the sector. */
453 194893718 (media_ptr -> fx_media_driver_entry) (media_ptr);
454
455 /* Clear data sector is present flag. */
456 194893718 media_ptr -> fx_media_driver_data_sector_read = FX_FALSE;
457
458 #ifdef FX_DISABLE_CACHE
459
12/12
✓ Branch 16 → 17 taken 3341691 times.
✓ Branch 16 → 20 taken 41176 times.
✓ Branch 17 → 18 taken 3339191 times.
✓ Branch 17 → 20 taken 2500 times.
✓ Branch 18 → 19 taken 3331073 times.
✓ Branch 18 → 20 taken 8118 times.
✓ Branch 22 → 23 taken 187994578 times.
✓ Branch 22 → 32 taken 28288 times.
✓ Branch 23 → 24 taken 184469588 times.
✓ Branch 23 → 32 taken 3524990 times.
✓ Branch 24 → 25 taken 184461429 times.
✓ Branch 24 → 32 taken 8159 times.
191405733 if ((media_ptr -> fx_media_driver_status == FX_SUCCESS) && (sectors == 1) && (buffer_ptr == media_ptr -> fx_media_memory_buffer))
460 {
461 187792502 media_ptr -> fx_media_memory_buffer_sector = logical_sector;
462 #ifdef FX_ENABLE_FAULT_TOLERANT
463
2/2
✓ Branch 25 → 26 taken 179890035 times.
✓ Branch 25 → 31 taken 4571394 times.
184461429 if (media_ptr -> fx_media_fault_tolerant_enabled &&
464
4/4
✓ Branch 26 → 27 taken 164486049 times.
✓ Branch 26 → 31 taken 15403986 times.
✓ Branch 27 → 28 taken 80084790 times.
✓ Branch 27 → 31 taken 84401259 times.
179890035 (media_ptr -> fx_media_fault_tolerant_state & FX_FAULT_TOLERANT_STATE_STARTED) &&
465 (sector_type == FX_DIRECTORY_SECTOR))
466 {
467
468 /* Read sector from log file. */
469 80084790 status = _fx_fault_tolerant_read_directory_sector(media_ptr, logical_sector, buffer_ptr, 1);
470
471 /* Check for successful completion. */
472
2/2
✓ Branch 29 → 30 taken 4 times.
✓ Branch 29 → 31 taken 80084786 times.
80084790 if (status)
473 {
474
475 /* Return the error status. */
476 4 return(status);
477 }
478 }
479 #endif /* FX_ENABLE_FAULT_TOLERANT */
480 187792498 return(FX_SUCCESS);
481 }
482 #endif /* FX_DISABLE_CACHE */
483
484 #ifndef FX_DISABLE_DIRECT_DATA_READ_CACHE_FILL
485
486 /* Determine if the read was successful and if number of sectors just read will
487 reasonably fit into the cache. */
488
8/8
✓ Branch 52 → 53 taken 15924 times.
✓ Branch 52 → 74 taken 6 times.
✓ Branch 53 → 54 taken 3837 times.
✓ Branch 53 → 74 taken 12087 times.
✓ Branch 58 → 59 taken 3472047 times.
✓ Branch 58 → 78 taken 8 times.
✓ Branch 59 → 60 taken 45731 times.
✓ Branch 59 → 78 taken 3426316 times.
3487985 if ((media_ptr -> fx_media_driver_status == FX_SUCCESS) && (sectors < (media_ptr -> fx_media_sector_cache_size / 4)))
489 {
490
491 /* Yes, read of direct sectors was successful. */
492
493 /* Copy the sectors directly read into the cache so they are available on
494 subsequent read requests. */
495
4/4
✓ Branch 73 → 55 taken 10653 times.
✓ Branch 73 → 74 taken 3831 times.
✓ Branch 77 → 61 taken 159022 times.
✓ Branch 77 → 78 taken 45725 times.
219231 while (sectors)
496 {
497
498 /* Attempt to read the cache entry. */
499 169675 cache_entry = _fx_utility_logical_sector_cache_entry_read(media_ptr, logical_sector, &previous_cache_entry);
500
501 /* Extended port-specific processing macro, which is by default defined to white space. */
502
8/8
✓ Branch 56 → 57 taken 12 times.
✓ Branch 56 → 59 taken 10641 times.
✓ Branch 57 → 58 taken 3 times.
✓ Branch 57 → 59 taken 9 times.
✓ Branch 62 → 63 taken 4 times.
✓ Branch 62 → 65 taken 159018 times.
✓ Branch 63 → 64 taken 2 times.
✓ Branch 63 → 65 taken 2 times.
169675 FX_UTILITY_LOGICAL_SECTOR_READ_EXTENSION_1
503
504 /* At this point, a cache entry should always be present since we invalidated
505 the cache over this sector range previously. In any case, check for the error
506 condition. */
507
4/4
✓ Branch 59 → 60 taken 3 times.
✓ Branch 59 → 61 taken 10650 times.
✓ Branch 65 → 66 taken 2 times.
✓ Branch 65 → 67 taken 159020 times.
169675 if (cache_entry == FX_NULL)
508 {
509
510 /* This case should never happen, however, if it does simply give up on updating the
511 cache with the sectors from the direct read. */
512 5 return(FX_SUCCESS);
513 }
514
515 /* Determine if the cache entry is dirty and needs to be written out before it is used. */
516
4/4
✓ Branch 61 → 62 taken 10299 times.
✓ Branch 61 → 69 taken 351 times.
✓ Branch 67 → 68 taken 16037 times.
✓ Branch 67 → 73 taken 142983 times.
169670 if ((cache_entry -> fx_cached_sector_valid) &&
517
4/4
✓ Branch 62 → 63 taken 396 times.
✓ Branch 62 → 69 taken 9903 times.
✓ Branch 68 → 69 taken 156 times.
✓ Branch 68 → 73 taken 15881 times.
26336 (cache_entry -> fx_cached_sector_buffer_dirty))
518 {
519
520 /* Yes, we need to flush this buffer out to the physical media
521 before we read in the new buffer. */
522
523 #ifndef FX_MEDIA_STATISTICS_DISABLE
524
525 /* Increment the number of driver write sector(s) requests. */
526 552 media_ptr -> fx_media_driver_write_requests++;
527 #endif
528
529 /* Build write request to the driver. */
530 552 media_ptr -> fx_media_driver_request = FX_DRIVER_WRITE;
531 552 media_ptr -> fx_media_driver_status = FX_IO_ERROR;
532 552 media_ptr -> fx_media_driver_buffer = cache_entry -> fx_cached_sector_memory_buffer;
533 #ifdef FX_DRIVER_USE_64BIT_LBA
534 media_ptr -> fx_media_driver_logical_sector = cache_entry -> fx_cached_sector;
535 #else
536 552 media_ptr -> fx_media_driver_logical_sector = (ULONG)cache_entry -> fx_cached_sector;
537 #endif
538 552 media_ptr -> fx_media_driver_sectors = 1;
539 552 media_ptr -> fx_media_driver_sector_type = cache_entry -> fx_cached_sector_type;
540
541 /* Only data sectors may be dirty when FX_FAULT_TOLERANT is defined */
542 #ifndef FX_FAULT_TOLERANT
543 /* Determine if the sector is a data sector or a system sector. */
544
2/2
✓ Branch 63 → 64 taken 132 times.
✓ Branch 63 → 65 taken 264 times.
396 if (cache_entry -> fx_cached_sector_type != FX_DATA_SECTOR)
545 {
546
547 /* System sector is present. */
548 132 media_ptr -> fx_media_driver_system_write = FX_TRUE;
549 }
550 #endif /* FX_FAULT_TOLERANT */
551
552 /* If trace is enabled, insert this event into the trace buffer. */
553 FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_WRITE, media_ptr, cache_entry -> fx_cached_sector, 1, cache_entry -> fx_cached_sector_memory_buffer, FX_TRACE_INTERNAL_EVENTS, 0, 0)
554
555 /* Invoke the driver to write the sector. */
556 552 (media_ptr -> fx_media_driver_entry) (media_ptr);
557
558 /* Clear the system write flag. */
559 552 media_ptr -> fx_media_driver_system_write = FX_FALSE;
560
561 /* Check for successful completion. */
562
4/4
✓ Branch 66 → 67 taken 3 times.
✓ Branch 66 → 68 taken 393 times.
✓ Branch 70 → 71 taken 4 times.
✓ Branch 70 → 72 taken 152 times.
552 if (media_ptr -> fx_media_driver_status)
563 {
564
565 /* Error writing a cached sector out. Return the
566 error status. */
567 7 return(media_ptr -> fx_media_driver_status);
568 }
569
570 /* Clear the buffer dirty flag since it has been flushed
571 out. */
572 545 cache_entry -> fx_cached_sector_buffer_dirty = FX_FALSE;
573
574 /* Decrement the number of outstanding dirty cache entries. */
575 545 media_ptr -> fx_media_sector_cache_dirty_count--;
576 }
577
578 /* Now setup the cache entry with information from the new sector. */
579
580 /* Remember the sector number. */
581 169663 cache_entry -> fx_cached_sector = logical_sector;
582
583 /* Make the cache entry valid. */
584 169663 cache_entry -> fx_cached_sector_valid = FX_TRUE;
585
586 /* Remember the sector type. */
587 169663 cache_entry -> fx_cached_sector_type = sector_type;
588
589 /* Place this entry that the head of the cached sector
590 list. */
591
592 /* Determine if we need to update the last used list. */
593
4/4
✓ Branch 69 → 70 taken 102 times.
✓ Branch 69 → 71 taken 10545 times.
✓ Branch 73 → 74 taken 23856 times.
✓ Branch 73 → 75 taken 135160 times.
169663 if (previous_cache_entry)
594 {
595
596 /* Yes, the current entry is not at the front of the list
597 so we need to change the order. */
598
599 /* Link the previous entry to this entry's next pointer. */
600 23958 previous_cache_entry -> fx_cached_sector_next_used =
601 23958 cache_entry -> fx_cached_sector_next_used;
602
603 /* Place this entry at the head of the list. */
604 23958 cache_entry -> fx_cached_sector_next_used =
605 23958 media_ptr -> fx_media_sector_cache_list_ptr;
606 23958 media_ptr -> fx_media_sector_cache_list_ptr = cache_entry;
607 }
608
609 /* Copy the data from the destination buffer to the cache entry. */
610 169663 _fx_utility_memory_copy(buffer_ptr, /* Use case of memcpy is verified. */
611 cache_entry -> fx_cached_sector_memory_buffer,
612 169663 media_ptr -> fx_media_bytes_per_sector);
613
614 /* Advance the destination buffer. */
615 169663 buffer_ptr = ((UCHAR *)buffer_ptr) + media_ptr -> fx_media_bytes_per_sector;
616
617 /* Advance the source sector and decrement the sector count. */
618 169663 logical_sector++;
619 169663 sectors--;
620 }
621 }
622 #endif
623
624 /* Return the driver status. */
625 7101204 return(media_ptr -> fx_media_driver_status);
626 }
627 }
628
629