?? mtdpart.c
字號(hào):
/* * Simple MTD partitioning layer * * (C) 2000 Nicolas Pitre <nico@cam.org> * * This code is GPL * * $Id: mtdpart.c,v 1.2 2007/09/21 03:09:24 quy Exp $ * * 02-21-2002 Thomas Gleixner <gleixner@autronix.de> * added support for read_oob, write_oob */ #include <linux/module.h>#include <linux/types.h>#include <linux/kernel.h>#include <linux/slab.h>#include <linux/list.h>#include <linux/config.h>#include <linux/kmod.h>#include <linux/mtd/mtd.h>#include <linux/mtd/partitions.h>#include <linux/mtd/compatmac.h>/* Our partition linked list */static LIST_HEAD(mtd_partitions);/* Our partition node structure */struct mtd_part { struct mtd_info mtd; struct mtd_info *master; u_int32_t offset; int index; struct list_head list; int registered;};/* * Given a pointer to the MTD object in the mtd_part structure, we can retrieve * the pointer to that structure with this macro. */#define PART(x) ((struct mtd_part *)(x)) /* * MTD methods which simply translate the effective address and pass through * to the _real_ device. */static int part_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf){ struct mtd_part *part = PART(mtd); if (from >= mtd->size) len = 0; else if (from + len > mtd->size) len = mtd->size - from; if (part->master->read_ecc == NULL) return part->master->read (part->master, from + part->offset, len, retlen, buf); else return part->master->read_ecc (part->master, from + part->offset, len, retlen, buf, NULL, &mtd->oobinfo);}static int part_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **buf){ struct mtd_part *part = PART(mtd); if (from >= mtd->size) len = 0; else if (from + len > mtd->size) len = mtd->size - from; return part->master->point (part->master, from + part->offset, len, retlen, buf);}static void part_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len){ struct mtd_part *part = PART(mtd); part->master->unpoint (part->master, addr, from + part->offset, len);}static int part_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel){ struct mtd_part *part = PART(mtd); if (oobsel == NULL) oobsel = &mtd->oobinfo; if (from >= mtd->size) len = 0; else if (from + len > mtd->size) len = mtd->size - from; return part->master->read_ecc (part->master, from + part->offset, len, retlen, buf, eccbuf, oobsel);}static int part_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf){ struct mtd_part *part = PART(mtd); if (from >= mtd->size) len = 0; else if (from + len > mtd->size) len = mtd->size - from; return part->master->read_oob (part->master, from + part->offset, len, retlen, buf);}static int part_read_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf){ struct mtd_part *part = PART(mtd); return part->master->read_user_prot_reg (part->master, from, len, retlen, buf);}static int part_get_user_prot_info (struct mtd_info *mtd, struct otp_info *buf, size_t len){ struct mtd_part *part = PART(mtd); return part->master->get_user_prot_info (part->master, buf, len);}static int part_read_fact_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf){ struct mtd_part *part = PART(mtd); return part->master->read_fact_prot_reg (part->master, from, len, retlen, buf);}static int part_get_fact_prot_info (struct mtd_info *mtd, struct otp_info *buf, size_t len){ struct mtd_part *part = PART(mtd); return part->master->get_fact_prot_info (part->master, buf, len);}static int part_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf){ struct mtd_part *part = PART(mtd); if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; if (to >= mtd->size) len = 0; else if (to + len > mtd->size) len = mtd->size - to; if (part->master->write_ecc == NULL) return part->master->write (part->master, to + part->offset, len, retlen, buf); else return part->master->write_ecc (part->master, to + part->offset, len, retlen, buf, NULL, &mtd->oobinfo); }static int part_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel){ struct mtd_part *part = PART(mtd); if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; if (oobsel == NULL) oobsel = &mtd->oobinfo; if (to >= mtd->size) len = 0; else if (to + len > mtd->size) len = mtd->size - to; return part->master->write_ecc (part->master, to + part->offset, len, retlen, buf, eccbuf, oobsel);}static int part_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf){ struct mtd_part *part = PART(mtd); if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; if (to >= mtd->size) len = 0; else if (to + len > mtd->size) len = mtd->size - to; return part->master->write_oob (part->master, to + part->offset, len, retlen, buf);}static int part_write_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf){ struct mtd_part *part = PART(mtd); return part->master->write_user_prot_reg (part->master, from, len, retlen, buf);}static int part_lock_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len) { struct mtd_part *part = PART(mtd); return part->master->lock_user_prot_reg (part->master, from, len);}static int part_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen){ struct mtd_part *part = PART(mtd); if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; if (part->master->writev_ecc == NULL) return part->master->writev (part->master, vecs, count, to + part->offset, retlen); else return part->master->writev_ecc (part->master, vecs, count, to + part->offset, retlen, NULL, &mtd->oobinfo);}static int part_readv (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, size_t *retlen){ struct mtd_part *part = PART(mtd); if (part->master->readv_ecc == NULL) return part->master->readv (part->master, vecs, count, from + part->offset, retlen); else return part->master->readv_ecc (part->master, vecs, count, from + part->offset, retlen, NULL, &mtd->oobinfo);}static int part_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel){ struct mtd_part *part = PART(mtd); if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; if (oobsel == NULL) oobsel = &mtd->oobinfo; return part->master->writev_ecc (part->master, vecs, count, to + part->offset, retlen, eccbuf, oobsel);}static int part_readv_ecc (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel){ struct mtd_part *part = PART(mtd); if (oobsel == NULL) oobsel = &mtd->oobinfo; return part->master->readv_ecc (part->master, vecs, count, from + part->offset, retlen, eccbuf, oobsel);}static int part_erase (struct mtd_info *mtd, struct erase_info *instr){ struct mtd_part *part = PART(mtd); int ret; if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; if (instr->addr >= mtd->size) return -EINVAL; instr->addr += part->offset; ret = part->master->erase(part->master, instr); return ret;}void mtd_erase_callback(struct erase_info *instr){ if (instr->mtd->erase == part_erase) { struct mtd_part *part = PART(instr->mtd); if (instr->fail_addr != 0xffffffff) instr->fail_addr -= part->offset; instr->addr -= part->offset; } if (instr->callback) instr->callback(instr);}EXPORT_SYMBOL_GPL(mtd_erase_callback);static int part_lock (struct mtd_info *mtd, loff_t ofs, size_t len){ struct mtd_part *part = PART(mtd); if ((len + ofs) > mtd->size) return -EINVAL; return part->master->lock(part->master, ofs + part->offset, len);}static int part_unlock (struct mtd_info *mtd, loff_t ofs, size_t len){ struct mtd_part *part = PART(mtd); if ((len + ofs) > mtd->size) return -EINVAL; return part->master->unlock(part->master, ofs + part->offset, len);}static void part_sync(struct mtd_info *mtd){ struct mtd_part *part = PART(mtd); part->master->sync(part->master);}static int part_suspend(struct mtd_info *mtd){ struct mtd_part *part = PART(mtd); return part->master->suspend(part->master);}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -