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