Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:04

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup lpc32xx_nand_mlc
0007  *
0008  * @brief lpc32xx_mlc_read_blocks() implementation.
0009  */
0010 
0011 /*
0012  * Copyright (c) 2010 embedded brains GmbH & Co. KG
0013  *
0014  * Redistribution and use in source and binary forms, with or without
0015  * modification, are permitted provided that the following conditions
0016  * are met:
0017  * 1. Redistributions of source code must retain the above copyright
0018  *    notice, this list of conditions and the following disclaimer.
0019  * 2. Redistributions in binary form must reproduce the above copyright
0020  *    notice, this list of conditions and the following disclaimer in the
0021  *    documentation and/or other materials provided with the distribution.
0022  *
0023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0024  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0026  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0027  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0028  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0029  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0033  * POSSIBILITY OF SUCH DAMAGE.
0034  */
0035 
0036 #include <bsp/nand-mlc.h>
0037 
0038 #include <string.h>
0039 
0040 static rtems_status_code read_page(
0041   uint32_t first_page_of_block,
0042   uint32_t page,
0043   uint32_t page_data [MLC_LARGE_DATA_WORD_COUNT],
0044   uint32_t page_spare [MLC_LARGE_SPARE_WORD_COUNT]
0045 )
0046 {
0047   rtems_status_code sc = RTEMS_SUCCESSFUL;
0048   uint32_t page_index = first_page_of_block + page;
0049   bool possible_bad_page = page == 0 || page == 1;
0050 
0051   if (possible_bad_page) {
0052     memset(page_spare, 0, MLC_LARGE_SPARE_SIZE);
0053   }
0054 
0055   sc = lpc32xx_mlc_read_page(page_index, page_data, page_spare, NULL);
0056   if (possible_bad_page && lpc32xx_mlc_is_bad_page(page_spare)) {
0057     return RTEMS_UNSATISFIED;
0058   } else if (sc == RTEMS_SUCCESSFUL) {
0059     return RTEMS_SUCCESSFUL;
0060   } else {
0061     return sc;
0062   }
0063 }
0064 
0065 rtems_status_code lpc32xx_mlc_read_blocks(
0066   uint32_t block_begin,
0067   uint32_t block_end,
0068   lpc32xx_mlc_read_process process,
0069   void *process_arg,
0070   uint32_t page_buffer_0 [MLC_LARGE_DATA_WORD_COUNT],
0071   uint32_t page_buffer_1 [MLC_LARGE_DATA_WORD_COUNT]
0072 )
0073 {
0074   rtems_status_code sc = RTEMS_SUCCESSFUL;
0075   uint32_t page_spare_0 [MLC_LARGE_SPARE_WORD_COUNT];
0076   uint32_t page_spare_1 [MLC_LARGE_SPARE_WORD_COUNT];
0077   uint32_t pages_per_block = lpc32xx_mlc_pages_per_block();
0078   uint32_t page_size = lpc32xx_mlc_page_size();
0079   uint32_t block = 0;
0080   uint32_t first_page_of_block = block_begin * pages_per_block;
0081 
0082   for (
0083     block = block_begin;
0084     block != block_end;
0085     ++block, first_page_of_block += pages_per_block
0086   ) {
0087     uint32_t page = 0;
0088     bool done = false;
0089 
0090     sc = read_page(first_page_of_block, 0, page_buffer_0, page_spare_0);
0091     if (sc == RTEMS_UNSATISFIED) {
0092       continue;
0093     } else if (sc != RTEMS_SUCCESSFUL) {
0094       goto done;
0095     }
0096 
0097     sc = read_page(first_page_of_block, 1, page_buffer_1, page_spare_1);
0098     if (sc == RTEMS_UNSATISFIED) {
0099       continue;
0100     } else if (sc != RTEMS_SUCCESSFUL) {
0101       goto done;
0102     }
0103 
0104     done = (*process)(
0105       process_arg,
0106       first_page_of_block + 0,
0107       page_size,
0108       page_buffer_0,
0109       page_spare_0
0110     );
0111     if (done) {
0112       goto done;
0113     }
0114 
0115     done = (*process)(
0116       process_arg,
0117       first_page_of_block + 1,
0118       page_size,
0119       page_buffer_1,
0120       page_spare_1
0121     );
0122     if (done) {
0123       goto done;
0124     }
0125 
0126     for (page = 2; page < pages_per_block; ++page) {
0127       sc = read_page(first_page_of_block, page, page_buffer_1, page_spare_1);
0128       if (sc != RTEMS_SUCCESSFUL) {
0129         goto done;
0130       }
0131 
0132       done = (*process)(
0133         process_arg,
0134         first_page_of_block + page,
0135         page_size,
0136         page_buffer_1,
0137         page_spare_1
0138       );
0139       if (done) {
0140         goto done;
0141       }
0142     }
0143   }
0144 
0145 done:
0146 
0147   return sc;
0148 }