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

📄 nettel-uc.c

📁 microwindows移植到S3C44B0的源码
💻 C
字号:
/****************************************************************************//* * Flash memory access on uClinux SnapGear like devices * Copyright (C) 2001-2002, David McCullough <davidm@snapgear.com> *//****************************************************************************/#include <linux/config.h>#include <linux/module.h>#include <linux/types.h>#include <linux/kernel.h>#include <linux/mtd/mtd.h>#ifdef CONFIG_NFTL#include <linux/mtd/nftl.h>#endif#include <linux/mtd/map.h>#include <linux/mtd/partitions.h>#include <linux/fs.h>#include <asm/io.h>#include <asm/delay.h>/****************************************************************************/#define NB_OF(x)  (sizeof(x)/sizeof(x[0]))#define SIZE_128K	(128 * 1024)#define SIZE_1MB	(1024 * 1024)#define SIZE_2MB	(2 * 1024 * 1024)#define SIZE_4MB	(4 * 1024 * 1024)#define SIZE_8MB	(8 * 1024 * 1024)#ifdef CONFIG_COLDFIRE#define FLASH_BASE	0xf0000000#define	BUS_WIDTH	2#endif#ifdef CONFIG_SUPERH#define FLASH_BASE	0x00000000#define	BUS_WIDTH	1#endif/****************************************************************************/static __u8 nettel_read8(struct map_info *map, unsigned long ofs){	return *(__u8 *)(map->map_priv_1 + ofs);}static __u16 nettel_read16(struct map_info *map, unsigned long ofs){	return *(__u16 *)(map->map_priv_1 + ofs);}static __u32 nettel_read32(struct map_info *map, unsigned long ofs){	return *(__u32 *)(map->map_priv_1 + ofs);}static void nettel_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len){	memcpy(to, (void *)(map->map_priv_1 + from), len);}static void nettel_write8(struct map_info *map, __u8 d, unsigned long adr){	*(__u8 *)(map->map_priv_1 + adr) = d;}static void nettel_write16(struct map_info *map, __u16 d, unsigned long adr){	*(__u16 *)(map->map_priv_1 + adr) = d;}static void nettel_write32(struct map_info *map, __u32 d, unsigned long adr){	*(__u32 *)(map->map_priv_1 + adr) = d;}static void nettel_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len){	memcpy((void *)(map->map_priv_1 + to), from, len);}/****************************************************************************/static struct map_info nettel_flash_map = {	name:		"Flash",	read8:		nettel_read8,	read16:		nettel_read16,	read32:		nettel_read32,	copy_from:	nettel_copy_from,	write8:		nettel_write8,	write16:	nettel_write16,	write32:	nettel_write32,	copy_to:	nettel_copy_to,};static struct map_info nettel_ram_map = {	name:		"RAM",	read8:		nettel_read8,	read16:		nettel_read16,	read32:		nettel_read32,	copy_from:	nettel_copy_from,	write8:		nettel_write8,	write16:	nettel_write16,	write32:	nettel_write32,	copy_to:	nettel_copy_to,};static struct mtd_info *ram_mtdinfo;static struct mtd_info *flash_mtdinfo;/****************************************************************************/static struct mtd_partition nettel_romfs[] = {	{ name: "Romfs", offset: 0 }};/****************************************************************************//* *	The layout of our flash,  note the order of the names,  this *	means we use the same major/minor for the same purpose on all *	layouts (when possible) */static struct mtd_partition nettel_128k[] = {	{ name: "Bootloader", offset: 0x00000000, size:   0x00004000 },	{ name: "Bootargs",   offset: 0x00004000, size:   0x00004000 },	{ name: "MAC",        offset: 0x00008000, size:   0x00004000 },	{ name: "Config",     offset: 0x00010000, size:   0x00010000 },	{ name: "Spare",      offset: 0x0000c000, size:   0x00004000 },	{ name: "Flash",      offset: 0 }};static struct mtd_partition nettel_1mb[] = {	{ name: "Bootloader", offset: 0x00000000, size:   0x00004000 },	{ name: "Bootargs",   offset: 0x00004000, size:   0x00002000 },	{ name: "MAC",        offset: 0x00006000, size:   0x00002000 },	{ name: "Config",     offset: 0x000f0000, size:   0x00010000 },	{ name: "Spare",      offset: 0x00008000, size:   0x00008000 },	{ name: "Image",      offset: 0x00010000, size:   0x000e0000 },	{ name: "Flash",      offset: 0 }};static struct mtd_partition nettel_2mb[] = {	{ name: "Bootloader", offset: 0x00000000, size:   0x00004000 },	{ name: "Bootargs",   offset: 0x00004000, size:   0x00002000 },	{ name: "MAC",        offset: 0x00006000, size:   0x00002000 },	{ name: "Config",     offset: 0x00010000, size:   0x00010000 },	{ name: "Spare",      offset: 0x00008000, size:   0x00008000 },	{ name: "Image",      offset: 0x00020000, size:   0x001e0000 },	{ name: "Flash",      offset: 0 }};static struct mtd_partition nettel_4mb[] = {	{ name: "Bootloader", offset: 0x00000000, size:   0x00004000 },	{ name: "Bootargs",   offset: 0x00004000, size:   0x00002000 },	{ name: "MAC",        offset: 0x00006000, size:   0x00002000 },	{ name: "Config",     offset: 0x00010000, size:   0x00010000 },	{ name: "Spare",      offset: 0x00008000, size:   0x00008000 },	{ name: "Image",      offset: 0x00020000, size:   0x001e0000 },	{ name: "Flash",      offset: 0x00000000, size:   0x00200000 },	{ name: "Image2",     offset: 0x00220000, size:   0x001e0000 },	{ name: "Flash2",     offset: 0 }};static struct mtd_partition nettel_8mb[] = {	{ name: "Bootloader", offset: 0x00000000, size:   0x00020000 },	{ name: "Bootargs",   offset: 0x00020000, size:   0x00020000 },	{ name: "MAC",        offset: 0x00040000, size:   0x00020000 },	{ name: "Config",     offset: 0x00080000, size:   0x00080000 },	{ name: "Spare",      offset: 0x00060000, size:   0x00020000 },	{ name: "Image",      offset: 0x00100000, size:   0x00700000 },	{ name: "Flash",      offset: 0 }};/****************************************************************************//* * Find the MTD device with the given name */static struct mtd_info *get_mtd_named(char *name){	int i;	struct mtd_info *mtd;	for (i = 0; i < MAX_MTD_DEVICES; i++) {		mtd = get_mtd_device(NULL, i);		if (mtd) {			if (strcmp(mtd->name, name) == 0)				return(mtd);			put_mtd_device(mtd);		}	}	return(NULL);}/****************************************************************************//* * Erase the configuration file system. * Used to support the software reset button. */static void nettel_erasecallback(struct erase_info *done){	wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv;	wake_up(wait_q);}int flash_eraseconfig(void){	struct mtd_info *mtd;	struct erase_info erase;	DECLARE_WAITQUEUE(wait, current);	wait_queue_head_t wait_q;	int ret;	init_waitqueue_head(&wait_q);	mtd = get_mtd_named("Config");	if (mtd) {		erase.mtd = mtd;		erase.callback = nettel_erasecallback;		erase.callback = 0;		erase.addr = 0;		erase.len = mtd->size;		erase.priv = (u_long)&wait_q;		erase.priv = 0;		set_current_state(TASK_INTERRUPTIBLE);		add_wait_queue(&wait_q, &wait);		ret = MTD_ERASE(mtd, &erase);		if (ret) {			set_current_state(TASK_RUNNING);			remove_wait_queue(&wait_q, &wait);			put_mtd_device(mtd);			return ret;		}		schedule();  /* Wait for erase to finish. */		remove_wait_queue(&wait_q, &wait);				put_mtd_device(mtd);	}	return 0;}/****************************************************************************/static intnettel_point(struct mtd_info *mtd, loff_t from, size_t len,		size_t *retlen, u_char **mtdbuf){	struct map_info *map = (struct map_info *) mtd->priv;	*mtdbuf = (u_char *) (map->map_priv_1 + (int)from);	*retlen = len;	return(0);}/****************************************************************************/static int __initnettel_probe(int ram, unsigned long addr, int size, int buswidth){	struct mtd_info *mymtd;	struct map_info *map_ptr;	if (ram)		map_ptr = &nettel_ram_map;	else		map_ptr = &nettel_flash_map;	map_ptr->buswidth = buswidth;	map_ptr->map_priv_2 = addr;	map_ptr->size = size;	printk(KERN_NOTICE "SnapGear %s probe(0x%lx,%d,%d): %lx at %lx\n",			ram ? "ram" : "flash",			addr, size, buswidth, map_ptr->size, map_ptr->map_priv_2);	map_ptr->map_priv_1 = (unsigned long)			ioremap_nocache(map_ptr->map_priv_2, map_ptr->size);	if (!map_ptr->map_priv_1) {		printk("Failed to ioremap_nocache\n");		return -EIO;	}	if (!ram) {		mymtd = do_map_probe("cfi_probe", map_ptr);		if (!mymtd)			mymtd = do_map_probe("jedec_probe", map_ptr);	} else		mymtd = do_map_probe("map_ram", map_ptr);	if (!mymtd) {		iounmap((void *)map_ptr->map_priv_1);		return -ENXIO;	}			mymtd->module = THIS_MODULE;	mymtd->point = nettel_point;	mymtd->priv = map_ptr;	if (ram) {		ram_mtdinfo = mymtd;		add_mtd_partitions(mymtd, nettel_romfs, NB_OF(nettel_romfs));		return(0);	}	flash_mtdinfo = mymtd;	switch (size) {	case SIZE_128K:		add_mtd_partitions(mymtd, nettel_128k, NB_OF(nettel_128k));		break;	case SIZE_1MB:		add_mtd_partitions(mymtd, nettel_1mb, NB_OF(nettel_1mb));		break;	case SIZE_2MB:		add_mtd_partitions(mymtd, nettel_2mb, NB_OF(nettel_2mb));		break;	case SIZE_4MB:		add_mtd_partitions(mymtd, nettel_4mb, NB_OF(nettel_4mb));		break;	case SIZE_8MB:		add_mtd_partitions(mymtd, nettel_8mb, NB_OF(nettel_8mb));		break;	}	return 0;}/****************************************************************************/int __init nettel_mtd_init(void){	int rc = -1;	struct mtd_info *mtd;	extern char _ebss;	/*	 * I hate this ifdef stuff,  but our HW doesn't always have	 * the same chipsize as the map that we use	 */#if defined(CONFIG_FLASH8MB) || defined(CONFIG_FLASHAUTO)	if (rc != 0)		rc = nettel_probe(0, FLASH_BASE, SIZE_8MB, BUS_WIDTH);#endif#if defined(CONFIG_FLASH4MB) || defined(CONFIG_FLASHAUTO)	if (rc != 0)		rc = nettel_probe(0, FLASH_BASE, SIZE_4MB, BUS_WIDTH);#endif#if defined(CONFIG_FLASH2MB) || defined(CONFIG_FLASHAUTO)	if (rc != 0)		rc = nettel_probe(0, FLASH_BASE, SIZE_2MB, BUS_WIDTH);#endif#if defined(CONFIG_FLASH1MB) || defined(CONFIG_FLASHAUTO)	if (rc != 0)		rc = nettel_probe(0, FLASH_BASE, SIZE_1MB, BUS_WIDTH);#endif#if defined(CONFIG_FLASH128K) || defined(CONFIG_FLASHAUTO)	if (rc != 0)		rc = nettel_probe(0, FLASH_BASE, SIZE_128K, BUS_WIDTH);#endif#ifdef CONFIG_COLDFIRE	/*	 * Map in the filesystem from RAM last so that,  if the filesystem	 * is not in RAM for some reason we do not change the minor/major	 * for the flash devices	 */#ifndef CONFIG_ROMFS_FROM_ROM	if (0 != nettel_probe(1, (unsigned long) &_ebss,			PAGE_ALIGN(* (unsigned long *)((&_ebss) + 8)), 4))		printk("Failed to probe RAM filesystem\n");#else	{		unsigned long start_area;		unsigned char *sp, *ep;		size_t len;		start_area = (unsigned long) &_ebss;		if (strncmp((char *) start_area, "-rom1fs-", 8) != 0) {			mtd = get_mtd_named("Image");			if (mtd && mtd->point) {				if ((*mtd->point)(mtd, 0, mtd->size, &len, &sp) == 0) {					ep = sp + len;					while (sp < ep && strncmp(sp, "-rom1fs-", 8) != 0)						sp++;					if (sp < ep)						start_area = (unsigned long) sp;				}			}			if (mtd)				put_mtd_device(mtd);		}		if (0 != nettel_probe(1, start_area,				PAGE_ALIGN(* (unsigned long *)(start_area + 8)), 4))			printk("Failed to probe RAM filesystem\n");	}#endif		mtd = get_mtd_named("Romfs");	if (mtd) {		ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index);		put_mtd_device(mtd);	}#endif#ifdef CONFIG_SH_SNAPGEAR4100{	extern int _end;	char *cp = (char *) &_end;	if (memcmp(cp, "-rom1fs-", 8) != 0)		ROOT_DEV = MKDEV(NFTL_MAJOR, 1);}#endif	return(rc);}/****************************************************************************/static void __exit nettel_mtd_cleanup(void){	if (flash_mtdinfo) {		del_mtd_partitions(flash_mtdinfo);		map_destroy(flash_mtdinfo);		flash_mtdinfo = NULL;	}	if (ram_mtdinfo) {		del_mtd_partitions(ram_mtdinfo);		map_destroy(ram_mtdinfo);		ram_mtdinfo = NULL;	}	if (nettel_ram_map.map_priv_1) {		iounmap((void *)nettel_ram_map.map_priv_1);		nettel_ram_map.map_priv_1 = 0;	}	if (nettel_flash_map.map_priv_1) {		iounmap((void *)nettel_flash_map.map_priv_1);		nettel_flash_map.map_priv_1 = 0;	}}/****************************************************************************/module_init(nettel_mtd_init);module_exit(nettel_mtd_cleanup);MODULE_LICENSE("GPL");MODULE_AUTHOR("David McCullough <davidm@snapgear.com>");MODULE_DESCRIPTION("SnapGear/SecureEdge FLASH support for uClinux");/****************************************************************************/

⌨️ 快捷键说明

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