GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lx_nor_flash_logical_sector_find.c Lines: 112 124 90.3 %
Date: 2026-03-06 18:45:40 Branches: 53 62 85.5 %

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

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

7985
        if ((valid_sector_found == LX_FALSE) && (max_logical_sector != LX_ALL_ONES))
522
        {
523
524
                /* Clear max logical sector to indicate sectors are all obsoleted.  */
525
                max_logical_sector = 0;
526
527
                /* Write the max logical sector to the block header.  */
528
                status =  _lx_nor_flash_driver_write(nor_flash, block_word_ptr + LX_NOR_FLASH_MAX_LOGICAL_SECTOR_OFFSET, &max_logical_sector, 1);
529
530
                /* Check for an error from flash driver. Drivers should never return an error..  */
531
                if (status)
532
                {
533
534
                    /* Call system error handler.  */
535
                    _lx_nor_flash_system_error(nor_flash, status);
536
537
                    /* Return the error.  */
538
                    return(status);
539
                }
540
        }
541
#endif
542
543
        /* Determine if there are any more mapped sectors.  */
544
7985
        if (mapped_sectors == 0)
545
74
            break;
546
547
        /* Move to the next block.  */
548
7911
        i++;
549
550
        /* Determine if we have wrapped.  */
551
7911
        if (i >= nor_flash -> lx_nor_flash_total_blocks)
552
        {
553
554
            /* Yes, we have wrapped, set to block 0.  */
555
1172
            i =  0;
556
        }
557
558
        /* Start at the first sector in the next block.  */
559
7911
        j =  0;
560
    }
561
562
    /* Return sector not found status.  */
563
515
    return(LX_SECTOR_NOT_FOUND);
564
}
565