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

5
Last change on this file was cfe8f7a, checked in by Sebastian Huber <sebastian.huber@…>, on Apr 27, 2020 at 2:14:06 PM

doxygen: Switch @brief and @ingroup

This order change fixes the Latex documentation build via Doxygen.

  • Property mode set to 100644
File size: 5.0 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup rtems_blkdev
5 *
6 * @brief 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
14#ifdef HAVE_CONFIG_H
15#include "config.h"
16#endif
17
18#include <errno.h>
19#include <string.h>
20
21#include <rtems.h>
22#include <rtems/libio.h>
23#include <sys/ioctl.h>
24
25#include "rtems/diskdevs.h"
26#include "rtems/bdbuf.h"
27
28#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
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 RTEMS_UNUSED,
37    rtems_device_minor_number minor RTEMS_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 RTEMS_UNUSED,
84    rtems_device_minor_number minor RTEMS_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 RTEMS_UNUSED,
159    rtems_device_minor_number minor RTEMS_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 RTEMS_UNUSED,
177    rtems_device_minor_number minor RTEMS_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
184    if (args->command != RTEMS_BLKIO_REQUEST)
185    {
186        args->ioctl_return = dd->ioctl(dd,
187                                                  args->command,
188                                                  args->buffer);
189    }
190    else
191    {
192        /*
193         * It is not allowed to directly access the driver circumventing the
194         * cache.
195         */
196        args->ioctl_return = -1;
197    }
198
199    return RTEMS_SUCCESSFUL;
200}
Note: See TracBrowser for help on using the repository browser.