ramDrv.c
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:15k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* ramDrv.c - RAM disk driver */
  2. /* Copyright 1984-1995 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 02m,11dec96,dgp  doc: fix SPR #7596, add INCLUDE FILE ramDrv.h
  8. 02l,16jan95,rhp  ANSIfy declaration of ramDrv().
  9. 02k,20jan93,jdi  documentation cleanup.
  10. 02j,21oct92,jdi  removed mangen SECTION designation.
  11. 02i,18jul92,smb  Changed errno.h to errnoLib.h.
  12. 02h,04jul92,jcf  scalable/ANSI/cleanup effort.
  13. 02g,26may92,rrr  the tree shuffle
  14. 02f,04oct91,rrr  passed through the ansification filter
  15.   -changed READ, WRITE and UPDATE to O_RDONLY O_WRONLY O_RDWR
  16.   -changed copyright notice
  17. 02e,11apr91,jdi  documentation cleanup; doc review by kdl.
  18. 02d,19oct90,kdl  changed "msdos" references to "dosFs"; changed "sector"
  19.  to "block" throughout.
  20. 02c,30jul90,dnw  coerced malloc to (char*) to eliminate warning
  21. 02b,12jul90,kdl  added bd_statusChk field to BLK_DEV.
  22. 02a,15may90,kdl  documentation.
  23. 01z,04may90,kdl  added BLK_DEV fields (bd_mode, bd_readyChanged);
  24.  added FIODISKFORMAT.
  25. 01y,23mar90,kdl  changed BLK_DEV field names (blkIo.h).
  26. 01x,05mar90,kdl  changed to support multiple file systems.
  27. 01w,21feb90,dab  added DEFAULT_DISK_SIZE for ramMkfs().
  28. 01v,08jul88,jcf  lint.
  29. 01u,06jun88,dnw  changed rtLib to rt11Lib.
  30. 01t,30may88,dnw  changed to v4 names.
  31. 01s,06nov87,ecs  documentation.
  32. 01r,04aug87,gae  made ramClose() return STATUS.
  33.  Changed "static" stuff in ramDrv().
  34. 01q,25mar87,jlf  documentation
  35. 01p,13mar87,gae  documentation and fixed/improved version 01o.
  36. 01o,11mar87,gae  changed raw device open to not use "-" any more.
  37.  made ramMkfs() return STATUS not (char *).
  38.  made ramDrv() be a NOP on successive calls.
  39. 01n,17feb87,gae  fixed rtDevInit() call.
  40. 01m,04feb87,llk  changed call to rtDevInit.  Specifies number of files.
  41. 01l,21dec86,dnw  changed to not get include files from default directories.
  42. 01k,05sep86,jlf  documentation
  43. 01j,15aug86,ecs  renamed ramIoctrl to ramIoctl, changed to call rtIoctl.
  44. 01i,02jul86,jlf  oops.
  45. 01h,02jul86,jlf  documentation.
  46. 01g,03mar86,jlf  changed ioctrl calls to ioctl.
  47. 01f,11nov85,jlf  made ramOpen, ramCreate, and ramDelete do a rtReadyChange.
  48.    The is a kludge so when multiple CPU's share a RAM
  49.    device, the directory will be reread when any of them
  50.    try to create, delete, or open a file.
  51. 01e,19sep85,jlf  got rid of checkMount, and removed member `mounted' from
  52.  dev descriptor.
  53. 01d,12sep85,jlf  updated calling sequence to rtDevInit.
  54. 01c,14aug85,dnw  added ramMkfs.
  55. 01b,21jul85,jlf  documentation
  56. 01a,24may85,jlf  written, by modifying v03k of fd208Drv.c.
  57. */
  58. /*
  59. This driver emulates a disk driver, but actually keeps all data in memory.
  60. The memory location and size are specified when the "disk" is created.
  61. The RAM disk feature is useful when data must be preserved between boots of
  62. VxWorks or when sharing data between CPUs.
  63. USER-CALLABLE ROUTINES
  64. Most of the routines in this driver are accessible only through the I/O system.
  65. Two routines, however, can be called directly by the user.  The first, ramDrv(),
  66. provides no real function except to parallel the initialization function found
  67. in true disk device drivers.  A call to ramDrv() is not required to use the RAM
  68. disk driver.  However, the second routine, ramDevCreate(), must be called 
  69. directly to create RAM disk devices.
  70. Once the device has been created, it must be associated with a name and
  71. file system (dosFs, rt11Fs, or rawFs).  This is accomplished by passing
  72. the value returned by ramDevCreate(), a pointer to a block device
  73. structure, to the file system's device initialization routine or
  74. make-file-system routine.  See the manual entry ramDevCreate() for a
  75. more detailed discussion.
  76. IOCTL FUNCTIONS
  77. The RAM driver is called in response to ioctl() codes in the same manner
  78. as a normal disk driver.  When the file system is unable to handle a
  79. specific ioctl() request, it is passed to the ramDrv driver.  Although
  80. there is no physical device to be controlled, ramDrv does handle a
  81. FIODISKFORMAT request, which always returns OK.  All other ioctl()
  82. requests return an error and set the task's `errno' to S_ioLib_UNKNOWN_REQUEST.
  83. INCLUDE FILE
  84. ramDrv.h
  85. SEE ALSO: dosFsDevInit(), dosFsMkfs(), rt11FsDevInit(), rt11FsMkfs(),
  86. rawFsDevInit(),
  87. .pG "I/O System, Local File Systems"
  88. LINTLIBRARY
  89. */
  90. #include "vxWorks.h"
  91. #include "blkIo.h"
  92. #include "ioLib.h"
  93. #include "iosLib.h"
  94. #include "memLib.h"
  95. #include "errnoLib.h"
  96. #include "string.h"
  97. #include "stdlib.h"
  98. #include "stdio.h"
  99. #define DEFAULT_DISK_SIZE  (min (memFindMax()/2, 51200))
  100. #define DEFAULT_SEC_SIZE   512
  101. typedef struct /* RAM_DEV - RAM disk device descriptor */
  102.     {
  103.     BLK_DEV  ram_blkdev; /* generic block device structure */
  104.     char  *ram_addr; /* memory location of the RAM disk */
  105.     int  ram_blkOffset; /* block offset of this device from ram_addr */
  106.     } RAM_DEV;
  107. /* FORWARD DECLARATIONS */
  108. LOCAL STATUS ramIoctl ();
  109. LOCAL STATUS ramBlkRd ();
  110. LOCAL STATUS ramBlkWrt ();
  111. /*******************************************************************************
  112. *
  113. * ramDrv - prepare a RAM disk driver for use (optional)
  114. *
  115. * This routine performs no real function, except to provide compatibility
  116. * with earlier versions of ramDrv and to parallel the initialization
  117. * function found in true disk device drivers.  It also is used in
  118. * usrConfig.c to link in the RAM disk driver when building
  119. * VxWorks.  Otherwise, there is no need to call this routine before using
  120. * the RAM disk driver.
  121. *
  122. * RETURNS: OK, always.
  123. */
  124. STATUS ramDrv (void)
  125.     {
  126.     return (OK); /* no initialization required */
  127.     }
  128. /*******************************************************************************
  129. *
  130. * ramDevCreate - create a RAM disk device
  131. *
  132. * This routine creates a RAM disk device.
  133. *
  134. * Memory for the RAM disk can be pre-allocated separately; if so, the
  135. * <ramAddr> parameter should be the address of the pre-allocated device
  136. * memory.  Or, memory can be automatically allocated with malloc() by
  137. * setting <ramAddr> to zero.
  138. *
  139. * The <bytesPerBlk> parameter specifies the size of each logical block
  140. * on the RAM disk.  If <bytesPerBlk> is zero, 512 is used.
  141. *
  142. * The <blksPerTrack> parameter specifies the number of blocks on each
  143. * logical track of the RAM disk.  If <blksPerTrack> is zero, the count of
  144. * blocks per track is set to <nBlocks> (i.e., the disk is defined
  145. * as having only one track).
  146. *
  147. * The <nBlocks> parameter specifies the size of the disk, in blocks.
  148. * If <nBlocks> is zero, a default size is used.  The default is calculated
  149. * using a total disk size of either 51,200 bytes or one-half of the size
  150. * of the largest memory area available, whichever is less.  This default
  151. * disk size is then divided by <bytesPerBlk> to determine the number
  152. * of blocks.
  153. *
  154. * The <blkOffset> parameter specifies an offset, in blocks, from the start
  155. * of the device to be used when writing or reading the RAM disk.  This
  156. * offset is added to the block numbers passed by the file system during
  157. * disk accesses.  (VxWorks file systems always use block numbers beginning
  158. * at zero for the start of a device.)  This offset value is typically useful
  159. * only if a specific address is given for <ramAddr>.  Normally, <blkOffset>
  160. * is 0.
  161. *
  162. * FILE SYSTEMS:
  163. * Once the device has been created, it must be associated with a name and a
  164. * file system (dosFs, rt11Fs, or rawFs).  This is accomplished using the
  165. * file system's device initialization routine or make-file-system routine,
  166. * e.g., dosFsDevInit() or dosFsMkfs().  The ramDevCreate() call returns a
  167. * pointer to a block device structure (BLK_DEV).  This structure contains
  168. * fields that describe the physical properties of a disk device and specify
  169. * the addresses of routines within the ramDrv driver.  The BLK_DEV structure
  170. * address must be passed to the desired file system (dosFs, rt11Fs or rawFs)
  171. * via the file system's device initialization or make-file-system routine.
  172. * Only then is a name and file system associated with the device, making it
  173. * available for use.
  174. *
  175. * EXAMPLE:
  176. * In the following example, a 200-Kbyte RAM disk is created with
  177. * automatically allocated memory, 512-byte blocks, a single track, and no
  178. * block offset.  The device is then initialized for use with dosFs and assigned
  179. * the name "DEV1:":
  180. * .CS
  181. *     BLK_DEV *pBlkDev;
  182. *     DOS_VOL_DESC *pVolDesc;
  183. *
  184. *     pBlkDev = ramDevCreate (0,  512,  400,  400,  0);
  185. *     pVolDesc = dosFsMkfs ("DEV1:", pBlkDev);
  186. * .CE
  187. * The dosFsMkfs() routine calls dosFsDevInit() with default parameters and
  188. * initializes the file system on the disk by calling ioctl() with the
  189. * %FIODISKINIT function.
  190. *
  191. * If the RAM disk memory already contains a disk image created elsewhere,
  192. * the first argument to ramDevCreate() should be the address in memory, and
  193. * the formatting parameters -- <bytesPerBlk>, <blksPerTrack>, <nBlocks>, and
  194. * <blkOffset> -- must be identical to those used when the image was
  195. * created.  For example:
  196. * .CS
  197. *     pBlkDev = ramDevCreate (0xc0000, 512, 400, 400, 0);
  198. *     pVolDesc = dosFsDevInit ("DEV1:", pBlkDev, NULL);
  199. * .CE
  200. * In this case, dosFsDevInit() must be used instead of dosFsMkfs(), because
  201. * the file system already exists on the disk and should not be
  202. * re-initialized.  This procedure is useful if a RAM disk is to be created
  203. * at the same address used in a previous boot of VxWorks.  The contents of
  204. * the RAM disk will then be preserved.
  205. *
  206. * These same procedures apply when creating a RAM disk with rt11Fs using
  207. * rt11FsDevInit() and rt11FsMkfs(), or creating a RAM disk with rawFs using
  208. * rawFsDevInit().
  209. *
  210. * RETURNS:
  211. * A pointer to a block device structure (BLK_DEV) or NULL if memory cannot
  212. * be allocated for the device structure or for the RAM disk.
  213. *
  214. * SEE ALSO: dosFsMkfs(), dosFsDevInit(), rt11FsDevInit(), rt11FsMkfs(),
  215. * rawFsDevInit()
  216. */
  217. BLK_DEV *ramDevCreate
  218.     (
  219.     char *ramAddr, /* where it is in memory (0 = malloc) */
  220.     FAST int bytesPerBlk, /* number of bytes per block */
  221.     int blksPerTrack, /* number of blocks per track */
  222.     int nBlocks, /* number of blocks on this device */
  223.     int blkOffset /* no. of blks to skip at start of device */
  224.     )
  225.  
  226.     {
  227.     FAST RAM_DEV *pRamDev; /* ptr to created RAM_DEV struct */
  228.     FAST BLK_DEV *pBlkDev; /* ptr to BLK_DEV struct in RAM_DEV */
  229.     /* Set up defaults for any values not specified */
  230.     if (bytesPerBlk == 0)
  231. bytesPerBlk = DEFAULT_SEC_SIZE;
  232.     if (nBlocks == 0)
  233. nBlocks = DEFAULT_DISK_SIZE / bytesPerBlk;
  234.     if (blksPerTrack == 0)
  235. blksPerTrack = nBlocks;
  236.     /* Allocate a RAM_DEV structure for device */
  237.     pRamDev = (RAM_DEV *) malloc (sizeof (RAM_DEV));
  238.     if (pRamDev == NULL)
  239. return (NULL); /* no memory */
  240.     /* Initialize BLK_DEV structure (in RAM_DEV) */
  241.     pBlkDev = &pRamDev->ram_blkdev;
  242.     pBlkDev->bd_nBlocks      = nBlocks; /* number of blocks */
  243.     pBlkDev->bd_bytesPerBlk  = bytesPerBlk; /* bytes per block */
  244.     pBlkDev->bd_blksPerTrack = blksPerTrack; /* blocks per track */
  245.     pBlkDev->bd_nHeads       = 1; /* one "head" */
  246.     pBlkDev->bd_removable    = FALSE; /* not removable */
  247.     pBlkDev->bd_retry      = 1; /* retry count */
  248.     pBlkDev->bd_mode      = O_RDWR; /* initial mode for device */
  249.     pBlkDev->bd_readyChanged = TRUE; /* new ready status */
  250.     pBlkDev->bd_blkRd      = ramBlkRd; /* read block function */
  251.     pBlkDev->bd_blkWrt      = ramBlkWrt; /* write block function */
  252.     pBlkDev->bd_ioctl      = ramIoctl; /* ioctl function */
  253.     pBlkDev->bd_reset      = NULL; /* no reset function */
  254.     pBlkDev->bd_statusChk    = NULL; /* no check-status function */
  255.     /* Initialize remainder of device struct */
  256.     if (ramAddr == NULL) /* allocate mem if 0 */
  257. {
  258. pRamDev->ram_addr = (char *) malloc ((UINT) (bytesPerBlk * nBlocks));
  259. if (pRamDev->ram_addr == NULL)
  260.     {
  261.     free ((char *) pRamDev);
  262.     return (NULL); /* no memory */
  263.     }
  264. }
  265.     else
  266. pRamDev->ram_addr = ramAddr;
  267.     pRamDev->ram_blkOffset = blkOffset; /* block offset */
  268.     return (&pRamDev->ram_blkdev);
  269.     }
  270. /*******************************************************************************
  271. *
  272. * ramIoctl - do device specific control function
  273. *
  274. * This routine is called when the file system cannot handle an ioctl()
  275. * function.
  276. *
  277. * The FIODISKFORMAT function always returns OK, since a RAM disk does
  278. * not require formatting.  All other requests return ERROR.
  279. *
  280. * RETURNS:  OK or ERROR.
  281. *
  282. * ERRNO: S_ioLib_UNKNOWN_REQUEST
  283. *
  284. */
  285. LOCAL STATUS ramIoctl (pRamDev, function, arg)
  286.     RAM_DEV *pRamDev; /* device structure pointer */
  287.     int function; /* function code */
  288.     int arg; /* some argument */
  289.     {
  290.     FAST int status; /* returned status value */
  291.     switch (function)
  292. {
  293. case FIODISKFORMAT:
  294.     status = OK;
  295.     break;
  296. default:
  297.     errnoSet (S_ioLib_UNKNOWN_REQUEST);
  298.     status = ERROR;
  299. }
  300.     return (status);
  301.     }
  302. /*******************************************************************************
  303. *
  304. * ramBlkRd - read one or more blocks from a RAM disk volume
  305. *
  306. * This routine reads one or more blocks from the specified volume,
  307. * starting with the specified block number.  The byte offset is
  308. * calculated and the RAM disk data is copied to the specified buffer.
  309. *
  310. * If any block offset was specified during ramDevCreate(), it is added
  311. * to <startBlk> before the transfer takes place.
  312. *
  313. * RETURNS: OK, always.
  314. */
  315. LOCAL STATUS ramBlkRd (pRamDev, startBlk, numBlks, pBuffer)
  316.     FAST RAM_DEV *pRamDev; /* pointer to device desriptor */
  317.     int startBlk; /* starting block number to read */
  318.     int numBlks; /* number of blocks to read */
  319.     char *pBuffer; /* pointer to buffer to receive data */
  320.     {
  321.     FAST int bytesPerBlk; /* number of bytes per block */
  322.     bytesPerBlk = pRamDev->ram_blkdev.bd_bytesPerBlk;
  323.     /* Add in the block offset */
  324.     startBlk += pRamDev->ram_blkOffset;
  325.     /* Read the block(s) */
  326.     bcopy ((pRamDev->ram_addr + (startBlk * bytesPerBlk)), pBuffer,
  327.    bytesPerBlk * numBlks);
  328.     return (OK);
  329.     }
  330. /*******************************************************************************
  331. *
  332. * ramBlkWrt - write one or more blocks to a RAM disk volume
  333. *
  334. * This routine writes one or more blocks to the specified volume,
  335. * starting with the specified block number.  The byte offset is
  336. * calculated and the buffer data is copied to the RAM disk.
  337. *
  338. * If any block offset was specified during ramDevCreate(), it is added
  339. * to <startBlk> before the transfer takes place.
  340. *
  341. * RETURNS: OK, always.
  342. */
  343. LOCAL STATUS ramBlkWrt (pRamDev, startBlk, numBlks, pBuffer)
  344.     FAST RAM_DEV *pRamDev; /* pointer to device desriptor */
  345.     int startBlk; /* starting block number to write */
  346.     int numBlks; /* number of blocks to write */
  347.     char *pBuffer; /* pointer to buffer of data to write */
  348.     {
  349.     FAST int bytesPerBlk; /* number of bytes per block */
  350.     bytesPerBlk = pRamDev->ram_blkdev.bd_bytesPerBlk;
  351.     /* Add in the block offset */
  352.     startBlk += pRamDev->ram_blkOffset;
  353.     /* Write the block(s) */
  354.     bcopy (pBuffer, (pRamDev->ram_addr + (startBlk * bytesPerBlk)),
  355.    bytesPerBlk * numBlks);
  356.     return (OK);
  357.     }