diff -Nurb linux/drivers/mtd/mtdcore.c linux-mtd-rw/drivers/mtd/mtdcore.c --- linux/drivers/mtd/mtdcore.c 2004-11-18 13:16:00.000000000 +0100 +++ linux-mtd-rw/drivers/mtd/mtdcore.c 2004-11-18 15:27:13.130036616 +0100 @@ -25,6 +25,10 @@ #include +/* this symbol is exported by the procfs. */ +extern struct proc_dir_entry *proc_sys_root; + + /* These are exported solely for the purpose of mtd_blkdevs.c. You should not use them for _anything_ else */ DECLARE_MUTEX(mtd_table_mutex); @@ -336,8 +340,83 @@ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) static struct proc_dir_entry *proc_mtd; + +static struct proc_dir_entry *proc_sys_mtd; +static struct proc_dir_entry *proc_sys_mtd_partition[MAX_MTD_DEVICES]; +static struct proc_dir_entry *proc_sys_mtd_partition_rw[MAX_MTD_DEVICES]; #endif +/*===================================0 + * mtdproc_read_partition_access + */ +static int mtdproc_read_partition_access ( char *page, char **start, off_t off,int count, + int *eof, void *data + ) +{ + int partid = (unsigned int)data; + int len = 0; + + // NO RETURN FROM HERE UNTIL "up(&mtd_table_mutex)". + down(&mtd_table_mutex); + + if (partid < MAX_MTD_DEVICES) + { + struct mtd_info *this = mtd_table[partid]; + if (this) + { + page[len] = (this->flags & MTD_WRITEABLE) ? '1' : '0'; + len++; + } + } + + up(&mtd_table_mutex); + + if (off >= len) + return 0; + *start = page + off; + return ((count < len-off) ? count : len-off); +} + + +static int mtdproc_write_partition_access (struct file *file, const char *buffer, + unsigned long count, void *data) +{ + int partid = (unsigned int)data; + int len = 0; + + // NO RETURN FROM HERE UNTIL "up(&mtd_table_mutex)". + down(&mtd_table_mutex); + + if (partid < MAX_MTD_DEVICES) + { + struct mtd_info *this = mtd_table[partid]; + if (this && count > 0) + { + switch (*buffer) + { + case '0': + this->flags &= ~(this->master_flags & MTD_WRITEABLE); + break; + + case '1': + this->flags |= ~(this->master_flags & MTD_WRITEABLE); + break; + + default: + break; + } + } + } + + up(&mtd_table_mutex); + + return count; +} + + + + + static inline int mtd_proc_info (char *buf, int i) { struct mtd_info *this = mtd_table[i]; @@ -349,6 +428,7 @@ this->erasesize, this->name); } + static int mtd_read_proc ( char *page, char **start, off_t off,int count #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) ,int *eof, void *data_unused @@ -404,12 +484,31 @@ /*====================================================================*/ /* Init code */ + int __init init_mtd(void) { #ifdef CONFIG_PROC_FS #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) + int i; + if ((proc_mtd = create_proc_entry( "mtd", 0, 0 ))) proc_mtd->read_proc = mtd_read_proc; + + proc_sys_mtd = proc_mkdir("mtd", proc_sys_root); + for (i=0; iread_proc = mtdproc_read_partition_access; + proc_sys_mtd_partition_rw[i]->write_proc = mtdproc_write_partition_access; + proc_sys_mtd_partition_rw[i]->data = (void *)i; + } + } #else proc_register_dynamic(&proc_root,&mtd_proc_entry); #endif @@ -425,6 +524,8 @@ return 0; } + + static void __exit cleanup_mtd(void) { #ifdef CONFIG_PM diff -Nurb linux/drivers/mtd/mtdpart.c linux-mtd-rw/drivers/mtd/mtdpart.c --- linux/drivers/mtd/mtdpart.c 2004-11-18 13:16:00.000000000 +0100 +++ linux-mtd-rw/drivers/mtd/mtdpart.c 2004-11-18 15:27:13.131036464 +0100 @@ -341,6 +341,9 @@ /* set up the MTD object for this partition */ slave->mtd.type = master->type; slave->mtd.flags = master->flags & ~parts[i].mask_flags; + slave->mtd.master_flags = master->flags; + slave->mtd.mask_flags = parts[i].mask_flags; + slave->mtd.size = parts[i].size; slave->mtd.oobblock = master->oobblock; slave->mtd.oobsize = master->oobsize; diff -Nurb linux/include/linux/mtd/mtd.h linux-mtd-rw/include/linux/mtd/mtd.h --- linux/include/linux/mtd/mtd.h 2004-11-18 13:16:31.000000000 +0100 +++ linux-mtd-rw/include/linux/mtd/mtd.h 2004-11-18 15:27:13.000000000 +0100 @@ -232,6 +232,9 @@ struct module *owner; int usecount; + + u_int32_t master_flags; + u_int32_t mask_flags; };