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

📄 cbiolib.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 5 页
字号:
    semGive(&pDev->cbio_mutex);    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.  * * dev - the CBIO handle of the device being accessed (from creation routine)* * src_block - source start block of the copy* * dst_block - destination start block of the copy* * num_block - number of blocks to copy** RETURNS OK or ERROR and may otherwise set errno.*/LOCAL STATUS blkWrapBlkCopy    (    CBIO_DEV_ID 	dev,    block_t		src_block,    block_t		dst_block,    block_t		num_blocks    )    {    CBIO_DEV	*pDev = (void *) dev ;    BLK_DEV *	pBd = pDev->pDc ;    STATUS	stat = OK;#ifdef DEBUG    if( OBJ_VERIFY( dev, cbioClassId ) != OK)	{	INFO_MSG("blkWrapBlkCopy: invalid handle\n",0,0,0,0,0,0);	errno = S_objLib_OBJ_ID_ERROR;	return ERROR;	}#endif    if( pBd->bd_readyChanged || dev->cbio_readyChanged )	{	dev->cbio_readyChanged = TRUE ;	errno = S_ioLib_DISK_NOT_PRESENT ;	return ERROR;	}    if( (src_block) > pDev->params.cbio_nBlocks ||	(dst_block) > pDev->params.cbio_nBlocks )	{	errno = EINVAL;	return ERROR;	}    if( (src_block+num_blocks) > pDev->params.cbio_nBlocks ||	(dst_block+num_blocks) > pDev->params.cbio_nBlocks )	{	errno = EINVAL;	return ERROR;	}    if( semTake( &pDev->cbio_mutex, WAIT_FOREVER) == ERROR )	return ERROR;    /* verify that there is a block buffer, if not, allocate one */    if( pDev->cbio_memBase == NULL)	{	if( cbioBufCreate( pDev) == ERROR )	    {	    semGive(&pDev->cbio_mutex);	    return ERROR;	    }	}    /* flush the current contents of the block buffer if needed */    if( pDev->cbio_blkNo != (u_long)NONE &&          pDev->cbio_dirtyMask != (u_long)0 )	{	block_t cachedBlock = pDev->cbio_blkNo ;	stat = blkWrapBlkRW( pDev, cachedBlock, 1,			    pDev->cbio_memBase, CBIO_WRITE, NULL);	if( stat == ERROR )	    {	    semGive(&pDev->cbio_mutex);	    return ERROR;	    }	}    pDev->cbio_blkNo = NONE ;	/* invalidate buffer contents */    pDev->cbio_dirtyMask = 0;    /* because tiny cache is one block size, copy blocks one at a time */    for(; num_blocks > 0; num_blocks -- )	{	stat = blkWrapBlkRW( pDev, src_block, 1,			    pDev->cbio_memBase, CBIO_READ, NULL);	if( stat == ERROR)	    break;	stat = blkWrapBlkRW( pDev, dst_block, 1,			    pDev->cbio_memBase, CBIO_WRITE, NULL);	if( stat == ERROR)	    break;	src_block ++;	dst_block ++;	}    semGive(&pDev->cbio_mutex);    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** Arguments are:* .IP* dev - the CBIO handle of the device being accessed (from creation routine)* .IP * command - ioctl() command being issued* .IP * arg - specific to the particular ioctl() function requested or un-used.* .LP** RETURNS OK or ERROR and may otherwise set errno.*/LOCAL STATUS blkWrapIoctl    (    CBIO_DEV_ID	dev,    int		command,    addr_t	arg    )    {    FAST CBIO_DEV *	pDev = (void *) dev ;    FAST BLK_DEV *	pBd = pDev->pDc ;    STATUS		stat = OK ;    if( OBJ_VERIFY( pDev, cbioClassId ) != OK)	{	errno = S_objLib_OBJ_ID_ERROR;	return ERROR;	}    if( semTake( &pDev->cbio_mutex, 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, limit = cbioBlkDevPtrLimit ;	/*	 * here we must verify BLK_DEV in much the same way as in	 * cbioDevVerify()	 */	stat = ERROR ;	errno = EINVAL ;	/* if the input is a valid CBIO device, ignore it */	if( OBJ_VERIFY( (void *) pBd, cbioClassId ) == OK)	    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	    {	    tmp = (long) pBd->bd_blkRd ;	    if( abs((long)pBd->bd_blkWrt - tmp) > limit ||		abs((long)pBd->bd_ioctl - tmp) > limit )		goto ioctl_exit ;	    if( (pBd->bd_statusChk != NULL ) &&		abs((long)pBd->bd_statusChk - tmp) > limit )		goto ioctl_exit ;	    /* 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 */	dev->cbio_readyChanged = TRUE ;	dev->pDc = (void *) pBd ;	semGive(&pDev->cbio_mutex);	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 );	pDev->cbio_readyChanged = (stat == ERROR) ? TRUE : FALSE ;	/* since the block size may have changed, we must re-init */	if( FALSE == pDev->cbio_readyChanged )	    {	    pBd->bd_readyChanged = FALSE ;/* XXX- FDC hack */	    pDev->params.cbio_nBlocks		= pBd->bd_nBlocks ;	    pDev->params.cbio_bytesPerBlk	= pBd->bd_bytesPerBlk ;	    pDev->params.cbio_blksPerTrack	= pBd->bd_blksPerTrack ;	    pDev->params.cbio_nHeads		= pBd->bd_nHeads ;	    pDev->params.cbio_offset		= 0 ;	    pDev->cbio_mode		= pBd->bd_mode ;	    if( pDev->cbio_memBase != NULL &&		pDev->cbio_memSize != pBd->bd_bytesPerBlk )		{		free( pDev->cbio_memBase );		pDev->cbio_memBase = NULL ;		pDev->cbio_memSize = 0;		pDev->pFuncs->cbio_blkRW = blkWrapBlkRW ;		}#ifdef	__unused__	    blkWrapDiskSizeAdjust( pDev) ;#endif	/*__unused__*/	    pDev->params.cbio_lastErrBlk = NONE ;	    pDev->params.cbio_lastErrno	 = 0 ;	    }	if( stat == ERROR && errno == OK )	    errno = S_ioLib_DISK_NOT_PRESENT ;	 	semGive(&pDev->cbio_mutex);	return stat;	}    /* all other commands, except RESET, wont work if disk is not there */    if( pBd->bd_readyChanged || pDev->cbio_readyChanged )	{	pDev->cbio_readyChanged = TRUE ;	errno = S_ioLib_DISK_NOT_PRESENT ;	semGive(&pDev->cbio_mutex);	return ERROR;	}    switch ( command )	{	case CBIO_STATUS_CHK : 	    stat = pBd->bd_statusChk( pBd );	    pDev->cbio_readyChanged = (stat == ERROR) ? TRUE : FALSE ;	    pBd->bd_readyChanged = FALSE ;/* XXX- FDC hack */	    break;	case CBIO_CACHE_FLUSH :	case CBIO_CACHE_INVAL :	case CBIO_CACHE_NEWBLK:	    if( pDev->cbio_memBase != NULL &&		pDev->cbio_blkNo != (u_long)NONE &&                 pDev->cbio_dirtyMask != (u_long)0 )		{		block_t cachedBlock = pDev->cbio_blkNo ;		stat = blkWrapBlkRW( pDev, cachedBlock, 1,			    pDev->cbio_memBase, CBIO_WRITE, NULL);		}	    if( pDev->cbio_memBase != (u_long)NULL &&                 command == (int)CBIO_CACHE_NEWBLK )		{		bzero( pDev->cbio_memBase, pDev->cbio_memSize);		pDev->cbio_blkNo = (block_t) arg ;		pDev->cbio_dirtyMask = 1;		}	    else		{		pDev->cbio_blkNo = NONE ;		pDev->cbio_dirtyMask = 0;		}	    break;	default:	    stat = pBd->bd_ioctl( pBd, command, arg );	    break ;	case CBIO_RESET : /* dealt with above, for switch completeness */	case CBIO_DEVICE_LOCK :	/* unimplemented commands */	case CBIO_DEVICE_UNLOCK :	case CBIO_DEVICE_EJECT :	    errno = S_ioLib_UNKNOWN_REQUEST;	    stat = ERROR;	    break;	}    ioctl_exit:    semGive(&pDev->cbio_mutex);    return stat;    }#ifdef	__unused__/********************************************************************************* blkWrapDiskSizeAdjust - adjust true disk size** Some block drivers report incorrect disk capacity in bd_nBlocks field.* This function will experimentally discover the true size of the disk,* by reading blocks until an error is returned by the driver.* In order to overcome driver's sanity checks, the bd_nBlocks will* be adjusted each time a call is made to read blocks beyond the* previously reported capacity.* There is a time limit on these attempts, so the final result may* be still inaccurate if the capacity reported by the driver* is significantly different from the actual disk capacity.** RETURNS: N/A*/LOCAL void blkWrapDiskSizeAdjust    (    CBIO_DEV_ID 	dev 	/* CBIO device handle */    )    {    FAST CBIO_DEV *	pDev = (void *) dev ;    FAST BLK_DEV *	pBd = pDev->pDc ;    STATUS		stat = OK ;    int timeout = tickGet() + 2 * sysClkRateGet();	/* 2 sec timeout */    int orig_nBlocks, secPerCyl ;    caddr_t tmpBuf ;    orig_nBlocks = pBd->bd_nBlocks ;    secPerCyl = pBd->bd_blksPerTrack * pBd->bd_nHeads ;    tmpBuf = malloc( pBd->bd_bytesPerBlk );    /* increment capacity by one cylinder and test readability */    while( (tickGet()<=timeout) && (stat == OK ) )	{	/* read last block in current capacity */	stat = pBd->bd_blkRd( pBd, pBd->bd_nBlocks-1, 1, tmpBuf );	/* if OK, try to read end of next cyl, if failed, go back and break */	if( stat == OK )	    pBd->bd_nBlocks += secPerCyl;	else	    pBd->bd_nBlocks -= secPerCyl;	}    /* refresh timeout */    timeout = tickGet() + (2 * sysClkRateGet());	/* 2 sec timeout */    stat = OK ;    /* increment capacity by one sector and test readability */    while( (tickGet() <= timeout) && (stat == OK ) )	{	/* read last block in current capacity */	stat = pBd->bd_blkRd( pBd, pBd->bd_nBlocks-1, 1, tmpBuf );	if( stat == OK )	    pBd->bd_nBlocks ++ ;	else	    pBd->bd_nBlocks -- ;	}#ifdef	DEBUG	if(cbioDebug > 0 && tickGet()> timeout )	    logMsg("blkWrapDiskSizeAdjust: timeout %d exceeded\n",		timeout,0,0,0,0,0);#endif    /* if all goes well, the last read operation should have succeeded */    if( (stat = pBd->bd_blkRd( pBd, pBd->bd_nBlocks-1, 1, tmpBuf )) == OK)	{#ifdef	DEBUG	if(cbioDebug > 0)	    logMsg("blkWrapDiskSizeAdjust: capacity increased by %d blocks\n",		pBd->bd_nBlocks - orig_nBlocks, 0,0,0,0,0);#endif	/* make it official */	pDev->params.cbio_nBlocks = pBd->bd_nBlocks ;	}    else	{	/* something is weird, put it back where it was */#ifdef	DEBUG	if(cbioDebug > 0)	    logMsg("blkWrapDiskSizeAdjust: failed to adjust\n",		0,0,0,0,0,0);#endif	pDev->params.cbio_nBlocks = pBd->bd_nBlocks = orig_nBlocks ;	}    free( tmpBuf );    }#endif	/*__unused__*//* End of File */

⌨️ 快捷键说明

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