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