summaryrefslogtreecommitdiffstats
path: root/cpukit/libblock/include/rtems/flashdisk.h
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/libblock/include/rtems/flashdisk.h')
-rw-r--r--cpukit/libblock/include/rtems/flashdisk.h366
1 files changed, 366 insertions, 0 deletions
diff --git a/cpukit/libblock/include/rtems/flashdisk.h b/cpukit/libblock/include/rtems/flashdisk.h
new file mode 100644
index 0000000000..c24b9b08be
--- /dev/null
+++ b/cpukit/libblock/include/rtems/flashdisk.h
@@ -0,0 +1,366 @@
+/*
+ * flashdisk.h -- Flash disk block device implementation
+ *
+ * Copyright (C) 2007 Chris Johns
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if !defined (_RTEMS_FLASHDISK_H_)
+#define _RTEMS_FLASHDISK_H_
+
+#include <stdint.h>
+#include <sys/ioctl.h>
+
+#include <rtems.h>
+
+/**
+ * The base name of the flash disks.
+ */
+#define RTEMS_FLASHDISK_DEVICE_BASE_NAME "/dev/fdd"
+
+/**
+ * Flash disk specific ioctl request types. To use open the
+ * device and issue the ioctl call.
+ *
+ * @code
+ * int fd = open ("/dev/flashdisk0", O_WRONLY, 0);
+ * if (fd < 0)
+ * {
+ * printf ("driver open failed: %s\n", strerror (errno));
+ * exit (1);
+ * }
+ * if (ioctl (fd, RTEMS_FDISK_IOCTL_ERASE_DISK) < 0)
+ * {
+ * printf ("driver erase failed: %s\n", strerror (errno));
+ * exit (1);
+ * }
+ * close (fd);
+ * @endcode
+ */
+#define RTEMS_FDISK_IOCTL_ERASE_DISK _IO('B', 128)
+#define RTEMS_FDISK_IOCTL_COMPACT _IO('B', 129)
+#define RTEMS_FDISK_IOCTL_ERASE_USED _IO('B', 130)
+#define RTEMS_FDISK_IOCTL_MONITORING _IO('B', 131)
+#define RTEMS_FDISK_IOCTL_INFO_LEVEL _IO('B', 132)
+#define RTEMS_FDISK_IOCTL_PRINT_STATUS _IO('B', 133)
+
+/**
+ * Flash Disk Monitoring Data allows a user to obtain
+ * the current status of the disk.
+ */
+typedef struct rtems_fdisk_monitor_data
+{
+ uint32_t block_size;
+ uint32_t block_count;
+ uint32_t unavail_blocks;
+ uint32_t device_count;
+ uint32_t segment_count;
+ uint32_t page_count;
+ uint32_t blocks_used;
+ uint32_t segs_available;
+ uint32_t segs_used;
+ uint32_t segs_failed;
+ uint32_t seg_erases;
+ uint32_t pages_desc;
+ uint32_t pages_active;
+ uint32_t pages_used;
+ uint32_t pages_bad;
+ uint32_t info_level;
+} rtems_fdisk_monitor_data;
+
+/**
+ * Flash Segment Descriptor holds, number of continuous segments in the
+ * device of this type, the base segment number in the device, the
+ * address offset of the base segment in the device, and the size of
+ * segment.
+ *
+ * Typically this structure is part of a table of segments in the
+ * device which is referenced in the flash disk configuration table.
+ * The reference is kept in the driver and used all the time to
+ * manage the flash device, therefore it must always exist.
+ */
+typedef struct rtems_fdisk_segment_desc
+{
+ uint16_t count; /**< Number of segments of this type in a row. */
+ uint16_t segment; /**< The base segment number. */
+ uint32_t offset; /**< Address offset of base segment in device. */
+ uint32_t size; /**< Size of the segment in bytes. */
+} rtems_fdisk_segment_desc;
+
+/**
+ * Return the number of kilo-bytes.
+ */
+#define RTEMS_FDISK_KBYTES(_k) (UINT32_C(1024) * (_k))
+
+/**
+ * Forward declaration of the device descriptor.
+ */
+struct rtems_fdisk_device_desc;
+
+/**
+ * Flash Low Level driver handlers.
+
+ * Typically this structure is part of a table of handlers in the
+ * device which is referenced in the flash disk configuration table.
+ * The reference is kept in the driver and used all the time to
+ * manage the flash device, therefore it must always exist.
+ */
+typedef struct rtems_fdisk_driver_handlers
+{
+ /**
+ * Read data from the device into the buffer. Return an errno
+ * error number if the device cannot be read. A segment descriptor
+ * can describe more than one segment in a device if the device has
+ * repeating segments. The segment number is the device segment to
+ * access and the segment descriptor must reference the segment
+ * being requested. For example the segment number must resided in
+ * the range [base, base + count).
+ *
+ * @param sd The segment descriptor.
+ * @param device The device to read data from.
+ * @param segment The segment within the device to read.
+ * @param offset The offset in the segment to read.
+ * @param buffer The buffer to read the data into.
+ * @param size The amount of data to read.
+ * @retval 0 No error.
+ * @retval EIO The read did not complete.
+ */
+ int (*read) (const rtems_fdisk_segment_desc* sd,
+ uint32_t device,
+ uint32_t segment,
+ uint32_t offset,
+ void* buffer,
+ uint32_t size);
+
+ /**
+ * Write data from the buffer to the device. Return an errno
+ * error number if the device cannot be written to. A segment
+ * descriptor can describe more than segment in a device if the
+ * device has repeating segments. The segment number is the device
+ * segment to access and the segment descriptor must reference
+ * the segment being requested. For example the segment number must
+ * resided in the range [base, base + count).
+ *
+ * @param sd The segment descriptor.
+ * @param device The device to write data from.
+ * @param segment The segment within the device to write to.
+ * @param offset The offset in the segment to write.
+ * @param buffer The buffer to write the data from.
+ * @param size The amount of data to write.
+ * @retval 0 No error.
+ * @retval EIO The write did not complete or verify.
+ */
+ int (*write) (const rtems_fdisk_segment_desc* sd,
+ uint32_t device,
+ uint32_t segment,
+ uint32_t offset,
+ const void* buffer,
+ uint32_t size);
+
+ /**
+ * Blank a segment in the device. Return an errno error number
+ * if the device cannot be read or is not blank. A segment descriptor
+ * can describe more than segment in a device if the device has
+ * repeating segments. The segment number is the device segment to
+ * access and the segment descriptor must reference the segment
+ * being requested. For example the segment number must resided in
+ * the range [base, base + count).
+ *
+ * @param sd The segment descriptor.
+ * @param device The device to read data from.
+ * @param segment The segment within the device to read.
+ * @param offset The offset in the segment to checl.
+ * @param size The amount of data to check.
+ * @retval 0 No error.
+ * @retval EIO The segment is not blank.
+ */
+ int (*blank) (const rtems_fdisk_segment_desc* sd,
+ uint32_t device,
+ uint32_t segment,
+ uint32_t offset,
+ uint32_t size);
+
+ /**
+ * Verify data in the buffer to the data in the device. Return an
+ * errno error number if the device cannot be read. A segment
+ * descriptor can describe more than segment in a device if the
+ * device has repeating segments. The segment number is the
+ * segment to access and the segment descriptor must reference
+ * the device segment being requested. For example the segment number
+ * must resided in the range [base, base + count).
+ *
+ * @param sd The segment descriptor.
+ * @param device The device to verify data in.
+ * @param segment The segment within the device to verify.
+ * @param offset The offset in the segment to verify.
+ * @param buffer The buffer to verify the data in the device with.
+ * @param size The amount of data to verify.
+ * @retval 0 No error.
+ * @retval EIO The data did not verify.
+ */
+ int (*verify) (const rtems_fdisk_segment_desc* sd,
+ uint32_t device,
+ uint32_t segment,
+ uint32_t offset,
+ const void* buffer,
+ uint32_t size);
+
+ /**
+ * Erase the segment. Return an errno error number if the
+ * segment cannot be erased. A segment descriptor can describe
+ * more than segment in a device if the device has repeating
+ * segments. The segment number is the device segment to access and
+ * the segment descriptor must reference the segment being requested.
+ *
+ * @param sd The segment descriptor.
+ * @param device The device to erase the segment of.
+ * @param segment The segment within the device to erase.
+ * @retval 0 No error.
+ * @retval EIO The segment was not erased.
+ */
+ int (*erase) (const rtems_fdisk_segment_desc* sd,
+ uint32_t device,
+ uint32_t segment);
+
+ /**
+ * Erase the device. Return an errno error number if the
+ * segment cannot be erased. A segment descriptor can describe
+ * more than segment in a device if the device has repeating
+ * segments. The segment number is the segment to access and
+ * the segment descriptor must reference the segment being requested.
+ *
+ * @param sd The segment descriptor.
+ * @param device The device to erase.
+ * @retval 0 No error.
+ * @retval EIO The device was not erased.
+ */
+ int (*erase_device) (const struct rtems_fdisk_device_desc* dd,
+ uint32_t device);
+
+} rtems_fdisk_driver_handlers;
+
+/**
+ * Flash Device Descriptor holds the segments in a device. The
+ * placing of the segments in a device decriptor allows the
+ * low level driver to share the segment descriptors for a
+ * number of devices.
+ *
+ * Typically this structure is part of a table of segments in the
+ * device which is referenced in the flash disk configuration table.
+ * The reference is kept in the driver and used all the time to
+ * manage the flash device, therefore it must always exist.
+ */
+typedef struct rtems_fdisk_device_desc
+{
+ uint32_t segment_count; /**< Number of segments. */
+ const rtems_fdisk_segment_desc* segments; /**< Array of segments. */
+ const rtems_fdisk_driver_handlers* flash_ops; /**< Device handlers. */
+} rtems_fdisk_device_desc;
+
+/**
+ * RTEMS Flash Disk configuration table used to initialise the
+ * driver.
+ *
+ * The unavailable blocks count is the number of blocks less than the
+ * available number of blocks the file system is given. This means there
+ * will always be that number of blocks available when the file system
+ * thinks the disk is full. The compaction code needs blocks to compact
+ * with so you will never be able to have all the blocks allocated to the
+ * file system and be able to full the disk.
+ *
+ * The compacting segment count is the number of segments that are
+ * moved into a new segment. A high number will mean more segments with
+ * low active page counts and high used page counts will be moved into
+ * avaliable pages how-ever this extends the compaction time due to
+ * time it takes the erase the pages. There is no pont making this number
+ * greater than the maximum number of pages in a segment.
+ *
+ * The available compacting segment count is the level when compaction occurs
+ * when writing. If you set this to 0 then compaction will fail because
+ * there will be no segments to compact into.
+ *
+ * The info level can be 0 for off with error, and abort messages allowed.
+ * Level 1 is warning messages, level 1 is informational messages, and level 3
+ * is debugging type prints. The info level can be turned off with a compile
+ * time directive on the command line to the compiler of:
+ *
+ * -DRTEMS_FDISK_TRACE=0
+ */
+typedef struct rtems_flashdisk_config
+{
+ uint32_t block_size; /**< The block size. */
+ uint32_t device_count; /**< The number of devices. */
+ const rtems_fdisk_device_desc* devices; /**< The device descriptions. */
+ uint32_t flags; /**< Set of flags to control
+ driver. */
+ uint32_t unavail_blocks; /**< Number of blocks not
+ available to the file sys. */
+ uint32_t compact_segs; /**< Max number of segs to
+ compact in one pass. */
+ uint32_t avail_compact_segs; /**< The number of segments
+ when compaction occurs
+ when writing. */
+ uint32_t info_level; /**< Default info level. */
+} rtems_flashdisk_config;
+
+/*
+ * Driver flags.
+ */
+
+/**
+ * Leave the erasing of used segment to the background handler.
+ */
+#define RTEMS_FDISK_BACKGROUND_ERASE (1 << 0)
+
+/**
+ * Leave the compacting of of used segment to the background handler.
+ */
+#define RTEMS_FDISK_BACKGROUND_COMPACT (1 << 1)
+
+/**
+ * Check the pages during initialisation to see which pages are
+ * valid and which are not. This could slow down initialising the
+ * disk driver.
+ */
+#define RTEMS_FDISK_CHECK_PAGES (1 << 2)
+
+/**
+ * Blank check the flash device before writing to them. This is needed if
+ * you think you have a driver or device problem.
+ */
+#define RTEMS_FDISK_BLANK_CHECK_BEFORE_WRITE (1 << 3)
+
+/**
+ * Flash disk device driver initialization. Place in a table as the
+ * initialisation entry and remainder of the entries are the
+ * RTEMS block device generic handlers.
+ *
+ * @param major Flash disk major device number.
+ * @param minor Minor device number, not applicable.
+ * @param arg Initialization argument, not applicable.
+ * @return The rtems_device_driver is actually just
+ * rtems_status_code.
+ */
+rtems_device_driver
+rtems_fdisk_initialize (rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void* arg);
+
+/**
+ * External reference to the configuration. Please supply.
+ * Support is present in confdefs.h for providing this variable.
+ */
+extern const rtems_flashdisk_config rtems_flashdisk_configuration[];
+
+/**
+ * External reference to the number of configurations. Please supply.
+ * Support is present in confdefs.h for providing this variable.
+ */
+extern uint32_t rtems_flashdisk_configuration_size;
+
+#endif