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

📄 cbiolib.c

📁 vxworks操作系统的文件系统部分原代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		if( pBd->bd_reset != NULL )		    pBd->bd_reset( pBd );		do		    {		    if( blkWrapIoctl( pDev, CBIO_STATUS_CHK, 0) == OK)			goto retryLoop;		    taskDelay(5);		    } while( tickGet() < (UINT32) tick+sysClkRateGet() ) ;		}	    }	}    return stat;    }/********************************************************************************* blkWrapBlkRWbuf - wrapper block I/O for coherency with tiny cache** This routine transfers between a user buffer and the lower layer BLK_DEV* It is optimized for block transfers.  ** RETURNS OK or ERROR and may otherwise set errno.*/LOCAL STATUS blkWrapBlkRWbuf    (    CBIO_DEV_ID     dev,    block_t         startBlock,    block_t         numBlocks,    addr_t          buffer,    CBIO_RW    	    rw,    cookie_t *      pCookie    )    {    FAST CBIO_DEV * pDev = dev ;    STATUS stat = OK ;    if( semTake( pDev->cbioMutex, WAIT_FOREVER) == ERROR )	return ERROR;    /* verify that there is a block buffer, if not, allocate one */    if( pDev->cbioMemBase == NULL)	{	if( cbioBlkWrapBufCreate( pDev) == ERROR )	    {	    semGive(pDev->cbioMutex);	    return ERROR;	    }	}    /* see if Tiny Cache contains a valid block */    if( pDev->cbioBlkNo != (u_long) NONE )	{	/* see if the range touches the cached block */	if( (pDev->cbioBlkNo >= startBlock) &&	    (pDev->cbioBlkNo < startBlock+numBlocks) )	    {	    /* flush the current contents of the block buffer if dirty */	    if( pDev->cbioDirtyMask != 0 )		{		block_t cachedBlock = pDev->cbioBlkNo ;		pDev->cbioBlkNo = NONE ;		pDev->cbioDirtyMask = 0;		stat = blkWrapBlkRW(  pDev, cachedBlock, 1,			    pDev->cbioMemBase, CBIO_WRITE, NULL);		}	    else		{		/* else just forget about it */		pDev->cbioBlkNo = NONE ;		}	    }	}    if( stat == ERROR )        {        semGive(pDev->cbioMutex); /* added semGive to fix SPR#76103 */        return (ERROR);        }                      stat = blkWrapBlkRW (dev, startBlock, numBlocks, buffer, rw, pCookie) ;    semGive(pDev->cbioMutex);    return stat ;    }/********************************************************************************* blkWrapBytesRW - Read/Write bytes** In order to implement the byte-wise read/write operation, a tiny* cache is implemented, which is used to store block data on which* byte operations are performed.** The tiny cache is a single disk block sized buffer at this time* which should suffice for solid-state (e.g. Flash) disks to be used* without the real disk cache, meaning dosFsLib directly on top of* this wrapper.** This routine transfers between a user buffer and the lower layer BLK_DEV* It is optimized for byte transfers.  ** RETURNS OK or ERROR and may otherwise set errno.*/LOCAL STATUS blkWrapBytesRW    (    CBIO_DEV_ID 	dev,    block_t		startBlock,    off_t		offset,    addr_t		buffer,    size_t		nBytes,    CBIO_RW		rw,    cookie_t *		pCookie    )    {    CBIO_DEV * 	pDev = dev ;    BLK_DEV *	pBd = pDev->blkSubDev;    STATUS	stat = OK ;    caddr_t 	pStart;    if( pBd->bd_readyChanged || CBIO_READYCHANGED (dev))	{	cbioRdyChgdSet(dev, TRUE);	errno = S_ioLib_DISK_NOT_PRESENT ;	return ERROR;	}    if( startBlock >= pDev->cbioParams.nBlocks )	{	errno = EINVAL;	return ERROR;	}    /* verify that all bytes are within one block range */    if (((offset + nBytes) > pDev->cbioParams.bytesPerBlk ) ||	(offset <0) || (nBytes <=0))	{	errno = EINVAL;	return ERROR;	}    if( semTake( pDev->cbioMutex, WAIT_FOREVER) == ERROR )	return ERROR;    /* verify that there is a block buffer, if not, allocate one */    if( pDev->cbioMemBase == NULL)	{	if( cbioBlkWrapBufCreate( pDev) == ERROR )	    {	    semGive(pDev->cbioMutex);	    return ERROR;	    }	}    /* flush the current contents of the block buffer if needed */    if( pDev->cbioBlkNo != (u_long)NONE &&	 pDev->cbioBlkNo != startBlock &&	 pDev->cbioDirtyMask != 0 )	{	block_t cachedBlock = pDev->cbioBlkNo ;	pDev->cbioBlkNo = NONE ;	pDev->cbioDirtyMask = 0;	stat = blkWrapBlkRW( pDev, cachedBlock, 1,			    pDev->cbioMemBase, CBIO_WRITE, NULL);	if( stat == ERROR )	    {	    semGive(pDev->cbioMutex);	    return ERROR;	    }	}    /* get the requested block into cache */    if( startBlock != pDev->cbioBlkNo && pDev->cbioDirtyMask == 0 )	{	stat = blkWrapBlkRW( pDev, startBlock, 1,			    pDev->cbioMemBase, CBIO_READ, NULL);	if( stat == ERROR )	    {	    semGive(pDev->cbioMutex);	    return ERROR;	    }	pDev->cbioBlkNo = startBlock ;	pDev->cbioDirtyMask = 0;	}    assert( startBlock == pDev->cbioBlkNo );    /* calculate actual memory address of data */    pStart = pDev->cbioMemBase + offset ;#ifdef	DEBUG    if(cbioDebug > 1)	logMsg("blkWrapBytesRW: blk %d + %d # %d bytes -> addr %x, %x bytes\n",	    startBlock, offset, nBytes, (int) pStart, nBytes, 0);#endif    switch( rw )	{	case CBIO_READ:	    bcopy( pStart, buffer, nBytes );	    break;	case CBIO_WRITE:	    bcopy( buffer, pStart,  nBytes );	    pDev->cbioDirtyMask = 1;	    break;	}    semGive(pDev->cbioMutex);    return (OK);    }/********************************************************************************* blkWrapBlkCopy - Copy sectors ** This routine makes copies of one or more blocks on the lower layer BLK_DEV.* It is optimized for block copies on the subordinate layer.  * * RETURNS OK or ERROR and may otherwise set errno.*/LOCAL STATUS blkWrapBlkCopy    (    CBIO_DEV_ID 	dev,    block_t		srcBlock,    block_t		dstBlock,    block_t		numBlocks    )    {    CBIO_DEV	*pDev = (void *) dev ;    BLK_DEV *	pBd = pDev->blkSubDev;    STATUS	stat = OK;    if( pBd->bd_readyChanged || CBIO_READYCHANGED(dev))	{	CBIO_READYCHANGED(dev) = TRUE;	errno = S_ioLib_DISK_NOT_PRESENT ;	return (ERROR);	}    if( (srcBlock) > pDev->cbioParams.nBlocks ||	(dstBlock) > pDev->cbioParams.nBlocks )	{	errno = EINVAL;	return ERROR;	}    if( (srcBlock+numBlocks) > pDev->cbioParams.nBlocks ||	(dstBlock+numBlocks) > pDev->cbioParams.nBlocks )	{	errno = EINVAL;	return ERROR;	}    if( semTake( pDev->cbioMutex, WAIT_FOREVER) == ERROR )	return ERROR;    /* verify that there is a block buffer, if not, allocate one */    if( pDev->cbioMemBase == NULL)	{	if( cbioBlkWrapBufCreate( pDev) == ERROR )	    {	    semGive(pDev->cbioMutex);	    return ERROR;	    }	}    /* flush the current contents of the block buffer if needed */    if( pDev->cbioBlkNo != (u_long)NONE &&          pDev->cbioDirtyMask != (u_long)0 )	{	block_t cachedBlock = pDev->cbioBlkNo ;	stat = blkWrapBlkRW( pDev, cachedBlock, 1,			    pDev->cbioMemBase, CBIO_WRITE, NULL);	if( stat == ERROR )	    {	    semGive(pDev->cbioMutex);	    return ERROR;	    }	}    pDev->cbioBlkNo = NONE ;	/* invalidate buffer contents */    pDev->cbioDirtyMask = 0;    /* because tiny cache is one block size, copy blocks one at a time */    for(; numBlocks > 0; numBlocks -- )	{	stat = blkWrapBlkRW( pDev, srcBlock, 1,			    pDev->cbioMemBase, CBIO_READ, NULL);	if( stat == ERROR)	    break;	stat = blkWrapBlkRW( pDev, dstBlock, 1,			    pDev->cbioMemBase, CBIO_WRITE, NULL);	if( stat == ERROR)	    break;	srcBlock ++;	dstBlock ++;	}    semGive(pDev->cbioMutex);    return stat;    }/********************************************************************************* blkWrapIoctl - Misc control operations ** This performs the requested ioctl() operation.* * CBIO modules can expect the following ioctl() codes from cbioLib.h:* .IP* CBIO_RESET - reset the CBIO device.   When the third argument to the ioctl* call accompaning CBIO_RESET is NULL, the code verifies that the disk is * inserted and is ready, after getting it to a known state.   When the 3rd * argument is a non-zero, it is assumed to be a BLK_DEV pointer and * CBIO_RESET will install a new subordinate block device.    This work* is performed at the BLK_DEV to CBIO layer, and all layers shall account* for it.  A CBIO_RESET indicates a possible change in device geometry, * and the CBIO_PARAMS members will be reinitialized after a CBIO_RESET.* .IP* CBIO_STATUS_CHK - check device status of CBIO device and lower layer* .IP* CBIO_DEVICE_LOCK - Prevent disk removal * .IP* CBIO_DEVICE_UNLOCK - Allow disk removal* .IP* CBIO_DEVICE_EJECT - Unmount and eject device* .IP* CBIO_CACHE_FLUSH - Flush any dirty cached data* .IP* CBIO_CACHE_INVAL - Flush & Invalidate all cached data* .IP* CBIO_CACHE_NEWBLK - Allocate scratch block* .LP** RETURNS OK or ERROR and may otherwise set errno.*/LOCAL STATUS blkWrapIoctl    (    CBIO_DEV_ID	dev,    UINT32	command,    addr_t	arg    )    {    FAST CBIO_DEV_ID 	pDev = dev ;    FAST BLK_DEV *	pBd = pDev->blkSubDev ;    STATUS		stat = OK ;    if( semTake( pDev->cbioMutex, WAIT_FOREVER) == ERROR )	return ERROR;    /*     * CBIO_RESET may be optionally used to      * install a new subordinate block device     * if 3rd argument is non-zero, it is expected to be     * a new BLK_DEV pointer.     */    if( command == (int)CBIO_RESET  && arg != NULL )	{	BLK_DEV * pBd = (void *) arg ;	int tmp;	/*	 * here we must verify BLK_DEV in much the same way as in	 * cbioWrapBlkDev()	 */	stat = ERROR ;	errno = EINVAL ;	/* if the input is already a valid CBIO device, ignore it */	if (OK == cbioDevVerify ((CBIO_DEV_ID)pBd))	    {	    goto ioctl_exit ; 	    }	/* blkIo has no mechanism for verification, improvise */	else if( (pBd->bd_blkRd == NULL) || (pBd->bd_blkWrt == NULL) ||		(pBd->bd_ioctl == NULL) )	    goto ioctl_exit ;	else	    {	    /* check that bytesPerBlk is 2^n */	    tmp = shiftCalc( pBd->bd_bytesPerBlk );	    if( pBd->bd_bytesPerBlk != (ULONG)( 1 << tmp ) )		goto ioctl_exit ;	    /* 	     * for simplicity, we place a dummy function	     * if statusChk is not provided	     */	    if( pBd->bd_statusChk == NULL )		pBd->bd_statusChk = cbioWrapOk ;	    stat = OK ;	    errno = 0;	    }	/* this means that RESET will be later issued and reset all fields */	CBIO_READYCHANGED(dev) = TRUE;	dev->blkSubDev = (void *) pBd ;	dev->pDc = (void *) pBd ;	semGive(pDev->cbioMutex);	return (stat);	}    /* End of CBIO_RESET for BLK_DEV replacement handling */    /*     * CBIO_RESET - 3rd arg is NULL:     * verify that the disk is inserted and is ready,     * after getting it to a known state for good measure     * and reset readyChanged if indeed the disk is ready to roll.     */    if( command == (int)CBIO_RESET )	{	stat = OK;         errno = OK;	/* if the Block's got a reset function, call it */	if( pBd->bd_reset != NULL )            {            stat = pBd->bd_reset( pBd );            }	/* 	 * for simplicity, we place a dummy function	 * if statusChk is not provided	 */	if( pBd->bd_statusChk == NULL )	    pBd->bd_statusChk = cbioWrapOk ;	/*	 * the drive's got a status check function,	 * use it to find out if all is cool and dandy, and	 * determine current state from status check result	 */	stat = pBd->bd_statusChk( pBd );        CBIO_READYCHANGED(dev) = (ERROR == stat) ? TRUE : FALSE;	/* since the block size may have changed, we must re-init */	if( FALSE == CBIO_READYCHANGED (dev) )	    {	    pBd->bd_readyChanged = FALSE ;	/* HELP - FDC hack */	    pDev->cbioParams.nBlocks		= pBd->bd_nBlocks ;	    pDev->cbioParams.bytesPerBlk	= pBd->bd_bytesPerBlk ;	    pDev->cbioParams.blocksPerTrack	= pBd->bd_blksPerTrack ;	    pDev->cbioParams.nHeads		= pBd-

⌨️ 快捷键说明

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