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

4.115
Last change on this file since 796967c was 796967c, checked in by Sebastian Huber <sebastian.huber@…>, on 02/28/12 at 16:19:49

libblock: Change bdbuf API

The functions

o rtems_bdbuf_get(),
o rtems_bdbuf_read(),
o rtems_bdbuf_syncdev(), and
o rtems_bdbuf_purge_dev(),

use now the disk device instead of the device identifier. This makes
bdbuf independent of rtems_disk_obtain() and rtems_disk_release(). It
is the responsiblity of the file system to obtain the disk device. This
also reduces the overhead to get a buffer.

The key for the AVL tree uses now the disk device instead of the device
identifier. The pointer is interpreted as an unsigned integer. This
reduces the memory overhead and makes the comparison operation a bit
faster.

Removed function rtems_bdbuf_purge_major(). This function was too
destructive and could have unpredictable side effects.

  • Property mode set to 100644
File size: 6.7 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 __attribute__((unused)),
37    rtems_device_minor_number minor __attribute__((unused)),
38    void                    * arg)
39{
40    rtems_status_code rc = RTEMS_SUCCESSFUL;
41    rtems_libio_rw_args_t *args = arg;
42    rtems_libio_t *iop = args->iop;
43    rtems_disk_device *dd = iop->data1;
44    uint32_t block_size = dd->block_size;
45    char *buf = args->buffer;
46    uint32_t count = args->count;
47    rtems_blkdev_bnum block = (rtems_blkdev_bnum) (args->offset / block_size);
48    uint32_t blkofs = (uint32_t) (args->offset % block_size);
49
50    args->bytes_moved = 0;
51
52    while (count > 0)
53    {
54        rtems_bdbuf_buffer *diskbuf;
55        uint32_t            copy;
56
57        rc = rtems_bdbuf_read(dd, block, &diskbuf);
58        if (rc != RTEMS_SUCCESSFUL)
59            break;
60        copy = block_size - blkofs;
61        if (copy > count)
62            copy = count;
63        memcpy(buf, (char *)diskbuf->buffer + blkofs, copy);
64        rc = rtems_bdbuf_release(diskbuf);
65        args->bytes_moved += copy;
66        if (rc != RTEMS_SUCCESSFUL)
67            break;
68        count -= copy;
69        buf += copy;
70        blkofs = 0;
71        block++;
72    }
73
74    return rc;
75}
76
77/* rtems_blkdev_generic_write --
78 *     Generic block device write primitive. Implemented using block device
79 *     buffer management primitives.
80 */
81rtems_device_driver
82rtems_blkdev_generic_write(
83    rtems_device_major_number major __attribute__((unused)),
84    rtems_device_minor_number minor __attribute__((unused)),
85    void                    * arg)
86{
87    rtems_status_code rc = RTEMS_SUCCESSFUL;
88    rtems_libio_rw_args_t *args = arg;
89    rtems_libio_t *iop = args->iop;
90    rtems_disk_device *dd = iop->data1;
91    uint32_t block_size = dd->block_size;
92    char *buf = args->buffer;
93    uint32_t count = args->count;
94    rtems_blkdev_bnum block = (rtems_blkdev_bnum) (args->offset / block_size);
95    uint32_t blkofs = (uint32_t) (args->offset % block_size);
96
97    args->bytes_moved = 0;
98
99    while (count > 0)
100    {
101        rtems_bdbuf_buffer *diskbuf;
102        uint32_t            copy;
103
104        if ((blkofs == 0) && (count >= block_size))
105            rc = rtems_bdbuf_get(dd, block, &diskbuf);
106        else
107            rc = rtems_bdbuf_read(dd, block, &diskbuf);
108        if (rc != RTEMS_SUCCESSFUL)
109            break;
110
111        copy = block_size - blkofs;
112        if (copy > count)
113            copy = count;
114        memcpy((char *)diskbuf->buffer + blkofs, buf, copy);
115        args->bytes_moved += copy;
116
117        rc = rtems_bdbuf_release_modified(diskbuf);
118        if (rc != RTEMS_SUCCESSFUL)
119            break;
120
121        count -= copy;
122        buf += copy;
123        blkofs = 0;
124        block++;
125    }
126
127    return rc;
128}
129
130/* blkdev_generic_open --
131 *     Generic block device open primitive.
132 */
133rtems_device_driver
134rtems_blkdev_generic_open(
135    rtems_device_major_number major,
136    rtems_device_minor_number minor,
137    void                    * arg)
138{
139  rtems_libio_open_close_args_t *oc = arg;
140  rtems_libio_t *iop = oc->iop;
141  dev_t dev = rtems_filesystem_make_dev_t(major, minor);
142  rtems_disk_device *dd = rtems_disk_obtain(dev);
143
144  iop->data1 = dd;
145
146  if (dd != NULL)
147    return RTEMS_SUCCESSFUL;
148  else
149    return RTEMS_UNSATISFIED;
150}
151
152
153/* blkdev_generic_close --
154 *     Generic block device close primitive.
155 */
156rtems_device_driver
157rtems_blkdev_generic_close(
158    rtems_device_major_number major __attribute__((unused)),
159    rtems_device_minor_number minor __attribute__((unused)),
160    void                    * arg)
161{
162  rtems_libio_open_close_args_t *oc = arg;
163  rtems_libio_t *iop = oc->iop;
164  rtems_disk_device *dd = iop->data1;
165
166  rtems_disk_release(dd);
167
168  return RTEMS_SUCCESSFUL;
169}
170
171/* blkdev_generic_ioctl --
172 *     Generic block device ioctl primitive.
173 */
174rtems_device_driver
175rtems_blkdev_generic_ioctl(
176    rtems_device_major_number major __attribute__((unused)),
177    rtems_device_minor_number minor __attribute__((unused)),
178    void                    * arg)
179{
180    rtems_libio_ioctl_args_t *args = arg;
181    rtems_libio_t *iop = args->iop;
182    rtems_disk_device *dd = iop->data1;
183    int rc;
184
185    switch (args->command)
186    {
187        case RTEMS_BLKIO_GETMEDIABLKSIZE:
188            *((uint32_t *) args->buffer) = dd->media_block_size;
189            args->ioctl_return = 0;
190            break;
191
192        case RTEMS_BLKIO_GETBLKSIZE:
193            *((uint32_t *) args->buffer) = dd->block_size;
194            args->ioctl_return = 0;
195            break;
196
197        case RTEMS_BLKIO_SETBLKSIZE:
198            dd->block_size = *((uint32_t *) args->buffer);
199            args->ioctl_return = 0;
200            break;
201
202        case RTEMS_BLKIO_GETSIZE:
203            *((rtems_blkdev_bnum *) args->buffer) = dd->size;
204            args->ioctl_return = 0;
205            break;
206
207        case RTEMS_BLKIO_SYNCDEV:
208            rc = rtems_bdbuf_syncdev(dd);
209            args->ioctl_return = (uint32_t) (rc == RTEMS_SUCCESSFUL ? 0 : -1);
210            break;
211
212        case RTEMS_BLKIO_GETDISKDEV:
213            *((rtems_disk_device **) args->buffer) = dd;
214            args->ioctl_return = 0;
215            break;
216
217        case RTEMS_BLKIO_REQUEST:
218            /*
219             * It is not allowed to directly access the driver circumventing
220             * the cache.
221             */
222            args->ioctl_return = (uint32_t) -1;
223            break;
224
225        default:
226            args->ioctl_return = (uint32_t) dd->ioctl(dd->phys_dev,
227                                                      args->command,
228                                                      args->buffer);
229            break;
230    }
231
232    return RTEMS_SUCCESSFUL;
233}
234
235int
236rtems_blkdev_ioctl(rtems_disk_device *dd, uint32_t req, void *argp)
237{
238    size_t            *arg_size = argp;
239    int                rc = 0;
240
241    switch (req)
242    {
243        case RTEMS_BLKIO_GETMEDIABLKSIZE:
244            *arg_size = dd->media_block_size;
245            break;
246
247        case RTEMS_BLKIO_GETBLKSIZE:
248            *arg_size = dd->block_size;
249            break;
250
251        case RTEMS_BLKIO_SETBLKSIZE:
252            dd->block_size = *arg_size;
253            break;
254
255        case RTEMS_BLKIO_GETSIZE:
256            *arg_size = dd->size;
257            break;
258
259        default:
260            errno = EINVAL;
261            rc = -1;
262            break;
263    }
264
265    return rc;
266}
Note: See TracBrowser for help on using the repository browser.