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

4.104.115
Last change on this file since c0e0a928 was c0e0a928, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on 11/12/09 at 15:32:11

Changed set and get IO controls to use the buffer argument for data exchange.

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