1111#include <linux/module.h>
1212#include <linux/slab.h>
1313#include <linux/bitops.h>
14- #include <linux/mtd/mtd.h>
15- #include <linux/mtd/rawnand.h>
1614#include <linux/mtd/nand.h>
1715#include <linux/mtd/nand-ecc-sw-bch.h>
18- #include <linux/bch.h>
19-
20- /**
21- * struct nand_bch_control - private NAND BCH control structure
22- * @bch: BCH control structure
23- * @errloc: error location array
24- * @eccmask: XOR ecc mask, allows erased pages to be decoded as valid
25- */
26- struct nand_bch_control {
27- struct bch_control * bch ;
28- unsigned int * errloc ;
29- unsigned char * eccmask ;
30- };
3116
3217/**
3318 * nand_ecc_sw_bch_calculate - Calculate the ECC corresponding to a data block
@@ -38,16 +23,15 @@ struct nand_bch_control {
3823int nand_ecc_sw_bch_calculate (struct nand_device * nand ,
3924 const unsigned char * buf , unsigned char * code )
4025{
41- struct nand_chip * chip = mtd_to_nand (nanddev_to_mtd (nand ));
42- struct nand_bch_control * nbc = chip -> ecc .priv ;
26+ struct nand_ecc_sw_bch_conf * engine_conf = nand -> ecc .ctx .priv ;
4327 unsigned int i ;
4428
45- memset (code , 0 , chip -> ecc . bytes );
46- bch_encode (nbc -> bch , buf , chip -> ecc .size , code );
29+ memset (code , 0 , engine_conf -> code_size );
30+ bch_encode (engine_conf -> bch , buf , nand -> ecc .ctx . conf . step_size , code );
4731
4832 /* apply mask so that an erased page is a valid codeword */
49- for (i = 0 ; i < chip -> ecc . bytes ; i ++ )
50- code [i ] ^= nbc -> eccmask [i ];
33+ for (i = 0 ; i < engine_conf -> code_size ; i ++ )
34+ code [i ] ^= engine_conf -> eccmask [i ];
5135
5236 return 0 ;
5337}
@@ -65,16 +49,16 @@ EXPORT_SYMBOL(nand_ecc_sw_bch_calculate);
6549int nand_ecc_sw_bch_correct (struct nand_device * nand , unsigned char * buf ,
6650 unsigned char * read_ecc , unsigned char * calc_ecc )
6751{
68- struct nand_chip * chip = mtd_to_nand ( nanddev_to_mtd ( nand )) ;
69- struct nand_bch_control * nbc = chip -> ecc .priv ;
70- unsigned int * errloc = nbc -> errloc ;
52+ struct nand_ecc_sw_bch_conf * engine_conf = nand -> ecc . ctx . priv ;
53+ unsigned int step_size = nand -> ecc .ctx . conf . step_size ;
54+ unsigned int * errloc = engine_conf -> errloc ;
7155 int i , count ;
7256
73- count = bch_decode (nbc -> bch , NULL , chip -> ecc . size , read_ecc , calc_ecc ,
74- NULL , errloc );
57+ count = bch_decode (engine_conf -> bch , NULL , step_size , read_ecc ,
58+ calc_ecc , NULL , errloc );
7559 if (count > 0 ) {
7660 for (i = 0 ; i < count ; i ++ ) {
77- if (errloc [i ] < (chip -> ecc . size * 8 ))
61+ if (errloc [i ] < (step_size * 8 ))
7862 /* The error is in the data area: correct it */
7963 buf [errloc [i ] >> 3 ] ^= (1 << (errloc [i ] & 7 ));
8064
@@ -97,31 +81,30 @@ EXPORT_SYMBOL(nand_ecc_sw_bch_correct);
9781 *
9882 * Returns: a pointer to a new NAND BCH control structure, or NULL upon failure
9983 *
100- * Initialize NAND BCH error correction. Parameters @eccsize and @eccbytes
101- * are used to compute the following BCH parameters:
84+ * Initialize NAND BCH error correction. @nand.ecc parameters 'step_size' and
85+ * 'bytes' are used to compute the following BCH parameters:
10286 * m, the Galois field order
10387 * t, the error correction capability
104- * @eccbytes should be equal to the number of bytes required to store m * t
88+ * 'bytes' should be equal to the number of bytes required to store m * t
10589 * bits, where m is such that 2^m - 1 > step_size * 8.
10690 *
10791 * Example: to configure 4 bit correction per 512 bytes, you should pass
108- * @eccsize = 512 (thus, m = 13 is the smallest integer such that 2^m - 1 > 512 * 8)
109- * @eccbytes = 7 (7 bytes are required to store m * t = 13 * 4 = 52 bits)
92+ * step_size = 512 (thus, m = 13 is the smallest integer such that 2^m - 1 > 512 * 8)
93+ * bytes = 7 (7 bytes are required to store m * t = 13 * 4 = 52 bits)
11094 */
11195int nand_ecc_sw_bch_init (struct nand_device * nand )
11296{
11397 struct mtd_info * mtd = nanddev_to_mtd (nand );
114- struct nand_chip * chip = mtd_to_nand (mtd );
11598 unsigned int m , t , eccsteps , i ;
116- struct nand_bch_control * nbc = NULL ;
99+ struct nand_ecc_sw_bch_conf * engine_conf = nand -> ecc . ctx . priv ;
117100 unsigned char * erased_page ;
118- unsigned int eccsize = chip -> ecc .size ;
119- unsigned int eccbytes = chip -> ecc . bytes ;
120- unsigned int eccstrength = chip -> ecc .strength ;
101+ unsigned int eccsize = nand -> ecc .ctx . conf . step_size ;
102+ unsigned int eccbytes = engine_conf -> code_size ;
103+ unsigned int eccstrength = nand -> ecc . ctx . conf .strength ;
121104
122105 if (!eccbytes && eccstrength ) {
123106 eccbytes = DIV_ROUND_UP (eccstrength * fls (8 * eccsize ), 8 );
124- chip -> ecc . bytes = eccbytes ;
107+ engine_conf -> code_size = eccbytes ;
125108 }
126109
127110 if (!eccsize || !eccbytes ) {
@@ -132,20 +115,14 @@ int nand_ecc_sw_bch_init(struct nand_device *nand)
132115 m = fls (1 + 8 * eccsize );
133116 t = (eccbytes * 8 )/m ;
134117
135- nbc = kzalloc (sizeof (* nbc ), GFP_KERNEL );
136- if (!nbc )
137- return - ENOMEM ;
138-
139- chip -> ecc .priv = nbc ;
140-
141- nbc -> bch = bch_init (m , t , 0 , false);
142- if (!nbc -> bch )
143- goto fail ;
118+ engine_conf -> bch = bch_init (m , t , 0 , false);
119+ if (!engine_conf -> bch )
120+ return - EINVAL ;
144121
145122 /* verify that eccbytes has the expected value */
146- if (nbc -> bch -> ecc_bytes != eccbytes ) {
123+ if (engine_conf -> bch -> ecc_bytes != eccbytes ) {
147124 pr_warn ("invalid eccbytes %u, should be %u\n" ,
148- eccbytes , nbc -> bch -> ecc_bytes );
125+ eccbytes , engine_conf -> bch -> ecc_bytes );
149126 goto fail ;
150127 }
151128
@@ -163,25 +140,15 @@ int nand_ecc_sw_bch_init(struct nand_device *nand)
163140 goto fail ;
164141 }
165142
166- /*
167- * ecc->steps and ecc->total might be used by mtd->ooblayout->ecc(),
168- * which is called by mtd_ooblayout_count_eccbytes().
169- * Make sure they are properly initialized before calling
170- * mtd_ooblayout_count_eccbytes().
171- * FIXME: we should probably rework the sequencing in nand_scan_tail()
172- * to avoid setting those fields twice.
173- */
174- chip -> ecc .steps = eccsteps ;
175- chip -> ecc .total = eccsteps * eccbytes ;
176- nand -> base .ecc .ctx .total = chip -> ecc .total ;
177143 if (mtd_ooblayout_count_eccbytes (mtd ) != (eccsteps * eccbytes )) {
178144 pr_warn ("invalid ecc layout\n" );
179145 goto fail ;
180146 }
181147
182- nbc -> eccmask = kzalloc (eccbytes , GFP_KERNEL );
183- nbc -> errloc = kmalloc_array (t , sizeof (* nbc -> errloc ), GFP_KERNEL );
184- if (!nbc -> eccmask || !nbc -> errloc )
148+ engine_conf -> eccmask = kzalloc (eccbytes , GFP_KERNEL );
149+ engine_conf -> errloc = kmalloc_array (t , sizeof (* engine_conf -> errloc ),
150+ GFP_KERNEL );
151+ if (!engine_conf -> eccmask || !engine_conf -> errloc )
185152 goto fail ;
186153
187154 /*
@@ -192,14 +159,15 @@ int nand_ecc_sw_bch_init(struct nand_device *nand)
192159 goto fail ;
193160
194161 memset (erased_page , 0xff , eccsize );
195- bch_encode (nbc -> bch , erased_page , eccsize , nbc -> eccmask );
162+ bch_encode (engine_conf -> bch , erased_page , eccsize ,
163+ engine_conf -> eccmask );
196164 kfree (erased_page );
197165
198166 for (i = 0 ; i < eccbytes ; i ++ )
199- nbc -> eccmask [i ] ^= 0xff ;
167+ engine_conf -> eccmask [i ] ^= 0xff ;
200168
201169 if (!eccstrength )
202- chip -> ecc .strength = (eccbytes * 8 ) / fls (8 * eccsize );
170+ nand -> ecc . ctx . conf .strength = (eccbytes * 8 ) / fls (8 * eccsize );
203171
204172 return 0 ;
205173
@@ -216,14 +184,12 @@ EXPORT_SYMBOL(nand_ecc_sw_bch_init);
216184 */
217185void nand_ecc_sw_bch_cleanup (struct nand_device * nand )
218186{
219- struct nand_chip * chip = mtd_to_nand (nanddev_to_mtd (nand ));
220- struct nand_bch_control * nbc = chip -> ecc .priv ;
221-
222- if (nbc ) {
223- bch_free (nbc -> bch );
224- kfree (nbc -> errloc );
225- kfree (nbc -> eccmask );
226- kfree (nbc );
187+ struct nand_ecc_sw_bch_conf * engine_conf = nand -> ecc .ctx .priv ;
188+
189+ if (engine_conf ) {
190+ bch_free (engine_conf -> bch );
191+ kfree (engine_conf -> errloc );
192+ kfree (engine_conf -> eccmask );
227193 }
228194}
229195EXPORT_SYMBOL (nand_ecc_sw_bch_cleanup );
0 commit comments