Mercurial > nand-ecoscentric
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 |
| 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 |
