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

4.104.114.84.95
Last change on this file since df6348bb was e51bd96, checked in by Joel Sherrill <joel.sherrill@…>, on 02/28/02 at 20:39:54

2002-02-28 Joel Sherrill <joel@…>

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