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

📄 apiutil.c

📁 基于东南大学开发的SEP3203的ARM7中的所有驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
        /* The first block of the cluster area is the root dir */
        pdr->firstclblock = pdr->rootblock;

        min_needed = 16;
        pdr->secpfat = pdr->bigsecpfat;

        SWAP16((UINT16 *)&pdr->fsinfo,(UINT16 *)&b[0x30]);
        /* Read the File System INFOmation */
        PC_DRIVE_IO_ENTER(driveno)
        if ( !pc_bdevsw[driveno].io_proc(driveno, (UINT32) pdr->fsinfo, &b[0], (UINT16) 1, YES) )
        {
            PC_DRIVE_IO_EXIT(driveno)
            pc_report_error(PCERR_INITREAD);
            pdr->opencount = 0;
            return(NUF_IO_ERROR);
        }
        PC_DRIVE_IO_EXIT(driveno)

        /* FSINFO
            Set to 0 when the free clusters count is unknown.
            Set to 1 when the free clusters count is known. */
        pdr->valid_fsinfo = 0;

        /* Check the signature of the file system information sector.*/
        if ( (b[0] == 'R') && (b[1] == 'R') && (b[2] == 'a') && (b[3] == 'A') &&
             (b[0x1e4] == 'r') && (b[0x1e5] == 'r') && (b[0x1e6] == 'A') && (b[0x1e7] == 'a') )
        {
            /* The count of free clusters on the drive.
                Note: Set to -1(0xffffffff) when the count is unknown. */
            SWAP32((UINT32 *)&pdr->free_clusters_count,(UINT32 *)&b[0x1e8]);

            if (pdr->free_clusters_count == (UINT32)0xffffffff)
                pdr->free_clusters_count = 0L;
            else
                pdr->valid_fsinfo = 1;

            /* The cluster number of the cluster that was most recently allocated. */
            SWAP32((UINT32 *)&pdr->free_contig_pointer,(UINT32 *)&b[0x1ec]);
        }
        else
        {
            pdr->free_clusters_count = 0L;
            pdr->free_contig_pointer = 2L;
        }
    }

    /*  Calculate the largest index in the file allocation table.
        Total # block in the cluster area)/Blockpercluster =='s total
        Number of clusters. Entries 0 & 1 are reserved so the highest
        valid fat index is 1 + total # clusters.
        Note: Max cluster number  = Number of clusters + 1 */
    pdr->maxfindex = (UINT32)
            (1 + (pdr->numsecs - pdr->firstclblock)/pdr->secpalloc);

    /* Check the number of next free cluster  */
    if (pdr->free_contig_pointer > pdr->maxfindex)
        pdr->free_contig_pointer = 2L;

    if (pdr->fasize == 3)
    {
        if (pdr->maxfindex > 0x0ff6L)
        {
            pdr->opencount = 0;
            return(NUF_FORMAT);
        }
    }
    else if (pdr->fasize == 4)
    {
        if (pdr->maxfindex > 0xfff6L)
        {
            pdr->opencount = 0;
            return(NUF_FORMAT);
        }
    }
    else    /* FAT32 */
    {
        if (pdr->maxfindex > 0x0ffffff6L)
        {
            pdr->opencount = 0;
            return(NUF_FORMAT);
        }
    }

    if (NUF_Drive_Fat_Size[driveno] < min_needed)
    {
        pc_report_error(PCERR_FATCORE);
        pdr->opencount = 0;
        return(NUF_FATCORE);
    }

    if (NUF_Drive_Fat_Size[driveno] >  (INT)pdr->secpfat)
    {
        NUF_Drive_Fat_Size[driveno] = (INT)pdr->secpfat;
    }


    /* Allocate FAT cache buffer */
    pdr->fat_swap_structure.data_array =
                    (UINT8 FAR *)NUF_Alloc(NUF_Drive_Fat_Size[driveno] << 9 );

    if (!pdr->fat_swap_structure.data_array)
    {
        pdr->opencount = 0;
        return(NUF_NO_MEMORY);
    }
    
    pdr->fat_swap_structure.inv_data_array =
                    (UINT8 FAR *)NUF_Alloc(NUF_Drive_Fat_Size[driveno] << 9 );

    if (!pdr->fat_swap_structure.inv_data_array)
    {
        pdr->opencount = 0;
        return(NUF_NO_MEMORY);
    }

    /* PESSIA(20041106):
      * Allocate the memory area for DATA BUFFER  */
   {
	pdr->fat_swap_structure.data_buffer =
                    (UINT8 FAR *)NUF_Alloc(NUF_Drive_Erase_Size[driveno] << 9 );
    }

    if (!pdr->fat_swap_structure.data_buffer)
    {
        pdr->opencount = 0;
        return(NUF_NO_MEMORY);
    }
    pdr->fat_swap_structure.data_buf_eb = 0;
    pdr->fat_swap_structure.data_buf_dirty = 0;

    /* Remember how many blocks we alloced */

    pdr->fat_swap_structure.n_blocks_total = (UINT16)NUF_Drive_Fat_Size[driveno];
    if (NUF_Drive_Fat_Size[driveno] == (INT)pdr->secpfat)
        pdr->use_fatbuf = 0;
    else
        pdr->use_fatbuf = 1;

