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

📄 device.c

📁 基于东南大学开发的SEP3203的ARM7中的所有驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
	{
		next = bad_fat_entries[i];
		if (next < 2) /* Free clusters are ignored */
			continue;
		
		while (n < num)
		{
			if ( *qfat == 0 ) /* find a free cluster */
			{	/* The free cluster is the first one found in the EB */
				if (mflag == 0) 
				{ 	/* Load the data of the EB */
					rdbuf = (UINT8 *)MALLOC(en<<9);
					if (rdbuf == NULL)
					{
						FREE(bad_fat_entries);
						FREE(rep_fat_entries);
						return 0;/*error*/
					}
					if (!pdev->io_proc(driveno, neweb, rdbuf, en, YES))
					{
						/* If error, the EB is ignored and it jumps to
						  * the next EB. The error will be handled when
						  * the bad EB is accessed next time. */
						FREE(rdbuf); rdbuf = NULL;
						/* Find next EB */
						pfat -= num; neweb-=en; qfat = pfat; n = 0;

						/* If there are no FREE clusters, break out of the whole loop */
						if (neweb < pdr->firstclblock)
							break;

						continue;
					}
				}
				/* Copy the cluster's data into the new place */
				m = pdr->secpalloc << 9;
				memcpy(rdbuf+(n*m), (char *)buffer+(i*m), m);
				
				/* 
				  * Modify the FAT and INVERSE FAT. 
				  */
				
				/* The new cluster's number is saved in the bad_fat_entries[] */
				m = (neweb - pdr->firstclblock)/pdr->secpalloc + n + 2;
				rep_fat_entries[i] = m;
				
				/* The next cluster's number(may be bad) is saved in the new cluster */
				if ( next < clsno || next >= clsno + num )
				{	/* If the next cluster is not in the same bad EB, put the next cluster's 
					  * number into the new cluster,  and set its previous pointer (saved 
					  * in INVERSE FAT) point to the new cluster. */
					SWAP16((UINT16*)qfat, (UINT16*)&next);
					SWAP16((UINT16*)&vfat[next], (UINT16*)&m);
				}
				else if (next < clsno + i )
				{	/* If the next cluster is in the same bad EB and is in front of the bad 
					  * cluster, the replacement's number of the next cluster which was 
					  * saved in the bad_fat_entries[] will be put into the new cluster. */
					tmp = rep_fat_entries[next - clsno]; 
					SWAP16((UINT16*)qfat, (UINT16*)&tmp);
					SWAP16((UINT16*)&vfat[tmp], (UINT16*)&m);
				}
				else
				{	/* If the next cluster is in the same bad EB and is behind the bad 
					  * cluster, the next cluster's previous pointer is modified and set to
					  * the value of the new cluster. */
					SWAP16((UINT16*)&vfat[next], (UINT16*)&m);
				}
				
				/* If the bad cluster has a valid previous brother, modify it. */
				tmp = vfat[clsno + i];
				if ( tmp >= 2 && tmp < 0xFFF7 )
				{	/* The previous cluster is not in the same bad EB with the bad 
					  * cluster, set its next pointer point to the new cluster. */
					if (tmp < clsno || tmp >= clsno + num)
					{	
						SWAP16((UINT16*)&rfat[tmp], (UINT16*)&m);
					}
				}
				
				/* Record the EB's read buffer("rdbuf") has been modified */
				mflag = 1; 
				/* Continue to handle the next bad cluster */
				n++; qfat++;
				break;
			}

			qfat++; n++;	/* Check next new cluster */
		}

		/* If there are no free clusters, break out of the whole loop */
		if (neweb < pdr->firstclblock)
			break;

		/* While a EB is passed, the EB should be update if modified. */
		if (n == num)
		{	/* The EB has been modified */
			if (mflag == 1)
			{
				/* Call itself to write the data into the EB. If error happened in the writing 
				  * process, it will be handled in the same way. And the function should 
				  * never return error because the system must have collapsed until then
				  * and there are no good clusters to replace the bad ones. */
				io_err_proc(driveno, neweb, rdbuf, en, NO);
				FREE(rdbuf); rdbuf = NULL;
				mflag = 0; /* Clear the modified flag */
				i++; /* Next bad cluster */
			}
			/* Find next new EB */
			pfat -= num; qfat = pfat; 
			n = 0; neweb-=en;
			
			/* If the found EB is not modified, it means the current bad cluster(i)
			  * has been not replaced, so keep "i", do not increase it. */
			continue;
		}

		i++; /* Next bad cluster */
	}

	/* If the bad cluster number is less than the free space in the EB, write it. */
	if (mflag==1 && n<=num && neweb>=pdr->firstclblock)
	{
		io_err_proc(driveno, neweb, rdbuf, en, NO);
	}

	FREE(bad_fat_entries);
	FREE(rep_fat_entries);
	if (rdbuf) FREE(rdbuf); 

	return 1; /* OK */
}

