diff options
Diffstat (limited to 'drivers/mtd/nand/nandsim.c')
-rw-r--r-- | drivers/mtd/nand/nandsim.c | 243 |
1 files changed, 158 insertions, 85 deletions
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index 545ff252d81e..c3bca9590ad2 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c | |||
@@ -37,10 +37,6 @@ | |||
37 | #include <linux/mtd/nand.h> | 37 | #include <linux/mtd/nand.h> |
38 | #include <linux/mtd/partitions.h> | 38 | #include <linux/mtd/partitions.h> |
39 | #include <linux/delay.h> | 39 | #include <linux/delay.h> |
40 | #ifdef CONFIG_NS_ABS_POS | ||
41 | #include <asm/io.h> | ||
42 | #endif | ||
43 | |||
44 | 40 | ||
45 | /* Default simulator parameters values */ | 41 | /* Default simulator parameters values */ |
46 | #if !defined(CONFIG_NANDSIM_FIRST_ID_BYTE) || \ | 42 | #if !defined(CONFIG_NANDSIM_FIRST_ID_BYTE) || \ |
@@ -164,7 +160,7 @@ MODULE_PARM_DESC(dbg, "Output debug information if not zero"); | |||
164 | /* After a command is input, the simulator goes to one of the following states */ | 160 | /* After a command is input, the simulator goes to one of the following states */ |
165 | #define STATE_CMD_READ0 0x00000001 /* read data from the beginning of page */ | 161 | #define STATE_CMD_READ0 0x00000001 /* read data from the beginning of page */ |
166 | #define STATE_CMD_READ1 0x00000002 /* read data from the second half of page */ | 162 | #define STATE_CMD_READ1 0x00000002 /* read data from the second half of page */ |
167 | #define STATE_CMD_READSTART 0x00000003 /* read data second command (large page devices) */ | 163 | #define STATE_CMD_READSTART 0x00000003 /* read data second command (large page devices) */ |
168 | #define STATE_CMD_PAGEPROG 0x00000004 /* start page programm */ | 164 | #define STATE_CMD_PAGEPROG 0x00000004 /* start page programm */ |
169 | #define STATE_CMD_READOOB 0x00000005 /* read OOB area */ | 165 | #define STATE_CMD_READOOB 0x00000005 /* read OOB area */ |
170 | #define STATE_CMD_ERASE1 0x00000006 /* sector erase first command */ | 166 | #define STATE_CMD_ERASE1 0x00000006 /* sector erase first command */ |
@@ -231,6 +227,14 @@ MODULE_PARM_DESC(dbg, "Output debug information if not zero"); | |||
231 | #define NS_MAX_PREVSTATES 1 | 227 | #define NS_MAX_PREVSTATES 1 |
232 | 228 | ||
233 | /* | 229 | /* |
230 | * A union to represent flash memory contents and flash buffer. | ||
231 | */ | ||
232 | union ns_mem { | ||
233 | u_char *byte; /* for byte access */ | ||
234 | uint16_t *word; /* for 16-bit word access */ | ||
235 | }; | ||
236 | |||
237 | /* | ||
234 | * The structure which describes all the internal simulator data. | 238 | * The structure which describes all the internal simulator data. |
235 | */ | 239 | */ |
236 | struct nandsim { | 240 | struct nandsim { |
@@ -247,17 +251,11 @@ struct nandsim { | |||
247 | uint16_t npstates; /* number of previous states saved */ | 251 | uint16_t npstates; /* number of previous states saved */ |
248 | uint16_t stateidx; /* current state index */ | 252 | uint16_t stateidx; /* current state index */ |
249 | 253 | ||
250 | /* The simulated NAND flash image */ | 254 | /* The simulated NAND flash pages array */ |
251 | union flash_media { | 255 | union ns_mem *pages; |
252 | u_char *byte; | ||
253 | uint16_t *word; | ||
254 | } mem; | ||
255 | 256 | ||
256 | /* Internal buffer of page + OOB size bytes */ | 257 | /* Internal buffer of page + OOB size bytes */ |
257 | union internal_buffer { | 258 | union ns_mem buf; |
258 | u_char *byte; /* for byte access */ | ||
259 | uint16_t *word; /* for 16-bit word access */ | ||
260 | } buf; | ||
261 | 259 | ||
262 | /* NAND flash "geometry" */ | 260 | /* NAND flash "geometry" */ |
263 | struct nandsin_geometry { | 261 | struct nandsin_geometry { |
@@ -346,12 +344,49 @@ static struct mtd_info *nsmtd; | |||
346 | static u_char ns_verify_buf[NS_LARGEST_PAGE_SIZE]; | 344 | static u_char ns_verify_buf[NS_LARGEST_PAGE_SIZE]; |
347 | 345 | ||
348 | /* | 346 | /* |
347 | * Allocate array of page pointers and initialize the array to NULL | ||
348 | * pointers. | ||
349 | * | ||
350 | * RETURNS: 0 if success, -ENOMEM if memory alloc fails. | ||
351 | */ | ||
352 | static int alloc_device(struct nandsim *ns) | ||
353 | { | ||
354 | int i; | ||
355 | |||
356 | ns->pages = vmalloc(ns->geom.pgnum * sizeof(union ns_mem)); | ||
357 | if (!ns->pages) { | ||
358 | NS_ERR("alloc_map: unable to allocate page array\n"); | ||
359 | return -ENOMEM; | ||
360 | } | ||
361 | for (i = 0; i < ns->geom.pgnum; i++) { | ||
362 | ns->pages[i].byte = NULL; | ||
363 | } | ||
364 | |||
365 | return 0; | ||
366 | } | ||
367 | |||
368 | /* | ||
369 | * Free any allocated pages, and free the array of page pointers. | ||
370 | */ | ||
371 | static void free_device(struct nandsim *ns) | ||
372 | { | ||
373 | int i; | ||
374 | |||
375 | if (ns->pages) { | ||
376 | for (i = 0; i < ns->geom.pgnum; i++) { | ||
377 | if (ns->pages[i].byte) | ||
378 | kfree(ns->pages[i].byte); | ||
379 | } | ||
380 | vfree(ns->pages); | ||
381 | } | ||
382 | } | ||
383 | |||
384 | /* | ||
349 | * Initialize the nandsim structure. | 385 | * Initialize the nandsim structure. |
350 | * | 386 | * |
351 | * RETURNS: 0 if success, -ERRNO if failure. | 387 | * RETURNS: 0 if success, -ERRNO if failure. |
352 | */ | 388 | */ |
353 | static int | 389 | static int init_nandsim(struct mtd_info *mtd) |
354 | init_nandsim(struct mtd_info *mtd) | ||
355 | { | 390 | { |
356 | struct nand_chip *chip = (struct nand_chip *)mtd->priv; | 391 | struct nand_chip *chip = (struct nand_chip *)mtd->priv; |
357 | struct nandsim *ns = (struct nandsim *)(chip->priv); | 392 | struct nandsim *ns = (struct nandsim *)(chip->priv); |
@@ -405,7 +440,7 @@ init_nandsim(struct mtd_info *mtd) | |||
405 | } | 440 | } |
406 | } else { | 441 | } else { |
407 | if (ns->geom.totsz <= (128 << 20)) { | 442 | if (ns->geom.totsz <= (128 << 20)) { |
408 | ns->geom.pgaddrbytes = 5; | 443 | ns->geom.pgaddrbytes = 4; |
409 | ns->geom.secaddrbytes = 2; | 444 | ns->geom.secaddrbytes = 2; |
410 | } else { | 445 | } else { |
411 | ns->geom.pgaddrbytes = 5; | 446 | ns->geom.pgaddrbytes = 5; |
@@ -439,23 +474,8 @@ init_nandsim(struct mtd_info *mtd) | |||
439 | printk("sector address bytes: %u\n", ns->geom.secaddrbytes); | 474 | printk("sector address bytes: %u\n", ns->geom.secaddrbytes); |
440 | printk("options: %#x\n", ns->options); | 475 | printk("options: %#x\n", ns->options); |
441 | 476 | ||
442 | /* Map / allocate and initialize the flash image */ | 477 | if (alloc_device(ns) != 0) |
443 | #ifdef CONFIG_NS_ABS_POS | 478 | goto error; |
444 | ns->mem.byte = ioremap(CONFIG_NS_ABS_POS, ns->geom.totszoob); | ||
445 | if (!ns->mem.byte) { | ||
446 | NS_ERR("init_nandsim: failed to map the NAND flash image at address %p\n", | ||
447 | (void *)CONFIG_NS_ABS_POS); | ||
448 | return -ENOMEM; | ||
449 | } | ||
450 | #else | ||
451 | ns->mem.byte = vmalloc(ns->geom.totszoob); | ||
452 | if (!ns->mem.byte) { | ||
453 | NS_ERR("init_nandsim: unable to allocate %u bytes for flash image\n", | ||
454 | ns->geom.totszoob); | ||
455 | return -ENOMEM; | ||
456 | } | ||
457 | memset(ns->mem.byte, 0xFF, ns->geom.totszoob); | ||
458 | #endif | ||
459 | 479 | ||
460 | /* Allocate / initialize the internal buffer */ | 480 | /* Allocate / initialize the internal buffer */ |
461 | ns->buf.byte = kmalloc(ns->geom.pgszoob, GFP_KERNEL); | 481 | ns->buf.byte = kmalloc(ns->geom.pgszoob, GFP_KERNEL); |
@@ -474,11 +494,7 @@ init_nandsim(struct mtd_info *mtd) | |||
474 | return 0; | 494 | return 0; |
475 | 495 | ||
476 | error: | 496 | error: |
477 | #ifdef CONFIG_NS_ABS_POS | 497 | free_device(ns); |
478 | iounmap(ns->mem.byte); | ||
479 | #else | ||
480 | vfree(ns->mem.byte); | ||
481 | #endif | ||
482 | 498 | ||
483 | return -ENOMEM; | 499 | return -ENOMEM; |
484 | } | 500 | } |
@@ -486,16 +502,10 @@ error: | |||
486 | /* | 502 | /* |
487 | * Free the nandsim structure. | 503 | * Free the nandsim structure. |
488 | */ | 504 | */ |
489 | static void | 505 | static void free_nandsim(struct nandsim *ns) |
490 | free_nandsim(struct nandsim *ns) | ||
491 | { | 506 | { |
492 | kfree(ns->buf.byte); | 507 | kfree(ns->buf.byte); |
493 | 508 | free_device(ns); | |
494 | #ifdef CONFIG_NS_ABS_POS | ||
495 | iounmap(ns->mem.byte); | ||
496 | #else | ||
497 | vfree(ns->mem.byte); | ||
498 | #endif | ||
499 | 509 | ||
500 | return; | 510 | return; |
501 | } | 511 | } |
@@ -503,8 +513,7 @@ free_nandsim(struct nandsim *ns) | |||
503 | /* | 513 | /* |
504 | * Returns the string representation of 'state' state. | 514 | * Returns the string representation of 'state' state. |
505 | */ | 515 | */ |
506 | static char * | 516 | static char *get_state_name(uint32_t state) |
507 | get_state_name(uint32_t state) | ||
508 | { | 517 | { |
509 | switch (NS_STATE(state)) { | 518 | switch (NS_STATE(state)) { |
510 | case STATE_CMD_READ0: | 519 | case STATE_CMD_READ0: |
@@ -562,8 +571,7 @@ get_state_name(uint32_t state) | |||
562 | * | 571 | * |
563 | * RETURNS: 1 if wrong command, 0 if right. | 572 | * RETURNS: 1 if wrong command, 0 if right. |
564 | */ | 573 | */ |
565 | static int | 574 | static int check_command(int cmd) |
566 | check_command(int cmd) | ||
567 | { | 575 | { |
568 | switch (cmd) { | 576 | switch (cmd) { |
569 | 577 | ||
@@ -589,8 +597,7 @@ check_command(int cmd) | |||
589 | /* | 597 | /* |
590 | * Returns state after command is accepted by command number. | 598 | * Returns state after command is accepted by command number. |
591 | */ | 599 | */ |
592 | static uint32_t | 600 | static uint32_t get_state_by_command(unsigned command) |
593 | get_state_by_command(unsigned command) | ||
594 | { | 601 | { |
595 | switch (command) { | 602 | switch (command) { |
596 | case NAND_CMD_READ0: | 603 | case NAND_CMD_READ0: |
@@ -626,8 +633,7 @@ get_state_by_command(unsigned command) | |||
626 | /* | 633 | /* |
627 | * Move an address byte to the correspondent internal register. | 634 | * Move an address byte to the correspondent internal register. |
628 | */ | 635 | */ |
629 | static inline void | 636 | static inline void accept_addr_byte(struct nandsim *ns, u_char bt) |
630 | accept_addr_byte(struct nandsim *ns, u_char bt) | ||
631 | { | 637 | { |
632 | uint byte = (uint)bt; | 638 | uint byte = (uint)bt; |
633 | 639 | ||
@@ -645,8 +651,7 @@ accept_addr_byte(struct nandsim *ns, u_char bt) | |||
645 | /* | 651 | /* |
646 | * Switch to STATE_READY state. | 652 | * Switch to STATE_READY state. |
647 | */ | 653 | */ |
648 | static inline void | 654 | static inline void switch_to_ready_state(struct nandsim *ns, u_char status) |
649 | switch_to_ready_state(struct nandsim *ns, u_char status) | ||
650 | { | 655 | { |
651 | NS_DBG("switch_to_ready_state: switch to %s state\n", get_state_name(STATE_READY)); | 656 | NS_DBG("switch_to_ready_state: switch to %s state\n", get_state_name(STATE_READY)); |
652 | 657 | ||
@@ -705,8 +710,7 @@ switch_to_ready_state(struct nandsim *ns, u_char status) | |||
705 | * -1 - several matches. | 710 | * -1 - several matches. |
706 | * 0 - operation is found. | 711 | * 0 - operation is found. |
707 | */ | 712 | */ |
708 | static int | 713 | static int find_operation(struct nandsim *ns, uint32_t flag) |
709 | find_operation(struct nandsim *ns, uint32_t flag) | ||
710 | { | 714 | { |
711 | int opsfound = 0; | 715 | int opsfound = 0; |
712 | int i, j, idx = 0; | 716 | int i, j, idx = 0; |
@@ -791,14 +795,93 @@ find_operation(struct nandsim *ns, uint32_t flag) | |||
791 | } | 795 | } |
792 | 796 | ||
793 | /* | 797 | /* |
798 | * Returns a pointer to the current page. | ||
799 | */ | ||
800 | static inline union ns_mem *NS_GET_PAGE(struct nandsim *ns) | ||
801 | { | ||
802 | return &(ns->pages[ns->regs.row]); | ||
803 | } | ||
804 | |||
805 | /* | ||
806 | * Retuns a pointer to the current byte, within the current page. | ||
807 | */ | ||
808 | static inline u_char *NS_PAGE_BYTE_OFF(struct nandsim *ns) | ||
809 | { | ||
810 | return NS_GET_PAGE(ns)->byte + ns->regs.column + ns->regs.off; | ||
811 | } | ||
812 | |||
813 | /* | ||
814 | * Fill the NAND buffer with data read from the specified page. | ||
815 | */ | ||
816 | static void read_page(struct nandsim *ns, int num) | ||
817 | { | ||
818 | union ns_mem *mypage; | ||
819 | |||
820 | mypage = NS_GET_PAGE(ns); | ||
821 | if (mypage->byte == NULL) { | ||
822 | NS_DBG("read_page: page %d not allocated\n", ns->regs.row); | ||
823 | memset(ns->buf.byte, 0xFF, num); | ||
824 | } else { | ||
825 | NS_DBG("read_page: page %d allocated, reading from %d\n", | ||
826 | ns->regs.row, ns->regs.column + ns->regs.off); | ||
827 | memcpy(ns->buf.byte, NS_PAGE_BYTE_OFF(ns), num); | ||
828 | } | ||
829 | } | ||
830 | |||
831 | /* | ||
832 | * Erase all pages in the specified sector. | ||
833 | */ | ||
834 | static void erase_sector(struct nandsim *ns) | ||
835 | { | ||
836 | union ns_mem *mypage; | ||
837 | int i; | ||
838 | |||
839 | mypage = NS_GET_PAGE(ns); | ||
840 | for (i = 0; i < ns->geom.pgsec; i++) { | ||
841 | if (mypage->byte != NULL) { | ||
842 | NS_DBG("erase_sector: freeing page %d\n", ns->regs.row+i); | ||
843 | kfree(mypage->byte); | ||
844 | mypage->byte = NULL; | ||
845 | } | ||
846 | mypage++; | ||
847 | } | ||
848 | } | ||
849 | |||
850 | /* | ||
851 | * Program the specified page with the contents from the NAND buffer. | ||
852 | */ | ||
853 | static int prog_page(struct nandsim *ns, int num) | ||
854 | { | ||
855 | int i; | ||
856 | union ns_mem *mypage; | ||
857 | u_char *pg_off; | ||
858 | |||
859 | mypage = NS_GET_PAGE(ns); | ||
860 | if (mypage->byte == NULL) { | ||
861 | NS_DBG("prog_page: allocating page %d\n", ns->regs.row); | ||
862 | mypage->byte = kmalloc(ns->geom.pgszoob, GFP_KERNEL); | ||
863 | if (mypage->byte == NULL) { | ||
864 | NS_ERR("prog_page: error allocating memory for page %d\n", ns->regs.row); | ||
865 | return -1; | ||
866 | } | ||
867 | memset(mypage->byte, 0xFF, ns->geom.pgszoob); | ||
868 | } | ||
869 | |||
870 | pg_off = NS_PAGE_BYTE_OFF(ns); | ||
871 | for (i = 0; i < num; i++) | ||
872 | pg_off[i] &= ns->buf.byte[i]; | ||
873 | |||
874 | return 0; | ||
875 | } | ||
876 | |||
877 | /* | ||
794 | * If state has any action bit, perform this action. | 878 | * If state has any action bit, perform this action. |
795 | * | 879 | * |
796 | * RETURNS: 0 if success, -1 if error. | 880 | * RETURNS: 0 if success, -1 if error. |
797 | */ | 881 | */ |
798 | static int | 882 | static int do_state_action(struct nandsim *ns, uint32_t action) |
799 | do_state_action(struct nandsim *ns, uint32_t action) | ||
800 | { | 883 | { |
801 | int i, num; | 884 | int num; |
802 | int busdiv = ns->busw == 8 ? 1 : 2; | 885 | int busdiv = ns->busw == 8 ? 1 : 2; |
803 | 886 | ||
804 | action &= ACTION_MASK; | 887 | action &= ACTION_MASK; |
@@ -822,7 +905,7 @@ do_state_action(struct nandsim *ns, uint32_t action) | |||
822 | break; | 905 | break; |
823 | } | 906 | } |
824 | num = ns->geom.pgszoob - ns->regs.off - ns->regs.column; | 907 | num = ns->geom.pgszoob - ns->regs.off - ns->regs.column; |
825 | memcpy(ns->buf.byte, ns->mem.byte + NS_RAW_OFFSET(ns) + ns->regs.off, num); | 908 | read_page(ns, num); |
826 | 909 | ||
827 | NS_DBG("do_state_action: (ACTION_CPY:) copy %d bytes to int buf, raw offset %d\n", | 910 | NS_DBG("do_state_action: (ACTION_CPY:) copy %d bytes to int buf, raw offset %d\n", |
828 | num, NS_RAW_OFFSET(ns) + ns->regs.off); | 911 | num, NS_RAW_OFFSET(ns) + ns->regs.off); |
@@ -863,7 +946,7 @@ do_state_action(struct nandsim *ns, uint32_t action) | |||
863 | ns->regs.row, NS_RAW_OFFSET(ns)); | 946 | ns->regs.row, NS_RAW_OFFSET(ns)); |
864 | NS_LOG("erase sector %d\n", ns->regs.row >> (ns->geom.secshift - ns->geom.pgshift)); | 947 | NS_LOG("erase sector %d\n", ns->regs.row >> (ns->geom.secshift - ns->geom.pgshift)); |
865 | 948 | ||
866 | memset(ns->mem.byte + NS_RAW_OFFSET(ns), 0xFF, ns->geom.secszoob); | 949 | erase_sector(ns); |
867 | 950 | ||
868 | NS_MDELAY(erase_delay); | 951 | NS_MDELAY(erase_delay); |
869 | 952 | ||
@@ -886,8 +969,8 @@ do_state_action(struct nandsim *ns, uint32_t action) | |||
886 | return -1; | 969 | return -1; |
887 | } | 970 | } |
888 | 971 | ||
889 | for (i = 0; i < num; i++) | 972 | if (prog_page(ns, num) == -1) |
890 | ns->mem.byte[NS_RAW_OFFSET(ns) + ns->regs.off + i] &= ns->buf.byte[i]; | 973 | return -1; |
891 | 974 | ||
892 | NS_DBG("do_state_action: copy %d bytes from int buf to (%#x, %#x), raw off = %d\n", | 975 | NS_DBG("do_state_action: copy %d bytes from int buf to (%#x, %#x), raw off = %d\n", |
893 | num, ns->regs.row, ns->regs.column, NS_RAW_OFFSET(ns) + ns->regs.off); | 976 | num, ns->regs.row, ns->regs.column, NS_RAW_OFFSET(ns) + ns->regs.off); |
@@ -928,8 +1011,7 @@ do_state_action(struct nandsim *ns, uint32_t action) | |||
928 | /* | 1011 | /* |
929 | * Switch simulator's state. | 1012 | * Switch simulator's state. |
930 | */ | 1013 | */ |
931 | static void | 1014 | static void switch_state(struct nandsim *ns) |
932 | switch_state(struct nandsim *ns) | ||
933 | { | 1015 | { |
934 | if (ns->op) { | 1016 | if (ns->op) { |
935 | /* | 1017 | /* |
@@ -1070,8 +1152,7 @@ switch_state(struct nandsim *ns) | |||
1070 | } | 1152 | } |
1071 | } | 1153 | } |
1072 | 1154 | ||
1073 | static u_char | 1155 | static u_char ns_nand_read_byte(struct mtd_info *mtd) |
1074 | ns_nand_read_byte(struct mtd_info *mtd) | ||
1075 | { | 1156 | { |
1076 | struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; | 1157 | struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; |
1077 | u_char outb = 0x00; | 1158 | u_char outb = 0x00; |
@@ -1144,8 +1225,7 @@ ns_nand_read_byte(struct mtd_info *mtd) | |||
1144 | return outb; | 1225 | return outb; |
1145 | } | 1226 | } |
1146 | 1227 | ||
1147 | static void | 1228 | static void ns_nand_write_byte(struct mtd_info *mtd, u_char byte) |
1148 | ns_nand_write_byte(struct mtd_info *mtd, u_char byte) | ||
1149 | { | 1229 | { |
1150 | struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; | 1230 | struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; |
1151 | 1231 | ||
@@ -1308,15 +1388,13 @@ static void ns_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int bitmask) | |||
1308 | ns_nand_write_byte(mtd, cmd); | 1388 | ns_nand_write_byte(mtd, cmd); |
1309 | } | 1389 | } |
1310 | 1390 | ||
1311 | static int | 1391 | static int ns_device_ready(struct mtd_info *mtd) |
1312 | ns_device_ready(struct mtd_info *mtd) | ||
1313 | { | 1392 | { |
1314 | NS_DBG("device_ready\n"); | 1393 | NS_DBG("device_ready\n"); |
1315 | return 1; | 1394 | return 1; |
1316 | } | 1395 | } |
1317 | 1396 | ||
1318 | static uint16_t | 1397 | static uint16_t ns_nand_read_word(struct mtd_info *mtd) |
1319 | ns_nand_read_word(struct mtd_info *mtd) | ||
1320 | { | 1398 | { |
1321 | struct nand_chip *chip = (struct nand_chip *)mtd->priv; | 1399 | struct nand_chip *chip = (struct nand_chip *)mtd->priv; |
1322 | 1400 | ||
@@ -1325,8 +1403,7 @@ ns_nand_read_word(struct mtd_info *mtd) | |||
1325 | return chip->read_byte(mtd) | (chip->read_byte(mtd) << 8); | 1403 | return chip->read_byte(mtd) | (chip->read_byte(mtd) << 8); |
1326 | } | 1404 | } |
1327 | 1405 | ||
1328 | static void | 1406 | static void ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) |
1329 | ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) | ||
1330 | { | 1407 | { |
1331 | struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; | 1408 | struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; |
1332 | 1409 | ||
@@ -1353,8 +1430,7 @@ ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) | |||
1353 | } | 1430 | } |
1354 | } | 1431 | } |
1355 | 1432 | ||
1356 | static void | 1433 | static void ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) |
1357 | ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) | ||
1358 | { | 1434 | { |
1359 | struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; | 1435 | struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; |
1360 | 1436 | ||
@@ -1407,8 +1483,7 @@ ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) | |||
1407 | return; | 1483 | return; |
1408 | } | 1484 | } |
1409 | 1485 | ||
1410 | static int | 1486 | static int ns_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) |
1411 | ns_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) | ||
1412 | { | 1487 | { |
1413 | ns_nand_read_buf(mtd, (u_char *)&ns_verify_buf[0], len); | 1488 | ns_nand_read_buf(mtd, (u_char *)&ns_verify_buf[0], len); |
1414 | 1489 | ||
@@ -1436,14 +1511,12 @@ static int __init ns_init_module(void) | |||
1436 | } | 1511 | } |
1437 | 1512 | ||
1438 | /* Allocate and initialize mtd_info, nand_chip and nandsim structures */ | 1513 | /* Allocate and initialize mtd_info, nand_chip and nandsim structures */ |
1439 | nsmtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip) | 1514 | nsmtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip) |
1440 | + sizeof(struct nandsim), GFP_KERNEL); | 1515 | + sizeof(struct nandsim), GFP_KERNEL); |
1441 | if (!nsmtd) { | 1516 | if (!nsmtd) { |
1442 | NS_ERR("unable to allocate core structures.\n"); | 1517 | NS_ERR("unable to allocate core structures.\n"); |
1443 | return -ENOMEM; | 1518 | return -ENOMEM; |
1444 | } | 1519 | } |
1445 | memset(nsmtd, 0, sizeof(struct mtd_info) + sizeof(struct nand_chip) + | ||
1446 | sizeof(struct nandsim)); | ||
1447 | chip = (struct nand_chip *)(nsmtd + 1); | 1520 | chip = (struct nand_chip *)(nsmtd + 1); |
1448 | nsmtd->priv = (void *)chip; | 1521 | nsmtd->priv = (void *)chip; |
1449 | nand = (struct nandsim *)(chip + 1); | 1522 | nand = (struct nandsim *)(chip + 1); |