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

📄 j_flash.cpp

📁 JFFS的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:

				D(printk("Flash: verify error 0x%p. "
				       "(flash_write() 1)\n",
				       programAddress));
				D(printk("*programAddress = 0x%04x, "
				       "*theData = 0x%04x\n",
				       *programAddress, *theData));
			} while(++retries < 2);

			if(retries >= 2) {
				D(printk("FATAL FLASH ERROR (1)\n"));
				return -EIO; /* we failed... */
			}

			programAddress++;
			theData++;
		}

		/* We should write one extra byte to the flash.  */
		if (odd_size) {
			unsigned char last_byte[2];
			int retries = 0;

			last_byte[0] = *(unsigned char *)theData;
			last_byte[1] = ((unsigned char *)programAddress)[1];

			do {
				int timeout = PROGRAM_TIMEOUT;
#ifdef IRQ_LOCKS
				unsigned long flags;
				save_flags(flags);
				cli();
#endif
		if( (unsigned long)programAddress < JFFS_ADDR_START || (unsigned long)programAddress >= JFFS_ADDR_END ){	//!!!
			D(printk("flash_write: illegal3 ptr 0x%p in flash_write.\n", programAddress));
			return -EINVAL;
		}

				flashStart[unlockAddress1] = unlockData1;
				flashStart[unlockAddress2] = unlockData2;
				flashStart[unlockAddress1] = programUnlockData;
				*programAddress = *(flashptr) last_byte;

				for(n=0; n<DELAY_90NS_LOOP; n++);
				
				/* Wait for programming to finish */
				while (timeout-- &&
				       (*flashStart & D6_MASK)
				       != (*flashStart & D6_MASK))
				/* nothing */;
#ifdef IRQ_LOCKS
				restore_flags(flags);
#endif
				if(!timeout)
					D(printk("flash: write timeout 0x%p\n",
					       programAddress));
				if(*programAddress
				   == *(flashptr)last_byte)
					break;

				D(printk("Flash: verify error 0x%p. "
				       "(flash_write() 2)\n",
				       programAddress));
			} while(++retries < 2);

			if(retries >= 2) {
				D(printk("FATAL FLASH ERROR (2)\n"));
				return -EIO; /* we failed... */
			}
		}
	}

	return 0;
}

int
flash_safe_write(void *_part, unsigned char *fptr,
		 const unsigned char *buf, int count)
{
	struct flashpartition *part = (struct flashpartition *)_part;
	int err;

	/* Check so it's not totally out of bounds.  */

	if(fptr + count > part->start + part->size) {
		D(printk("flash: write operation past "
		       "end of device (address: 0x%p, size: %d)\n",
		       fptr, count));
		return -EINVAL;
	}

	FDEBUG(printk("flash_safe_write: %d bytes from 0x%p to 0x%p\n",
		      count, buf, fptr));

	/* Actually do something, but get a lock on the chip first.  */

	flash_safe_acquire(part);

	if ((err = flash_write(fptr, buf, count)) < 0) {
		count = err;
	}

	/* Release the lock.  */

	flash_safe_release(part);

	return count; /* success */
}

void *flash_getpart(kdev_t dev)
{
	struct flashpartition *part;

	/*if (MINOR(dev) < FLASH_MINOR) {
		return 0;
	}

	part = &partitions[MINOR(dev) - FLASH_MINOR];*/
	
	part = &partitions[0];	/*!!!hard code*/

	if (!part->start) {
		return 0;
	}

	return (void *)part;
}

/*自己编写: 只有一个分区JFFS_ADDR_START-JFFS_ADDR_END*/
static void flash_init_partitions(void)
{
	if (chips[0].isValid) {
		partitions[0].chip = &chips[0];
		partitions[0].start = (unsigned char *)JFFS_ADDR_START;
		partitions[0].size = JFFS_ADDR_END - JFFS_ADDR_START;
	}
}

/* "Memset" a chunk of memory on the flash.
 * do this by flash_write()'ing a pattern chunk.
 */
int flash_memset(unsigned char *ptr, const __u8 c, unsigned long size)
{
	static unsigned char pattern[16];
	int i;/*livefall@163.com 2005.01.09*/

	/* fill up pattern */
	for(i = 0; i < 16; i++)	pattern[i] = c;	/*livefall@163.com 2005.01.09*/

	/* write as many 16-byte chunks as we can */
	while(size >= 16) {
		flash_write(ptr, pattern, 16);
		ptr += 16; size -= 16;
	}

	/* and the rest */
	if(size) flash_write(ptr, pattern, size);

	return 0;
}

/* start erasing flash-memory at ptr of a certain size
 * this does not wait until the erasing is done
 */