INT dev_io_proc(UINT16 driveno, UINT32 sector, VOID *buffer, UINT16 count, INT reading)
{
	_PC_BDEVSW	*pdev;
	DDRIVE	*pdr;
	UINT16	ltemp, ebnum, ebsize, ionum,offsetsec, *peb, *pfat, *pdirty;
	UINT8	*devbuf, *pbuffer = buffer;

	pdr = (DDRIVE *)NUF_Drive_Pointers[driveno];

	/* 
	  * MASTER BUFFER READ/WRITE 
	  */
	  
	ltemp = pdr->firstclblock;
	if ( sector < ltemp )
	{
		//printf("op sector=%x count=%d FAT TABLE %s\n", sector, count, (reading==YES)?"R":"Write");
		devbuf = pdr->fat_swap_structure.master_buffer + (sector<<9);
		
		if (reading == YES)
			memcpy(buffer, devbuf, count<<9);
		else if (reading == NO)
			memcpy1(devbuf, buffer, count<<9);
		else if (reading == FLUSH)
		{
			/* FLUSH the data in the data buffer into device, and 
			  * there is no error check here because the device 
			  * must have been destroyed completely.  */
			ebsize = NUF_Drive_Erase_Size[driveno];
			ebnum = 0;	
			for (ebnum = 0; ebnum < ltemp; ebnum += ebsize)
			{
				io_err_proc(driveno, ebnum, devbuf, ebsize, NO);
				devbuf += ebsize<<9;
			}
		}
		return 1;/*ok*/
	}

	/*
	  * DATA READ/WRITE 
	  */
	devbuf = pdr->fat_swap_structure.data_buffer;
	pdirty = &pdr->fat_swap_structure.data_buf_dirty;
	peb = &pdr->fat_swap_structure.data_buf_eb;
	ltemp = *peb;

	ebsize = NUF_Drive_Erase_Size[driveno];
	  /*
	    * if device is NOR FLASH(that is driveno == 1), and 
	    * only if operation is reading data, 
	    * read the nor flash device directly for speed up.
	    */
	if(driveno == 1 && reading == YES) 
	{
		pdev = &pc_bdevsw[driveno];
		while(count)
		{
			ebnum = sector/ebsize;
			offsetsec = sector%ebsize;
			if ( ebnum !=  ltemp || ltemp == 0 )		/* read the device directly*/
			{
				ionum = 	ebsize-offsetsec;
				if(count<=ionum)
				{
					if (pdev->io_proc(driveno, sector, pbuffer, count, YES))
						return YES;			/* read ok */
					return NO;				/* read failed */	
				}
				else
				{
					if (!pdev->io_proc(driveno, sector, pbuffer, ionum, YES))
						return NO;			/* read failed */	
				}
				sector += ionum;
				count -= ionum;
				pbuffer += ionum<<9;
			}
			else
			{
				if (offsetsec)
				{
					devbuf += (offsetsec<<9);
					ionum = ebsize - offsetsec;
					if (count<ionum)
						ionum = count;
				}
				else
				{
					if (count<=ebsize)
						ionum = count;
					else
						ionum = ebsize;
				}
				count -= ionum;
				sector += ionum;
				memcpy(pbuffer, devbuf, ionum<<9);			/* read data from data buffer */		
				pbuffer += ionum<<9;
			}
		}
		return YES;						/* read ok */
	}

					
	
	/* The DATA BUFFER is out of date, the current data in the buffer
	  * should be saved into the real device. And the new data sent by
	  * the caller will be put into the buffer afterward or read from the 
	  * buffer. */
	while(count)
	{
		ebnum = sector/ebsize;
		offsetsec = sector%ebsize;
		devbuf = pdr->fat_swap_structure.data_buffer;
		if ( ebnum !=  ltemp || ltemp == 0 )
		{
			if (ltemp != 0)
			{
				/* Save the current data in the buffer to the device */
				if ( *pdirty == 1 )
				{
					*pdirty = 0;
					if (!io_err_proc(driveno, ltemp*ebsize, devbuf, ebsize, NO))
						return 0;/*error*/
				}
				if (reading == FLUSH)
					return 1;/*ok*/
			}

			/* Record the new EB number */
			*peb = ebnum;
			ltemp = ebnum;
			
			/* Load the new data from the device */
			if (!io_err_proc(driveno, ebnum*ebsize, devbuf, ebsize, YES))
			{
				*peb = 0;
				return 0;/*error*/
			}
		}

		/* Check the EB according to the current data buffer is not BAD  */
		pdr = (DDRIVE *)NUF_Drive_Pointers[driveno];
		pfat = (UINT16*)&pdr->fat_swap_structure.data_array[0];
		pfat += (ebnum*ebsize-pdr->firstclblock)/pdr->secpalloc + 2; 
		if (*(pfat + 3 ) == 0xFFF7 )
		{
			*peb = 0; *pdirty = 0;
			return 0;/*error*/
		}

		/* The DATA BUFFER is update, continue the operation. */
		if (offsetsec)
		{
			devbuf += (offsetsec<<9);
			ionum = ebsize - offsetsec;
			if (count<ionum)
				ionum = count;
		}
		else
		{
			if (count<=ebsize)
				ionum = count;
			else
				ionum = ebsize;
		}
		count -= ionum;
		sector += ionum;
		
		if (reading == YES)
		{
			memcpy(pbuffer, devbuf, ionum<<9);			
			pbuffer += ionum<<9;
		}
		else
		{
			memcpy(devbuf, pbuffer, ionum<<9);
			pbuffer += ionum<<9;
			*pdirty = 1;
		}
	}
	return 1;/*ok*/
}

⌨️ 快捷键说明

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