diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 2009-10-05 15:00:53 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 2009-10-05 15:00:53 +0000 |
commit | 456a77680c32555167bcc10a1b2d1697bdf341eb (patch) | |
tree | 7902ee905094ccd98b9c4683b9ad34777065b7ce /cpukit | |
parent | 2009-10-05 Joel Sherrill <joel.sherrill@oarcorp.com> (diff) | |
download | rtems-456a77680c32555167bcc10a1b2d1697bdf341eb.tar.bz2 |
2009-10-04 Sebastian Huber <Sebastian.Huber@embedded-brains.de>
* sapi/include/rtems/io.h, sapi/src/ioregisterdriver.c: Documenation.
rtems_io_lookup_name() is now deprecated. Added
rtems_io_driver_io_error(). rtems_io_register_driver() is now
thread-safe.
Diffstat (limited to 'cpukit')
-rw-r--r-- | cpukit/ChangeLog | 7 | ||||
-rw-r--r-- | cpukit/sapi/include/rtems/io.h | 252 | ||||
-rw-r--r-- | cpukit/sapi/src/ioregisterdriver.c | 155 |
3 files changed, 201 insertions, 213 deletions
diff --git a/cpukit/ChangeLog b/cpukit/ChangeLog index 3008457bc5..bdc6b95a1a 100644 --- a/cpukit/ChangeLog +++ b/cpukit/ChangeLog @@ -1,3 +1,10 @@ +2009-10-04 Sebastian Huber <Sebastian.Huber@embedded-brains.de> + + * sapi/include/rtems/io.h, sapi/src/ioregisterdriver.c: Documenation. + rtems_io_lookup_name() is now deprecated. Added + rtems_io_driver_io_error(). rtems_io_register_driver() is now + thread-safe. + 2009-10-04 Joel Sherrill <joel.sherrill@oarcorp.com> * rtems/src/ratemonreportstatistics.c: owner field is always set so diff --git a/cpukit/sapi/include/rtems/io.h b/cpukit/sapi/include/rtems/io.h index fc03ec74fd..ba867c46f3 100644 --- a/cpukit/sapi/include/rtems/io.h +++ b/cpukit/sapi/include/rtems/io.h @@ -1,19 +1,9 @@ /** - * @file rtems/io.h + * @file * - * This include file contains all the constants and structures associated - * with the Input/Output Manager. This manager provides a well defined - * mechanism for accessing device drivers and a structured methodology for - * organizing device drivers. + * @ingroup ClassicIO * - * Directives provided are: - * - * + initialize a device driver - * + open a device driver - * + close a device driver - * + read from a device driver - * + write to a device driver - * + special device services + * @brief Classic Input/Output Manager API. */ /* @@ -40,136 +30,105 @@ extern "C" { #endif -/* +/** + * @defgroup ClassicIO Input/Output * - * The following defines the types for: + * @ingroup ClassicRTEMS * - * + major and minor numbers - * + the return type of a device driver entry - * + a pointer to a device driver entry - * + an entry in the the Device Driver Address Table. Each entry in this - * table corresponds to an application provided device driver and - * defines the entry points for that device driver. + * @{ */ -typedef uint32_t rtems_device_major_number; -typedef uint32_t rtems_device_minor_number; +typedef uint32_t rtems_device_major_number; + +typedef uint32_t rtems_device_minor_number; typedef rtems_status_code rtems_device_driver; -typedef rtems_device_driver ( *rtems_device_driver_entry )( - rtems_device_major_number, - rtems_device_minor_number, - void * - ); +typedef rtems_device_driver (*rtems_device_driver_entry)( + rtems_device_major_number, + rtems_device_minor_number, + void * +); typedef struct { - rtems_device_driver_entry initialization_entry; /* initialization procedure */ - rtems_device_driver_entry open_entry; /* open request procedure */ - rtems_device_driver_entry close_entry; /* close request procedure */ - rtems_device_driver_entry read_entry; /* read request procedure */ - rtems_device_driver_entry write_entry; /* write request procedure */ - rtems_device_driver_entry control_entry; /* special functions procedure */ -} rtems_driver_address_table; + rtems_device_driver_entry initialization_entry; + rtems_device_driver_entry open_entry; + rtems_device_driver_entry close_entry; + rtems_device_driver_entry read_entry; + rtems_device_driver_entry write_entry; + rtems_device_driver_entry control_entry; +} rtems_driver_address_table; -/* - * Table for the io device names - */ - -typedef struct { - char *device_name; - size_t device_name_length; - rtems_device_major_number major; - rtems_device_minor_number minor; -} rtems_driver_name_t; - -/* - * This is the table of device names. - */ - -/* - * The following declare the data required to manage the Driver - * Address Table and Device Name Table. +/** + * @name Device Driver Maintainance + * + * @{ */ -SAPI_IO_EXTERN uint32_t _IO_Number_of_drivers; -SAPI_IO_EXTERN rtems_driver_address_table *_IO_Driver_address_table; - -/* - * _IO_Manager_initialization - * - * DESCRIPTION: +/** + * @brief Returns @c RTEMS_IO_ERROR. * - * This routine performs the initialization necessary for this manager. + * @retval RTEMS_IO_ERROR Only this one. */ +rtems_status_code rtems_io_driver_io_error( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +); -void _IO_Manager_initialization(void); - -/* - * rtems_io_register_driver +/** + * @brief Registers and initializes the device with the device driver table + * @a driver_table and major number @a major. * - * DESCRIPTION: + * If the major number equals zero a major number will be obtained. The major + * number of the registered driver will be returned in @a registered_major. * - * Register a driver into the device driver table. + * After a successful registration rtems_io_initialize() will be called to + * initialize the device. * + * @retval RTEMS_SUCCESSFUL Device successfully registered and initialized. + * @retval RTEMS_INVALID_ADDRESS Pointer to driver table or to registered + * major number are invalid. Device driver table is empty. + * @retval RTEMS_INVALID_NUMBER Invalid major number. + * @retval RTEMS_TOO_MANY No major number available. + * @retval RTEMS_RESOURCE_IN_USE Major number in use. + * @retval * Status code depends on rtems_io_initialize(). */ - rtems_status_code rtems_io_register_driver( - rtems_device_major_number major, - const rtems_driver_address_table *driver_table, - rtems_device_major_number *registered_major + rtems_device_major_number major, + const rtems_driver_address_table *driver_table, + rtems_device_major_number *registered_major ); -/* - * rtems_io_unregister_driver - * - * DESCRIPTION: - * - * Unregister a driver from the device driver table. +/** + * @brief Unregisters the device driver with number @a major. * + * @retval RTEMS_SUCCESSFUL Device driver successfully unregistered. + * @retval RTEMS_UNSATISFIED Invalid major number. */ - rtems_status_code rtems_io_unregister_driver( - rtems_device_major_number major + rtems_device_major_number major ); -/* - * rtems_io_register_name - * - * DESCRIPTION: - * - * Associate a name with a driver. +/** + * @brief Registers the name @a device_name in the file system for the device + * with number tuple @a major and @a minor. * + * @retval RTEMS_SUCCESSFUL Name successfully registered. + * @retval RTEMS_TOO_MANY Name already in use or other errors. */ - rtems_status_code rtems_io_register_name( - const char *device_name, - rtems_device_major_number major, - rtems_device_minor_number minor -); - - -/* - * rtems_io_lookup_name - * - * DESCRIPTION: - * - * Find what driver "owns" this name - */ - -rtems_status_code rtems_io_lookup_name( - const char *name, - rtems_driver_name_t *device_info + const char *device_name, + rtems_device_major_number major, + rtems_device_minor_number minor ); +/** @} */ -/* - * rtems_io_initialize - * - * DESCRIPTION: +/** + * @name Device Driver Invocation * - * This routine implements the rtems_io_initialize directive. It is invoked - * to initialize a device driver or an individual device. + * @{ */ rtems_status_code rtems_io_initialize( @@ -178,89 +137,60 @@ rtems_status_code rtems_io_initialize( void *argument ); -/* - * rtems_io_open - * - * DESCRIPTION: - * - * This routine implements the rtems_io_open directive. It is invoked - * to open a device. - */ - rtems_status_code rtems_io_open( rtems_device_major_number major, rtems_device_minor_number minor, void *argument ); -/* - * rtems_io_close - * - * DESCRIPTION: - * - * This routine implements the rtems_io_close directive. It is invoked - * to close a device. - */ - rtems_status_code rtems_io_close( rtems_device_major_number major, rtems_device_minor_number minor, void *argument ); -/* - * rtems_io_read - * - * DESCRIPTION: - * - * This routine implements the rtems_io_read directive. It is invoked - * to read from a device. - */ - rtems_status_code rtems_io_read( rtems_device_major_number major, rtems_device_minor_number minor, void *argument ); -/* - * rtems_io_write - * - * DESCRIPTION: - * - * This routine implements the rtems_io_write directive. It is invoked - * to write to a device. - */ - rtems_status_code rtems_io_write( rtems_device_major_number major, rtems_device_minor_number minor, void *argument ); -/* - * rtems_io_control - * - * DESCRIPTION: - * - * This routine implements the rtems_io_control directive. It is invoked - * to perform a device specific operation on a device. - */ - rtems_status_code rtems_io_control( rtems_device_major_number major, rtems_device_minor_number minor, void *argument ); -/* - * _IO_Initialize_all_drivers - * - * DESCRIPTION: - * - * This routine initializes all of the device drivers configured - * in the Device Driver Address Table. +/** @} */ + +/** @} */ + +typedef struct { + char *device_name; + size_t device_name_length; + rtems_device_major_number major; + rtems_device_minor_number minor; +} rtems_driver_name_t; + +/** + * @deprecated Use stat() instead. */ +rtems_status_code rtems_io_lookup_name( + const char *name, + rtems_driver_name_t *device_info +) RTEMS_COMPILER_DEPRECATED_ATTRIBUTE; + +SAPI_IO_EXTERN uint32_t _IO_Number_of_drivers; + +SAPI_IO_EXTERN rtems_driver_address_table *_IO_Driver_address_table; + +void _IO_Manager_initialization( void ); void _IO_Initialize_all_drivers( void ); diff --git a/cpukit/sapi/src/ioregisterdriver.c b/cpukit/sapi/src/ioregisterdriver.c index 9036452310..61040f3e8f 100644 --- a/cpukit/sapi/src/ioregisterdriver.c +++ b/cpukit/sapi/src/ioregisterdriver.c @@ -1,9 +1,17 @@ -/* - * Input/Output Manager - Dynamically Register Device Driver +/** + * @file + * + * @ingroup ClassicIO * + * @brief Classic Input/Output Manager implementation. + */ + +/* * COPYRIGHT (c) 1989-2009. * On-Line Applications Research Corporation (OAR). * + * Copyright (c) 2009 embedded brains GmbH. + * * 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. @@ -17,76 +25,119 @@ #include <rtems/system.h> #include <rtems/io.h> +#include <rtems/rtems/intr.h> -/* - * rtems_io_register_driver - * - * Register a driver into the device driver table. - * - * Input Paramters: - * major - device major number (0 means allocate - * a number) - * driver_table - driver callout function table - * registered_major - the major number which is registered - * - * Output Parameters: - * RTEMS_SUCCESSFUL - if successful - * error code - if unsuccessful - */ +rtems_status_code rtems_io_driver_io_error( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + return RTEMS_IO_ERROR; +} + +static inline bool rtems_io_is_empty_table( + const rtems_driver_address_table *table +) +{ + return table->initialization_entry == NULL && table->open_entry == NULL; +} + +static inline void rtems_io_occupy_table( + rtems_driver_address_table *table +) +{ + table->open_entry = rtems_io_driver_io_error; +} + +static rtems_status_code rtems_io_obtain_major_number( + rtems_device_major_number *major +) +{ + rtems_device_major_number n = _IO_Number_of_drivers; + rtems_device_major_number m = 0; + + if ( major == NULL ) { + return RTEMS_INVALID_ADDRESS; + } + + for ( m = 0; m < n; ++m ) { + rtems_driver_address_table *const table = _IO_Driver_address_table + m; + rtems_interrupt_level level; + + rtems_interrupt_disable( level ); + if ( rtems_io_is_empty_table( table ) ) { + rtems_io_occupy_table( table ); + rtems_interrupt_enable( level ); + + break; + } + rtems_interrupt_enable( level ); + } + + /* Assigns invalid value in case of failure */ + *major = m; + + if ( m != n ) { + return RTEMS_SUCCESSFUL; + } else { + return RTEMS_TOO_MANY; + } +} rtems_status_code rtems_io_register_driver( - rtems_device_major_number major, + rtems_device_major_number major, const rtems_driver_address_table *driver_table, - rtems_device_major_number *registered_major + rtems_device_major_number *registered_major ) { + rtems_device_major_number major_limit = _IO_Number_of_drivers; - /* - * Validate the pointer data and contents passed in - */ - if ( !driver_table ) + if ( registered_major == NULL ) { return RTEMS_INVALID_ADDRESS; + } - if ( !registered_major ) - return RTEMS_INVALID_ADDRESS; + /* Set it to an invalid value */ + *registered_major = major_limit; - if ( !driver_table->initialization_entry && !driver_table->open_entry ) + if ( driver_table == NULL ) { return RTEMS_INVALID_ADDRESS; + } - *registered_major = 0; + if ( rtems_io_is_empty_table( driver_table ) ) { + return RTEMS_INVALID_ADDRESS; + } - /* - * The requested major number is higher than what is configured. - */ - if ( major >= _IO_Number_of_drivers ) + if ( major >= major_limit ) { return RTEMS_INVALID_NUMBER; - - /* - * Test for initialise/open being present to indicate the driver slot is - * in use. - */ + } if ( major == 0 ) { - bool found = false; - for ( major = _IO_Number_of_drivers - 1 ; major ; major-- ) { - if ( !_IO_Driver_address_table[major].initialization_entry && - !_IO_Driver_address_table[major].open_entry ) { - found = true; - break; - } - } + rtems_status_code sc = rtems_io_obtain_major_number( registered_major ); - if ( !found ) + if ( sc == RTEMS_SUCCESSFUL ) { + major = *registered_major; + } else { return RTEMS_TOO_MANY; - } - - if ( _IO_Driver_address_table[major].initialization_entry || - _IO_Driver_address_table[major].open_entry ) - return RTEMS_RESOURCE_IN_USE; + } + } else { + rtems_driver_address_table *const table = _IO_Driver_address_table + major; + rtems_interrupt_level level; + + rtems_interrupt_disable( level ); + if ( rtems_io_is_empty_table( table ) ) { + rtems_io_occupy_table( table ); + rtems_interrupt_enable( level ); + } else { + rtems_interrupt_enable( level ); + + return RTEMS_RESOURCE_IN_USE; + } + *registered_major = major; + } - _IO_Driver_address_table[major] = *driver_table; - *registered_major = major; + _IO_Driver_address_table [major] = *driver_table; return rtems_io_initialize( major, 0, NULL ); } |