source: rtems/cpukit/libblock/src/ramdisk.c @ 25d42183

4.104.114.84.9
Last change on this file since 25d42183 was 25d42183, checked in by Joel Sherrill <joel.sherrill@…>, on Apr 16, 2003 at 7:35:02 PM

2002-04-10 Victor V. Vengerov <vvv@…>

PR 385/filesystem

  • src/ramdisk.c: The "from" and "to" locations are calculated as the start of the block within the ram that data is to be transferred from/to for reads and writes respectively. However, within the loops, the "from" and "to" locations are never updated. The loop should have been updated as:

from += rd->block_size;

and

to += rd->block_size;

within the for loops in the ramdisk_read and ramdisk_write routines,
respectively.

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