GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lx_nor_flash_logical_sector_find.c Lines: 112 124 90.3 %
Date: 2024-03-11 05:20:25 Branches: 53 62 85.5 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 *
4
 * This program and the accompanying materials are made available under the
5
 * terms of the MIT License which is available at
6
 * https://opensource.org/licenses/MIT.
7
 *
8
 * SPDX-License-Identifier: MIT
9
 **************************************************************************/
10
11
12
/**************************************************************************/
13
/**************************************************************************/
14
/**                                                                       */
15
/** LevelX Component                                                      */
16
/**                                                                       */
17
/**   NOR Flash                                                           */
18
/**                                                                       */
19
/**************************************************************************/
20
/**************************************************************************/
21
22
#define LX_SOURCE_CODE
23
24
25
/* Disable ThreadX error checking.  */
26
27
#ifndef LX_DISABLE_ERROR_CHECKING
28
#define LX_DISABLE_ERROR_CHECKING
29
#endif
30
31
32
/* Include necessary system files.  */
33
34
#include "lx_api.h"
35
36
37
/**************************************************************************/
38
/*                                                                        */
39
/*  FUNCTION                                               RELEASE        */
40
/*                                                                        */
41
/*    _lx_nor_flash_logical_sector_find                   PORTABLE C      */
42
/*                                                           6.3.0        */
43
/*  AUTHOR                                                                */
44
/*                                                                        */
45
/*    William E. Lamie, Microsoft Corporation                             */
46
/*                                                                        */
47
/*  DESCRIPTION                                                           */
48
/*                                                                        */
49
/*    This function attempts to find the specified logical sector in      */
50
/*    the NOR flash.                                                      */
51
/*                                                                        */
52
/*  INPUT                                                                 */
53
/*                                                                        */
54
/*    nor_flash                             NOR flash instance            */
55
/*    logical_sector                        Logical sector number         */
56
/*    superceded_check                      Check for sector being        */
57
/*                                            superceded (can happen if   */
58
/*                                            on interruptions of sector  */
59
/*                                            write)                      */
60
/*    physical_sector_map_entry             Destination for physical      */
61
/*                                            sector map entry address    */
62
/*    physical_sector_address               Destination for physical      */
63
/*                                            sector data                 */
64
/*                                                                        */
65
/*  OUTPUT                                                                */
66
/*                                                                        */
67
/*    return status                                                       */
68
/*                                                                        */
69
/*  CALLS                                                                 */
70
/*                                                                        */
71
/*    _lx_nor_flash_driver_read             Driver flash sector read      */
72
/*    _lx_nor_flash_driver_write            Driver flash sector write     */
73
/*    _lx_nor_flash_system_error            Internal system error handler */
74
/*                                                                        */
75
/*  CALLED BY                                                             */
76
/*                                                                        */
77
/*    Internal LevelX                                                     */
78
/*                                                                        */
79
/*  RELEASE HISTORY                                                       */
80
/*                                                                        */
81
/*    DATE              NAME                      DESCRIPTION             */
82
/*                                                                        */
83
/*  05-19-2020     William E. Lamie         Initial Version 6.0           */
84
/*  09-30-2020     William E. Lamie         Modified comment(s),          */
85
/*                                            resulting in version 6.1    */
86
/*  06-02-2021     Bhupendra Naphade        Modified comment(s),          */
87
/*                                            resulting in version 6.1.7  */
88
/*  10-31-2023     Xiuwen Cai               Modified comment(s),          */
89
/*                                            added mapping bitmap cache, */
90
/*                                            added obsolete count cache, */
91
/*                                            optimized full obsoleted    */
92
/*                                            block searching logic,      */
93
/*                                            resulting in version 6.3.0  */
94
/*                                                                        */
95
/**************************************************************************/
96
5676
UINT  _lx_nor_flash_logical_sector_find(LX_NOR_FLASH *nor_flash, ULONG logical_sector, ULONG superceded_check, ULONG **physical_sector_map_entry, ULONG **physical_sector_address)
97
{
98
99
ULONG                               *block_word_ptr;
100
ULONG                               *list_word_ptr;
101
ULONG                               list_word;
102
ULONG                               min_logical_sector;
103
ULONG                               max_logical_sector;
104
ULONG                               mapped_sectors;
105
ULONG                               total_blocks;
106
ULONG                               total_sectors;
107
ULONG                               i, j;
108
ULONG                               search_start;
109
5676
LX_NOR_SECTOR_MAPPING_CACHE_ENTRY   *sector_mapping_cache_entry_ptr = LX_NULL;
110
LX_NOR_SECTOR_MAPPING_CACHE_ENTRY   temp_sector_mapping_cache_entry;
111
#ifndef LX_NOR_ENABLE_OBSOLETE_COUNT_CACHE
112
ULONG                               valid_sector_found;
113
#endif
114
#if !defined(LX_DIRECT_READ)  || !defined(LX_NOR_ENABLE_OBSOLETE_COUNT_CACHE)
115
UINT                                status;
116
#endif
117
118
119
    /* Initialize the return parameters.  */
120
5676
    *physical_sector_map_entry =  (ULONG *) 0;
121
5676
    *physical_sector_address =    (ULONG *) 0;
122
123
    /* Determine if there are any mapped physical sectors.  */
124
5676
    if (nor_flash -> lx_nor_flash_mapped_physical_sectors == 0)
125
    {
126
127
        /* No mapped sector so nothing can be found!.  */
128
7
        return(LX_SECTOR_NOT_FOUND);
129
    }
130
131
#ifndef LX_NOR_DISABLE_EXTENDED_CACHE
132
#ifdef LX_NOR_ENABLE_MAPPING_BITMAP
133
134
    /* Determine if the logical sector is in the range of mapping bitmap cache.  */
135
    if (logical_sector < nor_flash -> lx_nor_flash_extended_cache_mapping_bitmap_max_logical_sector)
136
    {
137
138
        /* Determine if the logical sector is mapped.  */
139
        if ((nor_flash -> lx_nor_flash_extended_cache_mapping_bitmap[logical_sector >> 5] & (ULONG)(1 << (logical_sector & 31))) == 0)
140
        {
141
142
            /* Not mapped, return not found.  */
143
            return(LX_SECTOR_NOT_FOUND);
144
        }
145
    }
146
#endif
147
#endif
148
149
    /* Determine if the sector mapping cache is enabled.  */
150
5669
    if (nor_flash -> lx_nor_flash_sector_mapping_cache_enabled)
151
    {
152
153
        /* Calculate the starting index of the sector cache for this sector entry.  */
154
5665
        i =  (logical_sector & LX_NOR_SECTOR_MAPPING_CACHE_HASH_MASK) * LX_NOR_SECTOR_MAPPING_CACHE_DEPTH;
155
156
        /* Build a pointer to the cache entry.  */
157
5665
        sector_mapping_cache_entry_ptr =  &nor_flash -> lx_nor_flash_sector_mapping_cache[i];
158
159
        /* Determine if the sector is in the sector mapping cache - assuming the depth of the sector
160
           mapping cache is LX_NOR_SECTOR_MAPPING_CACHE_DEPTH entries.  */
161
5665
        if ((sector_mapping_cache_entry_ptr -> lx_nor_sector_mapping_cache_logical_sector) == (logical_sector | LX_NOR_SECTOR_MAPPING_CACHE_ENTRY_VALID))
162
        {
163
164
            /* Increment the sector mapping cache hit counter.  */
165
2420
            nor_flash -> lx_nor_flash_sector_mapping_cache_hits++;
166
167
            /* Yes, return the cached values associated with the sector.  */
168
2420
            *physical_sector_map_entry =  sector_mapping_cache_entry_ptr -> lx_nor_sector_mapping_cache_physical_sector_map_entry;
169
2420
            *physical_sector_address =    sector_mapping_cache_entry_ptr -> lx_nor_sector_mapping_cache_physical_sector_address;
170
171
            /* Don't move anything since we found the entry at the top.  */
172
173
            /* Return a successful status.  */
174
2420
            return(LX_SUCCESS);
175
        }
176
3245
        else if (((sector_mapping_cache_entry_ptr + 1) -> lx_nor_sector_mapping_cache_logical_sector) == (logical_sector | LX_NOR_SECTOR_MAPPING_CACHE_ENTRY_VALID))
177
        {
178
179
            /* Increment the sector mapping cache hit counter.  */
180
68
            nor_flash -> lx_nor_flash_sector_mapping_cache_hits++;
181
182
            /* Yes, return the cached values associated with the sector.  */
183
68
            *physical_sector_map_entry =  (sector_mapping_cache_entry_ptr + 1) -> lx_nor_sector_mapping_cache_physical_sector_map_entry;
184
68
            *physical_sector_address =    (sector_mapping_cache_entry_ptr + 1) -> lx_nor_sector_mapping_cache_physical_sector_address;
185
186
            /* Just swap the first and second entry.  */
187
68
            temp_sector_mapping_cache_entry =        *(sector_mapping_cache_entry_ptr);
188
68
            *(sector_mapping_cache_entry_ptr) =      *(sector_mapping_cache_entry_ptr + 1);
189
68
            *(sector_mapping_cache_entry_ptr + 1) =  temp_sector_mapping_cache_entry;
190
191
            /* Return a successful status.  */
192
68
            return(LX_SUCCESS);
193
        }
194
3177
        else if (((sector_mapping_cache_entry_ptr + 2) -> lx_nor_sector_mapping_cache_logical_sector) == (logical_sector | LX_NOR_SECTOR_MAPPING_CACHE_ENTRY_VALID))
195
        {
196
197
            /* Increment the sector mapping cache hit counter.  */
198
76
            nor_flash -> lx_nor_flash_sector_mapping_cache_hits++;
199
200
            /* Yes, return the cached value.  */
201
76
            *physical_sector_map_entry =  (sector_mapping_cache_entry_ptr + 2) -> lx_nor_sector_mapping_cache_physical_sector_map_entry;
202
76
            *physical_sector_address =    (sector_mapping_cache_entry_ptr + 2) -> lx_nor_sector_mapping_cache_physical_sector_address;
203
204
            /* Move the third entry to the top and the first two entries down.  */
205
76
            temp_sector_mapping_cache_entry =        *(sector_mapping_cache_entry_ptr);
206
76
            *(sector_mapping_cache_entry_ptr) =      *(sector_mapping_cache_entry_ptr + 2);
207
76
            *(sector_mapping_cache_entry_ptr + 2) =  *(sector_mapping_cache_entry_ptr + 1);
208
76
            *(sector_mapping_cache_entry_ptr + 1) =  temp_sector_mapping_cache_entry;
209
210
            /* Return a successful status.  */
211
76
            return(LX_SUCCESS);
212
        }
213
3101
        else if (((sector_mapping_cache_entry_ptr + 3) -> lx_nor_sector_mapping_cache_logical_sector) == (logical_sector | LX_NOR_SECTOR_MAPPING_CACHE_ENTRY_VALID))
214
        {
215
216
            /* Increment the sector mapping cache hit counter.  */
217
20
            nor_flash -> lx_nor_flash_sector_mapping_cache_hits++;
218
219
            /* Yes, return the cached value.  */
220
20
            *physical_sector_map_entry =  (sector_mapping_cache_entry_ptr + 3) -> lx_nor_sector_mapping_cache_physical_sector_map_entry;
221
20
            *physical_sector_address =    (sector_mapping_cache_entry_ptr + 3) -> lx_nor_sector_mapping_cache_physical_sector_address;
222
223
            /* Move the last entry to the top and the first three entries down.  */
224
20
            temp_sector_mapping_cache_entry =        *(sector_mapping_cache_entry_ptr);
225
20
            *(sector_mapping_cache_entry_ptr) =      *(sector_mapping_cache_entry_ptr + 3);
226
20
            *(sector_mapping_cache_entry_ptr + 3) =  *(sector_mapping_cache_entry_ptr + 2);
227
20
            *(sector_mapping_cache_entry_ptr + 2) =  *(sector_mapping_cache_entry_ptr + 1);
228
20
            *(sector_mapping_cache_entry_ptr + 1) =  temp_sector_mapping_cache_entry;
229
230
            /* Return a successful status.  */
231
20
            return(LX_SUCCESS);
232
        }
233
234
        /* If we get here, we have a cache miss so increment the counter before we fall through the loop.  */
235
3081
        nor_flash -> lx_nor_flash_sector_mapping_cache_misses++;
236
    }
237
238
    /* Setup the total number of mapped sectors.  */
239
3085
    mapped_sectors =  nor_flash -> lx_nor_flash_mapped_physical_sectors;
240
241
    /* Start searching from the last found block.  */
242
3085
    i =  nor_flash -> lx_nor_flash_found_block_search;
243
244
    /* Setup the starting sector to look at.  */
245
3085
    j =  nor_flash -> lx_nor_flash_found_sector_search;
246
247
    /* Pickup the total number of blocks.  */
248
3085
    total_blocks =  nor_flash -> lx_nor_flash_total_blocks;
249
250
    /* Loop through the blocks to attempt to find the mapped logical sector.  */
251
13272
    while (total_blocks--)
252
    {
253
254
#ifdef LX_NOR_ENABLE_OBSOLETE_COUNT_CACHE
255
        /* Determine if the obsolete sector count is available in the cache.  */
256
        if (i < nor_flash -> lx_nor_flash_extended_cache_obsolete_count_max_block)
257
        {
258
259
            /* Check if the block contains obsolete sectors only.  */
260
            if ((ULONG)nor_flash -> lx_nor_flash_extended_cache_obsolete_count[i] == nor_flash -> lx_nor_flash_physical_sectors_per_block)
261
            {
262
263
                /* Move to the next block.  */
264
                i++;
265
266
                /* Determine if we have wrapped.  */
267
                if (i >= nor_flash -> lx_nor_flash_total_blocks)
268
                {
269
270
                    /* Yes, we have wrapped, set to block 0.  */
271
                    i =  0;
272
                }
273
274
                /* Start at the first sector in the next block.  */
275
                j =  0;
276
277
                /* No point in looking further into this block, just continue the loop.  */
278
                continue;
279
280
            }
281
        }
282
#endif
283
284
        /* Setup the block word pointer to the first word of the search block.  */
285
12831
        block_word_ptr =  (nor_flash -> lx_nor_flash_base_address + (i * nor_flash -> lx_nor_flash_words_per_block));
286
287
        /* Determine if the minimum and maximum logical sector values are present in the block header.  If these are
288
           present, we can quickly skip blocks that don't have our sector.  */
289
290
        /* Read the minimum and maximum logical sector values in this block.  */
291
#ifdef LX_DIRECT_READ
292
293
        /* Read the word directly.  */
294
        min_logical_sector =  *(block_word_ptr + LX_NOR_FLASH_MIN_LOGICAL_SECTOR_OFFSET);
295
#else
296
12831
        status =  _lx_nor_flash_driver_read(nor_flash, block_word_ptr + LX_NOR_FLASH_MIN_LOGICAL_SECTOR_OFFSET, &min_logical_sector, 1);
297
298
        /* Check for an error from flash driver. Drivers should never return an error..  */
299
12831
        if (status)
300
        {
301
302
            /* Call system error handler.  */
303
            _lx_nor_flash_system_error(nor_flash, status);
304
305
            /* Return the error.  */
306
            return(status);
307
        }
308
#endif
309
310
        /* Is the value valid?  */
311
12831
        if (min_logical_sector != LX_ALL_ONES)
312
        {
313
#ifdef LX_DIRECT_READ
314
315
            /* Read the word directly.  */
316
            max_logical_sector =  *(block_word_ptr + LX_NOR_FLASH_MAX_LOGICAL_SECTOR_OFFSET);
317
#else
318
9094
            status =  _lx_nor_flash_driver_read(nor_flash, block_word_ptr + LX_NOR_FLASH_MAX_LOGICAL_SECTOR_OFFSET, &max_logical_sector, 1);
319
320
            /* Check for an error from flash driver. Drivers should never return an error..  */
321
9094
            if (status)
322
            {
323
324
                /* Call system error handler.  */
325
                _lx_nor_flash_system_error(nor_flash, status);
326
327
                /* Return the error.  */
328
                return(status);
329
            }
330
#endif
331
332
            /* Is the value valid?  */
333
9094
            if (max_logical_sector != LX_ALL_ONES)
334
            {
335
336
                /* Now let's check to see if the search sector is within this range.  */
337

9094
                if ((logical_sector < min_logical_sector) || (logical_sector > max_logical_sector))
338
                {
339
340
                    /* Move to the next block.  */
341
2276
                    i++;
342
343
                    /* Determine if we have wrapped.  */
344
2276
                    if (i >= nor_flash -> lx_nor_flash_total_blocks)
345
                    {
346
347
                        /* Yes, we have wrapped, set to block 0.  */
348
98
                        i =  0;
349
                    }
350
351
                    /* Start at the first sector in the next block.  */
352
2276
                    j =  0;
353
354
                    /* No point in looking further into this block, just continue the loop.  */
355
2276
                    continue;
356
                }
357
            }
358
        }
359
        else
360
        {
361
362
            /* Set the max logical sector to all ones.  */
363
3737
            max_logical_sector = LX_ALL_ONES;
364
        }
365
#ifndef LX_NOR_ENABLE_OBSOLETE_COUNT_CACHE
366
367
        /* Clear the valid sector found flag.  */
368
10555
        valid_sector_found = LX_FALSE;
369
#endif
370
371
        /* Setup the total number of sectors.  */
372
10555
        total_sectors =  nor_flash -> lx_nor_flash_physical_sectors_per_block;
373
374
        /* Remember the start of the search.  */
375
10555
        search_start =  j;
376
377
        /* Now search through the sector list to find a match.  */
378
99895
        while (total_sectors--)
379
        {
380
381
            /* Setup a pointer to the mapped list.  */
382
95196
            list_word_ptr =  block_word_ptr + nor_flash -> lx_nor_flash_block_physical_sector_mapping_offset + j;
383
384
385
            /* Read in the mapped list for this block.  */
386
#ifdef LX_DIRECT_READ
387
388
            /* Read the word directly.  */
389
            list_word =  *(list_word_ptr);
390
#else
391
95196
            status =  _lx_nor_flash_driver_read(nor_flash, list_word_ptr, &list_word, 1);
392
393
            /* Check for an error from flash driver. Drivers should never return an error..  */
394
95196
            if (status)
395
            {
396
397
                /* Call system error handler.  */
398
                _lx_nor_flash_system_error(nor_flash, status);
399
400
                /* Return the error.  */
401
                return(status);
402
            }
403
#endif
404
405
            /* Determine if the entry hasn't been used.  */
406
95196
            if (list_word == LX_NOR_PHYSICAL_SECTOR_FREE)
407
            {
408
409
                /* Since the mapping is done sequentially in the block, we know nothing
410
                   else exists after this point.  */
411
412
                /* Determine if the search started at the beginning of the block.  */
413
3571
                if (search_start == 0)
414
                {
415
416
                    /* Yes, we started at the beginning of the block.  We are now done with this block. */
417
3286
                    break;
418
                }
419
                else
420
                {
421
422
                    /* Setup the new total to the search start.  */
423
285
                    total_sectors =  search_start;
424
425
                    /* Clear search start.  */
426
285
                    search_start =  0;
427
428
                    /* Start search over.  */
429
285
                    j =  0;
430
285
                    continue;
431
                }
432
            }
433
434
            /* Is this entry valid?  */
435
91625
            if ((list_word & (LX_NOR_PHYSICAL_SECTOR_VALID | LX_NOR_PHYSICAL_SECTOR_MAPPING_NOT_VALID)) == LX_NOR_PHYSICAL_SECTOR_VALID)
436
            {
437
438
                /* Decrement the number of mapped sectors.  */
439
87375
                mapped_sectors--;
440
441
                /* Do we have a valid sector match?  */
442
87375
                if ((list_word & LX_NOR_LOGICAL_SECTOR_MASK) == logical_sector)
443
                {
444
445
                    /* Determine if we care about the superceded bit.  */
446
2572
                    if (superceded_check == LX_FALSE)
447
                    {
448
449
                        /* Prepare the return information.  */
450
2568
                        *physical_sector_map_entry =  list_word_ptr;
451
2568
                        *physical_sector_address =    block_word_ptr + nor_flash -> lx_nor_flash_block_physical_sector_offset + (j * LX_NOR_SECTOR_SIZE);
452
453
                        /* Determine if the sector mapping cache is enabled.  */
454
2568
                        if (nor_flash -> lx_nor_flash_sector_mapping_cache_enabled)
455
                        {
456
457
                            /* Yes, update the cache with the sector mapping.  */
458
459
                            /* Move all the cache entries down so the oldest is at the bottom.  */
460
2568
                            *(sector_mapping_cache_entry_ptr + 3) =  *(sector_mapping_cache_entry_ptr + 2);
461
2568
                            *(sector_mapping_cache_entry_ptr + 2) =  *(sector_mapping_cache_entry_ptr + 1);
462
2568
                            *(sector_mapping_cache_entry_ptr + 1) =  *(sector_mapping_cache_entry_ptr);
463
464
                            /* Setup the new sector information in the cache.  */
465
2568
                            sector_mapping_cache_entry_ptr -> lx_nor_sector_mapping_cache_logical_sector =             (logical_sector | LX_NOR_SECTOR_MAPPING_CACHE_ENTRY_VALID);
466
2568
                            sector_mapping_cache_entry_ptr -> lx_nor_sector_mapping_cache_physical_sector_map_entry =  *physical_sector_map_entry;
467
2568
                            sector_mapping_cache_entry_ptr -> lx_nor_sector_mapping_cache_physical_sector_address =    *physical_sector_address;
468
                        }
469
470
                        /* Remember the last found block for next search.  */
471
2568
                        nor_flash -> lx_nor_flash_found_block_search =  i;
472
473
                        /* Remember the last found sector.  */
474
2568
                        nor_flash -> lx_nor_flash_found_sector_search =  j+1;
475
476
                        /* Has this wrapped around?  */
477
2568
                        if (nor_flash -> lx_nor_flash_found_sector_search >= nor_flash -> lx_nor_flash_physical_sectors_per_block)
478
                        {
479
480
                            /* Reset to the beginning sector.  */
481
43
                            nor_flash -> lx_nor_flash_found_sector_search =  0;
482
                        }
483
484
                        /* Return success!  */
485
2568
                        return(LX_SUCCESS);
486
                    }
487
488
                    /* Check for the superceded bit being clear, which means the sector was superceded.  */
489
4
                    else if (list_word & LX_NOR_PHYSICAL_SECTOR_SUPERCEDED)
490
                    {
491
492
                        /* Prepare the return information.  */
493
2
                        *physical_sector_map_entry =  list_word_ptr;
494
2
                        *physical_sector_address =    block_word_ptr + nor_flash -> lx_nor_flash_block_physical_sector_offset + (j * LX_NOR_SECTOR_SIZE);
495
496
                        /* No need to update the cache here, since this condition only happens during initialization.  */
497
498
                        /* Remember the last found block for next search.  */
499
2
                        nor_flash -> lx_nor_flash_found_block_search =  i;
500
501
                        /* Remember the last found sector.  */
502
2
                        nor_flash -> lx_nor_flash_found_sector_search =  j+1;
503
504
                        /* Has this wrapped around?  */
505
2
                        if (nor_flash -> lx_nor_flash_found_sector_search >= nor_flash -> lx_nor_flash_physical_sectors_per_block)
506
                        {
507
508
                            /* Reset to the beginning sector.  */
509
                            nor_flash -> lx_nor_flash_found_sector_search =  0;
510
                        }
511
512
                        /* Return success!  */
513
2
                        return(LX_SUCCESS);
514
                    }
515
                }
516
#ifndef LX_NOR_ENABLE_OBSOLETE_COUNT_CACHE
517
518
                /* Set the valid sector found flag.  */
519
84805
                valid_sector_found = LX_TRUE;
520
#endif
521
            }
522
523
            /* Move to the next list entry.  */
524
89055
            j++;
525
526
            /* Check for wrap around.  */
527
89055
            if (j >= nor_flash -> lx_nor_flash_physical_sectors_per_block)
528
            {
529
530
                /* Yes, wrap around, go back to the beginning.  */
531
4722
                j =  0;
532
            }
533
        }
534
#ifndef LX_NOR_ENABLE_OBSOLETE_COUNT_CACHE
535
        /* Check if the block contains no valid sectors.  */
536

7985
        if ((valid_sector_found == LX_FALSE) && (max_logical_sector != LX_ALL_ONES))
537
        {
538
539
                /* Clear max logical sector to indicate sectors are all obsoleted.  */
540
                max_logical_sector = 0;
541
542
                /* Write the max logical sector to the block header.  */
543
                status =  _lx_nor_flash_driver_write(nor_flash, block_word_ptr + LX_NOR_FLASH_MAX_LOGICAL_SECTOR_OFFSET, &max_logical_sector, 1);
544
545
                /* Check for an error from flash driver. Drivers should never return an error..  */
546
                if (status)
547
                {
548
549
                    /* Call system error handler.  */
550
                    _lx_nor_flash_system_error(nor_flash, status);
551
552
                    /* Return the error.  */
553
                    return(status);
554
                }
555
        }
556
#endif
557
558
        /* Determine if there are any more mapped sectors.  */
559
7985
        if (mapped_sectors == 0)
560
74
            break;
561
562
        /* Move to the next block.  */
563
7911
        i++;
564
565
        /* Determine if we have wrapped.  */
566
7911
        if (i >= nor_flash -> lx_nor_flash_total_blocks)
567
        {
568
569
            /* Yes, we have wrapped, set to block 0.  */
570
1172
            i =  0;
571
        }
572
573
        /* Start at the first sector in the next block.  */
574
7911
        j =  0;
575
    }
576
577
    /* Return sector not found status.  */
578
515
    return(LX_SECTOR_NOT_FOUND);
579
}
580