📄 dpartcbio.c
字号:
* * 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 dpartBlkCopy ( CBIO_DEV_ID dev, block_t src_block, block_t dst_block, block_t num_blocks ) { CBIO_DEV *pDev = (void *) dev ; STATUS retStat ; if( dev->cbio_readyChanged ) { errno = S_ioLib_DISK_NOT_PRESENT ; return ERROR; } if( (src_block) > pDev->params.cbio_nBlocks || (dst_block) > pDev->params.cbio_nBlocks ) return ERROR; if( (src_block+num_blocks) > pDev->params.cbio_nBlocks || (dst_block+num_blocks) > pDev->params.cbio_nBlocks ) return ERROR; src_block += pDev->params.cbio_offset; dst_block += pDev->params.cbio_offset; if( semTake( &pDev->cbio_mutex, WAIT_FOREVER) == ERROR ) return ERROR; retStat = pDev->pDc->subDev->pFuncs->cbio_blkCopy( pDev->pDc->subDev, src_block, dst_block, num_blocks ); if( retStat == ERROR ) if( dev->pDc->subDev->cbio_readyChanged ) dev->cbio_readyChanged = TRUE ; semGive( &pDev->cbio_mutex ); return ( retStat); }/********************************************************************************* dpartIoctl - Misc control operations ** This performs the requested ioctl() operation.* * CBIO modules can expect the following ioctl() codes from cbioLib.h:* CBIO_RESET - reset the CBIO device and the lower layer* CBIO_STATUS_CHK - check device status of CBIO device and lower layer* CBIO_DEVICE_LOCK - Prevent disk removal * CBIO_DEVICE_UNLOCK - Allow disk removal* CBIO_DEVICE_EJECT - Unmount and eject device* CBIO_CACHE_FLUSH - Flush any dirty cached data* CBIO_CACHE_INVAL - Flush & Invalidate all cached data* CBIO_CACHE_NEWBLK - Allocate scratch block** dev - the CBIO handle of the device being accessed (from creation routine)* * command - ioctl() command being issued* * arg - specific to the particular ioctl() function requested or un-used.** RETURNS OK or ERROR and may otherwise set errno.*/LOCAL STATUS dpartIoctl ( CBIO_DEV_ID dev, int command, addr_t arg ) { STATUS retStat = ERROR ; if( OBJ_VERIFY( dev, cbioClassId ) != OK) { INFO_MSG("dpartIoctl: invalid handle\n"); errno = S_objLib_OBJ_ID_ERROR; return ERROR; } if( semTake( &dev->cbio_mutex, WAIT_FOREVER) == ERROR ) return ERROR; switch ( command ) { case CBIO_RESET : /* * if this is the first partition to issue RESET * we need to RESET the lower level device too, * otherwise, RESET only this partition. */ if((dev->pDc->subDev->cbio_readyChanged ) || (dev->pDc->masterDev->cbio_readyChanged )) { DEBUG_MSG("dpartCbio: resetting subordinate\n"); retStat = dev->pDc->subDev->pFuncs->cbio_ioctl( dev->pDc->subDev, command, arg ); /* and also fill the partitions geometry now */ if( retStat == OK ) { retStat = dpartPartTableFill( dev->pDc ); } if( retStat == OK ) { dev->pDc->masterDev->cbio_readyChanged = FALSE ; } } else { /* * if masterDev does not have readyChanged * there is no need to reset subDev, its been * already reset */ retStat = OK; } /* non-existent partitions will remain "removed" */ if (retStat == OK && dev->params.cbio_nBlocks == 0) { errno = S_ioLib_DISK_NOT_PRESENT ; retStat = ERROR ; } if( retStat == OK ) dev->cbio_readyChanged = FALSE ; break; /* NEWBLK is the only ioctl where block# is coded in arg */ case CBIO_CACHE_NEWBLK: arg += dev->params.cbio_offset ; /*FALLTHROUGH*/ /* all other commands should be executed by the lower layer */ case CBIO_STATUS_CHK : case CBIO_DEVICE_LOCK : case CBIO_DEVICE_UNLOCK : case CBIO_DEVICE_EJECT : /* check if master has readyChanged */ if((dev->pDc->subDev->cbio_readyChanged ) || (dev->pDc->masterDev->cbio_readyChanged )) { dev->cbio_readyChanged = TRUE ; } /*FALLTHROUGH*/ case CBIO_CACHE_FLUSH : case CBIO_CACHE_INVAL : default: if( dev->cbio_readyChanged ) { errno = S_ioLib_DISK_NOT_PRESENT ; retStat = ERROR ; } else { if( command == (int)CBIO_DEVICE_LOCK ) semTake( &dev->pDc->subDev->cbio_mutex, WAIT_FOREVER) ; retStat = dev->pDc->subDev->pFuncs->cbio_ioctl( dev->pDc->subDev, command, arg ); if( command == (int)CBIO_DEVICE_UNLOCK ) semGive( &dev->pDc->subDev->cbio_mutex) ; } } /* end of switch */ if( retStat == ERROR ) if( dev->pDc->subDev->cbio_readyChanged ) dev->cbio_readyChanged = TRUE ; semGive( &dev->cbio_mutex ); return( retStat ); }/********************************************************************************* dpartDevCreate - Initialize a partitioned disk** To handle a partitioned disk, this function should be called,* with <subDev> as the handle returned from dcacheDevCreate(),* It is recommended that for efficient operation a single disk cache* be allocated for the entire disk and shared by its partitions.** <nPart> is the maximum number of partitions which are expected* for the particular disk drive. Up to 24 (C-Z) partitions per disk * are supported.** PARTITION DECODE FUNCTION* An external partition table decode function is provided via the* <pPartDecodeFunc> argument, which implements a particular style and* format of partition tables, and fill in the results into a table* defined as Pn array of PART_TABLE_ENTRY types. See dpartCbio.h* for definition of PART_TABLE_ENTRY.* The prototype for this function is as follows:* * .CS* STATUS parDecodeFunc* (* CBIO_DEV_ID dev, /@ device from which to read blocks @/* PART_TABLE_ENTRY *pPartTab, /@ table where to fill results @/* int nPart /@ # of entries in <pPartTable> @/* )* .CE** RETURNS: CBIO_DEV_ID or NULL if error creating CBIO device.* * SEE ALSO: dosFsDevCreate().* INTERNAL* during create, read-changed is TRUE so no accesses are allowed* until after a RESET, at which time actual partition table* will be brought in and applied.*/CBIO_DEV_ID dpartDevCreate ( CBIO_DEV_ID subDev, /* lower level CBIO device */ int nPart, /* # of partitions */ FUNCPTR pPartDecodeFunc /* function to decode partition table */ ) { CBIO_DEV * pDev = NULL ; DPART_CTRL * pDc ; int p ; if( nPart > PART_MAX_ENTRIES || pPartDecodeFunc == NULL ) { printErr ("%d is too many partitions, max limit %d\n", nPart, PART_MAX_ENTRIES); errno = EINVAL; return NULL; } cbioLibInit(); /* just in case */ subDev = cbioDevVerify (subDev, FALSE); if( subDev == NULL || (OBJ_VERIFY( subDev, cbioClassId ) != OK)) { DEBUG_MSG("dpartDevCreate: invalid handle\n"); errno = S_objLib_OBJ_ID_ERROR; return NULL; } pDc = malloc( sizeof(DPART_CTRL)) ; if( pDc == NULL ) return( NULL ); if( cbioClassId->createRtn != NULL ) pDev = (CBIO_DEV_ID) cbioClassId->createRtn( NULL, 0 ); if( pDev == NULL ) return( NULL ); /* the prime CBIO handle is not for any actual I/O, just for show */ pDev->cbio_description = "Partition Manager, Handle Pseudo Device" ; pDev->cbio_readyChanged = TRUE ; pDev->params.cbio_removable = subDev->params.cbio_removable ; pDev->params.cbio_nBlocks = subDev->params.cbio_nBlocks ; pDev->params.cbio_bytesPerBlk = subDev->params.cbio_bytesPerBlk ; pDev->params.cbio_blksPerTrack = subDev->params.cbio_blksPerTrack ; pDev->params.cbio_nHeads = subDev->params.cbio_nHeads ; pDev->cbio_mode = subDev->cbio_mode ; pDev->params.cbio_offset = 0 ; pDev->params.cbio_lastErrBlk = NONE ; pDev->params.cbio_lastErrno = 0 ; pDev->cbio_partIndex = NONE ; /* master */ /* point to actual device main block */ pDev->pDc = pDc ; /* cbioFuncs is staticly allocated in each driver. */ pDev->pFuncs = &cbioFuncs; bzero( (char *) pDc, sizeof( DPART_CTRL) ); pDc->subDev = subDev ; pDc->pPartDecodeFunc = pPartDecodeFunc ; pDc->nPart = nPart ; pDc->masterDev = pDev ; /* Now initialize the partition virtual devs */ for(p = 0; p < PART_MAX_ENTRIES; p++ ) { CBIO_DEV * vDev = & ( pDc->vDev[ p ] ); /* inherit most fields from the primary handle */ *vDev = *pDev ; vDev->cbio_description = "Partition Pseudo Device"; vDev->cbio_partIndex = p ; /* partition # */ vDev->cbio_readyChanged = TRUE ; /* semaphore can be just copied, it has to be init'ed */ semMInit( &vDev->cbio_mutex, SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE ); /* these will be filled later from actual geometry */ vDev->params.cbio_nBlocks = 0 ; vDev->params.cbio_offset = 0 ; } DEBUG_MSG("dpartDevCreate: handle dev %x subDev %x\n", pDev, subDev ); /* return device handle */ return( pDev ); }/********************************************************************************* dpartPartGet - retrieve handle for a partition** This function retrieves a CBIO handle into a particular partition* of a partitioned device. This handle is intended to be used with* dosFsDevCreate().** RETURNS: CBIO_DEV_ID or NULL if partition is out of range, or* <masterHandle> is invalid.** SEE ALSO: dosFsDevCreate()*/CBIO_DEV_ID dpartPartGet ( CBIO_DEV_ID masterHandle, /* CBIO handle of the master partition */ int partNum /* partition number from 0 to nPart */ ) { if( OBJ_VERIFY( masterHandle, cbioClassId ) != OK) { errno = S_objLib_OBJ_ID_ERROR; return NULL; } if( partNum >= masterHandle->pDc->nPart ) { errno = EINVAL; return NULL; } return ( & masterHandle->pDc->vDev[ partNum ] ); }/********************************************************************************* dpartShow - show current parameters of the RAM disk device** NOMANUAL*/STATUS dpartShow( CBIO_DEV_ID dev, int verb ) { DPART_CTRL * pDc ; int pn ; if( (OBJ_VERIFY( dev, cbioClassId ) != OK)) { DEBUG_MSG("dpartShow: invalid handle\n"); errno = S_objLib_OBJ_ID_ERROR; return ERROR; } pDc = dev->pDc ; if( dev->cbio_readyChanged ) dev->pFuncs->cbio_ioctl( dev, CBIO_RESET, 0); if( dev->cbio_partIndex == (u_long)NONE ) printf(" Device %#lx is Master handle, Partition Table:\n", (u_long) dev); else printf(" Device %#lx is partition %ld, Partition Table:\n", (u_long) dev, dev->cbio_partIndex ); for( pn = 0; pn < pDc->nPart ; pn ++ ) { printf(" #%ld: from %d to %ld (%ld blocks)\n", pDc->vDev[ pn ].cbio_partIndex, pDc->vDev[ pn ].params.cbio_offset, pDc->vDev[ pn ].params.cbio_nBlocks + pDc->vDev[ pn ].params.cbio_offset, pDc->vDev[ pn ].params.cbio_nBlocks ); } printf(" master dev %#lx, subordinate dev %#lx, with total %ld blocks\n", (u_long) pDc->masterDev, (u_long) pDc->subDev, pDc->subDev->params.cbio_nBlocks ); return OK; }/* End of File */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -