From d91e3a71bb6e6dbbb03b62c80fce972549ed13b7 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 13 Aug 2010 12:40:16 +0000 Subject: 2010-08-13 Sebastian Huber * libblock/include/rtems/media.h, libblock/src/media-desc.c, libblock/src/media-dev-ident.c, libblock/src/media-path.c, libblock/src/media-server.c, libblock/src/media.c: New files. * Makefile.am, preinstall.am, libblock/Makefile.am: Reflect changes above. --- cpukit/libblock/include/rtems/media.h | 525 ++++++++++++++++++++++++++++++++++ 1 file changed, 525 insertions(+) create mode 100644 cpukit/libblock/include/rtems/media.h (limited to 'cpukit/libblock/include/rtems/media.h') diff --git a/cpukit/libblock/include/rtems/media.h b/cpukit/libblock/include/rtems/media.h new file mode 100644 index 0000000000..df37342fd6 --- /dev/null +++ b/cpukit/libblock/include/rtems/media.h @@ -0,0 +1,525 @@ +/** + * @file + * + * @ingroup RTEMSMedia + * + * @brief Media API. + */ + +/* + * Copyright (c) 2009, 2010 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * + * + * 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. + */ + +#ifndef RTEMS_MEDIA_H +#define RTEMS_MEDIA_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @defgroup RTEMSMedia Media Manager + * + * @brief Removable media support. + * + * The media manager may be used to maintain the life cycle of a removable + * media. Currently only disk devices are supported. The initiator posts an + * event to the media manager and it will respond with appropriate default + * actions. For example a disk attach will lead to inspection of the partition + * table and mounted file systems. Clients can register listeners to react to + * events. + * @{ + */ + +#define RTEMS_MEDIA_MOUNT_BASE "/media" + +#define RTEMS_MEDIA_DELIMITER '-' + +/** + * Disk life cycle events: + * @dot + * digraph disk_events { + * "DISK ATTACH" -> "PARTITION INQUIRY"; + * "DISK ATTACH" -> "MOUNT"; + * "PARTITION INQUIRY" -> "PARTITION ATTACH"; + * "PARTITION INQUIRY" -> "DISK DETACH"; + * "PARTITION ATTACH" -> "MOUNT"; + * "MOUNT" -> "UNMOUNT"; + * "UNMOUNT" -> "PARTITION DETACH"; + * "UNMOUNT" -> "DISK DETACH"; + * "PARTITION DETACH" -> "DISK DETACH"; + * } + * @enddot + */ +typedef enum { + RTEMS_MEDIA_EVENT_DISK_ATTACH, + RTEMS_MEDIA_EVENT_DISK_DETACH, + RTEMS_MEDIA_EVENT_MOUNT, + RTEMS_MEDIA_EVENT_UNMOUNT, + RTEMS_MEDIA_EVENT_PARTITION_INQUIRY, + RTEMS_MEDIA_EVENT_PARTITION_ATTACH, + RTEMS_MEDIA_EVENT_PARTITION_DETACH, + RTEMS_MEDIA_EVENT_ERROR +} rtems_media_event; + +/** + * Normal state transition: + * @dot + * digraph state { + * INQUIRY -> READY [label="all listeners\nreturned successful"]; + * INQUIRY -> ABORTED [label="otherwise"]; + * READY -> SUCCESS [label="the worker\nreturned successful"]; + * READY -> FAILED [label="otherwise"]; + * } + * @enddot + */ +typedef enum { + RTEMS_MEDIA_STATE_INQUIRY, + RTEMS_MEDIA_STATE_READY, + RTEMS_MEDIA_STATE_ABORTED, + RTEMS_MEDIA_STATE_SUCCESS, + RTEMS_MEDIA_STATE_FAILED, + RTEMS_MEDIA_ERROR_DISK_UNKNOWN, + RTEMS_MEDIA_ERROR_DISK_EXISTS, + RTEMS_MEDIA_ERROR_DISK_OR_PARTITION_UNKNOWN, + RTEMS_MEDIA_ERROR_DISK_OR_PARTITION_EXISTS, + RTEMS_MEDIA_ERROR_PARTITION_UNKNOWN, + RTEMS_MEDIA_ERROR_PARTITION_ORPHAN, + RTEMS_MEDIA_ERROR_PARTITION_DETACH_WITH_MOUNT, + RTEMS_MEDIA_ERROR_PARTITION_WITH_UNKNOWN_DISK, + RTEMS_MEDIA_ERROR_MOUNT_POINT_UNKNOWN, + RTEMS_MEDIA_ERROR_MOUNT_POINT_EXISTS, + RTEMS_MEDIA_ERROR_MOUNT_POINT_ORPHAN +} rtems_media_state; + +/** + * @brief Event listener. + * + * The listener will be called with the @a listener_arg passed to + * rtems_media_listener_add(). + * + * Source and destination values for each event and state: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
EventStateSourceDestination
RTEMS_MEDIA_EVENT_DISK_ATTACHRTEMS_MEDIA_STATE_INQUIRYdriver nameNULL
RTEMS_MEDIA_STATE_READYdriver nameNULL
RTEMS_MEDIA_STATE_ABORTEDdriver nameNULL
RTEMS_MEDIA_STATE_SUCCESSdriver namedisk path
RTEMS_MEDIA_STATE_FAILEDdriver nameNULL
RTEMS_MEDIA_EVENT_DISK_DETACHRTEMS_MEDIA_STATE_INQUIRYdisk pathNULL
RTEMS_MEDIA_STATE_READYdisk pathNULL
RTEMS_MEDIA_STATE_ABORTEDdisk pathNULL
RTEMS_MEDIA_STATE_SUCCESSdisk pathNULL
RTEMS_MEDIA_STATE_FAILEDdisk pathNULL
RTEMS_MEDIA_EVENT_PARTITION_INQUIRYRTEMS_MEDIA_STATE_INQUIRYdisk pathNULL
RTEMS_MEDIA_STATE_READYdisk pathNULL
RTEMS_MEDIA_STATE_ABORTEDdisk pathNULL
RTEMS_MEDIA_STATE_SUCCESSdisk pathNULL
RTEMS_MEDIA_STATE_FAILEDdisk pathNULL
RTEMS_MEDIA_EVENT_PARTITION_ATTACHRTEMS_MEDIA_STATE_INQUIRYdisk pathNULL
RTEMS_MEDIA_STATE_READYdisk pathNULL
RTEMS_MEDIA_STATE_ABORTEDdisk pathNULL
RTEMS_MEDIA_STATE_SUCCESSdisk pathpartition path
RTEMS_MEDIA_STATE_FAILEDdisk pathNULL
RTEMS_MEDIA_EVENT_PARTITION_DETACHRTEMS_MEDIA_STATE_INQUIRYpartition pathNULL
RTEMS_MEDIA_STATE_READYpartition pathNULL
RTEMS_MEDIA_STATE_ABORTEDpartition pathNULL
RTEMS_MEDIA_STATE_SUCCESSpartition pathNULL
RTEMS_MEDIA_STATE_FAILEDpartition pathNULL
RTEMS_MEDIA_EVENT_MOUNTRTEMS_MEDIA_STATE_INQUIRYdisk or partition pathNULL
RTEMS_MEDIA_STATE_READYdisk or partition pathNULL
RTEMS_MEDIA_STATE_ABORTEDdisk or partition pathNULL
RTEMS_MEDIA_STATE_SUCCESSdisk or partition pathmount path
RTEMS_MEDIA_STATE_FAILEDdisk or partition pathNULL
RTEMS_MEDIA_EVENT_UNMOUNTRTEMS_MEDIA_STATE_INQUIRYmount pathNULL
RTEMS_MEDIA_STATE_READYmount pathNULL
RTEMS_MEDIA_STATE_ABORTEDmount pathNULL
RTEMS_MEDIA_STATE_SUCCESSmount pathNULL
RTEMS_MEDIA_STATE_FAILEDmount pathNULL
RTEMS_MEDIA_EVENT_ERRORRTEMS_MEDIA_ERROR_DISK_UNKNOWNdisk pathNULL
RTEMS_MEDIA_ERROR_DISK_EXISTSdisk pathNULL
RTEMS_MEDIA_ERROR_DISK_OR_PARTITION_UNKNOWNdisk or partition pathNULL
RTEMS_MEDIA_ERROR_DISK_OR_PARTITION_EXISTSdisk or partition pathNULL
RTEMS_MEDIA_ERROR_PARTITION_UNKNOWNpartition pathNULL
RTEMS_MEDIA_ERROR_PARTITION_ORPHANpartition pathdisk path
RTEMS_MEDIA_ERROR_PARTITION_DETACH_WITH_MOUNTpartition pathmount path
RTEMS_MEDIA_ERROR_PARTITION_WITH_UNKNOWN_DISKpartition pathdisk path
RTEMS_MEDIA_ERROR_MOUNT_POINT_UNKNOWNmount pathNULL
RTEMS_MEDIA_ERROR_MOUNT_POINT_EXISTSmount pathNULL
RTEMS_MEDIA_ERROR_MOUNT_POINT_ORPHANmount pathdisk path
+ * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_IO_ERROR In the inquiry state this will abort the action. + */ +typedef rtems_status_code (*rtems_media_listener)( + rtems_media_event event, + rtems_media_state state, + const char *src, + const char *dest, + void *listener_arg +); + +/** + * @brief Do the work corresponding to an event. + * + * The @a state will be + * - RTEMS_MEDIA_STATE_READY, or + * - RTEMS_MEDIA_STATE_ABORTED. + * + * It will be called with the @a src and @a worker_arg arguments passed to + * rtems_media_post_event(). + * + * The destination shall be returned in @a dest in case of success. It shall + * be allocated with malloc(). + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_IO_ERROR Failure. + */ +typedef rtems_status_code (*rtems_media_worker)( + rtems_media_state state, + const char *src, + char **dest, + void *worker_arg +); + +/** + * @name Base + * + * @{ + */ + +/** + * @brief Initializes the media manager. + * + * Calling this function more than once will have no effects. There is no + * protection against concurrent access. + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_NO_MEMORY Not enough resources. + */ +rtems_status_code rtems_media_initialize(void); + +/** + * @brief Adds the @a listener with argument @a listener_arg. + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_NO_MEMORY Not enough memory. + * @retval RTEMS_TOO_MANY Such a listener is already present. + */ +rtems_status_code rtems_media_listener_add( + rtems_media_listener listener, + void *listener_arg +); + +/** + * @brief Removes the @a listener with argument @a listener_arg. + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_INVALID_ID No such listener is present. + */ +rtems_status_code rtems_media_listener_remove( + rtems_media_listener listener, + void *listener_arg +); + +/** + * @brief Posts the @a event with source @a src. + * + * The @a worker will be called with the @a worker_arg argument. + * + * The destination will be returned in @a dest in case of success. It will be + * allocated with malloc() and should be freed if not needed anymore. + * + * The work will be done by the calling thread. You can avoid this if you use + * the media server via rtems_media_server_post_event(). + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_UNSATISFIED One or more listeners aborted the action. + * @retval RTEMS_IO_ERROR The worker returned with an error status. + */ +rtems_status_code rtems_media_post_event( + rtems_media_event event, + const char *src, + char **dest, + rtems_media_worker worker, + void *worker_arg +); + +/** @} */ + +/** + * @name Server + * + * @{ + */ + +/** + * @brief Initializes the media manager and media server. + * + * It creates a server task with the @a priority, @a stack_size, @a modes, and + * @a attributes parameters. + * + * A message queue will be used for communication with the server task which + * may buffer up to @a message_count messages. + * + * Calling this function more than once will have no effects. There is no + * protection against concurrent access. + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_NO_MEMORY Not enough resources. + */ +rtems_status_code rtems_media_server_initialize( + rtems_task_priority priority, + size_t stack_size, + rtems_mode modes, + rtems_attribute attributes, + uint32_t message_count +); + +/** + * @brief Sends an event message to the media server. + * + * @see See rtems_media_post_event(). + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_UNSATISFIED Message queue is full. + * @retval RTEMS_NO_MEMORY Not enough memory for the message. + */ +rtems_status_code rtems_media_server_post_event( + rtems_media_event event, + const char *src, + rtems_media_worker worker, + void *worker_arg +); + +/** + * @brief See rtems_media_server_post_event(). + */ +static inline rtems_status_code rtems_media_server_disk_attach( + const char *driver_name, + rtems_media_worker worker, + void *worker_arg +) +{ + return rtems_media_server_post_event( + RTEMS_MEDIA_EVENT_DISK_ATTACH, + driver_name, + worker, + worker_arg + ); +} + +/** + * @brief See rtems_media_server_post_event(). + */ +static inline rtems_status_code rtems_media_server_disk_detach( + const char *disk_path +) +{ + return rtems_media_server_post_event( + RTEMS_MEDIA_EVENT_DISK_DETACH, + disk_path, + NULL, + NULL + ); +} + +/** @} */ + +/** + * @name Path Construction + * + * @{ + */ + +/** + * @brief Creates a new path as "prefix/name-major". + * + * @return New string, or @c NULL if no memory is available. + */ +char *rtems_media_create_path( + const char *prefix, + const char *name, + rtems_device_major_number major +); + +/** + * @brief Replaces the prefix of the @a path with @a new_prefix. + * + * The prefix is everything up to the last '/'. + * + * @return New string, or @c NULL if no memory is available. + */ +char *rtems_media_replace_prefix(const char *new_prefix, const char *path); + +/** + * @brief Appends the @a minor number to the @a path resulting in "path-minor". + * + * @return New string, or @c NULL if no memory is available. + */ +char *rtems_media_append_minor( + const char *path, + rtems_device_minor_number minor +); + +/** @} */ + +/** + * @name Support + * + * @{ + */ + +/** + * @brief Returns the device identifier for the device located at + * @a device_path in @a device_identifier. + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_INVALID_ID No device at this path. + */ +rtems_status_code rtems_media_get_device_identifier( + const char *device_path, + dev_t *device_identifier +); + +const char *rtems_media_event_description(rtems_media_event event); + +const char *rtems_media_state_description(rtems_media_state state); + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* RTEMS_MEDIA_H */ -- cgit v1.2.3