source: rtems/cpukit/libblock/src/blkdev.c @ 945884fe

4.104.11
Last change on this file since 945884fe was 945884fe, checked in by Chris Johns <chrisj@…>, on Aug 6, 2009 at 3:58:09 AM

2009-08-06 Chris Johns <chrisj@…>

  • libblock/src/bdbuf.c: Fix group user logic.
  • libblock/include/rtems/blkdev.h, libblock/src/blkdev.c, libblock/src/nvdisk.c, libblock/src/flashdisk.c: Add set block size, and get media block size support.
  • Property mode set to 100644
File size: 6.8 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 = (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 = dd->ioctl(dd->phys_dev->dev, args->command,
247                                           req);
248            break;
249        }
250
251        default:
252            args->ioctl_return = dd->ioctl(dd->phys_dev->dev, args->command,
253                                           args->buffer);
254            break;
255    }
256    rtems_disk_release(dd);
257
258    return RTEMS_SUCCESSFUL;
259}
260
261int
262rtems_blkdev_ioctl(dev_t dev, uint32_t req, void *argp)
263{
264    rtems_disk_device *dd;
265    size_t            *arg_size = argp;
266
267    dd = rtems_disk_obtain(dev);
268    if (dd == NULL)
269    {
270        errno = ENODEV;
271        return -1;
272    }
273   
274    switch (req)
275    {
276        case RTEMS_BLKIO_GETMEDIABLKSIZE:
277            *arg_size = dd->media_block_size;
278            break;
279
280        case RTEMS_BLKIO_GETBLKSIZE:
281            *arg_size = dd->block_size;
282            break;
283
284        case RTEMS_BLKIO_SETBLKSIZE:
285            dd->block_size = *arg_size;
286            break;
287
288        case RTEMS_BLKIO_GETSIZE:
289            *arg_size = dd->size;
290            break;
291
292        default:
293            errno = EINVAL;
294            return -1;
295            break;
296    }
297   
298    rtems_disk_release(dd);
299
300    return 0;
301}
Note: See TracBrowser for help on using the repository browser.