summaryrefslogtreecommitdiffstats
path: root/cpukit/include/rtems/diskdevs.h
blob: 85d157dcd5293bdf3e801fe6127c471f104625a6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
/**
 * @file
 *
 * @brief Block Device Disk Management API
 *
 * @ingroup rtems_disk
 */

/*
 * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
 * Author: Victor V. Vengerov <vvv@oktet.ru>
 */

#ifndef _RTEMS_DISKDEVS_H
#define _RTEMS_DISKDEVS_H

#include <rtems.h>
#include <rtems/libio.h>
#include <rtems/chain.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef struct rtems_disk_device rtems_disk_device;

/**
 * @defgroup rtems_disk Block Device Disk Management
 *
 * @ingroup rtems_libblock
 *
 * @brief This module provides functions to manage disk devices.
 *
 * A disk is a set of blocks which are identified by a consecutive set of
 * non-negative integers starting at zero.  There are also logical disks which
 * contain a subset of consecutive disk blocks.  The logical disks are used to
 * represent the partitions of a disk.  The disk devices are accessed via the
 * @ref rtems_bdbuf "block device buffer module".
 */
/**@{**/

/**
 * @brief Block device block index type.
 */
typedef uint32_t rtems_blkdev_bnum;

/**
 * @brief Block device IO control handler type.
 */
typedef int (*rtems_block_device_ioctl)(
  rtems_disk_device *dd,
  uint32_t req,
  void *argp
);

/**
 * @brief Trigger value to disable further read-ahead requests.
 */
#define RTEMS_DISK_READ_AHEAD_NO_TRIGGER ((rtems_blkdev_bnum) -1)

/**
 * @brief Block device read-ahead control.
 */
typedef struct {
  /**
   * @brief Chain node for the read-ahead request queue of the read-ahead task.
   */
  rtems_chain_node node;

  /**
   * @brief Block value to trigger the read-ahead request.
   *
   * A value of @ref RTEMS_DISK_READ_AHEAD_NO_TRIGGER will disable further
   * read-ahead requests since no valid block can have this value.
   */
  rtems_blkdev_bnum trigger;

  /**
   * @brief Start block for the next read-ahead request.
   *
   * In case the trigger value is out of range of valid blocks, this value my
   * be arbitrary.
   */
  rtems_blkdev_bnum next;
} rtems_blkdev_read_ahead;

/**
 * @brief Block device statistics.
 *
 * Integer overflows in the statistic counters may happen.
 */
typedef struct {
  /**
   * @brief Read hit count.
   *
   * A read hit occurs in the rtems_bdbuf_read() function in case the block is
   * in the cached or modified state.
   */
  uint32_t read_hits;

  /**
   * @brief Read miss count.
   *
   * A read miss occurs in the rtems_bdbuf_read() function in case the block is
   * in the empty state and a read transfer must be initiated to read the data
   * from the device.
   */
  uint32_t read_misses;

  /**
   * @brief Read-ahead transfer count.
   *
   * Each read-ahead transfer may read multiple blocks.
   */
  uint32_t read_ahead_transfers;

  /**
   * @brief Count of blocks transfered from the device.
   */
  uint32_t read_blocks;

  /**
   * @brief Read error count.
   *
   * Error count of transfers issued by the read or read-ahead requests.
   */
  uint32_t read_errors;

  /**
   * @brief Write transfer count.
   *
   * Each write transfer may write multiple blocks.
   */
  uint32_t write_transfers;

  /**
   * @brief Count of blocks transfered to the device.
   */
  uint32_t write_blocks;

  /**
   * @brief Write error count.
   *
   * Error count of transfers issued by write requests.
   */
  uint32_t write_errors;
} rtems_blkdev_stats;

/**
 * @brief Description of a disk device (logical and physical disks).
 *
 * An array of pointer tables to rtems_disk_device structures is maintained.
 * The first table will be indexed by the major number and the second table
 * will be indexed by the minor number.  This allows quick lookup using a data
 * structure of moderated size.
 */
struct rtems_disk_device {
  /**
   * @brief Device identifier (concatenation of major and minor number).
   */
  dev_t dev;

  /**
   * @brief Physical device identifier (equals the @c dev entry if it specifies a
   * physical device).
   */
  rtems_disk_device *phys_dev;

  /**
   * @brief Driver capabilities.
   */
  uint32_t capabilities;

  /**
   * @brief Disk device name.
   */
  char *name;

  /**
   * @brief Usage counter.
   *
   * Devices cannot be deleted if they are in use.
   */
  unsigned uses;

  /**
   * @brief Start media block number.
   *
   * Equals zero for physical devices.  It is a media block offset to the
   * related physical device for logical device.
   */
  rtems_blkdev_bnum start;

  /**
   * @brief Size of the physical or logical disk in media blocks.
   */
  rtems_blkdev_bnum size;

  /**
   * @brief Media block size in bytes.
   *
   * This is the media transfer unit the hardware defaults to.
   */
  uint32_t media_block_size;

  /**
   * @brief Block size in bytes.
   *
   * This is the minimum transfer unit.  It may be a multiple of the media
   * block size. It must be positive.
   *
   * @see rtems_bdbuf_set_block_size().
   */
  uint32_t block_size;

  /**
   * @brief Block count.
   *
   * @see rtems_bdbuf_set_block_size().
   */
  rtems_blkdev_bnum block_count;

  /**
   * @brief Media blocks per device blocks.
   *
   * @see rtems_bdbuf_set_block_size().
   */
  uint32_t media_blocks_per_block;

  /**
   * @brief Block to media block shift.
   *
   * In case this value is non-negative the media block of a block can be
   * calculated as media block = block << block_to_media_block_shift, otherwise
   * a 64-bit operation will be used.
   *
   * @see rtems_bdbuf_set_block_size().
   */
  int block_to_media_block_shift;

  /**
   * @brief Buffer descriptors per group count.
   *
   * @see rtems_bdbuf_set_block_size().
   */
  size_t bds_per_group;

  /**
   * @brief IO control handler for this disk.
   */
  rtems_block_device_ioctl ioctl;

  /**
   * @brief Private data for the disk driver.
   */
  void *driver_data;

  /**
   * @brief Indicates that this disk should be deleted as soon as the last user
   * releases this disk.
   */
  bool deleted;

  /**
   * @brief Device statistics for this disk.
   */
  rtems_blkdev_stats stats;

  /**
   * @brief Read-ahead control for this disk.
   */
  rtems_blkdev_read_ahead read_ahead;
};

/**
 * @name Disk Device Data
 */
/**@{**/

/* Use fstat() instead */
RTEMS_DEPRECATED static inline dev_t rtems_disk_get_device_identifier(
  const rtems_disk_device *dd
)
{
  return dd->dev;
}

/* Use fstat() instead */
RTEMS_DEPRECATED static inline rtems_device_major_number rtems_disk_get_major_number(
  const rtems_disk_device *dd
)
{
  return rtems_filesystem_dev_major_t(dd->dev);
}

/* Use fstat() instead */
RTEMS_DEPRECATED static inline rtems_device_minor_number rtems_disk_get_minor_number(
  const rtems_disk_device *dd
)
{
  return rtems_filesystem_dev_minor_t(dd->dev);
}

static inline void *rtems_disk_get_driver_data(
  const rtems_disk_device *dd
)
{
  return dd->driver_data;
}

static inline uint32_t rtems_disk_get_media_block_size(
  const rtems_disk_device *dd
)
{
  return dd->media_block_size;
}

static inline uint32_t rtems_disk_get_block_size(
  const rtems_disk_device *dd
)
{
  return dd->block_size;
}

static inline rtems_blkdev_bnum rtems_disk_get_block_begin(
  const rtems_disk_device *dd
)
{
  return dd->start;
}

static inline rtems_blkdev_bnum rtems_disk_get_block_count(
  const rtems_disk_device *dd
)
{
  return dd->size;
}

/** @} */

/**
 * @name Disk Device Maintainance
 */
/**@{**/

/* Use rtems_blkdev_create() instead */
RTEMS_DEPRECATED rtems_status_code rtems_disk_create_phys(
  dev_t dev,
  uint32_t block_size,
  rtems_blkdev_bnum block_count,
  rtems_block_device_ioctl handler,
  void *driver_data,
  const char *name
);

/* Use rtems_blkdev_create_partition() instead */
RTEMS_DEPRECATED rtems_status_code rtems_disk_create_log(
  dev_t dev,
  dev_t phys,
  rtems_blkdev_bnum block_begin,
  rtems_blkdev_bnum block_count,
  const char *name
);

/*
 * Use rtems_blkdev_create() or rtems_blkdev_create_partition and unlink()
 * instead.
 */
RTEMS_DEPRECATED rtems_status_code rtems_disk_delete(dev_t dev);

/*
 * Use rtems_blkdev_create() or rtems_blkdev_create_partition and open()
 * instead.
 */
RTEMS_DEPRECATED rtems_disk_device *rtems_disk_obtain(dev_t dev);

/*
 * Use rtems_blkdev_create() or rtems_blkdev_create_partition and close()
 * instead.
 */
RTEMS_DEPRECATED rtems_status_code rtems_disk_release(rtems_disk_device *dd);

/** @} */

/**
 * @name Disk Management
 */
/**@{**/

/* Just remove calls to this function */
RTEMS_DEPRECATED rtems_status_code rtems_disk_io_initialize(void);

/* Just remove calls to this function */
RTEMS_DEPRECATED rtems_status_code rtems_disk_io_done(void);

/** @} */

/** @} */

/*
 * This functionality no longer available.  There is no global registration for
 * disk devices.
 */
RTEMS_DEPRECATED rtems_disk_device *rtems_disk_next(dev_t dev);

/* Internal function, do not use */
rtems_status_code rtems_disk_init_phys(
  rtems_disk_device *dd,
  uint32_t block_size,
  rtems_blkdev_bnum block_count,
  rtems_block_device_ioctl handler,
  void *driver_data
);

/* Internal function, do not use */
rtems_status_code rtems_disk_init_log(
  rtems_disk_device *dd,
  rtems_disk_device *phys_dd,
  rtems_blkdev_bnum block_begin,
  rtems_blkdev_bnum block_count
);

#ifdef __cplusplus
}
#endif

#endif