]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - sys/dev/nand/nand.c
Copy head (r256279) to stable/10 as part of the 10.0-RELEASE cycle.
[FreeBSD/stable/10.git] / sys / dev / nand / nand.c
1 /*-
2  * Copyright (C) 2009-2012 Semihalf
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/kernel.h>
33 #include <sys/socket.h>
34 #include <sys/malloc.h>
35 #include <sys/module.h>
36 #include <sys/bus.h>
37 #include <sys/lock.h>
38 #include <sys/mutex.h>
39 #include <sys/callout.h>
40 #include <sys/sysctl.h>
41
42 #include <dev/nand/nand.h>
43 #include <dev/nand/nandbus.h>
44 #include <dev/nand/nand_ecc_pos.h>
45 #include "nfc_if.h"
46 #include "nand_if.h"
47 #include "nandbus_if.h"
48 #include <machine/stdarg.h>
49
50 #define NAND_RESET_DELAY        1000    /* tRST */
51 #define NAND_ERASE_DELAY        3000    /* tBERS */
52 #define NAND_PROG_DELAY         700     /* tPROG */
53 #define NAND_READ_DELAY         50      /* tR */
54
55 #define BIT0(x) ((x) & 0x1)
56 #define BIT1(x) (BIT0(x >> 1))
57 #define BIT2(x) (BIT0(x >> 2))
58 #define BIT3(x) (BIT0(x >> 3))
59 #define BIT4(x) (BIT0(x >> 4))
60 #define BIT5(x) (BIT0(x >> 5))
61 #define BIT6(x) (BIT0(x >> 6))
62 #define BIT7(x) (BIT0(x >> 7))
63
64 #define SOFTECC_SIZE            256
65 #define SOFTECC_BYTES           3
66
67 int nand_debug_flag = 0;
68 SYSCTL_INT(_debug, OID_AUTO, nand_debug, CTLFLAG_RW, &nand_debug_flag, 0,
69     "NAND subsystem debug flag");
70
71 static void
72 nand_tunable_init(void *arg)
73 {
74
75         TUNABLE_INT_FETCH("debug.nand", &nand_debug_flag);
76 }
77
78 SYSINIT(nand_tunables, SI_SUB_VFS, SI_ORDER_ANY, nand_tunable_init, NULL);
79
80 MALLOC_DEFINE(M_NAND, "NAND", "NAND dynamic data");
81
82 static void calculate_ecc(const uint8_t *, uint8_t *);
83 static int correct_ecc(uint8_t *, uint8_t *, uint8_t *);
84
85 void
86 nand_debug(int level, const char *fmt, ...)
87 {
88         va_list ap;
89
90         if (!(nand_debug_flag & level))
91                 return;
92         va_start(ap, fmt);
93         vprintf(fmt, ap);
94         va_end(ap);
95         printf("\n");
96 }
97
98 void
99 nand_init(struct nand_softc *nand, device_t dev, int ecc_mode,
100     int ecc_bytes, int ecc_size, uint16_t *eccposition, char *cdev_name)
101 {
102
103         nand->ecc.eccmode = ecc_mode;
104         nand->chip_cdev_name = cdev_name;
105
106         if (ecc_mode == NAND_ECC_SOFT) {
107                 nand->ecc.eccbytes = SOFTECC_BYTES;
108                 nand->ecc.eccsize = SOFTECC_SIZE;
109         } else if (ecc_mode != NAND_ECC_NONE) {
110                 nand->ecc.eccbytes = ecc_bytes;
111                 nand->ecc.eccsize = ecc_size;
112                 if (eccposition)
113                         nand->ecc.eccpositions = eccposition;
114         }
115 }
116
117 void
118 nand_onfi_set_params(struct nand_chip *chip, struct onfi_params *params)
119 {
120         struct chip_geom *cg;
121
122         cg = &chip->chip_geom;
123
124         init_chip_geom(cg, params->luns, params->blocks_per_lun,
125             params->pages_per_block, params->bytes_per_page,
126             params->spare_bytes_per_page);
127         chip->t_bers = params->t_bers;
128         chip->t_prog = params->t_prog;
129         chip->t_r = params->t_r;
130         chip->t_ccs = params->t_ccs;
131
132         if (params->features & ONFI_FEAT_16BIT)
133                 chip->flags |= NAND_16_BIT;
134 }
135
136 void
137 nand_set_params(struct nand_chip *chip, struct nand_params *params)
138 {
139         struct chip_geom *cg;
140         uint32_t blocks_per_chip;
141
142         cg = &chip->chip_geom;
143         blocks_per_chip = (params->chip_size << 20) /
144             (params->page_size * params->pages_per_block);
145
146         init_chip_geom(cg, 1, blocks_per_chip,
147             params->pages_per_block, params->page_size,
148             params->oob_size);
149
150         chip->t_bers = NAND_ERASE_DELAY;
151         chip->t_prog = NAND_PROG_DELAY;
152         chip->t_r = NAND_READ_DELAY;
153         chip->t_ccs = 0;
154
155         if (params->flags & NAND_16_BIT)
156                 chip->flags |= NAND_16_BIT;
157 }
158
159 int
160 nand_init_stat(struct nand_chip *chip)
161 {
162         struct block_stat *blk_stat;
163         struct page_stat *pg_stat;
164         struct chip_geom *cg;
165         uint32_t blks, pgs;
166
167         cg = &chip->chip_geom;
168         blks = cg->blks_per_lun * cg->luns;
169         blk_stat = malloc(sizeof(struct block_stat) * blks, M_NAND,
170             M_WAITOK | M_ZERO);
171         if (!blk_stat)
172                 return (ENOMEM);
173
174         pgs = blks * cg->pgs_per_blk;
175         pg_stat = malloc(sizeof(struct page_stat) * pgs, M_NAND,
176             M_WAITOK | M_ZERO);
177         if (!pg_stat) {
178                 free(blk_stat, M_NAND);
179                 return (ENOMEM);
180         }
181
182         chip->blk_stat = blk_stat;
183         chip->pg_stat = pg_stat;
184
185         return (0);
186 }
187
188 void
189 nand_destroy_stat(struct nand_chip *chip)
190 {
191
192         free(chip->pg_stat, M_NAND);
193         free(chip->blk_stat, M_NAND);
194 }
195
196 int
197 init_chip_geom(struct chip_geom *cg, uint32_t luns, uint32_t blks_per_lun,
198     uint32_t pgs_per_blk, uint32_t pg_size, uint32_t oob_size)
199 {
200         int shift;
201
202         if (!cg)
203                 return (-1);
204
205         cg->luns = luns;
206         cg->blks_per_lun = blks_per_lun;
207         cg->blks_per_chip = blks_per_lun * luns;
208         cg->pgs_per_blk = pgs_per_blk;
209
210         cg->page_size = pg_size;
211         cg->oob_size = oob_size;
212         cg->block_size = cg->page_size * cg->pgs_per_blk;
213         cg->chip_size = cg->block_size * cg->blks_per_chip;
214
215         shift = fls(cg->pgs_per_blk - 1);
216         cg->pg_mask = (1 << shift) - 1;
217         cg->blk_shift = shift;
218
219         if (cg->blks_per_lun > 0) {
220                 shift = fls(cg->blks_per_lun - 1);
221                 cg->blk_mask = ((1 << shift) - 1) << cg->blk_shift;
222         } else {
223                 shift = 0;
224                 cg->blk_mask = 0;
225         }
226
227         cg->lun_shift = shift + cg->blk_shift;
228         shift = fls(cg->luns - 1);
229         cg->lun_mask = ((1 << shift) - 1) << cg->lun_shift;
230
231         nand_debug(NDBG_NAND, "Masks: lun 0x%x blk 0x%x page 0x%x\n"
232             "Shifts: lun %d blk %d",
233             cg->lun_mask, cg->blk_mask, cg->pg_mask,
234             cg->lun_shift, cg->blk_shift);
235
236         return (0);
237 }
238
239 int
240 nand_row_to_blkpg(struct chip_geom *cg, uint32_t row, uint32_t *lun,
241     uint32_t *blk, uint32_t *pg)
242 {
243
244         if (!cg || !lun || !blk || !pg)
245                 return (-1);
246
247         if (row & ~(cg->lun_mask | cg->blk_mask | cg->pg_mask)) {
248                 nand_debug(NDBG_NAND,"Address out of bounds\n");
249                 return (-1);
250         }
251
252         *lun = (row & cg->lun_mask) >> cg->lun_shift;
253         *blk = (row & cg->blk_mask) >> cg->blk_shift;
254         *pg = (row & cg->pg_mask);
255
256         nand_debug(NDBG_NAND,"address %x-%x-%x\n", *lun, *blk, *pg);
257
258         return (0);
259 }
260
261 int page_to_row(struct chip_geom *cg, uint32_t page, uint32_t *row)
262 {
263         uint32_t lun, block, pg_in_blk;
264
265         if (!cg || !row)
266                 return (-1);
267
268         block = page / cg->pgs_per_blk;
269         pg_in_blk = page % cg->pgs_per_blk;
270
271         lun = block / cg->blks_per_lun;
272         block = block % cg->blks_per_lun;
273
274         *row = (lun << cg->lun_shift) & cg->lun_mask;
275         *row |= ((block << cg->blk_shift) & cg->blk_mask);
276         *row |= (pg_in_blk & cg->pg_mask);
277
278         return (0);
279 }
280
281 int
282 nand_check_page_boundary(struct nand_chip *chip, uint32_t page)
283 {
284         struct chip_geom* cg;
285
286         cg = &chip->chip_geom;
287         if (page >= (cg->pgs_per_blk * cg->blks_per_lun * cg->luns)) {
288                 nand_debug(NDBG_GEN,"%s: page number too big %#x\n",
289                     __func__, page);
290                 return (1);
291         }
292
293         return (0);
294 }
295
296 void
297 nand_get_chip_param(struct nand_chip *chip, struct chip_param_io *param)
298 {
299         struct chip_geom *cg;
300
301         cg = &chip->chip_geom;
302         param->page_size = cg->page_size;
303         param->oob_size = cg->oob_size;
304
305         param->blocks = cg->blks_per_lun * cg->luns;
306         param->pages_per_block = cg->pgs_per_blk;
307 }
308
309 static uint16_t *
310 default_software_ecc_positions(struct nand_chip *chip)
311 {
312         struct nand_ecc_data *eccd;
313
314         eccd = &chip->nand->ecc;
315
316         if (eccd->eccpositions)
317                 return (eccd->eccpositions);
318
319         switch (chip->chip_geom.oob_size) {
320         case 16:
321                 return ((uint16_t *)&default_software_ecc_positions_16);
322         case 64:
323                 return ((uint16_t *)&default_software_ecc_positions_64);
324         case 128:
325                 return ((uint16_t *)&default_software_ecc_positions_128);
326         default:
327                 return (NULL); /* No ecc bytes positions defs available */
328         }
329
330         return (NULL);
331 }
332
333 static void
334 calculate_ecc(const uint8_t *buf, uint8_t *ecc)
335 {
336         uint8_t p8, byte;
337         int i;
338
339         memset(ecc, 0, 3);
340
341         for (i = 0; i < 256; i++) {
342                 byte = buf[i];
343                 ecc[0] ^= (BIT0(byte) ^ BIT2(byte) ^ BIT4(byte) ^
344                     BIT6(byte)) << 2;
345                 ecc[0] ^= (BIT1(byte) ^ BIT3(byte) ^ BIT5(byte) ^
346                     BIT7(byte)) << 3;
347                 ecc[0] ^= (BIT0(byte) ^ BIT1(byte) ^ BIT4(byte) ^
348                     BIT5(byte)) << 4;
349                 ecc[0] ^= (BIT2(byte) ^ BIT3(byte) ^ BIT6(byte) ^
350                     BIT7(byte)) << 5;
351                 ecc[0] ^= (BIT0(byte) ^ BIT1(byte) ^ BIT2(byte) ^
352                     BIT3(byte)) << 6;
353                 ecc[0] ^= (BIT4(byte) ^ BIT5(byte) ^ BIT6(byte) ^
354                     BIT7(byte)) << 7;
355
356                 p8 = BIT0(byte) ^ BIT1(byte) ^ BIT2(byte) ^
357                     BIT3(byte) ^ BIT4(byte) ^ BIT5(byte) ^ BIT6(byte) ^
358                     BIT7(byte);
359
360                 if (p8) {
361                         ecc[2] ^= (0x1 << BIT0(i));
362                         ecc[2] ^= (0x4 << BIT1(i));
363                         ecc[2] ^= (0x10 << BIT2(i));
364                         ecc[2] ^= (0x40 << BIT3(i));
365
366                         ecc[1] ^= (0x1 << BIT4(i));
367                         ecc[1] ^= (0x4 << BIT5(i));
368                         ecc[1] ^= (0x10 << BIT6(i));
369                         ecc[1] ^= (0x40 << BIT7(i));
370                 }
371         }
372         ecc[0] = ~ecc[0];
373         ecc[1] = ~ecc[1];
374         ecc[2] = ~ecc[2];
375         ecc[0] |= 3;
376 }
377
378 static int
379 correct_ecc(uint8_t *buf, uint8_t *calc_ecc, uint8_t *read_ecc)
380 {
381         uint8_t ecc0, ecc1, ecc2, onesnum, bit, byte;
382         uint16_t addr = 0;
383
384         ecc0 = calc_ecc[0] ^ read_ecc[0];
385         ecc1 = calc_ecc[1] ^ read_ecc[1];
386         ecc2 = calc_ecc[2] ^ read_ecc[2];
387
388         if (!ecc0 && !ecc1 && !ecc2)
389                 return (ECC_OK);
390
391         addr = BIT3(ecc0) | (BIT5(ecc0) << 1) | (BIT7(ecc0) << 2);
392         addr |= (BIT1(ecc2) << 3) | (BIT3(ecc2) << 4) |
393             (BIT5(ecc2) << 5) |  (BIT7(ecc2) << 6);
394         addr |= (BIT1(ecc1) << 7) | (BIT3(ecc1) << 8) |
395             (BIT5(ecc1) << 9) |  (BIT7(ecc1) << 10);
396
397         onesnum = 0;
398         while (ecc0 || ecc1 || ecc2) {
399                 if (ecc0 & 1)
400                         onesnum++;
401                 if (ecc1 & 1)
402                         onesnum++;
403                 if (ecc2 & 1)
404                         onesnum++;
405
406                 ecc0 >>= 1;
407                 ecc1 >>= 1;
408                 ecc2 >>= 1;
409         }
410
411         if (onesnum == 11) {
412                 /* Correctable error */
413                 bit = addr & 7;
414                 byte = addr >> 3;
415                 buf[byte] ^= (1 << bit);
416                 return (ECC_CORRECTABLE);
417         } else if (onesnum == 1) {
418                 /* ECC error */
419                 return (ECC_ERROR_ECC);
420         } else {
421                 /* Uncorrectable error */
422                 return (ECC_UNCORRECTABLE);
423         }
424
425         return (0);
426 }
427
428 int
429 nand_softecc_get(device_t dev, uint8_t *buf, int pagesize, uint8_t *ecc)
430 {
431         int steps = pagesize / SOFTECC_SIZE;
432         int i = 0, j = 0;
433
434         for (; i < (steps * SOFTECC_BYTES);
435             i += SOFTECC_BYTES, j += SOFTECC_SIZE) {
436                 calculate_ecc(&buf[j], &ecc[i]);
437         }
438
439         return (0);
440 }
441
442 int
443 nand_softecc_correct(device_t dev, uint8_t *buf, int pagesize,
444     uint8_t *readecc, uint8_t *calcecc)
445 {
446         int steps = pagesize / SOFTECC_SIZE;
447         int i = 0, j = 0, ret = 0;
448
449         for (i = 0; i < (steps * SOFTECC_BYTES);
450             i += SOFTECC_BYTES, j += SOFTECC_SIZE) {
451                 ret += correct_ecc(&buf[j], &calcecc[i], &readecc[i]);
452                 if (ret < 0)
453                         return (ret);
454         }
455
456         return (ret);
457 }
458
459 static int
460 offset_to_page(struct chip_geom *cg, uint32_t offset)
461 {
462
463         return (offset / cg->page_size);
464 }
465
466 int
467 nand_read_pages(struct nand_chip *chip, uint32_t offset, void *buf,
468     uint32_t len)
469 {
470         struct chip_geom *cg;
471         struct nand_ecc_data *eccd;
472         struct page_stat *pg_stat;
473         device_t nandbus;
474         void *oob = NULL;
475         uint8_t *ptr;
476         uint16_t *eccpos = NULL;
477         uint32_t page, num, steps = 0;
478         int i, retval = 0, needwrite;
479
480         nand_debug(NDBG_NAND,"%p read page %x[%x]", chip, offset, len);
481         cg = &chip->chip_geom;
482         eccd = &chip->nand->ecc;
483         page = offset_to_page(cg, offset);
484         num = len / cg->page_size;
485
486         if (eccd->eccmode != NAND_ECC_NONE) {
487                 steps = cg->page_size / eccd->eccsize;
488                 eccpos = default_software_ecc_positions(chip);
489                 oob = malloc(cg->oob_size, M_NAND, M_WAITOK);
490         }
491
492         nandbus = device_get_parent(chip->dev);
493         NANDBUS_LOCK(nandbus);
494         NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num);
495
496         ptr = (uint8_t *)buf;
497         while (num--) {
498                 pg_stat = &(chip->pg_stat[page]);
499
500                 if (NAND_READ_PAGE(chip->dev, page, ptr, cg->page_size, 0)) {
501                         retval = ENXIO;
502                         break;
503                 }
504
505                 if (eccd->eccmode != NAND_ECC_NONE) {
506                         if (NAND_GET_ECC(chip->dev, ptr, eccd->ecccalculated,
507                             &needwrite)) {
508                                 retval = ENXIO;
509                                 break;
510                         }
511                         nand_debug(NDBG_ECC,"%s: ECC calculated:",
512                             __func__);
513                         if (nand_debug_flag & NDBG_ECC)
514                                 for (i = 0; i < (eccd->eccbytes * steps); i++)
515                                         printf("%x ", eccd->ecccalculated[i]);
516
517                         nand_debug(NDBG_ECC,"\n");
518
519                         if (NAND_READ_OOB(chip->dev, page, oob, cg->oob_size,
520                             0)) {
521                                 retval = ENXIO;
522                                 break;
523                         }
524                         for (i = 0; i < (eccd->eccbytes * steps); i++)
525                                 eccd->eccread[i] = ((uint8_t *)oob)[eccpos[i]];
526
527                         nand_debug(NDBG_ECC,"%s: ECC read:", __func__);
528                         if (nand_debug_flag & NDBG_ECC)
529                                 for (i = 0; i < (eccd->eccbytes * steps); i++)
530                                         printf("%x ", eccd->eccread[i]);
531                         nand_debug(NDBG_ECC,"\n");
532
533                         retval = NAND_CORRECT_ECC(chip->dev, ptr, eccd->eccread,
534                             eccd->ecccalculated);
535
536                         nand_debug(NDBG_ECC, "NAND_CORRECT_ECC() returned %d",
537                             retval);
538
539                         if (retval == 0)
540                                 pg_stat->ecc_stat.ecc_succeded++;
541                         else if (retval > 0) {
542                                 pg_stat->ecc_stat.ecc_corrected += retval;
543                                 retval = ECC_CORRECTABLE;
544                         } else {
545                                 pg_stat->ecc_stat.ecc_failed++;
546                                 break;
547                         }
548                 }
549
550                 pg_stat->page_read++;
551                 page++;
552                 ptr += cg->page_size;
553         }
554
555         NANDBUS_UNLOCK(nandbus);
556
557         if (oob)
558                 free(oob, M_NAND);
559
560         return (retval);
561 }
562
563 int
564 nand_read_pages_raw(struct nand_chip *chip, uint32_t offset, void *buf,
565     uint32_t len)
566 {
567         struct chip_geom *cg;
568         device_t nandbus;
569         uint8_t *ptr;
570         uint32_t page, num, end, begin = 0, begin_off;
571         int retval = 0;
572
573         cg = &chip->chip_geom;
574         page = offset_to_page(cg, offset);
575         begin_off = offset - page * cg->page_size;
576         if (begin_off) {
577                 begin = cg->page_size - begin_off;
578                 len -= begin;
579         }
580         num = len / cg->page_size;
581         end = len % cg->page_size;
582
583         nandbus = device_get_parent(chip->dev);
584         NANDBUS_LOCK(nandbus);
585         NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num);
586
587         ptr = (uint8_t *)buf;
588         if (begin_off) {
589                 if (NAND_READ_PAGE(chip->dev, page, ptr, begin, begin_off)) {
590                         NANDBUS_UNLOCK(nandbus);
591                         return (ENXIO);
592                 }
593
594                 page++;
595                 ptr += begin;
596         }
597
598         while (num--) {
599                 if (NAND_READ_PAGE(chip->dev, page, ptr, cg->page_size, 0)) {
600                         NANDBUS_UNLOCK(nandbus);
601                         return (ENXIO);
602                 }
603
604                 page++;
605                 ptr += cg->page_size;
606         }
607
608         if (end)
609                 if (NAND_READ_PAGE(chip->dev, page, ptr, end, 0)) {
610                         NANDBUS_UNLOCK(nandbus);
611                         return (ENXIO);
612                 }
613
614         NANDBUS_UNLOCK(nandbus);
615
616         return (retval);
617 }
618
619
620 int
621 nand_prog_pages(struct nand_chip *chip, uint32_t offset, uint8_t *buf,
622     uint32_t len)
623 {
624         struct chip_geom *cg;
625         struct page_stat *pg_stat;
626         struct nand_ecc_data *eccd;
627         device_t nandbus;
628         uint32_t page, num;
629         uint8_t *oob = NULL;
630         uint16_t *eccpos = NULL;
631         int steps = 0, i, needwrite, err = 0;
632
633         nand_debug(NDBG_NAND,"%p prog page %x[%x]", chip, offset, len);
634
635         eccd = &chip->nand->ecc;
636         cg = &chip->chip_geom;
637         page = offset_to_page(cg, offset);
638         num = len / cg->page_size;
639
640         if (eccd->eccmode != NAND_ECC_NONE) {
641                 steps = cg->page_size / eccd->eccsize;
642                 oob = malloc(cg->oob_size, M_NAND, M_WAITOK);
643                 eccpos = default_software_ecc_positions(chip);
644         }
645
646         nandbus = device_get_parent(chip->dev);
647         NANDBUS_LOCK(nandbus);
648         NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num);
649
650         while (num--) {
651                 if (NAND_PROGRAM_PAGE(chip->dev, page, buf, cg->page_size, 0)) {
652                         err = ENXIO;
653                         break;
654                 }
655
656                 if (eccd->eccmode != NAND_ECC_NONE) {
657                         if (NAND_GET_ECC(chip->dev, buf, &eccd->ecccalculated,
658                             &needwrite)) {
659                                 err = ENXIO;
660                                 break;
661                         }
662                         nand_debug(NDBG_ECC,"ECC calculated:");
663                         if (nand_debug_flag & NDBG_ECC)
664                                 for (i = 0; i < (eccd->eccbytes * steps); i++)
665                                         printf("%x ", eccd->ecccalculated[i]);
666
667                         nand_debug(NDBG_ECC,"\n");
668
669                         if (needwrite) {
670                                 if (NAND_READ_OOB(chip->dev, page, oob, cg->oob_size,
671                                     0)) {
672                                         err = ENXIO;
673                                         break;
674                                 }
675
676                                 for (i = 0; i < (eccd->eccbytes * steps); i++)
677                                         oob[eccpos[i]] = eccd->ecccalculated[i];
678
679                                 if (NAND_PROGRAM_OOB(chip->dev, page, oob,
680                                     cg->oob_size, 0)) {
681                                         err = ENXIO;
682                                         break;
683                                 }
684                         }
685                 }
686
687                 pg_stat = &(chip->pg_stat[page]);
688                 pg_stat->page_written++;
689
690                 page++;
691                 buf += cg->page_size;
692         }
693
694         NANDBUS_UNLOCK(nandbus);
695
696         if (oob)
697                 free(oob, M_NAND);
698
699         return (err);
700 }
701
702 int
703 nand_prog_pages_raw(struct nand_chip *chip, uint32_t offset, void *buf,
704     uint32_t len)
705 {
706         struct chip_geom *cg;
707         device_t nandbus;
708         uint8_t *ptr;
709         uint32_t page, num, end, begin = 0, begin_off;
710         int retval = 0;
711
712         cg = &chip->chip_geom;
713         page = offset_to_page(cg, offset);
714         begin_off = offset - page * cg->page_size;
715         if (begin_off) {
716                 begin = cg->page_size - begin_off;
717                 len -= begin;
718         }
719         num = len / cg->page_size;
720         end = len % cg->page_size;
721
722         nandbus = device_get_parent(chip->dev);
723         NANDBUS_LOCK(nandbus);
724         NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num);
725
726         ptr = (uint8_t *)buf;
727         if (begin_off) {
728                 if (NAND_PROGRAM_PAGE(chip->dev, page, ptr, begin, begin_off)) {
729                         NANDBUS_UNLOCK(nandbus);
730                         return (ENXIO);
731                 }
732
733                 page++;
734                 ptr += begin;
735         }
736
737         while (num--) {
738                 if (NAND_PROGRAM_PAGE(chip->dev, page, ptr, cg->page_size, 0)) {
739                         NANDBUS_UNLOCK(nandbus);
740                         return (ENXIO);
741                 }
742
743                 page++;
744                 ptr += cg->page_size;
745         }
746
747         if (end)
748                 retval = NAND_PROGRAM_PAGE(chip->dev, page, ptr, end, 0);
749
750         NANDBUS_UNLOCK(nandbus);
751
752         return (retval);
753 }
754
755 int
756 nand_read_oob(struct nand_chip *chip, uint32_t page, void *buf,
757     uint32_t len)
758 {
759         device_t nandbus;
760         int retval = 0;
761
762         nandbus = device_get_parent(chip->dev);
763         NANDBUS_LOCK(nandbus);
764         NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num);
765
766         retval = NAND_READ_OOB(chip->dev, page, buf, len, 0);
767
768         NANDBUS_UNLOCK(nandbus);
769
770         return (retval);
771 }
772
773
774 int
775 nand_prog_oob(struct nand_chip *chip, uint32_t page, void *buf,
776     uint32_t len)
777 {
778         device_t nandbus;
779         int retval = 0;
780
781         nandbus = device_get_parent(chip->dev);
782         NANDBUS_LOCK(nandbus);
783         NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num);
784
785         retval = NAND_PROGRAM_OOB(chip->dev, page, buf, len, 0);
786
787         NANDBUS_UNLOCK(nandbus);
788
789         return (retval);
790 }
791
792 int
793 nand_erase_blocks(struct nand_chip *chip, off_t offset, size_t len)
794 {
795         device_t nandbus;
796         struct chip_geom *cg;
797         uint32_t block, num_blocks;
798         int err = 0;
799
800         cg = &chip->chip_geom;
801         if ((offset % cg->block_size) || (len % cg->block_size))
802                 return (EINVAL);
803
804         block = offset / cg->block_size;
805         num_blocks = len / cg->block_size;
806         nand_debug(NDBG_NAND,"%p erase blocks %d[%d]", chip, block, num_blocks);
807
808         nandbus = device_get_parent(chip->dev);
809         NANDBUS_LOCK(nandbus);
810         NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num);
811
812         while (num_blocks--) {
813                 if (!nand_check_bad_block(chip, block)) {
814                         if (NAND_ERASE_BLOCK(chip->dev, block)) {
815                                 nand_debug(NDBG_NAND,"%p erase blocks %d error",
816                                     chip, block);
817                                 nand_mark_bad_block(chip, block);
818                                 err = ENXIO;
819                         }
820                 } else
821                         err = ENXIO;
822
823                 block++;
824         };
825
826         NANDBUS_UNLOCK(nandbus);
827
828         if (err)
829                 nand_update_bbt(chip);
830
831         return (err);
832 }
833
834 MODULE_VERSION(nand, 1);