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

📄 rawfslib.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 4 页
字号:
	{	semGive (pRawFd->rawfd_semId);		/* release fd */	errnoSet (S_rawFsLib_FD_OBSOLETE);	return (ERROR);	}    /* Perform requested function */    switch (function)	{	case FIODISKINIT:	    retValue = OK;	    break;	case FIOSEEK:	    retValue = rawFsSeek (pRawFd, arg);	    break;	case FIOWHERE:	    retValue = rawFsWhere (pRawFd);	    break;	case FIOFLUSH:	case FIOSYNC:	    retValue = rawFsFlush (pRawFd->rawfd_vdptr);	    break;	case FIONREAD:	    *((int *) arg) = pRawFd->rawfd_endptr - (rawFsWhere (pRawFd));	    retValue = OK;	    break;	case FIODISKCHANGE:	    rawFsReadyChange (pRawFd->rawfd_vdptr);	    retValue = OK;	    break;	case FIOUNMOUNT:	    retValue = rawFsVolUnmount (pRawFd->rawfd_vdptr);	    break;	case FIOGETFL:	    *((int *) arg) = pRawFd->rawfd_mode;	    retValue = OK;	    break;	default:	    /* Call device driver function */	    retValue = (* pRawFd->rawfd_vdptr->rawvd_pBlkDev->bd_ioctl)		       (pRawFd->rawfd_vdptr->rawvd_pBlkDev, function, arg);	}    semGive (pRawFd->rawfd_semId);		/* release fd */    return (retValue);				/* return obtained result */    }/********************************************************************************* rawFsModeChange - modify the mode of a raw device volume** This routine sets the device's mode to <newMode> by setting the mode field in* the BLK_DEV structure.  This routine should be called whenever the read* and write capabilities are determined, usually after a ready change.** The driver's device initialization routine should initially set the mode* to O_RDWR (i.e., both O_RDONLY and O_WRONLY).** RETURNS: N/A** SEE ALSO: rawFsReadyChange()*/void rawFsModeChange    (    RAW_VOL_DESC  *vdptr,       /* pointer to volume descriptor */    int           newMode       /* O_RDONLY/O_WRONLY/O_RDWR (both) */    )    {    vdptr->rawvd_pBlkDev->bd_mode = newMode;    }/********************************************************************************* rawFsOpen - open a raw volume** This routine opens the volume with the specified mode* (O_RDONLY/O_WRONLY/O_RDWR/CREATE/TRUNC).** The specified <name> must be a null string, indicating that the* caller specified only the device name during open().** If the device driver supplies a status-check routine, it will be* called before the volume state is examined.** RETURNS: Pointer to raw volume file descriptor, or ERROR.*/LOCAL RAW_FILE_DESC *rawFsOpen    (    FAST RAW_VOL_DESC   *vdptr,         /* pointer to volume descriptor */    char                *name,          /* "file" name - should be empty str */    int                 flags           /* open flags */    )    {    FAST RAW_FILE_DESC	*pRawFd;	/* file descriptor pointer */    FAST BLK_DEV	*pBlkDev = vdptr->rawvd_pBlkDev;					/* pointer to block device info */    /* Check for open of other than raw volume (non-null filename) */    if (name [0] != EOS)	{	errnoSet (S_rawFsLib_ILLEGAL_NAME);	return ((RAW_FILE_DESC *) ERROR);	/* cannot specify filename */	}    /* Call driver check-status routine, if any */    if (vdptr->rawvd_pBlkDev->bd_statusChk != NULL)	{	if ((* vdptr->rawvd_pBlkDev->bd_statusChk) (vdptr->rawvd_pBlkDev) != OK)	    {	    return ((RAW_FILE_DESC *) ERROR);	/* driver returned error */	    }	}    /* Clear possible O_CREAT and O_TRUNC flag bits */    flags &= ~(O_CREAT | O_TRUNC);    /* Get a free file descriptor */    if ((pRawFd = rawFsFdGet()) == NULL)	return ((RAW_FILE_DESC *) ERROR);	/* max fd's already open */    semTake (pRawFd->rawfd_semId, WAIT_FOREVER); /* take control of fd */    /* Get ownership of volume */    semTake (vdptr->rawvd_semId, WAIT_FOREVER);	/* take volume */    /* Check that volume is available */    if (rawFsVolCheck (vdptr) != OK)	{	semGive (vdptr->rawvd_semId);	rawFsFdFree (pRawFd);	semGive (pRawFd->rawfd_semId);	errnoSet (S_rawFsLib_VOLUME_NOT_AVAILABLE);	return ((RAW_FILE_DESC *) ERROR);	/* cannot access volume */	}    /* Check for read-only volume opened for write/update */    if ((vdptr->rawvd_pBlkDev->bd_mode == O_RDONLY)  &&	(flags == O_WRONLY || flags == O_RDWR))	{	semGive (vdptr->rawvd_semId);	rawFsFdFree (pRawFd);	semGive (pRawFd->rawfd_semId);	errnoSet (S_ioLib_WRITE_PROTECTED);	return ((RAW_FILE_DESC *) ERROR);	/* volume not writable */	}    semGive (vdptr->rawvd_semId);		/* release volume */    pRawFd->rawfd_mode	   = flags;    pRawFd->rawfd_vdptr	   = vdptr;    pRawFd->rawfd_curptr   = 0;    pRawFd->rawfd_newptr   = 0;    pRawFd->rawfd_endptr   = (pBlkDev->bd_nBlocks * pBlkDev->bd_bytesPerBlk);    pRawFd->rawfd_modified = FALSE;    /* Allocate a 1 block buffer for short reads/writes */    pRawFd->rawfd_buffer = (char *)			   calloc ((unsigned) pBlkDev->bd_bytesPerBlk, 1);    if (pRawFd->rawfd_buffer == NULL)	{	rawFsFdFree (pRawFd);	return ((RAW_FILE_DESC *) ERROR);	/* mem alloc error */	}    pRawFd->rawfd_bufBlk = NONE;		/* no block in buffer yet */    semGive (pRawFd->rawfd_semId);		/* release fd */    return (pRawFd);    }/********************************************************************************* rawFsRead - read from a raw volume** This routine reads from the volume specified by the file descriptor* (returned by rawFsOpen()) into the specified buffer.* <maxbytes> bytes will be read, if there is that much data in the file.** RETURNS: Number of bytes actually read, or 0 if end of file, or ERROR.*/LOCAL int rawFsRead    (    FAST RAW_FILE_DESC  *pRawFd,        /* file descriptor pointer */    char                *pBuf,          /* addr of input buffer */    int                 maxBytes        /* maximum bytes to read into buffer */    )    {    STATUS		status;    int			bufIndex;	/* position in file I/O buffer */    FAST int		bytesLeft;	/* count of remaining bytes to read */    FAST int		nBytes;		/* byte count from individual read */    FAST int		blkNum;		/* starting block for read */    FAST int		numBlks;	/* number of blocks to read */    FAST RAW_VOL_DESC	*vdptr = pRawFd->rawfd_vdptr;					/* ptr to volume descriptor */    FAST BLK_DEV	*pBlkDev = pRawFd->rawfd_vdptr->rawvd_pBlkDev;					/* ptr to block device info */    FAST int		bytesPerBlk = pBlkDev->bd_bytesPerBlk;					/* number of bytes per block */    semTake (pRawFd->rawfd_semId, WAIT_FOREVER); /* take control of fd */    /* Check that file descriptor is current */    if (pRawFd->rawfd_status == RAWFD_OBSOLETE)	{	semGive (pRawFd->rawfd_semId);	errnoSet (S_rawFsLib_FD_OBSOLETE);	return (ERROR);	}    /* Check for valid maxBytes */    if (maxBytes <= 0)	{	semGive (pRawFd->rawfd_semId);	errnoSet (S_rawFsLib_INVALID_NUMBER_OF_BYTES);	return (ERROR);	}    semTake (vdptr->rawvd_semId, WAIT_FOREVER);	/* take control of volume */    /* Do successive reads until requested byte count or EOF */    bytesLeft = maxBytes;			/* init number remaining */    while (bytesLeft > 0)	{	nBytes = 0;				/* init individual read count */    	/* Do direct whole-block read if possible */    	if ((bytesLeft >= bytesPerBlk) &&	    (pRawFd->rawfd_newptr % bytesPerBlk == 0))	    {	    /* Calculate starting block and number to read */	    blkNum = pRawFd->rawfd_newptr / bytesPerBlk;            /* SPR# 9418: Check for new position past end of device */            if (blkNum >= pBlkDev->bd_nBlocks)                break;                          /* return number read OK */	    numBlks = bytesLeft / bytesPerBlk;	    /* Adjust if read would extend past end of device */	    numBlks = min (numBlks, (pBlkDev->bd_nBlocks - blkNum));	    /* Read blocks */	    if (rawFsBlkRd (vdptr, blkNum, numBlks, pBuf) != OK)	    	{				/* read error */		if (bytesLeft == maxBytes)	/* if nothing read yet */		    {	    	    semGive (vdptr->rawvd_semId);	    	    semGive (pRawFd->rawfd_semId);		    return (ERROR);		/*  indicate error */		    }		else	    	    break;			/* return number read OK */	    	}	    /* If file descriptor buffer contains modified data (O_RDWR mode)	     *  and the read included the buffered block, insert buffer	     *  contents into user's buffer at appropriate offset.	     */	    if (pRawFd->rawfd_modified)		{	    	if ((pRawFd->rawfd_bufBlk >= blkNum)  &&	    	    (pRawFd->rawfd_bufBlk < (blkNum + numBlks)))		    {    	    	    bcopy (pRawFd->rawfd_buffer,		           pBuf + ((pRawFd->rawfd_bufBlk - blkNum) *				   bytesPerBlk),		           bytesPerBlk);		    }		}	    nBytes = (numBlks * bytesPerBlk);	    }    	else					/* if not whole-block transfer*/	    {    	    /* Get new block in buffer, if necessary */    	    if ((status = rawFsBlkNew (pRawFd)) <= 0)		{				/* probably end of file */		if (bytesLeft == maxBytes)	/* if nothing read yet */		    {	    	    semGive (vdptr->rawvd_semId);	    	    semGive (pRawFd->rawfd_semId);		    return (status);		/*  indicate error */		    }		else	    	    break;			/* return number read OK */		}    	    /* Fill until end of caller's buffer, end of file buffer, or end     	     *  of volume, whichever comes first.	     */    	    bufIndex = pRawFd->rawfd_newptr % bytesPerBlk;    	    nBytes = min (bytesLeft, bytesPerBlk - bufIndex);    	    nBytes = min (nBytes,		          (pRawFd->rawfd_endptr - pRawFd->rawfd_newptr));    	    bcopy (&pRawFd->rawfd_buffer [bufIndex], pBuf, nBytes);	    }	/* Adjust count remaining, buffer pointer, and file pointer */	bytesLeft -= nBytes;	pBuf      += nBytes;    	pRawFd->rawfd_newptr += nBytes;	}  /* end while */    semGive (vdptr->rawvd_semId);		/* release volume */    semGive (pRawFd->rawfd_semId);		/* release fd */    return (maxBytes - bytesLeft);		/* number of bytes read */    }/********************************************************************************* rawFsReadyChange - notify rawFsLib of a change in ready status** This routine sets the volume descriptor state to RAW_VD_READY_CHANGED.* It should be called whenever a driver senses that a device has come on-line* or gone off-line, (e.g., a disk has been inserted or removed).** After this routine has been called, the next attempt to use the volume* will result in an attempted remount.** RETURNS: N/A*/void rawFsReadyChange    (    RAW_VOL_DESC *vdptr         /* pointer to volume descriptor */    )    {    vdptr->rawvd_state = RAW_VD_READY_CHANGED;    }/********************************************************************************* rawFsReset - reset a volume** This routine calls the specified volume's reset routine, if any.* If the reset fails, rawvd_state is set to (RAW_VD_CANT_RESET)* to indicate that disk won't reset.** RETURNS: OK, or ERROR if driver returned error.*/LOCAL STATUS rawFsReset    (    FAST RAW_VOL_DESC   *vdptr          /* pointer to volume descriptor */    )    {    FAST BLK_DEV	*pBlkDev = vdptr->rawvd_pBlkDev;					/* pointer to block device struct */    if (pBlkDev->bd_reset != NULL)	{	if ((* pBlkDev->bd_reset) (pBlkDev) != OK)	    {	    vdptr->rawvd_state = RAW_VD_CANT_RESET;	    return (ERROR);	    }	}    return (OK);    }/********************************************************************************* rawFsSeek - change file descriptor's current character position** This routine sets the specified file descriptor's current character* position to the specified position.  This only changes the pointer, it* doesn't affect the hardware at all.** Attempts to set the character pointer to a negative offset (i.e. before* the start of the disk) or to a point beyond the end of the device* will return ERROR.** RETURNS: OK, or ERROR if invalid character offset.*/LOCAL STATUS rawFsSeek    (    FAST RAW_FILE_DESC  *pRawFd,        /* file descriptor pointer */    int                 position        /* desired character position in file */

⌨️ 快捷键说明

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