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

📄 diskonchip.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	/* 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 = (void *)this->priv;	unsigned long 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 = (void *)this->priv;	unsigned long 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 = (void *)this->priv;	unsigned long 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 = (void *)this->priv;	unsigned long 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 = (void *)this->priv;	unsigned long 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 = (void *)this->priv;	unsigned long 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 = (void *)this->priv;	unsigned long 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_CTL_CLRNCE);	WriteDOC(floor, docptr, FloorSelect);	WriteDOC(chip, docptr, CDSNDeviceSelect);	doc200x_hwcontrol(mtd, NAND_CTL_SETNCE);	doc->curchip = chip;	doc->curfloor = floor;}static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd){	struct nand_chip *this = mtd->priv;	struct doc_priv *doc = (void *)this->priv;	unsigned long docptr = doc->virtadr;	switch(cmd) {	case NAND_CTL_SETNCE:		doc->CDSNControl |= CDSN_CTRL_CE;		break;	case NAND_CTL_CLRNCE:		doc->CDSNControl &= ~CDSN_CTRL_CE;		break;	case NAND_CTL_SETCLE:		doc->CDSNControl |= CDSN_CTRL_CLE;		break;	case NAND_CTL_CLRCLE:		doc->CDSNControl &= ~CDSN_CTRL_CLE;		break;	case NAND_CTL_SETALE:		doc->CDSNControl |= CDSN_CTRL_ALE;		break;	case NAND_CTL_CLRALE:		doc->CDSNControl &= ~CDSN_CTRL_ALE;		break;	case NAND_CTL_SETWP:		doc->CDSNControl |= CDSN_CTRL_WP;		break;	case NAND_CTL_CLRWP:		doc->CDSNControl &= ~CDSN_CTRL_WP;		break;	}	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);}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 = (void *)this->priv;	unsigned long 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->oobblock) {			/* OOB area */			column -= mtd->oobblock;			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 = (void *)this->priv;	unsigned long 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 = (void *)this->priv;	unsigned long 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 = (void *)this->priv;	unsigned long docptr = doc->virtadr;	/* Prime the ECC engine */	switch(mode) {	case NAND_ECC_READ:		WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);		WriteDOC(DOC_ECC_EN, docptr, Mplus_ECCConf);		break;	case NAND_ECC_WRITE:		WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);		WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, Mplus_ECCConf);		break;	}}/* This code is only called on write */static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat,				 unsigned char *ecc_code){	struct nand_chip *this = mtd->priv;	struct doc_priv *doc = (void *)this->priv;	unsigned long docptr = doc->virtadr;	int i;	int emptymatch = 1;	/* flush the pipeline */	if (DoC_is_2000(doc)) {		WriteDOC(doc->CDSNControl & ~CDSN_CTRL_FLASH_IO, docptr, CDSNControl);		WriteDOC(0, docptr, 2k_CDSN_IO);		WriteDOC(0, docptr, 2k_CDSN_IO);		WriteDOC(0, docptr, 2k_CDSN_IO);		WriteDOC(doc->CDSNControl, docptr, CDSNControl);	} else if (DoC_is_MillenniumPlus(doc)) {		WriteDOC(0, docptr, Mplus_NOP);

⌨️ 快捷键说明

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