source: rtems/cpukit/libblock/src/ramdisk.c @ d0c3b38b

4.104.115
Last change on this file since d0c3b38b was d0c3b38b, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on 05/05/09 at 12:57:16

Documentation. Changed integer types to match block device types.
Added const qualifier whenever possible. Added
rtems_fsmount_create_mount_point() prototype.

  • Property mode set to 100644
File size: 7.3 KB
Line 
1/**
2 * @file
3 *
4 * RAM disk block device.
5 */
6
7/*
8 * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
9 * Author: Victor V. Vengerov <vvv@oktet.ru>
10 *
11 * @(#) $Id$
12 */
13
14#if HAVE_CONFIG_H
15#include "config.h"
16#endif
17
18#include <rtems.h>
19#include <rtems/libio.h>
20#include <errno.h>
21#include <stdlib.h>
22#include <stdio.h>
23#include <string.h>
24#include <inttypes.h>
25
26#include <rtems/blkdev.h>
27#include <rtems/diskdevs.h>
28#include <rtems/ramdisk.h>
29
30/**
31 * Control tracing. It can be compiled out of the code for small
32 * footprint targets. Leave in by default.
33 */
34#if !defined (RTEMS_RAMDISK_TRACE)
35#define RTEMS_RAMDISK_TRACE 0
36#endif
37
38#define RAMDISK_DEVICE_BASE_NAME "/dev/rd"
39
40/* Internal RAM disk descriptor */
41struct ramdisk {
42  uint32_t block_size; /* RAM disk block size */
43  rtems_blkdev_bnum block_num; /* Number of blocks on this RAM disk */
44  void *area; /* RAM disk memory area */
45  bool initialized; /* RAM disk is initialized */
46  bool malloced; /* != 0, if memory allocated by malloc for this RAM disk */
47#if RTEMS_RAMDISK_TRACE
48  int info_level; /* Trace level */
49#endif
50};
51
52static struct ramdisk *ramdisk;
53static uint32_t nramdisks;
54
55#if RTEMS_RAMDISK_TRACE
56/**
57 * Print a message to the ramdisk output and flush it.
58 *
59 * @param rd The ramdisk control structure.
60 * @param format The format string. See printf for details.
61 * @param ... The arguments for the format text.
62 * @return int The number of bytes written to the output.
63 */
64static int
65rtems_ramdisk_printf (struct ramdisk *rd, const char *format, ...)
66{
67  int ret = 0;
68  if (rd->info_level >= 1)
69  {
70    va_list args;
71    va_start (args, format);
72    fprintf (stdout, "ramdisk:");
73    ret =  vfprintf (stdout, format, args);
74    fprintf (stdout, "\n");
75    fflush (stdout);
76  }
77  return ret;
78}
79#endif
80
81/* ramdisk_read --
82 *     RAM disk READ request handler. This primitive copies data from RAM
83 *     disk to supplied buffer and invoke the callout function to inform
84 *     upper layer that reading is completed.
85 *
86 * PARAMETERS:
87 *     req - pointer to the READ block device request info
88 *
89 * RETURNS:
90 *     ioctl return value
91 */
92static int
93ramdisk_read(struct ramdisk *rd, rtems_blkdev_request *req)
94{
95    char *from;
96    uint32_t   i;
97    rtems_blkdev_sg_buffer *sg;
98    uint32_t   remains;
99
100#if RTEMS_RAMDISK_TRACE
101    rtems_ramdisk_printf (rd, "ramdisk read: start=%d, blocks=%d remains=%d",
102                          req->bufs[0].block, req->bufnum,
103                          rd->block_size * req->count);
104#endif
105
106    remains = rd->block_size * req->bufnum;
107    sg = req->bufs;
108    for (i = 0; (remains > 0) && (i < req->bufnum); i++, sg++)
109    {
110        uint32_t count = sg->length;
111        from = ((char *)rd->area + (sg->block * rd->block_size));
112        if (count > remains)
113            count = remains;
114        memcpy(sg->buffer, from, count);
115        remains -= count;
116        from += count;
117    }
118    req->req_done(req->done_arg, RTEMS_SUCCESSFUL, 0);
119    return 0;
120}
121
122/* ramdisk_write --
123 *     RAM disk WRITE request handler. This primitive copies data from
124 *     supplied buffer to RAM disk and invoke the callout function to inform
125 *     upper layer that writing is completed.
126 *
127 * PARAMETERS:
128 *     req - pointer to the WRITE block device request info
129 *
130 * RETURNS:
131 *     ioctl return value
132 */
133static int
134ramdisk_write(struct ramdisk *rd, rtems_blkdev_request *req)
135{
136    char *to;
137    uint32_t   i;
138    rtems_blkdev_sg_buffer *sg;
139    uint32_t   remains;
140
141#if RTEMS_RAMDISK_TRACE
142    rtems_ramdisk_printf (rd, "ramdisk write: start=%d, blocks=%d remains=%d",
143                          req->bufs[0].block, req->bufnum,
144                          rd->block_size * req->bufnum);
145#endif
146    remains = rd->block_size * req->bufnum;
147    sg = req->bufs;
148    for (i = 0; (remains > 0) && (i < req->bufnum); i++, sg++)
149    {
150        uint32_t count = sg->length;
151        to = ((char *)rd->area + (sg->block * rd->block_size));
152        if (count > remains)
153            count = remains;
154        memcpy(to, sg->buffer, count);
155        remains -= count;
156        to += count;
157    }
158    req->req_done(req->done_arg, RTEMS_SUCCESSFUL, 0);
159    return 0;
160}
161
162/* ramdisk_ioctl --
163 *     IOCTL handler for RAM disk device.
164 *
165 * PARAMETERS:
166 *      dev  - device number (major, minor number)
167 *      req  - IOCTL request code
168 *      argp - IOCTL argument
169 *
170 * RETURNS:
171 *     IOCTL return value
172 */
173static int
174ramdisk_ioctl(dev_t dev, uint32_t req, void *argp)
175{
176    switch (req)
177    {
178        case RTEMS_BLKIO_REQUEST:
179        {
180            rtems_device_minor_number minor;
181            rtems_blkdev_request *r = argp;
182            struct ramdisk *rd;
183
184            minor = rtems_filesystem_dev_minor_t(dev);
185            if ((minor >= nramdisks) || !ramdisk[minor].initialized)
186            {
187                errno = ENODEV;
188                return -1;
189            }
190
191            rd = ramdisk + minor;
192
193            switch (r->req)
194            {
195                case RTEMS_BLKDEV_REQ_READ:
196                    return ramdisk_read(rd, r);
197
198                case RTEMS_BLKDEV_REQ_WRITE:
199                    return ramdisk_write(rd, r);
200
201                default:
202                    errno = EBADRQC;
203                    return -1;
204            }
205            break;
206        }
207
208        default:
209            errno = EBADRQC;
210            return -1;
211    }
212}
213
214/* ramdisk_initialize --
215 *     RAM disk device driver initialization. Run through RAM disk
216 *     configuration information and configure appropriate RAM disks.
217 *
218 * PARAMETERS:
219 *     major - RAM disk major device number
220 *     minor - minor device number, not applicable
221 *     arg   - initialization argument, not applicable
222 *
223 * RETURNS:
224 *     none
225 */
226rtems_device_driver
227ramdisk_initialize(
228    rtems_device_major_number major,
229    rtems_device_minor_number minor __attribute__((unused)),
230    void *arg __attribute__((unused)))
231{
232    rtems_device_minor_number i;
233    rtems_ramdisk_config *c = rtems_ramdisk_configuration;
234    struct ramdisk *r;
235    rtems_status_code rc;
236
237    rc = rtems_disk_io_initialize();
238    if (rc != RTEMS_SUCCESSFUL)
239        return rc;
240
241    r = ramdisk = calloc(rtems_ramdisk_configuration_size,
242                         sizeof(struct ramdisk));
243#if RTEMS_RAMDISK_TRACE
244    r->info_level = 1;
245#endif   
246    for (i = 0; i < rtems_ramdisk_configuration_size; i++, c++, r++)
247    {
248        dev_t dev = rtems_filesystem_make_dev_t(major, i);
249        char name [] = RAMDISK_DEVICE_BASE_NAME "a";
250        name [sizeof(RAMDISK_DEVICE_BASE_NAME)] += i;
251        r->block_size = c->block_size;
252        r->block_num = c->block_num;
253        if (c->location == NULL)
254        {
255            r->malloced = true;
256            r->area = malloc(r->block_size * r->block_num);
257            if (r->area == NULL) /* No enough memory for this disk */
258            {
259                r->initialized = false;
260                continue;
261            }
262            else
263            {
264                r->initialized = true;
265            }
266        }
267        else
268        {
269            r->malloced = false;
270            r->initialized = true;
271            r->area = c->location;
272        }
273        rc = rtems_disk_create_phys(dev, c->block_size, c->block_num,
274                                    ramdisk_ioctl, name);
275        if (rc != RTEMS_SUCCESSFUL)
276        {
277            if (r->malloced)
278            {
279                free(r->area);
280            }
281            r->initialized = false;
282        }
283    }
284    nramdisks = rtems_ramdisk_configuration_size;
285    return RTEMS_SUCCESSFUL;
286}
Note: See TracBrowser for help on using the repository browser.