source: rtems/cpukit/libblock/src/ramdisk.c @ 006fa1ef

4.104.114.84.9
Last change on this file since 006fa1ef was 006fa1ef, checked in by Ralf Corsepius <ralf.corsepius@…>, on Nov 20, 2003 at 12:14:50 PM

2003-11-20 Ralf Corsepius <corsepiu@…>

  • Makefile.am: AM_CPPFLAGS += -I$(top_builddir). Use AM_CPPFLAGS instead of AM_CFLAGS.
  • src/ata.c: Include config.h.
  • src/bdbuf.c: Ditto.
  • src/blkdev.c: Ditto.
  • src/diskdevs.c: Ditto.
  • src/ide_part_table.c: Ditto.
  • src/ramdisk.c: Ditto.
  • Property mode set to 100644
File size: 6.0 KB
Line 
1/* ramdisk.c -- RAM disk block device implementation
2 *
3 * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
4 * Author: Victor V. Vengerov <vvv@oktet.ru>
5 *
6 * @(#) $Id$
7 */
8
9#if HAVE_CONFIG_H
10#include "config.h"
11#endif
12
13#include <rtems.h>
14#include <rtems/libio.h>
15#include <errno.h>
16#include <stdlib.h>
17#include <stdio.h>
18#include <string.h>
19
20#include "rtems/blkdev.h"
21#include "rtems/diskdevs.h"
22#include "rtems/ramdisk.h"
23
24#define RAMDISK_DEVICE_BASE_NAME "/dev/ramdisk"
25
26/* Internal RAM disk descriptor */
27struct ramdisk {
28    int           block_size; /* RAM disk block size */
29    int           block_num;  /* Number of blocks on this RAM disk */
30    void         *area;       /* RAM disk memory area */
31    rtems_boolean initialized;/* RAM disk is initialized */
32    rtems_boolean malloced;   /* != 0, if memory allocated by malloc for this
33                                 RAM disk */
34};
35
36static struct ramdisk *ramdisk;
37static int nramdisks;
38
39/* ramdisk_read --
40 *     RAM disk READ request handler. This primitive copies data from RAM
41 *     disk to supplied buffer and invoke the callout function to inform
42 *     upper layer that reading is completed.
43 *
44 * PARAMETERS:
45 *     req - pointer to the READ block device request info
46 *
47 * RETURNS:
48 *     ioctl return value
49 */
50static int
51ramdisk_read(struct ramdisk *rd, blkdev_request *req)
52{
53    char *from;
54    rtems_unsigned32 i;
55    blkdev_sg_buffer *sg;
56    rtems_unsigned32 remains;
57   
58    from = (char *)rd->area + (req->start * rd->block_size);
59    remains = rd->block_size * req->count;
60    sg = req->bufs;
61    for (i = 0; (remains > 0) && (i < req->bufnum); i++, sg++)
62    {
63        int count = sg->length;
64        if (count > remains)
65            count = remains;
66        memcpy(sg->buffer, from, count);
67        remains -= count;
68        from += count;
69    }
70    req->req_done(req->done_arg, RTEMS_SUCCESSFUL, 0);
71    return 0;
72}
73
74/* ramdisk_write --
75 *     RAM disk WRITE request handler. This primitive copies data from
76 *     supplied buffer to RAM disk and invoke the callout function to inform
77 *     upper layer that writing is completed.
78 *
79 * PARAMETERS:
80 *     req - pointer to the WRITE block device request info
81 *
82 * RETURNS:
83 *     ioctl return value
84 */
85static int
86ramdisk_write(struct ramdisk *rd, blkdev_request *req)
87{
88    char *to;
89    rtems_unsigned32 i;
90    blkdev_sg_buffer *sg;
91    rtems_unsigned32 remains;
92   
93    to = (char *)rd->area + (req->start * rd->block_size);
94    remains = rd->block_size * req->count;
95    sg = req->bufs;
96    for (i = 0; (remains > 0) && (i < req->bufnum); i++, sg++)
97    {
98        int count = sg->length;
99        if (count > remains)
100            count = remains;
101        memcpy(to, sg->buffer, count);
102        remains -= count;
103        to += count;
104    }
105    req->req_done(req->done_arg, RTEMS_SUCCESSFUL, 0);
106    return 0;
107}
108
109/* ramdisk_ioctl --
110 *     IOCTL handler for RAM disk device.
111 *
112 * PARAMETERS:
113 *      dev  - device number (major, minor number)
114 *      req  - IOCTL request code
115 *      argp - IOCTL argument
116 *
117 * RETURNS:
118 *     IOCTL return value
119 */
120static int
121ramdisk_ioctl(dev_t dev, int req, void *argp)
122{
123    switch (req)
124    {
125        case BLKIO_REQUEST:
126        {
127            rtems_device_minor_number minor;
128            blkdev_request *r = argp;
129            struct ramdisk *rd;
130
131            minor = rtems_filesystem_dev_minor_t(dev);
132            if ((minor >= nramdisks) || !ramdisk[minor].initialized)
133            {
134                errno = ENODEV;
135                return -1;
136            }
137           
138            rd = ramdisk + minor;
139           
140            switch (r->req)
141            {
142                case BLKDEV_REQ_READ:
143                    return ramdisk_read(rd, r);
144
145                case BLKDEV_REQ_WRITE:
146                    return ramdisk_write(rd, r);
147                   
148                default:
149                    errno = EBADRQC;
150                    return -1;
151            }
152            break;
153        }
154       
155        default:
156            errno = EBADRQC;
157            return -1;
158    }
159}
160
161/* ramdisk_initialize --
162 *     RAM disk device driver initialization. Run through RAM disk
163 *     configuration information and configure appropriate RAM disks.
164 *
165 * PARAMETERS:
166 *     major - RAM disk major device number
167 *     minor - minor device number, not applicable
168 *     arg   - initialization argument, not applicable
169 *
170 * RETURNS:
171 *     none
172 */
173rtems_device_driver
174ramdisk_initialize(
175    rtems_device_major_number major,
176    rtems_device_minor_number minor,
177    void *arg)
178{
179    rtems_device_minor_number i;
180    rtems_ramdisk_config *c = rtems_ramdisk_configuration;
181    struct ramdisk *r;
182    rtems_status_code rc;
183
184    rc = rtems_disk_io_initialize();
185    if (rc != RTEMS_SUCCESSFUL)
186        return rc;
187       
188    r = ramdisk = calloc(rtems_ramdisk_configuration_size, 
189                         sizeof(struct ramdisk));
190   
191    for (i = 0; i < rtems_ramdisk_configuration_size; i++, c++, r++)
192    {
193        dev_t dev = rtems_filesystem_make_dev_t(major, i);
194        char name[sizeof(RAMDISK_DEVICE_BASE_NAME "0123456789")];
195        snprintf(name, sizeof(name), RAMDISK_DEVICE_BASE_NAME "%d", i);
196        r->block_size = c->block_size;
197        r->block_num = c->block_num;
198        if (c->location == NULL)
199        {
200            r->malloced = TRUE;
201            r->area = malloc(r->block_size * r->block_num);
202            if (r->area == NULL) /* No enough memory for this disk */
203            {
204                r->initialized = FALSE;
205                continue;
206            }
207            else
208            {
209                r->initialized = TRUE;
210            }
211        }
212        else
213        {
214            r->malloced = FALSE;
215            r->initialized = TRUE;
216            r->area = c->location;
217        }
218        rc = rtems_disk_create_phys(dev, c->block_size, c->block_num,
219                                    ramdisk_ioctl, name);
220        if (rc != RTEMS_SUCCESSFUL)
221        {
222            if (r->malloced)
223            {
224                free(r->area);
225            }
226            r->initialized = FALSE;
227        }
228    }
229    nramdisks = rtems_ramdisk_configuration_size;
230    return RTEMS_SUCCESSFUL;
231}
Note: See TracBrowser for help on using the repository browser.