OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [cpukit/] [libblock/] [src/] [ramdisk.c] - Blame information for rev 1780

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1026 ivang
/* 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
 * @(#) ramdisk.c,v 1.2 2002/04/08 18:29:02 joel Exp
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 */
23
struct 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
 
32
static struct ramdisk *ramdisk;
33
static 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
 */
46
static int
47
ramdisk_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
 */
80
static int
81
ramdisk_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
 */
114
static int
115
ramdisk_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
 */
167
rtems_device_driver
168
ramdisk_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
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.