/** * @file * * @brief Block Device Disk Management API * * @ingroup rtems_disk */ /* * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia * Author: Victor V. Vengerov */ #ifndef _RTEMS_DISKDEVS_H #define _RTEMS_DISKDEVS_H #include #include #include #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