loff_t addr = 0;
size_t amount_loaded = 0;
size_t len;
- struct mtd_oob_ops aml_oob_ops;
unsigned char *data_buf;
unsigned char oob_buf[sizeof(struct oobinfo_t)];
+ int page, realpage, chipnr;
+ struct nand_chip *chip = mtd_to_nand(mtd);
READ_RSV_AGAIN:
addr = nandrsv_info->valid_node->phy_blk_addr;
oobinfo = (struct oobinfo_t *)oob_buf;
while (amount_loaded < nandrsv_info->size) {
- aml_oob_ops.mode = MTD_OPS_AUTO_OOB;
- aml_oob_ops.len = mtd->writesize;
- aml_oob_ops.ooblen = sizeof(struct oobinfo_t);
- /*aml_oob_ops.ooboffs = mtd->ecclayout->oobfree[0].offset;*/
- aml_oob_ops.ooboffs = 0;
- aml_oob_ops.datbuf = data_buf;
- aml_oob_ops.oobbuf = oob_buf;
-
- memset((unsigned char *)aml_oob_ops.datbuf,
+ memset((unsigned char *)data_buf,
0x0, mtd->writesize);
- memset((unsigned char *)aml_oob_ops.oobbuf,
- 0x0, aml_oob_ops.ooblen);
-
- error = mtd->_read_oob(mtd, addr, &aml_oob_ops);
+ memset((unsigned char *)oob_buf,
+ 0x0, sizeof(struct oobinfo_t));
+ chipnr = (int)(addr >> chip->chip_shift);
+ chip->select_chip(mtd, chipnr);
+ realpage = (int)(addr >> chip->page_shift);
+ page = realpage & chip->pagemask;
+
+ chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
+ error = chip->ecc.read_page(mtd, chip, data_buf,
+ 1, page);
+ chip->select_chip(mtd, -1);
if ((error != 0) && (error != -EUCLEAN)) {
pr_info("blk good but read failed: %llx, %d\n",
(uint64_t)addr, error);
goto READ_RSV_AGAIN;
}
+ memcpy(oob_buf, chip->oob_poi, mtd->oobavail);
if (memcmp(oobinfo->name, nandrsv_info->name, 4))
pr_info("invalid nand info %s magic: %llx\n",
nandrsv_info->name, (uint64_t)addr);
-
addr += mtd->writesize;
+ page++;
len = min_t(uint32_t, mtd->writesize,
(nandrsv_info->size - amount_loaded));
memcpy(buf + amount_loaded, data_buf, len);
}
}
#endif
- /* if(data_buf) */
- /* kfree(data_buf); */
return 0;
}
struct aml_nandrsv_info_t *nandrsv_info, loff_t offset, u_char *buf)
{
struct aml_nand_chip *aml_chip = mtd_to_nand_chip(mtd);
+ struct nand_chip *chip = mtd_to_nand(mtd);
struct oobinfo_t *oobinfo;
int error = 0;
loff_t addr = 0;
size_t amount_saved = 0;
size_t len;
- struct mtd_oob_ops aml_oob_ops;
unsigned char *data_buf;
unsigned char oob_buf[sizeof(struct oobinfo_t)];
+ int page, chipnr;
data_buf = aml_chip->rsv_data_buf;
- /* if (data_buf == NULL) */
- /* return -ENOMEM; */
addr = offset;
pr_info("%s:%d,write info to %llx\n", __func__, __LINE__, addr);
}
#endif
while (amount_saved < nandrsv_info->size) {
- aml_oob_ops.mode = MTD_OPS_AUTO_OOB;
- aml_oob_ops.len = mtd->writesize;
- aml_oob_ops.ooblen = sizeof(struct oobinfo_t);
- aml_oob_ops.ooboffs = 0;/*mtd->ecclayout->oobfree[0].offset;*/
- aml_oob_ops.datbuf = data_buf;
- aml_oob_ops.oobbuf = oob_buf;
-
- memset((unsigned char *)aml_oob_ops.datbuf,
+ memset((unsigned char *)data_buf,
0x0, mtd->writesize);
len = min_t(uint32_t, mtd->writesize,
nandrsv_info->size - amount_saved);
- memcpy((unsigned char *)aml_oob_ops.datbuf,
+ memcpy((unsigned char *)data_buf,
buf + amount_saved, len);
- error = mtd->_write_oob(mtd, addr, &aml_oob_ops);
+ page = (int)(addr >> chip->page_shift);
+ chipnr = (int)(addr >> chip->chip_shift);
+ memset(chip->oob_poi, 0xff, mtd->oobsize);
+ memcpy(chip->oob_poi, oob_buf, mtd->oobsize);
+ chip->select_chip(mtd, chipnr);
+ error = chip->write_page(mtd, chip, 0, len, data_buf,
+ 1, page, 0, 0);
+ chip->select_chip(mtd, -1);
if (error) {
pr_info("blk check good but write failed: %llx, %d\n",
(uint64_t)addr, error);
}
if (amount_saved < nandrsv_info->size)
return 1;
- /* kfree(data_buf); */
+
return 0;
}
int aml_nand_save_rsv_info(struct mtd_info *mtd,
struct aml_nandrsv_info_t *nandrsv_info, u_char *buf)
{
+ struct nand_chip *chip = mtd_to_nand(mtd);
struct free_node_t *free_node = NULL, *tmp_node = NULL;
int error = 0, pages_per_blk, valid_page_addr, i = 1;
loff_t addr = 0;
- struct erase_info erase_info;
+ int chipnr = 0;
+ int page;
pages_per_blk = mtd->erasesize / mtd->writesize;
/*solve these abnormals caused by power off and ecc error*/
if ((valid_page_addr - i) == pages_per_blk) {
addr = nandrsv_info->valid_node->phy_blk_addr;
addr *= mtd->erasesize;
- memset(&erase_info,
- 0, sizeof(struct erase_info));
- erase_info.mtd = mtd;
- erase_info.addr = addr;
- erase_info.len = mtd->erasesize;
_aml_rsv_disprotect();
- error = mtd->_erase(mtd, &erase_info);
+ page = (int)(addr >> chip->page_shift);
+ chipnr = (int)(addr >> chip->chip_shift);
+ chip->select_chip(mtd, chipnr);
+ error = chip->erase(mtd, page & chip->pagemask);
+ chip->select_chip(mtd, -1);
_aml_rsv_protect();
nandrsv_info->valid_node->ec++;
pr_info("---erase bad env block:%llx\n", addr);
pr_info("%s:%d,save info to %llx\n", __func__, __LINE__, addr);
if (nandrsv_info->valid_node->phy_page_addr == 0) {
- error = mtd->_block_isbad(mtd, addr);
+ chipnr = (int)(addr >> chip->chip_shift);
+ chip->select_chip(mtd, chipnr);
+ error = chip->block_bad(mtd, addr);
+ chip->select_chip(mtd, -1);
if (error != 0) {
/*
*bad block here, need fix it
goto RE_SEARCH;
}
- memset(&erase_info, 0, sizeof(struct erase_info));
- erase_info.mtd = mtd;
- erase_info.addr = addr;
- erase_info.len = mtd->erasesize;
_aml_rsv_disprotect();
- error = mtd->_erase(mtd, &erase_info);
+ page = (int)(addr >> chip->page_shift);
+ //chipnr = (int)(addr >> chip->chip_shift);
+ chip->select_chip(mtd, chipnr);
+ error = chip->erase(mtd, page & chip->pagemask);
+ chip->select_chip(mtd, -1);
_aml_rsv_protect();
if (error) {
pr_info("env free blk erase failed %d\n", error);
- mtd->_block_markbad(mtd, addr);
+ chip->select_chip(mtd, chipnr);
+ chip->block_markbad(mtd, addr);
+ chip->select_chip(mtd, -1);
return error;
}
nandrsv_info->valid_node->ec++;
struct free_node_t *tmp_node, *next_node = NULL;
int error = 0;
loff_t addr = 0;
- struct erase_info erase_info;
+ int page, chipnr;
+ struct nand_chip *chip = mtd_to_nand(mtd);
pr_info("free %s:\n", nandrsv_info->name);
if (nandrsv_info->valid) {
addr = nandrsv_info->valid_node->phy_blk_addr;
addr *= mtd->erasesize;
- memset(&erase_info,
- 0, sizeof(struct erase_info));
- erase_info.mtd = mtd;
- erase_info.addr = addr;
- erase_info.len = mtd->erasesize;
+
+ page = (int)(addr >> chip->page_shift);
+ chipnr = (int)(addr >> chip->chip_shift);
_aml_rsv_disprotect();
- error = mtd->_erase(mtd, &erase_info);
+ chip->select_chip(mtd, chipnr);
+ error = chip->erase(mtd, page & chip->pagemask);
+ chip->select_chip(mtd, -1);
_aml_rsv_protect();
pr_info("erasing valid info block: %llx\n", addr);
nandrsv_info->valid_node->phy_blk_addr = -1;
{
struct aml_nand_chip *aml_chip = mtd_to_nand_chip(mtd);
struct nand_chip *chip = &aml_chip->chip;
- struct mtd_oob_ops aml_oob_ops;
struct oobinfo_t *oobinfo;
struct free_node_t *free_node, *tmp_node = NULL;
unsigned char oob_buf[sizeof(struct oobinfo_t)];
int phys_erase_shift, pages_per_blk, page_num;
int error = 0, ret = 0;
uint32_t remainder;
+ int page, realpage, chipnr;
data_buf = aml_chip->rsv_data_buf;
oobinfo = (struct oobinfo_t *)oob_buf;
offset *= start_blk;
scan_status = 0;
RE_RSV_INFO:
- aml_oob_ops.mode = MTD_OPS_AUTO_OOB;
- aml_oob_ops.len = mtd->writesize;
- aml_oob_ops.ooblen = sizeof(struct oobinfo_t);
- aml_oob_ops.ooboffs = 0;/*mtd->ecclayout->oobfree[0].offset;*/
- aml_oob_ops.datbuf = data_buf;
- aml_oob_ops.oobbuf = oob_buf;
-
- memset((unsigned char *)aml_oob_ops.datbuf,
+ memset((unsigned char *)data_buf,
0x0, mtd->writesize);
- memset((unsigned char *)aml_oob_ops.oobbuf,
- 0x0, aml_oob_ops.ooblen);
-
- error = mtd->_read_oob(mtd, offset, &aml_oob_ops);
+ memset((unsigned char *)oob_buf,
+ 0x0, sizeof(struct oobinfo_t));
+
+ realpage = (int)(offset >> chip->page_shift);
+ page = realpage & chip->pagemask;
+ chipnr = (int)(offset >> chip->chip_shift);
+
+ chip->select_chip(mtd, chipnr);
+ chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
+ error = chip->ecc.read_page(mtd, chip, data_buf,
+ 1, page);
+ chip->select_chip(mtd, -1);
if ((error != 0) && (error != -EUCLEAN)) {
pr_info("blk check good but read failed: %llx, %d\n",
(uint64_t)offset, error);
goto RE_RSV_INFO;
}
+ memcpy(oob_buf, chip->oob_poi, mtd->oobavail);
nandrsv_info->init = 1;
nandrsv_info->valid_node->status = 0;
if (!memcmp(oobinfo->name, nandrsv_info->name, 4)) {
if (nandrsv_info->valid == 1) {
pr_info("%s %d\n", __func__, __LINE__);
- aml_oob_ops.mode = MTD_OPS_AUTO_OOB;
- aml_oob_ops.len = mtd->writesize;
- aml_oob_ops.ooblen = sizeof(struct oobinfo_t);
- aml_oob_ops.ooboffs = 0;/*mtd->ecclayout->oobfree[0].offset;*/
- aml_oob_ops.datbuf = data_buf;
- aml_oob_ops.oobbuf = oob_buf;
for (i = 0; i < pages_per_blk; i++) {
- memset((unsigned char *)aml_oob_ops.datbuf,
+ memset((unsigned char *)data_buf,
0x0, mtd->writesize);
- memset((unsigned char *)aml_oob_ops.oobbuf,
- 0x0, aml_oob_ops.ooblen);
+ memset((unsigned char *)oob_buf,
+ 0x0, sizeof(struct oobinfo_t));
offset = nandrsv_info->valid_node->phy_blk_addr;
offset *= mtd->erasesize;
offset += i * mtd->writesize;
- error = mtd->_read_oob(mtd, offset, &aml_oob_ops);
+
+ realpage = (int)(offset >> chip->page_shift);
+ page = realpage & chip->pagemask;
+ chipnr = (int)(offset >> chip->chip_shift);
+ chip->select_chip(mtd, chipnr);
+ chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
+ error = chip->ecc.read_page(mtd, chip, data_buf,
+ 1, page);
+ chip->select_chip(mtd, -1);
if ((error != 0) && (error != -EUCLEAN)) {
pr_info("blk good but read failed:%llx,%d\n",
(uint64_t)offset, error);
continue;
}
+ memcpy(oob_buf, chip->oob_poi, mtd->oobavail);
if (!memcmp(oobinfo->name, nandrsv_info->name, 4)) {
good_addr[i] = 1;
nandrsv_info->valid_node->phy_page_addr = i;