annotate packages/io/nand/current/src/nand.c @ 2994:3d3b0d53c2e5

NAND: application interface v2: functions take partition-relative addresses.
author Ross Younger <wry@ecoscentric.com>
date Thu, 19 Nov 2009 15:50:03 +0000
parents d0daa15943a5
children 8502a048ad17
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
1 //=============================================================================
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
2 //
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
3 // nand.c
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
4 //
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
5 // Main application interface for the eCos NAND flash library
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
6 //
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
7 //=============================================================================
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
8 // ####ECOSGPLCOPYRIGHTBEGIN####
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
9 // -------------------------------------------
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
10 // This file is part of eCos, the Embedded Configurable Operating System.
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
11 // Copyright (C) 2009 eCosCentric Limited.
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
12 //
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
13 // eCos is free software; you can redistribute it and/or modify it under
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
14 // the terms of the GNU General Public License as published by the Free
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
15 // Software Foundation; either version 2 or (at your option) any later
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
16 // version.
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
17 //
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
18 // eCos is distributed in the hope that it will be useful, but WITHOUT
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
19 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
20 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
21 // for more details.
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
22 //
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
23 // You should have received a copy of the GNU General Public License
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
24 // along with eCos; if not, write to the Free Software Foundation, Inc.,
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
25 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
26 //
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
27 // As a special exception, if other files instantiate templates or use
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
28 // macros or inline functions from this file, or you compile this file
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
29 // and link it with other works to produce a work based on this file,
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
30 // this file does not by itself cause the resulting work to be covered by
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
31 // the GNU General Public License. However the source code for this file
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
32 // must still be made available in accordance with section (3) of the GNU
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
33 // General Public License v2.
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
34 //
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
35 // This exception does not invalidate any other reasons why a work based
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
36 // on this file might be covered by the GNU General Public License.
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
37 // -------------------------------------------
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
38 // ####ECOSGPLCOPYRIGHTEND####
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
39 //=============================================================================
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
40 //#####DESCRIPTIONBEGIN####
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
41 //
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
42 // Author(s): wry
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
43 // Date: 2009-03-02
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
44 //
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
45 //####DESCRIPTIONEND####
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
46 //=============================================================================
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
47
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
48 #include <cyg/hal/drv_api.h> // mutexes
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
49 #include <cyg/infra/diag.h>
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
50 #include <cyg/infra/cyg_ass.h>
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
51
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
52 #include <cyg/nand/nand.h>
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
53 #include <cyg/nand/nand_device.h>
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
54 #include <cyg/nand/nand_devtab.h>
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
55 #include <cyg/nand/util.h>
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
56 #include "nand_bbt.h"
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
57 #include CYGBLD_ISO_ERRNO_CODES_HEADER
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
58 #include <string.h>
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
59
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
60 /* ============================================================ */
2976
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
61 // Timing instrumentation hooks; or "where is all the time going?"
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
62 // timetag_to_csv.pl will turn gdb output ("p tagslist") into CSV,
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
63 // for ease of analysis.
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
64
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
65 #ifdef CYGSEM_IO_NAND_INSTRUMENT_TIMING
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
66 # ifndef HAL_CLOCK_READ
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
67 # error HAL_CLOCK_READ required
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
68 # endif
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
69 # define TAGSIZE 1024
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
70 cyg_uint32 tagslist[TAGSIZE];
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
71 cyg_uint32 tags_next;
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
72 static cyg_int64 rtc_resolution[] = CYGNUM_KERNEL_COUNTERS_RTC_RESOLUTION;
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
73 static cyg_int64 rtc_period = CYGNUM_KERNEL_COUNTERS_RTC_PERIOD;
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
74
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
75 # define TAG(_x) do { \
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
76 tagslist[tags_next++] = _x; \
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
77 if (tags_next >= TAGSIZE) tags_next = 0; \
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
78 } while(0)
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
79
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
80 # define TIMETAG() do { \
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
81 cyg_uint64 tick; \
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
82 cyg_uint32 haltick; \
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
83 tick=cyg_current_time();\
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
84 HAL_CLOCK_READ(&haltick);\
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
85 TAG(__LINE__); \
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
86 TAG(tick&0xFFFFFFFF); \
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
87 TAG(haltick); \
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
88 } while(0)
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
89
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
90 # define TIMETAG_INIT() do { \
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
91 int _i; \
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
92 for (_i=0; _i<TAGSIZE; _i++) \
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
93 tagslist[_i]=0; \
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
94 tags_next = 0; \
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
95 cyg_uint32 _tt, _tu; \
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
96 HAL_CLOCK_READ(&_tt); \
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
97 _tu = _tt; \
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
98 while (_tt == _tu) \
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
99 HAL_CLOCK_READ(&_tu); \
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
100 TIMETAG(); \
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
101 (void) rtc_period; \
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
102 (void) rtc_resolution; \
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
103 } while(0)
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
104
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
105 #else // ! CYGSEM_IO_NAND_INSTRUMENT_TIMING
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
106
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
107 # define TIMETAG_INIT() CYG_EMPTY_STATEMENT
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
108 # define TIMETAG() CYG_EMPTY_STATEMENT
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
109
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
110 #endif
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
111
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
112 /* ============================================================ */
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
113
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
114 /* We have a global ("devinit") lock, protects the nanddevtab and all
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
115 * writes to device->isInited.
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
116 *
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
117 * Each device also has its own lock, which protects the rest of
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
118 * the structure, and the hardware itself.
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
119 *
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
120 * Rules:
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
121 * 1. Nothing can use a device until it has been fully initialised
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
122 * (i.e. they must check dev->isInited, which is not set until
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
123 * initialisation is complete);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
124 * 2. All calls to a device which has been initialised must acquire
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
125 * the device's lock, to prevent multiple access;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
126 * 3. A repeated call to initialise a device is a safe no-op (under the
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
127 * global lock, see that isInited is set, so do nothing);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
128 * 4. It is not possible for multiple threads to simultaneously
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
129 * initialise the same device [via the lookup function]
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
130 * (they are protected by the global lock - the second blocks
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
131 * until the first has completed, at which point the second thread
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
132 * sees that the device has been inited and falls out into a no-op).
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
133 *
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
134 * Therefore, an operation in devinit which uses the chip need not
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
135 * assert the per-device lock, as nothing else can use the chip until
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
136 * it has completed and set isInited to 1.
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
137 */
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
138
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
139 static cyg_drv_mutex_t devinit_lock;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
140
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
141 #define LOCK_devinit() cyg_drv_mutex_lock(&devinit_lock)
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
142 #define UNLOCK_devinit() cyg_drv_mutex_unlock(&devinit_lock)
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
143
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
144 /* Per-device lock.
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
145 * NB that if multiple devices might interact (e.g. sharing a CPLD),
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
146 * their drivers must act in concert to prevent this, usually at the
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
147 * platform level. */
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
148 #define LOCK_DEV(dev) cyg_drv_mutex_lock(&dev->devlock)
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
149 #define UNLOCK_DEV(dev) cyg_drv_mutex_unlock(&dev->devlock)
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
150
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
151 /* ============================================================ */
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
152 /* Initialisation and lookup */
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
153
2949
b72667909323 NAND: add CYGBLD_IO_NAND_BUILD_UTILS; tidy bbt code
Ross Younger <wry@ecoscentric.com>
parents: 2948
diff changeset
154 __externC void cyg_nand_bbt_initx(void);
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
155 static cyg_nand_printf nand_default_pf;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
156
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
157 // This is called only by the C++ static constructor. Applications
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
158 // never need to call this themselves.
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
159 __externC void cyg_nand_initx(cyg_nand_printf pf)
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
160 {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
161 if (pf) CYG_CHECK_FUNC_PTRC(pf);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
162 cyg_drv_mutex_init(&devinit_lock);
2949
b72667909323 NAND: add CYGBLD_IO_NAND_BUILD_UTILS; tidy bbt code
Ross Younger <wry@ecoscentric.com>
parents: 2948
diff changeset
163 cyg_nand_bbt_initx();
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
164 nand_default_pf = pf;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
165 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
166
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
167 __externC
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
168 cyg_nand_partition* cyg_nand_get_partition(cyg_nand_device *dev, unsigned partno)
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
169 {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
170 if ((partno < 0) || (partno >= CYGNUM_NAND_MAX_PARTITIONS))
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
171 return NULL;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
172 LOCK_DEV(dev);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
173 cyg_nand_partition *rv = &(dev->partition[partno]);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
174 UNLOCK_DEV(dev);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
175 if (!rv->dev) return NULL; /* partition inactive */
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
176 return rv;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
177 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
178
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
179 __externC
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
180 int cyg_nand_lookup(const char *devname, cyg_nand_device **dev_o)
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
181 {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
182 int rv = -ENOENT;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
183 if (dev_o) {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
184 CYG_CHECK_DATA_PTRC(dev_o);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
185 *dev_o = 0;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
186 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
187 if (!devname) return -EINVAL;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
188
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
189 LOCK_devinit(); // ++++++++++++++++++++++++++++++++++++++++++++
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
190 cyg_nand_device *dev;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
191 for (dev = &cyg_nanddevtab[0]; dev != &cyg_nanddevtab_end; dev++) {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
192 if (0==strcmp(devname, dev->devname)) {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
193 rv = 0;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
194 break;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
195 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
196 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
197 if (!rv) {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
198 if (!dev->is_inited) {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
199 int i;
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
200
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
201 if (dev->version != 2) {
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
202 NAND_ERROR(dev, "Device %s declares incompatible version %d (expected 2)", devname, dev->version);
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
203 goto done;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
204 }
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
205 CYG_CHECK_DATA_PTRC(dev->fns);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
206 CYG_CHECK_FUNC_PTRC(dev->fns->devinit);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
207
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
208 dev->pf = nand_default_pf;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
209 for (i=0; i<CYGNUM_NAND_MAX_PARTITIONS; i++)
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
210 dev->partition[i].dev = 0;
2989
8fb3f9a53423 Further refine CYGSEM_IO_NAND_USE_BBT, drop the relevant parts of the struct when not enabled.
Ross Younger <wry@ecoscentric.com>
parents: 2976
diff changeset
211 #ifdef CYGSEM_IO_NAND_USE_BBT
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
212 dev->bbt.data = 0; // Paranoia, ensure devinit sets up
2989
8fb3f9a53423 Further refine CYGSEM_IO_NAND_USE_BBT, drop the relevant parts of the struct when not enabled.
Ross Younger <wry@ecoscentric.com>
parents: 2976
diff changeset
213 #endif
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
214
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
215 rv = dev->fns->devinit(dev);
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
216
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
217 if (rv) {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
218 NAND_ERROR(dev,"Could not initialise NAND device \"%s\": code %d\n", devname, rv);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
219 goto done;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
220 }
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
221
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
222 // Now check that we have everything we need
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
223 CYG_CHECK_FUNC_PTRC(dev->fns->read_begin);
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
224 CYG_CHECK_FUNC_PTRC(dev->fns->read_stride);
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
225 CYG_CHECK_FUNC_PTRC(dev->fns->read_finish);
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
226 CYG_CHECK_FUNC_PTRC(dev->fns->write_begin);
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
227 CYG_CHECK_FUNC_PTRC(dev->fns->write_stride);
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
228 CYG_CHECK_FUNC_PTRC(dev->fns->write_finish);
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
229
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
230 CYG_CHECK_FUNC_PTRC(dev->fns->erase_block);
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
231 CYG_CHECK_FUNC_PTRC(dev->fns->is_factory_bad);
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
232
2989
8fb3f9a53423 Further refine CYGSEM_IO_NAND_USE_BBT, drop the relevant parts of the struct when not enabled.
Ross Younger <wry@ecoscentric.com>
parents: 2976
diff changeset
233 #ifdef CYGSEM_IO_NAND_USE_BBT
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
234 CYG_CHECK_DATA_PTRC(dev->bbt.data);
2989
8fb3f9a53423 Further refine CYGSEM_IO_NAND_USE_BBT, drop the relevant parts of the struct when not enabled.
Ross Younger <wry@ecoscentric.com>
parents: 2976
diff changeset
235 #endif
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
236 CYG_CHECK_DATA_PTRC(dev->ecc);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
237 CYG_CHECK_DATA_PTRC(dev->oob);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
238 if (!dev->chipsize_log ||
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
239 !dev->blockcount_bits ||
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
240 !dev->block_page_bits ||
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
241 !dev->spare_per_page ||
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
242 !dev->page_bits ||
2989
8fb3f9a53423 Further refine CYGSEM_IO_NAND_USE_BBT, drop the relevant parts of the struct when not enabled.
Ross Younger <wry@ecoscentric.com>
parents: 2976
diff changeset
243 #ifdef CYGSEM_IO_NAND_USE_BBT
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
244 !dev->bbt.data ||
2989
8fb3f9a53423 Further refine CYGSEM_IO_NAND_USE_BBT, drop the relevant parts of the struct when not enabled.
Ross Younger <wry@ecoscentric.com>
parents: 2976
diff changeset
245 #endif
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
246 !dev->ecc ||
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
247 !dev->oob) {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
248 NAND_ERROR(dev,"BUG: NAND driver devinit did not fill in all required fields - disabling device\n");
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
249 rv = -ENOSYS;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
250 goto done;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
251 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
252
2989
8fb3f9a53423 Further refine CYGSEM_IO_NAND_USE_BBT, drop the relevant parts of the struct when not enabled.
Ross Younger <wry@ecoscentric.com>
parents: 2976
diff changeset
253 #ifdef CYGSEM_IO_NAND_USE_BBT
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
254 if (dev->bbt.datasize < (1 << (dev->blockcount_bits-2)) ) {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
255 NAND_ERROR(dev,"BUG: NAND driver declared bbt.data_size isn't big enough (got %lu, want %u) - disabling device\n", (unsigned long) dev->bbt.datasize, (1 << (dev->blockcount_bits-2)));
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
256 rv = -ENOSYS;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
257 goto done;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
258 }
2989
8fb3f9a53423 Further refine CYGSEM_IO_NAND_USE_BBT, drop the relevant parts of the struct when not enabled.
Ross Younger <wry@ecoscentric.com>
parents: 2976
diff changeset
259 #endif
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
260
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
261 if ( dev->oob->ecc_size != CYG_NAND_ECCPERPAGE(dev) ) {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
262 NAND_ERROR(dev,"BUG: NAND driver has inconsistent ECC size declaration (oob says %d, ecc says %d) - disabling device\n", dev->oob->ecc_size, CYG_NAND_ECCPERPAGE(dev));
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
263 rv = -ENOSYS;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
264 goto done;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
265 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
266
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
267 // NOW we are ready to read from the device !
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
268
2948
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
269 #ifdef CYGSEM_IO_NAND_USE_BBT
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
270 rv = cyg_nand_bbti_find_tables(dev);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
271 if (rv == -ENOENT) {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
272 NAND_CHATTER(1,dev, "Creating initial bad block table on device %s\n", devname);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
273 rv = cyg_nand_bbti_build_tables(dev);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
274 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
275 if (rv != 0) {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
276 NAND_ERROR(dev,"Cannot find or build BBT (%d)\n", -rv);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
277 goto done;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
278 }
2948
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
279 #endif
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
280
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
281 cyg_drv_mutex_init(&dev->devlock);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
282 dev->is_inited = 1;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
283
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
284 int live_partitions = 0;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
285 for (i=0; i<CYGNUM_NAND_MAX_PARTITIONS; i++)
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
286 if (dev->partition[i].dev) ++live_partitions;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
287 if (live_partitions)
2992
d0daa15943a5 NAND: cosmetic messages fix
Ross Younger <wry@ecoscentric.com>
parents: 2989
diff changeset
288 NAND_CHATTER(1,dev, "%s devinit complete, %u partition%c configured\n", devname, live_partitions, live_partitions==1 ? ' ' : 's' );
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
289 else
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
290 NAND_CHATTER(1,dev, "%s devinit complete, NO partitions configured!\n", devname); // hope they know what they're doing.
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
291 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
292 if (dev_o) *dev_o = dev;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
293 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
294 done:
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
295 UNLOCK_devinit(); // ------------------------------------------
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
296 return rv;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
297 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
298
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
299 /* ============================================================ */
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
300 /* Device access */
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
301
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
302 #define DEV_INIT_CHECK(dev) do { if (!dev->is_inited) return -ENXIO; } while(0)
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
303 #define PARTITION_CHECK(p) do { if (!p->dev) return -ENXIO; } while(0)
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
304
2994
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
305 // Partition-to-Device and Device-to-Partition address xlation
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
306 #define BLOCK_P_TO_D(_part,_block) ((_block) + (_part)->first)
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
307 #define BLOCK_D_TO_P(_part,_block) ((_block) - (_part)->first)
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
308
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
309 #define PAGE_P_TO_D(_part,_page) ((_page) + (_part)->first * CYG_NAND_PAGES_PER_BLOCK((_part)->dev) )
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
310 #define PAGE_D_TO_P(_part,_page) ((_page) - (_part)->first * CYG_NAND_PAGES_PER_BLOCK((_part)->dev) )
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
311
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
312 /* Sanity check helpers: these take a partition and a DEVICE address */
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
313 static inline int valid_block_addr(cyg_nand_partition *part, cyg_nand_block_addr block)
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
314 {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
315 return ( (block < part->first) || (block > part->last) ) ? -ENOENT : 0;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
316 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
317
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
318 static int valid_page_addr(cyg_nand_partition *part, cyg_nand_page_addr page)
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
319 {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
320 cyg_nand_block_addr block = CYG_NAND_PAGE2BLOCKADDR(part->dev,page);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
321 int rv = valid_block_addr(part, block);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
322 if (rv != 0)
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
323 NAND_CHATTER(1,part->dev, "Invalid attempted access to page %d\n", page);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
324 return rv;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
325 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
326
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
327 #define EG(what) do { rv = (what); if (rv != 0) goto err_exit; } while(0)
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
328
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
329 __externC
2994
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
330 int cyg_nandp_read_page(cyg_nand_partition *prt, cyg_nand_page_addr ppage,
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
331 void * dest, void * spare, size_t spare_size)
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
332 {
2975
7050b2f79b6e NAND bbt: fix internal race
Ross Younger <wry@ecoscentric.com>
parents: 2970
diff changeset
333 int rv, locked=0;
2976
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
334 TIMETAG_INIT();
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
335 PARTITION_CHECK(prt);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
336 cyg_nand_device *dev = prt->dev;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
337 DEV_INIT_CHECK(dev);
2994
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
338 cyg_nand_page_addr page = PAGE_P_TO_D(prt,ppage);
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
339
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
340 if (spare_size > dev->spare_per_page) return -EFBIG;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
341
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
342 EG(valid_page_addr(prt, page));
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
343
2948
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
344 #ifdef CYGSEM_IO_NAND_USE_BBT
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
345 cyg_nand_block_addr blk = CYG_NAND_PAGE2BLOCKADDR(dev,page);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
346 if (cyg_nand_bbti_query(dev, blk) != CYG_NAND_BBT_OK) {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
347 NAND_CHATTER(1,dev,"Asked to read page %u in bad block %u\n", page, blk);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
348 EG(-EINVAL);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
349 }
2948
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
350 #endif
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
351
2975
7050b2f79b6e NAND bbt: fix internal race
Ross Younger <wry@ecoscentric.com>
parents: 2970
diff changeset
352 LOCK_DEV(dev);
7050b2f79b6e NAND bbt: fix internal race
Ross Younger <wry@ecoscentric.com>
parents: 2970
diff changeset
353 locked = 1;
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
354 EG(nandi_read_whole_page_raw(dev, page, dest, spare, spare_size, 1));
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
355
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
356 err_exit:
2975
7050b2f79b6e NAND bbt: fix internal race
Ross Younger <wry@ecoscentric.com>
parents: 2970
diff changeset
357 if (locked) UNLOCK_DEV(dev);
2976
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
358 TIMETAG();
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
359 return rv;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
360 }
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
361
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
362
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
363
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
364 __externC
2994
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
365 int cyg_nandp_read_part_page(cyg_nand_partition *prt, cyg_nand_page_addr ppage,
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
366 void * dest, size_t offset, size_t length, int check_ecc)
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
367
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
368 {
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
369 int rv;
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
370 PARTITION_CHECK(prt);
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
371 cyg_nand_device *dev = prt->dev;
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
372 DEV_INIT_CHECK(dev);
2994
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
373 cyg_nand_page_addr page = PAGE_P_TO_D(prt,ppage);
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
374 CYG_BYTE *pagebuffer;
2975
7050b2f79b6e NAND bbt: fix internal race
Ross Younger <wry@ecoscentric.com>
parents: 2970
diff changeset
375 int got_pagebuf = 0, locked = 0;
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
376
2994
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
377 if (offset + length > CYG_NAND_BYTES_PER_PAGE(dev)) return -EFBIG;
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
378
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
379 EG(valid_page_addr(prt, page));
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
380
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
381 #ifdef CYGSEM_IO_NAND_USE_BBT
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
382 cyg_nand_block_addr blk = CYG_NAND_PAGE2BLOCKADDR(dev,page);
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
383 if (cyg_nand_bbti_query(dev, blk) != CYG_NAND_BBT_OK) {
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
384 NAND_CHATTER(1,dev,"Asked to read page %u in bad block %u\n", page, blk);
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
385 EG(-EINVAL);
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
386 }
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
387 #endif
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
388
2975
7050b2f79b6e NAND bbt: fix internal race
Ross Younger <wry@ecoscentric.com>
parents: 2970
diff changeset
389 LOCK_DEV(dev);
7050b2f79b6e NAND bbt: fix internal race
Ross Younger <wry@ecoscentric.com>
parents: 2970
diff changeset
390 locked = 1;
7050b2f79b6e NAND bbt: fix internal race
Ross Younger <wry@ecoscentric.com>
parents: 2970
diff changeset
391
2970
4d926b63650d NAND: Add device read_part_page function
Ross Younger <wry@ecoscentric.com>
parents: 2968
diff changeset
392 if (dev->fns->read_part_page && !check_ecc) {
4d926b63650d NAND: Add device read_part_page function
Ross Younger <wry@ecoscentric.com>
parents: 2968
diff changeset
393 EG(dev->fns->read_part_page(dev, dest, page, offset, length));
4d926b63650d NAND: Add device read_part_page function
Ross Younger <wry@ecoscentric.com>
parents: 2968
diff changeset
394 } else {
4d926b63650d NAND: Add device read_part_page function
Ross Younger <wry@ecoscentric.com>
parents: 2968
diff changeset
395 pagebuffer = nandi_grab_pagebuf();
4d926b63650d NAND: Add device read_part_page function
Ross Younger <wry@ecoscentric.com>
parents: 2968
diff changeset
396 got_pagebuf = 1;
4d926b63650d NAND: Add device read_part_page function
Ross Younger <wry@ecoscentric.com>
parents: 2968
diff changeset
397 EG(nandi_read_whole_page_raw(dev, page, pagebuffer, 0, 0, check_ecc));
4d926b63650d NAND: Add device read_part_page function
Ross Younger <wry@ecoscentric.com>
parents: 2968
diff changeset
398 if (dest)
4d926b63650d NAND: Add device read_part_page function
Ross Younger <wry@ecoscentric.com>
parents: 2968
diff changeset
399 memcpy(dest, &pagebuffer[offset], length);
4d926b63650d NAND: Add device read_part_page function
Ross Younger <wry@ecoscentric.com>
parents: 2968
diff changeset
400 }
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
401
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
402 err_exit:
2970
4d926b63650d NAND: Add device read_part_page function
Ross Younger <wry@ecoscentric.com>
parents: 2968
diff changeset
403 if (got_pagebuf) nandi_release_pagebuf();
2975
7050b2f79b6e NAND bbt: fix internal race
Ross Younger <wry@ecoscentric.com>
parents: 2970
diff changeset
404 if (locked) UNLOCK_DEV(dev);
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
405 return rv;
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
406 }
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
407
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
408
2975
7050b2f79b6e NAND bbt: fix internal race
Ross Younger <wry@ecoscentric.com>
parents: 2970
diff changeset
409 /* Internal, mostly-unchecked interface to read a page.
2994
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
410 * Takes a DEVICE address.
2975
7050b2f79b6e NAND bbt: fix internal race
Ross Younger <wry@ecoscentric.com>
parents: 2970
diff changeset
411 * Caller must hold the devlock! */
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
412 int nandi_read_whole_page_raw(cyg_nand_device *dev, cyg_nand_page_addr page,
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
413 CYG_BYTE * dest, CYG_BYTE * spare, size_t spare_size,
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
414 int check_ecc)
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
415 {
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
416 CYG_BYTE ecc_read[CYG_NAND_ECCPERPAGE(dev)],
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
417 ecc_calc[CYG_NAND_ECCPERPAGE(dev)];
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
418 CYG_BYTE *ecc_calc_p, *ecc_read_p;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
419
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
420 CYG_BYTE oob_buf[dev->spare_per_page];
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
421 int rv=0,tries=0;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
422 size_t remain;
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
423 const int do_hw_ecc = (dev->ecc->flags & NAND_ECC_FLAG_IS_HARDWARE) && check_ecc;
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
424
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
425 // Stride for reading from device:
2994
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
426 const unsigned read_data_stride = do_hw_ecc ? dev->ecc->data_size : CYG_NAND_BYTES_PER_PAGE(dev);
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
427 // Stride for calculating/checking/repairing ECC:
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
428 const unsigned ecc_data_stride = dev->ecc->data_size;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
429 // Stride within the ECC data
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
430 const unsigned ecc_stride = dev->ecc->ecc_size;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
431
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
432 if (dest) CYG_CHECK_DATA_PTRC(dest);
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
433 if (spare) CYG_CHECK_DATA_PTRC(spare);
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
434
2994
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
435 CYG_ASSERTC(CYG_NAND_BYTES_PER_PAGE(dev) % ecc_data_stride == 0);
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
436
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
437 do {
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
438 CYG_BYTE *data_dest = dest;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
439 CYG_BYTE *ecc_dest = ecc_calc;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
440
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
441 ++tries;
2994
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
442 remain = CYG_NAND_BYTES_PER_PAGE(dev);
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
443
2976
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
444 TIMETAG();
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
445 EG(dev->fns->read_begin(dev, page));
2976
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
446 TIMETAG();
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
447
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
448 if (dest) {
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
449 int step;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
450 while (remain) {
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
451 step = read_data_stride;
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
452 CYG_ASSERTC(remain >= read_data_stride);
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
453
2976
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
454 TIMETAG();
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
455 if (do_hw_ecc && dev->ecc->init) dev->ecc->init(dev);
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
456 EG(dev->fns->read_stride(dev, data_dest, read_data_stride));
2976
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
457 TIMETAG();
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
458
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
459 if (do_hw_ecc) {
2968
368f9c978e57 NAND: Drop poorly-conceived ecc sub-stride support
Ross Younger <wry@ecoscentric.com>
parents: 2966
diff changeset
460 dev->ecc->calc(dev, 0, ecc_dest);
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
461 ecc_dest += ecc_stride;
2976
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
462 TIMETAG();
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
463 }
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
464
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
465 data_dest += read_data_stride;
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
466 remain -= read_data_stride;
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
467 }
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
468
2976
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
469 TIMETAG();
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
470 EG(dev->fns->read_finish(dev, oob_buf, dev->spare_per_page));
2976
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
471 TIMETAG();
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
472 nand_oob_unpack(dev, spare, spare_size, ecc_read, oob_buf);
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
473
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
474 if (check_ecc) {
2976
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
475 TIMETAG();
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
476 if (!do_hw_ecc) {
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
477 // Calculate software ECC in one go to try and take
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
478 // advantage of the cache.
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
479 data_dest = dest;
2994
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
480 remain = CYG_NAND_BYTES_PER_PAGE(dev);
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
481 ecc_calc_p = ecc_calc;
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
482
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
483 while (remain) {
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
484 if (dev->ecc->init) dev->ecc->init(dev);
2968
368f9c978e57 NAND: Drop poorly-conceived ecc sub-stride support
Ross Younger <wry@ecoscentric.com>
parents: 2966
diff changeset
485 dev->ecc->calc(dev, data_dest, ecc_calc_p);
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
486
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
487 remain -= ecc_data_stride;
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
488 data_dest += ecc_data_stride;
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
489 ecc_calc_p += ecc_stride;
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
490 }
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
491 }
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
492
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
493 // Now repair ...
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
494 rv = 0;
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
495 int step_rv;
2994
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
496 remain = CYG_NAND_BYTES_PER_PAGE(dev);
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
497 data_dest = dest;
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
498
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
499 ecc_calc_p = ecc_calc;
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
500 ecc_read_p = ecc_read;
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
501
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
502 while (remain) {
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
503 CYG_ASSERTC(remain >= ecc_data_stride);
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
504
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
505 step_rv = dev->ecc->repair(dev,data_dest,ecc_data_stride,ecc_read_p,ecc_calc_p);
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
506 if (step_rv == -1) {
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
507 rv = -1;
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
508 break;
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
509 }
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
510 rv |= step_rv;
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
511
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
512 data_dest += ecc_data_stride;
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
513 ecc_read_p += ecc_stride;
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
514 ecc_calc_p += ecc_stride;
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
515 remain -= ecc_data_stride;
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
516 }
2976
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
517 TIMETAG();
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
518 }
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
519 } else { // !dest: very simple case
2976
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
520 TIMETAG();
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
521 EG(dev->fns->read_finish(dev, oob_buf, dev->spare_per_page));
2976
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
522 TIMETAG();
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
523 rv = 0;
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
524 nand_oob_unpack(dev, spare, spare_size, ecc_read, oob_buf);
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
525 }
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
526
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
527 if (rv==-1 && (tries < CYGNUM_NAND_MAX_READ_RETRIES) ) {
2953
b8b477f45f0c NAND: cosmetic messages fix
Ross Younger <wry@ecoscentric.com>
parents: 2949
diff changeset
528 NAND_CHATTER(4, dev, "ECC uncorrectable error on read, retrying\n");
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
529 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
530 } while (rv==-1 && (tries < CYGNUM_NAND_MAX_READ_RETRIES) );
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
531
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
532 switch (rv) {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
533 case 0:
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
534 NAND_CHATTER(8,dev,"Read page %u OK\n", page);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
535 break;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
536 case 1:
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
537 case 2:
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
538 case 3:
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
539 NAND_CHATTER(2,dev, "Page %u ECC correction, type %d\n", page,rv);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
540 rv=0;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
541 break;
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
542 case -1:
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
543 default:
2953
b8b477f45f0c NAND: cosmetic messages fix
Ross Younger <wry@ecoscentric.com>
parents: 2949
diff changeset
544 NAND_ERROR(dev,"Page %u read gave ECC uncorrectable error\n", page);
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
545 rv=-EIO;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
546 break;
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
547 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
548 err_exit:
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
549 return rv;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
550 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
551
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
552 __externC
2994
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
553 int cyg_nandp_write_page(cyg_nand_partition *prt, cyg_nand_page_addr ppage,
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
554 const void * src, const void * spare, size_t spare_size)
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
555 {
2975
7050b2f79b6e NAND bbt: fix internal race
Ross Younger <wry@ecoscentric.com>
parents: 2970
diff changeset
556 int rv, locked = 0;
2976
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
557 TIMETAG_INIT();
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
558 PARTITION_CHECK(prt);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
559 cyg_nand_device *dev = prt->dev;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
560 DEV_INIT_CHECK(dev);
2994
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
561 cyg_nand_page_addr page = PAGE_P_TO_D(prt,ppage);
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
562
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
563 EG(valid_page_addr(prt, page));
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
564
2948
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
565 #ifdef CYGSEM_IO_NAND_USE_BBT
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
566 cyg_nand_block_addr blk = CYG_NAND_PAGE2BLOCKADDR(dev,page);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
567 if (cyg_nand_bbti_query(dev, blk) != CYG_NAND_BBT_OK) {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
568 NAND_CHATTER(1,dev,"Asked to write page %u in bad block %u\n", page, blk);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
569 EG(-EINVAL);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
570 }
2948
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
571 #endif
2975
7050b2f79b6e NAND bbt: fix internal race
Ross Younger <wry@ecoscentric.com>
parents: 2970
diff changeset
572 LOCK_DEV(dev);
7050b2f79b6e NAND bbt: fix internal race
Ross Younger <wry@ecoscentric.com>
parents: 2970
diff changeset
573 locked = 1;
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
574 EG(nandi_write_page_raw(dev, page, src, spare, spare_size));
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
575
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
576 err_exit:
2975
7050b2f79b6e NAND bbt: fix internal race
Ross Younger <wry@ecoscentric.com>
parents: 2970
diff changeset
577 if (locked) UNLOCK_DEV(dev);
2976
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
578 TIMETAG();
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
579 return rv;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
580 }
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
581
2994
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
582 /* Internal, mostly-unchecked interface to write a page.
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
583 * Takes a DEVICE address. */
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
584 __externC
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
585 int nandi_write_page_raw(cyg_nand_device *dev, cyg_nand_page_addr page,
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
586 const CYG_BYTE * src, const CYG_BYTE * spare, size_t spare_size)
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
587 {
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
588 #ifdef CYGSEM_IO_NAND_READONLY
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
589 return -EROFS;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
590 #else
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
591 int rv;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
592 CYG_BYTE oob_packed[dev->spare_per_page];
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
593 CYG_BYTE ecc[CYG_NAND_ECCPERPAGE(dev)];
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
594
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
595 const int do_hw_ecc = (dev->ecc->flags & NAND_ECC_FLAG_IS_HARDWARE);
2994
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
596 const unsigned write_data_stride = do_hw_ecc ? dev->ecc->data_size : CYG_NAND_BYTES_PER_PAGE(dev);
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
597 const unsigned ecc_data_stride = dev->ecc->data_size;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
598 const unsigned ecc_stride = dev->ecc->ecc_size;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
599 size_t remain;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
600 CYG_BYTE *ecc_dest = ecc;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
601
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
602 memset(ecc, 0xff, CYG_NAND_ECCPERPAGE(dev));
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
603
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
604 if (src) CYG_CHECK_DATA_PTRC(src);
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
605 if (spare) CYG_CHECK_DATA_PTRC(spare);
2994
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
606 CYG_ASSERTC(CYG_NAND_BYTES_PER_PAGE(dev) % ecc_data_stride == 0);
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
607
2976
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
608 TIMETAG();
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
609 // If we're doing software ECC, do it all in one go now.
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
610 if (src && !do_hw_ecc) {
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
611 const CYG_BYTE *data_src = src;
2994
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
612 remain = CYG_NAND_BYTES_PER_PAGE(dev);
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
613
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
614 while (remain) {
2968
368f9c978e57 NAND: Drop poorly-conceived ecc sub-stride support
Ross Younger <wry@ecoscentric.com>
parents: 2966
diff changeset
615 CYG_ASSERTC(remain >= ecc_data_stride);
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
616 if (dev->ecc->init) dev->ecc->init(dev);
2968
368f9c978e57 NAND: Drop poorly-conceived ecc sub-stride support
Ross Younger <wry@ecoscentric.com>
parents: 2966
diff changeset
617 dev->ecc->calc(dev, data_src, ecc_dest);
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
618
2968
368f9c978e57 NAND: Drop poorly-conceived ecc sub-stride support
Ross Younger <wry@ecoscentric.com>
parents: 2966
diff changeset
619 remain -= ecc_data_stride;
368f9c978e57 NAND: Drop poorly-conceived ecc sub-stride support
Ross Younger <wry@ecoscentric.com>
parents: 2966
diff changeset
620 data_src += ecc_data_stride;
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
621 ecc_dest += ecc_stride;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
622 }
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
623 }
2976
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
624 TIMETAG();
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
625
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
626 EG(dev->fns->write_begin(dev, page));
2976
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
627 TIMETAG();
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
628 if (src) {
2994
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
629 remain = CYG_NAND_BYTES_PER_PAGE(dev);
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
630 while (remain) {
2968
368f9c978e57 NAND: Drop poorly-conceived ecc sub-stride support
Ross Younger <wry@ecoscentric.com>
parents: 2966
diff changeset
631 CYG_ASSERTC(remain >= write_data_stride);
2976
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
632 TIMETAG();
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
633 if (do_hw_ecc && dev->ecc->init) dev->ecc->init(dev);
2968
368f9c978e57 NAND: Drop poorly-conceived ecc sub-stride support
Ross Younger <wry@ecoscentric.com>
parents: 2966
diff changeset
634 EG(dev->fns->write_stride(dev, src, write_data_stride));
2976
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
635 TIMETAG();
2966
c6ce6b63dcb5 NAND: app interface change: read_page does only whole page, read_part_page does part pages
Ross Younger <wry@ecoscentric.com>
parents: 2953
diff changeset
636 if (do_hw_ecc) {
2968
368f9c978e57 NAND: Drop poorly-conceived ecc sub-stride support
Ross Younger <wry@ecoscentric.com>
parents: 2966
diff changeset
637 dev->ecc->calc(dev, 0, ecc_dest);
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
638 ecc_dest += ecc_stride;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
639 }
2968
368f9c978e57 NAND: Drop poorly-conceived ecc sub-stride support
Ross Younger <wry@ecoscentric.com>
parents: 2966
diff changeset
640 src += write_data_stride;
368f9c978e57 NAND: Drop poorly-conceived ecc sub-stride support
Ross Younger <wry@ecoscentric.com>
parents: 2966
diff changeset
641 remain -= write_data_stride;
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
642 }
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
643 }
2976
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
644 TIMETAG();
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
645
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
646 nand_oob_pack(dev, spare, spare_size, ecc, oob_packed);
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
647 NAND_CHATTER(8,dev,"Write page %u\n", page);
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
648 EG(dev->fns->write_finish(dev, oob_packed, dev->spare_per_page));
2976
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
649 TIMETAG();
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
650
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
651 /* N.B. We don't read-back to verify; drivers may do so themselves if
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
652 * they wish. Typically the spec sheet says that a read-back test
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
653 * is unnecessary if the device reports a successful program, and
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
654 * if ECC is being used. */
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
655
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
656 err_exit:
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
657 return rv;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
658 #endif
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
659 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
660
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
661 __externC
2994
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
662 int cyg_nandp_erase_block(cyg_nand_partition *prt, cyg_nand_block_addr pblk)
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
663 {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
664 #ifdef CYGSEM_IO_NAND_READONLY
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
665 return -EROFS;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
666 #else
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
667 PARTITION_CHECK(prt);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
668 cyg_nand_device *dev = prt->dev;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
669 int rv;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
670 DEV_INIT_CHECK(dev);
2994
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
671 cyg_nand_block_addr blk = BLOCK_P_TO_D(prt, pblk);
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
672
2976
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
673 TIMETAG();
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
674 LOCK_DEV(dev);
2976
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
675 TIMETAG();
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
676
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
677 EG(valid_block_addr(prt, blk));
2948
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
678 #ifdef CYGSEM_IO_NAND_USE_BBT
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
679 if (cyg_nand_bbti_query(dev, blk) != CYG_NAND_BBT_OK) {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
680 NAND_CHATTER(1,dev,"Asked to erase bad block %u\n", blk);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
681 EG(-EINVAL);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
682 }
2948
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
683 #endif
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
684 NAND_CHATTER(8,dev,"Erasing block %u\n", blk);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
685 rv = dev->fns->erase_block(dev, blk);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
686 if (rv==-EIO) {
2948
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
687 #ifdef CYGSEM_IO_NAND_USE_BBT
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
688 cyg_nand_bbti_markbad(dev, blk); // deliberate ignore
2948
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
689 #endif
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
690 EG(rv);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
691 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
692 err_exit:
2976
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
693 TIMETAG();
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
694 UNLOCK_DEV(dev);
2976
758f9d488949 NAND: Add timing instrumentation hooks (disabled by default)
Ross Younger <wry@ecoscentric.com>
parents: 2975
diff changeset
695 TIMETAG();
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
696 return rv;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
697 #endif
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
698 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
699
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
700 __externC
2994
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
701 int cyg_nandp_bbt_query(cyg_nand_partition *prt, cyg_nand_block_addr pblk)
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
702 {
2948
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
703 #ifdef CYGSEM_IO_NAND_USE_BBT
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
704 int rv;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
705 PARTITION_CHECK(prt);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
706 cyg_nand_device *dev = prt->dev;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
707 DEV_INIT_CHECK(dev);
2994
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
708 cyg_nand_block_addr blk = BLOCK_P_TO_D(prt, pblk);
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
709 LOCK_DEV(dev);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
710 EG(valid_block_addr(prt, blk));
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
711 rv = cyg_nand_bbti_query(dev, blk);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
712 err_exit:
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
713 UNLOCK_DEV(dev);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
714 return rv;
2948
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
715 #else
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
716 return -ENOSYS;
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
717 #endif
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
718 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
719
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
720 __externC
2994
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
721 int cyg_nandp_bbt_markbad(cyg_nand_partition *prt, cyg_nand_block_addr pblk)
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
722 {
2948
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
723 #ifdef CYGSEM_IO_NAND_USE_BBT
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
724 int rv;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
725 PARTITION_CHECK(prt);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
726 cyg_nand_device *dev = prt->dev;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
727 DEV_INIT_CHECK(dev);
2994
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
728 cyg_nand_block_addr blk = BLOCK_P_TO_D(prt, pblk);
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
729 LOCK_DEV(dev);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
730 EG(valid_block_addr(prt, blk));
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
731 EG(cyg_nand_bbti_markbad(dev, blk));
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
732 err_exit:
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
733 UNLOCK_DEV(dev);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
734 return rv;
2948
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
735 #else
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
736 return -ENOSYS;
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
737 #endif
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
738 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
739
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
740 __externC
2994
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
741 int cyg_nand_bbt_markbad_pageaddr(cyg_nand_partition *prt, cyg_nand_page_addr ppg)
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
742 {
2948
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
743 #ifdef CYGSEM_IO_NAND_USE_BBT
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
744 int rv;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
745 PARTITION_CHECK(prt);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
746 cyg_nand_device *dev = prt->dev;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
747 DEV_INIT_CHECK(dev);
2994
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
748 cyg_nand_block_addr pblk = CYG_NAND_PAGE2BLOCKADDR(dev, ppg);
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
749 cyg_nand_block_addr blk = BLOCK_P_TO_D(prt, pblk);
3d3b0d53c2e5 NAND: application interface v2: functions take partition-relative addresses.
Ross Younger <wry@ecoscentric.com>
parents: 2992
diff changeset
750 EG(valid_block_addr(prt, blk));
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
751 LOCK_DEV(dev);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
752 EG(cyg_nand_bbti_markbad(dev, blk));
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
753 err_exit:
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
754 UNLOCK_DEV(dev);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
755 return rv;
2948
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
756 #else
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
757 return -ENOSYS;
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
758 #endif
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
759 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
760
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
761 /* Computes the ECC for a whole device page.
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
762 * 'page' points to the data; a whole page will necessarily be read.
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
763 * The computed ECC will be stored in 'ecc_o'; CYG_NAND_ECCPERPAGE(dev)
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
764 * bytes will be written. */
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
765 void nand_ecci_calc_page(cyg_nand_device *dev, const CYG_BYTE *page, CYG_BYTE *ecc_o)
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
766 {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
767 int i;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
768 const int nblocks = (1<<dev->page_bits) / dev->ecc->data_size;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
769
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
770 CYG_CHECK_DATA_PTRC(page);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
771 CYG_CHECK_DATA_PTRC(ecc_o);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
772
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
773 for (i=0; i<nblocks; i++) {
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
774 if (dev->ecc->init)
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
775 dev->ecc->init(dev);
2968
368f9c978e57 NAND: Drop poorly-conceived ecc sub-stride support
Ross Younger <wry@ecoscentric.com>
parents: 2966
diff changeset
776 dev->ecc->calc(dev,page,ecc_o);
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
777 page += dev->ecc->data_size;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
778 ecc_o += dev->ecc->ecc_size;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
779 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
780 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
781
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
782 /* Checks and (if necessary) repairs the ECC for (up to) a whole device page.
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
783 * 'page' points to the data; an error at position after @nbytes@ will not
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
784 * be corrected.
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
785 * Broadly the same semantics as for cyg_nand_ecc_t.repair;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
786 * both ECCs are of size CYG_NAND_ECCPERPAGE(dev), and ecc_read may
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
787 * be corrected as well as the data.
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
788 * Returns:
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
789 * 0 for no errors
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
790 * 1 if there was at least one corrected data error
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
791 * 2 if there was at least one corrected ECC error
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
792 * 3 if there was at least one corrected error in both data and ECC
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
793 * -1 if there was an uncorrectable error (>1 bit in a single ECC block)
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
794 */
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
795 int nand_ecci_repair_page(cyg_nand_device *dev, CYG_BYTE *page, size_t remain,
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
796 CYG_BYTE *ecc_read, const CYG_BYTE *ecc_calc)
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
797 {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
798 int i, page_rv=0;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
799 const int nblocks = (1<<dev->page_bits) / dev->ecc->data_size;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
800 CYG_CHECK_DATA_PTRC(page);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
801 CYG_CHECK_DATA_PTRC(ecc_read);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
802 CYG_CHECK_DATA_PTRC(ecc_calc);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
803
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
804 for (i=0; i<nblocks; i++) {
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
805 int stride = dev->ecc->data_size;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
806 if (stride > remain) stride = remain;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
807 int chunk_rv = dev->ecc->repair(dev,page,stride,ecc_read,ecc_calc);
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
808 if (chunk_rv < 0) return chunk_rv;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
809 page_rv |= chunk_rv;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
810 page += dev->ecc->data_size;
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
811 remain -= dev->ecc->data_size;
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
812 ecc_read += dev->ecc->ecc_size;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
813 ecc_calc += dev->ecc->ecc_size;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
814 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
815 return page_rv;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
816 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
817