annotate packages/io/nand/current/src/nand.c @ 2953:b8b477f45f0c

NAND: cosmetic messages fix
author Ross Younger <wry@ecoscentric.com>
date Thu, 29 Oct 2009 13:21:23 +0000
parents b72667909323
children c6ce6b63dcb5
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 /* ============================================================ */
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
61
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
62 /* 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
63 * writes to device->isInited.
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
64 *
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
65 * 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
66 * the structure, and the hardware itself.
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
67 *
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
68 * Rules:
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
69 * 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
70 * (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
71 * initialisation is complete);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
72 * 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
73 * 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
74 * 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
75 * 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
76 * 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
77 * 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
78 * (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
79 * 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
80 * 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
81 *
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
82 * 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
83 * 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
84 * 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
85 */
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
86
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
87 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
88
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
89 #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
90 #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
91
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
92 /* Per-device lock.
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
93 * 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
94 * 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
95 * platform level. */
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
96 #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
97 #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
98
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
99 /* ============================================================ */
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
100 /* Initialisation and lookup */
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
101
2949
b72667909323 NAND: add CYGBLD_IO_NAND_BUILD_UTILS; tidy bbt code
Ross Younger <wry@ecoscentric.com>
parents: 2948
diff changeset
102 __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
103 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
104
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
105 // 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
106 // never need to call this themselves.
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
107 __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
108 {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
109 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
110 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
111 cyg_nand_bbt_initx();
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
112 nand_default_pf = pf;
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
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
115 __externC
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
116 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
117 {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
118 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
119 return NULL;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
120 LOCK_DEV(dev);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
121 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
122 UNLOCK_DEV(dev);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
123 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
124 return rv;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
125 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
126
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
127 __externC
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
128 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
129 {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
130 int rv = -ENOENT;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
131 if (dev_o) {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
132 CYG_CHECK_DATA_PTRC(dev_o);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
133 *dev_o = 0;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
134 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
135 if (!devname) return -EINVAL;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
136
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
137 LOCK_devinit(); // ++++++++++++++++++++++++++++++++++++++++++++
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
138 cyg_nand_device *dev;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
139 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
140 if (0==strcmp(devname, dev->devname)) {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
141 rv = 0;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
142 break;
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 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
145 if (!rv) {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
146 if (!dev->is_inited) {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
147 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
148
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
149 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
150 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
151 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
152 }
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
153 CYG_CHECK_DATA_PTRC(dev->fns);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
154 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
155
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
156 dev->pf = nand_default_pf;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
157 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
158 dev->partition[i].dev = 0;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
159 dev->bbt.data = 0; // Paranoia, ensure devinit sets up
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
160
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
161 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
162
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
163 if (rv) {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
164 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
165 goto done;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
166 }
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
167
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
168 // 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
169 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
170 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
171 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
172 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
173 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
174 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
175
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
176 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
177 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
178
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
179 CYG_CHECK_DATA_PTRC(dev->bbt.data);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
180 CYG_CHECK_DATA_PTRC(dev->ecc);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
181 CYG_CHECK_DATA_PTRC(dev->oob);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
182 if (!dev->chipsize_log ||
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
183 !dev->blockcount_bits ||
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
184 !dev->block_page_bits ||
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
185 !dev->spare_per_page ||
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
186 !dev->page_bits ||
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
187 !dev->bbt.data ||
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
188 !dev->ecc ||
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
189 !dev->oob) {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
190 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
191 rv = -ENOSYS;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
192 goto done;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
193 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
194
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
195 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
196 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
197 rv = -ENOSYS;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
198 goto done;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
199 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
200
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
201 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
202 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
203 rv = -ENOSYS;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
204 goto done;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
205 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
206
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
207 // 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
208
2948
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
209 #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
210 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
211 if (rv == -ENOENT) {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
212 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
213 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
214 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
215 if (rv != 0) {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
216 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
217 goto done;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
218 }
2948
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
219 #endif
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
220
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
221 cyg_drv_mutex_init(&dev->devlock);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
222 dev->is_inited = 1;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
223
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
224 int live_partitions = 0;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
225 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
226 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
227 if (live_partitions)
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
228 NAND_CHATTER(1,dev, "%s devinit complete, %u partitions configured\n", devname, live_partitions);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
229 else
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
230 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
231 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
232 if (dev_o) *dev_o = dev;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
233 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
234 done:
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
235 UNLOCK_devinit(); // ------------------------------------------
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
236 return rv;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
237 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
238
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
239 /* ============================================================ */
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
240 /* Device access */
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
241
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
242 #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
243 #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
244
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
245 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
246 {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
247 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
248 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
249
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
250 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
251 {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
252 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
253 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
254 if (rv != 0)
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
255 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
256 return rv;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
257 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
258
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
259 #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
260
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
261 __externC
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
262 int cyg_nand_read_page(cyg_nand_partition *prt, cyg_nand_page_addr page,
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
263 void * dest, size_t size, void * spare, size_t spare_size)
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
264 {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
265 int rv;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
266 PARTITION_CHECK(prt);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
267 cyg_nand_device *dev = prt->dev;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
268 DEV_INIT_CHECK(dev);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
269
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
270 if (size > (1<<dev->page_bits)) return -EFBIG;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
271 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
272
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
273 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
274
2948
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
275 #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
276 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
277 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
278 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
279 EG(-EINVAL);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
280 }
2948
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
281 #endif
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
282
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
283 EG(nandi_read_page_raw(dev, page, dest, size, spare, spare_size));
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
284
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
285 err_exit:
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
286 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
287 }
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
288
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
289
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
290 /* Internal, mostly-unchecked interface to read a page. */
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
291 int nandi_read_page_raw(cyg_nand_device *dev, cyg_nand_page_addr page,
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
292 CYG_BYTE * dest, const size_t sizex, CYG_BYTE * spare, size_t spare_size)
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
293 {
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
294 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
295 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
296 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
297
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
298 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
299 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
300 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
301 const int ecc_is_hw = (dev->ecc->flags & NAND_ECC_FLAG_IS_HARDWARE);
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
302
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
303 // Stride for reading from device:
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
304 const unsigned read_data_stride = ecc_is_hw ? dev->ecc->data_size : NAND_BYTES_PER_PAGE(dev);
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
305 // 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
306 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
307 // 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
308 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
309
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
310 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
311 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
312
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
313 if (!ecc_is_hw) {
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
314 // if s/w ecc, part-stride reads are not yet supported
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
315 if (sizex % ecc_data_stride != 0)
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
316 EG(-ENOSYS);
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
317 }
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
318
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
319 LOCK_DEV(dev);
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
320
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
321 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
322 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
323 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
324
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
325 ++tries;
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
326 remain = sizex;
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
327
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
328 EG(dev->fns->read_begin(dev, page));
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
329
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
330 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
331 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
332 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
333 step = read_data_stride;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
334
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
335 if (ecc_is_hw && dev->ecc->init) dev->ecc->init(dev);
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
336
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
337 if (step > remain) {
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
338 step = remain;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
339 EG(dev->fns->read_stride(dev, data_dest, step));
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
340 EG(dev->fns->read_stride(dev, 0, read_data_stride - step));
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
341 } else {
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(dev->fns->read_stride(dev, data_dest, step));
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
343 }
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
344 if (ecc_is_hw) {
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
345 dev->ecc->calc(dev, 0, 0, ecc_dest);
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
346 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
347 }
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
348 data_dest += step;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
349 remain -= step;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
350 }
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
351 }
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
352
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
353 EG(dev->fns->read_finish(dev, oob_buf, dev->spare_per_page));
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
354
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
355 nand_oob_unpack(dev, spare, spare_size, ecc_read, oob_buf);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
356
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
357 if (dest && !ecc_is_hw) {
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
358 // Calculate software ECC in one go to try and take advantage
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
359 // of the instruction cache.
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
360 int step = ecc_data_stride;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
361 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
362 remain = sizex;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
363 ecc_calc_p = 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
364
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
365 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
366 // We have already checked above that we're not doing any part-strides.
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
367 if (dev->ecc->init) dev->ecc->init(dev);
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
368 dev->ecc->calc(dev, data_dest, step, ecc_calc_p);
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
369
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
370 remain -= step;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
371 data_dest += step;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
372 ecc_calc_p += 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
373 }
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
374 }
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
375
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
376 rv = 0;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
377 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
378 int step = ecc_data_stride;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
379 int step_rv;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
380 remain = sizex;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
381 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
382
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
383 ecc_calc_p = 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
384 ecc_read_p = ecc_read;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
385
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
386 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
387 if (step > remain) step = remain;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
388
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
389 step_rv = dev->ecc->repair(dev,data_dest,step,ecc_read_p,ecc_calc_p);
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
390 if (step_rv == -1) {
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
391 rv = -1;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
392 break;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
393 }
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
394 rv |= step_rv;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
395
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
396 data_dest += step;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
397 ecc_read_p += 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
398 ecc_calc_p += 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
399 remain -= step;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
400 }
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
401 }
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
402
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
403 if (rv==-1 && (tries < CYGNUM_NAND_MAX_READ_RETRIES) ) {
2953
b8b477f45f0c NAND: cosmetic messages fix
Ross Younger <wry@ecoscentric.com>
parents: 2949
diff changeset
404 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
405 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
406 } 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
407
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
408 switch (rv) {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
409 case 0:
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
410 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
411 break;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
412 case 1:
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
413 case 2:
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
414 case 3:
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
415 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
416 rv=0;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
417 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
418 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
419 default:
2953
b8b477f45f0c NAND: cosmetic messages fix
Ross Younger <wry@ecoscentric.com>
parents: 2949
diff changeset
420 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
421 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
422 break;
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
423 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
424 err_exit:
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
425 UNLOCK_DEV(dev);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
426 return rv;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
427 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
428
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
429 /* Internal, mostly-unchecked interface to write a page. */
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
430 __externC
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
431 int cyg_nand_write_page(cyg_nand_partition *prt, cyg_nand_page_addr page,
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
432 const void * src, size_t size, const void * spare, size_t spare_size)
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
433 {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
434 int rv;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
435 PARTITION_CHECK(prt);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
436 cyg_nand_device *dev = prt->dev;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
437 DEV_INIT_CHECK(dev);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
438
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
439 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
440
2948
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
441 #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
442 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
443 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
444 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
445 EG(-EINVAL);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
446 }
2948
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
447 #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
448 EG(nandi_write_page_raw(dev, page, src, size, spare, spare_size));
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
449
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
450 err_exit:
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
451 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
452 }
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
453
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
454 __externC
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
455 int nandi_write_page_raw(cyg_nand_device *dev, cyg_nand_page_addr page,
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
456 const CYG_BYTE * src, const size_t sizex, const CYG_BYTE * spare, size_t spare_size)
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
457 {
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
458 #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
459 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
460 #else
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
461 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
462 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
463 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
464
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
465 const int ecc_is_hw = (dev->ecc->flags & NAND_ECC_FLAG_IS_HARDWARE);
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
466 const unsigned write_data_stride = ecc_is_hw ? dev->ecc->data_size : NAND_BYTES_PER_PAGE(dev);
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
467 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
468 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
469 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
470 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
471
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
472 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
473
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
474 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
475 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
476
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
477 // If we're doing software ECC, do it all in one go now.
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
478 if (src && !ecc_is_hw) {
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
479 int step = ecc_data_stride;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
480 const CYG_BYTE *data_src = src;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
481 remain = sizex;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
482
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
483 // if s/w ecc, part-stride writes are not yet supported
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
484 if (remain % ecc_data_stride != 0)
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
485 EG(-ENOSYS);
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
486
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
487 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
488 //if (step > remain) step = remain; // NYI
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
489 if (dev->ecc->init) dev->ecc->init(dev);
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
490 dev->ecc->calc(dev, data_src, step, ecc_dest);
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
491
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
492 remain -= step;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
493 data_src += step;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
494 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
495 }
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
496 }
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
497
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
498 LOCK_DEV(dev);
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
499 EG(dev->fns->write_begin(dev, page));
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
500 if (src) {
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
501 int step = write_data_stride;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
502 remain = sizex;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
503 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
504 if (ecc_is_hw && dev->ecc->init) dev->ecc->init(dev);
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
505
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
506 if (step > remain) {
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
507 step = remain;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
508 // We can only support part-stride writes by assuming
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
509 // that the rest of the stride is 0xFF.
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
510 // (Woe betide the caller if it isn't.)
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
511 EG(dev->fns->write_stride(dev, src, step));
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
512 EG(dev->fns->write_stride(dev, 0, write_data_stride - step));
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
513 } else {
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
514 EG(dev->fns->write_stride(dev, src, step));
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
515 }
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
516 if (ecc_is_hw) {
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
517 dev->ecc->calc(dev, 0, 0, ecc_dest);
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
518 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
519 }
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
520 src += step;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
521 remain -= step;
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
522 }
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
523 }
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
524
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
525 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
526 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
527 EG(dev->fns->write_finish(dev, 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
528
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
529 /* 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
530 * 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
531 * 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
532 * if ECC is being used. */
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
533
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
534 err_exit:
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
535 UNLOCK_DEV(dev);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
536 return rv;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
537 #endif
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
538 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
539
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
540 __externC
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
541 int cyg_nand_erase_block(cyg_nand_partition *prt, cyg_nand_block_addr blk)
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
542 {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
543 #ifdef CYGSEM_IO_NAND_READONLY
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
544 return -EROFS;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
545 #else
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
546 PARTITION_CHECK(prt);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
547 cyg_nand_device *dev = prt->dev;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
548 int rv;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
549 DEV_INIT_CHECK(dev);
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 LOCK_DEV(dev);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
552
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
553 EG(valid_block_addr(prt, blk));
2948
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
554 #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
555 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
556 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
557 EG(-EINVAL);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
558 }
2948
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
559 #endif
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
560 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
561 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
562 if (rv==-EIO) {
2948
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
563 #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
564 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
565 #endif
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
566 EG(rv);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
567 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
568 err_exit:
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
569 UNLOCK_DEV(dev);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
570 return rv;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
571 #endif
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
572 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
573
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
574 __externC
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
575 int cyg_nand_bbt_query(cyg_nand_partition *prt, cyg_nand_block_addr blk)
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
576 {
2948
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
577 #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
578 int rv;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
579 PARTITION_CHECK(prt);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
580 cyg_nand_device *dev = prt->dev;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
581 DEV_INIT_CHECK(dev);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
582 LOCK_DEV(dev);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
583 EG(valid_block_addr(prt, blk));
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
584 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
585 err_exit:
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
586 UNLOCK_DEV(dev);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
587 return rv;
2948
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
588 #else
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
589 return -ENOSYS;
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
590 #endif
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
591 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
592
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
593 __externC
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
594 int cyg_nand_bbt_markbad(cyg_nand_partition *prt, cyg_nand_block_addr blk)
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
595 {
2948
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
596 #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
597 int rv;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
598 PARTITION_CHECK(prt);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
599 cyg_nand_device *dev = prt->dev;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
600 DEV_INIT_CHECK(dev);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
601 LOCK_DEV(dev);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
602 EG(valid_block_addr(prt, blk));
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
603 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
604 err_exit:
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
605 UNLOCK_DEV(dev);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
606 return rv;
2948
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
607 #else
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
608 return -ENOSYS;
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
609 #endif
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
610 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
611
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
612 __externC
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
613 int cyg_nand_bbt_markbad_pageaddr(cyg_nand_partition *prt, cyg_nand_page_addr pg)
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
614 {
2948
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
615 #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
616 int rv;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
617 PARTITION_CHECK(prt);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
618 cyg_nand_device *dev = prt->dev;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
619 DEV_INIT_CHECK(dev);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
620 LOCK_DEV(dev);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
621 cyg_nand_block_addr blk = CYG_NAND_PAGE2BLOCKADDR(dev, pg);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
622 EG(valid_block_addr(prt, blk));
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
623 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
624 err_exit:
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
625 UNLOCK_DEV(dev);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
626 return rv;
2948
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
627 #else
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
628 return -ENOSYS;
f14749d39b9c NAND: implement CYGSEM_IO_NAND_USE_BBT
Ross Younger <wry@ecoscentric.com>
parents: 2944
diff changeset
629 #endif
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
630 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
631
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
632 /* 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
633 * '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
634 * 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
635 * bytes will be written. */
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
636 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
637 {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
638 int i;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
639 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
640
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
641 CYG_CHECK_DATA_PTRC(page);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
642 CYG_CHECK_DATA_PTRC(ecc_o);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
643
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
644 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
645 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
646 dev->ecc->init(dev);
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
647 dev->ecc->calc(dev,page,dev->ecc->data_size,ecc_o);
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
648 page += dev->ecc->data_size;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
649 ecc_o += dev->ecc->ecc_size;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
650 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
651 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
652
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
653 /* 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
654 * '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
655 * be corrected.
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
656 * 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
657 * 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
658 * 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
659 * Returns:
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
660 * 0 for no errors
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
661 * 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
662 * 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
663 * 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
664 * -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
665 */
2944
32bcd454bda4 Major update to allow hardware ECC: change driver interface (to "v2" - with CDL marker), expand ECC interface
wry
parents: 2930
diff changeset
666 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
667 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
668 {
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
669 int i, page_rv=0;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
670 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
671 CYG_CHECK_DATA_PTRC(page);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
672 CYG_CHECK_DATA_PTRC(ecc_read);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
673 CYG_CHECK_DATA_PTRC(ecc_calc);
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
674
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
675 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
676 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
677 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
678 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
679 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
680 page_rv |= chunk_rv;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
681 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
682 remain -= dev->ecc->data_size;
2930
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
683 ecc_read += dev->ecc->ecc_size;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
684 ecc_calc += dev->ecc->ecc_size;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
685 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
686 return page_rv;
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
687 }
6efd22c2e7b1 Import anoncvs-based NAND and device drivers to 20090826
Ross Younger <wry@ecoscentric.com>
parents:
diff changeset
688