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

📄 device.c

📁 基于东南大学开发的SEP3203的ARM7中的所有驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/************************************************************************
*                                                                       
*       Copyright (c) 2004 by PESSIA
*                                                                       
*  PROPRIETARY RIGHTS of PESSIA are  involved in  the subject matter 
*  of this material.  All manufacturing, reproduction, use, and sales 
*  rights pertaining to this subject matter are  governed by the license 
*  agreement.  The recipient of this software implicitly accepts the 
*  terms of the license.
*                                                                       
*                                                                       
*************************************************************************

*************************************************************************
* FILE NAME                                     VERSION                 
*                                                                       
*       DEVICE.C                               
*                                                                       
* COMPONENT                                                             
*                                                                       
*       Nucleus File                                                    
*                                                                       
* DESCRIPTION                                                           
*                                                                       
*       This file contains Nuclues File32 application interface.        
*                                                                       
* DATA STRUCTURES                                                       
*                                                                       
*       None.                                                           
*                                                                       
* FUNCTIONS                                                             
*
*       XXXXXXXXXXX
*                                                                       
* DEPENDENCIES                                                          
*                                                                       
*       pcdisk.h                            File common definitions     
*                                                                       
*************************************************************************/

#include        "file\pcdisk.h"
#include        "lmalloc.h"

extern _PC_BDEVSW       pc_bdevsw[];
extern UNSIGNED         *NUF_Drive_Pointers[];
extern INT              NUF_Fat_Type[];
extern INT              NUF_Drive_Fat_Size[];

#define MALLOC SysLmalloc
#define FREE SysLfree

static INT io_err_proc(INT16 driveno, UINT32 sector, VOID *buffer, UINT16 count, INT reading);

int memcpy1(void *dst, void *src, int num)
{
	register unsigned int *pdst;
	register unsigned int *psrc;
	register int number;
	int i;

	//for(i=0;i<10000;i++);
	pdst = (unsigned int *)dst;
	psrc = (unsigned int *)src;
	
	if(pdst == (unsigned int *)0x30cae4f8)
	{
		while(0);
	}
	for(i=0;i<1;i++);
	for(number=0;number<num/4;number++)
	{
		*(pdst) = *(psrc);
		pdst++;psrc++;
	}
	
	return number;
}



INT free_EB_proc(UINT16 *bad_fat_entries, INT16 driveno, UINT32 sector, VOID *buffer, UINT16 count, INT reading)
{
	_PC_BDEVSW	*pdev;
	DDRIVE	*pdr;
	UINT16	*pfat, *qfat, *rfat, *vfat, neweb, next, clsno, tmp;
	INT		i, n, num, en;
	UINT16 *rep_fat_entries;

	/* 
	  * Find a free EB to replace the bad one 
	  */

	pdev = &pc_bdevsw[driveno];
	pdr = (DDRIVE *)NUF_Drive_Pointers[driveno];
	pfat = (UINT16*)&pdr->fat_swap_structure.data_array[0];
	
	en = n = NUF_Drive_Erase_Size[driveno];
	num = en/pdr->secpalloc; /* num is the number of a EB's FAT entries */

	rep_fat_entries = (UINT16 *)MALLOC(num<<1);
	if (rep_fat_entries == NULL)
		return 0;/*error*/
	
	neweb = pdr->numsecs - en;
	clsno = (neweb - pdr->firstclblock)/pdr->secpalloc + 2;
	pfat += clsno;
	do
	{
		qfat = pfat;
		for (i=0; i<num; i++)
		{
			if ( *qfat++ != 0 )
				break;
		}
		/* Find a free EB */
		if (i == num)
		{
			/*
			  * Replace the bad EB by the new one if have
			  */

			/* qfat is the new EB */
			qfat = pfat;
			/* pfat is the start of INVERSE FAT, clsno is the first cluster number of the bad EB */
			vfat = (UINT16*)&pdr->fat_swap_structure.inv_data_array[0];
			clsno = (sector - pdr->firstclblock)/pdr->secpalloc + 2;
			pfat = vfat + clsno;
			/* rfat is the start of FAT */
			rfat = (UINT16*)&pdr->fat_swap_structure.data_array[0];
			/* n is the start cluster's number of the new EB */
			n = (neweb - pdr->firstclblock)/pdr->secpalloc + 2;
			/* Modify each FAT entry in the free EB */
			for (i=0; i<num; i++)
			{
				next = bad_fat_entries[i];
				/* The new cluster's number is saved in the bad_fat_entries[] */
				rep_fat_entries[i] = n;
				
				/* 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*)&n);
				}
				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*)&n);
				}
				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*)&n);
				}
				
				/* If the bad cluster has a valid previous brother, modify it. */
				if ( *pfat >= 2 && *pfat < 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 (*pfat < clsno || *pfat >= clsno + num)
					{	
						SWAP16((UINT16*)&rfat[*pfat], (UINT16*)&n);
					}
				}
				qfat++; pfat++; n++;
			}

			/* Write data into the new EB. */
			n -= num; /* n is the start cluster's number of the new EB */
			if (pdev->io_proc(driveno, neweb, buffer, count, reading))
			{
				FREE(bad_fat_entries);
				FREE(rep_fat_entries);
				return 1; /* OK */
			}

			/* The possibility of meeting error during the operation 
			  * to the new EB is supposed to be very little!!! */

			/* If error, Record the new EB as a BAD EB. */
			next = 0xFFF7;
			qfat = rfat + n;
			for (i=0; i<num; i++)
				SWAP16((UINT16 *)(qfat++), (UINT16*)&next);/*record bad flag*/

			/* Get ready to find next free EB */
			pfat = (UINT16*)&pdr->fat_swap_structure.data_array[0];
			pfat += n;
		}

		/* Continue to find next free EB. */
		pfat -= num;
		neweb -= en;
	}while (neweb>=pdr->firstclblock);

	FREE(rep_fat_entries);
	return 0;/*error*/
}

