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

4.104.114.84.95
Last change on this file since dbe06865 was 228587bb, checked in by Joel Sherrill <joel.sherrill@…>, on 04/08/02 at 18:29:02

2002-04-06 Ralf Corsepius <corsepiu@…>

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