⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mphysmap.c

📁 老版本的mtd-snap
💻 C
字号:
/* * $Id: mphysmap.c,v 1.2 2005/03/07 23:15:48 joern Exp $ * * Several mappings of NOR chips * * Copyright (c) 2001-2005	J鰎n Engel <joern@wh.fh-wedelde> */#include <linux/kernel.h>#include <linux/module.h>#include <linux/mtd/map.h>#include <linux/mtd/mtd.h>#define NO_DEVICES 8struct 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鰎n Engel <joern@wh.fh-wedelde>");MODULE_DESCRIPTION("Generic configurable extensible MTD map driver");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -