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

4.115
Last change on this file since f11858ac was 9f527308, checked in by Sebastian Huber <sebastian.huber@…>, on 06/12/12 at 07:46:09

libblock: Add block device statistics

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