···192 struct onenand_chip *this = mtd->priv;193 int value, readcmd = 0, block_cmd = 0;194 int block, page;195- /* Now we use page size operation */196- int sectors = 4, count = 4;197198 /* Address translation */199 switch (cmd) {···243 }244245 if (page != -1) {00246 int dataram;247248 switch (cmd) {···298 unsigned long timeout;299 unsigned int flags = ONENAND_INT_MASTER;300 unsigned int interrupt = 0;301- unsigned int ctrl, ecc;302303 /* The 20 msec is enough */304 timeout = jiffies + msecs_to_jiffies(20);···310311 if (state != FL_READING)312 cond_resched();313- touch_softlockup_watchdog();314 }315 /* To get correct interrupt status in timeout case */316 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);···317 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);318319 if (ctrl & ONENAND_CTRL_ERROR) {320- /* It maybe occur at initial bad block */321 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: controller error = 0x%04x\n", ctrl);322- /* Clear other interrupt bits for preventing ECC error */323- interrupt &= ONENAND_INT_MASTER;324- }325-326- if (ctrl & ONENAND_CTRL_LOCK) {327- DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: it's locked error = 0x%04x\n", ctrl);328- return -EACCES;329 }330331 if (interrupt & ONENAND_INT_READ) {332- ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS);333 if (ecc) {334 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: ECC error = 0x%04x\n", ecc);335- if (ecc & ONENAND_ECC_2BIT_ALL)336 mtd->ecc_stats.failed++;337- else if (ecc & ONENAND_ECC_1BIT_ALL)0338 mtd->ecc_stats.corrected++;339 }340 }···367{368 struct onenand_chip *this = mtd->priv;369370- /* To prevent soft lockup */371- touch_softlockup_watchdog();372-373 wait_for_completion(&this->complete);374375 return onenand_wait(mtd, state);···386387 /* We use interrupt wait first */388 this->wait = onenand_interrupt_wait;389-390- /* To prevent soft lockup */391- touch_softlockup_watchdog();392393 timeout = msecs_to_jiffies(100);394 remain = wait_for_completion_timeout(&this->complete, timeout);···710 struct mtd_ecc_stats stats;711 int read = 0, column;712 int thislen;713- int ret = 0;714715 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);716···727 /* TODO handling oob */728729 stats = mtd->ecc_stats;730- while (read < len) {731- thislen = min_t(int, mtd->writesize, len - read);732733- column = from & (mtd->writesize - 1);734- if (column + thislen > mtd->writesize)735- thislen = mtd->writesize - column;736737- if (!onenand_check_bufferram(mtd, from)) {738- this->command(mtd, ONENAND_CMD_READ, from, mtd->writesize);000000739740- ret = this->wait(mtd, FL_READING);741- /* First copy data and check return value for ECC handling */742- onenand_update_bufferram(mtd, from, 1);743- }744745- this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen);00000000000000000000000000000000000746747- read += thislen;748-749- if (read == len)750- break;751-752- if (ret) {753- DEBUG(MTD_DEBUG_LEVEL0, "onenand_read: read failed = %d\n", ret);754- goto out;755- }756-757- from += thislen;758- buf += thislen;759- }760-761-out:762 /* Deselect and wake up anyone waiting on the device */763 onenand_release_device(mtd);764···793794 if (mtd->ecc_stats.failed - stats.failed)795 return -EBADMSG;000796797 return mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;798}···834 column = from & (mtd->oobsize - 1);835836 while (read < len) {00837 thislen = mtd->oobsize - column;838 thislen = min_t(int, thislen, len);839···848849 this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);85000000851 read += thislen;852853 if (read == len)854 break;855-856- if (ret) {857- DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_oob: read failed = %d\n", ret);858- goto out;859- }860861 buf += thislen;862···935 void __iomem *dataram0, *dataram1;936 int ret = 0;9370000938 this->command(mtd, ONENAND_CMD_READ, addr, mtd->writesize);939940 ret = this->wait(mtd, FL_READING);···961#define onenand_verify_oob(...) (0)962#endif963964-#define NOTALIGNED(x) ((x & (mtd->writesize - 1)) != 0)965966/**967 * onenand_write - [MTD Interface] write buffer to FLASH···979 struct onenand_chip *this = mtd->priv;980 int written = 0;981 int ret = 0;0982983 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);984···998 return -EINVAL;999 }10000001001 /* Grab the lock and see if the device is available */1002 onenand_get_device(mtd, FL_WRITING);10031004 /* Loop until all data write */1005 while (written < len) {1006- int thislen = min_t(int, mtd->writesize, len - written);0010071008- this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->writesize);10091010- this->write_bufferram(mtd, ONENAND_DATARAM, buf, 0, thislen);0000000000001011 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);10121013 this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);10141015- onenand_update_bufferram(mtd, to, 1);010161017 ret = this->wait(mtd, FL_WRITING);1018 if (ret) {1019 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: write filaed %d\n", ret);1020- goto out;00000001021 }10221023 written += thislen;10241025- /* Only check verify write turn on */1026- ret = onenand_verify_page(mtd, (u_char *) buf, to);1027- if (ret) {1028- DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: verify failed %d\n", ret);1029- goto out;1030- }1031-1032 if (written == len)1033 break;103401035 to += thislen;1036 buf += thislen;1037 }10381039-out:1040 /* Deselect and wake up anyone waiting on the device */1041 onenand_release_device(mtd);1042···1097 /* Loop until all data write */1098 while (written < len) {1099 int thislen = min_t(int, mtd->oobsize, len - written);0011001101 column = to & (mtd->oobsize - 1);1102···1227 instr->state = MTD_ERASING;12281229 while (len) {012301231 /* Check if we have a bad block, we do not erase bad blocks */1232 if (onenand_block_checkbad(mtd, addr, 0, 0)) {···1241 ret = this->wait(mtd, FL_ERASING);1242 /* Check, if it is write protected */1243 if (ret) {1244- if (ret == -EPERM)1245- DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Device is write protected!!!\n");1246- else1247- DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Failed erase, block %d\n", (unsigned) (addr >> this->erase_shift));1248 instr->state = MTD_ERASE_FAILED;1249 instr->fail_addr = addr;1250 goto erase_exit;···2068 init_waitqueue_head(&this->wq);2069 spin_lock_init(&this->chip_lock);20700002071 switch (mtd->oobsize) {2072 case 64:2073 this->ecclayout = &onenand_oob_64;02074 break;20752076 case 32:2077 this->ecclayout = &onenand_oob_32;02078 break;20792080 default:2081 printk(KERN_WARNING "No OOB scheme defined for oobsize %d\n",2082 mtd->oobsize);02083 /* To prevent kernel oops */2084 this->ecclayout = &onenand_oob_32;2085 break;2086 }208702088 mtd->ecclayout = this->ecclayout;20892090 /* Fill in remaining MTD driver data */
···192 struct onenand_chip *this = mtd->priv;193 int value, readcmd = 0, block_cmd = 0;194 int block, page;00195196 /* Address translation */197 switch (cmd) {···245 }246247 if (page != -1) {248+ /* Now we use page size operation */249+ int sectors = 4, count = 4;250 int dataram;251252 switch (cmd) {···298 unsigned long timeout;299 unsigned int flags = ONENAND_INT_MASTER;300 unsigned int interrupt = 0;301+ unsigned int ctrl;302303 /* The 20 msec is enough */304 timeout = jiffies + msecs_to_jiffies(20);···310311 if (state != FL_READING)312 cond_resched();0313 }314 /* To get correct interrupt status in timeout case */315 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);···318 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);319320 if (ctrl & ONENAND_CTRL_ERROR) {0321 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: controller error = 0x%04x\n", ctrl);322+ if (ctrl & ONENAND_CTRL_LOCK)323+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: it's locked error.\n");324+ return ctrl;0000325 }326327 if (interrupt & ONENAND_INT_READ) {328+ int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS);329 if (ecc) {330 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: ECC error = 0x%04x\n", ecc);331+ if (ecc & ONENAND_ECC_2BIT_ALL) {332 mtd->ecc_stats.failed++;333+ return ecc;334+ } else if (ecc & ONENAND_ECC_1BIT_ALL)335 mtd->ecc_stats.corrected++;336 }337 }···372{373 struct onenand_chip *this = mtd->priv;374000375 wait_for_completion(&this->complete);376377 return onenand_wait(mtd, state);···394395 /* We use interrupt wait first */396 this->wait = onenand_interrupt_wait;000397398 timeout = msecs_to_jiffies(100);399 remain = wait_for_completion_timeout(&this->complete, timeout);···721 struct mtd_ecc_stats stats;722 int read = 0, column;723 int thislen;724+ int ret = 0, boundary = 0;725726 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);727···738 /* TODO handling oob */739740 stats = mtd->ecc_stats;00741742+ /* Read-while-load method */00743744+ /* Do first load to bufferRAM */745+ if (read < len) {746+ if (!onenand_check_bufferram(mtd, from)) {747+ this->command(mtd, ONENAND_CMD_READ, from, mtd->writesize);748+ ret = this->wait(mtd, FL_READING);749+ onenand_update_bufferram(mtd, from, !ret);750+ }751+ }752753+ thislen = min_t(int, mtd->writesize, len - read);754+ column = from & (mtd->writesize - 1);755+ if (column + thislen > mtd->writesize)756+ thislen = mtd->writesize - column;757758+ while (!ret) {759+ /* If there is more to load then start next load */760+ from += thislen;761+ if (read + thislen < len) {762+ this->command(mtd, ONENAND_CMD_READ, from, mtd->writesize);763+ /*764+ * Chip boundary handling in DDP765+ * Now we issued chip 1 read and pointed chip 1766+ * bufferam so we have to point chip 0 bufferam.767+ */768+ if (this->device_id & ONENAND_DEVICE_IS_DDP &&769+ unlikely(from == (this->chipsize >> 1))) {770+ this->write_word(0, this->base + ONENAND_REG_START_ADDRESS2);771+ boundary = 1;772+ } else773+ boundary = 0;774+ ONENAND_SET_PREV_BUFFERRAM(this);775+ }776+ /* While load is going, read from last bufferRAM */777+ this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen);778+ /* See if we are done */779+ read += thislen;780+ if (read == len)781+ break;782+ /* Set up for next read from bufferRAM */783+ if (unlikely(boundary))784+ this->write_word(0x8000, this->base + ONENAND_REG_START_ADDRESS2);785+ ONENAND_SET_NEXT_BUFFERRAM(this);786+ buf += thislen;787+ thislen = min_t(int, mtd->writesize, len - read);788+ column = 0;789+ cond_resched();790+ /* Now wait for load */791+ ret = this->wait(mtd, FL_READING);792+ onenand_update_bufferram(mtd, from, !ret);793+ }794000000000000000795 /* Deselect and wake up anyone waiting on the device */796 onenand_release_device(mtd);797···782783 if (mtd->ecc_stats.failed - stats.failed)784 return -EBADMSG;785+786+ if (ret)787+ return ret;788789 return mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;790}···820 column = from & (mtd->oobsize - 1);821822 while (read < len) {823+ cond_resched();824+825 thislen = mtd->oobsize - column;826 thislen = min_t(int, thislen, len);827···832833 this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);834835+ if (ret) {836+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_oob: read failed = 0x%x\n", ret);837+ goto out;838+ }839+840 read += thislen;841842 if (read == len)843 break;00000844845 buf += thislen;846···919 void __iomem *dataram0, *dataram1;920 int ret = 0;921922+ /* In partial page write, just skip it */923+ if ((addr & (mtd->writesize - 1)) != 0)924+ return 0;925+926 this->command(mtd, ONENAND_CMD_READ, addr, mtd->writesize);927928 ret = this->wait(mtd, FL_READING);···941#define onenand_verify_oob(...) (0)942#endif943944+#define NOTALIGNED(x) ((x & (this->subpagesize - 1)) != 0)945946/**947 * onenand_write - [MTD Interface] write buffer to FLASH···959 struct onenand_chip *this = mtd->priv;960 int written = 0;961 int ret = 0;962+ int column, subpage;963964 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);965···977 return -EINVAL;978 }979980+ column = to & (mtd->writesize - 1);981+ subpage = column || (len & (mtd->writesize - 1));982+983 /* Grab the lock and see if the device is available */984 onenand_get_device(mtd, FL_WRITING);985986 /* Loop until all data write */987 while (written < len) {988+ int bytes = mtd->writesize;989+ int thislen = min_t(int, bytes, len - written);990+ u_char *wbuf = (u_char *) buf;991992+ cond_resched();993994+ this->command(mtd, ONENAND_CMD_BUFFERRAM, to, bytes);995+996+ /* Partial page write */997+ if (subpage) {998+ bytes = min_t(int, bytes - column, (int) len);999+ memset(this->page_buf, 0xff, mtd->writesize);1000+ memcpy(this->page_buf + column, buf, bytes);1001+ wbuf = this->page_buf;1002+ /* Even though partial write, we need page size */1003+ thislen = mtd->writesize;1004+ }1005+1006+ this->write_bufferram(mtd, ONENAND_DATARAM, wbuf, 0, thislen);1007 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);10081009 this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);10101011+ /* In partial page write we don't update bufferram */1012+ onenand_update_bufferram(mtd, to, !subpage);10131014 ret = this->wait(mtd, FL_WRITING);1015 if (ret) {1016 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: write filaed %d\n", ret);1017+ break;1018+ }1019+1020+ /* Only check verify write turn on */1021+ ret = onenand_verify_page(mtd, (u_char *) wbuf, to);1022+ if (ret) {1023+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: verify failed %d\n", ret);1024+ break;1025 }10261027 written += thislen;102800000001029 if (written == len)1030 break;10311032+ column = 0;1033 to += thislen;1034 buf += thislen;1035 }103601037 /* Deselect and wake up anyone waiting on the device */1038 onenand_release_device(mtd);1039···1058 /* Loop until all data write */1059 while (written < len) {1060 int thislen = min_t(int, mtd->oobsize, len - written);1061+1062+ cond_resched();10631064 column = to & (mtd->oobsize - 1);1065···1186 instr->state = MTD_ERASING;11871188 while (len) {1189+ cond_resched();11901191 /* Check if we have a bad block, we do not erase bad blocks */1192 if (onenand_block_checkbad(mtd, addr, 0, 0)) {···1199 ret = this->wait(mtd, FL_ERASING);1200 /* Check, if it is write protected */1201 if (ret) {1202+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Failed erase, block %d\n", (unsigned) (addr >> this->erase_shift));0001203 instr->state = MTD_ERASE_FAILED;1204 instr->fail_addr = addr;1205 goto erase_exit;···2029 init_waitqueue_head(&this->wq);2030 spin_lock_init(&this->chip_lock);20312032+ /*2033+ * Allow subpage writes up to oobsize.2034+ */2035 switch (mtd->oobsize) {2036 case 64:2037 this->ecclayout = &onenand_oob_64;2038+ mtd->subpage_sft = 2;2039 break;20402041 case 32:2042 this->ecclayout = &onenand_oob_32;2043+ mtd->subpage_sft = 1;2044 break;20452046 default:2047 printk(KERN_WARNING "No OOB scheme defined for oobsize %d\n",2048 mtd->oobsize);2049+ mtd->subpage_sft = 0;2050 /* To prevent kernel oops */2051 this->ecclayout = &onenand_oob_32;2052 break;2053 }20542055+ this->subpagesize = mtd->writesize >> mtd->subpage_sft;2056 mtd->ecclayout = this->ecclayout;20572058 /* Fill in remaining MTD driver data */
+2-1
drivers/mtd/onenand/onenand_bbt.c
···93 ret = onenand_do_read_oob(mtd, from + j * mtd->writesize + bd->offs,94 readlen, &retlen, &buf[0]);9596- if (ret)097 return ret;9899 if (check_short_pattern(&buf[j * scanlen], scanlen, mtd->writesize, bd)) {
···93 ret = onenand_do_read_oob(mtd, from + j * mtd->writesize + bd->offs,94 readlen, &retlen, &buf[0]);9596+ /* If it is a initial bad block, just ignore it */97+ if (ret && !(ret & ONENAND_CTRL_LOAD))98 return ret;99100 if (check_short_pattern(&buf[j * scanlen], scanlen, mtd->writesize, bd)) {
+3
include/linux/mtd/onenand.h
···88 * operation is in progress89 * @state: [INTERN] the current state of the OneNAND device90 * @page_buf: data buffer091 * @ecclayout: [REPLACEABLE] the default ecc placement scheme92 * @bbm: [REPLACEABLE] pointer to Bad Block Management93 * @priv: [OPTIONAL] pointer to private chip date···129 onenand_state_t state;130 unsigned char *page_buf;1310132 struct nand_ecclayout *ecclayout;133134 void *bbm;···143#define ONENAND_CURRENT_BUFFERRAM(this) (this->bufferram_index)144#define ONENAND_NEXT_BUFFERRAM(this) (this->bufferram_index ^ 1)145#define ONENAND_SET_NEXT_BUFFERRAM(this) (this->bufferram_index ^= 1)0146147#define ONENAND_GET_SYS_CFG1(this) \148 (this->read_word(this->base + ONENAND_REG_SYS_CFG1))
···88 * operation is in progress89 * @state: [INTERN] the current state of the OneNAND device90 * @page_buf: data buffer91+ * @subpagesize: [INTERN] holds the subpagesize92 * @ecclayout: [REPLACEABLE] the default ecc placement scheme93 * @bbm: [REPLACEABLE] pointer to Bad Block Management94 * @priv: [OPTIONAL] pointer to private chip date···128 onenand_state_t state;129 unsigned char *page_buf;130131+ int subpagesize;132 struct nand_ecclayout *ecclayout;133134 void *bbm;···141#define ONENAND_CURRENT_BUFFERRAM(this) (this->bufferram_index)142#define ONENAND_NEXT_BUFFERRAM(this) (this->bufferram_index ^ 1)143#define ONENAND_SET_NEXT_BUFFERRAM(this) (this->bufferram_index ^= 1)144+#define ONENAND_SET_PREV_BUFFERRAM(this) (this->bufferram_index ^= 1)145146#define ONENAND_GET_SYS_CFG1(this) \147 (this->read_word(this->base + ONENAND_REG_SYS_CFG1))