source: rtems/cpukit/libblock/src/blkdev.c @ 2eb89ad

4.104.114.9
Last change on this file since 2eb89ad was 2eb89ad, checked in by Chris Johns <chrisj@…>, on Aug 2, 2008 at 6:23:45 AM

2008-08-02 Chris Johns (chrisj@…>

  • libblock/include/rtems/blkdev.h: Remove count and start from rtems_blkdev_request. Add RTEMS_BLKDEV_START_BLOCK macro.
  • libblock/src/bdbuf.c: Add read ahead blocks always consecutive comment. Change count to bufnum and remove start references. Sort the transfer list so blocks are consecutive where possible.
  • libblock/src/blkdev.c, libblock/src/nvdisk.c, libblock/src/ramdisk.c: Change count to bufnum and remove start references.
  • Property mode set to 100644
File size: 5.8 KB
Line 
1/*
2 * blkdev.h - block device driver generic support
3 *
4 * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
5 * Author: Victor V. Vengerov <vvv@oktet.ru>
6 *
7 * @(#) $Id$
8 */
9
10#if HAVE_CONFIG_H
11#include "config.h"
12#endif
13
14#include <string.h>
15
16#include <rtems.h>
17#include <rtems/libio.h>
18#include <sys/ioctl.h>
19
20#include "rtems/diskdevs.h"
21#include "rtems/bdbuf.h"
22
23/* rtems_blkdev_generic_read --
24 *     Generic block device read primitive. Implemented using block device
25 *     buffer management primitives.
26 */
27rtems_device_driver
28rtems_blkdev_generic_read(
29    rtems_device_major_number major,
30    rtems_device_minor_number minor,
31    void                    * arg)
32{
33    rtems_libio_rw_args_t *args = arg;
34    int block_size_log2;
35    int block_size;
36    char         *buf;
37    unsigned int count;
38    unsigned int block;
39    unsigned int blkofs;
40    dev_t dev;
41    rtems_disk_device *dd;
42
43    dev = rtems_filesystem_make_dev_t(major, minor);
44    dd = rtems_disk_obtain(dev);
45    if (dd == NULL)
46        return RTEMS_INVALID_NUMBER;
47
48    block_size_log2 = dd->block_size_log2;
49    block_size = dd->block_size;
50
51    buf = args->buffer;
52    count = args->count;
53    args->bytes_moved = 0;
54
55    block = args->offset >> block_size_log2;
56    blkofs = args->offset & (block_size - 1);
57
58    while (count > 0)
59    {
60        rtems_bdbuf_buffer *diskbuf;
61        int copy;
62        rtems_status_code rc;
63
64        rc = rtems_bdbuf_read(dev, block, &diskbuf);
65        if (rc != RTEMS_SUCCESSFUL)
66            return rc;
67        copy = block_size - blkofs;
68        if (copy > count)
69            copy = count;
70        memcpy(buf, (char *)diskbuf->buffer + blkofs, copy);
71        rc = rtems_bdbuf_release(diskbuf);
72        args->bytes_moved += copy;
73        if (rc != RTEMS_SUCCESSFUL)
74            return rc;
75        count -= copy;
76        buf += copy;
77        blkofs = 0;
78        block++;
79    }
80    return RTEMS_SUCCESSFUL;
81}
82
83/* rtems_blkdev_generic_write --
84 *     Generic block device write primitive. Implemented using block device
85 *     buffer management primitives.
86 */
87rtems_device_driver
88rtems_blkdev_generic_write(
89    rtems_device_major_number major,
90    rtems_device_minor_number minor,
91    void                    * arg)
92{
93    rtems_libio_rw_args_t *args = arg;
94    int block_size_log2;
95    int block_size;
96    char         *buf;
97    unsigned int count;
98    unsigned int block;
99    unsigned int blkofs;
100    dev_t dev;
101    rtems_status_code rc;
102    rtems_disk_device *dd;
103
104    dev = rtems_filesystem_make_dev_t(major, minor);
105    dd = rtems_disk_obtain(dev);
106    if (dd == NULL)
107        return RTEMS_INVALID_NUMBER;
108
109    block_size_log2 = dd->block_size_log2;
110    block_size = dd->block_size;
111
112    buf = args->buffer;
113    count = args->count;
114    args->bytes_moved = 0;
115
116    block = args->offset >> block_size_log2;
117    blkofs = args->offset & (block_size - 1);
118
119    while (count > 0)
120    {
121        rtems_bdbuf_buffer *diskbuf;
122        int copy;
123
124        if ((blkofs == 0) && (count >= block_size))
125            rc = rtems_bdbuf_get(dev, block, &diskbuf);
126        else
127            rc = rtems_bdbuf_read(dev, block, &diskbuf);
128        if (rc != RTEMS_SUCCESSFUL)
129            return rc;
130
131        copy = block_size - blkofs;
132        if (copy > count)
133            copy = count;
134        memcpy((char *)diskbuf->buffer + blkofs, buf, copy);
135        args->bytes_moved += copy;
136
137        rc = rtems_bdbuf_release_modified(diskbuf);
138        if (rc != RTEMS_SUCCESSFUL)
139            return rc;
140
141        count -= copy;
142        buf += copy;
143        blkofs = 0;
144        block++;
145    }
146    return RTEMS_SUCCESSFUL;
147}
148
149/* blkdev_generic_open --
150 *     Generic block device open primitive.
151 */
152rtems_device_driver
153rtems_blkdev_generic_open(
154    rtems_device_major_number major,
155    rtems_device_minor_number minor,
156    void                    * arg)
157{
158    dev_t dev;
159    rtems_disk_device *dd;
160
161    dev = rtems_filesystem_make_dev_t(major, minor);
162    dd = rtems_disk_obtain(dev);
163    if (dd == NULL)
164        return RTEMS_INVALID_NUMBER;
165
166    dd->uses++;
167
168    rtems_disk_release(dd);
169
170    return RTEMS_SUCCESSFUL;
171}
172
173
174/* blkdev_generic_close --
175 *     Generic block device close primitive.
176 */
177rtems_device_driver
178rtems_blkdev_generic_close(
179    rtems_device_major_number major,
180    rtems_device_minor_number minor,
181    void                    * arg)
182{
183    dev_t dev;
184    rtems_disk_device *dd;
185
186    dev = rtems_filesystem_make_dev_t(major, minor);
187    dd = rtems_disk_obtain(dev);
188    if (dd == NULL)
189        return RTEMS_INVALID_NUMBER;
190
191    dd->uses--;
192
193    rtems_disk_release(dd);
194
195    return RTEMS_SUCCESSFUL;
196}
197
198/* blkdev_generic_ioctl --
199 *     Generic block device ioctl primitive.
200 */
201rtems_device_driver
202rtems_blkdev_generic_ioctl(
203    rtems_device_major_number major,
204    rtems_device_minor_number minor,
205    void                    * arg)
206{
207    rtems_libio_ioctl_args_t *args = arg;
208    dev_t dev;
209    rtems_disk_device *dd;
210    int rc;
211
212    dev = rtems_filesystem_make_dev_t(major, minor);
213    dd = rtems_disk_obtain(dev);
214    if (dd == NULL)
215        return RTEMS_INVALID_NUMBER;
216
217    switch (args->command)
218    {
219        case RTEMS_BLKIO_GETBLKSIZE:
220            args->ioctl_return = dd->block_size;
221            break;
222
223        case RTEMS_BLKIO_GETSIZE:
224            args->ioctl_return = dd->size;
225            break;
226
227        case RTEMS_BLKIO_SYNCDEV:
228            rc = rtems_bdbuf_syncdev(dd->dev);
229            args->ioctl_return = (rc == RTEMS_SUCCESSFUL ? 0 : -1);
230            break;
231
232        case RTEMS_BLKIO_REQUEST:
233        {
234            rtems_blkdev_request *req = args->buffer;
235            args->ioctl_return = dd->ioctl(dd->phys_dev->dev, args->command,
236                                           req);
237            break;
238        }
239
240        default:
241            args->ioctl_return = dd->ioctl(dd->phys_dev->dev, args->command,
242                                           args->buffer);
243            break;
244    }
245    rtems_disk_release(dd);
246
247    return RTEMS_SUCCESSFUL;
248}
Note: See TracBrowser for help on using the repository browser.