📄 cbiolib.c
字号:
* ERROR will be returned with errno set to S_objLib_OBJ_ID_ERROR** RETURNS OK if sucessful or ERROR if the handle is invalid, or if the* CBIO device routine returns ERROR.*/STATUS cbioIoctl /* Misc control operations */ ( CBIO_DEV_ID dev, int command, addr_t arg ) { if( OBJ_VERIFY( dev, cbioClassId ) != OK) { errno = S_objLib_OBJ_ID_ERROR; return ERROR; } return (dev->pFuncs->cbio_ioctl(dev, command, arg)); }/********************************************************************************* cbioModeGet - return the mode setting for CBIO device** If the CBIO_DEV_ID passed to this routine is not a valid CBIO handle,* ERROR will be returned with errno set to S_objLib_OBJ_ID_ERROR* This routine is not protected by a semaphore.** RETURNS O_RDONLY, O_WRONLY, or O_RDWR or ERROR **/short cbioModeGet ( CBIO_DEV_ID dev ) { if( OBJ_VERIFY( dev, cbioClassId ) != OK) { errno = S_objLib_OBJ_ID_ERROR; return ERROR; } return (CBIO_MODE(dev)); }/********************************************************************************* cbioModeSet - set mode for CBIO device* * Valid modes are O_RDONLY, O_WRONLY, or O_RDWR.** If the CBIO_DEV_ID passed to this routine is not a valid CBIO handle,* ERROR will be returned with errno set to S_objLib_OBJ_ID_ERROR* This routine is not protected by a semaphore.** RETURNS OK or ERROR if mode is not set.**/STATUS cbioModeSet ( CBIO_DEV_ID dev, short mode ) { if( OBJ_VERIFY( dev, cbioClassId ) != OK) { errno = S_objLib_OBJ_ID_ERROR; return ERROR; } CBIO_MODE(dev) = mode; if (CBIO_MODE(dev) == mode) return (OK); else return (ERROR); }/********************************************************************************* cbioRdyChgdGet - determine ready status of CBIO device** For example * .CS* switch (cbioRdyChgdGet (cbioDeviceId)) * {* case TRUE:* printf ("Disk changed.\n");* break;* case FALSE:* printf ("Disk has not changed.\n");* break;* case ERROR:* printf ("Not a valid CBIO device.\n");* break;* default:* break;* }* .CE** If the CBIO_DEV_ID passed to this routine is not a valid CBIO handle,* ERROR will be returned with errno set to S_objLib_OBJ_ID_ERROR* This routine is not protected by a semaphore.** RETURNS TRUE if device ready status has changed, else FALSE if * the ready status has not changed, else ERROR if the CBIO_DEV_ID is invalid.**/int cbioRdyChgdGet ( CBIO_DEV_ID dev ) { if( OBJ_VERIFY( dev, cbioClassId ) != OK) { errno = S_objLib_OBJ_ID_ERROR; return ERROR; } return (CBIO_READYCHANGED(dev)); }/********************************************************************************* cbioRdyChgdSet - force a change in ready status of CBIO device** Pass TRUE in status to force READY status change.** If the CBIO_DEV_ID passed to this routine is not a valid CBIO handle,* ERROR will be returned with errno set to S_objLib_OBJ_ID_ERROR* This routine is not protected by a semaphore.** RETURNS OK or ERROR if the device is invalid or if the CBIO * device did not honor the esetting**/STATUS cbioRdyChgdSet ( CBIO_DEV_ID dev, BOOL status ) { if( OBJ_VERIFY( dev, cbioClassId ) != OK) { errno = S_objLib_OBJ_ID_ERROR; return ERROR; } CBIO_READYCHANGED(dev) = status; if (CBIO_READYCHANGED(dev) == status) return (OK); else return (ERROR); }/********************************************************************************* cbioLock - obtain CBIO device semaphore.** If the CBIO_DEV_ID passed to this routine is not a valid CBIO handle,* ERROR will be returned with errno set to S_objLib_OBJ_ID_ERROR** RETURNS: OK or ERROR if*/STATUS cbioLock ( CBIO_DEV_ID dev, int timeout ) { if( OBJ_VERIFY( dev, cbioClassId ) != OK) { errno = S_objLib_OBJ_ID_ERROR; return ERROR; } return (semTake(&dev->cbio_mutex, timeout)); } /********************************************************************************* cbioUnlock - release CBIO device semaphore.** If the CBIO_DEV_ID passed to this routine is not a valid CBIO handle,* ERROR will be returned with errno set to S_objLib_OBJ_ID_ERROR** RETURNS: OK or ERROR if*/STATUS cbioUnlock ( CBIO_DEV_ID dev ) { if( OBJ_VERIFY( dev, cbioClassId ) != OK) { errno = S_objLib_OBJ_ID_ERROR; return ERROR; } return (semGive(&dev->cbio_mutex)); }/********************************************************************************* cbioParamsGet - fill in CBIO_PARAMS structure with CBIO device parameters** If the CBIO_DEV_ID passed to this routine is not a valid CBIO handle,* ERROR will be returned with errno set to S_objLib_OBJ_ID_ERROR** RETURNS: OK or ERROR if*/STATUS cbioParamsGet ( CBIO_DEV_ID dev, CBIO_PARAMS * params ) { if( OBJ_VERIFY( dev, cbioClassId ) != OK) { errno = S_objLib_OBJ_ID_ERROR; return ERROR; } *params = dev->params; return (OK); }/********************************************************************************* cbioShow - print information about a CBIO device** This function will display on standard output all information which* is generic for all CBIO devices.* See the CBIO modules particular device show routines for displaying* implementation-specific information.** It takes two arguments:** A CBIO_DEV_ID which is the CBIO handle to display or NULL for * the most recent device.** RETURNS OK or ERROR if no valid CBIO_DEV is found.** SEE ALSO: dcacheShow(), dpartShow()**/STATUS cbioShow ( CBIO_DEV_ID dev ) { unsigned long size, factor = 1 ; char * units ; if( dev == NULL ) dev = cbioRecentDev; if( dev == NULL ) { errno = S_objLib_OBJ_ID_ERROR; return ERROR; } if( OBJ_VERIFY( dev, cbioClassId ) != OK) { errno = S_objLib_OBJ_ID_ERROR; return ERROR; } if( dev->params.cbio_bytesPerBlk == 0 ) { errno = EINVAL; return ERROR; } printf("Cached Block I/O Device, handle=%#lx\n", (u_long)dev); printf("\tDescription: %s\n", dev->cbio_description); /* calculate disk size, while avoiding 64-bit arithmetic */ if( dev->params.cbio_bytesPerBlk < 1024 ) { factor = 1024 / dev->params.cbio_bytesPerBlk ; size = dev->params.cbio_nBlocks / factor ; units = "Kbytes" ; } else /* if( dev->params.cbio_bytesPerBlk >= 1024 ) */ { factor = dev->params.cbio_bytesPerBlk / 1024 ; size = (dev->params.cbio_nBlocks / 1024) * factor ; units = "Mbytes" ; } if(( size > 10000 ) && ( units == "Kbytes")) { units = "Mbytes" ; size /= 1024 ; } if(( size > 10000 ) && ( units == "Mbytes")) { units = "Gbytes" ; size /= 1024 ; } printf("\tDisk size %ld %s, RAM Size %d bytes\n", size, units, dev->cbio_memSize ); printf("\tBlock size %d, heads %d, blocks/track %d, # of blocks %ld\n", dev->params.cbio_bytesPerBlk, dev->params.cbio_nHeads, dev->params.cbio_blksPerTrack, dev->params.cbio_nBlocks ); printf("\tpartition offset %d blocks, type %s, Media changed %s\n", dev->params.cbio_offset, (dev->params.cbio_removable) ? "Removable" : "Fixed", (dev->cbio_readyChanged) ? "Yes" : "No" ); if( dev->params.cbio_lastErrno != 0) printf("\tLast error errno=%x, block=%ld\n", dev->params.cbio_lastErrno, dev->params.cbio_lastErrBlk ); /* TBD: embedded objects */ return OK; }/********************************************************************************* cbioDevVerify - verify CBIO object or create CBIO wrapper for BLK_DEV device** The purpose of this function is to assure that 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 and the <noWrapper> boolean* is FALSE, then it is assumed to be a BLK_DEV style device and a basic CBIO * to BLK_DEV wrapper is created for the blkIo device. The returned device * pointer may be used subsequently for dosFsDevCreate(), dcacheDevCreate(), * and any other routines expecting a valid CBIO_DEV_ID handle.** If the boolean <noWrapper> is TRUE then the BASIC BLK_DEV wrapper will not * be created. The CBIO device will be verified, if it is not a CBIO device, * NULL is returned else the CBIO_DEV_ID handle is returned.** The 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 CBIO nor a blkIo device** SEE ALSO: dosFsLib, dcacheCbio, dpartCbio** INTERNAL* To verify a blkIo pointer we see that all mandatory functions* are not NULL, and that the distance between the function pointers* is less then 1/2 Mbytes, assuming there can not be a block driver* larger then 512 Kbytes. This size limit is adjustable by resetting* the global variable cbioBlkDevPtrLimit before cbioDevVerify is used.*/CBIO_DEV_ID cbioDevVerify ( void * device, /* CBIO_DEV_ID or BLK_DEV * device pointer */ BOOL noWrapper /* TRUE == skip creation of block dev wrapper */ ) { CBIO_DEV * pDev = NULL ; CBIO_DEV_ID dev = device ; BLK_DEV * pBd = device ; long tmp, limit = cbioBlkDevPtrLimit; /* func ptr distance for blkdev */ u_char shift ; cbioLibInit(); /* just in case */ /* if the input is a valid CBIO device, return it */ if( OBJ_VERIFY( dev, cbioClassId ) == OK) return( dev ); else if (TRUE == noWrapper) return (NULL); /* blkIo has no clear mechanism for verification, improvise something */ if( (pBd->bd_blkRd == NULL) || (pBd->bd_blkWrt == NULL) || (pBd->bd_ioctl == NULL) ) goto bad_blkIo ; tmp = (long) pBd->bd_blkRd ; if( abs((long)pBd->bd_blkWrt - tmp) > limit || abs((long)pBd->bd_ioctl - tmp) > limit ) goto bad_blkIo ; if( (pBd->bd_statusChk != NULL ) && abs((long)pBd->bd_statusChk - tmp) > limit ) goto bad_blkIo ; /* check that bytesPerBlk is 2^n */ shift = shiftCalc( pBd->bd_bytesPerBlk ); if( pBd->bd_bytesPerBlk != (ULONG)( 1 << shift ) ) goto bad_blkIo ; /* we place a dummy function if statusChk is not provided */ if( pBd->bd_statusChk == NULL ) pBd->bd_statusChk = cbioWrapOk ; /* create the CBIO handle, no cache memory (yet) */ if( cbioClassId->createRtn != NULL ) pDev = (CBIO_DEV_ID) cbioClassId->createRtn( NULL, 0 ); if( pDev == NULL ) return( NULL ); pDev->pDc = pBd ; pDev->cbio_description = "Block Device" ; pDev->params.cbio_removable = pBd->bd_removable ; pDev->cbio_readyChanged = FALSE ; 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 ; pDev->params.cbio_lastErrBlk = NONE ; pDev->params.cbio_lastErrno = 0 ; pDev->cbio_blkNo = NONE; pDev->cbio_dirtyMask = 0; pDev->cbio_blkShift = shift ; pDev->pFuncs = &cbioFuncs; return pDev ;bad_blkIo: INFO_MSG("cbioDevVerify: device %#x is neither CBIO nor blkIo pointer\n", 0,0,0,0,0,0); errno = S_objLib_OBJ_ID_ERROR; return NULL ; }/********************************************************************************* cbioDevCreate - Initialize a CBIO device (Generic)** This routine will create a 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.*/LOCAL CBIO_DEV_ID cbioDevCreate (
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -