mtd源码 linux,linux mtd源码分析--mtdchar.c

#define MAX_KMALLOC_SIZE 0x20000

static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t *ppos)

{

struct mtd_file_info *mfi = file->private_data;

struct mtd_info *mtd = mfi->mtd;

size_t retlen=0;

size_t total_retlen=0;

int ret=0;

int len;

char *kbuf;

DEBUG(MTD_DEBUG_LEVEL0,"MTD_read\n");

if (*ppos + count > mtd->size)

count = mtd->size - *ppos;

if (!count)

return 0;

/* FIXME: Use kiovec in 2.5 to lock down the user's buffers

and pass them directly to the MTD functions */

#<1>

if (count > MAX_KMALLOC_SIZE)

kbuf=kmalloc(MAX_KMALLOC_SIZE, GFP_KERNEL);

else

kbuf=kmalloc(count, GFP_KERNEL);

if (!kbuf)

return -ENOMEM;

while (count) {

if (count > MAX_KMALLOC_SIZE)

len = MAX_KMALLOC_SIZE;

else

len = count;

switch (mfi->mode) {#<2>

case MTD_MODE_OTP_FACTORY:

ret = mtd->read_fact_prot_reg(mtd, *ppos, len, &retlen, kbuf);

break;

case MTD_MODE_OTP_USER:

ret = mtd->read_user_prot_reg(mtd, *ppos, len, &retlen, kbuf);

break;

case MTD_MODE_RAW:

{

struct mtd_oob_ops ops;

ops.mode = MTD_OOB_RAW;

ops.datbuf = kbuf;

ops.oobbuf = NULL;

ops.len = len;

ret = mtd->read_oob(mtd, *ppos, &ops);

retlen = ops.retlen;

break;

}

default:

ret = mtd->read(mtd, *ppos, len, &retlen, kbuf);

}

/* Nand returns -EBADMSG on ecc errors, but it returns

* the data. For our userspace tools it is important

* to dump areas with ecc errors !

* For kernel internal usage it also might return -EUCLEAN

* to signal the caller that a bitflip has occured and has

* been corrected by the ECC algorithm.

* Userspace software which accesses NAND this way

* must be aware of the fact that it deals with NAND

*/

if (!ret || (ret == -EUCLEAN) || (ret == -EBADMSG)) {

*ppos += retlen;

if (copy_to_user(buf, kbuf, retlen)) {

kfree(kbuf);

return -EFAULT;

}

else

total_retlen += retlen;

count -= retlen;

buf += retlen;

if (retlen == 0)

count = 0;

}

else {

kfree(kbuf);

return ret;

}

}

kfree(kbuf);

return total_retlen;

} /* mtd_read */

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值