INT io_err_proc(INT16 driveno, UINT32 sector, VOID *buffer, UINT16 count, INT reading)
{
	_PC_BDEVSW	*pdev;
	DDRIVE	*pdr;
	UINT16	*pfat, *qfat, *rfat, *vfat, neweb, next, clsno, tmp;
	INT		i, n, m, num, mflag, en;
	UINT8	*rdbuf = NULL;
	UINT16	*bad_fat_entries;
	UINT16	*rep_fat_entries;

	/*
	  * Check the destination is not BAD
	  */

	pdr = (DDRIVE *)NUF_Drive_Pointers[driveno];
	clsno = (sector - pdr->firstclblock)/pdr->secpalloc + 2;
	pfat = (UINT16*)&pdr->fat_swap_structure.data_array[0];
	qfat = pfat + clsno; 
	if (*(qfat + 3 ) == 0xFFF7 )
		return 0;/*error*/ 

	/*
	   * Call the device interface to complete the IO operation.
	   */
	   
	pdev = &pc_bdevsw[driveno];
	if (pdev->io_proc(driveno, sector, buffer, count, reading))
		return 1; /* OK */

	/* 
	  * Only when the FATs and BOOT and ROOT will be flushed into 
	  * the device, it happens. 
	  * And here return OK directly, because if error, the system will 
	  * collapse during the next boot. 
	  */
	if (sector < pdr->firstclblock)
		return 1; /* OK */

	/*
	  **********************************************************
	  *  ERROR HANDLE PROCESS
	  **********************************************************
	  */
	
	/* 
	  * Backup the FAT entries of the bad EB 
	  */
	  
	en = n = NUF_Drive_Erase_Size[driveno];
	num = n/pdr->secpalloc; /* num is the number of a EB's FAT entries */

	next = 0xFFF7; /*bad flag*/
	if (reading == YES)
	{
		for (i=0; i<num; i++)
		{
			if (next == 0xFFFD)
			{	/* Jump over the media flag "FFFD, FFFF" of FAT16 */
				i++; qfat++; qfat++;
			}
			else
				SWAP16((UINT16 *)(qfat++), &next);/*record bad flag*/
		}	
		return 0;/*error*/
	}
	
	bad_fat_entries = (UINT16 *)MALLOC(num<<1);
	if (bad_fat_entries == NULL)
		return 0;/*error*/

	for (i=0; i<num; i++)
	{
		if (*qfat == 0xFFFD)
		{	/* Jump over the media flag "FFFD, FFFF" of FAT16 */
			i++; qfat++; qfat++;
		}
		else
		{
			SWAP16(&bad_fat_entries[i], (UINT16 *)(qfat)); /*backup*/
			SWAP16((UINT16 *)(qfat++), &next);/*record bad flag*/
		}
	}
	
	/* 
	  * Find a free EB to replace the bad one 
	  */
	if (free_EB_proc(bad_fat_entries, driveno, sector, buffer, count, reading) != 0)
		return 1; /* OK */
	
	/* 
	  * If no free EB, then find enough clusters to replace the bad EB. 
	  */

	rep_fat_entries = (UINT16 *)MALLOC(num<<1);
	if (rep_fat_entries == NULL)
	{
		FREE(bad_fat_entries);
		return 0;/*error*/
	}
	
	/* neweb is the first sector number of the current EB to be checked */;
	neweb = pdr->numsecs - en;
	rfat = pfat = (UINT16*)&pdr->fat_swap_structure.data_array[0];
	/* qfat is the new cluster to be checked, pfat is the new EB to be checked. */
	clsno = (neweb - pdr->firstclblock)/pdr->secpalloc + 2;
	pfat += clsno;
	qfat = pfat;
	/* rfat is the inverse FAT's start address */
	vfat = (UINT16*)&pdr->fat_swap_structure.inv_data_array[0];
	/* Check each cluster in the BAD EB, and move the used ones into a new place. */
	i = 0; mflag = 0; n= 0;
	clsno = (sector - pdr->firstclblock)/pdr->secpalloc + 2;
	while (i < num)

⌨️ 快捷键说明

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