#ifdef DEBUG0
        DEBUG_PRINT ("Oem NAME  %8s\n",pdr->oemname);
        DEBUG_PRINT ("Bytspsec  %d\n",pdr->bytspsector);
        DEBUG_PRINT ("secpallc  %d\n",pdr->secpalloc);
        DEBUG_PRINT ("secres    %d\n",pdr->fatblock);
        DEBUG_PRINT ("numfat    %d\n",pdr->numfats);
        DEBUG_PRINT ("numrot    %d\n",pdr->numroot);
        DEBUG_PRINT ("numsec    %d\n",pdr->numsecs);
        DEBUG_PRINT ("mediac    %d\n",pdr->mediadesc);
        DEBUG_PRINT ("secfat    %d\n",pdr->secpfat);
        DEBUG_PRINT ("sectrk    %d\n",pdr->secptrk);
        DEBUG_PRINT ("numhed    %d\n",pdr->numhead);
        DEBUG_PRINT ("numhide   %d\n",pdr->numhide);
#endif

    /* Clear the current working directory */
    fs_user->lcwd[driveno] = NULL;

    pdr->bytespcluster = (UINT16) (512 * pdr->secpalloc);

    /* bits to mask in to calculate byte offset in cluster from file pointer.
        AND file pointer with this to get byte offset in cluster a shift right
        9 to get block offset in cluster */
    pdr->byte_into_cl_mask = (UINT32) pdr->bytespcluster;
    pdr->byte_into_cl_mask -= 1L;

    /* save away log of sectors per alloc */
    pdr->log2_secpalloc = pc_log_base_2((UINT16)pdr->secpalloc);

    /* Number of maximum file clusters */
    pdr->maxfsize_cluster = MAXFILE_SIZE >> pdr->log2_secpalloc;

    /* Initialize the fat management code */

    /* Set driveno now becuse the drive structure is valid */  
    pdr->driveno = driveno;

    if (pdr->use_fatbuf)
    {
        /* Swap in item 0. (ie read the first page of the FAT) */
        ret_stat = pc_pfswap(&pdata, pdr, (UINT32)0, NO);
        if (ret_stat != NU_SUCCESS)
        {
            pc_report_error(PCERR_FATREAD);
            NU_Deallocate_Memory((VOID *)pdr->fat_swap_structure.data_array);
            pdr->opencount = 0;
            return(ret_stat);
        }
    }
    else
    {
        /* No fat swapping. We use  drive.fat_swap_structure elements
           to implement an in memory caching scheme. data_map[255] is used
           to indicate which blocks are dirty and data_array points to
           the buffer to hold the in memory fat */

        ltemp = pdr->secpfat;
        pdata = pdr->fat_swap_structure.data_array;
        fatoffset = pdr->fatblock;
        while (ltemp)
        {
            if (ltemp > MAXSECTORS)
                nblocks = MAXSECTORS;
            else
                nblocks = (UINT16) ltemp;

            /*PESSIA(20041105):
              * After FAT is read out of the device, it is not checked carefully!!!
              * So some serious problems may be missed here. 
              * However, if some error happened, one solution is to annouce
              * that the device has been damaged and the users should throw 
              * away the machine:) . The other way is to use the standby FAT
              * just saved after the previous. But the characteristic of the device
              * (the two FAT may be in the same erasing block) decides the 
              * second FAT is likely damaged too. 
              * So, just omit the possible error here, we could do nothing except
              * accepting.
              */

            /* The dirty blocks table data_map[255] was zeroed when we zeroed
               the drive structure */
            /* Now read the fat */
            PC_DRIVE_IO_ENTER(driveno)
            if ( !pc_bdevsw[driveno].io_proc(driveno, (UINT32)fatoffset, pdata, nblocks, YES) )
            {
                PC_DRIVE_IO_EXIT(driveno)
                pc_report_error(PCERR_FATREAD);
                NU_Deallocate_Memory((VOID *)pdr->fat_swap_structure.data_array);
                pdr->opencount = 0;
                return(NUF_IO_ERROR);
            }
            PC_DRIVE_IO_EXIT(driveno)

            ltemp -= nblocks;
            fatoffset += nblocks;
            pdata += (nblocks << 9);
        }

	/*PESSIA(20041105):
	  * Construct the inverse FAT from the origin FAT.  The inverse FAT is
	  * be used while one FAT entry would be set to "BAD(0xFFF7)". */
	pc_build_inv_fat (pdr->fat_swap_structure.data_array, \
			pdr->fat_swap_structure.inv_data_array, pdr->secpfat);

	/*PESSIA(20041106):
	  * Copy FATs into MASTER BUFFER. */
	pdata = pdr->fat_swap_structure.data_array;
	qdata = pdr->fat_swap_structure.master_buffer + (pdr->fatblock<<9);
	ltemp = pdr->numfats;
	while(ltemp--)
	{
		memcpy(qdata, pdata, (pdr->secpfat<<9));
		qdata += (pdr->secpfat<<9);
	}

	/*PESSIA(20041109):
	  * Copy ROOT into MASTER BUFFER. */
	ltemp = pdr->rootblock;
	pdata = pdr->fat_swap_structure.master_buffer + (pdr->rootblock<<9);
	nblocks = (pdr->numroot + INOPBLOCK - 1)/INOPBLOCK;
	PC_DRIVE_IO_ENTER(driveno)
	if ( !pc_bdevsw[driveno].io_proc(driveno, (UINT32)ltemp, pdata, nblocks, YES) )
	{
		PC_DRIVE_IO_EXIT(driveno)
		pc_report_error(PCERR_ROOTREAD);
		NU_Deallocate_Memory((VOID *)pdr->fat_swap_structure.master_buffer);
		pdr->opencount = 0;
		return(NUF_IO_ERROR);
	}
	PC_DRIVE_IO_EXIT(driveno)

    }
    return(NU_SUCCESS);
}


