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

📄 u-boot-lfc.patch

📁 该源码是2410下的nandboot的源码
💻 PATCH
📖 第 1 页 / 共 5 页
字号:
-	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 = this->priv;-	void __iomem *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 = 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->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 = 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) {-	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 = this->priv;-	void __iomem *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);-		WriteDOC(0, docptr, Mplus_NOP);-		WriteDOC(0, docptr, Mplus_NOP);-	} else {-		WriteDOC(0, docptr, NOP);-		WriteDOC(0, docptr, NOP);-		WriteDOC(0, docptr, NOP);-	}--	for (i = 0; i < 6; i++) {-		if (DoC_is_MillenniumPlus(doc))-			ecc_code[i] = ReadDOC_(docptr, DoC_Mplus_ECCSyndrome0 + i);-		else-			ecc_code[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i);-		if (ecc_code[i] != empty_write_ecc[i])-			emptymatch = 0;-	}-	if (DoC_is_MillenniumPlus(doc))-		WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf);-	else-		WriteDOC(DOC_ECC_DIS, docptr, ECCConf);-#if 0-	/* If emptymatch=1, we might have an all-0xff data buffer.  Check. */-	if (emptymatch) {-		/* Note: this somewhat expensive test should not be triggered-		   often.  It could be optimized away by examining the data in-		   the writebuf routine, and remembering the result. */-		for (i = 0; i < 512; i++) {-			if (dat[i] == 0xff) continue;-			emptymatch = 0;-			break;-		}-	}-	/* If emptymatch still =1, we do have an all-0xff data buffer.-	   Return all-0xff ecc value instead of the computed one, so-	   it'll look just like a freshly-erased page. */-	if (emptymatch) memset(ecc_code, 0xff, 6);-#endif-	return 0;-}--static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc)-{-	int i, ret = 0;-	struct nand_chip *this = mtd->priv;-	struct doc_priv *doc = this->priv;-	void __iomem *docptr = doc->virtadr;-	volatile u_char dummy;-	int emptymatch = 1;--	/* flush the pipeline */-	if (DoC_is_2000(doc)) {-		dummy = ReadDOC(docptr, 2k_ECCStatus);-		dummy = ReadDOC(docptr, 2k_ECCStatus);-		dummy = ReadDOC(docptr, 2k_ECCStatus);-	} else if (DoC_is_MillenniumPlus(doc)) {-		dummy = ReadDOC(docptr, Mplus_ECCConf);-		dummy = ReadDOC(docptr, Mplus_ECCConf);-		dummy = ReadDOC(docptr, Mplus_ECCConf);-	} else {-		dummy = ReadDOC(docptr, ECCConf);-		dummy = ReadDOC(docptr, ECCConf);-		dummy = ReadDOC(docptr, ECCConf);-	}--	/* Error occured ? */-	if (dummy & 0x80) {-		for (i = 0; i < 6; i++) {-			if (DoC_is_MillenniumPlus(doc))-				calc_ecc[i] = ReadDOC_(docptr, DoC_Mplus_ECCSyndrome0 + i);-			else-				calc_ecc[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i);-			if (calc_ecc[i] != empty_read_syndrome[i])-				emptymatch = 0;-		}-		/* If emptymatch=1, the read syndrome is consistent with an-		   all-0xff data and stored ecc block.  Check the stored ecc. */-		if (emptymatch) {-			for (i = 0; i < 6; i++) {-				if (read_ecc[i] == 0xff) continue;-				emptymatch = 0;-				break;-			}-		}-		/* If emptymatch still =1, check the data block. */-		if (emptymatch) {-		/* Note: this somewhat expensive test should not be triggered-		   often.  It could be optimized away by examining the data in-		   the readbuf routine, and remembering the result. */-			for (i = 0; i < 512; i++) {-				if (dat[i] == 0xff) continue;-				emptymatch = 0;-				break;-			}-		}-		/* If emptymatch still =1, this is almost certainly a freshly--		   erased block, in which case the ECC will not come out right.-		   We'll suppress the error and tell the caller everything's-		   OK.  Because it is. */-		if (!emptymatch) ret = doc_ecc_decode (rs_decoder, dat, calc_ecc);-		if (ret > 0)-			printk(KERN_ERR "doc200x_correct_data corrected %d errors\n", ret);-	}-	if (DoC_is_MillenniumPlus(doc))-		WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf);-	else-		WriteDOC(DOC_ECC_DIS, docptr, ECCConf);-	if (no_ecc_failures && (ret == -1)) {-		printk(KERN_ERR "suppressing ECC failure\n");-		ret = 0;-	}-	return ret;-}--/*u_char mydatabuf[528]; */--static struct nand_oobinfo doc200x_oobinfo = {-	.useecc = MTD_NANDECC_AUTOPLACE,-	.eccbytes = 6,-	.eccpos = {0, 1, 2, 3, 4, 5},-	.oobfree = { {8, 8} }-};--/* Find the (I)NFTL Media Header, and optionally also the mirror media header.-   On sucessful return, buf will contain a copy of the media header for-   further processing.  id is the string to scan for, and will presumably be-   either "ANAND" or "BNAND".  If findmirror=1, also look for the mirror media-   header.  The page #s of the found media headers are placed in mh0_page and-   mh1_page in the DOC private structure. */-static int __init find_media_headers(struct mtd_info *mtd, u_char *buf,-				     const char *id, int findmirror)-{-	struct nand_chip *this = mtd->priv;-	struct doc_priv *doc = this->priv;-	unsigned offs, end = (MAX_MEDIAHEADER_SCAN << this->phys_erase_shift);-	int ret;-	size_t retlen;--	end = min(end, mtd->size); /* paranoia */-	for (offs = 0; offs < end; offs += mtd->erasesize) {-		ret = mtd->read(mtd, offs, mtd->oobblock, &retlen, buf);-		if (retlen != mtd->oobblock) continue;-		if (ret) {-			printk(KERN_WARNING "ECC error scanning DOC at 0x%x\n",-				offs);-		}-		if (memcmp(buf, id, 6)) continue;-		printk(KERN_INFO "Found DiskOnChip %s Media Header at 0x%x\n", id, offs);-		if (doc->mh0_page == -1) {-			doc->mh0_page = offs >> this->page_shift;-			if (!findmirror) return 1;-			continue;-		}-		doc->mh1_page = offs >> this->page_shift;-		return 2;-	}-	if (doc->mh0_page == -1) {-		printk(KERN_WARNING "DiskOnChip %s Media Header not found.\n", id);-		return 0;-	}-	/* Only one mediaheader was found.  We want buf to contain a-	   mediaheader on return, so we'll have to re-read the one we found. */-	offs = doc->mh0_page << this->page_shift;-	ret = mtd->read(mtd, offs, mtd->oobblock, &retlen, buf);-	if (retlen != mtd->oobblock) {-		/* Insanity.  Give up. */-		printk(KERN_ERR "Read DiskOnChip Media Header once, but can't reread it???\n");-		return 0;-	}-	return 1;-}--static inline int __init nftl_partscan(struct mtd_info *mtd,-				struct mtd_partition *parts)-{-	struct nand_chip *this = mtd->priv;-	struct doc_priv *doc = this->priv;-	int ret = 0;-	u_char *buf;-	struct NFTLMediaHeader *mh;-	const unsigned psize = 1 << this->page_shift;-	unsigned blocks, maxblocks;-	int offs, numheaders;--	buf = kmalloc(mtd->oobblock, GFP_KERNEL);-	if (!buf) {-		printk(KERN_ERR "DiskOnChip mediaheader kmalloc failed!\n");-		return 0;-	}-	if (!(numheaders=find_media_headers(mtd, buf, "ANAND", 1))) goto out;-	mh = (struct NFTLMediaHeader *) buf;--/*#ifdef CONFIG_MTD_DEBUG_VERBOSE */-/*	if (CONFIG_MTD_DEBUG_VERBOSE >= 2) */-	printk(KERN_INFO "    DataOrgID        = %s\n"-			 "    NumEraseUnits    = %d\n"-			 "    FirstPhysicalEUN = %d\n"-			 "    FormattedSize    = %d\n"-			 "    UnitSizeFactor   = %d\n",-		mh->DataOrgID, mh->NumEraseUnits,-		mh->FirstPhysicalEUN, mh->FormattedSize,-		mh->UnitSizeFactor);-/*#endif */--	blocks = mtd->size >> this->phys_erase_shift;-	maxblocks = min(32768U, mtd->erasesize - psize);--	if (mh->UnitSizeFactor == 0x00) {-		/* Auto-determine UnitSizeFactor.  The constraints are:-		   - There can be at most 32768 virtual blocks.-		   - There can be at most (virtual block size - page size)-		     virtual blocks (because MediaHeader+BBT must fit in 1).-		*/-		mh->UnitSizeFactor = 0xff;-		while (blocks > maxblocks) {-			blocks >>= 1;-			maxblocks = min(32768U, (maxblocks << 1) + psize);-			mh->UnitSizeFactor--;-		}-		printk(KERN_WARNING "UnitSizeFactor=0x00 detected.  Correct value is assumed to be 0x%02x.\n", mh->UnitSizeF

⌨️ 快捷键说明

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