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