Lines Matching refs:ns
189 #define NS_IS_INITIALIZED(ns) ((ns)->geom.totsz != 0) argument
192 #define NS_STATUS_OK(ns) (NAND_STATUS_READY | (NAND_STATUS_WP * ((ns)->lines.wp == 0))) argument
195 #define NS_STATUS_FAILED(ns) (NAND_STATUS_FAIL | NS_STATUS_OK(ns)) argument
198 #define NS_RAW_OFFSET(ns) \ argument
199 (((ns)->regs.row * (ns)->geom.pgszoob) + (ns)->regs.column)
202 #define NS_RAW_OFFSET_OOB(ns) (NS_RAW_OFFSET(ns) + ns->geom.pgsz) argument
205 #define NS_PAGE_BYTE_SHIFT(ns) ((ns)->regs.column + (ns)->regs.off) argument
491 DEFINE_SHOW_ATTRIBUTE(ns);
500 static int ns_debugfs_create(struct nandsim *ns) in ns_debugfs_create() argument
515 ns->dent = debugfs_create_file("nandsim_wear_report", 0400, root, ns, in ns_debugfs_create()
517 if (IS_ERR_OR_NULL(ns->dent)) { in ns_debugfs_create()
525 static void ns_debugfs_remove(struct nandsim *ns) in ns_debugfs_remove() argument
527 debugfs_remove_recursive(ns->dent); in ns_debugfs_remove()
536 static int __init ns_alloc_device(struct nandsim *ns) in ns_alloc_device() argument
555 ns->pages_written = in ns_alloc_device()
557 BITS_TO_LONGS(ns->geom.pgnum))); in ns_alloc_device()
558 if (!ns->pages_written) { in ns_alloc_device()
563 ns->file_buf = kmalloc(ns->geom.pgszoob, GFP_KERNEL); in ns_alloc_device()
564 if (!ns->file_buf) { in ns_alloc_device()
569 ns->cfile = cfile; in ns_alloc_device()
574 vfree(ns->pages_written); in ns_alloc_device()
581 ns->pages = vmalloc(array_size(sizeof(union ns_mem), ns->geom.pgnum)); in ns_alloc_device()
582 if (!ns->pages) { in ns_alloc_device()
586 for (i = 0; i < ns->geom.pgnum; i++) { in ns_alloc_device()
587 ns->pages[i].byte = NULL; in ns_alloc_device()
589 ns->nand_pages_slab = kmem_cache_create("nandsim", in ns_alloc_device()
590 ns->geom.pgszoob, 0, 0, NULL); in ns_alloc_device()
591 if (!ns->nand_pages_slab) { in ns_alloc_device()
600 vfree(ns->pages); in ns_alloc_device()
608 static void ns_free_device(struct nandsim *ns) in ns_free_device() argument
612 if (ns->cfile) { in ns_free_device()
613 kfree(ns->file_buf); in ns_free_device()
614 vfree(ns->pages_written); in ns_free_device()
615 filp_close(ns->cfile, NULL); in ns_free_device()
619 if (ns->pages) { in ns_free_device()
620 for (i = 0; i < ns->geom.pgnum; i++) { in ns_free_device()
621 if (ns->pages[i].byte) in ns_free_device()
622 kmem_cache_free(ns->nand_pages_slab, in ns_free_device()
623 ns->pages[i].byte); in ns_free_device()
625 kmem_cache_destroy(ns->nand_pages_slab); in ns_free_device()
626 vfree(ns->pages); in ns_free_device()
643 struct nandsim *ns = nand_get_controller_data(chip); in ns_init() local
648 if (NS_IS_INITIALIZED(ns)) { in ns_init()
654 ns->busw = chip->options & NAND_BUSWIDTH_16 ? 16 : 8; in ns_init()
655 ns->geom.totsz = mtd->size; in ns_init()
656 ns->geom.pgsz = mtd->writesize; in ns_init()
657 ns->geom.oobsz = mtd->oobsize; in ns_init()
658 ns->geom.secsz = mtd->erasesize; in ns_init()
659 ns->geom.pgszoob = ns->geom.pgsz + ns->geom.oobsz; in ns_init()
660 ns->geom.pgnum = div_u64(ns->geom.totsz, ns->geom.pgsz); in ns_init()
661 ns->geom.totszoob = ns->geom.totsz + (uint64_t)ns->geom.pgnum * ns->geom.oobsz; in ns_init()
662 ns->geom.secshift = ffs(ns->geom.secsz) - 1; in ns_init()
663 ns->geom.pgshift = chip->page_shift; in ns_init()
664 ns->geom.pgsec = ns->geom.secsz / ns->geom.pgsz; in ns_init()
665 ns->geom.secszoob = ns->geom.secsz + ns->geom.oobsz * ns->geom.pgsec; in ns_init()
666 ns->options = 0; in ns_init()
668 if (ns->geom.pgsz == 512) { in ns_init()
669 ns->options |= OPT_PAGE512; in ns_init()
670 if (ns->busw == 8) in ns_init()
671 ns->options |= OPT_PAGE512_8BIT; in ns_init()
672 } else if (ns->geom.pgsz == 2048) { in ns_init()
673 ns->options |= OPT_PAGE2048; in ns_init()
674 } else if (ns->geom.pgsz == 4096) { in ns_init()
675 ns->options |= OPT_PAGE4096; in ns_init()
677 NS_ERR("init_nandsim: unknown page size %u\n", ns->geom.pgsz); in ns_init()
681 if (ns->options & OPT_SMALLPAGE) { in ns_init()
682 if (ns->geom.totsz <= (32 << 20)) { in ns_init()
683 ns->geom.pgaddrbytes = 3; in ns_init()
684 ns->geom.secaddrbytes = 2; in ns_init()
686 ns->geom.pgaddrbytes = 4; in ns_init()
687 ns->geom.secaddrbytes = 3; in ns_init()
690 if (ns->geom.totsz <= (128 << 20)) { in ns_init()
691 ns->geom.pgaddrbytes = 4; in ns_init()
692 ns->geom.secaddrbytes = 2; in ns_init()
694 ns->geom.pgaddrbytes = 5; in ns_init()
695 ns->geom.secaddrbytes = 3; in ns_init()
700 if (parts_num > ARRAY_SIZE(ns->partitions)) { in ns_init()
704 remains = ns->geom.totsz; in ns_init()
707 uint64_t part_sz = (uint64_t)parts[i] * ns->geom.secsz; in ns_init()
713 ns->partitions[i].name = ns_get_partition_name(i); in ns_init()
714 if (!ns->partitions[i].name) { in ns_init()
718 ns->partitions[i].offset = next_offset; in ns_init()
719 ns->partitions[i].size = part_sz; in ns_init()
720 next_offset += ns->partitions[i].size; in ns_init()
721 remains -= ns->partitions[i].size; in ns_init()
723 ns->nbparts = parts_num; in ns_init()
725 if (parts_num + 1 > ARRAY_SIZE(ns->partitions)) { in ns_init()
730 ns->partitions[i].name = ns_get_partition_name(i); in ns_init()
731 if (!ns->partitions[i].name) { in ns_init()
736 ns->partitions[i].offset = next_offset; in ns_init()
737 ns->partitions[i].size = remains; in ns_init()
738 ns->nbparts += 1; in ns_init()
741 if (ns->busw == 16) in ns_init()
745 (unsigned long long)ns->geom.totsz >> 20); in ns_init()
746 printk("page size: %u bytes\n", ns->geom.pgsz); in ns_init()
747 printk("OOB area size: %u bytes\n", ns->geom.oobsz); in ns_init()
748 printk("sector size: %u KiB\n", ns->geom.secsz >> 10); in ns_init()
749 printk("pages number: %u\n", ns->geom.pgnum); in ns_init()
750 printk("pages per sector: %u\n", ns->geom.pgsec); in ns_init()
751 printk("bus width: %u\n", ns->busw); in ns_init()
752 printk("bits in sector size: %u\n", ns->geom.secshift); in ns_init()
753 printk("bits in page size: %u\n", ns->geom.pgshift); in ns_init()
754 printk("bits in OOB size: %u\n", ffs(ns->geom.oobsz) - 1); in ns_init()
756 (unsigned long long)ns->geom.totszoob >> 10); in ns_init()
757 printk("page address bytes: %u\n", ns->geom.pgaddrbytes); in ns_init()
758 printk("sector address bytes: %u\n", ns->geom.secaddrbytes); in ns_init()
759 printk("options: %#x\n", ns->options); in ns_init()
761 ret = ns_alloc_device(ns); in ns_init()
766 ns->buf.byte = kmalloc(ns->geom.pgszoob, GFP_KERNEL); in ns_init()
767 if (!ns->buf.byte) { in ns_init()
769 ns->geom.pgszoob); in ns_init()
773 memset(ns->buf.byte, 0xFF, ns->geom.pgszoob); in ns_init()
778 ns_free_device(ns); in ns_init()
780 for (i = 0; i < ARRAY_SIZE(ns->partitions); ++i) in ns_init()
781 kfree(ns->partitions[i].name); in ns_init()
789 static void ns_free(struct nandsim *ns) in ns_free() argument
793 for (i = 0; i < ARRAY_SIZE(ns->partitions); ++i) in ns_free()
794 kfree(ns->partitions[i].name); in ns_free()
796 kfree(ns->buf.byte); in ns_free()
797 ns_free_device(ns); in ns_free()
802 static int ns_parse_badblocks(struct nandsim *ns, struct mtd_info *mtd) in ns_parse_badblocks() argument
819 offset = (loff_t)erase_block_no * ns->geom.secsz; in ns_parse_badblocks()
1138 static inline void ns_accept_addr_byte(struct nandsim *ns, u_char bt) in ns_accept_addr_byte() argument
1142 if (ns->regs.count < (ns->geom.pgaddrbytes - ns->geom.secaddrbytes)) in ns_accept_addr_byte()
1143 ns->regs.column |= (byte << 8 * ns->regs.count); in ns_accept_addr_byte()
1145 ns->regs.row |= (byte << 8 * (ns->regs.count - in ns_accept_addr_byte()
1146 ns->geom.pgaddrbytes + in ns_accept_addr_byte()
1147 ns->geom.secaddrbytes)); in ns_accept_addr_byte()
1156 static inline void ns_switch_to_ready_state(struct nandsim *ns, u_char status) in ns_switch_to_ready_state() argument
1161 ns->state = STATE_READY; in ns_switch_to_ready_state()
1162 ns->nxstate = STATE_UNKNOWN; in ns_switch_to_ready_state()
1163 ns->op = NULL; in ns_switch_to_ready_state()
1164 ns->npstates = 0; in ns_switch_to_ready_state()
1165 ns->stateidx = 0; in ns_switch_to_ready_state()
1166 ns->regs.num = 0; in ns_switch_to_ready_state()
1167 ns->regs.count = 0; in ns_switch_to_ready_state()
1168 ns->regs.off = 0; in ns_switch_to_ready_state()
1169 ns->regs.row = 0; in ns_switch_to_ready_state()
1170 ns->regs.column = 0; in ns_switch_to_ready_state()
1171 ns->regs.status = status; in ns_switch_to_ready_state()
1216 static int ns_find_operation(struct nandsim *ns, uint32_t flag) in ns_find_operation() argument
1225 if (!(ns->options & ops[i].reqopts)) in ns_find_operation()
1230 if (!(ops[i].states[ns->npstates] & STATE_ADDR_MASK)) in ns_find_operation()
1233 if (NS_STATE(ns->state) != NS_STATE(ops[i].states[ns->npstates])) in ns_find_operation()
1237 for (j = 0; j < ns->npstates; j++) in ns_find_operation()
1238 if (NS_STATE(ops[i].states[j]) != NS_STATE(ns->pstates[j]) in ns_find_operation()
1239 && (ns->options & ops[idx].reqopts)) { in ns_find_operation()
1252 ns->op = &ops[idx].states[0]; in ns_find_operation()
1261 ns->stateidx = ns->npstates - 1; in ns_find_operation()
1263 ns->stateidx = ns->npstates; in ns_find_operation()
1265 ns->npstates = 0; in ns_find_operation()
1266 ns->state = ns->op[ns->stateidx]; in ns_find_operation()
1267 ns->nxstate = ns->op[ns->stateidx + 1]; in ns_find_operation()
1269 idx, ns_get_state_name(ns->state), in ns_find_operation()
1270 ns_get_state_name(ns->nxstate)); in ns_find_operation()
1276 if (ns->npstates != 0) { in ns_find_operation()
1278 ns_get_state_name(ns->state)); in ns_find_operation()
1279 ns->npstates = 0; in ns_find_operation()
1280 return ns_find_operation(ns, 0); in ns_find_operation()
1284 ns_switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); in ns_find_operation()
1296 ns->pstates[ns->npstates++] = ns->state; in ns_find_operation()
1301 static void ns_put_pages(struct nandsim *ns) in ns_put_pages() argument
1305 for (i = 0; i < ns->held_cnt; i++) in ns_put_pages()
1306 put_page(ns->held_pages[i]); in ns_put_pages()
1310 static int ns_get_pages(struct nandsim *ns, struct file *file, size_t count, in ns_get_pages() argument
1321 ns->held_cnt = 0; in ns_get_pages()
1331 ns_put_pages(ns); in ns_get_pages()
1336 ns->held_pages[ns->held_cnt++] = page; in ns_get_pages()
1341 static ssize_t ns_read_file(struct nandsim *ns, struct file *file, void *buf, in ns_read_file() argument
1348 err = ns_get_pages(ns, file, count, pos); in ns_read_file()
1354 ns_put_pages(ns); in ns_read_file()
1358 static ssize_t ns_write_file(struct nandsim *ns, struct file *file, void *buf, in ns_write_file() argument
1365 err = ns_get_pages(ns, file, count, pos); in ns_write_file()
1371 ns_put_pages(ns); in ns_write_file()
1378 static inline union ns_mem *NS_GET_PAGE(struct nandsim *ns) in NS_GET_PAGE() argument
1380 return &(ns->pages[ns->regs.row]); in NS_GET_PAGE()
1386 static inline u_char *NS_PAGE_BYTE_OFF(struct nandsim *ns) in NS_PAGE_BYTE_OFF() argument
1388 return NS_GET_PAGE(ns)->byte + NS_PAGE_BYTE_SHIFT(ns); in NS_PAGE_BYTE_OFF()
1391 static int ns_do_read_error(struct nandsim *ns, int num) in ns_do_read_error() argument
1393 unsigned int page_no = ns->regs.row; in ns_do_read_error()
1396 get_random_bytes(ns->buf.byte, num); in ns_do_read_error()
1403 static void ns_do_bit_flips(struct nandsim *ns, int num) in ns_do_bit_flips() argument
1411 ns->buf.byte[pos / 8] ^= (1 << (pos % 8)); in ns_do_bit_flips()
1414 pos, ns->regs.row, NS_PAGE_BYTE_SHIFT(ns), in ns_do_bit_flips()
1423 static void ns_read_page(struct nandsim *ns, int num) in ns_read_page() argument
1427 if (ns->cfile) { in ns_read_page()
1428 if (!test_bit(ns->regs.row, ns->pages_written)) { in ns_read_page()
1429 NS_DBG("read_page: page %d not written\n", ns->regs.row); in ns_read_page()
1430 memset(ns->buf.byte, 0xFF, num); in ns_read_page()
1436 ns->regs.row, NS_PAGE_BYTE_SHIFT(ns)); in ns_read_page()
1437 if (ns_do_read_error(ns, num)) in ns_read_page()
1439 pos = (loff_t)NS_RAW_OFFSET(ns) + ns->regs.off; in ns_read_page()
1440 tx = ns_read_file(ns, ns->cfile, ns->buf.byte, num, in ns_read_page()
1443 NS_ERR("read_page: read error for page %d ret %ld\n", ns->regs.row, (long)tx); in ns_read_page()
1446 ns_do_bit_flips(ns, num); in ns_read_page()
1451 mypage = NS_GET_PAGE(ns); in ns_read_page()
1453 NS_DBG("read_page: page %d not allocated\n", ns->regs.row); in ns_read_page()
1454 memset(ns->buf.byte, 0xFF, num); in ns_read_page()
1457 ns->regs.row, NS_PAGE_BYTE_SHIFT(ns)); in ns_read_page()
1458 if (ns_do_read_error(ns, num)) in ns_read_page()
1460 memcpy(ns->buf.byte, NS_PAGE_BYTE_OFF(ns), num); in ns_read_page()
1461 ns_do_bit_flips(ns, num); in ns_read_page()
1468 static void ns_erase_sector(struct nandsim *ns) in ns_erase_sector() argument
1473 if (ns->cfile) { in ns_erase_sector()
1474 for (i = 0; i < ns->geom.pgsec; i++) in ns_erase_sector()
1475 if (__test_and_clear_bit(ns->regs.row + i, in ns_erase_sector()
1476 ns->pages_written)) { in ns_erase_sector()
1477 NS_DBG("erase_sector: freeing page %d\n", ns->regs.row + i); in ns_erase_sector()
1482 mypage = NS_GET_PAGE(ns); in ns_erase_sector()
1483 for (i = 0; i < ns->geom.pgsec; i++) { in ns_erase_sector()
1485 NS_DBG("erase_sector: freeing page %d\n", ns->regs.row+i); in ns_erase_sector()
1486 kmem_cache_free(ns->nand_pages_slab, mypage->byte); in ns_erase_sector()
1496 static int ns_prog_page(struct nandsim *ns, int num) in ns_prog_page() argument
1502 if (ns->cfile) { in ns_prog_page()
1507 NS_DBG("prog_page: writing page %d\n", ns->regs.row); in ns_prog_page()
1508 pg_off = ns->file_buf + NS_PAGE_BYTE_SHIFT(ns); in ns_prog_page()
1509 off = (loff_t)NS_RAW_OFFSET(ns) + ns->regs.off; in ns_prog_page()
1510 if (!test_bit(ns->regs.row, ns->pages_written)) { in ns_prog_page()
1512 memset(ns->file_buf, 0xff, ns->geom.pgszoob); in ns_prog_page()
1515 tx = ns_read_file(ns, ns->cfile, pg_off, num, off); in ns_prog_page()
1517 NS_ERR("prog_page: read error for page %d ret %ld\n", ns->regs.row, (long)tx); in ns_prog_page()
1522 pg_off[i] &= ns->buf.byte[i]; in ns_prog_page()
1524 loff_t pos = (loff_t)ns->regs.row * ns->geom.pgszoob; in ns_prog_page()
1525 tx = ns_write_file(ns, ns->cfile, ns->file_buf, in ns_prog_page()
1526 ns->geom.pgszoob, pos); in ns_prog_page()
1527 if (tx != ns->geom.pgszoob) { in ns_prog_page()
1528 NS_ERR("prog_page: write error for page %d ret %ld\n", ns->regs.row, (long)tx); in ns_prog_page()
1531 __set_bit(ns->regs.row, ns->pages_written); in ns_prog_page()
1533 tx = ns_write_file(ns, ns->cfile, pg_off, num, off); in ns_prog_page()
1535 NS_ERR("prog_page: write error for page %d ret %ld\n", ns->regs.row, (long)tx); in ns_prog_page()
1542 mypage = NS_GET_PAGE(ns); in ns_prog_page()
1544 NS_DBG("prog_page: allocating page %d\n", ns->regs.row); in ns_prog_page()
1551 mypage->byte = kmem_cache_alloc(ns->nand_pages_slab, GFP_NOFS); in ns_prog_page()
1553 NS_ERR("prog_page: error allocating memory for page %d\n", ns->regs.row); in ns_prog_page()
1556 memset(mypage->byte, 0xFF, ns->geom.pgszoob); in ns_prog_page()
1559 pg_off = NS_PAGE_BYTE_OFF(ns); in ns_prog_page()
1561 pg_off[i] &= ns->buf.byte[i]; in ns_prog_page()
1571 static int ns_do_state_action(struct nandsim *ns, uint32_t action) in ns_do_state_action() argument
1574 int busdiv = ns->busw == 8 ? 1 : 2; in ns_do_state_action()
1580 if (action != ACTION_SECERASE && ns->regs.row >= ns->geom.pgnum) { in ns_do_state_action()
1581 NS_WARN("do_state_action: wrong page number (%#x)\n", ns->regs.row); in ns_do_state_action()
1593 if (ns->regs.column >= (ns->geom.pgszoob - ns->regs.off)) { in ns_do_state_action()
1597 num = ns->geom.pgszoob - NS_PAGE_BYTE_SHIFT(ns); in ns_do_state_action()
1598 ns_read_page(ns, num); in ns_do_state_action()
1601 num, NS_RAW_OFFSET(ns) + ns->regs.off); in ns_do_state_action()
1603 if (ns->regs.off == 0) in ns_do_state_action()
1604 NS_LOG("read page %d\n", ns->regs.row); in ns_do_state_action()
1605 else if (ns->regs.off < ns->geom.pgsz) in ns_do_state_action()
1606 NS_LOG("read page %d (second half)\n", ns->regs.row); in ns_do_state_action()
1608 NS_LOG("read OOB of page %d\n", ns->regs.row); in ns_do_state_action()
1611 NS_UDELAY(input_cycle * ns->geom.pgsz / 1000 / busdiv); in ns_do_state_action()
1620 if (ns->lines.wp) { in ns_do_state_action()
1625 if (ns->regs.row >= ns->geom.pgnum - ns->geom.pgsec in ns_do_state_action()
1626 || (ns->regs.row & ~(ns->geom.secsz - 1))) { in ns_do_state_action()
1627 NS_ERR("do_state_action: wrong sector address (%#x)\n", ns->regs.row); in ns_do_state_action()
1631 ns->regs.row = (ns->regs.row << in ns_do_state_action()
1632 8 * (ns->geom.pgaddrbytes - ns->geom.secaddrbytes)) | ns->regs.column; in ns_do_state_action()
1633 ns->regs.column = 0; in ns_do_state_action()
1635 erase_block_no = ns->regs.row >> (ns->geom.secshift - ns->geom.pgshift); in ns_do_state_action()
1638 ns->regs.row, NS_RAW_OFFSET(ns)); in ns_do_state_action()
1641 ns_erase_sector(ns); in ns_do_state_action()
1660 if (ns->lines.wp) { in ns_do_state_action()
1665 num = ns->geom.pgszoob - NS_PAGE_BYTE_SHIFT(ns); in ns_do_state_action()
1666 if (num != ns->regs.count) { in ns_do_state_action()
1668 ns->regs.count, num); in ns_do_state_action()
1672 if (ns_prog_page(ns, num) == -1) in ns_do_state_action()
1675 page_no = ns->regs.row; in ns_do_state_action()
1678 num, ns->regs.row, ns->regs.column, NS_RAW_OFFSET(ns) + ns->regs.off); in ns_do_state_action()
1679 NS_LOG("programm page %d\n", ns->regs.row); in ns_do_state_action()
1682 NS_UDELAY(output_cycle * ns->geom.pgsz / 1000 / busdiv); in ns_do_state_action()
1693 ns->regs.off = 0; in ns_do_state_action()
1697 if (!(ns->options & OPT_PAGE512_8BIT)) { in ns_do_state_action()
1702 NS_DBG("do_state_action: set internal offset to %d\n", ns->geom.pgsz/2); in ns_do_state_action()
1703 ns->regs.off = ns->geom.pgsz/2; in ns_do_state_action()
1707 NS_DBG("do_state_action: set internal offset to %d\n", ns->geom.pgsz); in ns_do_state_action()
1708 ns->regs.off = ns->geom.pgsz; in ns_do_state_action()
1721 static void ns_switch_state(struct nandsim *ns) in ns_switch_state() argument
1723 if (ns->op) { in ns_switch_state()
1729 ns->stateidx += 1; in ns_switch_state()
1730 ns->state = ns->nxstate; in ns_switch_state()
1731 ns->nxstate = ns->op[ns->stateidx + 1]; in ns_switch_state()
1735 ns_get_state_name(ns->state), in ns_switch_state()
1736 ns_get_state_name(ns->nxstate)); in ns_switch_state()
1747 ns->state = ns_get_state_by_command(ns->regs.command); in ns_switch_state()
1751 if (ns_find_operation(ns, 0)) in ns_switch_state()
1756 if ((ns->state & ACTION_MASK) && in ns_switch_state()
1757 ns_do_state_action(ns, ns->state) < 0) { in ns_switch_state()
1758 ns_switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); in ns_switch_state()
1763 if ((ns->nxstate & STATE_ADDR_MASK) && ns->busw == 16) { in ns_switch_state()
1765 ns->regs.column <<= 1; in ns_switch_state()
1768 if (NS_STATE(ns->nxstate) == STATE_READY) { in ns_switch_state()
1773 u_char status = NS_STATUS_OK(ns); in ns_switch_state()
1776 if ((ns->state & (STATE_DATAIN_MASK | STATE_DATAOUT_MASK)) in ns_switch_state()
1777 && ns->regs.count != ns->regs.num) { in ns_switch_state()
1779 ns->regs.num - ns->regs.count); in ns_switch_state()
1780 status = NS_STATUS_FAILED(ns); in ns_switch_state()
1785 ns_switch_to_ready_state(ns, status); in ns_switch_state()
1788 } else if (ns->nxstate & (STATE_DATAIN_MASK | STATE_DATAOUT_MASK)) { in ns_switch_state()
1793 ns->state = ns->nxstate; in ns_switch_state()
1794 ns->nxstate = ns->op[++ns->stateidx + 1]; in ns_switch_state()
1795 ns->regs.num = ns->regs.count = 0; in ns_switch_state()
1799 ns_get_state_name(ns->state), in ns_switch_state()
1800 ns_get_state_name(ns->nxstate)); in ns_switch_state()
1806 switch (NS_STATE(ns->state)) { in ns_switch_state()
1809 ns->regs.num = ns->geom.pgszoob - NS_PAGE_BYTE_SHIFT(ns); in ns_switch_state()
1813 ns->regs.num = ns->geom.idbytes; in ns_switch_state()
1817 ns->regs.count = ns->regs.num = 0; in ns_switch_state()
1824 } else if (ns->nxstate & STATE_ADDR_MASK) { in ns_switch_state()
1830 ns->regs.count = 0; in ns_switch_state()
1832 switch (NS_STATE(ns->nxstate)) { in ns_switch_state()
1834 ns->regs.num = ns->geom.pgaddrbytes; in ns_switch_state()
1838 ns->regs.num = ns->geom.secaddrbytes; in ns_switch_state()
1842 ns->regs.num = 1; in ns_switch_state()
1847 ns->regs.num = ns->geom.pgaddrbytes - ns->geom.secaddrbytes; in ns_switch_state()
1858 ns->regs.num = 0; in ns_switch_state()
1859 ns->regs.count = 0; in ns_switch_state()
1865 struct nandsim *ns = nand_get_controller_data(chip); in ns_nand_read_byte() local
1869 if (!ns->lines.ce) { in ns_nand_read_byte()
1873 if (ns->lines.ale || ns->lines.cle) { in ns_nand_read_byte()
1877 if (!(ns->state & STATE_DATAOUT_MASK)) { in ns_nand_read_byte()
1879 ns_get_state_name(ns->state), (uint)outb); in ns_nand_read_byte()
1884 if (NS_STATE(ns->state) == STATE_DATAOUT_STATUS) { in ns_nand_read_byte()
1885 NS_DBG("read_byte: return %#x status\n", ns->regs.status); in ns_nand_read_byte()
1886 return ns->regs.status; in ns_nand_read_byte()
1890 if (ns->regs.count == ns->regs.num) { in ns_nand_read_byte()
1895 switch (NS_STATE(ns->state)) { in ns_nand_read_byte()
1897 if (ns->busw == 8) { in ns_nand_read_byte()
1898 outb = ns->buf.byte[ns->regs.count]; in ns_nand_read_byte()
1899 ns->regs.count += 1; in ns_nand_read_byte()
1901 outb = (u_char)cpu_to_le16(ns->buf.word[ns->regs.count >> 1]); in ns_nand_read_byte()
1902 ns->regs.count += 2; in ns_nand_read_byte()
1906 NS_DBG("read_byte: read ID byte %d, total = %d\n", ns->regs.count, ns->regs.num); in ns_nand_read_byte()
1907 outb = ns->ids[ns->regs.count]; in ns_nand_read_byte()
1908 ns->regs.count += 1; in ns_nand_read_byte()
1914 if (ns->regs.count == ns->regs.num) { in ns_nand_read_byte()
1917 if (NS_STATE(ns->nxstate) == STATE_READY) in ns_nand_read_byte()
1918 ns_switch_state(ns); in ns_nand_read_byte()
1926 struct nandsim *ns = nand_get_controller_data(chip); in ns_nand_write_byte() local
1929 if (!ns->lines.ce) { in ns_nand_write_byte()
1933 if (ns->lines.ale && ns->lines.cle) { in ns_nand_write_byte()
1938 if (ns->lines.cle == 1) { in ns_nand_write_byte()
1945 ns_switch_to_ready_state(ns, NS_STATUS_OK(ns)); in ns_nand_write_byte()
1955 if (NS_STATE(ns->state) == STATE_DATAOUT_STATUS in ns_nand_write_byte()
1956 || NS_STATE(ns->state) == STATE_DATAOUT) { in ns_nand_write_byte()
1957 int row = ns->regs.row; in ns_nand_write_byte()
1959 ns_switch_state(ns); in ns_nand_write_byte()
1961 ns->regs.row = row; in ns_nand_write_byte()
1965 if (NS_STATE(ns->nxstate) != STATE_UNKNOWN && !(ns->nxstate & STATE_CMD_MASK)) { in ns_nand_write_byte()
1967 if (!(ns->regs.command == NAND_CMD_READID && in ns_nand_write_byte()
1968 NS_STATE(ns->state) == STATE_DATAOUT_ID && ns->regs.count == 2)) { in ns_nand_write_byte()
1976 ns_get_state_name(ns->nxstate)); in ns_nand_write_byte()
1978 ns_switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); in ns_nand_write_byte()
1983 ns->regs.command = byte; in ns_nand_write_byte()
1984 ns_switch_state(ns); in ns_nand_write_byte()
1986 } else if (ns->lines.ale == 1) { in ns_nand_write_byte()
1991 if (NS_STATE(ns->nxstate) == STATE_UNKNOWN) { in ns_nand_write_byte()
1995 if (ns_find_operation(ns, 1) < 0) in ns_nand_write_byte()
1998 if ((ns->state & ACTION_MASK) && in ns_nand_write_byte()
1999 ns_do_state_action(ns, ns->state) < 0) { in ns_nand_write_byte()
2000 ns_switch_to_ready_state(ns, in ns_nand_write_byte()
2001 NS_STATUS_FAILED(ns)); in ns_nand_write_byte()
2005 ns->regs.count = 0; in ns_nand_write_byte()
2006 switch (NS_STATE(ns->nxstate)) { in ns_nand_write_byte()
2008 ns->regs.num = ns->geom.pgaddrbytes; in ns_nand_write_byte()
2011 ns->regs.num = ns->geom.secaddrbytes; in ns_nand_write_byte()
2014 ns->regs.num = 1; in ns_nand_write_byte()
2022 if (!(ns->nxstate & STATE_ADDR_MASK)) { in ns_nand_write_byte()
2024 (uint)byte, ns_get_state_name(ns->nxstate)); in ns_nand_write_byte()
2025 ns_switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); in ns_nand_write_byte()
2030 if (ns->regs.count == ns->regs.num) { in ns_nand_write_byte()
2032 ns_switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); in ns_nand_write_byte()
2036 ns_accept_addr_byte(ns, byte); in ns_nand_write_byte()
2038 ns->regs.count += 1; in ns_nand_write_byte()
2041 (uint)byte, ns->regs.count, ns->regs.num); in ns_nand_write_byte()
2043 if (ns->regs.count == ns->regs.num) { in ns_nand_write_byte()
2044 NS_DBG("address (%#x, %#x) is accepted\n", ns->regs.row, ns->regs.column); in ns_nand_write_byte()
2045 ns_switch_state(ns); in ns_nand_write_byte()
2054 if (!(ns->state & STATE_DATAIN_MASK)) { in ns_nand_write_byte()
2056 (uint)byte, ns_get_state_name(ns->state), in ns_nand_write_byte()
2058 ns_switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); in ns_nand_write_byte()
2063 if (ns->regs.count == ns->regs.num) { in ns_nand_write_byte()
2065 ns->regs.num); in ns_nand_write_byte()
2069 if (ns->busw == 8) { in ns_nand_write_byte()
2070 ns->buf.byte[ns->regs.count] = byte; in ns_nand_write_byte()
2071 ns->regs.count += 1; in ns_nand_write_byte()
2073 ns->buf.word[ns->regs.count >> 1] = cpu_to_le16((uint16_t)byte); in ns_nand_write_byte()
2074 ns->regs.count += 2; in ns_nand_write_byte()
2084 struct nandsim *ns = nand_get_controller_data(chip); in ns_nand_write_buf() local
2087 if (!(ns->state & STATE_DATAIN_MASK)) { in ns_nand_write_buf()
2089 ns_get_state_name(ns->state)); in ns_nand_write_buf()
2090 ns_switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); in ns_nand_write_buf()
2095 if (ns->regs.count + len > ns->regs.num) { in ns_nand_write_buf()
2097 ns_switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); in ns_nand_write_buf()
2101 memcpy(ns->buf.byte + ns->regs.count, buf, len); in ns_nand_write_buf()
2102 ns->regs.count += len; in ns_nand_write_buf()
2104 if (ns->regs.count == ns->regs.num) { in ns_nand_write_buf()
2105 NS_DBG("write_buf: %d bytes were written\n", ns->regs.count); in ns_nand_write_buf()
2111 struct nandsim *ns = nand_get_controller_data(chip); in ns_nand_read_buf() local
2114 if (!ns->lines.ce) { in ns_nand_read_buf()
2118 if (ns->lines.ale || ns->lines.cle) { in ns_nand_read_buf()
2122 if (!(ns->state & STATE_DATAOUT_MASK)) { in ns_nand_read_buf()
2124 ns_get_state_name(ns->state)); in ns_nand_read_buf()
2128 if (NS_STATE(ns->state) != STATE_DATAOUT) { in ns_nand_read_buf()
2138 if (ns->regs.count + len > ns->regs.num) { in ns_nand_read_buf()
2140 ns_switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); in ns_nand_read_buf()
2144 memcpy(buf, ns->buf.byte + ns->regs.count, len); in ns_nand_read_buf()
2145 ns->regs.count += len; in ns_nand_read_buf()
2147 if (ns->regs.count == ns->regs.num) { in ns_nand_read_buf()
2148 if (NS_STATE(ns->nxstate) == STATE_READY) in ns_nand_read_buf()
2149 ns_switch_state(ns); in ns_nand_read_buf()
2161 struct nandsim *ns = nand_get_controller_data(chip); in ns_exec_op() local
2166 ns->lines.ce = 1; in ns_exec_op()
2170 ns->lines.cle = 0; in ns_exec_op()
2171 ns->lines.ale = 0; in ns_exec_op()
2175 ns->lines.cle = 1; in ns_exec_op()
2179 ns->lines.ale = 1; in ns_exec_op()
2249 struct nandsim *ns; in ns_init_module() local
2257 ns = kzalloc(sizeof(struct nandsim), GFP_KERNEL); in ns_init_module()
2258 if (!ns) { in ns_init_module()
2262 chip = &ns->chip; in ns_init_module()
2264 nand_set_controller_data(chip, (void *)ns); in ns_init_module()
2289 ns->geom.idbytes = 8; in ns_init_module()
2291 ns->geom.idbytes = 6; in ns_init_module()
2293 ns->geom.idbytes = 4; in ns_init_module()
2295 ns->geom.idbytes = 2; in ns_init_module()
2296 ns->regs.status = NS_STATUS_OK(ns); in ns_init_module()
2297 ns->nxstate = STATE_UNKNOWN; in ns_init_module()
2298 ns->options |= OPT_PAGE512; /* temporary value */ in ns_init_module()
2299 memcpy(ns->ids, id_bytes, sizeof(ns->ids)); in ns_init_module()
2301 ns->busw = 16; in ns_init_module()
2319 nand_controller_init(&ns->base); in ns_init_module()
2320 ns->base.ops = &ns_controller_ops; in ns_init_module()
2321 chip->controller = &ns->base; in ns_init_module()
2362 ret = ns_parse_badblocks(ns, nsmtd); in ns_init_module()
2367 ret = mtd_device_register(nsmtd, &ns->partitions[0], ns->nbparts); in ns_init_module()
2371 ret = ns_debugfs_create(ns); in ns_init_module()
2380 ns_free(ns); in ns_init_module()
2401 kfree(ns); in ns_init_module()
2414 struct nandsim *ns = nand_get_controller_data(chip); in ns_cleanup_module() local
2417 ns_debugfs_remove(ns); in ns_cleanup_module()
2419 ns_free(ns); in ns_cleanup_module()
2438 kfree(ns); in ns_cleanup_module()