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

📄 cbiolib.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 5 页
字号:
    caddr_t  	ramAddr, 	/* where it is in memory (0 = malloc) */    size_t	ramSize		/* pool size */    )    {    CBIO_DEV *	pDev = NULL ;    caddr_t	pBase = NULL ;    if( !cbioInstalled )	if( cbioLibInit() == ERROR )	     goto error;    if (ramSize != 0)	{	if( ramAddr == NULL )	    pBase = malloc(ramSize );	else	    pBase = ramAddr ;	if( pBase == NULL )	    goto error ;	}    /* allocate and initialize the device control structure */    pDev = (CBIO_DEV *) objAlloc( cbioClassId );    if( pDev == NULL )	goto error;    /* init Common fields */    if( semMInit( &pDev->cbio_mutex,	cbioMutexSemOptions ) == ERROR)	goto error ;    pDev->cbio_readyChanged	= FALSE ;    pDev->params.cbio_lastErrBlk	= NONE ;    pDev->params.cbio_lastErrno	= 0 ;    pDev->cbio_memBase		= pBase ;    pDev->cbio_memSize		= ramSize ;    /* pointer to method functions needs to be filled later */    pDev->pFuncs = NULL ;    /* make this object belong to its class */    objCoreInit (&pDev->objCore, cbioClassId);    cbioRecentDev = pDev ;    /* return device handle */    return( (CBIO_DEV_ID) pDev );error:    if( pBase != NULL )	free (pBase);    if( pDev != NULL )	free (pDev);    return ( NULL );    }/********************************************************************************* shiftCalc - calculate how many shift bits** How many shifts <n< are needed such that <mask> == 1 << <N>* This is very useful for replacing multiplication with shifts,* where it is known a priori that the multiplier is 2^k.** RETURNS: Number of shifts.*/LOCAL int shiftCalc    (    u_long mask    )    {    FAST i;    for (i=0; i<32; i++)	{	if (mask & 1)	    break ;	mask = mask >> 1 ;	}    return( i );    }/********************************************************************************* cbioWrapOk - dummy function returning OK**/LOCAL STATUS cbioWrapOk ()    {    return OK;    }/********************************************************************************* cbioBufCreate - create the local block buffer**/LOCAL STATUS cbioBufCreate ( CBIO_DEV_ID pDev )    {    if( pDev->cbio_memBase != NULL &&	pDev->cbio_memSize != pDev->params.cbio_bytesPerBlk )	{	/* block size may have changed */	free( pDev->cbio_memBase );	pDev->cbio_memBase = 0;	pDev->cbio_memSize = 0;	}    if( pDev->cbio_memBase == NULL && pDev->cbio_memSize == 0 )	{	pDev->cbio_memSize = pDev->params.cbio_bytesPerBlk ;	pDev->cbio_memBase = malloc( pDev->cbio_memSize );	if( pDev->cbio_memBase == NULL )	    {	    return ERROR;	    }	/* Overload the block I/O function, better own the mutex here */	pDev->pFuncs->cbio_blkRW = blkWrapBlkRWbuf ;	/* empty block */	pDev->cbio_blkNo = (u_long)NONE ;	pDev->cbio_dirtyMask = 0;	return OK;	}    else 	{	errno = EINVAL;	return ERROR;	}    }/********************************************************************************* blkWrapBlkRW	- Read/Write blocks** Wrapper block Read/Write function calls the blkIo functions* directly, It does not deal with the tiny cache, and is used* only when there is no Tiny cache for by byte-wise operations.* When a tiny cache is installed, this function is overloaded* with the blkWrapBlkRWbuf function, which deals with Tiny cache* coherency and call this function subsequently.** This routine transfers between a user buffer and the lower layer * BLK_DEV. It is optimized for block transfers.  ** dev - the CBIO handle of the device being accessed (from creation routine)* * start_block - the starting block of the transfer operation* * num_blocks - the total number of blocks to transfer* * buffer - address of the memory buffer used for the transfer* * rw - indicates the direction of transfer up or down (READ/WRITE)* * *cookie - pointer to cookie used by upper layer such as dosFsLib(),* it should be preserved.** RETURNS OK or ERROR and may otherwise set errno.*/LOCAL STATUS blkWrapBlkRW    (    CBIO_DEV_ID		dev,    block_t		start_block,    block_t		num_blocks,    addr_t		buffer,    enum cbio_rw	rw,    cookie_t		*cookie    )    {    CBIO_DEV *	pDev = (void *) dev ;    BLK_DEV *	pBd = pDev->pDc ;    STATUS stat = ERROR;    int retryCount = 0 ;#ifdef	DEBUG    if( OBJ_VERIFY( dev, cbioClassId ) != OK)	{	INFO_MSG("blkWrapBlkRW: invalid handle\n",0,0,0,0,0,0);	errno = S_objLib_OBJ_ID_ERROR;	return ERROR;	}#endifretry_loop:    if( pBd->bd_readyChanged || dev->cbio_readyChanged )	{	dev->cbio_readyChanged = TRUE ;	errno = S_ioLib_DISK_NOT_PRESENT ;	return ERROR;	}    if( start_block > pDev->params.cbio_nBlocks ||	(start_block+num_blocks) > pDev->params.cbio_nBlocks )	{	errno = EINVAL;	return ERROR;	}    switch( rw )	{	case CBIO_READ:	    stat = pBd->bd_blkRd( pBd, start_block, num_blocks, buffer);	    break;	case CBIO_WRITE:	    stat = pBd->bd_blkWrt( pBd, start_block, num_blocks, buffer);	    break;	default:	    errno = S_ioLib_UNKNOWN_REQUEST;	    return ERROR;	}    /* record error if any */    if( stat == ERROR )	{	pDev->params.cbio_lastErrBlk = start_block;	pDev->params.cbio_lastErrno = errno ;	if( errno == S_ioLib_DISK_NOT_PRESENT )	    dev->cbio_readyChanged = TRUE;	/* some block drivers dont do retires relying on old dosFs for that */	if( (blkWrapIoctl( pDev, CBIO_STATUS_CHK, 0) == OK) &&	    ( retryCount++ < pBd->bd_retry ))	    {	    int tick = tickGet();	    /* if device was not obviously replaced, try to reset it */	    if( !( pBd->bd_readyChanged || dev->cbio_readyChanged) )		{		if( pBd->bd_reset != NULL )		    pBd->bd_reset( pBd );		do		    {		    if( blkWrapIoctl( pDev, CBIO_STATUS_CHK, 0) == OK)			goto retry_loop;		    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.  ** dev - the CBIO handle of the device being accessed (from creation routine)* * start_block - the starting block of the transfer operation* * num_blocks - the total number of blocks to transfer* * buffer - address of the memory buffer used for the transfer* * rw - indicates the direction of transfer up or down (READ/WRITE)* * *cookie - pointer to cookie used by upper layer such as dosFsLib(),* it should be preserved.** RETURNS OK or ERROR and may otherwise set errno.*/LOCAL STATUS blkWrapBlkRWbuf    (    CBIO_DEV_ID     dev,    block_t         start_block,    block_t         num_blocks,    addr_t          buffer,    enum cbio_rw    rw,    cookie_t        *cookie    )    {    FAST CBIO_DEV * pDev = dev ;    STATUS stat = OK ;    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;	    }	}    /* see if Tiny Cache contains a valid block */    if( pDev->cbio_blkNo != (u_long) NONE )	{	/* see if the range touches the cached block */	if( (pDev->cbio_blkNo >= start_block) &&	    (pDev->cbio_blkNo < start_block+num_blocks) )	    {	    /* flush the current contents of the block buffer if dirty */	    if( pDev->cbio_dirtyMask != 0 )		{		block_t cachedBlock = pDev->cbio_blkNo ;		pDev->cbio_blkNo = NONE ;		pDev->cbio_dirtyMask = 0;		stat = blkWrapBlkRW(  pDev, cachedBlock, 1,			    pDev->cbio_memBase, CBIO_WRITE, NULL);		}	    else		{		/* else just forget about it */		pDev->cbio_blkNo = NONE ;		}	    }	}    if( stat == ERROR )	return stat;    stat = blkWrapBlkRW (dev, start_block, num_blocks, buffer, rw, cookie) ;    semGive(&pDev->cbio_mutex);    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.  ** dev - the CBIO handle of the device being accessed (from creation routine)* * start_block - the starting block of the transfer operation* * offset - offset in bytes from the beginning of the starting block* * buffer - address of the memory buffer used for the transfer* * nBytes - number of bytes to transfer* * rw - indicates the direction of transfer up or down (READ/WRITE)* * *cookie - pointer to cookie used by upper layer such as dosFsLib(),* it should be preserved.* * RETURNS OK or ERROR and may otherwise set errno.*/LOCAL STATUS blkWrapBytesRW    (    CBIO_DEV_ID 	dev,    block_t		start_block,    off_t		offset,    addr_t		buffer,    size_t		nBytes,    enum cbio_rw	rw,    cookie_t		*cookie    )    {    CBIO_DEV * 	pDev = dev ;    BLK_DEV *	pBd = pDev->pDc ;    STATUS	stat = OK ;    caddr_t 	pStart;    if( pBd->bd_readyChanged || dev->cbio_readyChanged )	{	dev->cbio_readyChanged = TRUE ;	errno = S_ioLib_DISK_NOT_PRESENT ;	return ERROR;	}    if( start_block >= pDev->params.cbio_nBlocks )	{	errno = EINVAL;	return ERROR;	}    /* verify that all bytes are within one block range */    if (((offset + nBytes) > pDev->params.cbio_bytesPerBlk ) ||	(offset <0) || (nBytes <=0))	{	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_blkNo != start_block &&	 pDev->cbio_dirtyMask != 0 )	{	block_t cachedBlock = pDev->cbio_blkNo ;	pDev->cbio_blkNo = NONE ;	pDev->cbio_dirtyMask = 0;	stat = blkWrapBlkRW( pDev, cachedBlock, 1,			    pDev->cbio_memBase, CBIO_WRITE, NULL);	if( stat == ERROR )	    {	    semGive(&pDev->cbio_mutex);	    return ERROR;	    }	}    /* get the requested block into cache */    if( start_block != pDev->cbio_blkNo && pDev->cbio_dirtyMask == 0 )	{	stat = blkWrapBlkRW( pDev, start_block, 1,			    pDev->cbio_memBase, CBIO_READ, NULL);	if( stat == ERROR )	    {	    semGive(&pDev->cbio_mutex);	    return ERROR;	    }	pDev->cbio_blkNo = start_block ;	pDev->cbio_dirtyMask = 0;	}    assert( start_block == pDev->cbio_blkNo );    /* calculate actual memory address of data */    pStart = pDev->cbio_memBase + offset ;#ifdef	DEBUG    if(cbioDebug > 1)	logMsg("blkWrapBytesRW: blk %d + %d # %d bytes -> addr %x, %x bytes\n",	    start_block, 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->cbio_dirtyMask = 1;	    break;	}

⌨️ 快捷键说明

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