Changeset 456a776 in rtems


Ignore:
Timestamp:
Oct 5, 2009, 3:00:53 PM (10 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, master
Children:
63e99db5
Parents:
37f9717a
Message:

2009-10-04 Sebastian Huber <Sebastian.Huber@…>

  • 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.
Location:
cpukit
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • cpukit/ChangeLog

    r37f9717a r456a776  
     12009-10-04      Sebastian Huber <Sebastian.Huber@embedded-brains.de>
     2
     3        * sapi/include/rtems/io.h, sapi/src/ioregisterdriver.c: Documenation.
     4        rtems_io_lookup_name() is now deprecated.  Added
     5        rtems_io_driver_io_error().  rtems_io_register_driver() is now
     6        thread-safe.
     7
    182009-10-04      Joel Sherrill <joel.sherrill@oarcorp.com>
    29
  • cpukit/sapi/include/rtems/io.h

    r37f9717a r456a776  
    11/**
    2  * @file rtems/io.h
    3  *
    4  *  This include file contains all the constants and structures associated
    5  *  with the Input/Output Manager.  This manager provides a well defined
    6  *  mechanism for accessing device drivers and a structured methodology for
    7  *  organizing device drivers.
    8  *
    9  *  Directives provided are:
    10  *
    11  *     + initialize a device driver
    12  *     + open a device driver
    13  *     + close a device driver
    14  *     + read from a device driver
    15  *     + write to a device driver
    16  *     + special device services
     2 * @file
     3 *
     4 * @ingroup ClassicIO
     5 *
     6 * @brief Classic Input/Output Manager API.
    177 */
    188 
     
    4131#endif
    4232
    43 /*
    44  *
    45  *  The following defines the types for:
    46  *
    47  *    + major and minor numbers
    48  *    + the return type of a device driver entry
    49  *    + a pointer to a device driver entry
    50  *    + an entry in the the Device Driver Address Table.  Each entry in this
    51  *      table corresponds to an application provided device driver and
    52  *      defines the entry points for that device driver.
    53  */
    54 
    55 typedef uint32_t   rtems_device_major_number;
    56 typedef uint32_t   rtems_device_minor_number;
     33/**
     34 * @defgroup ClassicIO Input/Output
     35 *
     36 * @ingroup ClassicRTEMS
     37 *
     38 * @{
     39 */
     40
     41typedef uint32_t rtems_device_major_number;
     42
     43typedef uint32_t rtems_device_minor_number;
    5744
    5845typedef rtems_status_code rtems_device_driver;
    5946
    60 typedef rtems_device_driver ( *rtems_device_driver_entry )(
    61                  rtems_device_major_number,
    62                  rtems_device_minor_number,
    63                  void *
    64              );
     47typedef rtems_device_driver (*rtems_device_driver_entry)(
     48  rtems_device_major_number,
     49  rtems_device_minor_number,
     50  void *
     51);
    6552
    6653typedef struct {
    67   rtems_device_driver_entry initialization_entry; /* initialization procedure */
    68   rtems_device_driver_entry open_entry;        /* open request procedure */
    69   rtems_device_driver_entry close_entry;       /* close request procedure */
    70   rtems_device_driver_entry read_entry;        /* read request procedure */
    71   rtems_device_driver_entry write_entry;       /* write request procedure */
    72   rtems_device_driver_entry control_entry;     /* special functions procedure */
    73 }   rtems_driver_address_table;
    74 
    75 /*
    76  * Table for the io device names
    77  */
     54  rtems_device_driver_entry initialization_entry;
     55  rtems_device_driver_entry open_entry;
     56  rtems_device_driver_entry close_entry;
     57  rtems_device_driver_entry read_entry;
     58  rtems_device_driver_entry write_entry;
     59  rtems_device_driver_entry control_entry;
     60} rtems_driver_address_table;
     61
     62/**
     63 * @name Device Driver Maintainance
     64 *
     65 * @{
     66 */
     67
     68/**
     69 * @brief Returns @c RTEMS_IO_ERROR.
     70 *
     71 * @retval RTEMS_IO_ERROR Only this one.
     72 */
     73rtems_status_code rtems_io_driver_io_error(
     74  rtems_device_major_number major,
     75  rtems_device_minor_number minor,
     76  void *arg
     77);
     78
     79/**
     80 * @brief Registers and initializes the device with the device driver table
     81 * @a driver_table and major number @a major.
     82 *
     83 * If the major number equals zero a major number will be obtained.  The major
     84 * number of the registered driver will be returned in @a registered_major.
     85 *
     86 * After a successful registration rtems_io_initialize() will be called to
     87 * initialize the device.
     88 *
     89 * @retval RTEMS_SUCCESSFUL Device successfully registered and initialized.
     90 * @retval RTEMS_INVALID_ADDRESS Pointer to driver table or to registered
     91 * major number are invalid.  Device driver table is empty.
     92 * @retval RTEMS_INVALID_NUMBER Invalid major number.
     93 * @retval RTEMS_TOO_MANY No major number available.
     94 * @retval RTEMS_RESOURCE_IN_USE Major number in use.
     95 * @retval * Status code depends on rtems_io_initialize().
     96 */
     97rtems_status_code rtems_io_register_driver(
     98  rtems_device_major_number major,
     99  const rtems_driver_address_table *driver_table,
     100  rtems_device_major_number *registered_major
     101);
     102
     103/**
     104 * @brief Unregisters the device driver with number @a major.
     105 *
     106 * @retval RTEMS_SUCCESSFUL Device driver successfully unregistered.
     107 * @retval RTEMS_UNSATISFIED Invalid major number.
     108 */
     109rtems_status_code rtems_io_unregister_driver(
     110  rtems_device_major_number major
     111);
     112
     113/**
     114 * @brief Registers the name @a device_name in the file system for the device
     115 * with number tuple @a major and @a minor.
     116 *
     117 * @retval RTEMS_SUCCESSFUL Name successfully registered.
     118 * @retval RTEMS_TOO_MANY Name already in use or other errors.
     119 */
     120rtems_status_code rtems_io_register_name(
     121  const char *device_name,
     122  rtems_device_major_number major,
     123  rtems_device_minor_number minor
     124);
     125
     126/** @} */
     127
     128/**
     129 * @name Device Driver Invocation
     130 *
     131 * @{
     132 */
     133
     134rtems_status_code rtems_io_initialize(
     135  rtems_device_major_number  major,
     136  rtems_device_minor_number  minor,
     137  void                      *argument
     138);
     139
     140rtems_status_code rtems_io_open(
     141  rtems_device_major_number  major,
     142  rtems_device_minor_number  minor,
     143  void                      *argument
     144);
     145
     146rtems_status_code rtems_io_close(
     147  rtems_device_major_number  major,
     148  rtems_device_minor_number  minor,
     149  void                      *argument
     150);
     151
     152rtems_status_code rtems_io_read(
     153  rtems_device_major_number  major,
     154  rtems_device_minor_number  minor,
     155  void                      *argument
     156);
     157
     158rtems_status_code rtems_io_write(
     159  rtems_device_major_number  major,
     160  rtems_device_minor_number  minor,
     161  void                      *argument
     162);
     163
     164rtems_status_code rtems_io_control(
     165  rtems_device_major_number  major,
     166  rtems_device_minor_number  minor,
     167  void                      *argument
     168);
     169
     170/** @} */
     171
     172/** @} */
    78173
    79174typedef struct {
     
    84179} rtems_driver_name_t;
    85180
    86 /*
    87  *  This is the table of device names.
    88  */
    89 
    90 /*
    91  *  The following declare the data required to manage the Driver
    92  *  Address Table and Device Name Table.
    93  */
    94 
    95 SAPI_IO_EXTERN uint32_t                    _IO_Number_of_drivers;
    96 SAPI_IO_EXTERN rtems_driver_address_table *_IO_Driver_address_table;
    97 
    98 /*
    99  *  _IO_Manager_initialization
    100  *
    101  *  DESCRIPTION:
    102  *
    103  *  This routine performs the initialization necessary for this manager.
    104  */
    105 
    106 void _IO_Manager_initialization(void);
    107 
    108 /*
    109  *  rtems_io_register_driver
    110  *
    111  *  DESCRIPTION:
    112  *
    113  *  Register a driver into the device driver table.
    114  *
    115  */
    116 
    117 rtems_status_code rtems_io_register_driver(
    118     rtems_device_major_number   major,
    119     const rtems_driver_address_table *driver_table,
    120     rtems_device_major_number  *registered_major
    121 );
    122 
    123 /*
    124  *  rtems_io_unregister_driver
    125  *
    126  *  DESCRIPTION:
    127  *
    128  *  Unregister a driver from the device driver table.
    129  *
    130  */
    131 
    132 rtems_status_code rtems_io_unregister_driver(
    133     rtems_device_major_number major
    134 );
    135 
    136 /*
    137  *  rtems_io_register_name
    138  *
    139  *  DESCRIPTION:
    140  *
    141  *  Associate a name with a driver.
    142  *
    143  */
    144 
    145 rtems_status_code rtems_io_register_name(
    146     const char                *device_name,
    147     rtems_device_major_number  major,
    148     rtems_device_minor_number  minor
    149 );
    150 
    151 
    152 /*
    153  *  rtems_io_lookup_name
    154  *
    155  *  DESCRIPTION:
    156  *
    157  *  Find what driver "owns" this name
    158  */
    159 
     181/**
     182 * @deprecated Use stat() instead.
     183 */
    160184rtems_status_code rtems_io_lookup_name(
    161185    const char           *name,
    162186    rtems_driver_name_t  *device_info
    163 );
    164 
    165 
    166 /*
    167  *  rtems_io_initialize
    168  *
    169  *  DESCRIPTION:
    170  *
    171  *  This routine implements the rtems_io_initialize directive.  It is invoked
    172  *  to initialize a device driver or an individual device.
    173  */
    174 
    175 rtems_status_code rtems_io_initialize(
    176   rtems_device_major_number  major,
    177   rtems_device_minor_number  minor,
    178   void                      *argument
    179 );
    180 
    181 /*
    182  *  rtems_io_open
    183  *
    184  *  DESCRIPTION:
    185  *
    186  *  This routine implements the rtems_io_open directive.  It is invoked
    187  *  to open a device.
    188  */
    189 
    190 rtems_status_code rtems_io_open(
    191   rtems_device_major_number  major,
    192   rtems_device_minor_number  minor,
    193   void                      *argument
    194 );
    195 
    196 /*
    197  *  rtems_io_close
    198  *
    199  *  DESCRIPTION:
    200  *
    201  *  This routine implements the rtems_io_close directive.  It is invoked
    202  *  to close a device.
    203  */
    204 
    205 rtems_status_code rtems_io_close(
    206   rtems_device_major_number  major,
    207   rtems_device_minor_number  minor,
    208   void                      *argument
    209 );
    210 
    211 /*
    212  *  rtems_io_read
    213  *
    214  *  DESCRIPTION:
    215  *
    216  *  This routine implements the rtems_io_read directive.  It is invoked
    217  *  to read from a device.
    218  */
    219 
    220 rtems_status_code rtems_io_read(
    221   rtems_device_major_number  major,
    222   rtems_device_minor_number  minor,
    223   void                      *argument
    224 );
    225 
    226 /*
    227  *  rtems_io_write
    228  *
    229  *  DESCRIPTION:
    230  *
    231  *  This routine implements the rtems_io_write directive.  It is invoked
    232  *  to write to a device.
    233  */
    234 
    235 rtems_status_code rtems_io_write(
    236   rtems_device_major_number  major,
    237   rtems_device_minor_number  minor,
    238   void                      *argument
    239 );
    240 
    241 /*
    242  *  rtems_io_control
    243  *
    244  *  DESCRIPTION:
    245  *
    246  *  This routine implements the rtems_io_control directive.  It is invoked
    247  *  to perform a device specific operation on a device.
    248  */
    249 
    250 rtems_status_code rtems_io_control(
    251   rtems_device_major_number  major,
    252   rtems_device_minor_number  minor,
    253   void                      *argument
    254 );
    255 
    256 /*
    257  *  _IO_Initialize_all_drivers
    258  *
    259  *  DESCRIPTION:
    260  *
    261  *  This routine initializes all of the device drivers configured
    262  *  in the Device Driver Address Table.
    263  */
     187) RTEMS_COMPILER_DEPRECATED_ATTRIBUTE;
     188
     189SAPI_IO_EXTERN uint32_t _IO_Number_of_drivers;
     190
     191SAPI_IO_EXTERN rtems_driver_address_table *_IO_Driver_address_table;
     192
     193void _IO_Manager_initialization( void );
    264194
    265195void _IO_Initialize_all_drivers( void );
  • cpukit/sapi/src/ioregisterdriver.c

    r37f9717a r456a776  
     1/**
     2 * @file
     3 *
     4 * @ingroup ClassicIO
     5 *
     6 * @brief Classic Input/Output Manager implementation.
     7 */
     8 
    19/*
    2  *  Input/Output Manager - Dynamically Register Device Driver
    3  *
    410 *  COPYRIGHT (c) 1989-2009.
    511 *  On-Line Applications Research Corporation (OAR).
     12 *
     13 *  Copyright (c) 2009 embedded brains GmbH.
    614 *
    715 *  The license and distribution terms for this file may be
     
    1826#include <rtems/system.h>
    1927#include <rtems/io.h>
     28#include <rtems/rtems/intr.h>
    2029
    21 /*
    22  *  rtems_io_register_driver
    23  *
    24  *  Register a driver into the device driver table.
    25  *
    26  *  Input Paramters:
    27  *    major            - device major number (0 means allocate
    28  *                       a number)
    29  *    driver_table     - driver callout function table
    30  *    registered_major - the major number which is registered
    31  *
    32  *  Output Parameters:
    33  *    RTEMS_SUCCESSFUL - if successful
    34  *    error code       - if unsuccessful
    35  */
     30rtems_status_code rtems_io_driver_io_error(
     31  rtems_device_major_number major,
     32  rtems_device_minor_number minor,
     33  void *arg
     34)
     35{
     36  return RTEMS_IO_ERROR;
     37}
     38
     39static inline bool rtems_io_is_empty_table(
     40  const rtems_driver_address_table *table
     41)
     42{
     43  return table->initialization_entry == NULL && table->open_entry == NULL;
     44}
     45
     46static inline void rtems_io_occupy_table(
     47  rtems_driver_address_table *table
     48)
     49{
     50  table->open_entry = rtems_io_driver_io_error;
     51}
     52
     53static rtems_status_code rtems_io_obtain_major_number(
     54  rtems_device_major_number *major
     55)
     56{
     57  rtems_device_major_number n = _IO_Number_of_drivers;
     58  rtems_device_major_number m = 0;
     59 
     60  if ( major == NULL ) {
     61    return RTEMS_INVALID_ADDRESS;
     62  }
     63
     64  for ( m = 0; m < n; ++m ) {
     65    rtems_driver_address_table *const table = _IO_Driver_address_table + m;
     66    rtems_interrupt_level level;
     67
     68    rtems_interrupt_disable( level );
     69    if ( rtems_io_is_empty_table( table ) ) {
     70      rtems_io_occupy_table( table );
     71      rtems_interrupt_enable( level );
     72
     73      break;
     74    }
     75    rtems_interrupt_enable( level );
     76  }
     77
     78  /* Assigns invalid value in case of failure */
     79  *major = m;
     80
     81  if ( m != n ) {
     82    return RTEMS_SUCCESSFUL;
     83  } else {
     84    return RTEMS_TOO_MANY;
     85  }
     86}
    3687
    3788rtems_status_code rtems_io_register_driver(
    38   rtems_device_major_number         major,
     89  rtems_device_major_number major,
    3990  const rtems_driver_address_table *driver_table,
    40   rtems_device_major_number        *registered_major
     91  rtems_device_major_number *registered_major
    4192)
    4293{
     94  rtems_device_major_number major_limit = _IO_Number_of_drivers;
    4395
    44   /*
    45    *  Validate the pointer data and contents passed in
    46    */
    47   if ( !driver_table )
     96  if ( registered_major == NULL ) {
    4897    return RTEMS_INVALID_ADDRESS;
     98  }
    4999
    50   if ( !registered_major )
     100  /* Set it to an invalid value */
     101  *registered_major = major_limit;
     102
     103  if ( driver_table == NULL ) {
    51104    return RTEMS_INVALID_ADDRESS;
     105  }
    52106
    53   if ( !driver_table->initialization_entry && !driver_table->open_entry )
     107  if ( rtems_io_is_empty_table( driver_table ) ) {
    54108    return RTEMS_INVALID_ADDRESS;
     109  }
    55110
    56   *registered_major = 0;
    57 
    58   /*
    59    *  The requested major number is higher than what is configured.
    60    */
    61   if ( major >= _IO_Number_of_drivers )
     111  if ( major >= major_limit ) {
    62112    return RTEMS_INVALID_NUMBER;
    63 
    64   /*
    65    * Test for initialise/open being present to indicate the driver slot is
    66    * in use.
    67    */
     113  }
    68114
    69115  if ( major == 0 ) {
    70     bool found = false;
    71     for ( major = _IO_Number_of_drivers - 1 ; major ; major-- ) {
    72       if ( !_IO_Driver_address_table[major].initialization_entry &&
    73            !_IO_Driver_address_table[major].open_entry ) {
    74         found = true;
    75         break;
    76       }
     116    rtems_status_code sc = rtems_io_obtain_major_number( registered_major );
     117
     118    if ( sc == RTEMS_SUCCESSFUL ) {
     119      major = *registered_major;
     120    } else {
     121      return RTEMS_TOO_MANY;
     122    }
     123  } else {
     124    rtems_driver_address_table *const table = _IO_Driver_address_table + major;
     125    rtems_interrupt_level level;
     126
     127    rtems_interrupt_disable( level );
     128    if ( rtems_io_is_empty_table( table ) ) {
     129      rtems_io_occupy_table( table );
     130      rtems_interrupt_enable( level );
     131    } else {
     132      rtems_interrupt_enable( level );
     133
     134      return RTEMS_RESOURCE_IN_USE;
    77135    }
    78136
    79     if ( !found )
    80       return RTEMS_TOO_MANY;
     137    *registered_major = major;
    81138  }
    82139
    83   if ( _IO_Driver_address_table[major].initialization_entry ||
    84        _IO_Driver_address_table[major].open_entry )
    85     return RTEMS_RESOURCE_IN_USE;
    86 
    87 
    88   _IO_Driver_address_table[major] = *driver_table;
    89   *registered_major               = major;
     140  _IO_Driver_address_table [major] = *driver_table;
    90141
    91142  return rtems_io_initialize( major, 0, NULL );
Note: See TracChangeset for help on using the changeset viewer.