source: rtems/cpukit/include/rtems/blkdev.h @ 0b038bd4

Last change on this file since 0b038bd4 was 0b038bd4, checked in by Sebastian Huber <sebastian.huber@…>, on Aug 4, 2018 at 8:38:48 AM

libblock: Add RTEMS_DEPRECATED

Close #3358.

  • Property mode set to 100644
File size: 11.7 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/print.h>
20#include <sys/ioccom.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[RTEMS_ZERO_LENGTH_ARRAY];
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 * @retval RTEMS_INCORRECT_STATE Cannot initialize bdbuf.
300 *
301 * @see rtems_blkdev_create_partition(), rtems_bdbuf_set_block_size(), and
302 * rtems_blkdev_request.
303 */
304rtems_status_code rtems_blkdev_create(
305  const char *device,
306  uint32_t media_block_size,
307  rtems_blkdev_bnum media_block_count,
308  rtems_block_device_ioctl handler,
309  void *driver_data
310);
311
312/**
313 * @brief Creates a partition within a parent block device.
314 *
315 * A partition manages a subset of consecutive blocks contained in a parent block
316 * device.  The blocks must be within the range of blocks managed by the
317 * associated parent block device.  The media block size and IO control
318 * handler are inherited by the parent block device.  The block size is set to
319 * the media block size.
320 *
321 * @param[in] partition The path for the new partition device.
322 * @param[in] parent_block_device The parent block device path.
323 * @param[in] media_block_begin The media block begin of the partition within
324 * the parent block device.
325 * @param[in] media_block_count The media block count of the partition.
326 *
327 * @retval RTEMS_SUCCESSFUL Successful operation.
328 * @retval RTEMS_INVALID_ID Block device node does not exist.
329 * @retval RTEMS_INVALID_NODE File system node is not a block device.
330 * @retval RTEMS_NOT_IMPLEMENTED Block device implementation is incomplete.
331 * @retval RTEMS_INVALID_NUMBER Block begin or block count is invalid.
332 * @retval RTEMS_NO_MEMORY Not enough memory.
333 * @retval RTEMS_UNSATISFIED Cannot create generic device node.
334 *
335 * @see rtems_blkdev_create() and rtems_bdbuf_set_block_size().
336 */
337rtems_status_code rtems_blkdev_create_partition(
338  const char *partition,
339  const char *parent_block_device,
340  rtems_blkdev_bnum media_block_begin,
341  rtems_blkdev_bnum media_block_count
342);
343
344/**
345 * @brief Prints the block device statistics.
346 */
347void rtems_blkdev_print_stats(
348  const rtems_blkdev_stats *stats,
349  uint32_t media_block_size,
350  uint32_t media_block_count,
351  uint32_t block_size,
352  const rtems_printer* printer
353);
354
355/**
356 * @brief Block device statistics command.
357 */
358void rtems_blkstats(
359  const rtems_printer *printer,
360  const char *device,
361  bool reset
362);
363
364/** @} */
365
366/**
367 * @defgroup rtems_blkdev_generic Generic Disk Device
368 *
369 * @ingroup rtems_blkdev
370 *
371 * Generic disk device operations for standard RTEMS IO drivers.
372 */
373/**@{**/
374
375/**
376 * The device driver interface conventions suppose that a driver may contain an
377 * initialize, open, close, read, write and IO control entry points. These
378 * primitives (except initialize) can be implemented in a generic fashion based
379 * upon the supplied block device driver IO control handler. Every block device
380 * driver should provide an initialize entry point, which registers the
381 * appropriate IO control handler.
382 */
383#define RTEMS_GENERIC_BLOCK_DEVICE_DRIVER_ENTRIES \
384  rtems_blkdev_generic_open, \
385  rtems_blkdev_generic_close, \
386  rtems_blkdev_generic_read, \
387  rtems_blkdev_generic_write, \
388  rtems_blkdev_generic_ioctl
389
390/* Use rtems_blkdev_create() instead */
391RTEMS_DEPRECATED rtems_device_driver
392rtems_blkdev_generic_read(
393    rtems_device_major_number major,
394    rtems_device_minor_number minor,
395    void                    * arg
396);
397
398/* Use rtems_blkdev_create() instead */
399RTEMS_DEPRECATED rtems_device_driver
400rtems_blkdev_generic_write(
401    rtems_device_major_number major,
402    rtems_device_minor_number minor,
403    void                    * arg
404);
405
406/* Use rtems_blkdev_create() instead */
407RTEMS_DEPRECATED rtems_device_driver
408rtems_blkdev_generic_open(
409    rtems_device_major_number major,
410    rtems_device_minor_number minor,
411    void                    * arg
412);
413
414/* Use rtems_blkdev_create() instead */
415RTEMS_DEPRECATED rtems_device_driver
416rtems_blkdev_generic_close(
417    rtems_device_major_number major,
418    rtems_device_minor_number minor,
419    void                    * arg
420);
421
422/* Use rtems_blkdev_create() instead */
423RTEMS_DEPRECATED rtems_device_driver
424rtems_blkdev_generic_ioctl(
425    rtems_device_major_number major,
426    rtems_device_minor_number minor,
427    void                    * arg
428);
429
430/* Use rtems_blkdev_create() instead */
431RTEMS_DEPRECATED extern const rtems_driver_address_table rtems_blkdev_generic_ops;
432
433/** @} */
434
435#ifdef __cplusplus
436}
437#endif
438
439#endif
Note: See TracBrowser for help on using the repository browser.