tffsdrv.c

来自「cpc-1631的BSP包for VxWorks操作系统」· C语言 代码 · 共 830 行 · 第 1/2 页

C
830
字号
        return (ERROR);
        }

    ioreq.irHandle = pTffsDev->tffsDriveNo;

    status = flCheckVolume(&ioreq);

    if (status == flNotMounted)
        {
        status = flMountVolume(&ioreq);

        if (status == flOK)
            {
            ioreq.irData = &bpb;
            status = flGetBPB(&ioreq);
            }

        if (status != flOK)
            {
            pTffsDev->tffsBlkdev.bd_readyChanged = TRUE;
            return (ERROR);
            }

        /* Modify BLK_DEV structure */

        tffsSetFromBPB( &(pTffsDev->tffsBlkdev), &bpb);

        pTffsDev->tffsBlkdev.bd_mode = O_RDWR; /* initial mode for device */
        }

    ioreq.irSectorNo    = startBlk;
    ioreq.irSectorCount = numBlks;
    ioreq.irData        = pBuffer;

    status = flAbsRead(&ioreq);

    /* if success cancel dosFs re-mount volume request */

    if (status != flOK)
        pTffsDev->tffsBlkdev.bd_readyChanged = TRUE;

    return ((status == flOK) ? OK : ERROR);
    }

/*******************************************************************************
*
* tffsBlkWrt - write sequence of blocks to TFFS device
*
* This routine writes a sequence of blocks to TrueFFS device.
*
* RETURNS: OK, or ERROR if it failed.
*
* NOMANUAL
*/

LOCAL STATUS tffsBlkWrt 
    (
    FAST TFFS_DEV * pTffsDev,		/* pointer to device descriptor */
    int startBlk,			/* starting block number to write */
    int numBlks,			/* number of blocks to write */
    char * pBuffer			/* pointer to buffer containing data */
    )
    {
    FLStatus   status = flOK;
    IOreq      ioreq;
    BPB        bpb;

    if ( (NULL == pTffsDev) || (NULL == pBuffer) ||
         (pTffsDev->tffsDriveNo >= DRIVES) )
        {
        return (ERROR);
        }

    ioreq.irHandle = pTffsDev->tffsDriveNo;

    status = flCheckVolume(&ioreq);

    if (status == flNotMounted)
        {
        status = flMountVolume(&ioreq);

        if (status == flOK)
            {
            ioreq.irData = &bpb;
            status = flGetBPB(&ioreq);
            }

        if (status != flOK)
            {
            pTffsDev->tffsBlkdev.bd_readyChanged = TRUE;
            return (ERROR);
            }

        /* Modify BLK_DEV structure */

        tffsSetFromBPB( &(pTffsDev->tffsBlkdev), &bpb);
        pTffsDev->tffsBlkdev.bd_mode = O_RDWR;	/* initial mode for device */
        }

    ioreq.irSectorNo    = startBlk;
    ioreq.irSectorCount = numBlks;
    ioreq.irData        = pBuffer;

    status = flAbsWrite(&ioreq);

    if (status == flWriteProtect)
        {
        flDismountVolume(&ioreq);		/* force a remount */
        pTffsDev->tffsBlkdev.bd_mode = O_RDONLY;
        }

    /* re-mount volume request */

    if (status != flOK)
        pTffsDev->tffsBlkdev.bd_readyChanged = TRUE;

    return ((status == flOK) ? OK : ERROR);
    }

/*******************************************************************************
*
* tffsSetFromBPB - copy some data from BIOS parameter block
*
* This routine copies BIOS parameter block data describing the flash device
* returned by TrueFFS into a device descriptor.
*
* RETURNS: N/A
*
* NOMANUAL
*/

LOCAL void tffsSetFromBPB 
    (
    BLK_DEV * pBlkDev,		/* pointer to device descriptor */
    BPB * pBPB			/* pointer to BIOS parameters block */
    )
    {
    if ((NULL == pBlkDev) || (NULL == pBPB))
        return;

    pBlkDev->bd_nBlocks      = 0;
    pBlkDev->bd_bytesPerBlk  = 0;
    pBlkDev->bd_blksPerTrack = 0;
    pBlkDev->bd_nHeads       = 0;     /* clear first */

    if( UNAL2(pBPB->totalSectorsInVolumeDOS3) )
        pBlkDev->bd_nBlocks  = UNAL2(pBPB->totalSectorsInVolumeDOS3);
    else
        pBlkDev->bd_nBlocks  = LE4(pBPB->totalSectorsInVolume);

    pBlkDev->bd_bytesPerBlk  = UNAL2(pBPB->bytesPerSector);
    pBlkDev->bd_blksPerTrack = LE2(pBPB->sectorsPerTrack);
    pBlkDev->bd_nHeads       = LE2(pBPB->noOfHeads);
    }

/*******************************************************************************
*
* tffsDiskChangeAnnounce - announce disk change to the file system attached
*
* This routine is called by TFFS to update the the readyChanged field in the
* device descriptor so that the file system can be notified of a disk change.
*
* RETURNS: N/A
*
* NOMANUAL
*/

