ramDiskCbio.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:14k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* ramDiskCbio.c - RAM Disk Cached Block Driver */
  2. /* Copyright 1998-2002 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01j,12dec01,jkf  fixing diab build warnings
  7. 01i,09dec01,jkf  SPR#71637, fix for SPR#68387 caused ready changed bugs.
  8. 01h,30jul01,jkf  SPR#69031, common code for both AE & 5.x.
  9. 01g,14jun01,jyo  SPR#67729: Updating blkSubDev, cbioSubDev, isDriver in
  10.                  ramDiskDevCreate().
  11. 01f,19apr00,dat  doc fixes
  12. 01e,29feb00,jkf  T3 changes
  13. 01d,31aug99,jkf  CBIO API changes
  14. 01c,31jul99,jkf  T2 merge, tidiness & spelling.
  15. 01b,07jun98,lrn  re-integration, doc
  16. 01a,15jan98,lrn  written, preliminary
  17. */
  18. /*
  19. DESCRIPTION
  20. This module implements a RAM-disk driver with a CBIO interface
  21. which can be directly utilized by dosFsLib without the use of 
  22. the Disk Cache module dcacheCbio.  This results in an
  23. ultra-compact RAM footprint.  This module is implemented 
  24. using the CBIO API (see cbioLib())
  25. This module is delivered in source as a functional example of 
  26. a basic CBIO module.
  27. CAVEAT
  28. This module may be used for SRAM or other non-volatile RAM cards to 
  29. store a file system, but that configuration will be susceptible
  30. to data corruption in events of system failure which are not normally
  31. observed with magnetic disks, i.e. using this driver with an SRAM card
  32. can not guard against interruptions in midst of updating a particular
  33. sector, resulting in that sector become internally inconsistent.
  34. SEE ALSO
  35. dosFsLib, cbioLib
  36. */
  37. /* includes */
  38. #include "vxWorks.h"
  39. #include "stdlib.h"
  40. #include "semLib.h"
  41. #include "ioLib.h"
  42. #include "string.h"
  43. #include "errno.h"
  44. #include "assert.h"
  45. #include "private/dosFsVerP.h"
  46. #include "private/cbioLibP.h" /* only CBIO modules may include this file */
  47. #include "ramDiskCbio.h"
  48. /* Implementation dependent fields */
  49. #define cbioBlkShift cbioPriv0
  50. extern void logMsg( const char *fmt, ... );
  51. LOCAL STATUS ramDiskBlkRW
  52.     (
  53.     CBIO_DEV_ID dev,
  54.     block_t startBlock,
  55.     block_t numBlocks,
  56.     addr_t buffer,
  57.     CBIO_RW rw,
  58.     cookie_t *pCookie
  59.     );
  60. LOCAL STATUS ramDiskBytesRW
  61.     (
  62.     CBIO_DEV_ID  dev,
  63.     block_t startBlock,
  64.     off_t offset,
  65.     addr_t buffer,
  66.     size_t nBytes,
  67.     CBIO_RW rw,
  68.     cookie_t *pCookie
  69.     );
  70. LOCAL STATUS ramDiskBlkCopy
  71.     (
  72.     CBIO_DEV_ID  dev,
  73.     block_t srcBlock,
  74.     block_t dstBlock,
  75.     block_t numBlocks
  76.     );
  77. LOCAL STATUS ramDiskIoctl
  78.     (
  79.     CBIO_DEV_ID dev,
  80.     UINT32 command,
  81.     addr_t arg
  82.     );
  83. /* CBIO_FUNCS, one per cbio driver */
  84. LOCAL CBIO_FUNCS cbioFuncs = {(FUNCPTR) ramDiskBlkRW,
  85.       (FUNCPTR) ramDiskBytesRW,
  86.       (FUNCPTR) ramDiskBlkCopy,
  87.       (FUNCPTR) ramDiskIoctl};
  88. int ramDiskDebug = 0;
  89. #define INFO_MSG logMsg
  90. #define DEBUG_MSG if(ramDiskDebug) logMsg
  91. /*******************************************************************************
  92. *
  93. * ramDiskBlkRW - Read/Write blocks
  94. * This routine transfers between a user buffer and the lower layer hardware
  95. * It is optimized for block transfers.  
  96. *
  97. * dev - the CBIO handle of the device being accessed (from creation routine)
  98. * startBlock - the starting block of the transfer operation
  99. * numBlocks - the total number of blocks to transfer
  100. * buffer - address of the memory buffer used for the transfer
  101. * rw - indicates the direction of transfer up or down (READ/WRITE)
  102. * *pCookie - pointer to cookie used by upper layer such as dosFsLib(),
  103. * it should be preserved.
  104. *
  105. * RETURNS OK or ERROR and may otherwise set errno.
  106. *
  107. */
  108. LOCAL STATUS ramDiskBlkRW
  109.     (
  110.     CBIO_DEV_ID dev,
  111.     block_t startBlock,
  112.     block_t numBlocks,
  113.     addr_t buffer,
  114.     CBIO_RW rw,
  115.     cookie_t *pCookie
  116.     )
  117.     {
  118.     CBIO_DEV * pDev = (void *) dev ;
  119.     caddr_t  pStart;
  120.     size_t  nBytes ;
  121.     if( TRUE == CBIO_READYCHANGED (dev) )
  122. {
  123. errno = S_ioLib_DISK_NOT_PRESENT ;
  124. return ERROR;
  125. }
  126.     if( (startBlock) > pDev->cbioParams.nBlocks ||
  127.      (startBlock+numBlocks) > pDev->cbioParams.nBlocks )
  128. return ERROR;
  129.     startBlock += pDev->cbioParams.blockOffset;
  130.     pStart = pDev->cbioMemBase + ( startBlock << pDev->cbioBlkShift ) ;
  131.     nBytes = numBlocks << pDev->cbioBlkShift ;
  132.     DEBUG_MSG("ramDiskBlkRW: blk %d # %d -> addr %x, %x bytesn",
  133. startBlock, numBlocks, pStart, nBytes );
  134.     if( semTake( pDev->cbioMutex, WAIT_FOREVER) == ERROR )
  135. return ERROR;
  136.     switch( rw )
  137. {
  138. case CBIO_READ:
  139.     bcopy( pStart, buffer, nBytes );
  140.     break;
  141. case CBIO_WRITE:
  142.     bcopy( buffer, pStart,  nBytes );
  143.     break;
  144. }
  145.     semGive(pDev->cbioMutex);
  146.     return OK;
  147.     }
  148. /*******************************************************************************
  149. *
  150. * ramDiskBytesRW - Read/Write bytes
  151. *
  152. * This routine transfers between a user buffer and the lower layer hardware
  153. * It is optimized for byte transfers.  
  154. *
  155. * dev - the CBIO handle of the device being accessed (from creation routine)
  156. * startBlock - the starting block of the transfer operation
  157. * offset - offset in bytes from the beginning of the starting block
  158. * buffer - address of the memory buffer used for the transfer
  159. * nBytes - number of bytes to transfer
  160. * rw - indicates the direction of transfer up or down (READ/WRITE)
  161. * *pCookie - pointer to cookie used by upper layer such as dosFsLib(),
  162. * it should be preserved.
  163. * RETURNS OK or ERROR and may otherwise set errno.
  164. */
  165. LOCAL STATUS ramDiskBytesRW
  166.     (
  167.     CBIO_DEV_ID  dev,
  168.     block_t startBlock,
  169.     off_t offset,
  170.     addr_t buffer,
  171.     size_t nBytes,
  172.     CBIO_RW rw,
  173.     cookie_t *pCookie
  174.     )
  175.     {
  176.     CBIO_DEV *  pDev = dev ;
  177.     caddr_t  pStart;
  178.     if( TRUE == CBIO_READYCHANGED (dev) )
  179. {
  180. errno = S_ioLib_DISK_NOT_PRESENT ;
  181. return ERROR;
  182. }
  183.     if( startBlock >= pDev->cbioParams.nBlocks )
  184. return ERROR;
  185.     /* verify that all bytes are within one block range */
  186.     if (((offset + nBytes) > pDev->cbioParams.bytesPerBlk ) ||
  187. (offset <0) || (nBytes <=0))
  188. return ERROR;
  189.     /* calculate actual memory address of data */
  190.     startBlock += pDev->cbioParams.blockOffset;
  191.     pStart = pDev->cbioMemBase + ( startBlock << pDev->cbioBlkShift ) ;
  192.     pStart += offset ;
  193.     DEBUG_MSG("ramDiskBytesRW: blk %d + %d # %d bytes -> addr %x, %x bytesn",
  194. startBlock, offset, nBytes, pStart, nBytes );
  195.     if( semTake( pDev->cbioMutex, WAIT_FOREVER) == ERROR )
  196. return ERROR;
  197.     switch( rw )
  198. {
  199. case CBIO_READ:
  200.     bcopy( pStart, buffer, nBytes );
  201.     break;
  202. case CBIO_WRITE:
  203.     bcopy( buffer, pStart,  nBytes );
  204.     break;
  205. }
  206.     semGive(pDev->cbioMutex);
  207.     return OK;
  208.     }
  209. /*******************************************************************************
  210. *
  211. * ramDiskBlkCopy - Copy sectors 
  212. * This routine makes copies of one or more blocks on the lower layer hardware.
  213. * It is optimized for block copies on the subordinate layer.  
  214. * dev - the CBIO handle of the device being accessed (from creation routine)
  215. * srcBlock - source start block of the copy
  216. * dstBlock - destination start block of the copy
  217. * num_block - number of blocks to copy
  218. *
  219. * RETURNS OK or ERROR and may otherwise set errno.
  220. */
  221. LOCAL STATUS ramDiskBlkCopy
  222.     (
  223.     CBIO_DEV_ID  dev,
  224.     block_t srcBlock,
  225.     block_t dstBlock,
  226.     block_t numBlocks
  227.     )
  228.     {
  229.     CBIO_DEV *pDev = (void *) dev ;
  230.     caddr_t pSrc, pDst;
  231.     size_t nBytes ;
  232.     if( TRUE == CBIO_READYCHANGED (dev) )
  233. {
  234. errno = S_ioLib_DISK_NOT_PRESENT ;
  235. return ERROR;
  236. }
  237.     if( (srcBlock) > pDev->cbioParams.nBlocks ||
  238.         (dstBlock) > pDev->cbioParams.nBlocks )
  239. return ERROR;
  240.     if( (srcBlock+numBlocks) > pDev->cbioParams.nBlocks ||
  241.         (dstBlock+numBlocks) > pDev->cbioParams.nBlocks )
  242. return ERROR;
  243.     srcBlock += pDev->cbioParams.blockOffset;
  244.     dstBlock += pDev->cbioParams.blockOffset;
  245.     pSrc = pDev->cbioMemBase + ( srcBlock << pDev->cbioBlkShift ) ;
  246.     pDst = pDev->cbioMemBase + ( dstBlock << pDev->cbioBlkShift ) ;
  247.     nBytes = numBlocks << pDev->cbioBlkShift ;
  248.     DEBUG_MSG("ramDiskBlkCopy: blk %d to %d # %d -> addr %x,to %x %x bytesn",
  249. srcBlock, dstBlock, numBlocks, pSrc, pDst, nBytes );
  250.     if( semTake( pDev->cbioMutex, WAIT_FOREVER) == ERROR )
  251. return ERROR;
  252.     /* Do the actual copying */
  253.     bcopy( pSrc, pDst, nBytes );
  254.     semGive(pDev->cbioMutex);
  255.     return OK;
  256.     }
  257. /*******************************************************************************
  258. *
  259. * ramDiskIoctl - Misc control operations 
  260. * This performs the requested ioctl() operation.
  261. * CBIO modules can expect the following ioctl() codes from cbioLib.h:
  262. * CBIO_RESET - reset the CBIO device and the lower layer
  263. * CBIO_STATUS_CHK - check device status of CBIO device and lower layer
  264. * CBIO_DEVICE_LOCK - Prevent disk removal 
  265. * CBIO_DEVICE_UNLOCK - Allow disk removal
  266. * CBIO_DEVICE_EJECT - Unmount and eject device
  267. * CBIO_CACHE_FLUSH - Flush any dirty cached data
  268. * CBIO_CACHE_INVAL - Flush & Invalidate all cached data
  269. * CBIO_CACHE_NEWBLK - Allocate scratch block
  270. *
  271. * dev - the CBIO handle of the device being accessed (from creation routine)
  272. * command - ioctl() command being issued
  273. * arg - specific to the particular ioctl() function requested or un-used.
  274. *
  275. * RETURNS OK or ERROR and may otherwise set errno.
  276. */
  277. LOCAL STATUS ramDiskIoctl
  278.     (
  279.     CBIO_DEV_ID dev,
  280.     UINT32 command,
  281.     addr_t arg
  282.     )
  283.     {
  284.     switch ( command )
  285. {
  286. case CBIO_RESET :
  287. /* HELP is this really okay for a driver to do? */
  288. CBIO_READYCHANGED (dev) = FALSE; 
  289. return (OK);
  290. case CBIO_STATUS_CHK : /* These are no-ops for the RAM Disk : */
  291. case CBIO_DEVICE_LOCK :
  292. case CBIO_DEVICE_UNLOCK :
  293. case CBIO_DEVICE_EJECT :
  294. case CBIO_CACHE_FLUSH :
  295. case CBIO_CACHE_INVAL :
  296.     if( TRUE == CBIO_READYCHANGED (dev) )
  297. {
  298. errno = S_ioLib_DISK_NOT_PRESENT ;
  299. return ERROR;
  300. }
  301.     return OK;
  302. case CBIO_CACHE_NEWBLK:
  303.     if( TRUE == CBIO_READYCHANGED (dev) )
  304. {
  305. errno = S_ioLib_DISK_NOT_PRESENT ;
  306. return ERROR;
  307. }
  308.     else
  309. {
  310. /* zero out the new block */
  311. caddr_t pBlk ;
  312. block_t blk = (long) arg ;
  313. int nBytes = 1 << dev->cbioBlkShift ;
  314. if( blk >= dev->cbioParams.nBlocks )
  315.     return ERROR;
  316. blk += dev->cbioParams.blockOffset ;
  317. pBlk = dev->cbioMemBase + ( blk << dev->cbioBlkShift ) ;
  318. bzero( pBlk, nBytes );
  319. return OK;
  320. }
  321. default:
  322.     errno = EINVAL;
  323.     return (ERROR);
  324. }
  325.     }
  326. /*******************************************************************************
  327. *
  328. * shiftCalc - calculate how many shift bits
  329. *
  330. * How many shifts <n< are needed such that <mask> == 1 << <N>
  331. * This is very useful for replacing multiplication with shifts,
  332. * where it is known a priori that the multiplier is 2^k.
  333. *
  334. * RETURNS: Number of shifts.
  335. */
  336. LOCAL int shiftCalc
  337.     (
  338.     u_long mask
  339.     )
  340.     {
  341.     int i;
  342.     for (i=0; i<32; i++)
  343. {
  344. if (mask & 1)
  345.     break ;
  346. mask = mask >> 1 ;
  347. }
  348.     return( i );
  349.     }
  350. /*******************************************************************************
  351. *
  352. * ramDiskDevCreate - Initialize a RAM Disk device
  353. *
  354. * This function creates a compact RAM-Disk device that can be directly
  355. * utilized by dosFsLib, without the intermediate disk cache.
  356. * It can be used for non-volatile RAM as well as volatile RAM disks.
  357. *
  358. * The RAM size is specified in terms of total number of blocks in the
  359. * device and the block size in bytes. The minimal block size is 32 bytes.
  360. * If <pRamAddr> is NULL, space will be allocated from the default memory
  361. * pool.
  362. *
  363. * RETURNS: a CBIO handle that can be directly used by dosFsDevCreate()
  364. * or NULL if the requested amount of RAM is not available.
  365. *
  366. * CAVEAT: When used with NV-RAM, this module can not eliminate mid-block
  367. * write interruption, which may cause file system corruption not
  368. * existent in common disk drives.
  369. *
  370. * SEE ALSO: dosFsDevCreate().
  371. */
  372. CBIO_DEV_ID ramDiskDevCreate
  373.     (
  374.     char  *pRamAddr,     /* where it is in memory (0 = malloc)     */
  375.     int   bytesPerBlk,   /* number of bytes per block              */
  376.     int   blksPerTrack,  /* number of blocks per track             */
  377.     int   nBlocks,       /* number of blocks on this device        */
  378.     int   blkOffset      /* no. of blks to skip at start of device */
  379.     )
  380.     {
  381.     CBIO_DEV_ID pDev = NULL ;
  382.     size_t diskSize;
  383.     char shift;
  384.     /* Fill in defaults for args with 0 value */
  385.     if( bytesPerBlk == 0)
  386. bytesPerBlk = 64 ;
  387.     if( nBlocks == 0)
  388. nBlocks = 2048 ;
  389.     if( blksPerTrack == 0)
  390. blksPerTrack = 16 ;
  391.     /* first check that bytesPerBlk is 2^n */
  392.     shift = shiftCalc( bytesPerBlk );
  393.     if( bytesPerBlk != ( 1 << shift ) )
  394. {
  395. errno = EINVAL;
  396. return( NULL );
  397. }
  398.     /* calculate memory pool size in bytes */
  399.     diskSize = nBlocks << shift ;
  400.     cbioLibInit(); /* just in case */
  401.     /* Create CBIO device - generic (cbioDevCreate, cbioLib.c) */
  402.     pDev = (CBIO_DEV_ID) cbioDevCreate ( pRamAddr, diskSize );
  403.     if( pDev == NULL )
  404. return( NULL );
  405.     /* If we got here, then generic device is allocated */
  406.     pDev->cbioDesc = "RAM Disk Driver";
  407.     pDev->cbioParams.cbioRemovable = FALSE ;
  408.     CBIO_READYCHANGED (pDev)      = FALSE ;
  409.     pDev->cbioParams.nBlocks = nBlocks ;
  410.     pDev->cbioParams.bytesPerBlk = bytesPerBlk ;
  411.     pDev->cbioParams.blocksPerTrack = blksPerTrack ;
  412.     pDev->cbioParams.nHeads = 1 ;
  413.     pDev->cbioParams.blockOffset = blkOffset ;
  414.     pDev->cbioMode = O_RDWR ;
  415.     pDev->cbioParams.lastErrBlk = NONE ;
  416.     pDev->cbioParams.lastErrno = 0 ;
  417.     pDev->cbioBlkShift = shift ;
  418.     /* cbioFuncs is staticly allocated in each driver. */
  419.     pDev->pFuncs = &cbioFuncs;
  420.     /* 
  421.      * SPR#67729: Fill in the members blksubDev, cbioSubDev and isDriver 
  422.      * appropriately 
  423.      */
  424.     pDev->blkSubDev = NULL;  /* This layer does not have a BLKDEV below it */
  425.     pDev->cbioSubDev = pDev; /* Stores a pointer to itself   */
  426.                              /* since this is the last layer */
  427.     pDev->isDriver = TRUE;   /* For ramDiskCbio we are the lowest layer */
  428.     DEBUG_MSG("ramDiskDevCreate: dev %x, size %xn", pDev, diskSize );
  429.     /* return device handle */
  430.     return( pDev );
  431.     }
  432. /*******************************************************************************
  433. *
  434. * ramDiskShow - show current parameters of the RAM disk device
  435. *
  436. * This function is not implemented.
  437. * NOMANUAL
  438. */
  439. STATUS ramDiskShow( CBIO_DEV_ID dev, int verb )
  440.     {
  441.     return OK;
  442.     }