xref: /trueos/sys/dev/nand/nand.c (revision 8b635cded30beba47401118e7af15d2d31ce15ed)
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
nand_tunable_init(void * arg)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
nand_debug(int level,const char * fmt,...)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
nand_init(struct nand_softc * nand,device_t dev,int ecc_mode,int ecc_bytes,int ecc_size,uint16_t * eccposition,char * cdev_name)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
nand_onfi_set_params(struct nand_chip * chip,struct onfi_chip_params * params)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
nand_set_params(struct nand_chip * chip,struct nand_params * params)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
nand_init_stat(struct nand_chip * chip)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
nand_destroy_stat(struct nand_chip * chip)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
init_chip_geom(struct chip_geom * cg,uint32_t luns,uint32_t blks_per_lun,uint32_t pgs_per_blk,uint32_t pg_size,uint32_t oob_size)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
nand_row_to_blkpg(struct chip_geom * cg,uint32_t row,uint32_t * lun,uint32_t * blk,uint32_t * pg)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 
page_to_row(struct chip_geom * cg,uint32_t page,uint32_t * row)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
nand_check_page_boundary(struct nand_chip * chip,uint32_t page)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
nand_get_chip_param(struct nand_chip * chip,struct chip_param_io * param)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 *
default_software_ecc_positions(struct nand_chip * chip)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
calculate_ecc(const uint8_t * buf,uint8_t * ecc)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
correct_ecc(uint8_t * buf,uint8_t * calc_ecc,uint8_t * read_ecc)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
nand_softecc_get(device_t dev,uint8_t * buf,int pagesize,uint8_t * ecc)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
nand_softecc_correct(device_t dev,uint8_t * buf,int pagesize,uint8_t * readecc,uint8_t * calcecc)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
offset_to_page(struct chip_geom * cg,uint32_t offset)459 offset_to_page(struct chip_geom *cg, uint32_t offset)
460 {
461 
462 	return (offset / cg->page_size);
463 }
464 
465 int
nand_read_pages(struct nand_chip * chip,uint32_t offset,void * buf,uint32_t len)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
nand_read_pages_raw(struct nand_chip * chip,uint32_t offset,void * buf,uint32_t len)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
nand_prog_pages(struct nand_chip * chip,uint32_t offset,uint8_t * buf,uint32_t len)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
nand_prog_pages_raw(struct nand_chip * chip,uint32_t offset,void * buf,uint32_t len)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
nand_read_oob(struct nand_chip * chip,uint32_t page,void * buf,uint32_t len)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
nand_prog_oob(struct nand_chip * chip,uint32_t page,void * buf,uint32_t len)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
nand_erase_blocks(struct nand_chip * chip,off_t offset,size_t len)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);
834