source: rtems/cpukit/libblock/include/rtems/blkdev.h @ 40284de

4.115
Last change on this file since 40284de was 40284de, checked in by Sebastian Huber <sebastian.huber@…>, on 05/30/12 at 10:43:56

libblock: Remove const qualifier from bdbuf API

This allows addtion of per disk statistics for example.

  • Property mode set to 100644
File size: 9.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
14#ifndef _RTEMS_BLKDEV_H
15#define _RTEMS_BLKDEV_H
16
17#include <rtems.h>
18#include <rtems/diskdevs.h>
19#include <sys/ioctl.h>
20
21#ifdef __cplusplus
22extern "C" {
23#endif
24
25/**
26 * @defgroup rtems_blkdev Block Device Management
27 *
28 * @ingroup rtems_libblock
29 *
30 * Interface between device drivers and the
31 * @ref rtems_bdbuf "block device buffer module".
32 *
33 * The heart of the block device driver is the @ref RTEMS_BLKIO_REQUEST IO
34 * control. This call puts IO @ref rtems_blkdev_request "requests" to the block
35 * device for asynchronous processing. When a driver executes a request, it
36 * invokes the request done callback function to finish the request.
37 *
38 * @{
39 */
40
41/**
42 * Block device request type.
43 *
44 * @warning The sync request is an IO one and only used from the cache. Use the
45 *          Block IO when operating at the device level. We need a sync request
46 *          to avoid requests looping for ever.
47 */
48typedef enum rtems_blkdev_request_op {
49  RTEMS_BLKDEV_REQ_READ,       /**< Read the requested blocks of data. */
50  RTEMS_BLKDEV_REQ_WRITE,      /**< Write the requested blocks of data. */
51  RTEMS_BLKDEV_REQ_SYNC        /**< Sync any data with the media. */
52} rtems_blkdev_request_op;
53
54/**
55 * @brief Block device request done callback function type.
56 *
57 * The first parameter @a arg must be the argument provided by the block device
58 * request structure @ref rtems_blkdev_request.
59 *
60 * The second parameter @a status should contain the status of the operation:
61 *  - @c RTEMS_SUCCESSFUL Operation was successful.
62 *  - @c RTEMS_IO_ERROR Some sort of input or output error.
63 *  - @c RTEMS_UNSATISFIED Media no more present.
64 */
65typedef void (*rtems_blkdev_request_cb)(void *arg, rtems_status_code status);
66
67/**
68 * Block device scatter or gather buffer structure.
69 */
70typedef struct rtems_blkdev_sg_buffer {
71  /**
72   * Block index.
73   */
74  rtems_blkdev_bnum block;
75
76  /**
77   * Buffer length.
78   */
79  uint32_t length;
80
81  /**
82   * Buffer pointer.
83   */
84  void *buffer;
85
86  /**
87   * User pointer.
88   */
89  void *user;
90} rtems_blkdev_sg_buffer;
91
92/**
93 * The block device request structure is used to read or write a number of
94 * blocks from or to the device.
95 *
96 * TODO: The use of these req blocks is not a great design. The req is a
97 *       struct with a single 'bufs' declared in the req struct and the
98 *       others are added in the outer level struct. This relies on the
99 *       structs joining as a single array and that assumes the compiler
100 *       packs the structs. Why not just place on a list ? The BD has a
101 *       node that can be used.
102 */
103typedef struct rtems_blkdev_request {
104  /**
105   * Block device operation (read or write).
106   */
107  rtems_blkdev_request_op req;
108
109  /**
110   * Request done callback function.
111   */
112  rtems_blkdev_request_cb req_done;
113
114  /**
115   * Argument to be passed to callback function.
116   */
117  void *done_arg;
118
119  /**
120   * Last IO operation completion status.
121   */
122  rtems_status_code status;
123
124  /**
125   * Number of blocks for this request.
126   */
127  uint32_t bufnum;
128
129  /**
130   * The task requesting the IO operation.
131   */
132  rtems_id io_task;
133
134  /**
135   * List of scatter or gather buffers.
136   */
137  rtems_blkdev_sg_buffer bufs[0];
138} rtems_blkdev_request;
139
140/**
141 * The start block in a request.
142 *
143 * Only valid if the driver has returned the @ref RTEMS_BLKIO_CAPABILITIES of
144 * @ref RTEMS_BLKDEV_CAP_MULTISECTOR_CONT.
145 */
146#define RTEMS_BLKDEV_START_BLOCK(req) (req->bufs[0].block)
147
148/**
149 * @name IO Control Request Codes
150 *
151 * @{
152 */
153
154#define RTEMS_BLKIO_REQUEST         _IOWR('B', 1, rtems_blkdev_request)
155#define RTEMS_BLKIO_GETMEDIABLKSIZE _IOR('B', 2, uint32_t)
156#define RTEMS_BLKIO_GETBLKSIZE      _IOR('B', 3, uint32_t)
157#define RTEMS_BLKIO_SETBLKSIZE      _IOW('B', 4, uint32_t)
158#define RTEMS_BLKIO_GETSIZE         _IOR('B', 5, rtems_blkdev_bnum)
159#define RTEMS_BLKIO_SYNCDEV         _IO('B', 6)
160#define RTEMS_BLKIO_DELETED         _IO('B', 7)
161#define RTEMS_BLKIO_CAPABILITIES    _IO('B', 8)
162#define RTEMS_BLKIO_GETDISKDEV      _IOR('B', 9, rtems_disk_device *)
163#define RTEMS_BLKIO_PURGEDEV        _IO('B', 10)
164
165/** @} */
166
167static inline int rtems_disk_fd_get_media_block_size(
168  int fd,
169  uint32_t *media_block_size
170)
171{
172  return ioctl(fd, RTEMS_BLKIO_GETMEDIABLKSIZE, media_block_size);
173}
174
175static inline int rtems_disk_fd_get_block_size(int fd, uint32_t *block_size)
176{
177  return ioctl(fd, RTEMS_BLKIO_GETBLKSIZE, block_size);
178}
179
180static inline int rtems_disk_fd_set_block_size(int fd, uint32_t block_size)
181{
182  return ioctl(fd, RTEMS_BLKIO_SETBLKSIZE, &block_size);
183}
184
185static inline int rtems_disk_fd_get_block_count(
186  int fd,
187  rtems_blkdev_bnum *block_count
188)
189{
190  return ioctl(fd, RTEMS_BLKIO_GETSIZE, block_count);
191}
192
193static inline int rtems_disk_fd_get_disk_device(
194  int fd,
195  rtems_disk_device **dd_ptr
196)
197{
198  return ioctl(fd, RTEMS_BLKIO_GETDISKDEV, dd_ptr);
199}
200
201static inline int rtems_disk_fd_sync(int fd)
202{
203  return ioctl(fd, RTEMS_BLKIO_SYNCDEV);
204}
205
206static inline int rtems_disk_fd_purge(int fd)
207{
208  return ioctl(fd, RTEMS_BLKIO_PURGEDEV);
209}
210
211/**
212 * Only consecutive multi-sector buffer requests are supported.
213 *
214 * This option means the cache will only supply multiple buffers that are
215 * inorder so the ATA multi-sector command for example can be used. This is a
216 * hack to work around the current ATA driver.
217 */
218#define RTEMS_BLKDEV_CAP_MULTISECTOR_CONT (1 << 0)
219
220/**
221 * The driver will accept a sync call. A sync call is made to a driver
222 * after a bdbuf cache sync has finished.
223 */
224#define RTEMS_BLKDEV_CAP_SYNC (1 << 1)
225
226/**
227 * The device driver interface conventions suppose that a driver may contain an
228 * initialize, open, close, read, write and IO control entry points. These
229 * primitives (except initialize) can be implemented in a generic fashion based
230 * upon the supplied block device driver IO control handler. Every block device
231 * driver should provide an initialize entry point, which registers the
232 * appropriate IO control handler.
233 */
234#define RTEMS_GENERIC_BLOCK_DEVICE_DRIVER_ENTRIES \
235  rtems_blkdev_generic_open, \
236  rtems_blkdev_generic_close, \
237  rtems_blkdev_generic_read, \
238  rtems_blkdev_generic_write, \
239  rtems_blkdev_generic_ioctl
240
241/**
242 * Generic block device read primitive.
243 *
244 * Implemented using block device buffer management primitives.
245 */
246rtems_device_driver
247rtems_blkdev_generic_read(
248    rtems_device_major_number major,
249    rtems_device_minor_number minor,
250    void                    * arg
251);
252
253/**
254 * Generic block device write primitive.
255 *
256 * Implemented using block device buffer management primitives.
257 */
258rtems_device_driver
259rtems_blkdev_generic_write(
260    rtems_device_major_number major,
261    rtems_device_minor_number minor,
262    void                    * arg
263);
264
265/**
266 * Generic block device open primitive.
267 *
268 * Implemented using block device buffer management primitives.
269 */
270rtems_device_driver
271rtems_blkdev_generic_open(
272    rtems_device_major_number major,
273    rtems_device_minor_number minor,
274    void                    * arg
275);
276
277/**
278 * Generic block device close primitive.
279 *
280 * Implemented using block device buffer management primitives.
281 */
282rtems_device_driver
283rtems_blkdev_generic_close(
284    rtems_device_major_number major,
285    rtems_device_minor_number minor,
286    void                    * arg
287);
288
289/**
290 * Generic block device IO control primitive.
291 *
292 * Implemented using block device buffer management primitives.
293 */
294rtems_device_driver
295rtems_blkdev_generic_ioctl(
296    rtems_device_major_number major,
297    rtems_device_minor_number minor,
298    void                    * arg
299);
300
301/**
302 * Common IO control primitive.
303 *
304 * Use this in all block devices to handle the common set of ioctl requests.
305 */
306int
307rtems_blkdev_ioctl(rtems_disk_device *dd, uint32_t req, void *argp);
308
309/**
310 * @brief Generic block operations driver address table.
311 */
312extern const rtems_driver_address_table rtems_blkdev_generic_ops;
313
314/**
315 * @brief Creates a block device.
316 *
317 * @param[in] device The path for the new block device.
318 * @param[in] block_size The block size.  Must be positive.
319 * @param[in] block_count The block count.  Must be positive.
320 * @param[in] handler The block device IO control handler.  Must not be @c NULL.
321 * @param[in] driver_data The block device driver data.
322 *
323 * @retval RTEMS_SUCCESSFUL Successful operation.
324 * @retval RTEMS_INVALID_NUMBER Block size or block count is not positive.
325 * @retval RTEMS_NO_MEMORY Not enough memory.
326 * @retval RTEMS_UNSATISFIED Cannot create generic device node.
327 */
328rtems_status_code rtems_blkdev_create(
329  const char *device,
330  uint32_t block_size,
331  rtems_blkdev_bnum block_count,
332  rtems_block_device_ioctl handler,
333  void *driver_data
334);
335
336/**
337 * @brief Creates a partition within a block device.
338 *
339 * A partition manages a subset of consecutive blocks contained in a block
340 * device.  The blocks must be within the range of blocks managed by the
341 * associated block device.  The media block size, block size, and IO control
342 * handler are inherited by the block device.
343 *
344 * @param[in] partition The path for the new partition device.
345 * @param[in] device The block device path.
346 * @param[in] block_begin The block begin of the partition.
347 * @param[in] block_count The block count of the partition.
348 *
349 * @retval RTEMS_SUCCESSFUL Successful operation.
350 * @retval RTEMS_INVALID_ID Block device node does not exist.
351 * @retval RTEMS_INVALID_NODE File system node is not a block device.
352 * @retval RTEMS_NOT_IMPLEMENTED Block device implementation is incomplete.
353 * @retval RTEMS_INVALID_NUMBER Block begin or block count is invalid.
354 * @retval RTEMS_NO_MEMORY Not enough memory.
355 * @retval RTEMS_UNSATISFIED Cannot create generic device node.
356 */
357rtems_status_code rtems_blkdev_create_partition(
358  const char *partition,
359  const char *device,
360  rtems_blkdev_bnum block_begin,
361  rtems_blkdev_bnum block_count
362);
363
364/** @} */
365
366#ifdef __cplusplus
367}
368#endif
369
370#endif
Note: See TracBrowser for help on using the repository browser.