/************************************************************************
* FUNCTION                                                              
*                                                                       
*       pc_idskclose                                                    
*                                                                       
* DESCRIPTION                                                           
*                                                                       
*       Given a valid drive number. Flush the file allocation table and 
*       purge any buffers or objects associated with the drive.         
*                                                                       
* AUTHOR                                                                
*                                                                       
*       Kyoichiro Toda                             
*                                                                       
* INPUTS                                                                
*                                                                       
*       driveno                             Drive number                
*                                                                       
* OUTPUTS                                                               
*                                                                       
*       NU_SUCCESS                          Unmount successful.         
*       NUF_BADDRIVE                        Invalid drive specified.    
*       NUF_IO_ERROR                        Driver returned error.      
*       NUF_INTERNAL                        Nucleus FILE internal error.
*                                                                       
*************************************************************************/
STATUS pc_idskclose(INT16 driveno)
{
DDRIVE      *pdr;
STATUS      ret_val;
UINT8       b[512];
UINT32      fstemp;
INT         i;
UINT16      signature;


    pdr = pc_drno2dr(driveno);

    /* Check drive number */
    if (pdr)
    {
        PC_FAT_ENTER(driveno)
        ret_val = pc_flushfat(pdr);
        PC_FAT_EXIT(driveno)

        if (ret_val == NU_SUCCESS)
        {
            if (pdr->fasize == 8)
            {
                /* Build up a Partition FSINFO(File System INFOrmation)
                    Note: PBR include a BIOS Parameter Block(BPB) */
                pc_memfill(&b[0], 512, '\0');

                /* FSI signature offset 0 */
                pc_cppad(&b[0], (UINT8 *)"RRaA", 4);

                /* FSI signature offset 0x1E0 */
                pc_cppad(&b[0x1e4], (UINT8 *)"rrAa", 4);

                if (!pdr->valid_fsinfo)   /* Set the free cluster count. */
                    pdr->free_clusters_count = pc_ifree(driveno);

                SWAP32((UINT32 *)&(b[0x1e8]), (UINT32 *)&pdr->free_clusters_count);

                SWAP32((UINT32 *)&(b[0x1ec]), (UINT32 *)&pdr->free_contig_pointer);

                /* Signature word */
                signature = 0xAA55;
                SWAP16((UINT16 *)&(b[0x1fe]), (UINT16 *)&signature);

                /* Update FSINFO */
                fstemp = (UINT32) pdr->fsinfo;
                for (i = 0; i < 2; i++)
                {
                    if ( !pc_bdevsw[driveno].io_proc(driveno, fstemp, &(b[0]), (UINT16) 1, NO) )
                    {
                        pc_report_error(PCERR_FMTWBZERO);
                        ret_val = NUF_IO_ERROR;
                        break;
                    }
                    fstemp += 6;
                }
            }
            if (ret_val == NU_SUCCESS)
            {
                /* Release the drive if opencount == 0 */
                ret_val = pc_dskfree(driveno, NO);
            }
        }
    }
    else
    {
        ret_val = NUF_NOT_OPENED;
    }
    return(ret_val);
}

⌨️ 快捷键说明

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