source: rtems/cpukit/libblock/src/blkdev.c @ 9de9b7d2

4.115
Last change on this file since 9de9b7d2 was f6c7bcfe, checked in by Mathew Kallada <matkallada@…>, on 12/21/12 at 17:42:39

libblock: Doxygen Enhancement Task #1

  • Property mode set to 100644
File size: 5.0 KB
Line 
1/**
2 * @file
3 *
4 * @brief Block Device Management
5 * @ingroup rtems_blkdev
6 */
7
8/*
9 * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
10 * Author: Victor V. Vengerov <vvv@oktet.ru>
11 */
12
13#if HAVE_CONFIG_H
14#include "config.h"
15#endif
16
17#include <errno.h>
18#include <string.h>
19
20#include <rtems.h>
21#include <rtems/libio.h>
22#include <sys/ioctl.h>
23
24#include "rtems/diskdevs.h"
25#include "rtems/bdbuf.h"
26
27/* rtems_blkdev_generic_read --
28 *     Generic block device read primitive. Implemented using block device
29 *     buffer management primitives.
30 */
31rtems_device_driver
32rtems_blkdev_generic_read(
33    rtems_device_major_number major __attribute__((unused)),
34    rtems_device_minor_number minor __attribute__((unused)),
35    void                    * arg)
36{
37    rtems_status_code rc = RTEMS_SUCCESSFUL;
38    rtems_libio_rw_args_t *args = arg;
39    rtems_libio_t *iop = args->iop;
40    rtems_disk_device *dd = iop->data1;
41    uint32_t block_size = dd->block_size;
42    char *buf = args->buffer;
43    uint32_t count = args->count;
44    rtems_blkdev_bnum block = (rtems_blkdev_bnum) (args->offset / block_size);
45    uint32_t blkofs = (uint32_t) (args->offset % block_size);
46
47    args->bytes_moved = 0;
48
49    while (count > 0)
50    {
51        rtems_bdbuf_buffer *diskbuf;
52        uint32_t            copy;
53
54        rc = rtems_bdbuf_read(dd, block, &diskbuf);
55        if (rc != RTEMS_SUCCESSFUL)
56            break;
57        copy = block_size - blkofs;
58        if (copy > count)
59            copy = count;
60        memcpy(buf, (char *)diskbuf->buffer + blkofs, copy);
61        rc = rtems_bdbuf_release(diskbuf);
62        args->bytes_moved += copy;
63        if (rc != RTEMS_SUCCESSFUL)
64            break;
65        count -= copy;
66        buf += copy;
67        blkofs = 0;
68        block++;
69    }
70
71    return rc;
72}
73
74/* rtems_blkdev_generic_write --
75 *     Generic block device write primitive. Implemented using block device
76 *     buffer management primitives.
77 */
78rtems_device_driver
79rtems_blkdev_generic_write(
80    rtems_device_major_number major __attribute__((unused)),
81    rtems_device_minor_number minor __attribute__((unused)),
82    void                    * arg)
83{
84    rtems_status_code rc = RTEMS_SUCCESSFUL;
85    rtems_libio_rw_args_t *args = arg;
86    rtems_libio_t *iop = args->iop;
87    rtems_disk_device *dd = iop->data1;
88    uint32_t block_size = dd->block_size;
89    char *buf = args->buffer;
90    uint32_t count = args->count;
91    rtems_blkdev_bnum block = (rtems_blkdev_bnum) (args->offset / block_size);
92    uint32_t blkofs = (uint32_t) (args->offset % block_size);
93
94    args->bytes_moved = 0;
95
96    while (count > 0)
97    {
98        rtems_bdbuf_buffer *diskbuf;
99        uint32_t            copy;
100
101        if ((blkofs == 0) && (count >= block_size))
102            rc = rtems_bdbuf_get(dd, block, &diskbuf);
103        else
104            rc = rtems_bdbuf_read(dd, block, &diskbuf);
105        if (rc != RTEMS_SUCCESSFUL)
106            break;
107
108        copy = block_size - blkofs;
109        if (copy > count)
110            copy = count;
111        memcpy((char *)diskbuf->buffer + blkofs, buf, copy);
112        args->bytes_moved += copy;
113
114        rc = rtems_bdbuf_release_modified(diskbuf);
115        if (rc != RTEMS_SUCCESSFUL)
116            break;
117
118        count -= copy;
119        buf += copy;
120        blkofs = 0;
121        block++;
122    }
123
124    return rc;
125}
126
127/* blkdev_generic_open --
128 *     Generic block device open primitive.
129 */
130rtems_device_driver
131rtems_blkdev_generic_open(
132    rtems_device_major_number major,
133    rtems_device_minor_number minor,
134    void                    * arg)
135{
136  rtems_libio_open_close_args_t *oc = arg;
137  rtems_libio_t *iop = oc->iop;
138  dev_t dev = rtems_filesystem_make_dev_t(major, minor);
139  rtems_disk_device *dd = rtems_disk_obtain(dev);
140
141  iop->data1 = dd;
142
143  if (dd != NULL)
144    return RTEMS_SUCCESSFUL;
145  else
146    return RTEMS_UNSATISFIED;
147}
148
149
150/* blkdev_generic_close --
151 *     Generic block device close primitive.
152 */
153rtems_device_driver
154rtems_blkdev_generic_close(
155    rtems_device_major_number major __attribute__((unused)),
156    rtems_device_minor_number minor __attribute__((unused)),
157    void                    * arg)
158{
159  rtems_libio_open_close_args_t *oc = arg;
160  rtems_libio_t *iop = oc->iop;
161  rtems_disk_device *dd = iop->data1;
162
163  rtems_disk_release(dd);
164
165  return RTEMS_SUCCESSFUL;
166}
167
168/* blkdev_generic_ioctl --
169 *     Generic block device ioctl primitive.
170 */
171rtems_device_driver
172rtems_blkdev_generic_ioctl(
173    rtems_device_major_number major __attribute__((unused)),
174    rtems_device_minor_number minor __attribute__((unused)),
175    void                    * arg)
176{
177    rtems_libio_ioctl_args_t *args = arg;
178    rtems_libio_t *iop = args->iop;
179    rtems_disk_device *dd = iop->data1;
180
181    if (args->command != RTEMS_BLKIO_REQUEST)
182    {
183        args->ioctl_return = dd->ioctl(dd,
184                                                  args->command,
185                                                  args->buffer);
186    }
187    else
188    {
189        /*
190         * It is not allowed to directly access the driver circumventing the
191         * cache.
192         */
193        args->ioctl_return = -1;
194    }
195
196    return RTEMS_SUCCESSFUL;
197}
Note: See TracBrowser for help on using the repository browser.