1 /**************************************************************************/
2 /*                                                                        */
3 /*       Copyright (c) Microsoft Corporation. All rights reserved.        */
4 /*                                                                        */
5 /*       This software is licensed under the Microsoft Software License   */
6 /*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
7 /*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
8 /*       and in the root directory of this software.                      */
9 /*                                                                        */
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 /*  RELEASE HISTORY                                                       */
81 /*                                                                        */
82 /*    DATE              NAME                      DESCRIPTION             */
83 /*                                                                        */
84 /*  05-19-2020     William E. Lamie         Initial Version 6.0           */
85 /*  09-30-2020     William E. Lamie         Modified comment(s),          */
86 /*                                            resulting in version 6.1    */
87 /*  06-02-2021     Bhupendra Naphade        Modified comment(s),          */
88 /*                                            resulting in version 6.1.7  */
89 /*  10-31-2023     Xiuwen Cai               Modified comment(s),          */
90 /*                                            added mapping bitmap cache, */
91 /*                                            added obsolete count cache, */
92 /*                                            optimized full obsoleted    */
93 /*                                            block searching logic,      */
94 /*                                            resulting in version 6.3.0  */
95 /*                                                                        */
96 /**************************************************************************/
_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 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)
98 {
99 
100 ULONG                               *block_word_ptr;
101 ULONG                               *list_word_ptr;
102 ULONG                               list_word;
103 ULONG                               min_logical_sector;
104 ULONG                               max_logical_sector;
105 ULONG                               mapped_sectors;
106 ULONG                               total_blocks;
107 ULONG                               total_sectors;
108 ULONG                               i, j;
109 ULONG                               search_start;
110 LX_NOR_SECTOR_MAPPING_CACHE_ENTRY   *sector_mapping_cache_entry_ptr = LX_NULL;
111 LX_NOR_SECTOR_MAPPING_CACHE_ENTRY   temp_sector_mapping_cache_entry;
112 #ifndef LX_NOR_ENABLE_OBSOLETE_COUNT_CACHE
113 ULONG                               valid_sector_found;
114 #endif
115 #if !defined(LX_DIRECT_READ)  || !defined(LX_NOR_ENABLE_OBSOLETE_COUNT_CACHE)
116 UINT                                status;
117 #endif
118 
119 
120     /* Initialize the return parameters.  */
121     *physical_sector_map_entry =  (ULONG *) 0;
122     *physical_sector_address =    (ULONG *) 0;
123 
124     /* Determine if there are any mapped physical sectors.  */
125     if (nor_flash -> lx_nor_flash_mapped_physical_sectors == 0)
126     {
127 
128         /* No mapped sector so nothing can be found!.  */
129         return(LX_SECTOR_NOT_FOUND);
130     }
131 
132 #ifndef LX_NOR_DISABLE_EXTENDED_CACHE
133 #ifdef LX_NOR_ENABLE_MAPPING_BITMAP
134 
135     /* Determine if the logical sector is in the range of mapping bitmap cache.  */
136     if (logical_sector < nor_flash -> lx_nor_flash_extended_cache_mapping_bitmap_max_logical_sector)
137     {
138 
139         /* Determine if the logical sector is mapped.  */
140         if ((nor_flash -> lx_nor_flash_extended_cache_mapping_bitmap[logical_sector >> 5] & (ULONG)(1 << (logical_sector & 31))) == 0)
141         {
142 
143             /* Not mapped, return not found.  */
144             return(LX_SECTOR_NOT_FOUND);
145         }
146     }
147 #endif
148 #endif
149 
150     /* Determine if the sector mapping cache is enabled.  */
151     if (nor_flash -> lx_nor_flash_sector_mapping_cache_enabled)
152     {
153 
154         /* Calculate the starting index of the sector cache for this sector entry.  */
155         i =  (logical_sector & LX_NOR_SECTOR_MAPPING_CACHE_HASH_MASK) * LX_NOR_SECTOR_MAPPING_CACHE_DEPTH;
156 
157         /* Build a pointer to the cache entry.  */
158         sector_mapping_cache_entry_ptr =  &nor_flash -> lx_nor_flash_sector_mapping_cache[i];
159 
160         /* Determine if the sector is in the sector mapping cache - assuming the depth of the sector
161            mapping cache is LX_NOR_SECTOR_MAPPING_CACHE_DEPTH entries.  */
162         if ((sector_mapping_cache_entry_ptr -> lx_nor_sector_mapping_cache_logical_sector) == (logical_sector | LX_NOR_SECTOR_MAPPING_CACHE_ENTRY_VALID))
163         {
164 
165             /* Increment the sector mapping cache hit counter.  */
166             nor_flash -> lx_nor_flash_sector_mapping_cache_hits++;
167 
168             /* Yes, return the cached values associated with the sector.  */
169             *physical_sector_map_entry =  sector_mapping_cache_entry_ptr -> lx_nor_sector_mapping_cache_physical_sector_map_entry;
170             *physical_sector_address =    sector_mapping_cache_entry_ptr -> lx_nor_sector_mapping_cache_physical_sector_address;
171 
172             /* Don't move anything since we found the entry at the top.  */
173 
174             /* Return a successful status.  */
175             return(LX_SUCCESS);
176         }
177         else if (((sector_mapping_cache_entry_ptr + 1) -> lx_nor_sector_mapping_cache_logical_sector) == (logical_sector | LX_NOR_SECTOR_MAPPING_CACHE_ENTRY_VALID))
178         {
179 
180             /* Increment the sector mapping cache hit counter.  */
181             nor_flash -> lx_nor_flash_sector_mapping_cache_hits++;
182 
183             /* Yes, return the cached values associated with the sector.  */
184             *physical_sector_map_entry =  (sector_mapping_cache_entry_ptr + 1) -> lx_nor_sector_mapping_cache_physical_sector_map_entry;
185             *physical_sector_address =    (sector_mapping_cache_entry_ptr + 1) -> lx_nor_sector_mapping_cache_physical_sector_address;
186 
187             /* Just swap the first and second entry.  */
188             temp_sector_mapping_cache_entry =        *(sector_mapping_cache_entry_ptr);
189             *(sector_mapping_cache_entry_ptr) =      *(sector_mapping_cache_entry_ptr + 1);
190             *(sector_mapping_cache_entry_ptr + 1) =  temp_sector_mapping_cache_entry;
191 
192             /* Return a successful status.  */
193             return(LX_SUCCESS);
194         }
195         else if (((sector_mapping_cache_entry_ptr + 2) -> lx_nor_sector_mapping_cache_logical_sector) == (logical_sector | LX_NOR_SECTOR_MAPPING_CACHE_ENTRY_VALID))
196         {
197 
198             /* Increment the sector mapping cache hit counter.  */
199             nor_flash -> lx_nor_flash_sector_mapping_cache_hits++;
200 
201             /* Yes, return the cached value.  */
202             *physical_sector_map_entry =  (sector_mapping_cache_entry_ptr + 2) -> lx_nor_sector_mapping_cache_physical_sector_map_entry;
203             *physical_sector_address =    (sector_mapping_cache_entry_ptr + 2) -> lx_nor_sector_mapping_cache_physical_sector_address;
204 
205             /* Move the third entry to the top and the first two entries down.  */
206             temp_sector_mapping_cache_entry =        *(sector_mapping_cache_entry_ptr);
207             *(sector_mapping_cache_entry_ptr) =      *(sector_mapping_cache_entry_ptr + 2);
208             *(sector_mapping_cache_entry_ptr + 2) =  *(sector_mapping_cache_entry_ptr + 1);
209             *(sector_mapping_cache_entry_ptr + 1) =  temp_sector_mapping_cache_entry;
210 
211             /* Return a successful status.  */
212             return(LX_SUCCESS);
213         }
214         else if (((sector_mapping_cache_entry_ptr + 3) -> lx_nor_sector_mapping_cache_logical_sector) == (logical_sector | LX_NOR_SECTOR_MAPPING_CACHE_ENTRY_VALID))
215         {
216 
217             /* Increment the sector mapping cache hit counter.  */
218             nor_flash -> lx_nor_flash_sector_mapping_cache_hits++;
219 
220             /* Yes, return the cached value.  */
221             *physical_sector_map_entry =  (sector_mapping_cache_entry_ptr + 3) -> lx_nor_sector_mapping_cache_physical_sector_map_entry;
222             *physical_sector_address =    (sector_mapping_cache_entry_ptr + 3) -> lx_nor_sector_mapping_cache_physical_sector_address;
223 
224             /* Move the last entry to the top and the first three entries down.  */
225             temp_sector_mapping_cache_entry =        *(sector_mapping_cache_entry_ptr);
226             *(sector_mapping_cache_entry_ptr) =      *(sector_mapping_cache_entry_ptr + 3);
227             *(sector_mapping_cache_entry_ptr + 3) =  *(sector_mapping_cache_entry_ptr + 2);
228             *(sector_mapping_cache_entry_ptr + 2) =  *(sector_mapping_cache_entry_ptr + 1);
229             *(sector_mapping_cache_entry_ptr + 1) =  temp_sector_mapping_cache_entry;
230 
231             /* Return a successful status.  */
232             return(LX_SUCCESS);
233         }
234 
235         /* If we get here, we have a cache miss so increment the counter before we fall through the loop.  */
236         nor_flash -> lx_nor_flash_sector_mapping_cache_misses++;
237     }
238 
239     /* Setup the total number of mapped sectors.  */
240     mapped_sectors =  nor_flash -> lx_nor_flash_mapped_physical_sectors;
241 
242     /* Start searching from the last found block.  */
243     i =  nor_flash -> lx_nor_flash_found_block_search;
244 
245     /* Setup the starting sector to look at.  */
246     j =  nor_flash -> lx_nor_flash_found_sector_search;
247 
248     /* Pickup the total number of blocks.  */
249     total_blocks =  nor_flash -> lx_nor_flash_total_blocks;
250 
251     /* Loop through the blocks to attempt to find the mapped logical sector.  */
252     while (total_blocks--)
253     {
254 
255 #ifdef LX_NOR_ENABLE_OBSOLETE_COUNT_CACHE
256         /* Determine if the obsolete sector count is available in the cache.  */
257         if (i < nor_flash -> lx_nor_flash_extended_cache_obsolete_count_max_block)
258         {
259 
260             /* Check if the block contains obsolete sectors only.  */
261             if ((ULONG)nor_flash -> lx_nor_flash_extended_cache_obsolete_count[i] == nor_flash -> lx_nor_flash_physical_sectors_per_block)
262             {
263 
264                 /* Move to the next block.  */
265                 i++;
266 
267                 /* Determine if we have wrapped.  */
268                 if (i >= nor_flash -> lx_nor_flash_total_blocks)
269                 {
270 
271                     /* Yes, we have wrapped, set to block 0.  */
272                     i =  0;
273                 }
274 
275                 /* Start at the first sector in the next block.  */
276                 j =  0;
277 
278                 /* No point in looking further into this block, just continue the loop.  */
279                 continue;
280 
281             }
282         }
283 #endif
284 
285         /* Setup the block word pointer to the first word of the search block.  */
286         block_word_ptr =  (nor_flash -> lx_nor_flash_base_address + (i * nor_flash -> lx_nor_flash_words_per_block));
287 
288         /* Determine if the minimum and maximum logical sector values are present in the block header.  If these are
289            present, we can quickly skip blocks that don't have our sector.  */
290 
291         /* Read the minimum and maximum logical sector values in this block.  */
292 #ifdef LX_DIRECT_READ
293 
294         /* Read the word directly.  */
295         min_logical_sector =  *(block_word_ptr + LX_NOR_FLASH_MIN_LOGICAL_SECTOR_OFFSET);
296 #else
297         status =  _lx_nor_flash_driver_read(nor_flash, block_word_ptr + LX_NOR_FLASH_MIN_LOGICAL_SECTOR_OFFSET, &min_logical_sector, 1);
298 
299         /* Check for an error from flash driver. Drivers should never return an error..  */
300         if (status)
301         {
302 
303             /* Call system error handler.  */
304             _lx_nor_flash_system_error(nor_flash, status);
305 
306             /* Return the error.  */
307             return(status);
308         }
309 #endif
310 
311         /* Is the value valid?  */
312         if (min_logical_sector != LX_ALL_ONES)
313         {
314 #ifdef LX_DIRECT_READ
315 
316             /* Read the word directly.  */
317             max_logical_sector =  *(block_word_ptr + LX_NOR_FLASH_MAX_LOGICAL_SECTOR_OFFSET);
318 #else
319             status =  _lx_nor_flash_driver_read(nor_flash, block_word_ptr + LX_NOR_FLASH_MAX_LOGICAL_SECTOR_OFFSET, &max_logical_sector, 1);
320 
321             /* Check for an error from flash driver. Drivers should never return an error..  */
322             if (status)
323             {
324 
325                 /* Call system error handler.  */
326                 _lx_nor_flash_system_error(nor_flash, status);
327 
328                 /* Return the error.  */
329                 return(status);
330             }
331 #endif
332 
333             /* Is the value valid?  */
334             if (max_logical_sector != LX_ALL_ONES)
335             {
336 
337                 /* Now let's check to see if the search sector is within this range.  */
338                 if ((logical_sector < min_logical_sector) || (logical_sector > max_logical_sector))
339                 {
340 
341                     /* Move to the next block.  */
342                     i++;
343 
344                     /* Determine if we have wrapped.  */
345                     if (i >= nor_flash -> lx_nor_flash_total_blocks)
346                     {
347 
348                         /* Yes, we have wrapped, set to block 0.  */
349                         i =  0;
350                     }
351 
352                     /* Start at the first sector in the next block.  */
353                     j =  0;
354 
355                     /* No point in looking further into this block, just continue the loop.  */
356                     continue;
357                 }
358             }
359         }
360         else
361         {
362 
363             /* Set the max logical sector to all ones.  */
364             max_logical_sector = LX_ALL_ONES;
365         }
366 #ifndef LX_NOR_ENABLE_OBSOLETE_COUNT_CACHE
367 
368         /* Clear the valid sector found flag.  */
369         valid_sector_found = LX_FALSE;
370 #endif
371 
372         /* Setup the total number of sectors.  */
373         total_sectors =  nor_flash -> lx_nor_flash_physical_sectors_per_block;
374 
375         /* Remember the start of the search.  */
376         search_start =  j;
377 
378         /* Now search through the sector list to find a match.  */
379         while (total_sectors--)
380         {
381 
382             /* Setup a pointer to the mapped list.  */
383             list_word_ptr =  block_word_ptr + nor_flash -> lx_nor_flash_block_physical_sector_mapping_offset + j;
384 
385 
386             /* Read in the mapped list for this block.  */
387 #ifdef LX_DIRECT_READ
388 
389             /* Read the word directly.  */
390             list_word =  *(list_word_ptr);
391 #else
392             status =  _lx_nor_flash_driver_read(nor_flash, list_word_ptr, &list_word, 1);
393 
394             /* Check for an error from flash driver. Drivers should never return an error..  */
395             if (status)
396             {
397 
398                 /* Call system error handler.  */
399                 _lx_nor_flash_system_error(nor_flash, status);
400 
401                 /* Return the error.  */
402                 return(status);
403             }
404 #endif
405 
406             /* Determine if the entry hasn't been used.  */
407             if (list_word == LX_NOR_PHYSICAL_SECTOR_FREE)
408             {
409 
410                 /* Since the mapping is done sequentially in the block, we know nothing
411                    else exists after this point.  */
412 
413                 /* Determine if the search started at the beginning of the block.  */
414                 if (search_start == 0)
415                 {
416 
417                     /* Yes, we started at the beginning of the block.  We are now done with this block. */
418                     break;
419                 }
420                 else
421                 {
422 
423                     /* Setup the new total to the search start.  */
424                     total_sectors =  search_start;
425 
426                     /* Clear search start.  */
427                     search_start =  0;
428 
429                     /* Start search over.  */
430                     j =  0;
431                     continue;
432                 }
433             }
434 
435             /* Is this entry valid?  */
436             if ((list_word & (LX_NOR_PHYSICAL_SECTOR_VALID | LX_NOR_PHYSICAL_SECTOR_MAPPING_NOT_VALID)) == LX_NOR_PHYSICAL_SECTOR_VALID)
437             {
438 
439                 /* Decrement the number of mapped sectors.  */
440                 mapped_sectors--;
441 
442                 /* Do we have a valid sector match?  */
443                 if ((list_word & LX_NOR_LOGICAL_SECTOR_MASK) == logical_sector)
444                 {
445 
446                     /* Determine if we care about the superceded bit.  */
447                     if (superceded_check == LX_FALSE)
448                     {
449 
450                         /* Prepare the return information.  */
451                         *physical_sector_map_entry =  list_word_ptr;
452                         *physical_sector_address =    block_word_ptr + nor_flash -> lx_nor_flash_block_physical_sector_offset + (j * LX_NOR_SECTOR_SIZE);
453 
454                         /* Determine if the sector mapping cache is enabled.  */
455                         if (nor_flash -> lx_nor_flash_sector_mapping_cache_enabled)
456                         {
457 
458                             /* Yes, update the cache with the sector mapping.  */
459 
460                             /* Move all the cache entries down so the oldest is at the bottom.  */
461                             *(sector_mapping_cache_entry_ptr + 3) =  *(sector_mapping_cache_entry_ptr + 2);
462                             *(sector_mapping_cache_entry_ptr + 2) =  *(sector_mapping_cache_entry_ptr + 1);
463                             *(sector_mapping_cache_entry_ptr + 1) =  *(sector_mapping_cache_entry_ptr);
464 
465                             /* Setup the new sector information in the cache.  */
466                             sector_mapping_cache_entry_ptr -> lx_nor_sector_mapping_cache_logical_sector =             (logical_sector | LX_NOR_SECTOR_MAPPING_CACHE_ENTRY_VALID);
467                             sector_mapping_cache_entry_ptr -> lx_nor_sector_mapping_cache_physical_sector_map_entry =  *physical_sector_map_entry;
468                             sector_mapping_cache_entry_ptr -> lx_nor_sector_mapping_cache_physical_sector_address =    *physical_sector_address;
469                         }
470 
471                         /* Remember the last found block for next search.  */
472                         nor_flash -> lx_nor_flash_found_block_search =  i;
473 
474                         /* Remember the last found sector.  */
475                         nor_flash -> lx_nor_flash_found_sector_search =  j+1;
476 
477                         /* Has this wrapped around?  */
478                         if (nor_flash -> lx_nor_flash_found_sector_search >= nor_flash -> lx_nor_flash_physical_sectors_per_block)
479                         {
480 
481                             /* Reset to the beginning sector.  */
482                             nor_flash -> lx_nor_flash_found_sector_search =  0;
483                         }
484 
485                         /* Return success!  */
486                         return(LX_SUCCESS);
487                     }
488 
489                     /* Check for the superceded bit being clear, which means the sector was superceded.  */
490                     else if (list_word & LX_NOR_PHYSICAL_SECTOR_SUPERCEDED)
491                     {
492 
493                         /* Prepare the return information.  */
494                         *physical_sector_map_entry =  list_word_ptr;
495                         *physical_sector_address =    block_word_ptr + nor_flash -> lx_nor_flash_block_physical_sector_offset + (j * LX_NOR_SECTOR_SIZE);
496 
497                         /* No need to update the cache here, since this condition only happens during initialization.  */
498 
499                         /* Remember the last found block for next search.  */
500                         nor_flash -> lx_nor_flash_found_block_search =  i;
501 
502                         /* Remember the last found sector.  */
503                         nor_flash -> lx_nor_flash_found_sector_search =  j+1;
504 
505                         /* Has this wrapped around?  */
506                         if (nor_flash -> lx_nor_flash_found_sector_search >= nor_flash -> lx_nor_flash_physical_sectors_per_block)
507                         {
508 
509                             /* Reset to the beginning sector.  */
510                             nor_flash -> lx_nor_flash_found_sector_search =  0;
511                         }
512 
513                         /* Return success!  */
514                         return(LX_SUCCESS);
515                     }
516                 }
517 #ifndef LX_NOR_ENABLE_OBSOLETE_COUNT_CACHE
518 
519                 /* Set the valid sector found flag.  */
520                 valid_sector_found = LX_TRUE;
521 #endif
522             }
523 
524             /* Move to the next list entry.  */
525             j++;
526 
527             /* Check for wrap around.  */
528             if (j >= nor_flash -> lx_nor_flash_physical_sectors_per_block)
529             {
530 
531                 /* Yes, wrap around, go back to the beginning.  */
532                 j =  0;
533             }
534         }
535 #ifndef LX_NOR_ENABLE_OBSOLETE_COUNT_CACHE
536         /* Check if the block contains no valid sectors.  */
537         if ((valid_sector_found == LX_FALSE) && (max_logical_sector != LX_ALL_ONES))
538         {
539 
540                 /* Clear max logical sector to indicate sectors are all obsoleted.  */
541                 max_logical_sector = 0;
542 
543                 /* Write the max logical sector to the block header.  */
544                 status =  _lx_nor_flash_driver_write(nor_flash, block_word_ptr + LX_NOR_FLASH_MAX_LOGICAL_SECTOR_OFFSET, &max_logical_sector, 1);
545 
546                 /* Check for an error from flash driver. Drivers should never return an error..  */
547                 if (status)
548                 {
549 
550                     /* Call system error handler.  */
551                     _lx_nor_flash_system_error(nor_flash, status);
552 
553                     /* Return the error.  */
554                     return(status);
555                 }
556         }
557 #endif
558 
559         /* Determine if there are any more mapped sectors.  */
560         if (mapped_sectors == 0)
561             break;
562 
563         /* Move to the next block.  */
564         i++;
565 
566         /* Determine if we have wrapped.  */
567         if (i >= nor_flash -> lx_nor_flash_total_blocks)
568         {
569 
570             /* Yes, we have wrapped, set to block 0.  */
571             i =  0;
572         }
573 
574         /* Start at the first sector in the next block.  */
575         j =  0;
576     }
577 
578     /* Return sector not found status.  */
579     return(LX_SECTOR_NOT_FOUND);
580 }
581 
582