mtd/drivers/mtd/maps mphysmap.c, 1.1, 1.2 Kconfig, 1.46, 1.47 Makefile.common, 1.26, 1.27

joern at infradead.org joern at infradead.org
Mon Mar 7 18:15:51 EST 2005


Update of /home/cvs/mtd/drivers/mtd/maps
In directory phoenix.infradead.org:/home/joern/mtd/drivers/mtd/maps

Modified Files:
	Kconfig Makefile.common 
Added Files:
	mphysmap.c 
Log Message:
Add mphysmap driver.  This driver only works for 2.6 (if at all - I haven't
tested it).



Index: mphysmap.c
===================================================================
RCS file: mphysmap.c
diff -N mphysmap.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ mphysmap.c	7 Mar 2005 23:15:48 -0000	1.2
@@ -0,0 +1,282 @@
+/*
+ * $Id$
+ *
+ * Several mappings of NOR chips
+ *
+ * Copyright (c) 2001-2005	Jörn Engel <joern at wh.fh-wedelde>
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/mtd.h>
+
+
+#define NO_DEVICES 8
+struct map_info maps[NO_DEVICES] = {
+#if CONFIG_MTD_MULTI_PHYSMAP_1_WIDTH
+	{
+		.name		= CONFIG_MTD_MULTI_PHYSMAP_1_NAME,
+		.phys		= CONFIG_MTD_MULTI_PHYSMAP_1_START,
+		.size		= CONFIG_MTD_MULTI_PHYSMAP_1_LEN,
+		.bankwidth	= CONFIG_MTD_MULTI_PHYSMAP_1_WIDTH,
+	},
+#endif
+#if CONFIG_MTD_MULTI_PHYSMAP_2_WIDTH
+	{
+		.name		= CONFIG_MTD_MULTI_PHYSMAP_2_NAME,
+		.phys		= CONFIG_MTD_MULTI_PHYSMAP_2_START,
+		.size		= CONFIG_MTD_MULTI_PHYSMAP_2_LEN,
+		.bankwidth	= CONFIG_MTD_MULTI_PHYSMAP_2_WIDTH,
+	},
+#endif
+#if CONFIG_MTD_MULTI_PHYSMAP_3_WIDTH
+	{
+		.name		= CONFIG_MTD_MULTI_PHYSMAP_3_NAME,
+		.phys		= CONFIG_MTD_MULTI_PHYSMAP_3_START,
+		.size		= CONFIG_MTD_MULTI_PHYSMAP_3_LEN,
+		.bankwidth	= CONFIG_MTD_MULTI_PHYSMAP_3_WIDTH,
+	},
+#endif
+#if CONFIG_MTD_MULTI_PHYSMAP_4_WIDTH
+	{
+		.name		= CONFIG_MTD_MULTI_PHYSMAP_4_NAME,
+		.phys		= CONFIG_MTD_MULTI_PHYSMAP_4_START,
+		.size		= CONFIG_MTD_MULTI_PHYSMAP_4_LEN,
+		.bankwidth	= CONFIG_MTD_MULTI_PHYSMAP_4_WIDTH,
+	},
+#endif
+	{
+		.name = NULL,
+	},
+};
+DECLARE_MUTEX(map_mutex);
+
+
+static int map_one(struct map_info *map)
+{
+	struct mtd_info *mtd;
+
+	map->virt = ioremap(map->phys, map->size);
+	if (!map->virt)
+		return -EIO;
+
+	simple_map_init(map);
+
+	mtd = do_map_probe("cfi_probe", map);
+	if (!mtd) {
+		iounmap(map->virt);
+		return -ENXIO;
+	}
+
+	map->map_priv_1 = (unsigned long)mtd;
+	mtd->owner = THIS_MODULE;
+	/* TODO: partitioning */
+	return add_mtd_device(mtd);
+}
+
+
+static void unmap_one(struct map_info *map)
+{
+	struct mtd_info *mtd = (struct mtd_info*)map->map_priv_1;
+
+	if (map->map_priv_2)
+		kfree(map->name);
+
+	if (!map->virt)
+		return;
+
+	BUG_ON(!mtd);
+	BUG_ON(map->map_priv_2 > 1);
+
+	del_mtd_device(mtd);
+	map_destroy(mtd);
+	iounmap(map->virt);
+
+	map->map_priv_1 = 0;
+	map->map_priv_2 = 0;
+	map->virt = NULL;
+}
+
+
+static struct map_info *next_free_map(void)
+{
+	int i;
+	for (i=0; i<NO_DEVICES; i++) {
+		struct map_info *map = &maps[i];
+		if (!map->virt)
+			return map;
+	}
+	return NULL;
+}
+
+
+static int add_one_map(const char *name, unsigned long start,
+		unsigned long len, int width)
+{
+	struct map_info *map = next_free_map();
+	if (!map)
+		return -ENOSPC;
+	
+	map->name = kmalloc(strlen(name)+1, GFP_KERNEL);
+	if (!name)
+		return -ENOMEM;
+
+	strcpy(map->name, name);
+	map->phys = start;
+	map->size = len;
+	map->bankwidth = width;
+	map->map_priv_2 = 1; /* marker to free map->name */
+
+	return map_one(map);
+}
+
+
+static int parse_ulong(unsigned long *num, const char *token)
+{
+	char *endp;
+	unsigned long n;
+
+	n = ustrtoul(token, &endp, 0);
+	if (*endp)
+		return -EINVAL;
+
+	*num = n;
+	return 0;
+}
+
+
+static int parse_uint(unsigned int *num, const char *token)
+{
+	char *endp;
+	unsigned long n;
+
+	n = ustrtoul(token, &endp, 0);
+	if (*endp)
+		return -EINVAL;
+	if ((int)n != n)
+		return -EINVAL;
+
+	*num = n;
+	return 0;
+}
+
+
+static int parse_name(char **pname, const char *token, int limit)
+{
+	size_t len;
+	char *name;
+
+	len = strlen(token) + 1;
+	if (len > limit)
+		return -ENOSPC;
+
+	name = kmalloc(len, GFP_KERNEL);
+	if (!name)
+		return -ENOMEM;
+
+	memcpy(name, token, len);
+
+	*pname = name;
+	return 0;
+}
+
+
+static inline void kill_final_newline(char *str)
+{
+	char *newline = strrchr(str, '\n');
+	if (newline && !newline[1])
+		*newline = 0;
+}
+
+
+#define parse_err(fmt, args...) do {	\
+	printk(KERN_ERR fmt "\n", ## args);	\
+	return 0;			\
+} while(0)
+
+/* mphysmap=name,start,len,width */
+static int mphysmap_setup(const char *val, struct kernel_param *kp)
+{
+	char buf[64+14+14+14], *str = buf;
+	char *token[4];
+	char *name;
+	unsigned long start;
+	unsigned long len;
+	unsigned int width;
+	int i, ret;
+
+	if (strnlen(val, sizeof(buf)) >= sizeof(buf))
+		parse_err("parameter too long");
+
+	strcpy(str, val);
+	kill_final_newline(str);
+
+	for (i=0; i<4; i++)
+		token[i] = strsep(&str, ",");
+
+	if (str)
+		parse_err("too many arguments");
+	if (!token[3])
+		parse_err("not enough arguments");
+
+	ret = parse_name(&name, token[0], 64);
+	if (ret == -ENOMEM)
+		parse_err("out of memory");
+	if (ret == -ENOSPC)
+		parse_err("name too long");
+	if (ret)
+		parse_err("illegal name: %d", ret);
+
+	ret = parse_ulong(&start, token[1]);
+	if (ret)
+		parse_err("illegal start address");
+
+	ret = parse_ulong(&len, token[2]);
+	if (ret)
+		parse_err("illegal length");
+
+	ret = parse_uint(&width, token[3]);
+	if (ret)
+		parse_err("illegal bus width");
+
+	down(&map_mutex);
+	ret = add_one_map(name, start, len, width);
+	up(&map_mutex);
+	if (ret == -ENOSPC)
+		parse_err("no free space for new map");
+	if (ret)
+		parse_err("error while mapping: %d", ret);
+
+	return 0;
+}
+
+
+static int __init mphysmap_init(void)
+{
+	int i;
+	down(&map_mutex);
+	for (i=0; i<NO_DEVICES; i++)
+		map_one(&maps[i]);
+	up(&map_mutex);
+	return 0;
+}
+
+
+static void __exit mphysmap_exit(void)
+{
+	int i;
+	down(&map_mutex);
+	for (i=0; i<NO_DEVICES; i++)
+		unmap_one(&maps[i]);
+	up(&map_mutex);
+}
+
+
+__module_param_call("", mphysmap, mphysmap_setup, NULL, NULL, 0600);
+
+module_init(mphysmap_init);
+module_exit(mphysmap_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jörn Engel <joern at wh.fh-wedelde>");
+MODULE_DESCRIPTION("Generic configurable extensible MTD map driver");

Index: Kconfig
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/maps/Kconfig,v
retrieving revision 1.46
retrieving revision 1.47
diff -u -r1.46 -r1.47
--- Kconfig	2 Mar 2005 14:51:04 -0000	1.46
+++ Kconfig	7 Mar 2005 23:15:47 -0000	1.47
@@ -60,6 +60,92 @@
 	  Ignore this option if you use run-time physmap configuration
 	  (i.e., run-time calling physmap_configure()).
 
+config MTD_MULTI_PHYSMAP
+	tristate "multiple CFI Flash devices in physical memory map"
+	depends on MTD_CFI
+	help
+	  Similar to MTD_PHYSMAP, just allows several seperate mappings.
+
+config MTD_MULTI_PHYSMAP_1_NAME
+	string "1st mapping name"
+	depends on MTD_MULTI_PHYSMAP
+	default ""
+
+config MTD_MULTI_PHYSMAP_1_START
+	hex "1st mapping start"
+	depends on MTD_MULTI_PHYSMAP
+	default "0x00000000"
+
+config MTD_MULTI_PHYSMAP_1_LEN
+	hex "1st mapping length"
+	depends on MTD_MULTI_PHYSMAP
+	default "0x00000000"
+
+config MTD_MULTI_PHYSMAP_1_WIDTH
+	int "1st mapping bus width - 0 disables mapping"
+	depends on MTD_MULTI_PHYSMAP
+	default "2"
+
+config MTD_MULTI_PHYSMAP_2_NAME
+	string "2nd mapping name"
+	depends on MTD_MULTI_PHYSMAP
+	default ""
+
+config MTD_MULTI_PHYSMAP_2_START
+	hex "2nd mapping start"
+	depends on MTD_MULTI_PHYSMAP
+	default "0x00000000"
+
+config MTD_MULTI_PHYSMAP_2_LEN
+	hex "2nd mapping length"
+	depends on MTD_MULTI_PHYSMAP
+	default "0x00000000"
+
+config MTD_MULTI_PHYSMAP_2_WIDTH
+	int "2nd mapping bus width - 0 disables mapping"
+	depends on MTD_MULTI_PHYSMAP
+	default "2"
+
+config MTD_MULTI_PHYSMAP_3_NAME
+	string "3rd mapping name"
+	depends on MTD_MULTI_PHYSMAP
+	default ""
+
+config MTD_MULTI_PHYSMAP_3_START
+	hex "3rd mapping start"
+	depends on MTD_MULTI_PHYSMAP
+	default "0x00000000"
+
+config MTD_MULTI_PHYSMAP_3_LEN
+	hex "3rd mapping length"
+	depends on MTD_MULTI_PHYSMAP
+	default "0x00000000"
+
+config MTD_MULTI_PHYSMAP_3_WIDTH
+	int "3rd mapping bus width - 0 disables mapping"
+	depends on MTD_MULTI_PHYSMAP
+	default "2"
+
+config MTD_MULTI_PHYSMAP_4_NAME
+	string "4th mapping name"
+	depends on MTD_MULTI_PHYSMAP
+	default ""
+
+config MTD_MULTI_PHYSMAP_4_START
+	hex "4th mapping start"
+	depends on MTD_MULTI_PHYSMAP
+	default "0x00000000"
+
+config MTD_MULTI_PHYSMAP_4_LEN
+	hex "4th mapping length"
+	depends on MTD_MULTI_PHYSMAP
+	default "0x00000000"
+
+config MTD_MULTI_PHYSMAP_4_WIDTH
+	int "4th mapping bus width - 0 disables mapping"
+	depends on MTD_MULTI_PHYSMAP
+	default "2"
+
 config MTD_SUN_UFLASH
 	tristate "Sun Microsystems userflash support"
 	depends on (SPARC32 || SPARC64) && MTD_CFI

Index: Makefile.common
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/maps/Makefile.common,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- Makefile.common	2 Mar 2005 14:51:04 -0000	1.26
+++ Makefile.common	7 Mar 2005 23:15:48 -0000	1.27
@@ -26,6 +26,7 @@
 obj-$(CONFIG_MTD_CEIVA)		+= ceiva.o
 obj-$(CONFIG_MTD_OCTAGON)	+= octagon-5066.o
 obj-$(CONFIG_MTD_PHYSMAP)	+= physmap.o 
+obj-$(CONFIG_MTD_MULTI_PHYSMAP)	+= mphysmap.o
 obj-$(CONFIG_MTD_PNC2000)	+= pnc2000.o
 obj-$(CONFIG_MTD_PCMCIA)	+= pcmciamtd.o
 obj-$(CONFIG_MTD_RPXLITE)	+= rpxlite.o





More information about the linux-mtd-cvs mailing list