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