source: rtems/cpukit/libblock/src/blkdev.c @ b96e09c

4.104.11
Last change on this file since b96e09c was b96e09c, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on Oct 13, 2009 at 7:58:33 AM
  • libblock/include/rtems/diskdevs.h: Added driver data pointer to IO control function. The IO control handler takes now the disk device as first parameter instead of the physical device number.
  • cpukit/libblock/include/rtems/blkdev.h, libblock/src/bdbuf.c, libblock/src/blkdev.c, libblock/src/diskdevs.c, libblock/src/nvdisk.c, libblock/src/flashdisk.c, libblock/src/ramdisk.c: Update for block device API change.
  • Property mode set to 100644
File size: 6.6 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup rtems_blkdev
5 *
6 * Block device management.
7 */
8 
9/*
10 * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
11 * Author: Victor V. Vengerov <vvv@oktet.ru>
12 *
13 * @(#) $Id$
14 */
15
16#if HAVE_CONFIG_H
17#include "config.h"
18#endif
19
20#include <errno.h>
21#include <string.h>
22
23#include <rtems.h>
24#include <rtems/libio.h>
25#include <sys/ioctl.h>
26
27#include "rtems/diskdevs.h"
28#include "rtems/bdbuf.h"
29
30/* rtems_blkdev_generic_read --
31 *     Generic block device read primitive. Implemented using block device
32 *     buffer management primitives.
33 */
34rtems_device_driver
35rtems_blkdev_generic_read(
36    rtems_device_major_number major,
37    rtems_device_minor_number minor,
38    void                    * arg)
39{
40    rtems_libio_rw_args_t *args = arg;
41    int block_size;
42    char         *buf;
43    unsigned int count;
44    unsigned int block;
45    unsigned int blkofs;
46    dev_t dev;
47    rtems_disk_device *dd;
48
49    dev = rtems_filesystem_make_dev_t(major, minor);
50    dd = rtems_disk_obtain(dev);
51    if (dd == NULL)
52        return RTEMS_INVALID_NUMBER;
53
54    block_size = dd->block_size;
55
56    buf = args->buffer;
57    count = args->count;
58    args->bytes_moved = 0;
59
60    block = args->offset / block_size;
61    blkofs = args->offset % block_size;
62
63    while (count > 0)
64    {
65        rtems_bdbuf_buffer *diskbuf;
66        uint32_t            copy;
67        rtems_status_code   rc;
68
69        rc = rtems_bdbuf_read(dev, block, &diskbuf);
70        if (rc != RTEMS_SUCCESSFUL)
71            return rc;
72        copy = block_size - blkofs;
73        if (copy > count)
74            copy = count;
75        memcpy(buf, (char *)diskbuf->buffer + blkofs, copy);
76        rc = rtems_bdbuf_release(diskbuf);
77        args->bytes_moved += copy;
78        if (rc != RTEMS_SUCCESSFUL)
79            return rc;
80        count -= copy;
81        buf += copy;
82        blkofs = 0;
83        block++;
84    }
85    return RTEMS_SUCCESSFUL;
86}
87
88/* rtems_blkdev_generic_write --
89 *     Generic block device write primitive. Implemented using block device
90 *     buffer management primitives.
91 */
92rtems_device_driver
93rtems_blkdev_generic_write(
94    rtems_device_major_number major,
95    rtems_device_minor_number minor,
96    void                    * arg)
97{
98    rtems_libio_rw_args_t *args = arg;
99    uint32_t      block_size;
100    char         *buf;
101    uint32_t      count;
102    uint32_t      block;
103    uint32_t      blkofs;
104    dev_t dev;
105    rtems_status_code rc;
106    rtems_disk_device *dd;
107
108    dev = rtems_filesystem_make_dev_t(major, minor);
109    dd = rtems_disk_obtain(dev);
110    if (dd == NULL)
111        return RTEMS_INVALID_NUMBER;
112
113    block_size = dd->block_size;
114
115    buf = args->buffer;
116    count = args->count;
117    args->bytes_moved = 0;
118
119    block = args->offset / block_size;
120    blkofs = args->offset % block_size;
121
122    while (count > 0)
123    {
124        rtems_bdbuf_buffer *diskbuf;
125        uint32_t            copy;
126
127        if ((blkofs == 0) && (count >= block_size))
128            rc = rtems_bdbuf_get(dev, block, &diskbuf);
129        else
130            rc = rtems_bdbuf_read(dev, block, &diskbuf);
131        if (rc != RTEMS_SUCCESSFUL)
132            return rc;
133
134        copy = block_size - blkofs;
135        if (copy > count)
136            copy = count;
137        memcpy((char *)diskbuf->buffer + blkofs, buf, copy);
138        args->bytes_moved += copy;
139
140        rc = rtems_bdbuf_release_modified(diskbuf);
141        if (rc != RTEMS_SUCCESSFUL)
142            return rc;
143
144        count -= copy;
145        buf += copy;
146        blkofs = 0;
147        block++;
148    }
149    return RTEMS_SUCCESSFUL;
150}
151
152/* blkdev_generic_open --
153 *     Generic block device open primitive.
154 */
155rtems_device_driver
156rtems_blkdev_generic_open(
157    rtems_device_major_number major,
158    rtems_device_minor_number minor,
159    void                    * arg __attribute__((unused)))
160{
161    dev_t dev;
162    rtems_disk_device *dd;
163
164    dev = rtems_filesystem_make_dev_t(major, minor);
165    dd = rtems_disk_obtain(dev);
166    if (dd == NULL)
167        return RTEMS_INVALID_NUMBER;
168
169    dd->uses++;
170
171    rtems_disk_release(dd);
172
173    return RTEMS_SUCCESSFUL;
174}
175
176
177/* blkdev_generic_close --
178 *     Generic block device close primitive.
179 */
180rtems_device_driver
181rtems_blkdev_generic_close(
182    rtems_device_major_number major,
183    rtems_device_minor_number minor,
184    void                    * arg __attribute__((unused)))
185{
186    dev_t dev;
187    rtems_disk_device *dd;
188
189    dev = rtems_filesystem_make_dev_t(major, minor);
190    dd = rtems_disk_obtain(dev);
191    if (dd == NULL)
192        return RTEMS_INVALID_NUMBER;
193
194    dd->uses--;
195
196    rtems_disk_release(dd);
197
198    return RTEMS_SUCCESSFUL;
199}
200
201/* blkdev_generic_ioctl --
202 *     Generic block device ioctl primitive.
203 */
204rtems_device_driver
205rtems_blkdev_generic_ioctl(
206    rtems_device_major_number major,
207    rtems_device_minor_number minor,
208    void                    * arg)
209{
210    rtems_libio_ioctl_args_t *args = arg;
211    dev_t dev;
212    rtems_disk_device *dd;
213    int rc;
214
215    dev = rtems_filesystem_make_dev_t(major, minor);
216    dd = rtems_disk_obtain(dev);
217    if (dd == NULL)
218        return RTEMS_INVALID_NUMBER;
219
220    switch (args->command)
221    {
222        case RTEMS_BLKIO_GETMEDIABLKSIZE:
223            args->ioctl_return = dd->media_block_size;
224            break;
225
226        case RTEMS_BLKIO_GETBLKSIZE:
227            args->ioctl_return = dd->block_size;
228            break;
229
230        case RTEMS_BLKIO_SETBLKSIZE:
231            dd->block_size = *((size_t*) args->buffer);
232            break;
233
234        case RTEMS_BLKIO_GETSIZE:
235            args->ioctl_return = dd->size;
236            break;
237
238        case RTEMS_BLKIO_SYNCDEV:
239            rc = rtems_bdbuf_syncdev(dd->dev);
240            args->ioctl_return = (uint32_t) (rc == RTEMS_SUCCESSFUL ? 0 : -1);
241            break;
242
243        case RTEMS_BLKIO_REQUEST:
244        {
245            rtems_blkdev_request *req = args->buffer;
246            args->ioctl_return = (uint32_t) dd->ioctl(dd, args->command, req);
247            break;
248        }
249
250        default:
251            args->ioctl_return = (uint32_t) dd->ioctl(dd, args->command,
252                                                      args->buffer);
253            break;
254    }
255    rtems_disk_release(dd);
256
257    return RTEMS_SUCCESSFUL;
258}
259
260int
261rtems_blkdev_ioctl(rtems_disk_device *dd, uint32_t req, void *argp)
262{
263    size_t            *arg_size = argp;
264    int                rc = 0;
265   
266    switch (req)
267    {
268        case RTEMS_BLKIO_GETMEDIABLKSIZE:
269            *arg_size = dd->media_block_size;
270            break;
271
272        case RTEMS_BLKIO_GETBLKSIZE:
273            *arg_size = dd->block_size;
274            break;
275
276        case RTEMS_BLKIO_SETBLKSIZE:
277            dd->block_size = *arg_size;
278            break;
279
280        case RTEMS_BLKIO_GETSIZE:
281            *arg_size = dd->size;
282            break;
283
284        default:
285            errno = EINVAL;
286            rc = -1;
287            break;
288    }
289
290    return rc;
291}
Note: See TracBrowser for help on using the repository browser.