#include "mtdcore.h"
+#define DYNAMIC_CHANGE_MTD_WRITEABLE
+#ifdef DYNAMIC_CHANGE_MTD_WRITEABLE //wschen 2011-01-05
+#include <linux/proc_fs.h>
+#include <asm/uaccess.h>
+static struct mtd_info *my_mtd = NULL;
+int mtd_writeable_proc_write(struct file *file, const char *buffer, unsigned long count, void *data);
+
+struct mtd_change {
+ uint64_t size;
+ uint64_t offset;
+};
+int mtd_change_proc_write(struct file *file, const char *buffer, unsigned long count, void *data);
+#endif
+
+
/* Our partition linked list */
static LIST_HEAD(mtd_partitions);
static DEFINE_MUTEX(mtd_partitions_mutex);
mutex_lock(&mtd_partitions_mutex);
list_for_each_entry_safe(slave, next, &mtd_partitions, list)
if (slave->master == master) {
+#ifdef DYNAMIC_CHANGE_MTD_WRITEABLE //wschen 2011-01-05
+ my_mtd = NULL;
+#endif
+
ret = del_mtd_device(&slave->mtd);
if (ret < 0) {
err = ret;
for (i = 0; i < nbparts; i++) {
slave = allocate_partition(master, parts + i, i, cur_offset);
- if (IS_ERR(slave))
+ if (IS_ERR(slave)) {
+ del_mtd_partitions(master);
return PTR_ERR(slave);
+ }
mutex_lock(&mtd_partitions_mutex);
list_add(&slave->list, &mtd_partitions);
cur_offset = slave->offset + slave->mtd.size;
}
-
+#ifdef DYNAMIC_CHANGE_MTD_WRITEABLE //wschen 2011-01-05
+ my_mtd = master;
+#endif
return 0;
}
* Do not forget to update 'parse_mtd_partitions()' kerneldoc comment if you
* are changing this array!
*/
-static const char *default_mtd_part_types[] = {
+static const char * const default_mtd_part_types[] = {
"cmdlinepart",
"ofpart",
NULL
* o a positive number of found partitions, in which case on exit @pparts will
* point to an array containing this number of &struct mtd_info objects.
*/
-int parse_mtd_partitions(struct mtd_info *master, const char **types,
+int parse_mtd_partitions(struct mtd_info *master, const char *const *types,
struct mtd_partition **pparts,
struct mtd_part_parser_data *data)
{
}
EXPORT_SYMBOL_GPL(mtd_is_partition);
+#ifdef CONFIG_MTK_MTD_NAND
+u64 mtd_partition_start_address(struct mtd_info *mtd)
+{
+ struct mtd_part *part = PART(mtd);
+ return part->offset;
+}
+EXPORT_SYMBOL_GPL(mtd_partition_start_address);
+#endif
+
/* Returns the size of the entire flash chip */
uint64_t mtd_get_device_size(const struct mtd_info *mtd)
{
return PART(mtd)->master->size;
}
EXPORT_SYMBOL_GPL(mtd_get_device_size);
+
+#ifdef DYNAMIC_CHANGE_MTD_WRITEABLE //wschen 2011-01-05
+int mtd_writeable_proc_write(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+ char buf[3];
+
+ if (count != 3) {
+ return -EFAULT;
+ }
+
+ if (copy_from_user(buf, buffer, 3)) {
+ return -EFAULT;
+ }
+
+ if ((buf[0] != 0) || (buf[1] != 0) || (buf[2] != 0)) {
+ return -EFAULT;
+ }
+
+ if (my_mtd) {
+
+ struct mtd_part *slave, *next;
+
+ list_for_each_entry_safe(slave, next, &mtd_partitions, list)
+ if (slave->master == my_mtd) {
+ slave->mtd.flags |= MTD_WRITEABLE;
+ }
+ }
+
+ return count;
+}
+
+#define MTD_CHANGE_NUM 4
+int mtd_change_proc_write(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+ struct mtd_change mtd_change[MTD_CHANGE_NUM];
+ int write_3 = 0;
+
+ if (count == (sizeof(struct mtd_change) * (MTD_CHANGE_NUM - 1))) {
+ write_3 = 1;
+ } else if (count != (sizeof(struct mtd_change) * MTD_CHANGE_NUM)) {
+ return -EFAULT;
+ }
+
+ if (copy_from_user(mtd_change, buffer, count)) {
+ return -EFAULT;
+ }
+
+ if (my_mtd) {
+ struct mtd_part *slave, *next;
+
+ list_for_each_entry_safe(slave, next, &mtd_partitions, list)
+ if (slave->master == my_mtd) {
+ if (write_3 == 1) {
+ if (strncmp(slave->mtd.name, "system", strlen(slave->mtd.name)) == 0) {
+ slave->mtd.size = mtd_change[0].size;
+ slave->offset = mtd_change[0].offset;
+ } else if (strncmp(slave->mtd.name, "cache", strlen(slave->mtd.name)) == 0) {
+ slave->mtd.size = mtd_change[1].size;
+ slave->offset = mtd_change[1].offset;
+ } else if (strncmp(slave->mtd.name, "userdata", strlen(slave->mtd.name)) == 0) {
+ slave->mtd.size = mtd_change[2].size;
+ slave->offset = mtd_change[2].offset;
+ }
+ } else {
+ //4 arguments
+ if (strncmp(slave->mtd.name, "expdb", strlen(slave->mtd.name)) == 0) {
+ slave->mtd.size = mtd_change[0].size;
+ slave->offset = mtd_change[0].offset;
+ } else if (strncmp(slave->mtd.name, "system", strlen(slave->mtd.name)) == 0) {
+ slave->mtd.size = mtd_change[1].size;
+ slave->offset = mtd_change[1].offset;
+ } else if (strncmp(slave->mtd.name, "cache", strlen(slave->mtd.name)) == 0) {
+ slave->mtd.size = mtd_change[2].size;
+ slave->offset = mtd_change[2].offset;
+ } else if (strncmp(slave->mtd.name, "userdata", strlen(slave->mtd.name)) == 0) {
+ slave->mtd.size = mtd_change[3].size;
+ slave->offset = mtd_change[3].offset;
+ }
+ }
+ }
+ }
+
+ return count;
+}
+#endif