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

4.104.114.84.95
Last change on this file since f36a7bfc was e51bd96, checked in by Joel Sherrill <joel.sherrill@…>, on 02/28/02 at 20:39:54

2002-02-28 Joel Sherrill <joel@…>

  • Submitted by Victor V. Vengerov <vvv@…> and merged into the RTEMS source.
  • ChangeLog?, Makefile.am, README, configure.ac, include/Makefile.am, include/rtems/bdbuf.h, include/rtems/blkdev.h, include/rtems/diskdevs.h, include/rtems/ramdisk.h, include/rtems/.cvsignore, include/.cvsignore, src/Makefile.am, src/bdbuf.c, src/blkdev.c, src/diskdevs.c, src/ramdisk.c, src/.cvsignore, .cvsignore: New files.
  • Property mode set to 100644
File size: 5.9 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#include <rtems.h>
11#include <rtems/libio.h>
12#include <sys/ioctl.h>
13
14#include "rtems/diskdevs.h"
15#include "rtems/bdbuf.h"
16
17/* rtems_blkdev_generic_read --
18 *     Generic block device read primitive. Implemented using block device
19 *     buffer management primitives.
20 */
21rtems_device_driver
22rtems_blkdev_generic_read(
23    rtems_device_major_number major,
24    rtems_device_minor_number minor,
25    void                    * arg)
26{
27    rtems_libio_rw_args_t *args = arg;
28    int block_size_log2;
29    int block_size;
30    char *buf;
31    unsigned int count;
32    unsigned int block;
33    unsigned int blkofs;
34    dev_t dev;
35    disk_device *dd;
36   
37    dev = rtems_filesystem_make_dev_t(major, minor);
38    dd = rtems_disk_lookup(dev);
39    if (dd == NULL)
40        return RTEMS_INVALID_NUMBER;
41   
42    block_size_log2 = dd->block_size_log2;
43    block_size = dd->block_size;
44   
45    buf = args->buffer;
46    count = args->count;
47    args->bytes_moved = 0;
48   
49    block = args->offset >> block_size_log2;
50    blkofs = args->offset & (block_size - 1);
51   
52    while (count > 0)
53    {
54        bdbuf_buffer *diskbuf;
55        int copy;
56        rtems_status_code rc;
57       
58        rc = rtems_bdbuf_read(dev, block, &diskbuf);
59        if (rc != RTEMS_SUCCESSFUL)
60            return rc;
61        copy = block_size - blkofs;
62        if (copy > count)
63            copy = count;
64        memcpy(buf, (char *)diskbuf->buffer + blkofs, copy);
65        rc = rtems_bdbuf_release(diskbuf);
66        args->bytes_moved += copy;
67        if (rc != RTEMS_SUCCESSFUL)
68            return rc;
69        count -= copy;
70        buf += copy;
71        blkofs = 0;
72        block++;
73    }
74    return RTEMS_SUCCESSFUL;
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,
84    rtems_device_minor_number minor,
85    void                    * arg)
86{
87    rtems_libio_rw_args_t *args = arg;
88    int block_size_log2;
89    int block_size;
90    char *buf;
91    unsigned int count;
92    unsigned int block;
93    unsigned int blkofs;
94    dev_t dev;
95    rtems_status_code rc;
96    disk_device *dd;
97   
98    dev = rtems_filesystem_make_dev_t(major, minor);
99    dd = rtems_disk_lookup(dev);
100    if (dd == NULL)
101        return RTEMS_INVALID_NUMBER;
102   
103    block_size_log2 = dd->block_size_log2;
104    block_size = dd->block_size;
105   
106    buf = args->buffer;
107    count = args->count;
108    args->bytes_moved = 0;
109   
110    block = args->offset >> block_size_log2;
111    blkofs = args->offset & (block_size - 1);
112   
113    while (count > 0)
114    {
115        bdbuf_buffer *diskbuf;
116        int copy;
117       
118        if ((blkofs == 0) && (count > block_size))
119            rc = rtems_bdbuf_get(dev, block, &diskbuf);
120        else
121            rc = rtems_bdbuf_read(dev, block, &diskbuf);
122        if (rc != RTEMS_SUCCESSFUL)
123            return rc;
124           
125        copy = block_size - blkofs;
126        if (copy > count)
127            copy = count;
128        memcpy((char *)diskbuf->buffer + blkofs, buf, copy);
129        args->bytes_moved += copy;
130       
131        rc = rtems_bdbuf_release_modified(diskbuf);
132        if (rc != RTEMS_SUCCESSFUL)
133            return rc;
134       
135        count -= copy;
136        buf += copy;
137        blkofs = 0;
138        block++;
139    }
140    return RTEMS_SUCCESSFUL;
141}
142
143/* blkdev_generic_open --
144 *     Generic block device open primitive.
145 */
146rtems_device_driver
147rtems_blkdev_generic_open(
148    rtems_device_major_number major,
149    rtems_device_minor_number minor,
150    void                    * arg)
151{
152    dev_t dev;
153    disk_device *dd;
154   
155    dev = rtems_filesystem_make_dev_t(major, minor);
156    dd = rtems_disk_lookup(dev);
157    if (dd == NULL)
158        return RTEMS_INVALID_NUMBER;
159       
160    dd->uses++;
161   
162    rtems_disk_release(dd);
163   
164    return RTEMS_SUCCESSFUL;
165}
166
167
168/* blkdev_generic_close --
169 *     Generic block device close primitive.
170 */
171rtems_device_driver
172rtems_blkdev_generic_close(
173    rtems_device_major_number major,
174    rtems_device_minor_number minor,
175    void                    * arg)
176{
177    dev_t dev;
178    disk_device *dd;
179   
180    dev = rtems_filesystem_make_dev_t(major, minor);
181    dd = rtems_disk_lookup(dev);
182    if (dd == NULL)
183        return RTEMS_INVALID_NUMBER;
184       
185    dd->uses--;
186   
187    rtems_disk_release(dd);
188   
189    return RTEMS_SUCCESSFUL;
190}
191
192/* blkdev_generic_ioctl --
193 *     Generic block device ioctl primitive.
194 */
195rtems_device_driver
196rtems_blkdev_generic_ioctl(
197    rtems_device_major_number major,
198    rtems_device_minor_number minor,
199    void                    * arg)
200{
201    rtems_libio_ioctl_args_t *args = arg;
202    dev_t dev;
203    disk_device *dd;
204    int rc;
205   
206    dev = rtems_filesystem_make_dev_t(major, minor);
207    dd = rtems_disk_lookup(dev);
208    if (dd == NULL)
209        return RTEMS_INVALID_NUMBER;
210   
211    switch (args->command)
212    {
213        case BLKIO_GETBLKSIZE:
214            args->ioctl_return = dd->block_size;
215            break;
216       
217        case BLKIO_GETSIZE:
218            args->ioctl_return = dd->size;
219            break;
220
221        case BLKIO_SYNCDEV:
222            rc = rtems_bdbuf_syncdev(dd->dev);
223            args->ioctl_return = (rc == RTEMS_SUCCESSFUL ? 0 : -1);
224            break;
225           
226        case BLKIO_REQUEST:
227        {
228            blkdev_request *req = args->buffer;
229            req->start += dd->start;
230            args->ioctl_return = dd->ioctl(dd->phys_dev->dev, args->command,
231                                           req);
232            break;
233        }
234       
235        default:
236            args->ioctl_return = dd->ioctl(dd->phys_dev->dev, args->command,
237                                           args->buffer);
238            break;
239    }
240    rtems_disk_release(dd);
241   
242    return RTEMS_SUCCESSFUL;
243}
Note: See TracBrowser for help on using the repository browser.