X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fmtd%2Fmtdcore.c;fp=drivers%2Fmtd%2Fmtdcore.c;h=dade02ab0687aeee729a3e1c80339b5e27fbdf87;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=168d3ba063c3637ca48373312271e59f897f4fb4;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 168d3ba06..dade02ab0 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -6,6 +6,7 @@ * */ +#include #include #include #include @@ -18,13 +19,15 @@ #include #include #include +#ifdef CONFIG_PROC_FS #include +#endif #include /* These are exported solely for the purpose of mtd_blkdevs.c. You should not use them for _anything_ else */ -DEFINE_MUTEX(mtd_table_mutex); +DECLARE_MUTEX(mtd_table_mutex); struct mtd_info *mtd_table[MAX_MTD_DEVICES]; EXPORT_SYMBOL_GPL(mtd_table_mutex); @@ -46,8 +49,7 @@ int add_mtd_device(struct mtd_info *mtd) { int i; - BUG_ON(mtd->writesize == 0); - mutex_lock(&mtd_table_mutex); + down(&mtd_table_mutex); for (i=0; i < MAX_MTD_DEVICES; i++) if (!mtd_table[i]) { @@ -65,7 +67,7 @@ int add_mtd_device(struct mtd_info *mtd) not->add(mtd); } - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); /* We _know_ we aren't being removed, because our caller is still holding us here. So none of this try_ nonsense, and no bitching about it @@ -74,7 +76,7 @@ int add_mtd_device(struct mtd_info *mtd) return 0; } - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); return 1; } @@ -92,7 +94,7 @@ int del_mtd_device (struct mtd_info *mtd) { int ret; - mutex_lock(&mtd_table_mutex); + down(&mtd_table_mutex); if (mtd_table[mtd->index] != mtd) { ret = -ENODEV; @@ -116,7 +118,7 @@ int del_mtd_device (struct mtd_info *mtd) ret = 0; } - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); return ret; } @@ -133,7 +135,7 @@ void register_mtd_user (struct mtd_notifier *new) { int i; - mutex_lock(&mtd_table_mutex); + down(&mtd_table_mutex); list_add(&new->list, &mtd_notifiers); @@ -143,7 +145,7 @@ void register_mtd_user (struct mtd_notifier *new) if (mtd_table[i]) new->add(mtd_table[i]); - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); } /** @@ -160,7 +162,7 @@ int unregister_mtd_user (struct mtd_notifier *old) { int i; - mutex_lock(&mtd_table_mutex); + down(&mtd_table_mutex); module_put(THIS_MODULE); @@ -169,7 +171,7 @@ int unregister_mtd_user (struct mtd_notifier *old) old->remove(mtd_table[i]); list_del(&old->list); - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); return 0; } @@ -191,7 +193,7 @@ struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num) struct mtd_info *ret = NULL; int i; - mutex_lock(&mtd_table_mutex); + down(&mtd_table_mutex); if (num == -1) { for (i=0; i< MAX_MTD_DEVICES; i++) @@ -209,7 +211,7 @@ struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num) if (ret) ret->usecount++; - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); return ret; } @@ -217,9 +219,9 @@ void put_mtd_device(struct mtd_info *mtd) { int c; - mutex_lock(&mtd_table_mutex); + down(&mtd_table_mutex); c = --mtd->usecount; - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); BUG_ON(c < 0); module_put(mtd->owner); @@ -254,6 +256,37 @@ int default_mtd_writev(struct mtd_info *mtd, const struct kvec *vecs, return ret; } + +/* default_mtd_readv - default mtd readv method for MTD devices that dont + * implement their own + */ + +int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs, + unsigned long count, loff_t from, size_t *retlen) +{ + unsigned long i; + size_t totlen = 0, thislen; + int ret = 0; + + if(!mtd->read) { + ret = -EIO; + } else { + for (i=0; iread(mtd, from, vecs[i].iov_len, &thislen, vecs[i].iov_base); + totlen += thislen; + if (ret || thislen != vecs[i].iov_len) + break; + from += vecs[i].iov_len; + } + } + if (retlen) + *retlen = totlen; + return ret; +} + + EXPORT_SYMBOL(add_mtd_device); EXPORT_SYMBOL(del_mtd_device); EXPORT_SYMBOL(get_mtd_device); @@ -261,12 +294,12 @@ EXPORT_SYMBOL(put_mtd_device); EXPORT_SYMBOL(register_mtd_user); EXPORT_SYMBOL(unregister_mtd_user); EXPORT_SYMBOL(default_mtd_writev); - -#ifdef CONFIG_PROC_FS +EXPORT_SYMBOL(default_mtd_readv); /*====================================================================*/ /* Support for /proc/mtd */ +#ifdef CONFIG_PROC_FS static struct proc_dir_entry *proc_mtd; static inline int mtd_proc_info (char *buf, int i) @@ -286,7 +319,7 @@ static int mtd_read_proc (char *page, char **start, off_t off, int count, int len, l, i; off_t begin = 0; - mutex_lock(&mtd_table_mutex); + down(&mtd_table_mutex); len = sprintf(page, "dev: size erasesize name\n"); for (i=0; i< MAX_MTD_DEVICES; i++) { @@ -304,34 +337,38 @@ static int mtd_read_proc (char *page, char **start, off_t off, int count, *eof = 1; done: - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); if (off >= len+begin) return 0; *start = page + (off-begin); return ((count < begin+len-off) ? count : begin+len-off); } +#endif /* CONFIG_PROC_FS */ + /*====================================================================*/ /* Init code */ static int __init init_mtd(void) { +#ifdef CONFIG_PROC_FS if ((proc_mtd = create_proc_entry( "mtd", 0, NULL ))) proc_mtd->read_proc = mtd_read_proc; +#endif return 0; } static void __exit cleanup_mtd(void) { +#ifdef CONFIG_PROC_FS if (proc_mtd) remove_proc_entry( "mtd", NULL); +#endif } module_init(init_mtd); module_exit(cleanup_mtd); -#endif /* CONFIG_PROC_FS */ - MODULE_LICENSE("GPL"); MODULE_AUTHOR("David Woodhouse ");