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

📄 mtdcore.c

📁 SMDK2440 boot code, base on vivi
💻 C
字号:
/* * vivi/drivers/mtd/mtdcore.c:  *   core for MTD * * Copyright (c) 2001-2004 MIZI Research, Inc. All rights reserved. *  * $Id: mtdcore.c,v 1.33 2004/05/24 06:56:40 nandy Exp $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * *  * 2001-12-23  Janghoon Lyu *             - Initial code. * * 2002-02-23  Janghoon Lyu *              -  Add flash commands. * * 2004-03-23 Janghoon Lyu *             - Update MTDs. */#include <config.h>#include <machine.h>#include <mtd/partitions.h>#include <mtd/mtd.h>#include <command.h>#include <serial.h>#include <vstring.h>#include <types.h>#include <errno.h>#include <progressbar.h>extern int bon_do_read(int npart, char *buf, unsigned long pos, size_t size);extern int bon_do_write(int npart, char *buf, unsigned long pos, size_t size);extern int doc_do_write(mtd_partition_t *part, size_t len, const u_char *buf);extern int doc_do_read(mtd_partition_t *part, u_char *buf);struct mtd_info *mymtd = NULL;int add_mtd_device (struct mtd_info *mtd){	mymtd = mtd;	return 0;}int del_mtd_device (struct mtd_info *mtd){	mymtd = NULL;	return 0;}int mtd_read_raw(u_char *buf, ulong ofs, size_t count){	int retlen;	if (MTD_READ(mymtd, ofs, count, &retlen, buf) < 0)		return 1;	if (retlen != count)		return 1;	return 0;}int mtd_write_raw(u_char *buf, ulong ofs, size_t count){	int retlen;	ulong len;	struct erase_info ei;	len = (((count >> 14) + 1) << 14);	ei.mtd = mymtd;	ei.addr = ofs;	ei.len = len;	ei.retries = 0;	ei.callback = NULL;	if (MTD_ERASE(mymtd, &ei) < 0)		return 1; 	len = (((count >> 9) + 1) << 9);	if (MTD_WRITE(mymtd, ofs, len, &retlen, buf) < 0)		return 1;	if (retlen != len)		return 1;	return 0;}int mtd_read_part(char *name, u_char *buf, size_t count){	mtd_partition_t *part;	part = get_mtd_partition(name);	if (part == NULL) {		printk("Unable to find the '%s' partition\n",name);		return 1;	}	switch (part->flag) {	case MF_BON:#ifdef CONFIG_MTD_NAND_BON#if 0		if (!count)			count = part->used;#endif		/* 亲惑 颇萍记狼 矫累困摹俊辑. */		bon_do_read(*(int *)(part->priv), buf, 0, part->size);#else		return 1;#endif /* CONFIG_MTD_NAND_BON */		break;	case MF_DOC:#ifdef CONFIG_MTD_MDOCG3		return doc_do_read(part, buf);#else		return 1;#endif /* CONFIG_MTD_MDOCG3 */		break;	case MF_RAW:		return mtd_read_raw(buf, part->offset, part->size);	default:		return 1;	}	return 0;}int mtd_write_part(char *name, u_char *buf, size_t count){	mtd_partition_t *part;	part = get_mtd_partition(name);	if (part == NULL) {		printk("Unable to find the '%s' partition\n",name);		return 1;	}	switch (part->flag) {	case MF_BON:#ifdef CONFIG_MTD_NAND_BON		/* 亲惑 颇萍记狼 矫累困摹俊辑. */		bon_do_write(*(int *)(part->priv), buf, 0, count);#else		return 1;#endif /* CONFIG_MTD_NAND_BON */		break;	case MF_DOC:#ifdef CONFIG_MTD_MDOCG3		return doc_do_write(part, buf, count);#else		return 1;#endif /* CONFIG_MTD_MDOCG3 */	  	break;	case MF_RAW:		return mtd_write_raw(buf, part->offset, count);	default:		return 1;	}	return 0;}static intdo_unlock(struct mtd_info *mtd, loff_t ofs, size_t len){	int ret;	printk("Unlocking... ");	ret = mtd->unlock(mtd, ofs, len);	if (ret) {		printk("fail\n");		return -1;	}	printk("ok\n");	return 0;}static intdo_lock(struct mtd_info *mtd, loff_t ofs, size_t len){   	int ret;	printk("Locking...   ");	ret = mtd->lock(mtd, ofs, len);	if (ret < 0) {		printk("fail\n");		return ret;	}	printk("ok\n");	return 0;}static intdo_erase(struct mtd_info *mtd, loff_t ofs, size_t len){	int ret = 0;	struct erase_info erase;	printk("Erasing 0x%Lx - 0x%Lx... ", ofs, ofs+len);	progressbar_set_total(len);	while (len > 0) {		erase.addr = ofs;		erase.len = mtd->erasesize;		ret = mtd->erase(mtd, &erase);		if (ret)			break;		len -= mtd->erasesize;		ofs += mtd->erasesize;		progressbar(len, BAR_DECREASE);	}	if (ret)		printk("FAIL\n");	else		printk("OK\n");	return 0;}static void do_dump(struct mtd_info *mtd, loff_t ofs){	unsigned char readbuf[512];	unsigned char oobbuf[16];	int i;	int bs = 512;	printk("Dump 0x%x:\n", ofs);	if (!mtd->read_ecc) {		printk("There is no read_ecc()");		return;	}	mtd->read_ecc(mtd, ofs, bs, NULL, readbuf, NULL, NULL);	for (i = 0; i < bs; i+= 16) {		printk("0x%08x: %02x %02x %02x %02x %02x %02x %02x %02x "			"%02x %02x %02x %02x %02x %02x %02x %02x\n",			(unsigned int)(ofs + i), 			readbuf[i], readbuf[i+1], readbuf[i+2], 			readbuf[i+3], readbuf[i+4], readbuf[i+5], 			readbuf[i+6], readbuf[i+7], readbuf[i+8], 			readbuf[i+9], readbuf[i+10], readbuf[i+11], 			readbuf[i+12], readbuf[i+13], readbuf[i+14], 			readbuf[i+15]);	}	if (!mtd->read_oob) {		printk("There is no read_oob()");		return;	}	mtd->read_oob(mtd, ofs, mtd->oobsize, NULL, oobbuf);	if (mtd->oobsize == 16) {		printk("OOB Data: %02x %02x %02x %02x %02x %02x %02x %02x "			"%02x %02x %02x %02x %02x %02x %02x %02x\n",			oobbuf[0], oobbuf[1], oobbuf[2],			oobbuf[3], oobbuf[4], oobbuf[5],			oobbuf[6], oobbuf[7], oobbuf[8],			oobbuf[9], oobbuf[10], oobbuf[11],			oobbuf[12], oobbuf[13], oobbuf[14],			oobbuf[15]);	} else {		printk("OOB Data: %02x %02x %02x %02x %02x %02x %02x %02x",			oobbuf[0], oobbuf[1], oobbuf[2],			oobbuf[3], oobbuf[4], oobbuf[5],			oobbuf[6], oobbuf[7]);	}}static void usage(void){	printk("\nUsage:\n"		"  flash erase <offset> <length>       - erase blocks\n"		"  flash erase all                     - erase all blocks\n"		"  flash lock <offset> <length>        - lock blocks\n"		"  flash unlock <offset> <length>      - unlock blocks\n"		"  flash dump <offset>                 - dump 512 bytes\n"		"  flash ee                            - erase bad block\n"  		"  flash de                            - don't erase bad block\n"		"\n");}#ifdef CONFIG_MTD_NANDextern void enable_bad_block_erase(void);extern void disable_bad_block_erase(void);#endif /* CONFIG_MTD_NAND */void command_flash(int argc, const char *argv[]){	struct mtd_info *mtd = mymtd;	mtd_partition_t *part = NULL;	ulong offset = ~0, size = 0;	if (mtd == NULL) {		printk("Error: Can not find MTD information\n");		return;	}	switch (argc) {	case 2:		if (strncmp("help", argv[1], 4) == 0) {			usage();			return;		}#ifdef CONFIG_MTD_NAND		if (strncmp("ee", argv[1], 2) == 0) {			enable_bad_block_erase();			return;		}		if (strncmp("de", argv[1], 2) == 0) {			disable_bad_block_erase();			return;		}#endif /* CONFIG_MTD_NAND */		break;	case 3:		if (strncmp("dump", argv[1], 4) == 0) {			offset = simple_strtoul(argv[2], NULL, 0);			do_dump(mtd, offset);			return;		}		if (strncmp("erase", argv[1], 5) == 0) {			offset = 0;			size = mtd->size;			do_erase(mtd, offset, size);			return;		}		part = get_mtd_partition(argv[2]);		offset = part->offset;		size = part->size;		break;	case 4:		offset = simple_strtoul(argv[2], NULL, 0);		size = simple_strtoul(argv[3], NULL, 0);		break;	default:		usage();		return;	}	if (strncmp("lock", argv[1], 4) == 0) {		do_lock(mtd, offset, size);	} else if (strncmp("unlock", argv[1], 6) == 0) {		do_unlock(mtd, offset, size);	} else if (strncmp("erase", argv[1], 5) == 0) {		do_erase(mtd, offset, size);	} else {		usage();	}}static user_command_t flash_cmd = {	"flash",	command_flash,	NULL};extern int s3c2410_nand_init(void);extern int mp2520f_nand_init(void);extern int bon_init(void);extern int doc_init(void);extern user_command_t nandtst_cmd;extern int s3c24a0_nand_init(void);int mtd_dev_init(void){	int ret = 0;#if defined(CONFIG_MTD_NAND_S3C2410)	ret = s3c2410_nand_init();#elif defined(CONFIG_MTD_NAND_MMSP2)	ret = mp2520f_nand_init();#elif defined(CONFIG_MTD_NAND_S3C24A0)	ret = s3c24a0_nand_init();#elif defined(CONFIG_MTD_MDOCG3)	return doc_init();#else	ret = 1;#endif	if (ret)		return 1;#ifdef CONFIG_MTD_NAND_BON	ret = bon_init();#endif#ifdef CONFIG_MTD_NAND_TESTCMD	add_command(&nandtst_cmd);#endif	add_command(&flash_cmd);	return ret;}

⌨️ 快捷键说明

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