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