void tffsDiskChangeAnnounce
    (
    unsigned volNo		/* FLite drive number (0 - DRIVES-1) */
    )
    {
    if ((volNo < DRIVES) && (tffsBlkDevs[volNo] != NULL))
        tffsBlkDevs[volNo]->tffsBlkdev.bd_readyChanged = TRUE;
    }

/*******************************************************************************
*
* tffsDevFormat - format a flash device for use with TrueFFS
*
* This routine formats a flash device for use with TrueFFS.  It takes two 
* parameters, a drive number and a pointer to a device format structure. 
* This structure describes how the volume should be formatted.  The structure 
* is defined in dosformt.h.  The drive number is assigned in the order that 
* the socket component for the device was registered.
*
* The format process marks each erase unit with an Erase Unit Header (EUH) and
* creates the physical and virtual Block Allocation Maps (BAM) for the device. 
* The erase units reserved for the "boot-image" are skipped and the first
* EUH is placed at number (boot-image length - 1). To write to the boot-image
* region, call tffsBootImagePut(). 
* 
* WARNING: If any of the erase units in the boot-image 
* region contains an erase unit header from a previous format call (this can
* happen if you reformat a flash device specifying a larger boot region) 
* TrueFFS fails to mount the device.  To fix this problem, use tffsRawio() to
* erase the problem erase units (thus removing the outdated EUH).  
*
* The macro TFFS_STD_FORMAT_PARAMS defines the default values used for 
* formatting a flask disk device. If the second argument to this routine 
* is zero, tffsDevFormat() uses these default values.
*
* RETURNS: OK, or ERROR if it failed.
*/

STATUS tffsDevFormat 
    (
    int tffsDriveNo,		/* TrueFFS drive number (0 - DRIVES-1) */
    int arg			/* pointer to tffsDevFormatParams structure */
    )
    {
    tffsDevFormatParams defaultParams = TFFS_STD_FORMAT_PARAMS;
    tffsDevFormatParams *devFormatParams;
    IOreq                ioreq;
    FLStatus             status;

    if (tffsDriveNo >= DRIVES)
        return (ERROR);

    /* tell dosFs to re-mount volume */
  
    if (tffsBlkDevs[tffsDriveNo] != NULL)
        tffsBlkDevs[tffsDriveNo]->tffsBlkdev.bd_readyChanged = TRUE;

    if (arg == 0)
        devFormatParams = &defaultParams;
    else
        devFormatParams = (tffsDevFormatParams *) arg;

    ioreq.irHandle = tffsDriveNo;
    ioreq.irFlags  = devFormatParams->formatFlags;
    ioreq.irData   = &(devFormatParams->formatParams);

    status = flFormatVolume(&ioreq);

    return ((status == flOK) ? OK : ERROR);
    }

/*******************************************************************************
*
* tffsRawio - low level I/O access to flash components
*
* Use the utilities provided by thisroutine with the utmost care. If you use 
* these routines carelessly, you risk data loss as well as  permanent 
* physical damage to the flash device.
*
* This routine is a gateway to a series of utilities (listed below). Functions 
* such as mkbootTffs() and tffsBootImagePut() use these tffsRawio() utilities 
* to write boot sector information. The functions for physical read, write, and 
* erase are made available with the intention that they be used on erase units 
* allocated to the boot-image region by tffsDevFormat(). Using these functions 
* elsewhere could be dangerous.
*
* The <arg0>, <arg1>, and <arg2> parameters to tffsRawio() are interpreted 
* differently depending on the function number you specify for <functionNo>. 
* The drive number is determined by the order in which the socket 
* components were registered. 
*
* .TS
* tab(|);
* lf3 lf3 lf3 lf3
* l l l l .
* Function Name | arg0 | arg1 | arg2
* _
* TFFS_GET_PHYSICAL_INFO | user buffer address | N/A | N/A
* TFFS_PHYSICAL_READ | address to read | byte count | user buffer address
* TFFS_PHYSICAL_WRITE | address to write | byte count | user buffer address
* TFFS_PHYSICAL_ERASE | first unit | number of units | N/A
* TFFS_ABS_READ	| sector number | number of sectors | user buffer address
* TFFS_ABS_WRITE | sector number | number of sectors | user buffer address
* TFFS_ABS_DELETE | sector number | number of sectors | N/A
* TFFS_DEFRAGMENT_VOLUME | number of sectors | user buffer address | N/A
* .TE
*
* TFFS_GET_PHYSICAL_INFO writes the flash type, erasable block size, and media
* size to the user buffer specified in <arg0>.
*
* TFFS_PHYSICAL_READ reads <arg1> bytes from <arg0> and writes them to 
* the buffer specified by <arg2>.
*
* TFFS_PHYSICAL_WRITE copies <arg1> bytes from the <arg2> buffer and writes 
* them to the flash memory location specified by <arg0>.  
* This aborts if the volume is already mounted to prevent the versions of 
* translation data in memory and in flash from going out of synchronization.
*
* TFFS_PHYSICAL_ERASE erases <arg1> erase units, starting at the erase unit
* specified in <arg0>.
* This aborts if the volume is already mounted to prevent the versions of 
* translation data in memory and in flash from going out of synchronization.
*
* TFFS_ABS_READ reads <arg1> sectors, starting at sector <arg0>, and writes
* them to the user buffer specified in <arg2>.
*
* TFFS_ABS_WRITE takes data from the <arg2> user buffer and writes <arg1> 
* sectors of it to the flash location starting at sector <arg0>.
* 
* TFFS_ABS_DELETE deletes <arg1> sectors of data starting at sector <arg0>. 
*
* TFFS_DEFRAGMENT_VOLUME calls the defragmentation routine with the minimum
* number of sectors to be reclaimed, <arg0>, and writes the actual number 
* reclaimed in the user buffer by <arg1>. Calling this function through some 
* low priority task will make writes more deterministic.
* No validation is done of the user specified address fields, so the functions 
* assume they are writable. If the address is invalid, you could see bus errors
* or segmentation faults.
* 
* RETURNS: OK, or ERROR if it failed.
*/

