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

📄 diskonchip.c

📁 基于linux-2.6.28的mtd驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
	/* Find out what the first chip is */	mfrid = doc200x_ident_chip(mtd, 0);	/* Find how many chips in each floor. */	for (i = 1; i < 4; i++) {		if (doc200x_ident_chip(mtd, i) != mfrid)			break;	}	doc->chips_per_floor = i;	printk(KERN_DEBUG "Detected %d chips per floor.\n", i);}static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this){	struct doc_priv *doc = this->priv;	int status;	DoC_WaitReady(doc);	this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);	DoC_WaitReady(doc);	status = (int)this->read_byte(mtd);	return status;}static void doc2001_write_byte(struct mtd_info *mtd, u_char datum){	struct nand_chip *this = mtd->priv;	struct doc_priv *doc = this->priv;	void __iomem *docptr = doc->virtadr;	WriteDOC(datum, docptr, CDSNSlowIO);	WriteDOC(datum, docptr, Mil_CDSN_IO);	WriteDOC(datum, docptr, WritePipeTerm);}static u_char doc2001_read_byte(struct mtd_info *mtd){	struct nand_chip *this = mtd->priv;	struct doc_priv *doc = this->priv;	void __iomem *docptr = doc->virtadr;	//ReadDOC(docptr, CDSNSlowIO);	/* 11.4.5 -- delay twice to allow extended length cycle */	DoC_Delay(doc, 2);	ReadDOC(docptr, ReadPipeInit);	//return ReadDOC(docptr, Mil_CDSN_IO);	return ReadDOC(docptr, LastDataRead);}static void doc2001_writebuf(struct mtd_info *mtd, const u_char *buf, int len){	struct nand_chip *this = mtd->priv;	struct doc_priv *doc = this->priv;	void __iomem *docptr = doc->virtadr;	int i;	for (i = 0; i < len; i++)		WriteDOC_(buf[i], docptr, DoC_Mil_CDSN_IO + i);	/* Terminate write pipeline */	WriteDOC(0x00, docptr, WritePipeTerm);}static void doc2001_readbuf(struct mtd_info *mtd, u_char *buf, int len){	struct nand_chip *this = mtd->priv;	struct doc_priv *doc = this->priv;	void __iomem *docptr = doc->virtadr;	int i;	/* Start read pipeline */	ReadDOC(docptr, ReadPipeInit);	for (i = 0; i < len - 1; i++)		buf[i] = ReadDOC(docptr, Mil_CDSN_IO + (i & 0xff));	/* Terminate read pipeline */	buf[i] = ReadDOC(docptr, LastDataRead);}static int doc2001_verifybuf(struct mtd_info *mtd, const u_char *buf, int len){	struct nand_chip *this = mtd->priv;	struct doc_priv *doc = this->priv;	void __iomem *docptr = doc->virtadr;	int i;	/* Start read pipeline */	ReadDOC(docptr, ReadPipeInit);	for (i = 0; i < len - 1; i++)		if (buf[i] != ReadDOC(docptr, Mil_CDSN_IO)) {			ReadDOC(docptr, LastDataRead);			return i;		}	if (buf[i] != ReadDOC(docptr, LastDataRead))		return i;	return 0;}static u_char doc2001plus_read_byte(struct mtd_info *mtd){	struct nand_chip *this = mtd->priv;	struct doc_priv *doc = this->priv;	void __iomem *docptr = doc->virtadr;	u_char ret;	ReadDOC(docptr, Mplus_ReadPipeInit);	ReadDOC(docptr, Mplus_ReadPipeInit);	ret = ReadDOC(docptr, Mplus_LastDataRead);	if (debug)		printk("read_byte returns %02x\n", ret);	return ret;}static void doc2001plus_writebuf(struct mtd_info *mtd, const u_char *buf, int len){	struct nand_chip *this = mtd->priv;	struct doc_priv *doc = this->priv;	void __iomem *docptr = doc->virtadr;	int i;	if (debug)		printk("writebuf of %d bytes: ", len);	for (i = 0; i < len; i++) {		WriteDOC_(buf[i], docptr, DoC_Mil_CDSN_IO + i);		if (debug && i < 16)			printk("%02x ", buf[i]);	}	if (debug)		printk("\n");}static void doc2001plus_readbuf(struct mtd_info *mtd, u_char *buf, int len){	struct nand_chip *this = mtd->priv;	struct doc_priv *doc = this->priv;	void __iomem *docptr = doc->virtadr;	int i;	if (debug)		printk("readbuf of %d bytes: ", len);	/* Start read pipeline */	ReadDOC(docptr, Mplus_ReadPipeInit);	ReadDOC(docptr, Mplus_ReadPipeInit);	for (i = 0; i < len - 2; i++) {		buf[i] = ReadDOC(docptr, Mil_CDSN_IO);		if (debug && i < 16)			printk("%02x ", buf[i]);	}	/* Terminate read pipeline */	buf[len - 2] = ReadDOC(docptr, Mplus_LastDataRead);	if (debug && i < 16)		printk("%02x ", buf[len - 2]);	buf[len - 1] = ReadDOC(docptr, Mplus_LastDataRead);	if (debug && i < 16)		printk("%02x ", buf[len - 1]);	if (debug)		printk("\n");}static int doc2001plus_verifybuf(struct mtd_info *mtd, const u_char *buf, int len){	struct nand_chip *this = mtd->priv;	struct doc_priv *doc = this->priv;	void __iomem *docptr = doc->virtadr;	int i;	if (debug)		printk("verifybuf of %d bytes: ", len);	/* Start read pipeline */	ReadDOC(docptr, Mplus_ReadPipeInit);	ReadDOC(docptr, Mplus_ReadPipeInit);	for (i = 0; i < len - 2; i++)		if (buf[i] != ReadDOC(docptr, Mil_CDSN_IO)) {			ReadDOC(docptr, Mplus_LastDataRead);			ReadDOC(docptr, Mplus_LastDataRead);			return i;		}	if (buf[len - 2] != ReadDOC(docptr, Mplus_LastDataRead))		return len - 2;	if (buf[len - 1] != ReadDOC(docptr, Mplus_LastDataRead))		return len - 1;	return 0;}static void doc2001plus_select_chip(struct mtd_info *mtd, int chip){	struct nand_chip *this = mtd->priv;	struct doc_priv *doc = this->priv;	void __iomem *docptr = doc->virtadr;	int floor = 0;	if (debug)		printk("select chip (%d)\n", chip);	if (chip == -1) {		/* Disable flash internally */		WriteDOC(0, docptr, Mplus_FlashSelect);		return;	}	floor = chip / doc->chips_per_floor;	chip -= (floor * doc->chips_per_floor);	/* Assert ChipEnable and deassert WriteProtect */	WriteDOC((DOC_FLASH_CE), docptr, Mplus_FlashSelect);	this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);	doc->curchip = chip;	doc->curfloor = floor;}static void doc200x_select_chip(struct mtd_info *mtd, int chip){	struct nand_chip *this = mtd->priv;	struct doc_priv *doc = this->priv;	void __iomem *docptr = doc->virtadr;	int floor = 0;	if (debug)		printk("select chip (%d)\n", chip);	if (chip == -1)		return;	floor = chip / doc->chips_per_floor;	chip -= (floor * doc->chips_per_floor);	/* 11.4.4 -- deassert CE before changing chip */	doc200x_hwcontrol(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);	WriteDOC(floor, docptr, FloorSelect);	WriteDOC(chip, docptr, CDSNDeviceSelect);	doc200x_hwcontrol(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);	doc->curchip = chip;	doc->curfloor = floor;}#define CDSN_CTRL_MSK (CDSN_CTRL_CE | CDSN_CTRL_CLE | CDSN_CTRL_ALE)static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd,			      unsigned int ctrl){	struct nand_chip *this = mtd->priv;	struct doc_priv *doc = this->priv;	void __iomem *docptr = doc->virtadr;	if (ctrl & NAND_CTRL_CHANGE) {		doc->CDSNControl &= ~CDSN_CTRL_MSK;		doc->CDSNControl |= ctrl & CDSN_CTRL_MSK;		if (debug)			printk("hwcontrol(%d): %02x\n", cmd, doc->CDSNControl);		WriteDOC(doc->CDSNControl, docptr, CDSNControl);		/* 11.4.3 -- 4 NOPs after CSDNControl write */		DoC_Delay(doc, 4);	}	if (cmd != NAND_CMD_NONE) {		if (DoC_is_2000(doc))			doc2000_write_byte(mtd, cmd);		else			doc2001_write_byte(mtd, cmd);	}}static void doc2001plus_command(struct mtd_info *mtd, unsigned command, int column, int page_addr){	struct nand_chip *this = mtd->priv;	struct doc_priv *doc = this->priv;	void __iomem *docptr = doc->virtadr;	/*	 * Must terminate write pipeline before sending any commands	 * to the device.	 */	if (command == NAND_CMD_PAGEPROG) {		WriteDOC(0x00, docptr, Mplus_WritePipeTerm);		WriteDOC(0x00, docptr, Mplus_WritePipeTerm);	}	/*	 * Write out the command to the device.	 */	if (command == NAND_CMD_SEQIN) {		int readcmd;		if (column >= mtd->writesize) {			/* OOB area */			column -= mtd->writesize;			readcmd = NAND_CMD_READOOB;		} else if (column < 256) {			/* First 256 bytes --> READ0 */			readcmd = NAND_CMD_READ0;		} else {			column -= 256;			readcmd = NAND_CMD_READ1;		}		WriteDOC(readcmd, docptr, Mplus_FlashCmd);	}	WriteDOC(command, docptr, Mplus_FlashCmd);	WriteDOC(0, docptr, Mplus_WritePipeTerm);	WriteDOC(0, docptr, Mplus_WritePipeTerm);	if (column != -1 || page_addr != -1) {		/* Serially input address */		if (column != -1) {			/* Adjust columns for 16 bit buswidth */			if (this->options & NAND_BUSWIDTH_16)				column >>= 1;			WriteDOC(column, docptr, Mplus_FlashAddress);		}		if (page_addr != -1) {			WriteDOC((unsigned char)(page_addr & 0xff), docptr, Mplus_FlashAddress);			WriteDOC((unsigned char)((page_addr >> 8) & 0xff), docptr, Mplus_FlashAddress);			/* One more address cycle for higher density devices */			if (this->chipsize & 0x0c000000) {				WriteDOC((unsigned char)((page_addr >> 16) & 0x0f), docptr, Mplus_FlashAddress);				printk("high density\n");			}		}		WriteDOC(0, docptr, Mplus_WritePipeTerm);		WriteDOC(0, docptr, Mplus_WritePipeTerm);		/* deassert ALE */		if (command == NAND_CMD_READ0 || command == NAND_CMD_READ1 ||		    command == NAND_CMD_READOOB || command == NAND_CMD_READID)			WriteDOC(0, docptr, Mplus_FlashControl);	}	/*	 * program and erase have their own busy handlers	 * status and sequential in needs no delay	 */	switch (command) {	case NAND_CMD_PAGEPROG:	case NAND_CMD_ERASE1:	case NAND_CMD_ERASE2:	case NAND_CMD_SEQIN:	case NAND_CMD_STATUS:		return;	case NAND_CMD_RESET:		if (this->dev_ready)			break;		udelay(this->chip_delay);		WriteDOC(NAND_CMD_STATUS, docptr, Mplus_FlashCmd);		WriteDOC(0, docptr, Mplus_WritePipeTerm);		WriteDOC(0, docptr, Mplus_WritePipeTerm);		while (!(this->read_byte(mtd) & 0x40)) ;		return;		/* This applies to read commands */	default:		/*		 * If we don't have access to the busy pin, we apply the given		 * command delay		 */		if (!this->dev_ready) {			udelay(this->chip_delay);			return;		}	}	/* Apply this short delay always to ensure that we do wait tWB in	 * any case on any machine. */	ndelay(100);	/* wait until command is processed */	while (!this->dev_ready(mtd)) ;}static int doc200x_dev_ready(struct mtd_info *mtd){	struct nand_chip *this = mtd->priv;	struct doc_priv *doc = this->priv;	void __iomem *docptr = doc->virtadr;	if (DoC_is_MillenniumPlus(doc)) {		/* 11.4.2 -- must NOP four times before checking FR/B# */		DoC_Delay(doc, 4);		if ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) {			if (debug)				printk("not ready\n");			return 0;		}		if (debug)			printk("was ready\n");		return 1;	} else {		/* 11.4.2 -- must NOP four times before checking FR/B# */		DoC_Delay(doc, 4);		if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {			if (debug)				printk("not ready\n");			return 0;		}		/* 11.4.2 -- Must NOP twice if it's ready */		DoC_Delay(doc, 2);		if (debug)			printk("was ready\n");		return 1;	}}static int doc200x_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip){	/* This is our last resort if we couldn't find or create a BBT.  Just	   pretend all blocks are good. */	return 0;}static void doc200x_enable_hwecc(struct mtd_info *mtd, int mode){	struct nand_chip *this = mtd->priv;	struct doc_priv *doc = this->priv;	void __iomem *docptr = doc->virtadr;	/* Prime the ECC engine */	switch (mode) {	case NAND_ECC_READ:		WriteDOC(DOC_ECC_RESET, docptr, ECCConf);		WriteDOC(DOC_ECC_EN, docptr, ECCConf);		break;	case NAND_ECC_WRITE:		WriteDOC(DOC_ECC_RESET, docptr, ECCConf);		WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf);		break;	}}static void doc2001plus_enable_hwecc(struct mtd_info *mtd, int mode){	struct nand_chip *this = mtd->priv;	struct doc_priv *doc = this->priv;	void __iomem *docptr = doc->virtadr;	/* Prime the ECC engine */	switch (mode) {

⌨️ 快捷键说明

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