xref: /netbsd-src/sys/dev/nand/nand.c (revision 14ce4ecc83abd9c99530f94b30f34c17763a8b02)
1 /*	$NetBSD: nand.c,v 1.3 2011/03/09 10:05:08 ahoka Exp $	*/
2 
3 /*-
4  * Copyright (c) 2010 Department of Software Engineering,
5  *		      University of Szeged, Hungary
6  * Copyright (c) 2010 Adam Hoka <ahoka@NetBSD.org>
7  * All rights reserved.
8  *
9  * This code is derived from software contributed to The NetBSD Foundation
10  * by the Department of Software Engineering, University of Szeged, Hungary
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 /* Common driver for NAND chips implementing the ONFI 2.2 specification */
35 
36 #include <sys/cdefs.h>
37 __KERNEL_RCSID(0, "$NetBSD: nand.c,v 1.3 2011/03/09 10:05:08 ahoka Exp $");
38 
39 #include "locators.h"
40 
41 #include <sys/param.h>
42 #include <sys/types.h>
43 #include <sys/device.h>
44 #include <sys/kmem.h>
45 #include <sys/sysctl.h>
46 
47 #include <dev/flash/flash.h>
48 #include <dev/nand/nand.h>
49 #include <dev/nand/onfi.h>
50 #include <dev/nand/hamming.h>
51 #include <dev/nand/nand_bbt.h>
52 #include <dev/nand/nand_crc.h>
53 
54 #include "opt_nand.h"
55 
56 int nand_match(device_t, cfdata_t, void *);
57 void nand_attach(device_t, device_t, void *);
58 int nand_detach(device_t, int);
59 bool nand_shutdown(device_t, int);
60 
61 int nand_print(void *, const char *);
62 
63 static int nand_search(device_t, cfdata_t, const int *, void *);
64 static void nand_address_row(device_t, size_t);
65 static void nand_address_column(device_t, size_t, size_t);
66 static void nand_readid(device_t, struct nand_chip *);
67 static void nand_read_parameter_page(device_t, struct nand_chip *);
68 static const char *nand_midtoname(int);
69 static int nand_scan_media(device_t, struct nand_chip *);
70 static bool nand_check_wp(device_t);
71 
72 CFATTACH_DECL_NEW(nand, sizeof(struct nand_softc),
73     nand_match, nand_attach, nand_detach, NULL);
74 
75 #ifdef NAND_DEBUG
76 int	nanddebug = NAND_DEBUG;
77 #endif
78 
79 int nand_cachesync_timeout = 1;
80 int nand_cachesync_nodenum;
81 
82 const struct nand_manufacturer nand_mfrs[] = {
83 	{ NAND_MFR_AMD,		"AMD" },
84 	{ NAND_MFR_FUJITSU,	"Fujitsu" },
85 	{ NAND_MFR_RENESAS,	"Renesas" },
86 	{ NAND_MFR_STMICRO,	"ST Micro" },
87 	{ NAND_MFR_MICRON,	"Micron" },
88 	{ NAND_MFR_NATIONAL,	"National" },
89 	{ NAND_MFR_TOSHIBA,	"Toshiba" },
90 	{ NAND_MFR_HYNIX,	"Hynix" },
91 	{ NAND_MFR_SAMSUNG,	"Samsung" },
92 	{ NAND_MFR_UNKNOWN,	"Unknown" }
93 };
94 
95 /* ARGSUSED */
96 int
97 nand_match(device_t parent, cfdata_t match, void *aux)
98 {
99 	/* pseudo device, always attaches */
100 	return 1;
101 }
102 
103 void
104 nand_attach(device_t parent, device_t self, void *aux)
105 {
106 	struct nand_softc *sc = device_private(self);
107 	struct nand_attach_args *naa = aux;
108 	struct nand_chip *chip = &sc->sc_chip;
109 
110 	sc->sc_dev = self;
111 	sc->nand_dev = parent;
112 	sc->nand_if = naa->naa_nand_if;
113 
114 	aprint_naive("\n");
115 
116 	if (nand_check_wp(self)) {
117 		aprint_error("NAND chip is write protected!\n");
118 		return;
119 	}
120 
121 	if (nand_scan_media(self, chip)) {
122 		return;
123 	}
124 
125 	/* allocate cache */
126 	chip->nc_oob_cache = kmem_alloc(chip->nc_spare_size, KM_SLEEP);
127 	chip->nc_page_cache = kmem_alloc(chip->nc_page_size, KM_SLEEP);
128 
129 	mutex_init(&sc->sc_device_lock, MUTEX_DEFAULT, IPL_NONE);
130 
131 	if (nand_sync_thread_start(self)) {
132 		goto error;
133 	}
134 
135 	if (!pmf_device_register1(sc->sc_dev, NULL, NULL, nand_shutdown))
136 		aprint_error_dev(sc->sc_dev,
137 		    "couldn't establish power handler\n");
138 
139 #ifdef NAND_BBT
140 	nand_bbt_init(self);
141 	nand_bbt_scan(self);
142 #endif
143 
144 	/*
145 	 * Attach all our devices
146 	 */
147 	config_search_ia(nand_search, self, NULL, NULL);
148 
149 	return;
150 error:
151 	kmem_free(chip->nc_oob_cache, chip->nc_spare_size);
152 	kmem_free(chip->nc_page_cache, chip->nc_page_size);
153 	mutex_destroy(&sc->sc_device_lock);
154 }
155 
156 static int
157 nand_search(device_t parent, cfdata_t cf, const int *ldesc, void *aux)
158 {
159 	struct nand_softc *sc = device_private(parent);
160 	struct nand_chip *chip = &sc->sc_chip;
161 	struct flash_interface *flash_if;
162 	struct flash_attach_args faa;
163 
164 	flash_if = kmem_alloc(sizeof(*flash_if), KM_SLEEP);
165 
166 	flash_if->type = FLASH_TYPE_NAND;
167 
168 	flash_if->read = nand_flash_read;
169 	flash_if->write = nand_flash_write;
170 	flash_if->erase = nand_flash_erase;
171 	flash_if->block_isbad = nand_flash_isbad;
172 	flash_if->block_markbad = nand_flash_markbad;
173 
174 	flash_if->submit = nand_io_submit;
175 
176 	flash_if->erasesize = chip->nc_block_size;
177 	flash_if->page_size = chip->nc_page_size;
178 	flash_if->writesize = chip->nc_page_size;
179 
180 	flash_if->partition.part_offset = cf->cf_loc[FLASHBUSCF_OFFSET];
181 
182 	if (cf->cf_loc[FLASHBUSCF_SIZE] == 0) {
183 		flash_if->size = chip->nc_size -
184 		    flash_if->partition.part_offset;
185 		flash_if->partition.part_size = flash_if->size;
186 	} else {
187 		flash_if->size = cf->cf_loc[FLASHBUSCF_SIZE];
188 		flash_if->partition.part_size = cf->cf_loc[FLASHBUSCF_SIZE];
189 	}
190 
191 	if (cf->cf_loc[FLASHBUSCF_READONLY])
192 		flash_if->partition.part_flags = FLASH_PART_READONLY;
193 	else
194 		flash_if->partition.part_flags = 0;
195 
196 	faa.flash_if = flash_if;
197 
198 	if (config_match(parent, cf, &faa)) {
199 		config_attach(parent, cf, &faa, nand_print);
200 		return 0;
201 	} else {
202 		kmem_free(flash_if, sizeof(*flash_if));
203 	}
204 
205 	return 1;
206 }
207 
208 int
209 nand_detach(device_t self, int flags)
210 {
211 	struct nand_softc *sc = device_private(self);
212 	struct nand_chip *chip = &sc->sc_chip;
213 	int ret = 0;
214 
215 #ifdef NAND_BBT
216 	nand_bbt_detach(self);
217 #endif
218 	nand_sync_thread_stop(self);
219 
220 	/* free oob cache */
221 	kmem_free(chip->nc_oob_cache, chip->nc_spare_size);
222 	kmem_free(chip->nc_page_cache, chip->nc_page_size);
223 	kmem_free(chip->nc_ecc_cache, chip->nc_ecc->necc_size);
224 
225 	mutex_destroy(&sc->sc_device_lock);
226 
227 	pmf_device_deregister(sc->sc_dev);
228 
229 	return ret;
230 }
231 
232 int
233 nand_print(void *aux, const char *pnp)
234 {
235 	if (pnp != NULL)
236 		aprint_normal("nand at %s\n", pnp);
237 
238 	return UNCONF;
239 }
240 
241 device_t
242 nand_attach_mi(struct nand_interface *nand_if, device_t parent)
243 {
244 	struct nand_attach_args arg;
245 
246 	KASSERT(nand_if != NULL);
247 
248 	arg.naa_nand_if = nand_if;
249 	return config_found_ia(parent, "nandbus", &arg, nand_print);
250 }
251 
252 static const char *
253 nand_midtoname(int id)
254 {
255 	int i;
256 
257 	for (i = 0; nand_mfrs[i].id != 0; i++) {
258 		if (nand_mfrs[i].id == id)
259 			return nand_mfrs[i].name;
260 	}
261 
262 	KASSERT(nand_mfrs[i].id == 0);
263 
264 	return nand_mfrs[i].name;
265 }
266 
267 #if 0
268 /* handle quirks here */
269 static void
270 nand_quirks(device_t self, struct nand_chip *chip)
271 {
272 	/* this is an example only! */
273 	switch (chip->nc_manf_id) {
274 	case NAND_MFR_SAMSUNG:
275 		if (chip->nc_dev_id == 0x00) {
276 			/* do something only samsung chips need */
277 			/* or */
278 			/* chip->nc_quirks |= NC_QUIRK_NO_READ_START */
279 		}
280 	}
281 
282 	return;
283 }
284 #endif
285 
286 static int
287 nand_read_legacy_parameters(device_t self, struct nand_chip *chip)
288 {
289 	switch (chip->nc_manf_id) {
290 	case NAND_MFR_MICRON:
291 		return nand_read_parameters_micron(self, chip);
292 	default:
293 		return 1;
294 	}
295 
296 	return 0;
297 }
298 
299 /**
300  * scan media to determine the chip's properties
301  * this function resets the device
302  */
303 static int
304 nand_scan_media(device_t self, struct nand_chip *chip)
305 {
306 	struct nand_softc *sc = device_private(self);
307 	struct nand_ecc *ecc;
308 	uint8_t onfi_signature[4];
309 
310 	nand_select(self, true);
311 	nand_command(self, ONFI_RESET);
312 	nand_select(self, false);
313 
314 	/* check if the device implements the ONFI standard */
315 	nand_select(self, true);
316 	nand_command(self, ONFI_READ_ID);
317 	nand_address(self, 0x20);
318 	nand_read_byte(self, &onfi_signature[0]);
319 	nand_read_byte(self, &onfi_signature[1]);
320 	nand_read_byte(self, &onfi_signature[2]);
321 	nand_read_byte(self, &onfi_signature[3]);
322 	nand_select(self, false);
323 
324 	if (onfi_signature[0] != 'O' || onfi_signature[1] != 'N' ||
325 	    onfi_signature[2] != 'F' || onfi_signature[3] != 'I') {
326 		chip->nc_isonfi = false;
327 
328 		aprint_normal(": Legacy NAND Flash\n");
329 
330 		nand_readid(self, chip);
331 
332 		if (nand_read_legacy_parameters(self, chip)) {
333 			aprint_error_dev(self,
334 			    "can't read device parameters for legacy chip\n");
335 			return 1;
336 		}
337 	} else {
338 		chip->nc_isonfi = true;
339 
340 		aprint_normal(": ONFI NAND Flash\n");
341 
342 		nand_readid(self, chip);
343 		nand_read_parameter_page(self, chip);
344 	}
345 
346 #ifdef NAND_VERBOSE
347 	aprint_normal_dev(self,
348 	    "manufacturer id: 0x%.2x (%s), device id: 0x%.2x\n",
349 	    chip->nc_manf_id,
350 	    nand_midtoname(chip->nc_manf_id),
351 	    chip->nc_dev_id);
352 #endif
353 
354 	aprint_normal_dev(self,
355 	   "page size: %u bytes, spare size: %u bytes, block size: %u bytes\n",
356 	    chip->nc_page_size, chip->nc_spare_size, chip->nc_block_size);
357 
358 	aprint_normal_dev(self,
359 	    "LUN size: %u blocks, LUNs: %u, total storage size: %u MB\n",
360 	    chip->nc_lun_blocks, chip->nc_num_luns,
361 	    chip->nc_size / 1024 / 1024);
362 
363 #ifdef NAND_VERBOSE
364 	aprint_normal_dev(self, "column cycles: %d, row cycles: %d\n",
365 	    chip->nc_addr_cycles_column, chip->nc_addr_cycles_row);
366 #endif
367 
368 	ecc = chip->nc_ecc = &sc->nand_if->ecc;
369 
370 	/*
371 	 * calculate the place of ecc data in oob
372 	 * we try to be compatible with Linux here
373 	 */
374 	switch (chip->nc_spare_size) {
375 	case 8:
376 		ecc->necc_offset = 0;
377 		break;
378 	case 16:
379 		ecc->necc_offset = 0;
380 		break;
381 	case 64:
382 		ecc->necc_offset = 40;
383 		break;
384 	case 128:
385 		ecc->necc_offset = 80;
386 		break;
387 	default:
388 		panic("OOB size is unexpected");
389 	}
390 
391 	ecc->necc_steps = chip->nc_page_size / ecc->necc_block_size;
392 	ecc->necc_size = ecc->necc_steps * ecc->necc_code_size;
393 
394 	/* check if we fit in oob */
395 	if (ecc->necc_offset + ecc->necc_size > chip->nc_spare_size) {
396 		panic("NAND ECC bits dont fit in OOB");
397 	}
398 
399 	/* TODO: mark free oob area available for file systems */
400 
401 	chip->nc_ecc_cache = kmem_zalloc(ecc->necc_size, KM_SLEEP);
402 
403 	/*
404 	 * calculate badblock marker offset in oob
405 	 * we try to be compatible with linux here
406 	 */
407 	if (chip->nc_page_size > 512)
408 		chip->nc_badmarker_offs = 0;
409 	else
410 		chip->nc_badmarker_offs = 5;
411 
412 	/* Calculate page shift and mask */
413 	chip->nc_page_shift = ffs(chip->nc_page_size) - 1;
414 	chip->nc_page_mask = ~(chip->nc_page_size - 1);
415 	/* same for block */
416 	chip->nc_block_shift = ffs(chip->nc_block_size) - 1;
417 	chip->nc_block_mask = ~(chip->nc_block_size - 1);
418 
419 	/* look for quirks here if needed in future */
420 	/* nand_quirks(self, chip); */
421 
422 	return 0;
423 }
424 
425 static void
426 nand_readid(device_t self, struct nand_chip *chip)
427 {
428 	nand_select(self, true);
429 	nand_command(self, ONFI_READ_ID);
430 	nand_address(self, 0x00);
431 
432 	nand_read_byte(self, &chip->nc_manf_id);
433 	nand_read_byte(self, &chip->nc_dev_id);
434 
435 	nand_select(self, false);
436 }
437 
438 static void
439 nand_read_parameter_page(device_t self, struct nand_chip *chip)
440 {
441 	struct onfi_parameter_page params;
442 	uint8_t *bufp;
443 	uint8_t	vendor[13], model[21];
444 	uint16_t crc;
445 	int i;
446 
447 	KASSERT(sizeof(params) == 256);
448 
449 	nand_select(self, true);
450 	nand_command(self, ONFI_READ_PARAMETER_PAGE);
451 	nand_address(self, 0x00);
452 
453 	nand_busy(self);
454 
455 	bufp = (uint8_t *)&params;
456 	for (i = 0; i < 256; i++) {
457 		nand_read_byte(self, &bufp[i]);
458 	}
459 	nand_select(self, false);
460 
461 	/* validate the parameter page with the crc */
462 	crc = nand_crc16(bufp, 254);
463 
464 	if (crc != params.param_integrity_crc) {
465 		aprint_error_dev(self, "parameter page crc check failed\n");
466 		/* TODO: we should read the next parameter page copy */
467 	}
468 
469 	/* strip manufacturer and model string */
470 	strlcpy(vendor, params.param_manufacturer, sizeof(vendor));
471 	for (i = 11; i > 0 && vendor[i] == ' '; i--)
472 		vendor[i] = 0;
473 	strlcpy(model, params.param_model, sizeof(model));
474 	for (i = 19; i > 0 && model[i] == ' '; i--)
475 		model[i] = 0;
476 
477 	aprint_normal_dev(self, "vendor: %s, model: %s\n", vendor, model);
478 
479 	/* XXX TODO multiple LUNs */
480 	if (__predict_false(params.param_numluns != 1)) {
481 		panic("more than one LUNs are not supported yet!\n");
482 	}
483 
484 	chip->nc_size = params.param_pagesize * params.param_blocksize *
485 	    params.param_lunsize * params.param_numluns;
486 
487 	chip->nc_page_size = params.param_pagesize;
488 	chip->nc_block_pages = params.param_blocksize;
489 	chip->nc_block_size = params.param_blocksize * params.param_pagesize;
490 	chip->nc_spare_size = params.param_sparesize;
491 	chip->nc_lun_blocks = params.param_lunsize;
492 	chip->nc_num_luns = params.param_numluns;
493 
494 	/* the lower 4 bits contain the row address cycles */
495 	chip->nc_addr_cycles_row = params.param_addr_cycles & 0x07;
496 	/* the upper 4 bits contain the column address cycles */
497 	chip->nc_addr_cycles_column = (params.param_addr_cycles & ~0x07) >> 4;
498 
499 	if (params.param_features & ONFI_FEATURE_16BIT)
500 		chip->nc_flags |= NC_BUSWIDTH_16;
501 
502 	if (params.param_features & ONFI_FEATURE_EXTENDED_PARAM)
503 		chip->nc_flags |= NC_EXTENDED_PARAM;
504 }
505 
506 /* ARGSUSED */
507 bool
508 nand_shutdown(device_t self, int howto)
509 {
510 	return true;
511 }
512 
513 static void
514 nand_address_column(device_t self, size_t row, size_t column)
515 {
516 	struct nand_softc *sc = device_private(self);
517 	struct nand_chip *chip = &sc->sc_chip;
518 	uint8_t i;
519 
520 	DPRINTF(("addressing row: 0x%jx column: %zu\n",
521 		(uintmax_t )row, column));
522 
523 	/* XXX TODO */
524 	row >>= chip->nc_page_shift;
525 
526 	/* Write the column (subpage) address */
527 	if (chip->nc_flags & NC_BUSWIDTH_16)
528 		column >>= 1;
529 	for (i = 0; i < chip->nc_addr_cycles_column; i++, column >>= 8)
530 		nand_address(self, column & 0xff);
531 
532 	/* Write the row (page) address */
533 	for (i = 0; i < chip->nc_addr_cycles_row; i++, row >>= 8)
534 		nand_address(self, row & 0xff);
535 }
536 
537 static void
538 nand_address_row(device_t self, size_t row)
539 {
540 	struct nand_softc *sc = device_private(self);
541 	struct nand_chip *chip = &sc->sc_chip;
542 	off_t i;
543 
544 	/* XXX TODO */
545 	row >>= chip->nc_page_shift;
546 
547 	/* Write the row (page) address */
548 	for (i = 0; i < chip->nc_addr_cycles_row; i++, row >>= 8)
549 		nand_address(self, row & 0xff);
550 }
551 
552 static inline uint8_t
553 nand_get_status(device_t self)
554 {
555 	uint8_t status;
556 
557 	nand_command(self, ONFI_READ_STATUS);
558 	nand_busy(self);
559 	nand_read_byte(self, &status);
560 
561 	return status;
562 }
563 
564 static bool
565 nand_check_wp(device_t self)
566 {
567 	if (nand_get_status(self) & 0x80)
568 		return false;
569 	else
570 		return true;
571 }
572 
573 static void
574 nand_prepare_read(device_t self, flash_addr_t row, flash_addr_t column)
575 {
576 	nand_command(self, ONFI_READ);
577 	nand_address_column(self, row, column);
578 	nand_command(self, ONFI_READ_START);
579 
580 	nand_busy(self);
581 }
582 
583 /* read a page with ecc correction */
584 int
585 nand_read_page(device_t self, size_t offset, uint8_t *data)
586 {
587 	struct nand_softc *sc = device_private(self);
588 	struct nand_chip *chip = &sc->sc_chip;
589 	size_t b, bs, e, cs;
590 	uint8_t *ecc;
591 	int result;
592 
593 	nand_prepare_read(self, offset, 0);
594 
595 	bs = chip->nc_ecc->necc_block_size;
596 	cs = chip->nc_ecc->necc_code_size;
597 
598 	/* decide if we access by 8 or 16 bits */
599 	if (chip->nc_flags & NC_BUSWIDTH_16) {
600 		for (b = 0, e = 0; b < chip->nc_page_size; b += bs, e += cs) {
601 			nand_ecc_prepare(self, NAND_ECC_READ);
602 			nand_read_buf_word(self, data + b, bs);
603 			nand_ecc_compute(self, data + b,
604 			    chip->nc_ecc_cache + e);
605 		}
606 	} else {
607 		for (b = 0, e = 0; b < chip->nc_page_size; b += bs, e += cs) {
608 			nand_ecc_prepare(self, NAND_ECC_READ);
609 			nand_read_buf_byte(self, data + b, bs);
610 			nand_ecc_compute(self, data + b,
611 			    chip->nc_ecc_cache + e);
612 		}
613 	}
614 
615 	/* for debugging new drivers */
616 #if 0
617 	nand_dump_data("page", data, chip->nc_page_size);
618 #endif
619 
620 	nand_read_oob(self, offset, chip->nc_oob_cache);
621 	ecc = chip->nc_oob_cache + chip->nc_ecc->necc_offset;
622 
623 	/* useful for debugging new ecc drivers */
624 #if 0
625 	printf("dumping ecc %d\n--------------\n", chip->nc_ecc->necc_steps);
626 	for (e = 0; e < chip->nc_ecc->necc_steps; e++) {
627 		printf("0x");
628 		for (b = 0; b < cs; b++) {
629 			printf("%.2hhx", ecc[e+b]);
630 		}
631 		printf(" 0x");
632 		for (b = 0; b < cs; b++) {
633 			printf("%.2hhx", chip->nc_ecc_cache[e+b]);
634 		}
635 		printf("\n");
636 	}
637 	printf("--------------\n");
638 #endif
639 
640 	for (b = 0, e = 0; b < chip->nc_page_size; b += bs, e += cs) {
641 		result = nand_ecc_correct(self, data + b, ecc + e,
642 		    chip->nc_ecc_cache + e);
643 
644 		switch (result) {
645 		case NAND_ECC_OK:
646 			break;
647 		case NAND_ECC_CORRECTED:
648 			aprint_error_dev(self,
649 			    "data corrected with ECC at page offset 0x%jx "
650 			    "block %zu\n", (uintmax_t)offset, b);
651 			break;
652 		case NAND_ECC_TWOBIT:
653 			aprint_error_dev(self,
654 			    "uncorrectable ECC error at page offset 0x%jx "
655 			    "block %zu\n", (uintmax_t)offset, b);
656 			return EIO;
657 			break;
658 		case NAND_ECC_INVALID:
659 			aprint_error_dev(self,
660 			    "invalid ECC in oob at page offset 0x%jx "
661 			    "block %zu\n", (uintmax_t)offset, b);
662 			return EIO;
663 			break;
664 		default:
665 			panic("invalid ECC correction errno");
666 		}
667 	}
668 
669 	return 0;
670 }
671 
672 static int
673 nand_program_page(device_t self, size_t page, const uint8_t *data)
674 {
675 	struct nand_softc *sc = device_private(self);
676 	struct nand_chip *chip = &sc->sc_chip;
677 	size_t bs, cs, e, b;
678 	uint8_t status;
679 	uint8_t *ecc;
680 
681 	nand_command(self, ONFI_PAGE_PROGRAM);
682 	nand_address_column(self, page, 0);
683 
684 	nand_busy(self);
685 
686 	bs = chip->nc_ecc->necc_block_size;
687 	cs = chip->nc_ecc->necc_code_size;
688 	ecc = chip->nc_oob_cache + chip->nc_ecc->necc_offset;
689 
690 	/* XXX code duplication */
691 	/* decide if we access by 8 or 16 bits */
692 	if (chip->nc_flags & NC_BUSWIDTH_16) {
693 		for (b = 0, e = 0; b < chip->nc_page_size; b += bs, e += cs) {
694 			nand_ecc_prepare(self, NAND_ECC_WRITE);
695 			nand_write_buf_word(self, data + b, bs);
696 			nand_ecc_compute(self, data + b, ecc + e);
697 		}
698 		/* write oob with ecc correction code */
699 		nand_write_buf_word(self, chip->nc_oob_cache,
700 		    chip->nc_spare_size);
701 	} else {
702 		for (b = 0, e = 0; b < chip->nc_page_size; b += bs, e += cs) {
703 			nand_ecc_prepare(self, NAND_ECC_WRITE);
704 			nand_write_buf_byte(self, data + b, bs);
705 			nand_ecc_compute(self, data + b, ecc + e);
706 		}
707 		/* write oob with ecc correction code */
708 		nand_write_buf_byte(self, chip->nc_oob_cache,
709 		    chip->nc_spare_size);
710 	}
711 
712 	nand_command(self, ONFI_PAGE_PROGRAM_START);
713 
714 	nand_busy(self);
715 
716 	/* for debugging ecc */
717 #if 0
718 	printf("dumping ecc %d\n--------------\n", chip->nc_ecc->necc_steps);
719 	for (e = 0; e < chip->nc_ecc->necc_steps; e++) {
720 		printf("0x");
721 		for (b = 0; b < cs; b++) {
722 			printf("%.2hhx", ecc[e+b]);
723 		}
724 		printf("\n");
725 	}
726 	printf("--------------\n");
727 #endif
728 
729 	status = nand_get_status(self);
730 	KASSERT(status & ONFI_STATUS_RDY);
731 	if (status & ONFI_STATUS_FAIL) {
732 		aprint_error_dev(self, "page program failed!\n");
733 		return EIO;
734 	}
735 
736 	return 0;
737 }
738 
739 int
740 nand_read_oob(device_t self, size_t page, void *oob)
741 {
742 	struct nand_softc *sc = device_private(self);
743 	struct nand_chip *chip = &sc->sc_chip;
744 
745 	nand_prepare_read(self, page, chip->nc_page_size);
746 
747 	if (chip->nc_flags & NC_BUSWIDTH_16)
748 		nand_read_buf_word(self, oob, chip->nc_spare_size);
749 	else
750 		nand_read_buf_byte(self, oob, chip->nc_spare_size);
751 
752 	/* for debugging drivers */
753 #if 0
754 	nand_dump_data("oob", oob, chip->nc_spare_size);
755 #endif
756 
757 	return 0;
758 }
759 
760 static int
761 nand_write_oob(device_t self, size_t offset, const void *oob)
762 {
763 	struct nand_softc *sc = device_private(self);
764 	struct nand_chip *chip = &sc->sc_chip;
765 	uint8_t status;
766 
767 	nand_command(self, ONFI_PAGE_PROGRAM);
768 	nand_address_column(self, offset, chip->nc_page_size);
769 	nand_command(self, ONFI_PAGE_PROGRAM_START);
770 
771 	nand_busy(self);
772 
773 	if (chip->nc_flags & NC_BUSWIDTH_16)
774 		nand_write_buf_word(self, oob, chip->nc_spare_size);
775 	else
776 		nand_write_buf_byte(self, oob, chip->nc_spare_size);
777 
778 	status = nand_get_status(self);
779 	KASSERT(status & ONFI_STATUS_RDY);
780 	if (status & ONFI_STATUS_FAIL)
781 		return EIO;
782 	else
783 		return 0;
784 }
785 
786 void
787 nand_markbad(device_t self, size_t offset)
788 {
789 	struct nand_softc *sc = device_private(self);
790 	struct nand_chip *chip = &sc->sc_chip;
791 	flash_addr_t blockoffset, marker;
792 #ifdef NAND_BBT
793 	flash_addr_t block;
794 
795 	block = offset / chip->nc_block_size;
796 
797 	nand_bbt_block_markbad(self, block);
798 #endif
799 	blockoffset = offset & chip->nc_block_mask;
800 	marker = chip->nc_badmarker_offs & ~0x01;
801 
802 	/* check if it is already marked bad */
803 	if (nand_isbad(self, blockoffset))
804 		return;
805 
806 	nand_read_oob(self, blockoffset, chip->nc_oob_cache);
807 
808 	chip->nc_oob_cache[chip->nc_badmarker_offs] = 0x00;
809 	chip->nc_oob_cache[chip->nc_badmarker_offs + 1] = 0x00;
810 
811 	nand_write_oob(self, blockoffset, chip->nc_oob_cache);
812 }
813 
814 bool
815 nand_isfactorybad(device_t self, flash_addr_t offset)
816 {
817 	struct nand_softc *sc = device_private(self);
818 	struct nand_chip *chip = &sc->sc_chip;
819 	flash_addr_t block, first_page, last_page, page;
820 	int i;
821 
822 	/* Check for factory bad blocks first
823 	 * Factory bad blocks are marked in the first or last
824 	 * page of the blocks, see: ONFI 2.2, 3.2.2.
825 	 */
826 	block = offset / chip->nc_block_size;
827 	first_page = block * chip->nc_block_size;
828 	last_page = (block + 1) * chip->nc_block_size
829 	    - chip->nc_page_size;
830 
831 	for (i = 0, page = first_page; i < 2; i++, page = last_page) {
832 		/* address OOB */
833 		nand_prepare_read(self, page, chip->nc_page_size);
834 
835 		if (chip->nc_flags & NC_BUSWIDTH_16) {
836 			uint16_t word;
837 			nand_read_word(self, &word);
838 			if (word == 0x0000)
839 				return true;
840 		} else {
841 			uint8_t byte;
842 			nand_read_byte(self, &byte);
843 			if (byte == 0x00)
844 				return true;
845 		}
846 	}
847 
848 	return false;
849 }
850 
851 bool
852 nand_iswornoutbad(device_t self, flash_addr_t offset)
853 {
854 	struct nand_softc *sc = device_private(self);
855 	struct nand_chip *chip = &sc->sc_chip;
856 	flash_addr_t block;
857 
858 	/* we inspect the first page of the block */
859 	block = offset & chip->nc_block_mask;
860 
861 	/* Linux/u-boot compatible badblock handling */
862 	if (chip->nc_flags & NC_BUSWIDTH_16) {
863 		uint16_t word, mark;
864 
865 		nand_prepare_read(self, block,
866 		    chip->nc_page_size + (chip->nc_badmarker_offs & 0xfe));
867 
868 		nand_read_word(self, &word);
869 		mark = htole16(word);
870 		if (chip->nc_badmarker_offs & 0x01)
871 			mark >>= 8;
872 		if ((mark & 0xff) != 0xff)
873 			return true;
874 	} else {
875 		uint8_t byte;
876 
877 		nand_prepare_read(self, block,
878 		    chip->nc_page_size + chip->nc_badmarker_offs);
879 
880 		nand_read_byte(self, &byte);
881 		if (byte != 0xff)
882 			return true;
883 	}
884 
885 	return false;
886 }
887 
888 bool
889 nand_isbad(device_t self, flash_addr_t offset)
890 {
891 #ifdef NAND_BBT
892 	struct nand_softc *sc = device_private(self);
893 	struct nand_chip *chip = &sc->sc_chip;
894 	flash_addr_t block;
895 
896 	block = offset / chip->nc_block_size;
897 
898 	return nand_bbt_block_isbad(self, block);
899 #else
900 	/* ONFI host requirement */
901 	if (nand_isfactorybad(self, offset))
902 		return true;
903 
904 	/* Look for Linux/U-Boot compatible bad marker */
905 	if (nand_iswornoutbad(self, offset))
906 		return true;
907 
908 	return false;
909 #endif
910 }
911 
912 int
913 nand_erase_block(device_t self, size_t offset)
914 {
915 	uint8_t status;
916 
917 	/* xxx calculate first page of block for address? */
918 
919 	nand_command(self, ONFI_BLOCK_ERASE);
920 	nand_address_row(self, offset);
921 	nand_command(self, ONFI_BLOCK_ERASE_START);
922 
923 	nand_busy(self);
924 
925 	status = nand_get_status(self);
926 	KASSERT(status & ONFI_STATUS_RDY);
927 	if (status & ONFI_STATUS_FAIL) {
928 		aprint_error_dev(self, "block erase failed!\n");
929 		nand_markbad(self, offset);
930 		return EIO;
931 	} else {
932 		return 0;
933 	}
934 }
935 
936 /* default functions for driver development */
937 
938 /* default ECC using hamming code of 256 byte chunks */
939 int
940 nand_default_ecc_compute(device_t self, const uint8_t *data, uint8_t *code)
941 {
942 	hamming_compute_256(data, code);
943 
944 	return 0;
945 }
946 
947 int
948 nand_default_ecc_correct(device_t self, uint8_t *data, const uint8_t *origcode,
949 	const uint8_t *compcode)
950 {
951 	return hamming_correct_256(data, origcode, compcode);
952 }
953 
954 void
955 nand_default_select(device_t self, bool enable)
956 {
957 	/* do nothing */
958 	return;
959 }
960 
961 /* implementation of the block device API */
962 
963 /*
964  * handle (page) unaligned write to nand
965  */
966 static int
967 nand_flash_write_unaligned(device_t self, off_t offset, size_t len,
968     size_t *retlen, const uint8_t *buf)
969 {
970 	struct nand_softc *sc = device_private(self);
971 	struct nand_chip *chip = &sc->sc_chip;
972 	flash_addr_t first, last, firstoff;
973 	const uint8_t *bufp;
974 	flash_addr_t addr;
975 	size_t left, count;
976 	int error, i;
977 
978 	first = offset & chip->nc_page_mask;
979 	firstoff = offset & ~chip->nc_page_mask;
980 	/* XXX check if this should be len - 1 */
981 	last = (offset + len) & chip->nc_page_mask;
982 	count = last - first + 1;
983 
984 	addr = first;
985 	*retlen = 0;
986 
987 	if (count == 1) {
988 		if (nand_isbad(self, addr)) {
989 			aprint_error_dev(self,
990 			    "nand_flash_write_unaligned: "
991 			    "bad block encountered\n");
992 			return EIO;
993 		}
994 
995 		error = nand_read_page(self, addr, chip->nc_page_cache);
996 		if (error)
997 			return error;
998 
999 		memcpy(chip->nc_page_cache + firstoff, buf, len);
1000 
1001 		error = nand_program_page(self, addr, chip->nc_page_cache);
1002 		if (error)
1003 			return error;
1004 
1005 		*retlen = len;
1006 		return 0;
1007 	}
1008 
1009 	bufp = buf;
1010 	left = len;
1011 
1012 	for (i = 0; i < count && left != 0; i++) {
1013 		if (nand_isbad(self, addr)) {
1014 			aprint_error_dev(self,
1015 			    "nand_flash_write_unaligned: "
1016 			    "bad block encountered\n");
1017 			return EIO;
1018 		}
1019 
1020 		if (i == 0) {
1021 			error = nand_read_page(self,
1022 			    addr, chip->nc_page_cache);
1023 			if (error)
1024 				return error;
1025 
1026 			memcpy(chip->nc_page_cache + firstoff,
1027 			    bufp, chip->nc_page_size - firstoff);
1028 
1029 			printf("program page: %s: %d\n", __FILE__, __LINE__);
1030 			error = nand_program_page(self,
1031 			    addr, chip->nc_page_cache);
1032 			if (error)
1033 				return error;
1034 
1035 			bufp += chip->nc_page_size - firstoff;
1036 			left -= chip->nc_page_size - firstoff;
1037 			*retlen += chip->nc_page_size - firstoff;
1038 
1039 		} else if (i == count - 1) {
1040 			error = nand_read_page(self,
1041 			    addr, chip->nc_page_cache);
1042 			if (error)
1043 				return error;
1044 
1045 			memcpy(chip->nc_page_cache, bufp, left);
1046 
1047 			error = nand_program_page(self,
1048 			    addr, chip->nc_page_cache);
1049 			if (error)
1050 				return error;
1051 
1052 			*retlen += left;
1053 			KASSERT(left < chip->nc_page_size);
1054 
1055 		} else {
1056 			/* XXX debug */
1057 			if (left > chip->nc_page_size) {
1058 				printf("left: %zu, i: %d, count: %zu\n",
1059 				    (size_t )left, i, count);
1060 			}
1061 			KASSERT(left > chip->nc_page_size);
1062 
1063 			error = nand_program_page(self, addr, bufp);
1064 			if (error)
1065 				return error;
1066 
1067 			bufp += chip->nc_page_size;
1068 			left -= chip->nc_page_size;
1069 			*retlen += chip->nc_page_size;
1070 		}
1071 
1072 		addr += chip->nc_page_size;
1073 	}
1074 
1075 	KASSERT(*retlen == len);
1076 
1077 	return 0;
1078 }
1079 
1080 int
1081 nand_flash_write(device_t self, off_t offset, size_t len, size_t *retlen,
1082     const uint8_t *buf)
1083 {
1084 	struct nand_softc *sc = device_private(self);
1085 	struct nand_chip *chip = &sc->sc_chip;
1086 	const uint8_t *bufp;
1087 	size_t pages, page;
1088 	daddr_t addr;
1089 	int error = 0;
1090 
1091 	if ((offset + len) > chip->nc_size) {
1092 		DPRINTF(("nand_flash_write: write (off: 0x%jx, len: %ju),"
1093 			" is over device size (0x%jx)\n",
1094 			(uintmax_t)offset, (uintmax_t)len,
1095 			(uintmax_t)chip->nc_size));
1096 		return EINVAL;
1097 	}
1098 
1099 	if (len % chip->nc_page_size != 0 ||
1100 	    offset % chip->nc_page_size != 0) {
1101 		return nand_flash_write_unaligned(self,
1102 		    offset, len, retlen, buf);
1103 	}
1104 
1105 	pages = len / chip->nc_page_size;
1106 	KASSERT(pages != 0);
1107 	*retlen = 0;
1108 
1109 	addr = offset;
1110 	bufp = buf;
1111 
1112 	mutex_enter(&sc->sc_device_lock);
1113 	for (page = 0; page < pages; page++) {
1114 		/* do we need this check here? */
1115 		if (nand_isbad(self, addr)) {
1116 			aprint_error_dev(self,
1117 			    "nand_flash_write: bad block encountered\n");
1118 
1119 			error = EIO;
1120 			goto out;
1121 		}
1122 
1123 		error = nand_program_page(self, addr, bufp);
1124 		if (error)
1125 			goto out;
1126 
1127 		addr += chip->nc_page_size;
1128 		bufp += chip->nc_page_size;
1129 		*retlen += chip->nc_page_size;
1130 	}
1131 out:
1132 	mutex_exit(&sc->sc_device_lock);
1133 	DPRINTF(("page programming: retlen: %zu, len: %zu\n", *retlen, len));
1134 
1135 	return error;
1136 }
1137 
1138 /*
1139  * handle (page) unaligned read from nand
1140  */
1141 static int
1142 nand_flash_read_unaligned(device_t self, size_t offset,
1143     size_t len, size_t *retlen, uint8_t *buf)
1144 {
1145 	struct nand_softc *sc = device_private(self);
1146 	struct nand_chip *chip = &sc->sc_chip;
1147 	daddr_t first, last, count, firstoff;
1148 	uint8_t *bufp;
1149 	daddr_t addr;
1150 	size_t left;
1151 	int error = 0, i;
1152 
1153 	first = offset & chip->nc_page_mask;
1154 	firstoff = offset & ~chip->nc_page_mask;
1155 	last = (offset + len) & chip->nc_page_mask;
1156 	count = (last - first) / chip->nc_page_size + 1;
1157 
1158 	addr = first;
1159 	bufp = buf;
1160 	left = len;
1161 	*retlen = 0;
1162 
1163 	mutex_enter(&sc->sc_device_lock);
1164 	if (count == 1) {
1165 		error = nand_read_page(self, addr, chip->nc_page_cache);
1166 		if (error)
1167 			goto out;
1168 
1169 		memcpy(bufp, chip->nc_page_cache + firstoff, len);
1170 
1171 		*retlen = len;
1172 		goto out;
1173 	}
1174 
1175 	for (i = 0; i < count && left != 0; i++) {
1176 		error = nand_read_page(self, addr, chip->nc_page_cache);
1177 		if (error)
1178 			goto out;
1179 
1180 		if (i == 0) {
1181 			memcpy(bufp, chip->nc_page_cache + firstoff,
1182 			    chip->nc_page_size - firstoff);
1183 
1184 			bufp += chip->nc_page_size - firstoff;
1185 			left -= chip->nc_page_size - firstoff;
1186 			*retlen += chip->nc_page_size - firstoff;
1187 
1188 		} else if (i == count - 1) {
1189 			memcpy(bufp, chip->nc_page_cache, left);
1190 			*retlen += left;
1191 			KASSERT(left < chip->nc_page_size);
1192 
1193 		} else {
1194 			memcpy(bufp, chip->nc_page_cache, chip->nc_page_size);
1195 
1196 			bufp += chip->nc_page_size;
1197 			left -= chip->nc_page_size;
1198 			*retlen += chip->nc_page_size;
1199 		}
1200 
1201 		addr += chip->nc_page_size;
1202 	}
1203 
1204 	KASSERT(*retlen == len);
1205 
1206 out:
1207 	mutex_exit(&sc->sc_device_lock);
1208 
1209 	return error;
1210 }
1211 
1212 int
1213 nand_flash_read(device_t self, off_t offset, size_t len, size_t *retlen,
1214     uint8_t *buf)
1215 {
1216 	struct nand_softc *sc = device_private(self);
1217 	struct nand_chip *chip = &sc->sc_chip;
1218 	uint8_t *bufp;
1219 	size_t addr;
1220 	size_t i, pages;
1221 	int error = 0;
1222 
1223 	*retlen = 0;
1224 
1225 	DPRINTF(("nand_flash_read: off: 0x%jx, len: %zu\n",
1226 		(uintmax_t)offset, len));
1227 
1228 	if (__predict_false((offset + len) > chip->nc_size)) {
1229 		DPRINTF(("nand_flash_read: read (off: 0x%jx, len: %zu),"
1230 			" is over device size (%ju)\n", (uintmax_t)offset,
1231 			len, (uintmax_t)chip->nc_size));
1232 		return EINVAL;
1233 	}
1234 
1235 	/* Handle unaligned access, shouldnt be needed when using the
1236 	 * block device, as strategy handles it, so only low level
1237 	 * accesses will use this path
1238 	 */
1239 	/* XXX^2 */
1240 #if 0
1241 	if (len < chip->nc_page_size)
1242 		panic("TODO page size is larger than read size");
1243 #endif
1244 
1245 
1246 	if (len % chip->nc_page_size != 0 ||
1247 	    offset % chip->nc_page_size != 0) {
1248 		return nand_flash_read_unaligned(self,
1249 		    offset, len, retlen, buf);
1250 	}
1251 
1252 	bufp = buf;
1253 	addr = offset;
1254 	pages = len / chip->nc_page_size;
1255 
1256 	mutex_enter(&sc->sc_device_lock);
1257 	for (i = 0; i < pages; i++) {
1258 		/* XXX do we need this check here? */
1259 		if (nand_isbad(self, addr)) {
1260 			aprint_error_dev(self, "bad block encountered\n");
1261 			error = EIO;
1262 			goto out;
1263 		}
1264 		error = nand_read_page(self, addr, bufp);
1265 		if (error)
1266 			goto out;
1267 
1268 		bufp += chip->nc_page_size;
1269 		addr += chip->nc_page_size;
1270 		*retlen += chip->nc_page_size;
1271 	}
1272 
1273 out:
1274 	mutex_exit(&sc->sc_device_lock);
1275 
1276 	return error;
1277 }
1278 
1279 int
1280 nand_flash_isbad(device_t self, uint64_t ofs)
1281 {
1282 	struct nand_softc *sc = device_private(self);
1283 	struct nand_chip *chip = &sc->sc_chip;
1284 	bool result;
1285 
1286 	if (ofs > chip->nc_size) {
1287 		DPRINTF(("nand_flash_isbad: offset 0x%jx is larger than"
1288 			" device size (0x%jx)\n", (uintmax_t)ofs,
1289 			(uintmax_t)chip->nc_size));
1290 		return EINVAL;
1291 	}
1292 
1293 	if (ofs % chip->nc_block_size != 0) {
1294 		panic("offset (0x%jx) is not the multiple of block size (%ju)",
1295 		    (uintmax_t)ofs, (uintmax_t)chip->nc_block_size);
1296 	}
1297 
1298 	mutex_enter(&sc->sc_device_lock);
1299 	result = nand_isbad(self, ofs);
1300 	mutex_exit(&sc->sc_device_lock);
1301 
1302 	if (result)
1303 		return 1;
1304 	else
1305 		return 0;
1306 }
1307 
1308 int
1309 nand_flash_markbad(device_t self, uint64_t ofs)
1310 {
1311 	struct nand_softc *sc = device_private(self);
1312 	struct nand_chip *chip = &sc->sc_chip;
1313 
1314 	if (ofs > chip->nc_size) {
1315 		DPRINTF(("nand_flash_markbad: offset 0x%jx is larger than"
1316 			" device size (0x%jx)\n", ofs,
1317 			(uintmax_t)chip->nc_size));
1318 		return EINVAL;
1319 	}
1320 
1321 	if (ofs % chip->nc_block_size != 0) {
1322 		panic("offset (%ju) is not the multiple of block size (%ju)",
1323 		    (uintmax_t)ofs, (uintmax_t)chip->nc_block_size);
1324 	}
1325 
1326 	mutex_enter(&sc->sc_device_lock);
1327 	nand_markbad(self, ofs);
1328 	mutex_exit(&sc->sc_device_lock);
1329 
1330 	return 0;
1331 }
1332 
1333 int
1334 nand_flash_erase(device_t self,
1335     struct flash_erase_instruction *ei)
1336 {
1337 	struct nand_softc *sc = device_private(self);
1338 	struct nand_chip *chip = &sc->sc_chip;
1339 	flash_addr_t addr;
1340 	int error;
1341 
1342 	if (ei->ei_addr < 0 || ei->ei_len < chip->nc_block_size)
1343 		return EINVAL;
1344 
1345 	if (ei->ei_addr + ei->ei_len > chip->nc_size) {
1346 		DPRINTF(("nand_flash_erase: erase address is over the end"
1347 			" of the device\n"));
1348 		return EINVAL;
1349 	}
1350 
1351 	if (ei->ei_addr % chip->nc_block_size != 0) {
1352 		aprint_error_dev(self,
1353 		    "nand_flash_erase: ei_addr (%ju) is not"
1354 		    "the multiple of block size (%ju)",
1355 		    (uintmax_t)ei->ei_addr,
1356 		    (uintmax_t)chip->nc_block_size);
1357 		return EINVAL;
1358 	}
1359 
1360 	if (ei->ei_len % chip->nc_block_size != 0) {
1361 		aprint_error_dev(self,
1362 		    "nand_flash_erase: ei_len (%ju) is not"
1363 		    "the multiple of block size (%ju)",
1364 		    (uintmax_t)ei->ei_addr,
1365 		    (uintmax_t)chip->nc_block_size);
1366 		return EINVAL;
1367 	}
1368 
1369 	mutex_enter(&sc->sc_device_lock);
1370 	addr = ei->ei_addr;
1371 	while (addr < ei->ei_addr + ei->ei_len) {
1372 		if (nand_isbad(self, addr)) {
1373 			mutex_exit(&sc->sc_device_lock);
1374 			aprint_error_dev(self, "bad block encountered\n");
1375 			ei->ei_state = FLASH_ERASE_FAILED;
1376 			return EIO;
1377 		}
1378 
1379 		error = nand_erase_block(self, addr);
1380 		if (error) {
1381 			mutex_exit(&sc->sc_device_lock);
1382 			ei->ei_state = FLASH_ERASE_FAILED;
1383 			return error;
1384 		}
1385 
1386 		addr += chip->nc_block_size;
1387 	}
1388 	mutex_exit(&sc->sc_device_lock);
1389 
1390 	ei->ei_state = FLASH_ERASE_DONE;
1391 	if (ei->ei_callback != NULL)
1392 		ei->ei_callback(ei);
1393 
1394 	return 0;
1395 }
1396 
1397 static int
1398 sysctl_nand_verify(SYSCTLFN_ARGS)
1399 {
1400 	int error, t;
1401 	struct sysctlnode node;
1402 
1403 	node = *rnode;
1404 	t = *(int *)rnode->sysctl_data;
1405 	node.sysctl_data = &t;
1406 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
1407 	if (error || newp == NULL)
1408 		return error;
1409 
1410 	if (node.sysctl_num == nand_cachesync_nodenum) {
1411 		if (t <= 0 || t > 60)
1412 			return EINVAL;
1413 	} else {
1414 		return EINVAL;
1415 	}
1416 
1417 	*(int *)rnode->sysctl_data = t;
1418 
1419 	return 0;
1420 }
1421 
1422 SYSCTL_SETUP(sysctl_nand, "sysctl nand subtree setup")
1423 {
1424 	int rc, nand_root_num;
1425 	const struct sysctlnode *node;
1426 
1427 	if ((rc = sysctl_createv(clog, 0, NULL, NULL,
1428 	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", NULL,
1429 	    NULL, 0, NULL, 0, CTL_HW, CTL_EOL)) != 0) {
1430 		goto error;
1431 	}
1432 
1433 	if ((rc = sysctl_createv(clog, 0, NULL, &node,
1434 	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "nand",
1435 	    SYSCTL_DESCR("NAND driver controls"),
1436 	    NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0) {
1437 		goto error;
1438 	}
1439 
1440 	nand_root_num = node->sysctl_num;
1441 
1442 	if ((rc = sysctl_createv(clog, 0, NULL, &node,
1443 	    CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1444 	    CTLTYPE_INT, "cache_sync_timeout",
1445 	    SYSCTL_DESCR("NAND write cache sync timeout in seconds"),
1446 	    sysctl_nand_verify, 0, &nand_cachesync_timeout,
1447 	    0, CTL_HW, nand_root_num, CTL_CREATE,
1448 	    CTL_EOL)) != 0) {
1449 		goto error;
1450 	}
1451 
1452 	nand_cachesync_nodenum = node->sysctl_num;
1453 
1454 	return;
1455 
1456 error:
1457 	aprint_error("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
1458 }
1459 
1460 MODULE(MODULE_CLASS_DRIVER, nand, "flash");
1461 
1462 #ifdef _MODULE
1463 #include "ioconf.c"
1464 #endif
1465 
1466 static int
1467 nand_modcmd(modcmd_t cmd, void *opaque)
1468 {
1469 	switch (cmd) {
1470 	case MODULE_CMD_INIT:
1471 #ifdef _MODULE
1472 		return config_init_component(cfdriver_ioconf_nand,
1473 		    cfattach_ioconf_nand, cfdata_ioconf_nand);
1474 #else
1475 		return 0;
1476 #endif
1477 	case MODULE_CMD_FINI:
1478 #ifdef _MODULE
1479 		return config_fini_component(cfdriver_ioconf_nand,
1480 		    cfattach_ioconf_nand, cfdata_ioconf_nand);
1481 #else
1482 		return 0;
1483 #endif
1484 	default:
1485 		return ENOTTY;
1486 	}
1487 }
1488