]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - sys/dev/nand/nand.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.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_chip_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         /* If positions have been set already, use them. */
313         if (chip->nand->ecc.eccpositions)
314                 return (chip->nand->ecc.eccpositions);
315
316         /*
317          * XXX Note that the following logic isn't really sufficient, especially
318          * in the ONFI case where the number of ECC bytes can be dictated by
319          * values in the parameters page, and that could lead to needing more
320          * byte positions than exist within the tables of software-ecc defaults.
321          */
322         if (chip->chip_geom.oob_size >= 128)
323                 return (default_software_ecc_positions_128);
324         if (chip->chip_geom.oob_size >= 64)
325                 return (default_software_ecc_positions_64);
326         else if (chip->chip_geom.oob_size >= 16)
327                 return (default_software_ecc_positions_16);
328
329         return (NULL);
330 }
331
332 static void
333 calculate_ecc(const uint8_t *buf, uint8_t *ecc)
334 {
335         uint8_t p8, byte;
336         int i;
337
338         memset(ecc, 0, 3);
339
340         for (i = 0; i < 256; i++) {
341                 byte = buf[i];
342                 ecc[0] ^= (BIT0(byte) ^ BIT2(byte) ^ BIT4(byte) ^
343                     BIT6(byte)) << 2;
344                 ecc[0] ^= (BIT1(byte) ^ BIT3(byte) ^ BIT5(byte) ^
345                     BIT7(byte)) << 3;
346                 ecc[0] ^= (BIT0(byte) ^ BIT1(byte) ^ BIT4(byte) ^
347                     BIT5(byte)) << 4;
348                 ecc[0] ^= (BIT2(byte) ^ BIT3(byte) ^ BIT6(byte) ^
349                     BIT7(byte)) << 5;
350                 ecc[0] ^= (BIT0(byte) ^ BIT1(byte) ^ BIT2(byte) ^
351                     BIT3(byte)) << 6;
352                 ecc[0] ^= (BIT4(byte) ^ BIT5(byte) ^ BIT6(byte) ^
353                     BIT7(byte)) << 7;
354
355                 p8 = BIT0(byte) ^ BIT1(byte) ^ BIT2(byte) ^
356                     BIT3(byte) ^ BIT4(byte) ^ BIT5(byte) ^ BIT6(byte) ^
357                     BIT7(byte);
358
359                 if (p8) {
360                         ecc[2] ^= (0x1 << BIT0(i));
361                         ecc[2] ^= (0x4 << BIT1(i));
362                         ecc[2] ^= (0x10 << BIT2(i));
363                         ecc[2] ^= (0x40 << BIT3(i));
364
365                         ecc[1] ^= (0x1 << BIT4(i));
366                         ecc[1] ^= (0x4 << BIT5(i));
367                         ecc[1] ^= (0x10 << BIT6(i));
368                         ecc[1] ^= (0x40 << BIT7(i));
369                 }
370         }
371         ecc[0] = ~ecc[0];
372         ecc[1] = ~ecc[1];
373         ecc[2] = ~ecc[2];
374         ecc[0] |= 3;
375 }
376
377 static int
378 correct_ecc(uint8_t *buf, uint8_t *calc_ecc, uint8_t *read_ecc)
379 {
380         uint8_t ecc0, ecc1, ecc2, onesnum, bit, byte;
381         uint16_t addr = 0;
382
383         ecc0 = calc_ecc[0] ^ read_ecc[0];
384         ecc1 = calc_ecc[1] ^ read_ecc[1];
385         ecc2 = calc_ecc[2] ^ read_ecc[2];
386
387         if (!ecc0 && !ecc1 && !ecc2)
388                 return (ECC_OK);
389
390         addr = BIT3(ecc0) | (BIT5(ecc0) << 1) | (BIT7(ecc0) << 2);
391         addr |= (BIT1(ecc2) << 3) | (BIT3(ecc2) << 4) |
392             (BIT5(ecc2) << 5) |  (BIT7(ecc2) << 6);
393         addr |= (BIT1(ecc1) << 7) | (BIT3(ecc1) << 8) |
394             (BIT5(ecc1) << 9) |  (BIT7(ecc1) << 10);
395
396         onesnum = 0;
397         while (ecc0 || ecc1 || ecc2) {
398                 if (ecc0 & 1)
399                         onesnum++;
400                 if (ecc1 & 1)
401                         onesnum++;
402                 if (ecc2 & 1)
403                         onesnum++;
404
405                 ecc0 >>= 1;
406                 ecc1 >>= 1;
407                 ecc2 >>= 1;
408         }
409
410         if (onesnum == 11) {
411                 /* Correctable error */
412                 bit = addr & 7;
413                 byte = addr >> 3;
414                 buf[byte] ^= (1 << bit);
415                 return (ECC_CORRECTABLE);
416         } else if (onesnum == 1) {
417                 /* ECC error */
418                 return (ECC_ERROR_ECC);
419         } else {
420                 /* Uncorrectable error */
421                 return (ECC_UNCORRECTABLE);
422         }
423
424         return (0);
425 }
426
427 int
428 nand_softecc_get(device_t dev, uint8_t *buf, int pagesize, uint8_t *ecc)
429 {
430         int steps = pagesize / SOFTECC_SIZE;
431         int i = 0, j = 0;
432
433         for (; i < (steps * SOFTECC_BYTES);
434             i += SOFTECC_BYTES, j += SOFTECC_SIZE) {
435                 calculate_ecc(&buf[j], &ecc[i]);
436         }
437
438         return (0);
439 }
440
441 int
442 nand_softecc_correct(device_t dev, uint8_t *buf, int pagesize,
443     uint8_t *readecc, uint8_t *calcecc)
444 {
445         int steps = pagesize / SOFTECC_SIZE;
446         int i = 0, j = 0, ret = 0;
447
448         for (i = 0; i < (steps * SOFTECC_BYTES);
449             i += SOFTECC_BYTES, j += SOFTECC_SIZE) {
450                 ret += correct_ecc(&buf[j], &calcecc[i], &readecc[i]);
451                 if (ret < 0)
452                         return (ret);
453         }
454
455         return (ret);
456 }
457
458 static int
459 offset_to_page(struct chip_geom *cg, uint32_t offset)
460 {
461
462         return (offset / cg->page_size);
463 }
464
465 int
466 nand_read_pages(struct nand_chip *chip, uint32_t offset, void *buf,
467     uint32_t len)
468 {
469         struct chip_geom *cg;
470         struct nand_ecc_data *eccd;
471         struct page_stat *pg_stat;
472         device_t nandbus;
473         void *oob = NULL;
474         uint8_t *ptr;
475         uint16_t *eccpos = NULL;
476         uint32_t page, num, steps = 0;
477         int i, retval = 0, needwrite;
478
479         nand_debug(NDBG_NAND,"%p read page %x[%x]", chip, offset, len);
480         cg = &chip->chip_geom;
481         eccd = &chip->nand->ecc;
482         page = offset_to_page(cg, offset);
483         num = len / cg->page_size;
484
485         if (eccd->eccmode != NAND_ECC_NONE) {
486                 steps = cg->page_size / eccd->eccsize;
487                 eccpos = default_software_ecc_positions(chip);
488                 oob = malloc(cg->oob_size, M_NAND, M_WAITOK);
489         }
490
491         nandbus = device_get_parent(chip->dev);
492         NANDBUS_LOCK(nandbus);
493         NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num);
494
495         ptr = (uint8_t *)buf;
496         while (num--) {
497                 pg_stat = &(chip->pg_stat[page]);
498
499                 if (NAND_READ_PAGE(chip->dev, page, ptr, cg->page_size, 0)) {
500                         retval = ENXIO;
501                         break;
502                 }
503
504                 if (eccd->eccmode != NAND_ECC_NONE) {
505                         if (NAND_GET_ECC(chip->dev, ptr, eccd->ecccalculated,
506                             &needwrite)) {
507                                 retval = ENXIO;
508                                 break;
509                         }
510                         nand_debug(NDBG_ECC,"%s: ECC calculated:",
511                             __func__);
512                         if (nand_debug_flag & NDBG_ECC)
513                                 for (i = 0; i < (eccd->eccbytes * steps); i++)
514                                         printf("%x ", eccd->ecccalculated[i]);
515
516                         nand_debug(NDBG_ECC,"\n");
517
518                         if (NAND_READ_OOB(chip->dev, page, oob, cg->oob_size,
519                             0)) {
520                                 retval = ENXIO;
521                                 break;
522                         }
523                         for (i = 0; i < (eccd->eccbytes * steps); i++)
524                                 eccd->eccread[i] = ((uint8_t *)oob)[eccpos[i]];
525
526                         nand_debug(NDBG_ECC,"%s: ECC read:", __func__);
527                         if (nand_debug_flag & NDBG_ECC)
528                                 for (i = 0; i < (eccd->eccbytes * steps); i++)
529                                         printf("%x ", eccd->eccread[i]);
530                         nand_debug(NDBG_ECC,"\n");
531
532                         retval = NAND_CORRECT_ECC(chip->dev, ptr, eccd->eccread,
533                             eccd->ecccalculated);
534
535                         nand_debug(NDBG_ECC, "NAND_CORRECT_ECC() returned %d",
536                             retval);
537
538                         if (retval == 0)
539                                 pg_stat->ecc_stat.ecc_succeded++;
540                         else if (retval > 0) {
541                                 pg_stat->ecc_stat.ecc_corrected += retval;
542                                 retval = ECC_CORRECTABLE;
543                         } else {
544                                 pg_stat->ecc_stat.ecc_failed++;
545                                 break;
546                         }
547                 }
548
549                 pg_stat->page_read++;
550                 page++;
551                 ptr += cg->page_size;
552         }
553
554         NANDBUS_UNLOCK(nandbus);
555
556         if (oob)
557                 free(oob, M_NAND);
558
559         return (retval);
560 }
561
562 int
563 nand_read_pages_raw(struct nand_chip *chip, uint32_t offset, void *buf,
564     uint32_t len)
565 {
566         struct chip_geom *cg;
567         device_t nandbus;
568         uint8_t *ptr;
569         uint32_t page, num, end, begin = 0, begin_off;
570         int retval = 0;
571
572         cg = &chip->chip_geom;
573         page = offset_to_page(cg, offset);
574         begin_off = offset - page * cg->page_size;
575         if (begin_off) {
576                 begin = cg->page_size - begin_off;
577                 len -= begin;
578         }
579         num = len / cg->page_size;
580         end = len % cg->page_size;
581
582         nandbus = device_get_parent(chip->dev);
583         NANDBUS_LOCK(nandbus);
584         NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num);
585
586         ptr = (uint8_t *)buf;
587         if (begin_off) {
588                 if (NAND_READ_PAGE(chip->dev, page, ptr, begin, begin_off)) {
589                         NANDBUS_UNLOCK(nandbus);
590                         return (ENXIO);
591                 }
592
593                 page++;
594                 ptr += begin;
595         }
596
597         while (num--) {
598                 if (NAND_READ_PAGE(chip->dev, page, ptr, cg->page_size, 0)) {
599                         NANDBUS_UNLOCK(nandbus);
600                         return (ENXIO);
601                 }
602
603                 page++;
604                 ptr += cg->page_size;
605         }
606
607         if (end)
608                 if (NAND_READ_PAGE(chip->dev, page, ptr, end, 0)) {
609                         NANDBUS_UNLOCK(nandbus);
610                         return (ENXIO);
611                 }
612
613         NANDBUS_UNLOCK(nandbus);
614
615         return (retval);
616 }
617
618
619 int
620 nand_prog_pages(struct nand_chip *chip, uint32_t offset, uint8_t *buf,
621     uint32_t len)
622 {
623         struct chip_geom *cg;
624         struct page_stat *pg_stat;
625         struct nand_ecc_data *eccd;
626         device_t nandbus;
627         uint32_t page, num;
628         uint8_t *oob = NULL;
629         uint16_t *eccpos = NULL;
630         int steps = 0, i, needwrite, err = 0;
631
632         nand_debug(NDBG_NAND,"%p prog page %x[%x]", chip, offset, len);
633
634         eccd = &chip->nand->ecc;
635         cg = &chip->chip_geom;
636         page = offset_to_page(cg, offset);
637         num = len / cg->page_size;
638
639         if (eccd->eccmode != NAND_ECC_NONE) {
640                 steps = cg->page_size / eccd->eccsize;
641                 oob = malloc(cg->oob_size, M_NAND, M_WAITOK);
642                 eccpos = default_software_ecc_positions(chip);
643         }
644
645         nandbus = device_get_parent(chip->dev);
646         NANDBUS_LOCK(nandbus);
647         NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num);
648
649         while (num--) {
650                 if (NAND_PROGRAM_PAGE(chip->dev, page, buf, cg->page_size, 0)) {
651                         err = ENXIO;
652                         break;
653                 }
654
655                 if (eccd->eccmode != NAND_ECC_NONE) {
656                         if (NAND_GET_ECC(chip->dev, buf, &eccd->ecccalculated,
657                             &needwrite)) {
658                                 err = ENXIO;
659                                 break;
660                         }
661                         nand_debug(NDBG_ECC,"ECC calculated:");
662                         if (nand_debug_flag & NDBG_ECC)
663                                 for (i = 0; i < (eccd->eccbytes * steps); i++)
664                                         printf("%x ", eccd->ecccalculated[i]);
665
666                         nand_debug(NDBG_ECC,"\n");
667
668                         if (needwrite) {
669                                 if (NAND_READ_OOB(chip->dev, page, oob, cg->oob_size,
670                                     0)) {
671                                         err = ENXIO;
672                                         break;
673                                 }
674
675                                 for (i = 0; i < (eccd->eccbytes * steps); i++)
676                                         oob[eccpos[i]] = eccd->ecccalculated[i];
677
678                                 if (NAND_PROGRAM_OOB(chip->dev, page, oob,
679                                     cg->oob_size, 0)) {
680                                         err = ENXIO;
681                                         break;
682                                 }
683                         }
684                 }
685
686                 pg_stat = &(chip->pg_stat[page]);
687                 pg_stat->page_written++;
688
689                 page++;
690                 buf += cg->page_size;
691         }
692
693         NANDBUS_UNLOCK(nandbus);
694
695         if (oob)
696                 free(oob, M_NAND);
697
698         return (err);
699 }
700
701 int
702 nand_prog_pages_raw(struct nand_chip *chip, uint32_t offset, void *buf,
703     uint32_t len)
704 {
705         struct chip_geom *cg;
706         device_t nandbus;
707         uint8_t *ptr;
708         uint32_t page, num, end, begin = 0, begin_off;
709         int retval = 0;
710
711         cg = &chip->chip_geom;
712         page = offset_to_page(cg, offset);
713         begin_off = offset - page * cg->page_size;
714         if (begin_off) {
715                 begin = cg->page_size - begin_off;
716                 len -= begin;
717         }
718         num = len / cg->page_size;
719         end = len % cg->page_size;
720
721         nandbus = device_get_parent(chip->dev);
722         NANDBUS_LOCK(nandbus);
723         NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num);
724
725         ptr = (uint8_t *)buf;
726         if (begin_off) {
727                 if (NAND_PROGRAM_PAGE(chip->dev, page, ptr, begin, begin_off)) {
728                         NANDBUS_UNLOCK(nandbus);
729                         return (ENXIO);
730                 }
731
732                 page++;
733                 ptr += begin;
734         }
735
736         while (num--) {
737                 if (NAND_PROGRAM_PAGE(chip->dev, page, ptr, cg->page_size, 0)) {
738                         NANDBUS_UNLOCK(nandbus);
739                         return (ENXIO);
740                 }
741
742                 page++;
743                 ptr += cg->page_size;
744         }
745
746         if (end)
747                 retval = NAND_PROGRAM_PAGE(chip->dev, page, ptr, end, 0);
748
749         NANDBUS_UNLOCK(nandbus);
750
751         return (retval);
752 }
753
754 int
755 nand_read_oob(struct nand_chip *chip, uint32_t page, void *buf,
756     uint32_t len)
757 {
758         device_t nandbus;
759         int retval = 0;
760
761         nandbus = device_get_parent(chip->dev);
762         NANDBUS_LOCK(nandbus);
763         NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num);
764
765         retval = NAND_READ_OOB(chip->dev, page, buf, len, 0);
766
767         NANDBUS_UNLOCK(nandbus);
768
769         return (retval);
770 }
771
772
773 int
774 nand_prog_oob(struct nand_chip *chip, uint32_t page, void *buf,
775     uint32_t len)
776 {
777         device_t nandbus;
778         int retval = 0;
779
780         nandbus = device_get_parent(chip->dev);
781         NANDBUS_LOCK(nandbus);
782         NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num);
783
784         retval = NAND_PROGRAM_OOB(chip->dev, page, buf, len, 0);
785
786         NANDBUS_UNLOCK(nandbus);
787
788         return (retval);
789 }
790
791 int
792 nand_erase_blocks(struct nand_chip *chip, off_t offset, size_t len)
793 {
794         device_t nandbus;
795         struct chip_geom *cg;
796         uint32_t block, num_blocks;
797         int err = 0;
798
799         cg = &chip->chip_geom;
800         if ((offset % cg->block_size) || (len % cg->block_size))
801                 return (EINVAL);
802
803         block = offset / cg->block_size;
804         num_blocks = len / cg->block_size;
805         nand_debug(NDBG_NAND,"%p erase blocks %d[%d]", chip, block, num_blocks);
806
807         nandbus = device_get_parent(chip->dev);
808         NANDBUS_LOCK(nandbus);
809         NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num);
810
811         while (num_blocks--) {
812                 if (!nand_check_bad_block(chip, block)) {
813                         if (NAND_ERASE_BLOCK(chip->dev, block)) {
814                                 nand_debug(NDBG_NAND,"%p erase blocks %d error",
815                                     chip, block);
816                                 nand_mark_bad_block(chip, block);
817                                 err = ENXIO;
818                         }
819                 } else
820                         err = ENXIO;
821
822                 block++;
823         };
824
825         NANDBUS_UNLOCK(nandbus);
826
827         if (err)
828                 nand_update_bbt(chip);
829
830         return (err);
831 }
832
833 MODULE_VERSION(nand, 1);