1/*- 2 * Copyright (C) 2009-2012 Semihalf 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD$"); 29 30#include <sys/param.h> 31#include <sys/systm.h> 32#include <sys/kernel.h> 33#include <sys/socket.h> 34#include <sys/malloc.h> 35#include <sys/module.h> 36#include <sys/bus.h> 37#include <sys/lock.h> 38#include <sys/mutex.h> 39#include <sys/callout.h> 40#include <sys/sysctl.h> 41 42#include <dev/nand/nand.h> 43#include <dev/nand/nandbus.h> 44#include <dev/nand/nand_ecc_pos.h> 45#include "nfc_if.h" 46#include "nand_if.h" 47#include "nandbus_if.h" 48#include <machine/stdarg.h> 49 50#define NAND_RESET_DELAY 1000 /* tRST */ 51#define NAND_ERASE_DELAY 3000 /* tBERS */ 52#define NAND_PROG_DELAY 700 /* tPROG */ 53#define NAND_READ_DELAY 50 /* tR */ 54 55#define BIT0(x) ((x) & 0x1) 56#define BIT1(x) (BIT0(x >> 1)) 57#define BIT2(x) (BIT0(x >> 2)) 58#define BIT3(x) (BIT0(x >> 3)) 59#define BIT4(x) (BIT0(x >> 4)) 60#define BIT5(x) (BIT0(x >> 5)) 61#define BIT6(x) (BIT0(x >> 6)) 62#define BIT7(x) (BIT0(x >> 7)) 63 64#define SOFTECC_SIZE 256 65#define SOFTECC_BYTES 3 66 67int nand_debug_flag = 0; 68SYSCTL_INT(_debug, OID_AUTO, nand_debug, CTLFLAG_RW, &nand_debug_flag, 0, 69 "NAND subsystem debug flag"); 70 71static void 72nand_tunable_init(void *arg) 73{ 74 75 TUNABLE_INT_FETCH("debug.nand", &nand_debug_flag); 76} 77 78SYSINIT(nand_tunables, SI_SUB_VFS, SI_ORDER_ANY, nand_tunable_init, NULL); 79 80MALLOC_DEFINE(M_NAND, "NAND", "NAND dynamic data"); 81 82static void calculate_ecc(const uint8_t *, uint8_t *); 83static int correct_ecc(uint8_t *, uint8_t *, uint8_t *); 84 85void 86nand_debug(int level, const char *fmt, ...) 87{ 88 va_list ap; 89 90 if (!(nand_debug_flag & level)) 91 return; 92 va_start(ap, fmt); 93 vprintf(fmt, ap); 94 va_end(ap); 95 printf("\n"); 96} 97 98void 99nand_init(struct nand_softc *nand, device_t dev, int ecc_mode, 100 int ecc_bytes, int ecc_size, uint16_t *eccposition, char *cdev_name) 101{ 102 103 nand->ecc.eccmode = ecc_mode; 104 nand->chip_cdev_name = cdev_name; 105 106 if (ecc_mode == NAND_ECC_SOFT) { 107 nand->ecc.eccbytes = SOFTECC_BYTES; 108 nand->ecc.eccsize = SOFTECC_SIZE; 109 } else if (ecc_mode != NAND_ECC_NONE) { 110 nand->ecc.eccbytes = ecc_bytes; 111 nand->ecc.eccsize = ecc_size; 112 if (eccposition) 113 nand->ecc.eccpositions = eccposition; 114 } 115} 116 117void 118nand_onfi_set_params(struct nand_chip *chip, struct onfi_params *params) 119{ 120 struct chip_geom *cg; 121 122 cg = &chip->chip_geom; 123 124 init_chip_geom(cg, params->luns, params->blocks_per_lun, 125 params->pages_per_block, params->bytes_per_page, 126 params->spare_bytes_per_page); 127 chip->t_bers = params->t_bers; 128 chip->t_prog = params->t_prog; 129 chip->t_r = params->t_r; 130 chip->t_ccs = params->t_ccs; 131 132 if (params->features & ONFI_FEAT_16BIT) 133 chip->flags |= NAND_16_BIT; 134} 135 136void 137nand_set_params(struct nand_chip *chip, struct nand_params *params) 138{ 139 struct chip_geom *cg; 140 uint32_t blocks_per_chip; 141 142 cg = &chip->chip_geom; 143 blocks_per_chip = (params->chip_size << 20) / 144 (params->page_size * params->pages_per_block); 145 146 init_chip_geom(cg, 1, blocks_per_chip, 147 params->pages_per_block, params->page_size, 148 params->oob_size); 149 150 chip->t_bers = NAND_ERASE_DELAY; 151 chip->t_prog = NAND_PROG_DELAY; 152 chip->t_r = NAND_READ_DELAY; 153 chip->t_ccs = 0; 154 155 if (params->flags & NAND_16_BIT) 156 chip->flags |= NAND_16_BIT; 157} 158 159int 160nand_init_stat(struct nand_chip *chip) 161{ 162 struct block_stat *blk_stat; 163 struct page_stat *pg_stat; 164 struct chip_geom *cg; 165 uint32_t blks, pgs; 166 167 cg = &chip->chip_geom; 168 blks = cg->blks_per_lun * cg->luns; 169 blk_stat = malloc(sizeof(struct block_stat) * blks, M_NAND, 170 M_WAITOK | M_ZERO); 171 if (!blk_stat) 172 return (ENOMEM); 173 174 pgs = blks * cg->pgs_per_blk; 175 pg_stat = malloc(sizeof(struct page_stat) * pgs, M_NAND, 176 M_WAITOK | M_ZERO); 177 if (!pg_stat) { 178 free(blk_stat, M_NAND); 179 return (ENOMEM); 180 } 181 182 chip->blk_stat = blk_stat; 183 chip->pg_stat = pg_stat; 184 185 return (0); 186} 187 188void 189nand_destroy_stat(struct nand_chip *chip) 190{ 191 192 free(chip->pg_stat, M_NAND); 193 free(chip->blk_stat, M_NAND); 194} 195 196int 197init_chip_geom(struct chip_geom *cg, uint32_t luns, uint32_t blks_per_lun, 198 uint32_t pgs_per_blk, uint32_t pg_size, uint32_t oob_size) 199{ 200 int shift; 201 202 if (!cg) 203 return (-1); 204 205 cg->luns = luns; 206 cg->blks_per_lun = blks_per_lun; 207 cg->blks_per_chip = blks_per_lun * luns; 208 cg->pgs_per_blk = pgs_per_blk; 209 210 cg->page_size = pg_size; 211 cg->oob_size = oob_size; 212 cg->block_size = cg->page_size * cg->pgs_per_blk; 213 cg->chip_size = cg->block_size * cg->blks_per_chip; 214 215 shift = fls(cg->pgs_per_blk - 1); 216 cg->pg_mask = (1 << shift) - 1; 217 cg->blk_shift = shift; 218 219 if (cg->blks_per_lun > 0) { 220 shift = fls(cg->blks_per_lun - 1); 221 cg->blk_mask = ((1 << shift) - 1) << cg->blk_shift; 222 } else { 223 shift = 0; 224 cg->blk_mask = 0; 225 } 226 227 cg->lun_shift = shift + cg->blk_shift; 228 shift = fls(cg->luns - 1); 229 cg->lun_mask = ((1 << shift) - 1) << cg->lun_shift; 230 231 nand_debug(NDBG_NAND, "Masks: lun 0x%x blk 0x%x page 0x%x\n" 232 "Shifts: lun %d blk %d", 233 cg->lun_mask, cg->blk_mask, cg->pg_mask, 234 cg->lun_shift, cg->blk_shift); 235 236 return (0); 237} 238 239int 240nand_row_to_blkpg(struct chip_geom *cg, uint32_t row, uint32_t *lun, 241 uint32_t *blk, uint32_t *pg) 242{ 243 244 if (!cg || !lun || !blk || !pg) 245 return (-1); 246 247 if (row & ~(cg->lun_mask | cg->blk_mask | cg->pg_mask)) { 248 nand_debug(NDBG_NAND,"Address out of bounds\n"); 249 return (-1); 250 } 251 252 *lun = (row & cg->lun_mask) >> cg->lun_shift; 253 *blk = (row & cg->blk_mask) >> cg->blk_shift; 254 *pg = (row & cg->pg_mask); 255 256 nand_debug(NDBG_NAND,"address %x-%x-%x\n", *lun, *blk, *pg); 257 258 return (0); 259} 260 261int page_to_row(struct chip_geom *cg, uint32_t page, uint32_t *row) 262{ 263 uint32_t lun, block, pg_in_blk; 264 265 if (!cg || !row) 266 return (-1); 267 268 block = page / cg->pgs_per_blk; 269 pg_in_blk = page % cg->pgs_per_blk; 270 271 lun = block / cg->blks_per_lun; 272 block = block % cg->blks_per_lun; 273 274 *row = (lun << cg->lun_shift) & cg->lun_mask; 275 *row |= ((block << cg->blk_shift) & cg->blk_mask); 276 *row |= (pg_in_blk & cg->pg_mask); 277 278 return (0); 279} 280 281int 282nand_check_page_boundary(struct nand_chip *chip, uint32_t page) 283{ 284 struct chip_geom* cg; 285 286 cg = &chip->chip_geom; 287 if (page >= (cg->pgs_per_blk * cg->blks_per_lun * cg->luns)) { 288 nand_debug(NDBG_GEN,"%s: page number too big %#x\n", 289 __func__, page); 290 return (1); 291 } 292 293 return (0); 294} 295 296void 297nand_get_chip_param(struct nand_chip *chip, struct chip_param_io *param) 298{ 299 struct chip_geom *cg; 300 301 cg = &chip->chip_geom; 302 param->page_size = cg->page_size; 303 param->oob_size = cg->oob_size; 304 305 param->blocks = cg->blks_per_lun * cg->luns; 306 param->pages_per_block = cg->pgs_per_blk; 307} 308 309static uint16_t * 310default_software_ecc_positions(struct nand_chip *chip) 311{ 312 struct nand_ecc_data *eccd; 313 314 eccd = &chip->nand->ecc; 315 316 if (eccd->eccpositions) 317 return (eccd->eccpositions); 318 319 switch (chip->chip_geom.oob_size) { 320 case 16: 321 return ((uint16_t *)&default_software_ecc_positions_16); 322 case 64: 323 return ((uint16_t *)&default_software_ecc_positions_64); 324 case 128: 325 return ((uint16_t *)&default_software_ecc_positions_128); 326 default: 327 return (NULL); /* No ecc bytes positions defs available */ 328 } 329 330 return (NULL); 331} 332 333static void 334calculate_ecc(const uint8_t *buf, uint8_t *ecc) 335{ 336 uint8_t p8, byte; 337 int i; 338 339 memset(ecc, 0, 3); 340 341 for (i = 0; i < 256; i++) { 342 byte = buf[i]; 343 ecc[0] ^= (BIT0(byte) ^ BIT2(byte) ^ BIT4(byte) ^ 344 BIT6(byte)) << 2; 345 ecc[0] ^= (BIT1(byte) ^ BIT3(byte) ^ BIT5(byte) ^ 346 BIT7(byte)) << 3; 347 ecc[0] ^= (BIT0(byte) ^ BIT1(byte) ^ BIT4(byte) ^ 348 BIT5(byte)) << 4; 349 ecc[0] ^= (BIT2(byte) ^ BIT3(byte) ^ BIT6(byte) ^ 350 BIT7(byte)) << 5; 351 ecc[0] ^= (BIT0(byte) ^ BIT1(byte) ^ BIT2(byte) ^ 352 BIT3(byte)) << 6; 353 ecc[0] ^= (BIT4(byte) ^ BIT5(byte) ^ BIT6(byte) ^ 354 BIT7(byte)) << 7; 355 356 p8 = BIT0(byte) ^ BIT1(byte) ^ BIT2(byte) ^ 357 BIT3(byte) ^ BIT4(byte) ^ BIT5(byte) ^ BIT6(byte) ^ 358 BIT7(byte); 359 360 if (p8) { 361 ecc[2] ^= (0x1 << BIT0(i)); 362 ecc[2] ^= (0x4 << BIT1(i)); 363 ecc[2] ^= (0x10 << BIT2(i)); 364 ecc[2] ^= (0x40 << BIT3(i)); 365 366 ecc[1] ^= (0x1 << BIT4(i)); 367 ecc[1] ^= (0x4 << BIT5(i)); 368 ecc[1] ^= (0x10 << BIT6(i)); 369 ecc[1] ^= (0x40 << BIT7(i)); 370 } 371 } 372 ecc[0] = ~ecc[0]; 373 ecc[1] = ~ecc[1]; 374 ecc[2] = ~ecc[2]; 375 ecc[0] |= 3; 376} 377 378static int 379correct_ecc(uint8_t *buf, uint8_t *calc_ecc, uint8_t *read_ecc) 380{ 381 uint8_t ecc0, ecc1, ecc2, onesnum, bit, byte; 382 uint16_t addr = 0; 383 384 ecc0 = calc_ecc[0] ^ read_ecc[0]; 385 ecc1 = calc_ecc[1] ^ read_ecc[1]; 386 ecc2 = calc_ecc[2] ^ read_ecc[2]; 387 388 if (!ecc0 && !ecc1 && !ecc2) 389 return (ECC_OK); 390 391 addr = BIT3(ecc0) | (BIT5(ecc0) << 1) | (BIT7(ecc0) << 2); 392 addr |= (BIT1(ecc2) << 3) | (BIT3(ecc2) << 4) | 393 (BIT5(ecc2) << 5) | (BIT7(ecc2) << 6); 394 addr |= (BIT1(ecc1) << 7) | (BIT3(ecc1) << 8) | 395 (BIT5(ecc1) << 9) | (BIT7(ecc1) << 10); 396 397 onesnum = 0; 398 while (ecc0 || ecc1 || ecc2) { 399 if (ecc0 & 1) 400 onesnum++; 401 if (ecc1 & 1) 402 onesnum++; 403 if (ecc2 & 1) 404 onesnum++; 405 406 ecc0 >>= 1; 407 ecc1 >>= 1; 408 ecc2 >>= 1; 409 } 410 411 if (onesnum == 11) { 412 /* Correctable error */ 413 bit = addr & 7; 414 byte = addr >> 3; 415 buf[byte] ^= (1 << bit); 416 return (ECC_CORRECTABLE); 417 } else if (onesnum == 1) { 418 /* ECC error */ 419 return (ECC_ERROR_ECC); 420 } else { 421 /* Uncorrectable error */ 422 return (ECC_UNCORRECTABLE); 423 } 424 425 return (0); 426} 427 428int 429nand_softecc_get(device_t dev, uint8_t *buf, int pagesize, uint8_t *ecc) 430{ 431 int steps = pagesize / SOFTECC_SIZE; 432 int i = 0, j = 0; 433 434 for (; i < (steps * SOFTECC_BYTES); 435 i += SOFTECC_BYTES, j += SOFTECC_SIZE) { 436 calculate_ecc(&buf[j], &ecc[i]); 437 } 438 439 return (0); 440} 441 442int 443nand_softecc_correct(device_t dev, uint8_t *buf, int pagesize, 444 uint8_t *readecc, uint8_t *calcecc) 445{ 446 int steps = pagesize / SOFTECC_SIZE; 447 int i = 0, j = 0, ret = 0; 448 449 for (i = 0; i < (steps * SOFTECC_BYTES); 450 i += SOFTECC_BYTES, j += SOFTECC_SIZE) { 451 ret += correct_ecc(&buf[j], &calcecc[i], &readecc[i]); 452 if (ret < 0) 453 return (ret); 454 } 455 456 return (ret); 457} 458 459static int 460offset_to_page(struct chip_geom *cg, uint32_t offset) 461{ 462 463 return (offset / cg->page_size); 464} 465 466int 467nand_read_pages(struct nand_chip *chip, uint32_t offset, void *buf, 468 uint32_t len) 469{ 470 struct chip_geom *cg; 471 struct nand_ecc_data *eccd; 472 struct page_stat *pg_stat; 473 device_t nandbus; 474 void *oob = NULL; 475 uint8_t *ptr; 476 uint16_t *eccpos = NULL; 477 uint32_t page, num, steps = 0; 478 int i, retval = 0, needwrite; 479 480 nand_debug(NDBG_NAND,"%p read page %x[%x]", chip, offset, len); 481 cg = &chip->chip_geom; 482 eccd = &chip->nand->ecc; 483 page = offset_to_page(cg, offset); 484 num = len / cg->page_size; 485 486 if (eccd->eccmode != NAND_ECC_NONE) { 487 steps = cg->page_size / eccd->eccsize; 488 eccpos = default_software_ecc_positions(chip); 489 oob = malloc(cg->oob_size, M_NAND, M_WAITOK); 490 } 491 492 nandbus = device_get_parent(chip->dev); 493 NANDBUS_LOCK(nandbus); 494 NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num); 495 496 ptr = (uint8_t *)buf; 497 while (num--) { 498 pg_stat = &(chip->pg_stat[page]); 499 500 if (NAND_READ_PAGE(chip->dev, page, ptr, cg->page_size, 0)) { 501 retval = ENXIO; 502 break; 503 } 504 505 if (eccd->eccmode != NAND_ECC_NONE) { 506 if (NAND_GET_ECC(chip->dev, ptr, eccd->ecccalculated, 507 &needwrite)) { 508 retval = ENXIO; 509 break; 510 } 511 nand_debug(NDBG_ECC,"%s: ECC calculated:", 512 __func__); 513 if (nand_debug_flag & NDBG_ECC) 514 for (i = 0; i < (eccd->eccbytes * steps); i++) 515 printf("%x ", eccd->ecccalculated[i]); 516 517 nand_debug(NDBG_ECC,"\n"); 518 519 if (NAND_READ_OOB(chip->dev, page, oob, cg->oob_size, 520 0)) { 521 retval = ENXIO; 522 break; 523 } 524 for (i = 0; i < (eccd->eccbytes * steps); i++) 525 eccd->eccread[i] = ((uint8_t *)oob)[eccpos[i]]; 526 527 nand_debug(NDBG_ECC,"%s: ECC read:", __func__); 528 if (nand_debug_flag & NDBG_ECC) 529 for (i = 0; i < (eccd->eccbytes * steps); i++) 530 printf("%x ", eccd->eccread[i]); 531 nand_debug(NDBG_ECC,"\n"); 532 533 retval = NAND_CORRECT_ECC(chip->dev, ptr, eccd->eccread, 534 eccd->ecccalculated); 535 536 nand_debug(NDBG_ECC, "NAND_CORRECT_ECC() returned %d", 537 retval); 538 539 if (retval == 0) 540 pg_stat->ecc_stat.ecc_succeded++; 541 else if (retval > 0) { 542 pg_stat->ecc_stat.ecc_corrected += retval; 543 retval = ECC_CORRECTABLE; 544 } else { 545 pg_stat->ecc_stat.ecc_failed++; 546 break; 547 } 548 } 549 550 pg_stat->page_read++; 551 page++; 552 ptr += cg->page_size; 553 } 554 555 NANDBUS_UNLOCK(nandbus); 556 557 if (oob) 558 free(oob, M_NAND); 559 560 return (retval); 561} 562 563int 564nand_read_pages_raw(struct nand_chip *chip, uint32_t offset, void *buf, 565 uint32_t len) 566{ 567 struct chip_geom *cg; 568 device_t nandbus; 569 uint8_t *ptr; 570 uint32_t page, num, end, begin = 0, begin_off; 571 int retval = 0; 572 573 cg = &chip->chip_geom; 574 page = offset_to_page(cg, offset); 575 begin_off = offset - page * cg->page_size; 576 if (begin_off) { 577 begin = cg->page_size - begin_off; 578 len -= begin; 579 } 580 num = len / cg->page_size; 581 end = len % cg->page_size; 582 583 nandbus = device_get_parent(chip->dev); 584 NANDBUS_LOCK(nandbus); 585 NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num); 586 587 ptr = (uint8_t *)buf; 588 if (begin_off) { 589 if (NAND_READ_PAGE(chip->dev, page, ptr, begin, begin_off)) { 590 NANDBUS_UNLOCK(nandbus); 591 return (ENXIO); 592 } 593 594 page++; 595 ptr += begin; 596 } 597 598 while (num--) { 599 if (NAND_READ_PAGE(chip->dev, page, ptr, cg->page_size, 0)) { 600 NANDBUS_UNLOCK(nandbus); 601 return (ENXIO); 602 } 603 604 page++; 605 ptr += cg->page_size; 606 } 607 608 if (end) 609 if (NAND_READ_PAGE(chip->dev, page, ptr, end, 0)) { 610 NANDBUS_UNLOCK(nandbus); 611 return (ENXIO); 612 } 613 614 NANDBUS_UNLOCK(nandbus); 615 616 return (retval); 617} 618 619 620int 621nand_prog_pages(struct nand_chip *chip, uint32_t offset, uint8_t *buf, 622 uint32_t len) 623{ 624 struct chip_geom *cg; 625 struct page_stat *pg_stat; 626 struct nand_ecc_data *eccd; 627 device_t nandbus; 628 uint32_t page, num; 629 uint8_t *oob = NULL; 630 uint16_t *eccpos = NULL; 631 int steps = 0, i, needwrite, err = 0; 632 633 nand_debug(NDBG_NAND,"%p prog page %x[%x]", chip, offset, len); 634 635 eccd = &chip->nand->ecc; 636 cg = &chip->chip_geom; 637 page = offset_to_page(cg, offset); 638 num = len / cg->page_size; 639 640 if (eccd->eccmode != NAND_ECC_NONE) { 641 steps = cg->page_size / eccd->eccsize; 642 oob = malloc(cg->oob_size, M_NAND, M_WAITOK); 643 eccpos = default_software_ecc_positions(chip); 644 } 645 646 nandbus = device_get_parent(chip->dev); 647 NANDBUS_LOCK(nandbus); 648 NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num); 649 650 while (num--) { 651 if (NAND_PROGRAM_PAGE(chip->dev, page, buf, cg->page_size, 0)) { 652 err = ENXIO; 653 break; 654 } 655 656 if (eccd->eccmode != NAND_ECC_NONE) { 657 if (NAND_GET_ECC(chip->dev, buf, &eccd->ecccalculated, 658 &needwrite)) { 659 err = ENXIO; 660 break; 661 } 662 nand_debug(NDBG_ECC,"ECC calculated:"); 663 if (nand_debug_flag & NDBG_ECC) 664 for (i = 0; i < (eccd->eccbytes * steps); i++) 665 printf("%x ", eccd->ecccalculated[i]); 666 667 nand_debug(NDBG_ECC,"\n"); 668 669 if (needwrite) { 670 if (NAND_READ_OOB(chip->dev, page, oob, cg->oob_size, 671 0)) { 672 err = ENXIO; 673 break; 674 } 675 676 for (i = 0; i < (eccd->eccbytes * steps); i++) 677 oob[eccpos[i]] = eccd->ecccalculated[i]; 678 679 if (NAND_PROGRAM_OOB(chip->dev, page, oob, 680 cg->oob_size, 0)) { 681 err = ENXIO; 682 break; 683 } 684 } 685 } 686 687 pg_stat = &(chip->pg_stat[page]); 688 pg_stat->page_written++; 689 690 page++; 691 buf += cg->page_size; 692 } 693 694 NANDBUS_UNLOCK(nandbus); 695 696 if (oob) 697 free(oob, M_NAND); 698 699 return (err); 700} 701 702int 703nand_prog_pages_raw(struct nand_chip *chip, uint32_t offset, void *buf, 704 uint32_t len) 705{ 706 struct chip_geom *cg; 707 device_t nandbus; 708 uint8_t *ptr; 709 uint32_t page, num, end, begin = 0, begin_off; 710 int retval = 0; 711 712 cg = &chip->chip_geom; 713 page = offset_to_page(cg, offset); 714 begin_off = offset - page * cg->page_size; 715 if (begin_off) { 716 begin = cg->page_size - begin_off; 717 len -= begin; 718 } 719 num = len / cg->page_size; 720 end = len % cg->page_size; 721 722 nandbus = device_get_parent(chip->dev); 723 NANDBUS_LOCK(nandbus); 724 NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num); 725 726 ptr = (uint8_t *)buf; 727 if (begin_off) { 728 if (NAND_PROGRAM_PAGE(chip->dev, page, ptr, begin, begin_off)) { 729 NANDBUS_UNLOCK(nandbus); 730 return (ENXIO); 731 } 732 733 page++; 734 ptr += begin; 735 } 736 737 while (num--) { 738 if (NAND_PROGRAM_PAGE(chip->dev, page, ptr, cg->page_size, 0)) { 739 NANDBUS_UNLOCK(nandbus); 740 return (ENXIO); 741 } 742 743 page++; 744 ptr += cg->page_size; 745 } 746 747 if (end) 748 retval = NAND_PROGRAM_PAGE(chip->dev, page, ptr, end, 0); 749 750 NANDBUS_UNLOCK(nandbus); 751 752 return (retval); 753} 754 755int 756nand_read_oob(struct nand_chip *chip, uint32_t page, void *buf, 757 uint32_t len) 758{ 759 device_t nandbus; 760 int retval = 0; 761 762 nandbus = device_get_parent(chip->dev); 763 NANDBUS_LOCK(nandbus); 764 NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num); 765 766 retval = NAND_READ_OOB(chip->dev, page, buf, len, 0); 767 768 NANDBUS_UNLOCK(nandbus); 769 770 return (retval); 771} 772 773 774int 775nand_prog_oob(struct nand_chip *chip, uint32_t page, void *buf, 776 uint32_t len) 777{ 778 device_t nandbus; 779 int retval = 0; 780 781 nandbus = device_get_parent(chip->dev); 782 NANDBUS_LOCK(nandbus); 783 NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num); 784 785 retval = NAND_PROGRAM_OOB(chip->dev, page, buf, len, 0); 786 787 NANDBUS_UNLOCK(nandbus); 788 789 return (retval); 790} 791 792int 793nand_erase_blocks(struct nand_chip *chip, off_t offset, size_t len) 794{ 795 device_t nandbus; 796 struct chip_geom *cg; 797 uint32_t block, num_blocks; 798 int err = 0; 799 800 cg = &chip->chip_geom; 801 if ((offset % cg->block_size) || (len % cg->block_size)) 802 return (EINVAL); 803 804 block = offset / cg->block_size; 805 num_blocks = len / cg->block_size; 806 nand_debug(NDBG_NAND,"%p erase blocks %d[%d]", chip, block, num_blocks); 807 808 nandbus = device_get_parent(chip->dev); 809 NANDBUS_LOCK(nandbus); 810 NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num); 811 812 while (num_blocks--) { 813 if (!nand_check_bad_block(chip, block)) { 814 if (NAND_ERASE_BLOCK(chip->dev, block)) { 815 nand_debug(NDBG_NAND,"%p erase blocks %d error", 816 chip, block); 817 nand_mark_bad_block(chip, block); 818 err = ENXIO; 819 } 820 } else 821 err = ENXIO; 822 823 block++; 824 }; 825 826 NANDBUS_UNLOCK(nandbus); 827 828 if (err) 829 nand_update_bbt(chip); 830 831 return (err); 832} 833 834MODULE_VERSION(nand, 1); 835