source: rtems/cpukit/libblock/include/rtems/blkdev.h @ 9de9b7d2

4.115
Last change on this file since 9de9b7d2 was b697bc6, checked in by Joel Sherrill <joel.sherrill@…>, on 01/10/13 at 21:06:42

cpukit: Use Consistent Beginning of Doxygen Group Notation

This is the result of a sed script which converts all uses
of @{ into a consistent form.

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