1 /* $NetBSD: nandemulator.c,v 1.7 2015/08/20 14:40:18 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 2011 Department of Software Engineering, 5 * University of Szeged, Hungary 6 * Copyright (c) 2011 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 #include <sys/cdefs.h> 35 __KERNEL_RCSID(0, "$NetBSD: nandemulator.c,v 1.7 2015/08/20 14:40:18 christos Exp $"); 36 37 #include <sys/param.h> 38 #include <sys/device.h> 39 #include <sys/conf.h> 40 #include <sys/kmem.h> 41 #include <sys/kernel.h> 42 43 #include "nandemulator.h" 44 45 #include <dev/nand/nand.h> 46 #include <dev/nand/onfi.h> 47 #include <dev/nand/nand_crc.h> 48 49 #include "ioconf.h" 50 51 extern struct cfdriver nandemulator_cd; 52 53 static int nandemulator_match(device_t, cfdata_t, void *); 54 static void nandemulator_attach(device_t, device_t, void *); 55 static int nandemulator_detach(device_t, int); 56 57 static void nandemulator_device_reset(device_t); 58 static void nandemulator_command(device_t, uint8_t); 59 static void nandemulator_address(device_t, uint8_t); 60 static void nandemulator_busy(device_t); 61 static void nandemulator_read_1(device_t, uint8_t *); 62 static void nandemulator_write_1(device_t, uint8_t); 63 static void nandemulator_read_2(device_t, uint16_t *); 64 static void nandemulator_write_2(device_t, uint16_t); 65 static void nandemulator_read_buf_1(device_t, void *, size_t); 66 static void nandemulator_read_buf_2(device_t, void *, size_t); 67 static void nandemulator_write_buf_1(device_t, const void *, size_t); 68 static void nandemulator_write_buf_2(device_t, const void *, size_t); 69 70 static size_t nandemulator_address_to_page(device_t); 71 static size_t nandemulator_page_to_backend_offset(device_t, size_t); 72 static size_t nandemulator_column_address_to_subpage(device_t); 73 /* 74 #define NANDEMULATOR_DEBUG 1 75 76 #ifdef NANDEMULATOR_DEBUG 77 #warning debug enabled 78 #define DPRINTF(x) if (nandemulatordebug) printf x 79 #define DPRINTFN(n,x) if (nandemulatordebug>(n)) printf x 80 #else 81 #error no debug 82 #define DPRINTF(x) 83 #define DPRINTFN(n,x) 84 #endif 85 86 #ifdef NANDEMULATOR_DEBUG 87 int nandemulatordebug = NANDEMULATOR_DEBUG; 88 #endif 89 */ 90 91 extern int nanddebug; 92 93 enum { 94 NANDEMULATOR_8BIT, 95 NANDEMULATOR_16BIT 96 }; 97 98 struct nandemulator_softc { 99 device_t sc_dev; 100 device_t sc_nanddev; 101 102 int sc_buswidth; 103 104 struct nand_interface sc_nand_if; 105 106 uint8_t sc_command; 107 size_t sc_io_len; 108 uint8_t *sc_io_pointer; 109 uint64_t sc_address; 110 111 uint8_t *sc_backend; 112 size_t sc_backend_size; 113 size_t sc_device_size; 114 bool sc_register_writable; 115 116 uint8_t sc_status_register; 117 uint8_t sc_ids[2]; 118 uint8_t sc_onfi[4]; 119 120 size_t sc_page_size; 121 size_t sc_block_size; 122 size_t sc_spare_size; 123 size_t sc_lun_size; 124 uint8_t sc_row_cycles; 125 uint8_t sc_column_cycles; 126 uint64_t sc_row_mask; 127 128 int sc_address_counter; 129 130 struct onfi_parameter_page *sc_parameter_page; 131 }; 132 133 CFATTACH_DECL_NEW(nandemulator, sizeof(struct nandemulator_softc), 134 nandemulator_match, nandemulator_attach, nandemulator_detach, NULL); 135 136 void 137 nandemulatorattach(int n) 138 { 139 int i, err; 140 cfdata_t cf; 141 142 aprint_debug("nandemulator: requested %d units\n", n); 143 144 err = config_cfattach_attach(nandemulator_cd.cd_name, 145 &nandemulator_ca); 146 if (err) { 147 aprint_error("%s: couldn't register cfattach: %d\n", 148 nandemulator_cd.cd_name, err); 149 config_cfdriver_detach(&nandemulator_cd); 150 return; 151 } 152 for (i = 0; i < n; i++) { 153 cf = kmem_alloc(sizeof(struct cfdata), KM_NOSLEEP); 154 if (cf == NULL) { 155 aprint_error("%s: couldn't allocate cfdata\n", 156 nandemulator_cd.cd_name); 157 continue; 158 } 159 cf->cf_name = nandemulator_cd.cd_name; 160 cf->cf_atname = nandemulator_cd.cd_name; 161 cf->cf_unit = i; 162 cf->cf_fstate = FSTATE_STAR; 163 164 (void)config_attach_pseudo(cf); 165 } 166 } 167 168 /* ARGSUSED */ 169 static int 170 nandemulator_match(device_t parent, cfdata_t match, void *aux) 171 { 172 /* pseudo device, always attaches */ 173 return 1; 174 } 175 176 static void 177 nandemulator_attach(device_t parent, device_t self, void *aux) 178 { 179 struct nandemulator_softc *sc = device_private(self); 180 int i; 181 182 aprint_normal_dev(self, "NAND emulator\n"); 183 184 sc->sc_dev = self; 185 186 nand_init_interface(&sc->sc_nand_if); 187 188 sc->sc_nand_if.command = &nandemulator_command; 189 sc->sc_nand_if.address = &nandemulator_address; 190 sc->sc_nand_if.read_buf_1 = &nandemulator_read_buf_1; 191 sc->sc_nand_if.read_buf_2 = &nandemulator_read_buf_2; 192 sc->sc_nand_if.read_1 = &nandemulator_read_1; 193 sc->sc_nand_if.read_2 = &nandemulator_read_2; 194 sc->sc_nand_if.write_buf_1 = &nandemulator_write_buf_1; 195 sc->sc_nand_if.write_buf_2 = &nandemulator_write_buf_2; 196 sc->sc_nand_if.write_1 = &nandemulator_write_1; 197 sc->sc_nand_if.write_2 = &nandemulator_write_2; 198 sc->sc_nand_if.busy = &nandemulator_busy; 199 200 sc->sc_nand_if.ecc.necc_code_size = 3; 201 sc->sc_nand_if.ecc.necc_block_size = 256; 202 203 if (!pmf_device_register1(sc->sc_dev, NULL, NULL, NULL)) 204 aprint_error_dev(sc->sc_dev, 205 "couldn't establish power handler\n"); 206 207 sc->sc_buswidth = NANDEMULATOR_16BIT; /* 16bit for now */ 208 209 /* hardcode these now, make it configurable later */ 210 sc->sc_device_size = 32 * 1024 * 1024; /* 32MB */ 211 sc->sc_page_size = 2048; 212 sc->sc_block_size = 64; 213 sc->sc_lun_size = 214 sc->sc_device_size / (sc->sc_page_size * sc->sc_block_size); 215 KASSERT(sc->sc_device_size % 216 (sc->sc_page_size * sc->sc_block_size) == 0); 217 sc->sc_spare_size = 64; 218 219 sc->sc_column_cycles = 2; 220 sc->sc_row_cycles = 3; 221 222 /* init the emulator data structures */ 223 sc->sc_backend_size = 224 sc->sc_device_size + 225 sc->sc_device_size / sc->sc_page_size * sc->sc_spare_size; 226 227 sc->sc_backend = kmem_alloc(sc->sc_backend_size, KM_SLEEP); 228 memset(sc->sc_backend, 0xff, sc->sc_backend_size); 229 230 sc->sc_parameter_page = 231 kmem_zalloc(sizeof(struct onfi_parameter_page) * 4, KM_SLEEP); 232 233 struct onfi_parameter_page *opp; 234 uint8_t sig[4] = { 'O', 'N', 'F', 'I' }; 235 236 for (i = 0; i < 4; i++) { 237 opp = &sc->sc_parameter_page[i]; 238 239 opp->param_signature = htole32(*(uint32_t *)sig); 240 opp->param_pagesize = htole32(sc->sc_page_size); 241 opp->param_blocksize = htole32(sc->sc_block_size); 242 opp->param_sparesize = htole16(sc->sc_spare_size); 243 opp->param_lunsize = htole32(sc->sc_lun_size); 244 opp->param_numluns = 1; 245 246 opp->param_manufacturer_id = 0x00; 247 memcpy(opp->param_manufacturer, 248 "NETBSD", strlen("NETBSD")); 249 memcpy(opp->param_model, 250 "NANDEMULATOR", strlen("NANDEMULATOR")); 251 252 uint16_t features = ONFI_FEATURE_16BIT; 253 opp->param_features = htole16(features); 254 255 /* the lower 4 bits contain the row address cycles 256 * the upper 4 bits contain the column address cycles 257 */ 258 opp->param_addr_cycles = sc->sc_row_cycles; 259 opp->param_addr_cycles |= (sc->sc_column_cycles << 4); 260 261 opp->param_integrity_crc = nand_crc16((uint8_t *)opp, 254); 262 } 263 264 sc->sc_ids[0] = 0x00; 265 sc->sc_ids[1] = 0x00; 266 267 sc->sc_onfi[0] = 'O'; 268 sc->sc_onfi[1] = 'N'; 269 sc->sc_onfi[2] = 'F'; 270 sc->sc_onfi[3] = 'I'; 271 272 sc->sc_row_mask = 0x00; 273 for (i = 0; i < sc->sc_row_cycles; i++) { 274 sc->sc_row_mask <<= 8; 275 sc->sc_row_mask |= 0xff; 276 } 277 278 nandemulator_device_reset(self); 279 280 sc->sc_nanddev = nand_attach_mi(&sc->sc_nand_if, sc->sc_dev); 281 } 282 283 static int 284 nandemulator_detach(device_t self, int flags) 285 { 286 struct nandemulator_softc *sc = device_private(self); 287 int ret = 0; 288 289 aprint_normal_dev(sc->sc_dev, "detaching emulator\n"); 290 291 pmf_device_deregister(sc->sc_dev); 292 293 if (sc->sc_nanddev != NULL) 294 ret = config_detach(sc->sc_nanddev, flags); 295 296 kmem_free(sc->sc_backend, sc->sc_backend_size); 297 kmem_free(sc->sc_parameter_page, 298 sizeof(struct onfi_parameter_page) * 4); 299 300 return ret; 301 } 302 303 /** 304 * bring the emulated device to a known state 305 */ 306 static void 307 nandemulator_device_reset(device_t self) 308 { 309 struct nandemulator_softc *sc = device_private(self); 310 311 DPRINTF(("device reset\n")); 312 313 sc->sc_command = 0; 314 sc->sc_register_writable = false; 315 sc->sc_io_len = 0; 316 sc->sc_io_pointer = NULL; 317 sc->sc_address = 0; 318 sc->sc_address_counter = 0; 319 320 sc->sc_status_register = ONFI_STATUS_RDY | ONFI_STATUS_WP; 321 } 322 323 static void 324 nandemulator_address_chip(device_t self) 325 { 326 struct nandemulator_softc *sc = device_private(self); 327 size_t page, offset; 328 329 KASSERT(sc->sc_address_counter == 330 sc->sc_column_cycles + sc->sc_row_cycles); 331 332 if (sc->sc_address_counter != 333 sc->sc_column_cycles + sc->sc_row_cycles) { 334 aprint_error_dev(self, "incorrect number of address cycles\n"); 335 aprint_error_dev(self, "cc: %d, rc: %d, ac: %d\n", 336 sc->sc_column_cycles, sc->sc_row_cycles, 337 sc->sc_address_counter); 338 } 339 340 page = nandemulator_address_to_page(self); 341 offset = sc->sc_page_size * page; 342 343 DPRINTF(("READ/PROGRAM; page: 0x%jx (row addr: 0x%jx)\n", 344 (uintmax_t )page, 345 (uintmax_t )offset)); 346 347 KASSERT(offset < sc->sc_device_size); 348 349 if (offset >= sc->sc_device_size) { 350 aprint_error_dev(self, "address > device size!\n"); 351 sc->sc_io_len = 0; 352 } else { 353 size_t addr = 354 nandemulator_page_to_backend_offset(self, page); 355 size_t pageoff = 356 nandemulator_column_address_to_subpage(self); 357 358 DPRINTF(("subpage: 0x%jx\n", (uintmax_t )pageoff)); 359 360 KASSERT(pageoff < 361 sc->sc_page_size + sc->sc_spare_size); 362 KASSERT(addr < sc->sc_backend_size); 363 364 sc->sc_io_pointer = sc->sc_backend + addr + pageoff; 365 sc->sc_io_len = 366 sc->sc_page_size + sc->sc_spare_size - pageoff; 367 } 368 } 369 370 static void 371 nandemulator_command(device_t self, uint8_t command) 372 { 373 struct nandemulator_softc *sc = device_private(self); 374 size_t offset, page; 375 376 sc->sc_command = command; 377 sc->sc_register_writable = false; 378 379 DPRINTF(("nandemulator command: 0x%hhx\n", command)); 380 381 switch (command) { 382 case ONFI_READ_STATUS: 383 sc->sc_io_pointer = &sc->sc_status_register; 384 sc->sc_io_len = 1; 385 break; 386 case ONFI_RESET: 387 nandemulator_device_reset(self); 388 break; 389 case ONFI_PAGE_PROGRAM: 390 sc->sc_register_writable = true; 391 case ONFI_READ: 392 case ONFI_BLOCK_ERASE: 393 sc->sc_address_counter = 0; 394 case ONFI_READ_ID: 395 case ONFI_READ_PARAMETER_PAGE: 396 sc->sc_io_len = 0; 397 sc->sc_address = 0; 398 break; 399 case ONFI_PAGE_PROGRAM_START: 400 /* XXX the program should only happen here */ 401 break; 402 case ONFI_READ_START: 403 nandemulator_address_chip(self); 404 break; 405 case ONFI_BLOCK_ERASE_START: 406 page = nandemulator_address_to_page(self); 407 offset = sc->sc_page_size * page; 408 409 KASSERT(offset % 410 (sc->sc_block_size * sc->sc_page_size) == 0); 411 412 KASSERT(offset < sc->sc_device_size); 413 414 if (offset >= sc->sc_device_size) { 415 aprint_error_dev(self, "address > device size!\n"); 416 } else { 417 size_t addr = 418 nandemulator_page_to_backend_offset(self, page); 419 420 size_t blocklen = 421 sc->sc_block_size * 422 (sc->sc_page_size + sc->sc_spare_size); 423 424 KASSERT(addr < sc->sc_backend_size); 425 uint8_t *block = sc->sc_backend + addr; 426 427 DPRINTF(("erasing block at 0x%jx\n", 428 (uintmax_t )offset)); 429 430 memset(block, 0xff, blocklen); 431 } 432 sc->sc_io_len = 0; 433 break; 434 default: 435 aprint_error_dev(self, 436 "invalid nand command (0x%hhx)\n", command); 437 KASSERT(false); 438 sc->sc_io_len = 0; 439 } 440 }; 441 442 static void 443 nandemulator_address(device_t self, uint8_t address) 444 { 445 struct nandemulator_softc *sc = device_private(self); 446 447 DPRINTF(("nandemulator_address: %hhx\n", address)); 448 449 /** 450 * we have to handle read id/parameter page here, 451 * as we can read right after giving the address. 452 */ 453 switch (sc->sc_command) { 454 case ONFI_READ_ID: 455 if (address == 0x00) { 456 sc->sc_io_len = 2; 457 sc->sc_io_pointer = sc->sc_ids; 458 } else if (address == 0x20) { 459 sc->sc_io_len = 4; 460 sc->sc_io_pointer = sc->sc_onfi; 461 } else { 462 sc->sc_io_len = 0; 463 } 464 break; 465 case ONFI_READ_PARAMETER_PAGE: 466 if (address == 0x00) { 467 sc->sc_io_len = sizeof(struct onfi_parameter_page) * 4; 468 sc->sc_io_pointer = (uint8_t *)sc->sc_parameter_page; 469 } else { 470 sc->sc_io_len = 0; 471 } 472 break; 473 case ONFI_PAGE_PROGRAM: 474 sc->sc_address <<= 8; 475 sc->sc_address |= address; 476 sc->sc_address_counter++; 477 478 if (sc->sc_address_counter == 479 sc->sc_column_cycles + sc->sc_row_cycles) { 480 nandemulator_address_chip(self); 481 } 482 break; 483 default: 484 sc->sc_address <<= 8; 485 sc->sc_address |= address; 486 sc->sc_address_counter++; 487 } 488 }; 489 490 static void 491 nandemulator_busy(device_t self) 492 { 493 #ifdef NANDEMULATOR_DELAYS 494 struct nandemulator_softc *sc = device_private(self); 495 496 /* do some delay depending on command */ 497 switch (sc->sc_command) { 498 case ONFI_PAGE_PROGRAM_START: 499 case ONFI_BLOCK_ERASE_START: 500 DELAY(10); 501 break; 502 case ONFI_READ_START: 503 default: 504 DELAY(1); 505 } 506 #endif 507 } 508 509 static void 510 nandemulator_read_1(device_t self, uint8_t *data) 511 { 512 struct nandemulator_softc *sc = device_private(self); 513 514 KASSERT(sc->sc_io_len > 0); 515 516 if (sc->sc_io_len > 0) { 517 *data = *sc->sc_io_pointer; 518 519 sc->sc_io_pointer++; 520 sc->sc_io_len--; 521 } else { 522 aprint_error_dev(self, "reading byte from invalid location\n"); 523 *data = 0xff; 524 } 525 } 526 527 static void 528 nandemulator_write_1(device_t self, uint8_t data) 529 { 530 struct nandemulator_softc *sc = device_private(self); 531 532 KASSERT(sc->sc_register_writable); 533 534 if (!sc->sc_register_writable) { 535 aprint_error_dev(self, 536 "trying to write read only location without effect\n"); 537 return; 538 } 539 540 KASSERT(sc->sc_io_len > 0); 541 542 if (sc->sc_io_len > 0) { 543 *sc->sc_io_pointer = data; 544 545 sc->sc_io_pointer++; 546 sc->sc_io_len--; 547 } else { 548 aprint_error_dev(self, "write to invalid location\n"); 549 } 550 } 551 552 static void 553 nandemulator_read_2(device_t self, uint16_t *data) 554 { 555 struct nandemulator_softc *sc = device_private(self); 556 557 KASSERT(sc->sc_buswidth == NANDEMULATOR_16BIT); 558 559 if (sc->sc_buswidth != NANDEMULATOR_16BIT) { 560 aprint_error_dev(self, 561 "trying to read a word on an 8bit chip\n"); 562 return; 563 } 564 565 KASSERT(sc->sc_io_len > 1); 566 567 if (sc->sc_io_len > 1) { 568 *data = *(uint16_t *)sc->sc_io_pointer; 569 570 sc->sc_io_pointer += 2; 571 sc->sc_io_len -= 2; 572 } else { 573 aprint_error_dev(self, "reading word from invalid location\n"); 574 *data = 0xffff; 575 } 576 } 577 578 static void 579 nandemulator_write_2(device_t self, uint16_t data) 580 { 581 struct nandemulator_softc *sc = device_private(self); 582 583 KASSERT(sc->sc_register_writable); 584 585 if (!sc->sc_register_writable) { 586 aprint_error_dev(self, 587 "trying to write read only location without effect\n"); 588 return; 589 } 590 591 KASSERT(sc->sc_buswidth == NANDEMULATOR_16BIT); 592 593 if (sc->sc_buswidth != NANDEMULATOR_16BIT) { 594 aprint_error_dev(self, 595 "trying to write a word to an 8bit chip"); 596 return; 597 } 598 599 KASSERT(sc->sc_io_len > 1); 600 601 if (sc->sc_io_len > 1) { 602 *(uint16_t *)sc->sc_io_pointer = data; 603 604 sc->sc_io_pointer += 2; 605 sc->sc_io_len -= 2; 606 } else { 607 aprint_error_dev(self, "writing to invalid location"); 608 } 609 } 610 611 static void 612 nandemulator_read_buf_1(device_t self, void *buf, size_t len) 613 { 614 uint8_t *addr; 615 616 KASSERT(buf != NULL); 617 KASSERT(len >= 1); 618 619 addr = buf; 620 while (len > 0) { 621 nandemulator_read_1(self, addr); 622 addr++, len--; 623 } 624 } 625 626 static void 627 nandemulator_read_buf_2(device_t self, void *buf, size_t len) 628 { 629 uint16_t *addr; 630 631 KASSERT(buf != NULL); 632 KASSERT(len >= 2); 633 KASSERT(!(len & 0x01)); 634 635 addr = buf; 636 len /= 2; 637 while (len > 0) { 638 nandemulator_read_2(self, addr); 639 addr++, len--; 640 } 641 } 642 643 static void 644 nandemulator_write_buf_1(device_t self, const void *buf, size_t len) 645 { 646 const uint8_t *addr; 647 648 KASSERT(buf != NULL); 649 KASSERT(len >= 1); 650 651 addr = buf; 652 while (len > 0) { 653 nandemulator_write_1(self, *addr); 654 addr++, len--; 655 } 656 } 657 658 static void 659 nandemulator_write_buf_2(device_t self, const void *buf, size_t len) 660 { 661 const uint16_t *addr; 662 663 KASSERT(buf != NULL); 664 KASSERT(len >= 2); 665 KASSERT(!(len & 0x01)); 666 667 addr = buf; 668 len /= 2; 669 while (len > 0) { 670 nandemulator_write_2(self, *addr); 671 addr++, len--; 672 } 673 } 674 675 static size_t 676 nandemulator_address_to_page(device_t self) 677 { 678 struct nandemulator_softc *sc = device_private(self); 679 uint64_t address, offset; 680 int i; 681 682 address = htole64(sc->sc_address); 683 address &= sc->sc_row_mask; 684 685 offset = 0; 686 for (i = 0; i < sc->sc_row_cycles; i++) { 687 offset <<= 8; 688 offset |= (address & 0xff); 689 address >>= 8; 690 } 691 692 return le64toh(offset); 693 } 694 695 static size_t 696 nandemulator_column_address_to_subpage(device_t self) 697 { 698 struct nandemulator_softc *sc = device_private(self); 699 uint64_t address, offset; 700 int i; 701 702 address = htole64(sc->sc_address); 703 address >>= (8 * sc->sc_row_cycles); 704 705 offset = 0; 706 for (i = 0; i < sc->sc_column_cycles; i++) { 707 offset <<= 8; 708 offset |= (address & 0xff); 709 address >>= 8; 710 } 711 712 if (sc->sc_buswidth == NANDEMULATOR_16BIT) 713 return (size_t )le64toh(offset << 1); 714 else 715 return (size_t )le64toh(offset); 716 } 717 718 static size_t 719 nandemulator_page_to_backend_offset(device_t self, size_t page) 720 { 721 struct nandemulator_softc *sc = device_private(self); 722 723 return (sc->sc_page_size + sc->sc_spare_size) * page; 724 } 725 726 #ifdef _MODULE 727 728 MODULE(MODULE_CLASS_DRIVER, nandemulator, "nand"); 729 730 static const struct cfiattrdata nandbuscf_iattrdata = { 731 "nandbus", 0, { { NULL, NULL, 0 }, } 732 }; 733 static const struct cfiattrdata * const nandemulator_attrs[] = { 734 &nandbuscf_iattrdata, NULL 735 }; 736 737 CFDRIVER_DECL(nandemulator, DV_DULL, nandemulator_attrs); 738 extern struct cfattach nandemulator_ca; 739 static int nandemulatorloc[] = { -1, -1 }; 740 741 static struct cfdata nandemulator_cfdata[] = { 742 { 743 .cf_name = "nandemulator", 744 .cf_atname = "nandemulator", 745 .cf_unit = 0, 746 .cf_fstate = FSTATE_STAR, 747 .cf_loc = nandemulatorloc, 748 .cf_flags = 0, 749 .cf_pspec = NULL, 750 }, 751 { NULL, NULL, 0, 0, NULL, 0, NULL } 752 }; 753 754 static int 755 nandemulator_modcmd(modcmd_t cmd, void *arg) 756 { 757 int error; 758 759 switch (cmd) { 760 case MODULE_CMD_INIT: 761 error = config_cfdriver_attach(&nandemulator_cd); 762 if (error) { 763 return error; 764 } 765 766 error = config_cfattach_attach(nandemulator_cd.cd_name, 767 &nandemulator_ca); 768 if (error) { 769 config_cfdriver_detach(&nandemulator_cd); 770 aprint_error("%s: unable to register cfattach\n", 771 nandemulator_cd.cd_name); 772 773 return error; 774 } 775 776 error = config_cfdata_attach(nandemulator_cfdata, 1); 777 if (error) { 778 config_cfattach_detach(nandemulator_cd.cd_name, 779 &nandemulator_ca); 780 config_cfdriver_detach(&nandemulator_cd); 781 aprint_error("%s: unable to register cfdata\n", 782 nandemulator_cd.cd_name); 783 784 return error; 785 } 786 787 (void)config_attach_pseudo(nandemulator_cfdata); 788 789 return 0; 790 791 case MODULE_CMD_FINI: 792 error = config_cfdata_detach(nandemulator_cfdata); 793 if (error) { 794 return error; 795 } 796 797 config_cfattach_detach(nandemulator_cd.cd_name, 798 &nandemulator_ca); 799 config_cfdriver_detach(&nandemulator_cd); 800 801 return 0; 802 803 case MODULE_CMD_AUTOUNLOAD: 804 /* prevent auto-unload */ 805 return EBUSY; 806 807 default: 808 return ENOTTY; 809 } 810 } 811 812 #endif 813