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
69int nand_debug_flag = 0;
70SYSCTL_INT(_debug, OID_AUTO, nand_debug, CTLFLAG_RWTUN, &nand_debug_flag, 0,
71    "NAND subsystem debug flag");
72
73MALLOC_DEFINE(M_NAND, "NAND", "NAND dynamic data");
74
75static void calculate_ecc(const uint8_t *, uint8_t *);
76static int correct_ecc(uint8_t *, uint8_t *, uint8_t *);
77
78void
79nand_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
91void
92nand_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
110void
111nand_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
129void
130nand_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
152int
153nand_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
181void
182nand_destroy_stat(struct nand_chip *chip)
183{
184
185	free(chip->pg_stat, M_NAND);
186	free(chip->blk_stat, M_NAND);
187}
188
189int
190init_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
232int
233nand_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
254int 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
274int
275nand_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
289void
290nand_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
302static uint16_t *
303default_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
325static void
326calculate_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
370static int
371correct_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
420int
421nand_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
434int
435nand_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
451static int
452offset_to_page(struct chip_geom *cg, uint32_t offset)
453{
454
455	return (offset / cg->page_size);
456}
457
458int
459nand_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
555int
556nand_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
612int
613nand_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
694int
695nand_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
747int
748nand_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
766int
767nand_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
784int
785nand_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
826MODULE_VERSION(nand, 1);
827