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 Oct 5, 2009 at 3:00:53 PM

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
Line 
1/**
2 * @file
3 *
4 * @ingroup ClassicIO
5 *
6 * @brief Classic Input/Output Manager implementation.
7 */
8 
9/*
10 *  COPYRIGHT (c) 1989-2009.
11 *  On-Line Applications Research Corporation (OAR).
12 *
13 *  Copyright (c) 2009 embedded brains GmbH.
14 *
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>
28#include <rtems/rtems/intr.h>
29
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}
87
88rtems_status_code rtems_io_register_driver(
89  rtems_device_major_number major,
90  const rtems_driver_address_table *driver_table,
91  rtems_device_major_number *registered_major
92)
93{
94  rtems_device_major_number major_limit = _IO_Number_of_drivers;
95
96  if ( registered_major == NULL ) {
97    return RTEMS_INVALID_ADDRESS;
98  }
99
100  /* Set it to an invalid value */
101  *registered_major = major_limit;
102
103  if ( driver_table == NULL ) {
104    return RTEMS_INVALID_ADDRESS;
105  }
106
107  if ( rtems_io_is_empty_table( driver_table ) ) {
108    return RTEMS_INVALID_ADDRESS;
109  }
110
111  if ( major >= major_limit ) {
112    return RTEMS_INVALID_NUMBER;
113  }
114
115  if ( major == 0 ) {
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;
135    }
136
137    *registered_major = major;
138  }
139
140  _IO_Driver_address_table [major] = *driver_table;
141
142  return rtems_io_initialize( major, 0, NULL );
143}
Note: See TracBrowser for help on using the repository browser.