source: rtems/cpukit/libblock/include/rtems/diskdevs.h @ d8ec270b

5
Last change on this file since d8ec270b was d8ec270b, checked in by Sebastian Huber <sebastian.huber@…>, on 04/07/16 at 08:29:09

libblock: Drop superfluous <stdlib.h> include

Drop superfluous <stdlib.h> include from <rtems/diskdevs.h> since this
leads to conflicts with the latest Newlib in case this header file is
used in the FreeBSD kernel space, e.g. for USB mass storage support.

  • Property mode set to 100644
File size: 12.6 KB
Line 
1/**
2 * @file
3 *
4 * @brief Block Device Disk Management API
5 *
6 * @ingroup rtems_disk
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_DISKDEVS_H
15#define _RTEMS_DISKDEVS_H
16
17#include <rtems.h>
18#include <rtems/libio.h>
19#include <rtems/chain.h>
20
21#ifdef __cplusplus
22extern "C" {
23#endif
24
25typedef struct rtems_disk_device rtems_disk_device;
26
27/**
28 * @defgroup rtems_disk Block Device Disk Management
29 *
30 * @ingroup rtems_libblock
31 *
32 * @brief This module provides functions to manage disk devices.
33 *
34 * A disk is a set of blocks which are identified by a consecutive set of
35 * non-negative integers starting at zero.  There are also logical disks which
36 * contain a subset of consecutive disk blocks.  The logical disks are used to
37 * represent the partitions of a disk.  The disk devices are accessed via the
38 * @ref rtems_bdbuf "block device buffer module".
39 */
40/**@{**/
41
42/**
43 * @brief Block device block index type.
44 */
45typedef uint32_t rtems_blkdev_bnum;
46
47/**
48 * @brief Block device IO control handler type.
49 */
50typedef int (*rtems_block_device_ioctl)(
51  rtems_disk_device *dd,
52  uint32_t req,
53  void *argp
54);
55
56/**
57 * @brief Trigger value to disable further read-ahead requests.
58 */
59#define RTEMS_DISK_READ_AHEAD_NO_TRIGGER ((rtems_blkdev_bnum) -1)
60
61/**
62 * @brief Block device read-ahead control.
63 */
64typedef struct {
65  /**
66   * @brief Chain node for the read-ahead request queue of the read-ahead task.
67   */
68  rtems_chain_node node;
69
70  /**
71   * @brief Block value to trigger the read-ahead request.
72   *
73   * A value of @ref RTEMS_DISK_READ_AHEAD_NO_TRIGGER will disable further
74   * read-ahead requests since no valid block can have this value.
75   */
76  rtems_blkdev_bnum trigger;
77
78  /**
79   * @brief Start block for the next read-ahead request.
80   *
81   * In case the trigger value is out of range of valid blocks, this value my
82   * be arbitrary.
83   */
84  rtems_blkdev_bnum next;
85} rtems_blkdev_read_ahead;
86
87/**
88 * @brief Block device statistics.
89 *
90 * Integer overflows in the statistic counters may happen.
91 */
92typedef struct {
93  /**
94   * @brief Read hit count.
95   *
96   * A read hit occurs in the rtems_bdbuf_read() function in case the block is
97   * in the cached or modified state.
98   */
99  uint32_t read_hits;
100
101  /**
102   * @brief Read miss count.
103   *
104   * A read miss occurs in the rtems_bdbuf_read() function in case the block is
105   * in the empty state and a read transfer must be initiated to read the data
106   * from the device.
107   */
108  uint32_t read_misses;
109
110  /**
111   * @brief Read-ahead transfer count.
112   *
113   * Each read-ahead transfer may read multiple blocks.
114   */
115  uint32_t read_ahead_transfers;
116
117  /**
118   * @brief Count of blocks transfered from the device.
119   */
120  uint32_t read_blocks;
121
122  /**
123   * @brief Read error count.
124   *
125   * Error count of transfers issued by the read or read-ahead requests.
126   */
127  uint32_t read_errors;
128
129  /**
130   * @brief Write transfer count.
131   *
132   * Each write transfer may write multiple blocks.
133   */
134  uint32_t write_transfers;
135
136  /**
137   * @brief Count of blocks transfered to the device.
138   */
139  uint32_t write_blocks;
140
141  /**
142   * @brief Write error count.
143   *
144   * Error count of transfers issued by write requests.
145   */
146  uint32_t write_errors;
147} rtems_blkdev_stats;
148
149/**
150 * @brief Description of a disk device (logical and physical disks).
151 *
152 * An array of pointer tables to rtems_disk_device structures is maintained.
153 * The first table will be indexed by the major number and the second table
154 * will be indexed by the minor number.  This allows quick lookup using a data
155 * structure of moderated size.
156 */
157struct rtems_disk_device {
158  /**
159   * @brief Device identifier (concatenation of major and minor number).
160   */
161  dev_t dev;
162
163  /**
164   * @brief Physical device identifier (equals the @c dev entry if it specifies a
165   * physical device).
166   */
167  rtems_disk_device *phys_dev;
168
169  /**
170   * @brief Driver capabilities.
171   */
172  uint32_t capabilities;
173
174  /**
175   * @brief Disk device name.
176   */
177  char *name;
178
179  /**
180   * @brief Usage counter.
181   *
182   * Devices cannot be deleted if they are in use.
183   */
184  unsigned uses;
185
186  /**
187   * @brief Start media block number.
188   *
189   * Equals zero for physical devices.  It is a media block offset to the
190   * related physical device for logical device.
191   */
192  rtems_blkdev_bnum start;
193
194  /**
195   * @brief Size of the physical or logical disk in media blocks.
196   */
197  rtems_blkdev_bnum size;
198
199  /**
200   * @brief Media block size in bytes.
201   *
202   * This is the media transfer unit the hardware defaults to.
203   */
204  uint32_t media_block_size;
205
206  /**
207   * @brief Block size in bytes.
208   *
209   * This is the minimum transfer unit.  It may be a multiple of the media
210   * block size. It must be positive.
211   *
212   * @see rtems_bdbuf_set_block_size().
213   */
214  uint32_t block_size;
215
216  /**
217   * @brief Block count.
218   *
219   * @see rtems_bdbuf_set_block_size().
220   */
221  rtems_blkdev_bnum block_count;
222
223  /**
224   * @brief Media blocks per device blocks.
225   *
226   * @see rtems_bdbuf_set_block_size().
227   */
228  uint32_t media_blocks_per_block;
229
230  /**
231   * @brief Block to media block shift.
232   *
233   * In case this value is non-negative the media block of a block can be
234   * calculated as media block = block << block_to_media_block_shift, otherwise
235   * a 64-bit operation will be used.
236   *
237   * @see rtems_bdbuf_set_block_size().
238   */
239  int block_to_media_block_shift;
240
241  /**
242   * @brief Buffer descriptors per group count.
243   *
244   * @see rtems_bdbuf_set_block_size().
245   */
246  size_t bds_per_group;
247
248  /**
249   * @brief IO control handler for this disk.
250   */
251  rtems_block_device_ioctl ioctl;
252
253  /**
254   * @brief Private data for the disk driver.
255   */
256  void *driver_data;
257
258  /**
259   * @brief Indicates that this disk should be deleted as soon as the last user
260   * releases this disk.
261   */
262  bool deleted;
263
264  /**
265   * @brief Device statistics for this disk.
266   */
267  rtems_blkdev_stats stats;
268
269  /**
270   * @brief Read-ahead control for this disk.
271   */
272  rtems_blkdev_read_ahead read_ahead;
273};
274
275/**
276 * @name Disk Device Data
277 */
278/**@{**/
279
280static inline dev_t rtems_disk_get_device_identifier(
281  const rtems_disk_device *dd
282)
283{
284  return dd->dev;
285}
286
287static inline rtems_device_major_number rtems_disk_get_major_number(
288  const rtems_disk_device *dd
289)
290{
291  return rtems_filesystem_dev_major_t(dd->dev);
292}
293
294static inline rtems_device_minor_number rtems_disk_get_minor_number(
295  const rtems_disk_device *dd
296)
297{
298  return rtems_filesystem_dev_minor_t(dd->dev);
299}
300
301static inline void *rtems_disk_get_driver_data(
302  const rtems_disk_device *dd
303)
304{
305  return dd->driver_data;
306}
307
308static inline uint32_t rtems_disk_get_media_block_size(
309  const rtems_disk_device *dd
310)
311{
312  return dd->media_block_size;
313}
314
315static inline uint32_t rtems_disk_get_block_size(
316  const rtems_disk_device *dd
317)
318{
319  return dd->block_size;
320}
321
322static inline rtems_blkdev_bnum rtems_disk_get_block_begin(
323  const rtems_disk_device *dd
324)
325{
326  return dd->start;
327}
328
329static inline rtems_blkdev_bnum rtems_disk_get_block_count(
330  const rtems_disk_device *dd
331)
332{
333  return dd->size;
334}
335
336/** @} */
337
338/**
339 * @name Disk Device Maintainance
340 */
341/**@{**/
342
343/**
344 * @brief Creates a physical disk with device identifier @a dev.
345 *
346 * The block size @a block_size must be positive.  The disk will have
347 * @a block_count blocks.  The block index starts with zero.  The associated disk
348 * device driver will be invoked via the IO control handler @a handler.  A
349 * device node will be registered in the file system with absolute path @a
350 * name, if @a name is not @c NULL.  This function is usually invoked from a
351 * block device driver during initialization when a physical device is detected
352 * in the system.  The device driver provides an IO control handler to allow
353 * block device operations.
354 *
355 * @retval RTEMS_SUCCESSFUL Successful operation.
356 * @retval RTEMS_NOT_CONFIGURED Cannot lock disk device operation mutex.
357 * @retval RTEMS_INVALID_ADDRESS IO control handler is @c NULL.
358 * @retval RTEMS_INVALID_NUMBER Block size is invalid.
359 * @retval RTEMS_NO_MEMORY Not enough memory.
360 * @retval RTEMS_RESOURCE_IN_USE Disk device descriptor is already in use.
361 * @retval RTEMS_UNSATISFIED Cannot create device node.
362 */
363rtems_status_code rtems_disk_create_phys(
364  dev_t dev,
365  uint32_t block_size,
366  rtems_blkdev_bnum block_count,
367  rtems_block_device_ioctl handler,
368  void *driver_data,
369  const char *name
370);
371
372/**
373 * @brief Creates a logical disk with device identifier @a dev.
374 *
375 * A logical disk manages a subset of consecutive blocks contained in the
376 * physical disk with identifier @a phys.  The start block index of the logical
377 * disk device is @a block_begin.  The block count of the logcal disk will be
378 * @a block_count.  The blocks must be within the range of blocks managed by
379 * the associated physical disk device.  A device node will be registered in
380 * the file system with absolute path @a name, if @a name is not @c NULL.  The
381 * block size and IO control handler are inherited by the physical disk.
382 *
383 * @retval RTEMS_SUCCESSFUL Successful operation.
384 * @retval RTEMS_NOT_CONFIGURED Cannot lock disk device operation mutex.
385 * @retval RTEMS_INVALID_ID Specified physical disk identifier does not
386 * correspond to a physical disk.
387 * @retval RTEMS_INVALID_NUMBER Begin block or block count are out of range.
388 * @retval RTEMS_NO_MEMORY Not enough memory.
389 * @retval RTEMS_RESOURCE_IN_USE Disk device descriptor for logical disk
390 * identifier is already in use.
391 * @retval RTEMS_UNSATISFIED Cannot create device node.
392 */
393rtems_status_code rtems_disk_create_log(
394  dev_t dev,
395  dev_t phys,
396  rtems_blkdev_bnum block_begin,
397  rtems_blkdev_bnum block_count,
398  const char *name
399);
400
401/**
402 * @brief Deletes a physical or logical disk device with identifier @a dev.
403 *
404 * Marks the disk device as deleted.  When a physical disk device is deleted,
405 * all corresponding logical disk devices will marked as deleted too.  Disks
406 * that are marked as deleted and have a usage counter of zero will be deleted.
407 * The corresponding device nodes will be removed from the file system.  In
408 * case of a physical disk deletion the IO control handler will be invoked with
409 * a RTEMS_BLKIO_DELETED request.  Disks that are still in use will be deleted
410 * upon release.
411 *
412 * @retval RTEMS_SUCCESSFUL Successful operation.
413 * @retval RTEMS_NOT_CONFIGURED Cannot lock disk device operation mutex.
414 * @retval RTEMS_INVALID_ID No disk for specified device identifier.
415 */
416rtems_status_code rtems_disk_delete(dev_t dev);
417
418/**
419 * @brief Returns the disk device descriptor for the device identifier @a dev.
420 *
421 * Increments usage counter by one.  You should release the disk device
422 * descriptor with rtems_disk_release().
423 *
424 * @return Pointer to the disk device descriptor or @c NULL if no corresponding
425 * disk exists.
426 */
427rtems_disk_device *rtems_disk_obtain(dev_t dev);
428
429/**
430 * @brief Releases the disk device descriptor @a dd.
431 *
432 * Decrements usage counter by one.
433 *
434 * @retval RTEMS_SUCCESSFUL Successful operation.
435 */
436rtems_status_code rtems_disk_release(rtems_disk_device *dd);
437
438/** @} */
439
440/**
441 * @name Disk Management
442 */
443/**@{**/
444
445/**
446 * @brief Initializes the disk device management.
447 *
448 * This functions returns successful if the disk device management is already
449 * initialized.  There is no protection against concurrent access.
450 *
451 * @retval RTEMS_SUCCESSFUL Successful initialization.
452 * @retval RTEMS_NO_MEMORY Not enough memory or no semaphore available.
453 * @retval RTEMS_UNSATISFIED Block device buffer initialization failed.
454 */
455rtems_status_code rtems_disk_io_initialize(void);
456
457/**
458 * @brief Releases all resources allocated for disk device management.
459 *
460 * There is no protection against concurrent access.  If parts of the system
461 * are still in use the behaviour is undefined.
462 *
463 * @retval RTEMS_SUCCESSFUL Successful operation.
464 */
465rtems_status_code rtems_disk_io_done(void);
466
467/** @} */
468
469/** @} */
470
471/**
472 * @brief Disk device iterator.
473 *
474 * Returns the next disk device descriptor with a device identifier larger than
475 * @a dev.  If there is no such device, @c NULL will be returned.  Use minus
476 * one to start the search.
477 *
478 * @code
479 * rtems_status_code sc = RTEMS_SUCCESSFUL;
480 * rtems_disk_device *dd = (dev_t) -1;
481 *
482 * while (sc == RTEMS_SUCCESSFUL && (dd = rtems_disk_next(dev)) != NULL) {
483 *   dev = rtems_disk_get_device_identifier(dd);
484 *   sc = rtems_disk_release(dd);
485 * }
486 * @endcode
487 */
488rtems_disk_device *rtems_disk_next(dev_t dev);
489
490/* Internal function, do not use */
491rtems_status_code rtems_disk_init_phys(
492  rtems_disk_device *dd,
493  uint32_t block_size,
494  rtems_blkdev_bnum block_count,
495  rtems_block_device_ioctl handler,
496  void *driver_data
497);
498
499/* Internal function, do not use */
500rtems_status_code rtems_disk_init_log(
501  rtems_disk_device *dd,
502  rtems_disk_device *phys_dd,
503  rtems_blkdev_bnum block_begin,
504  rtems_blkdev_bnum block_count
505);
506
507#ifdef __cplusplus
508}
509#endif
510
511#endif
Note: See TracBrowser for help on using the repository browser.