STATUS tffsRawio 
    (
    int tffsDriveNo,		/* TrueFFS drive number (0 - DRIVES-1) */
    int functionNo,		/* TrueFFS function code */
    int arg0,			/* argument 0 */
    int arg1,			/* argument 1 */
    int arg2			/* argument 2 */
    )
    {
    IOreq	ioreq;
    FLStatus	status;
    int		function;

    if (tffsDriveNo >= DRIVES)
        return (ERROR);

    ioreq.irHandle = tffsDriveNo;	/* drive number */

    switch (functionNo)
	{
	case TFFS_GET_PHYSICAL_INFO:
	    function = FL_GET_PHYSICAL_INFO;
	    ioreq.irData = (char *)arg0; /* address of user buffer to store */
	    break;

	case TFFS_PHYSICAL_READ:
	    function = FL_PHYSICAL_READ;
	    ioreq.irAddress = arg0;	/* chip/card address to read/write */
	    ioreq.irByteCount = arg1;	/* number of bytes to read/write */
	    ioreq.irData = (char *)arg2; /* address of user buffer to r/w */
	    break;

	case TFFS_PHYSICAL_WRITE:
	    function = FL_PHYSICAL_WRITE;
	    ioreq.irAddress = arg0;	/* chip/card address to read/write */
	    ioreq.irByteCount = arg1;	/* number of bytes to read/write */
	    ioreq.irData = (char *)arg2; /* address of user buffer to r/w */
	    break;

	case TFFS_PHYSICAL_ERASE:
	    function = FL_PHYSICAL_ERASE;
	    ioreq.irUnitNo = arg0;	/* first unit to erase */
	    ioreq.irUnitCount = arg1;	/* number of units to erase */
	    break;
	
	case TFFS_ABS_READ:
	    function = FL_ABS_READ;
	    ioreq.irSectorNo = arg0;	/* sector number to read/write */
	    ioreq.irSectorCount = arg1;	/* number of sectors to read/write */
	    ioreq.irData = (char *)arg2; /* address of user buffer to r/w */
	    break;
	
	case TFFS_ABS_WRITE:
	    function = FL_ABS_WRITE;
	    ioreq.irSectorNo = arg0;	/* sector number to read/write */
	    ioreq.irSectorCount = arg1;	/* number of sectors to read/write */
	    ioreq.irData = (char *)arg2; /* address of user buffer to r/w */
	    break;
	
	case TFFS_ABS_DELETE:
	    function = FL_ABS_DELETE;
	    ioreq.irSectorNo = arg0;	/* sector number to delete */
	    ioreq.irSectorCount = arg1;	/* number of sectors to delete */
	    break;
	
	case TFFS_DEFRAGMENT_VOLUME:
	    function = FL_DEFRAGMENT_VOLUME;
	    ioreq.irLength = arg0;	/* minimum number of sectors to get */
	    break;
	
	default:
	    return (ERROR);
	}

    status = flCall (function, &ioreq);

    switch (functionNo)
	{
	case TFFS_DEFRAGMENT_VOLUME:
	    *(int *)arg1 = ioreq.irLength; /* min number of sectors gotten */
	    break;
	}

    return ((status == flOK) ? OK : ERROR);
    }
#if     (POLLING_INTERVAL > 0)
/*******************************************************************************
*
* flPollSemCreate - create semaphore for polling task
*
* This routine creates the semaphore used to delay socket polling until
* TrueFFS initialization is complete.
*
* RETURNS: flOK, or flNotEnoughMemory if it fails.
*/

LOCAL FLStatus flPollSemCreate (void)
    {
    if ((flPollSemId = semBCreate (SEM_Q_PRIORITY, SEM_EMPTY)) == NULL)
        return (flNotEnoughMemory);
    else
        return (flOK);
    }
#endif /* (POLLING_INTERVAL > 0) */

⌨️ 快捷键说明

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