xref: /NextBSD/sys/dev/nand/nand.c (revision e5d2f8730c92c4abb6de986ec4e1f39a242b9868)
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_RWTUN, &nand_debug_flag, 0,
69     "NAND subsystem debug flag");
70 
71 MALLOC_DEFINE(M_NAND, "NAND", "NAND dynamic data");
72 
73 static void calculate_ecc(const uint8_t *, uint8_t *);
74 static int correct_ecc(uint8_t *, uint8_t *, uint8_t *);
75 
76 void
nand_debug(int level,const char * fmt,...)77 nand_debug(int level, const char *fmt, ...)
78 {
79 	va_list ap;
80 
81 	if (!(nand_debug_flag & level))
82 		return;
83 	va_start(ap, fmt);
84 	vprintf(fmt, ap);
85 	va_end(ap);
86 	printf("\n");
87 }
88 
89 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)90 nand_init(struct nand_softc *nand, device_t dev, int ecc_mode,
91     int ecc_bytes, int ecc_size, uint16_t *eccposition, char *cdev_name)
92 {
93 
94 	nand->ecc.eccmode = ecc_mode;
95 	nand->chip_cdev_name = cdev_name;
96 
97 	if (ecc_mode == NAND_ECC_SOFT) {
98 		nand->ecc.eccbytes = SOFTECC_BYTES;
99 		nand->ecc.eccsize = SOFTECC_SIZE;
100 	} else if (ecc_mode != NAND_ECC_NONE) {
101 		nand->ecc.eccbytes = ecc_bytes;
102 		nand->ecc.eccsize = ecc_size;
103 		if (eccposition)
104 			nand->ecc.eccpositions = eccposition;
105 	}
106 }
107 
108 void
nand_onfi_set_params(struct nand_chip * chip,struct onfi_chip_params * params)109 nand_onfi_set_params(struct nand_chip *chip, struct onfi_chip_params *params)
110 {
111 	struct chip_geom *cg;
112 
113 	cg = &chip->chip_geom;
114 
115 	init_chip_geom(cg, params->luns, params->blocks_per_lun,
116 	    params->pages_per_block, params->bytes_per_page,
117 	    params->spare_bytes_per_page);
118 	chip->t_bers = params->t_bers;
119 	chip->t_prog = params->t_prog;
120 	chip->t_r = params->t_r;
121 	chip->t_ccs = params->t_ccs;
122 
123 	if (params->features & ONFI_FEAT_16BIT)
124 		chip->flags |= NAND_16_BIT;
125 }
126 
127 void
nand_set_params(struct nand_chip * chip,struct nand_params * params)128 nand_set_params(struct nand_chip *chip, struct nand_params *params)
129 {
130 	struct chip_geom *cg;
131 	uint32_t blocks_per_chip;
132 
133 	cg = &chip->chip_geom;
134 	blocks_per_chip = (params->chip_size << 20) /
135 	    (params->page_size * params->pages_per_block);
136 
137 	init_chip_geom(cg, 1, blocks_per_chip,
138 	    params->pages_per_block, params->page_size,
139 	    params->oob_size);
140 
141 	chip->t_bers = NAND_ERASE_DELAY;
142 	chip->t_prog = NAND_PROG_DELAY;
143 	chip->t_r = NAND_READ_DELAY;
144 	chip->t_ccs = 0;
145 
146 	if (params->flags & NAND_16_BIT)
147 		chip->flags |= NAND_16_BIT;
148 }
149 
150 int
nand_init_stat(struct nand_chip * chip)151 nand_init_stat(struct nand_chip *chip)
152 {
153 	struct block_stat *blk_stat;
154 	struct page_stat *pg_stat;
155 	struct chip_geom *cg;
156 	uint32_t blks, pgs;
157 
158 	cg = &chip->chip_geom;
159 	blks = cg->blks_per_lun * cg->luns;
160 	blk_stat = malloc(sizeof(struct block_stat) * blks, M_NAND,
161 	    M_WAITOK | M_ZERO);
162 	if (!blk_stat)
163 		return (ENOMEM);
164 
165 	pgs = blks * cg->pgs_per_blk;
166 	pg_stat = malloc(sizeof(struct page_stat) * pgs, M_NAND,
167 	    M_WAITOK | M_ZERO);
168 	if (!pg_stat) {
169 		free(blk_stat, M_NAND);
170 		return (ENOMEM);
171 	}
172 
173 	chip->blk_stat = blk_stat;
174 	chip->pg_stat = pg_stat;
175 
176 	return (0);
177 }
178 
179 void
nand_destroy_stat(struct nand_chip * chip)180 nand_destroy_stat(struct nand_chip *chip)
181 {
182 
183 	free(chip->pg_stat, M_NAND);
184 	free(chip->blk_stat, M_NAND);
185 }
186 
187 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)188 init_chip_geom(struct chip_geom *cg, uint32_t luns, uint32_t blks_per_lun,
189     uint32_t pgs_per_blk, uint32_t pg_size, uint32_t oob_size)
190 {
191 	int shift;
192 
193 	if (!cg)
194 		return (-1);
195 
196 	cg->luns = luns;
197 	cg->blks_per_lun = blks_per_lun;
198 	cg->blks_per_chip = blks_per_lun * luns;
199 	cg->pgs_per_blk = pgs_per_blk;
200 
201 	cg->page_size = pg_size;
202 	cg->oob_size = oob_size;
203 	cg->block_size = cg->page_size * cg->pgs_per_blk;
204 	cg->chip_size = cg->block_size * cg->blks_per_chip;
205 
206 	shift = fls(cg->pgs_per_blk - 1);
207 	cg->pg_mask = (1 << shift) - 1;
208 	cg->blk_shift = shift;
209 
210 	if (cg->blks_per_lun > 0) {
211 		shift = fls(cg->blks_per_lun - 1);
212 		cg->blk_mask = ((1 << shift) - 1) << cg->blk_shift;
213 	} else {
214 		shift = 0;
215 		cg->blk_mask = 0;
216 	}
217 
218 	cg->lun_shift = shift + cg->blk_shift;
219 	shift = fls(cg->luns - 1);
220 	cg->lun_mask = ((1 << shift) - 1) << cg->lun_shift;
221 
222 	nand_debug(NDBG_NAND, "Masks: lun 0x%x blk 0x%x page 0x%x\n"
223 	    "Shifts: lun %d blk %d",
224 	    cg->lun_mask, cg->blk_mask, cg->pg_mask,
225 	    cg->lun_shift, cg->blk_shift);
226 
227 	return (0);
228 }
229 
230 int
nand_row_to_blkpg(struct chip_geom * cg,uint32_t row,uint32_t * lun,uint32_t * blk,uint32_t * pg)231 nand_row_to_blkpg(struct chip_geom *cg, uint32_t row, uint32_t *lun,
232     uint32_t *blk, uint32_t *pg)
233 {
234 
235 	if (!cg || !lun || !blk || !pg)
236 		return (-1);
237 
238 	if (row & ~(cg->lun_mask | cg->blk_mask | cg->pg_mask)) {
239 		nand_debug(NDBG_NAND,"Address out of bounds\n");
240 		return (-1);
241 	}
242 
243 	*lun = (row & cg->lun_mask) >> cg->lun_shift;
244 	*blk = (row & cg->blk_mask) >> cg->blk_shift;
245 	*pg = (row & cg->pg_mask);
246 
247 	nand_debug(NDBG_NAND,"address %x-%x-%x\n", *lun, *blk, *pg);
248 
249 	return (0);
250 }
251 
page_to_row(struct chip_geom * cg,uint32_t page,uint32_t * row)252 int page_to_row(struct chip_geom *cg, uint32_t page, uint32_t *row)
253 {
254 	uint32_t lun, block, pg_in_blk;
255 
256 	if (!cg || !row)
257 		return (-1);
258 
259 	block = page / cg->pgs_per_blk;
260 	pg_in_blk = page % cg->pgs_per_blk;
261 
262 	lun = block / cg->blks_per_lun;
263 	block = block % cg->blks_per_lun;
264 
265 	*row = (lun << cg->lun_shift) & cg->lun_mask;
266 	*row |= ((block << cg->blk_shift) & cg->blk_mask);
267 	*row |= (pg_in_blk & cg->pg_mask);
268 
269 	return (0);
270 }
271 
272 int
nand_check_page_boundary(struct nand_chip * chip,uint32_t page)273 nand_check_page_boundary(struct nand_chip *chip, uint32_t page)
274 {
275 	struct chip_geom* cg;
276 
277 	cg = &chip->chip_geom;
278 	if (page >= (cg->pgs_per_blk * cg->blks_per_lun * cg->luns)) {
279 		nand_debug(NDBG_GEN,"%s: page number too big %#x\n",
280 		    __func__, page);
281 		return (1);
282 	}
283 
284 	return (0);
285 }
286 
287 void
nand_get_chip_param(struct nand_chip * chip,struct chip_param_io * param)288 nand_get_chip_param(struct nand_chip *chip, struct chip_param_io *param)
289 {
290 	struct chip_geom *cg;
291 
292 	cg = &chip->chip_geom;
293 	param->page_size = cg->page_size;
294 	param->oob_size = cg->oob_size;
295 
296 	param->blocks = cg->blks_per_lun * cg->luns;
297 	param->pages_per_block = cg->pgs_per_blk;
298 }
299 
300 static uint16_t *
default_software_ecc_positions(struct nand_chip * chip)301 default_software_ecc_positions(struct nand_chip *chip)
302 {
303 	/* If positions have been set already, use them. */
304 	if (chip->nand->ecc.eccpositions)
305 		return (chip->nand->ecc.eccpositions);
306 
307 	/*
308 	 * XXX Note that the following logic isn't really sufficient, especially
309 	 * in the ONFI case where the number of ECC bytes can be dictated by
310 	 * values in the parameters page, and that could lead to needing more
311 	 * byte positions than exist within the tables of software-ecc defaults.
312 	 */
313 	if (chip->chip_geom.oob_size >= 128)
314 		return (default_software_ecc_positions_128);
315 	if (chip->chip_geom.oob_size >= 64)
316 		return (default_software_ecc_positions_64);
317 	else if (chip->chip_geom.oob_size >= 16)
318 		return (default_software_ecc_positions_16);
319 
320 	return (NULL);
321 }
322 
323 static void
calculate_ecc(const uint8_t * buf,uint8_t * ecc)324 calculate_ecc(const uint8_t *buf, uint8_t *ecc)
325 {
326 	uint8_t p8, byte;
327 	int i;
328 
329 	memset(ecc, 0, 3);
330 
331 	for (i = 0; i < 256; i++) {
332 		byte = buf[i];
333 		ecc[0] ^= (BIT0(byte) ^ BIT2(byte) ^ BIT4(byte) ^
334 		    BIT6(byte)) << 2;
335 		ecc[0] ^= (BIT1(byte) ^ BIT3(byte) ^ BIT5(byte) ^
336 		    BIT7(byte)) << 3;
337 		ecc[0] ^= (BIT0(byte) ^ BIT1(byte) ^ BIT4(byte) ^
338 		    BIT5(byte)) << 4;
339 		ecc[0] ^= (BIT2(byte) ^ BIT3(byte) ^ BIT6(byte) ^
340 		    BIT7(byte)) << 5;
341 		ecc[0] ^= (BIT0(byte) ^ BIT1(byte) ^ BIT2(byte) ^
342 		    BIT3(byte)) << 6;
343 		ecc[0] ^= (BIT4(byte) ^ BIT5(byte) ^ BIT6(byte) ^
344 		    BIT7(byte)) << 7;
345 
346 		p8 = BIT0(byte) ^ BIT1(byte) ^ BIT2(byte) ^
347 		    BIT3(byte) ^ BIT4(byte) ^ BIT5(byte) ^ BIT6(byte) ^
348 		    BIT7(byte);
349 
350 		if (p8) {
351 			ecc[2] ^= (0x1 << BIT0(i));
352 			ecc[2] ^= (0x4 << BIT1(i));
353 			ecc[2] ^= (0x10 << BIT2(i));
354 			ecc[2] ^= (0x40 << BIT3(i));
355 
356 			ecc[1] ^= (0x1 << BIT4(i));
357 			ecc[1] ^= (0x4 << BIT5(i));
358 			ecc[1] ^= (0x10 << BIT6(i));
359 			ecc[1] ^= (0x40 << BIT7(i));
360 		}
361 	}
362 	ecc[0] = ~ecc[0];
363 	ecc[1] = ~ecc[1];
364 	ecc[2] = ~ecc[2];
365 	ecc[0] |= 3;
366 }
367 
368 static int
correct_ecc(uint8_t * buf,uint8_t * calc_ecc,uint8_t * read_ecc)369 correct_ecc(uint8_t *buf, uint8_t *calc_ecc, uint8_t *read_ecc)
370 {
371 	uint8_t ecc0, ecc1, ecc2, onesnum, bit, byte;
372 	uint16_t addr = 0;
373 
374 	ecc0 = calc_ecc[0] ^ read_ecc[0];
375 	ecc1 = calc_ecc[1] ^ read_ecc[1];
376 	ecc2 = calc_ecc[2] ^ read_ecc[2];
377 
378 	if (!ecc0 && !ecc1 && !ecc2)
379 		return (ECC_OK);
380 
381 	addr = BIT3(ecc0) | (BIT5(ecc0) << 1) | (BIT7(ecc0) << 2);
382 	addr |= (BIT1(ecc2) << 3) | (BIT3(ecc2) << 4) |
383 	    (BIT5(ecc2) << 5) |  (BIT7(ecc2) << 6);
384 	addr |= (BIT1(ecc1) << 7) | (BIT3(ecc1) << 8) |
385 	    (BIT5(ecc1) << 9) |  (BIT7(ecc1) << 10);
386 
387 	onesnum = 0;
388 	while (ecc0 || ecc1 || ecc2) {
389 		if (ecc0 & 1)
390 			onesnum++;
391 		if (ecc1 & 1)
392 			onesnum++;
393 		if (ecc2 & 1)
394 			onesnum++;
395 
396 		ecc0 >>= 1;
397 		ecc1 >>= 1;
398 		ecc2 >>= 1;
399 	}
400 
401 	if (onesnum == 11) {
402 		/* Correctable error */
403 		bit = addr & 7;
404 		byte = addr >> 3;
405 		buf[byte] ^= (1 << bit);
406 		return (ECC_CORRECTABLE);
407 	} else if (onesnum == 1) {
408 		/* ECC error */
409 		return (ECC_ERROR_ECC);
410 	} else {
411 		/* Uncorrectable error */
412 		return (ECC_UNCORRECTABLE);
413 	}
414 
415 	return (0);
416 }
417 
418 int
nand_softecc_get(device_t dev,uint8_t * buf,int pagesize,uint8_t * ecc)419 nand_softecc_get(device_t dev, uint8_t *buf, int pagesize, uint8_t *ecc)
420 {
421 	int steps = pagesize / SOFTECC_SIZE;
422 	int i = 0, j = 0;
423 
424 	for (; i < (steps * SOFTECC_BYTES);
425 	    i += SOFTECC_BYTES, j += SOFTECC_SIZE) {
426 		calculate_ecc(&buf[j], &ecc[i]);
427 	}
428 
429 	return (0);
430 }
431 
432 int
nand_softecc_correct(device_t dev,uint8_t * buf,int pagesize,uint8_t * readecc,uint8_t * calcecc)433 nand_softecc_correct(device_t dev, uint8_t *buf, int pagesize,
434     uint8_t *readecc, uint8_t *calcecc)
435 {
436 	int steps = pagesize / SOFTECC_SIZE;
437 	int i = 0, j = 0, ret = 0;
438 
439 	for (i = 0; i < (steps * SOFTECC_BYTES);
440 	    i += SOFTECC_BYTES, j += SOFTECC_SIZE) {
441 		ret += correct_ecc(&buf[j], &calcecc[i], &readecc[i]);
442 		if (ret < 0)
443 			return (ret);
444 	}
445 
446 	return (ret);
447 }
448 
449 static int
offset_to_page(struct chip_geom * cg,uint32_t offset)450 offset_to_page(struct chip_geom *cg, uint32_t offset)
451 {
452 
453 	return (offset / cg->page_size);
454 }
455 
456 int
nand_read_pages(struct nand_chip * chip,uint32_t offset,void * buf,uint32_t len)457 nand_read_pages(struct nand_chip *chip, uint32_t offset, void *buf,
458     uint32_t len)
459 {
460 	struct chip_geom *cg;
461 	struct nand_ecc_data *eccd;
462 	struct page_stat *pg_stat;
463 	device_t nandbus;
464 	void *oob = NULL;
465 	uint8_t *ptr;
466 	uint16_t *eccpos = NULL;
467 	uint32_t page, num, steps = 0;
468 	int i, retval = 0, needwrite;
469 
470 	nand_debug(NDBG_NAND,"%p read page %x[%x]", chip, offset, len);
471 	cg = &chip->chip_geom;
472 	eccd = &chip->nand->ecc;
473 	page = offset_to_page(cg, offset);
474 	num = len / cg->page_size;
475 
476 	if (eccd->eccmode != NAND_ECC_NONE) {
477 		steps = cg->page_size / eccd->eccsize;
478 		eccpos = default_software_ecc_positions(chip);
479 		oob = malloc(cg->oob_size, M_NAND, M_WAITOK);
480 	}
481 
482 	nandbus = device_get_parent(chip->dev);
483 	NANDBUS_LOCK(nandbus);
484 	NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num);
485 
486 	ptr = (uint8_t *)buf;
487 	while (num--) {
488 		pg_stat = &(chip->pg_stat[page]);
489 
490 		if (NAND_READ_PAGE(chip->dev, page, ptr, cg->page_size, 0)) {
491 			retval = ENXIO;
492 			break;
493 		}
494 
495 		if (eccd->eccmode != NAND_ECC_NONE) {
496 			if (NAND_GET_ECC(chip->dev, ptr, eccd->ecccalculated,
497 			    &needwrite)) {
498 				retval = ENXIO;
499 				break;
500 			}
501 			nand_debug(NDBG_ECC,"%s: ECC calculated:",
502 			    __func__);
503 			if (nand_debug_flag & NDBG_ECC)
504 				for (i = 0; i < (eccd->eccbytes * steps); i++)
505 					printf("%x ", eccd->ecccalculated[i]);
506 
507 			nand_debug(NDBG_ECC,"\n");
508 
509 			if (NAND_READ_OOB(chip->dev, page, oob, cg->oob_size,
510 			    0)) {
511 				retval = ENXIO;
512 				break;
513 			}
514 			for (i = 0; i < (eccd->eccbytes * steps); i++)
515 				eccd->eccread[i] = ((uint8_t *)oob)[eccpos[i]];
516 
517 			nand_debug(NDBG_ECC,"%s: ECC read:", __func__);
518 			if (nand_debug_flag & NDBG_ECC)
519 				for (i = 0; i < (eccd->eccbytes * steps); i++)
520 					printf("%x ", eccd->eccread[i]);
521 			nand_debug(NDBG_ECC,"\n");
522 
523 			retval = NAND_CORRECT_ECC(chip->dev, ptr, eccd->eccread,
524 			    eccd->ecccalculated);
525 
526 			nand_debug(NDBG_ECC, "NAND_CORRECT_ECC() returned %d",
527 			    retval);
528 
529 			if (retval == 0)
530 				pg_stat->ecc_stat.ecc_succeded++;
531 			else if (retval > 0) {
532 				pg_stat->ecc_stat.ecc_corrected += retval;
533 				retval = ECC_CORRECTABLE;
534 			} else {
535 				pg_stat->ecc_stat.ecc_failed++;
536 				break;
537 			}
538 		}
539 
540 		pg_stat->page_read++;
541 		page++;
542 		ptr += cg->page_size;
543 	}
544 
545 	NANDBUS_UNLOCK(nandbus);
546 
547 	if (oob)
548 		free(oob, M_NAND);
549 
550 	return (retval);
551 }
552 
553 int
nand_read_pages_raw(struct nand_chip * chip,uint32_t offset,void * buf,uint32_t len)554 nand_read_pages_raw(struct nand_chip *chip, uint32_t offset, void *buf,
555     uint32_t len)
556 {
557 	struct chip_geom *cg;
558 	device_t nandbus;
559 	uint8_t *ptr;
560 	uint32_t page, num, end, begin = 0, begin_off;
561 	int retval = 0;
562 
563 	cg = &chip->chip_geom;
564 	page = offset_to_page(cg, offset);
565 	begin_off = offset - page * cg->page_size;
566 	if (begin_off) {
567 		begin = cg->page_size - begin_off;
568 		len -= begin;
569 	}
570 	num = len / cg->page_size;
571 	end = len % cg->page_size;
572 
573 	nandbus = device_get_parent(chip->dev);
574 	NANDBUS_LOCK(nandbus);
575 	NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num);
576 
577 	ptr = (uint8_t *)buf;
578 	if (begin_off) {
579 		if (NAND_READ_PAGE(chip->dev, page, ptr, begin, begin_off)) {
580 			NANDBUS_UNLOCK(nandbus);
581 			return (ENXIO);
582 		}
583 
584 		page++;
585 		ptr += begin;
586 	}
587 
588 	while (num--) {
589 		if (NAND_READ_PAGE(chip->dev, page, ptr, cg->page_size, 0)) {
590 			NANDBUS_UNLOCK(nandbus);
591 			return (ENXIO);
592 		}
593 
594 		page++;
595 		ptr += cg->page_size;
596 	}
597 
598 	if (end)
599 		if (NAND_READ_PAGE(chip->dev, page, ptr, end, 0)) {
600 			NANDBUS_UNLOCK(nandbus);
601 			return (ENXIO);
602 		}
603 
604 	NANDBUS_UNLOCK(nandbus);
605 
606 	return (retval);
607 }
608 
609 
610 int
nand_prog_pages(struct nand_chip * chip,uint32_t offset,uint8_t * buf,uint32_t len)611 nand_prog_pages(struct nand_chip *chip, uint32_t offset, uint8_t *buf,
612     uint32_t len)
613 {
614 	struct chip_geom *cg;
615 	struct page_stat *pg_stat;
616 	struct nand_ecc_data *eccd;
617 	device_t nandbus;
618 	uint32_t page, num;
619 	uint8_t *oob = NULL;
620 	uint16_t *eccpos = NULL;
621 	int steps = 0, i, needwrite, err = 0;
622 
623 	nand_debug(NDBG_NAND,"%p prog page %x[%x]", chip, offset, len);
624 
625 	eccd = &chip->nand->ecc;
626 	cg = &chip->chip_geom;
627 	page = offset_to_page(cg, offset);
628 	num = len / cg->page_size;
629 
630 	if (eccd->eccmode != NAND_ECC_NONE) {
631 		steps = cg->page_size / eccd->eccsize;
632 		oob = malloc(cg->oob_size, M_NAND, M_WAITOK);
633 		eccpos = default_software_ecc_positions(chip);
634 	}
635 
636 	nandbus = device_get_parent(chip->dev);
637 	NANDBUS_LOCK(nandbus);
638 	NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num);
639 
640 	while (num--) {
641 		if (NAND_PROGRAM_PAGE(chip->dev, page, buf, cg->page_size, 0)) {
642 			err = ENXIO;
643 			break;
644 		}
645 
646 		if (eccd->eccmode != NAND_ECC_NONE) {
647 			if (NAND_GET_ECC(chip->dev, buf, &eccd->ecccalculated,
648 			    &needwrite)) {
649 				err = ENXIO;
650 				break;
651 			}
652 			nand_debug(NDBG_ECC,"ECC calculated:");
653 			if (nand_debug_flag & NDBG_ECC)
654 				for (i = 0; i < (eccd->eccbytes * steps); i++)
655 					printf("%x ", eccd->ecccalculated[i]);
656 
657 			nand_debug(NDBG_ECC,"\n");
658 
659 			if (needwrite) {
660 				if (NAND_READ_OOB(chip->dev, page, oob, cg->oob_size,
661 				    0)) {
662 					err = ENXIO;
663 					break;
664 				}
665 
666 				for (i = 0; i < (eccd->eccbytes * steps); i++)
667 					oob[eccpos[i]] = eccd->ecccalculated[i];
668 
669 				if (NAND_PROGRAM_OOB(chip->dev, page, oob,
670 				    cg->oob_size, 0)) {
671 					err = ENXIO;
672 					break;
673 				}
674 			}
675 		}
676 
677 		pg_stat = &(chip->pg_stat[page]);
678 		pg_stat->page_written++;
679 
680 		page++;
681 		buf += cg->page_size;
682 	}
683 
684 	NANDBUS_UNLOCK(nandbus);
685 
686 	if (oob)
687 		free(oob, M_NAND);
688 
689 	return (err);
690 }
691 
692 int
nand_prog_pages_raw(struct nand_chip * chip,uint32_t offset,void * buf,uint32_t len)693 nand_prog_pages_raw(struct nand_chip *chip, uint32_t offset, void *buf,
694     uint32_t len)
695 {
696 	struct chip_geom *cg;
697 	device_t nandbus;
698 	uint8_t *ptr;
699 	uint32_t page, num, end, begin = 0, begin_off;
700 	int retval = 0;
701 
702 	cg = &chip->chip_geom;
703 	page = offset_to_page(cg, offset);
704 	begin_off = offset - page * cg->page_size;
705 	if (begin_off) {
706 		begin = cg->page_size - begin_off;
707 		len -= begin;
708 	}
709 	num = len / cg->page_size;
710 	end = len % cg->page_size;
711 
712 	nandbus = device_get_parent(chip->dev);
713 	NANDBUS_LOCK(nandbus);
714 	NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num);
715 
716 	ptr = (uint8_t *)buf;
717 	if (begin_off) {
718 		if (NAND_PROGRAM_PAGE(chip->dev, page, ptr, begin, begin_off)) {
719 			NANDBUS_UNLOCK(nandbus);
720 			return (ENXIO);
721 		}
722 
723 		page++;
724 		ptr += begin;
725 	}
726 
727 	while (num--) {
728 		if (NAND_PROGRAM_PAGE(chip->dev, page, ptr, cg->page_size, 0)) {
729 			NANDBUS_UNLOCK(nandbus);
730 			return (ENXIO);
731 		}
732 
733 		page++;
734 		ptr += cg->page_size;
735 	}
736 
737 	if (end)
738 		retval = NAND_PROGRAM_PAGE(chip->dev, page, ptr, end, 0);
739 
740 	NANDBUS_UNLOCK(nandbus);
741 
742 	return (retval);
743 }
744 
745 int
nand_read_oob(struct nand_chip * chip,uint32_t page,void * buf,uint32_t len)746 nand_read_oob(struct nand_chip *chip, uint32_t page, void *buf,
747     uint32_t len)
748 {
749 	device_t nandbus;
750 	int retval = 0;
751 
752 	nandbus = device_get_parent(chip->dev);
753 	NANDBUS_LOCK(nandbus);
754 	NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num);
755 
756 	retval = NAND_READ_OOB(chip->dev, page, buf, len, 0);
757 
758 	NANDBUS_UNLOCK(nandbus);
759 
760 	return (retval);
761 }
762 
763 
764 int
nand_prog_oob(struct nand_chip * chip,uint32_t page,void * buf,uint32_t len)765 nand_prog_oob(struct nand_chip *chip, uint32_t page, void *buf,
766     uint32_t len)
767 {
768 	device_t nandbus;
769 	int retval = 0;
770 
771 	nandbus = device_get_parent(chip->dev);
772 	NANDBUS_LOCK(nandbus);
773 	NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num);
774 
775 	retval = NAND_PROGRAM_OOB(chip->dev, page, buf, len, 0);
776 
777 	NANDBUS_UNLOCK(nandbus);
778 
779 	return (retval);
780 }
781 
782 int
nand_erase_blocks(struct nand_chip * chip,off_t offset,size_t len)783 nand_erase_blocks(struct nand_chip *chip, off_t offset, size_t len)
784 {
785 	device_t nandbus;
786 	struct chip_geom *cg;
787 	uint32_t block, num_blocks;
788 	int err = 0;
789 
790 	cg = &chip->chip_geom;
791 	if ((offset % cg->block_size) || (len % cg->block_size))
792 		return (EINVAL);
793 
794 	block = offset / cg->block_size;
795 	num_blocks = len / cg->block_size;
796 	nand_debug(NDBG_NAND,"%p erase blocks %d[%d]", chip, block, num_blocks);
797 
798 	nandbus = device_get_parent(chip->dev);
799 	NANDBUS_LOCK(nandbus);
800 	NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num);
801 
802 	while (num_blocks--) {
803 		if (!nand_check_bad_block(chip, block)) {
804 			if (NAND_ERASE_BLOCK(chip->dev, block)) {
805 				nand_debug(NDBG_NAND,"%p erase blocks %d error",
806 				    chip, block);
807 				nand_mark_bad_block(chip, block);
808 				err = ENXIO;
809 			}
810 		} else
811 			err = ENXIO;
812 
813 		block++;
814 	};
815 
816 	NANDBUS_UNLOCK(nandbus);
817 
818 	if (err)
819 		nand_update_bbt(chip);
820 
821 	return (err);
822 }
823 
824 MODULE_VERSION(nand, 1);
825