void flash_init_erase(unsigned char *ptr, unsigned int size)
{
	struct flashchip *chip;
	int bootSectorCounter = 0;
	unsigned int erasedSize = 0;
	flashptr flashStart;
#ifdef IRQ_LOCKS
	unsigned long flags;
#endif
	int n;

	/*ptr = (unsigned char *)((unsigned long)ptr | MEM_NON_CACHEABLE);*/
	chip = getchip(ptr);
	flashStart = (flashptr)chip->start;

	FDEBUG(safe_printk("Flash: erasing memory at 0x%p, size 0x%x.\n", ptr, size));

	/* need to disable interrupts, to avoid possible delays between the
	 * unlocking and erase-init
	 */

#ifdef IRQ_LOCKS
	save_flags(flags);
	cli();
#endif

	/* Init erasing of the number of sectors needed */

	flashStart[unlockAddress1] = unlockData1; 
	flashStart[unlockAddress2] = unlockData2;
	flashStart[unlockAddress1] = sectorEraseUnlockData;
	flashStart[unlockAddress1] = unlockData1;
	flashStart[unlockAddress2] = unlockData2;

	while (erasedSize < size) {
		*(flashptr)ptr = sectorEraseUnlockData2;

		/* make sure we erase the individual bootsectors if in that area */
		/* TODO this BREAKS if we start erasing in the middle of the bootblock! */

		if (ptr < chip->bootsector || ptr >= (chip->bootsector +
						      chip->sectorsize)) {
			erasedSize += chip->sectorsize;
			ptr += chip->sectorsize;
		}
		else {
			erasedSize += chip->bootsectorsize[bootSectorCounter];
			ptr += chip->bootsectorsize[bootSectorCounter++];
		}
	}

#ifdef IRQ_LOCKS
	restore_flags(flags);
#endif

	for(n=0; n<DELAY_90NS_LOOP; n++);
}

int flash_erase_region(kdev_t dev, __u32 offset, __u32 size)
{
	struct flashpartition *part;
	unsigned char *erase_start;
	short retries = 2;
	short success;
	int count,blocks,i;

	/*part = &partitions[minor - FLASH_MINOR];*/
	part = &partitions[0];
	if (!part->start) {
		return -EINVAL;
	}

	/* Start the erasure, then sleep and wake up now and then to see
	 * if it's done.
	 */

	erase_start = part->start + offset;

	flash_safe_acquire(part);
	do {
		flash_init_erase(erase_start, size);
		count = 0;	/*livefall@163.com 2005.01.09*/
		blocks = size/(part->chip->sectorsize)+1;	/*livefall@163.com 2005.01.09*/
		while (flash_is_busy((flashptr)part->chip->start)) {
			if(sys_init_done == 0){
				for(i=0; i<100*FOR_1_MS; i++);	/*livefall@163.com 2005.01.09*/
				clearHW();
			}
			else NU_Sleep(10);
			if(count++ > S_ERASE_TIMEOUT/100*blocks) break;
		}
		/*!!!0xffff->0xff*/
		success = ((flashptr)erase_start)[0] == 0xff
			  && ((flashptr)erase_start)[1] == 0xff
			  && ((flashptr)erase_start)[2] == 0xff
			  && ((flashptr)erase_start)[3] == 0xff;	

		if (!success) {
			printk("flash: erase of region "
			       "[0x%p, 0x%p] failed once\n",
			       erase_start, erase_start + size);
		}

	} while (retries-- && !success);

	flash_safe_release(part);

	if (retries == 0 && !success) {
		printk("flash: erase of region "
			       "[0x%p, 0x%p] totally failed\n",
			       erase_start, erase_start + size);
		return -1;
	}

	return 0;
}

static int flash_is_busy(flashptr flashStart)
{
	/* this should probably be protected! */
	return ((*flashStart & D6_MASK) != (*flashStart & D6_MASK));
}


/* check if it's possible to erase the wanted range, and if not, return
 * the range that IS erasable, or a negative error code.
 */
long flash_erasable_size(void *_part, __u32 offset, __u32 size)
{
	struct flashpartition *part = (struct flashpartition *)_part;
	int ssize;

	if (!part->start) {
		return -EINVAL;
	}

	/* assume that sector size for a partition is constant even
	 * if it spans more than one chip (you usually put the same
	 * type of chips in a system)
	 */

	ssize = part->chip->sectorsize;

	if (offset % ssize) {
		/* The offset is not sector size aligned.  */
		return -1;
	}
	else if (offset > part->size) {
		return -2;
	}
	else if (offset + size > part->size) {
		return -3;
	}

	return (size / ssize) * ssize;
}
int mgetchar();
int formatCmd(int argc,char *argv[])
{
	int ret;/*livefall@163.com 2005.01.09*/
	//printf("确认格式化Flash盘[y/n]?\n");
    //char c = mgetchar();
	//if(c == 'y' || c == 'Y'){
		printf("擦除Flash存储器开始...\n");
		ret = flash_erase_region(0,0,(JFFS_ADDR_END-JFFS_ADDR_START));	//!!!/*livefall@163.com 2005.01.09*/
		if(ret < 0)
			printf("擦除Flash存储器失败!\n");
		else 
			printf("擦除Flash存储器成功!\n");
	//}	
	//else{	
	//	printf("操作取消!\n");
	//}
	return 0;
}

⌨️ 快捷键说明

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