Ignore:
Timestamp:
Oct 5, 2009, 3:00:53 PM (11 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 5, 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.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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.