📄 cbiolib.c
字号:
size = dev->cbioParams.nBlocks / factor ; units = "Kbytes" ; } else /* if( dev->cbioParams.bytesPerBlk >= 1024 ) */ { factor = dev->cbioParams.bytesPerBlk / 1024 ; size = (dev->cbioParams.nBlocks / 1024) * factor ; units = "Mbytes" ; } if(( size > 10000 ) && (0 == strcmp (units,"Kbytes"))) { units = "Mbytes" ; size /= 1024 ; } if(( size > 10000 ) && (0 == strcmp(units, "Mbytes"))) { units = "Gbytes" ; size /= 1024 ; } printf("\tDisk size %ld %s, RAM Size %d bytes\n", size, units, (int) dev->cbioMemSize ); printf("\tBlock size %d, heads %d, blocks/track %d, # of blocks %ld\n", (int) dev->cbioParams.bytesPerBlk, dev->cbioParams.nHeads, dev->cbioParams.blocksPerTrack, (block_t) dev->cbioParams.nBlocks ); printf("\tpartition offset %ld blocks, type %s, Media changed %s\n", (block_t) dev->cbioParams.blockOffset, (dev->cbioParams.cbioRemovable) ? "Removable" : "Fixed", ((TRUE == CBIO_READYCHANGED(dev)) ? "Yes" : "No" )); if( dev->cbioParams.lastErrno != 0) printf("\tLast error errno=%x, block=%ld\n", dev->cbioParams.lastErrno, dev->cbioParams.lastErrBlk ); printf ("\n Current ready changed bit" " for this layer and all subordinates:\n"); cbioRdyChk (dev); /* TBD: embedded objects */ return (OK); }/********************************************************************************* cbioDevVerify - verify CBIO_DEV_ID ** The purpose of this function is to determine if the device complies with the * CBIO interface. It can be used to verify a CBIO handle before it is passed * to dosFsLib, rawFsLib, usrFdiskPartLib, or other CBIO modules which expect a * valid CBIO interface. ** The device handle provided to this function, <device> is verified to be a * CBIO device. If <device> is not a CBIO device ERROR is returned with errno * set to S_cbioLib_INVALID_CBIO_DEV_ID** The dcacheCbio and dpartCbio CBIO modules (and dosFsLib) use this function * internally, and therefore this function need not be otherwise invoked when * using compliant CBIO modules.** RETURNS: OK or ERROR if not a CBIO device, if passed a NULL address, or * if the check could cause an unaligned access. ** SEE ALSO: dosFsLib, dcacheCbio, dpartCbio*/STATUS cbioDevVerify ( CBIO_DEV_ID device /* CBIO_DEV_ID to be verified */ ) { /* SPR#71720, avoid NULL access */ if (NULL == device) { errno = S_cbioLib_INVALID_CBIO_DEV_ID; return(ERROR); } /* SPR#71720, avoid causing unaligned pointer access. */ if (FALSE == (_WRS_ALIGN_CHECK(device,CBIO_DEV))) { errno = S_cbioLib_INVALID_CBIO_DEV_ID; return(ERROR); }#ifdef _WRS_DOSFS2_VXWORKS_AE /* if the input is a valid CBIO device, return it */ if( OK == HANDLE_VERIFY( &device->cbioHandle, handleTypeCbioHdl )) { return( OK ); }#else if(OK == OBJ_VERIFY( device, cbioClassId ) ) { return (OK); }#endif /* _WRS_DOSFS2_VXWORKS_AE */ else {#ifdef DEBUG logMsg("cbioDevVerify: device 0x%08lx is not a CBIO pointer\n", (long unsigned int)device,0,0,0,0,0);#endif errno = S_cbioLib_INVALID_CBIO_DEV_ID; return (ERROR); } }/********************************************************************************* cbioWrapBlkDev - create CBIO wrapper atop a BLK_DEV device** The purpose of this function is to make a blkIo (BLK_DEV) device comply * with the CBIO interface via a wrapper. ** The device handle provided to this function, <device> is verified to * be a blkIo device. A lean CBIO to BLK_DEV wrapper is then created for * a valid blkIo device. The returned CBIO_DEV_ID device handle may be * used with dosFsDevCreate(), dcacheDevCreate(), and any other routine * expecting a valid CBIO_DEV_ID handle.** To verify a blkIo pointer we see that all mandatory functions* are not NULL.** Note that if a valid CBIO_DEV_ID is passed to this function, it will * simply be returned without modification.** The dosFsLib, dcacheCbio, and dpartCbio CBIO modules use this function * internally, and therefore this function need not be otherwise invoked * when using those CBIO modules.** RETURNS: a CBIO device pointer, or NULL if not a blkIo device** SEE ALSO: dosFsLib, dcacheCbio, dpartCbio**/CBIO_DEV_ID cbioWrapBlkDev ( BLK_DEV * pDevice /* BLK_DEV * device pointer */ ) { CBIO_DEV * pDev = NULL ; BLK_DEV * pBd = pDevice ; u_char shift ; cbioLibInit(); /* just in case */ if (NULL == pDevice) { goto bad_blkIo ; } /* simply return any valid CBIO_DEV_ID as is */ if (OK == cbioDevVerify((CBIO_DEV_ID)pDevice)) { return ((CBIO_DEV_ID) pDevice); } /* blkIo has no clear mechanism for verification, improvise (HELP)*/ if( (pBd->bd_blkRd == NULL) || (pBd->bd_blkWrt == NULL) || (pBd->bd_ioctl == NULL) ) goto bad_blkIo ; shift = shiftCalc( pBd->bd_bytesPerBlk ); /* we place a dummy function if statusChk is not provided */ if( pBd->bd_statusChk == NULL ) pBd->bd_statusChk = cbioWrapOk ; /* create our CBIO handle, no cache memory (yet) */ pDev = (CBIO_DEV_ID) cbioDevCreate ( NULL, 0 ); if( pDev == NULL ) return( NULL ); pDev->pDc = pBd ; pDev->cbioDesc = "CBIO to BLK_DEV Wrapper" ; pDev->cbioParams.cbioRemovable = pBd->bd_removable ; pDev->readyChanged = pBd->bd_readyChanged ; pDev->cbioParams.nBlocks = pBd->bd_nBlocks ; pDev->cbioParams.bytesPerBlk = pBd->bd_bytesPerBlk ; pDev->cbioParams.blocksPerTrack = pBd->bd_blksPerTrack ; pDev->cbioParams.nHeads = pBd->bd_nHeads ; pDev->cbioParams.blockOffset = 0; pDev->cbioMode = pBd->bd_mode ; pDev->cbioParams.lastErrBlk = NONE ; pDev->cbioParams.lastErrno = 0 ; pDev->cbioBlkNo = NONE; pDev->cbioDirtyMask = 0; pDev->cbioBlkShift = shift ; pDev->pFuncs = &cbioFuncs; /* SPR#67729: Fill in the members subDev and isDriver appropriately */ pDev->blkSubDev = pBd; /* Pointer to lower BlkDev */ pDev->cbioSubDev = NULL; /* Pointer to lower BlkDev */ pDev->isDriver = TRUE;/* ==TRUE since this is a */ /* CBIO to BLKDEV layer */ return (pDev) ;bad_blkIo: logMsg("cbioWrapBlkDev: BLK_DEV pointer 0x%08lx appears invalid.\n", (unsigned long) pDevice,0,0,0,0,0); return (NULL) ; }/********************************************************************************* cbioDevCreate - Initialize a CBIO device (Generic)** This routine will create an empty CBIO_DEV structure and* return a handle to that structure (CBIO_DEV_ID). * * This routine is intended to be used by CBIO modules only.* See cbioLibP.h** RETURNS CBIO_DEV_ID or NULL if ERROR.*/CBIO_DEV_ID cbioDevCreate ( caddr_t ramAddr, /* where it is in memory (0 = KHEAP_ALLOC) */ 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 = KHEAP_ALLOC(ramSize); else pBase = ramAddr ; if( pBase == NULL ) goto error ; } /* allocate and initialize the device control structure */#ifdef _WRS_DOSFS2_VXWORKS_AE pDev = (CBIO_DEV *) KHEAP_ALLOC((sizeof (CBIO_DEV)));#else pDev = (CBIO_DEV *) objAlloc(cbioClassId);#endif /* _WRS_DOSFS2_VXWORKS_AE */ if( pDev == NULL ) goto error; /* init Common fields */ pDev->cbioMutex = semMCreate (cbioMutexSemOptions); if( NULL == pDev->cbioMutex ) { goto error ; } pDev->readyChanged = FALSE ; pDev->cbioParams.lastErrBlk = NONE ; pDev->cbioParams.lastErrno = 0 ; pDev->cbioMemBase = pBase ; pDev->cbioMemSize = ramSize ; /* pointer to method functions needs to be filled later */ pDev->pFuncs = NULL ; /* init the handle */#ifdef _WRS_DOSFS2_VXWORKS_AE handleInit (&pDev->cbioHandle, handleTypeCbioHdl);#else /* make this object belong to its class */ objCoreInit (&pDev->objCore, cbioClassId);#endif /* _WRS_DOSFS2_VXWORKS_AE */ cbioRecentDev = pDev ; /* return device handle */ return( (CBIO_DEV_ID) pDev );error: if( pBase != NULL ) KHEAP_FREE(pBase); if( pDev != NULL ) KHEAP_FREE((char *)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 ) { int 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; }/********************************************************************************* cbioBlkWrapBufCreate - create the local block buffer**/LOCAL STATUS cbioBlkWrapBufCreate ( CBIO_DEV_ID pDev ) { if( pDev->cbioMemBase != NULL && pDev->cbioMemSize != pDev->cbioParams.bytesPerBlk ) { /* block size may have changed */ KHEAP_FREE(pDev->cbioMemBase); pDev->cbioMemBase = 0; pDev->cbioMemSize = 0; } if( pDev->cbioMemBase == NULL && pDev->cbioMemSize == 0 ) { pDev->cbioMemSize = pDev->cbioParams.bytesPerBlk ; pDev->cbioMemBase = KHEAP_ALLOC(pDev->cbioMemSize); if( pDev->cbioMemBase == NULL ) { return ERROR; } /* Overload the block I/O function, better own the mutex here */ pDev->pFuncs->cbioDevBlkRW = blkWrapBlkRWbuf ; /* empty block */ pDev->cbioBlkNo = (u_long)NONE ; pDev->cbioDirtyMask = 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. ** RETURNS OK or ERROR and may otherwise set errno.*/LOCAL STATUS blkWrapBlkRW ( CBIO_DEV_ID dev, block_t startBlock, block_t numBlocks, addr_t buffer, CBIO_RW rw, cookie_t * pCookie ) { CBIO_DEV * pDev = (void *) dev ; BLK_DEV * pBd = pDev->blkSubDev ; STATUS stat = ERROR; int retryCount = 0 ;retryLoop: if (TRUE == pBd->bd_readyChanged || TRUE == CBIO_READYCHANGED(dev)) { errno = S_ioLib_DISK_NOT_PRESENT ; return (ERROR); } if( startBlock > pDev->cbioParams.nBlocks || (startBlock+numBlocks) > pDev->cbioParams.nBlocks ) { errno = EINVAL; return (ERROR); } switch( rw ) { case CBIO_READ: stat = pBd->bd_blkRd( pBd, startBlock, numBlocks, buffer); break; case CBIO_WRITE: stat = pBd->bd_blkWrt( pBd, startBlock, numBlocks, buffer); break; default: errno = S_ioLib_UNKNOWN_REQUEST; return (ERROR); } /* record error if any */ if( stat == ERROR ) { pDev->cbioParams.lastErrBlk = startBlock; pDev->cbioParams.lastErrno = errno ; if( errno == S_ioLib_DISK_NOT_PRESENT ) { CBIO_READYCHANGED (dev) = TRUE; } /* some block drivers dont do retires relying on dosFs1 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 || CBIO_READYCHANGED(dev)) ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -