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

📄 doc2001plus.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
	DoC_CheckASIC(docptr);	/* Find the chip which is to be used and select it */	if (this->curfloor != mychip->floor) {		DoC_SelectFloor(docptr, mychip->floor);		DoC_SelectChip(docptr, mychip->chip);	} else if (this->curchip != mychip->chip) {		DoC_SelectChip(docptr, mychip->chip);	}	this->curfloor = mychip->floor;	this->curchip = mychip->chip;	/* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */	WriteDOC(DOC_FLASH_CE, docptr, Mplus_FlashSelect);	/* Reset the chip, see Software Requirement 11.4 item 1. */	DoC_Command(docptr, NAND_CMD_RESET, 0);	DoC_WaitReady(docptr);	/* Set device to appropriate plane of flash */	fto = to;	WriteDOC(DoC_GetDataOffset(mtd, &fto), docptr, Mplus_FlashCmd);	/* On interleaved devices the flags for 2nd half 512 are before data */	if (eccbuf && before)		fto -= 2;	/* issue the Serial Data In command to initial the Page Program process */	DoC_Command(docptr, NAND_CMD_SEQIN, 0x00);	DoC_Address(this, 3, fto, 0x00, 0x00);	/* Disable the ECC engine */	WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);	if (eccbuf) {		if (before) {			/* Write the block status BLOCK_USED (0x5555) */			WriteDOC(0x55, docptr, Mil_CDSN_IO);			WriteDOC(0x55, docptr, Mil_CDSN_IO);		}		/* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/		WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, Mplus_ECCConf);	}	MemWriteDOC(docptr, (unsigned char *) buf, len);	if (eccbuf) {		/* Write ECC data to flash, the ECC info is generated by		   the DiskOnChip ECC logic see Reed-Solomon EDC/ECC 11.1 */		DoC_Delay(docptr, 3);		/* Read the ECC data through the DiskOnChip ECC logic */		for (i = 0; i < 6; i++)			eccbuf[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i);		/* disable the ECC engine */		WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf);		/* Write the ECC data to flash */		MemWriteDOC(docptr, eccbuf, 6);		if (!before) {			/* Write the block status BLOCK_USED (0x5555) */			WriteDOC(0x55, docptr, Mil_CDSN_IO+6);			WriteDOC(0x55, docptr, Mil_CDSN_IO+7);		}#ifdef PSYCHO_DEBUG		printk("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",		       (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],		       eccbuf[4], eccbuf[5]);#endif	}	WriteDOC(0x00, docptr, Mplus_WritePipeTerm);	WriteDOC(0x00, docptr, Mplus_WritePipeTerm);	/* Commit the Page Program command and wait for ready	   see Software Requirement 11.4 item 1.*/	DoC_Command(docptr, NAND_CMD_PAGEPROG, 0x00);	DoC_WaitReady(docptr);	/* Read the status of the flash device through CDSN IO register	   see Software Requirement 11.4 item 5.*/	DoC_Command(docptr, NAND_CMD_STATUS, 0);	dummy = ReadDOC(docptr, Mplus_ReadPipeInit);	dummy = ReadDOC(docptr, Mplus_ReadPipeInit);	DoC_Delay(docptr, 2);	if ((dummy = ReadDOC(docptr, Mplus_LastDataRead)) & 1) {		printk("MTD: Error 0x%x programming at 0x%x\n", dummy, (int)to);		/* Error in programming		   FIXME: implement Bad Block Replacement (in nftl.c ??) */		*retlen = 0;		ret = -EIO;	}	dummy = ReadDOC(docptr, Mplus_LastDataRead);	/* Disable flash internally */	WriteDOC(0, docptr, Mplus_FlashSelect);	/* Let the caller know we completed it */	*retlen = len;	return ret;}static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,			size_t *retlen, u_char *buf){	loff_t fofs, base;	struct DiskOnChip *this = mtd->priv;	void __iomem * docptr = this->virtadr;	struct Nand *mychip = &this->chips[ofs >> this->chipshift];	size_t i, size, got, want;	DoC_CheckASIC(docptr);	/* Find the chip which is to be used and select it */	if (this->curfloor != mychip->floor) {		DoC_SelectFloor(docptr, mychip->floor);		DoC_SelectChip(docptr, mychip->chip);	} else if (this->curchip != mychip->chip) {		DoC_SelectChip(docptr, mychip->chip);	}	this->curfloor = mychip->floor;	this->curchip = mychip->chip;	/* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */	WriteDOC((DOC_FLASH_CE | DOC_FLASH_WP), docptr, Mplus_FlashSelect);	/* disable the ECC engine */	WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);	DoC_WaitReady(docptr);	/* Maximum of 16 bytes in the OOB region, so limit read to that */	if (len > 16)		len = 16;	got = 0;	want = len;	for (i = 0; ((i < 3) && (want > 0)); i++) {		/* Figure out which region we are accessing... */		fofs = ofs;		base = ofs & 0xf;		if (!this->interleave) {			DoC_Command(docptr, NAND_CMD_READOOB, 0);			size = 16 - base;		} else if (base < 6) {			DoC_Command(docptr, DoC_GetECCOffset(mtd, &fofs), 0);			size = 6 - base;		} else if (base < 8) {			DoC_Command(docptr, DoC_GetFlagsOffset(mtd, &fofs), 0);			size = 8 - base;		} else {			DoC_Command(docptr, DoC_GetHdrOffset(mtd, &fofs), 0);			size = 16 - base;		}		if (size > want)			size = want;		/* Issue read command */		DoC_Address(this, 3, fofs, 0, 0x00);		WriteDOC(0, docptr, Mplus_FlashControl);		DoC_WaitReady(docptr);		ReadDOC(docptr, Mplus_ReadPipeInit);		ReadDOC(docptr, Mplus_ReadPipeInit);		MemReadDOC(docptr, &buf[got], size - 2);		buf[got + size - 2] = ReadDOC(docptr, Mplus_LastDataRead);		buf[got + size - 1] = ReadDOC(docptr, Mplus_LastDataRead);		ofs += size;		got += size;		want -= size;	}	/* Disable flash internally */	WriteDOC(0, docptr, Mplus_FlashSelect);	*retlen = len;	return 0;}static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,			 size_t *retlen, const u_char *buf){	volatile char dummy;	loff_t fofs, base;	struct DiskOnChip *this = mtd->priv;	void __iomem * docptr = this->virtadr;	struct Nand *mychip = &this->chips[ofs >> this->chipshift];	size_t i, size, got, want;	int ret = 0;	DoC_CheckASIC(docptr);	/* Find the chip which is to be used and select it */	if (this->curfloor != mychip->floor) {		DoC_SelectFloor(docptr, mychip->floor);		DoC_SelectChip(docptr, mychip->chip);	} else if (this->curchip != mychip->chip) {		DoC_SelectChip(docptr, mychip->chip);	}	this->curfloor = mychip->floor;	this->curchip = mychip->chip;	/* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */	WriteDOC(DOC_FLASH_CE, docptr, Mplus_FlashSelect);	/* Maximum of 16 bytes in the OOB region, so limit write to that */	if (len > 16)		len = 16;	got = 0;	want = len;	for (i = 0; ((i < 3) && (want > 0)); i++) {		/* Reset the chip, see Software Requirement 11.4 item 1. */		DoC_Command(docptr, NAND_CMD_RESET, 0);		DoC_WaitReady(docptr);		/* Figure out which region we are accessing... */		fofs = ofs;		base = ofs & 0x0f;		if (!this->interleave) {			WriteDOC(NAND_CMD_READOOB, docptr, Mplus_FlashCmd);			size = 16 - base;		} else if (base < 6) {			WriteDOC(DoC_GetECCOffset(mtd, &fofs), docptr, Mplus_FlashCmd);			size = 6 - base;		} else if (base < 8) {			WriteDOC(DoC_GetFlagsOffset(mtd, &fofs), docptr, Mplus_FlashCmd);			size = 8 - base;		} else {			WriteDOC(DoC_GetHdrOffset(mtd, &fofs), docptr, Mplus_FlashCmd);			size = 16 - base;		}		if (size > want)			size = want;		/* Issue the Serial Data In command to initial the Page Program process */		DoC_Command(docptr, NAND_CMD_SEQIN, 0x00);		DoC_Address(this, 3, fofs, 0, 0x00);		/* Disable the ECC engine */		WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);		/* Write the data via the internal pipeline through CDSN IO		   register, see Pipelined Write Operations 11.2 */		MemWriteDOC(docptr, (unsigned char *) &buf[got], size);		WriteDOC(0x00, docptr, Mplus_WritePipeTerm);		WriteDOC(0x00, docptr, Mplus_WritePipeTerm);		/* Commit the Page Program command and wait for ready	 	   see Software Requirement 11.4 item 1.*/		DoC_Command(docptr, NAND_CMD_PAGEPROG, 0x00);		DoC_WaitReady(docptr);		/* Read the status of the flash device through CDSN IO register		   see Software Requirement 11.4 item 5.*/		DoC_Command(docptr, NAND_CMD_STATUS, 0x00);		dummy = ReadDOC(docptr, Mplus_ReadPipeInit);		dummy = ReadDOC(docptr, Mplus_ReadPipeInit);		DoC_Delay(docptr, 2);		if ((dummy = ReadDOC(docptr, Mplus_LastDataRead)) & 1) {			printk("MTD: Error 0x%x programming oob at 0x%x\n",				dummy, (int)ofs);			/* FIXME: implement Bad Block Replacement */			*retlen = 0;			ret = -EIO;		}		dummy = ReadDOC(docptr, Mplus_LastDataRead);		ofs += size;		got += size;		want -= size;	}	/* Disable flash internally */	WriteDOC(0, docptr, Mplus_FlashSelect);	*retlen = len;	return ret;}int doc_erase(struct mtd_info *mtd, struct erase_info *instr){	volatile char dummy;	struct DiskOnChip *this = mtd->priv;	__u32 ofs = instr->addr;	__u32 len = instr->len;	void __iomem * docptr = this->virtadr;	struct Nand *mychip = &this->chips[ofs >> this->chipshift];	DoC_CheckASIC(docptr);	if (len != mtd->erasesize)		printk(KERN_WARNING "MTD: Erase not right size (%x != %x)n",		       len, mtd->erasesize);	/* Find the chip which is to be used and select it */	if (this->curfloor != mychip->floor) {		DoC_SelectFloor(docptr, mychip->floor);		DoC_SelectChip(docptr, mychip->chip);	} else if (this->curchip != mychip->chip) {		DoC_SelectChip(docptr, mychip->chip);	}	this->curfloor = mychip->floor;	this->curchip = mychip->chip;	instr->state = MTD_ERASE_PENDING;	/* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */	WriteDOC(DOC_FLASH_CE, docptr, Mplus_FlashSelect);	DoC_Command(docptr, NAND_CMD_RESET, 0x00);	DoC_WaitReady(docptr);	DoC_Command(docptr, NAND_CMD_ERASE1, 0);	DoC_Address(this, 2, ofs, 0, 0x00);	DoC_Command(docptr, NAND_CMD_ERASE2, 0);	DoC_WaitReady(docptr);	instr->state = MTD_ERASING;	/* Read the status of the flash device through CDSN IO register	   see Software Requirement 11.4 item 5. */	DoC_Command(docptr, NAND_CMD_STATUS, 0);	dummy = ReadDOC(docptr, Mplus_ReadPipeInit);	dummy = ReadDOC(docptr, Mplus_ReadPipeInit);	if ((dummy = ReadDOC(docptr, Mplus_LastDataRead)) & 1) {		printk("MTD: Error 0x%x erasing at 0x%x\n", dummy, ofs);		/* FIXME: implement Bad Block Replacement (in nftl.c ??) */		instr->state = MTD_ERASE_FAILED;	} else {		instr->state = MTD_ERASE_DONE;	}	dummy = ReadDOC(docptr, Mplus_LastDataRead);	/* Disable flash internally */	WriteDOC(0, docptr, Mplus_FlashSelect);	mtd_erase_callback(instr);	return 0;}/**************************************************************************** * * Module stuff * ****************************************************************************/static int __init init_doc2001plus(void){	inter_module_register(im_name, THIS_MODULE, &DoCMilPlus_init);	return 0;}static void __exit cleanup_doc2001plus(void){	struct mtd_info *mtd;	struct DiskOnChip *this;	while ((mtd=docmilpluslist)) {		this = mtd->priv;		docmilpluslist = this->nextdoc;		del_mtd_device(mtd);		iounmap(this->virtadr);		kfree(this->chips);		kfree(mtd);	}	inter_module_unregister(im_name);}module_exit(cleanup_doc2001plus);module_init(init_doc2001plus);MODULE_LICENSE("GPL");MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com> et al.");MODULE_DESCRIPTION("Driver for DiskOnChip Millennium Plus");

⌨️ 快捷键说明

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