source: rtems/cpukit/sapi/src/ioregisterdriver.c @ 456a776

4.104.115
Last change on this file since 456a776 was 456a776, checked in by Joel Sherrill <joel.sherrill@…>, on 10/05/09 at 15:00:53

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.
  • Property mode set to 100644
File size: 3.1 KB
RevLine 
[456a776]1/**
2 * @file
3 *
4 * @ingroup ClassicIO
[9c556023]5 *
[456a776]6 * @brief Classic Input/Output Manager implementation.
7 */
8 
9/*
[6914ffe]10 *  COPYRIGHT (c) 1989-2009.
[9c556023]11 *  On-Line Applications Research Corporation (OAR).
12 *
[456a776]13 *  Copyright (c) 2009 embedded brains GmbH.
14 *
[9c556023]15 *  The license and distribution terms for this file may be
16 *  found in the file LICENSE in this distribution or at
17 *  http://www.rtems.com/license/LICENSE.
18 *
19 *  $Id$
20 */
21
22#if HAVE_CONFIG_H
23#include "config.h"
24#endif
25
26#include <rtems/system.h>
27#include <rtems/io.h>
[456a776]28#include <rtems/rtems/intr.h>
[9c556023]29
[456a776]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}
[9c556023]87
88rtems_status_code rtems_io_register_driver(
[456a776]89  rtems_device_major_number major,
[bf95ccb5]90  const rtems_driver_address_table *driver_table,
[456a776]91  rtems_device_major_number *registered_major
[9c556023]92)
93{
[456a776]94  rtems_device_major_number major_limit = _IO_Number_of_drivers;
[9c556023]95
[456a776]96  if ( registered_major == NULL ) {
[9c556023]97    return RTEMS_INVALID_ADDRESS;
[456a776]98  }
[9c556023]99
[456a776]100  /* Set it to an invalid value */
101  *registered_major = major_limit;
[9c556023]102
[456a776]103  if ( driver_table == NULL ) {
[9c556023]104    return RTEMS_INVALID_ADDRESS;
[456a776]105  }
[9c556023]106
[456a776]107  if ( rtems_io_is_empty_table( driver_table ) ) {
108    return RTEMS_INVALID_ADDRESS;
109  }
[9c556023]110
[456a776]111  if ( major >= major_limit ) {
[9c556023]112    return RTEMS_INVALID_NUMBER;
[456a776]113  }
[9c556023]114
115  if ( major == 0 ) {
[456a776]116    rtems_status_code sc = rtems_io_obtain_major_number( registered_major );
[9c556023]117
[456a776]118    if ( sc == RTEMS_SUCCESSFUL ) {
119      major = *registered_major;
120    } else {
[9c556023]121      return RTEMS_TOO_MANY;
[456a776]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;
135    }
[9c556023]136
[456a776]137    *registered_major = major;
138  }
[9c556023]139
[456a776]140  _IO_Driver_address_table [major] = *driver_table;
[9c556023]141
[06bd7c7]142  return rtems_io_initialize( major, 0, NULL );
[9c556023]143}
Note: See TracBrowser for help on using the repository browser.