source: rtems/cpukit/sapi/src/ioregisterdriver.c @ 599d71f

Last change on this file since 599d71f was 8d6fd40, checked in by Sebastian Huber <sebastian.huber@…>, on Apr 17, 2015 at 6:45:50 AM

sapi: Avoid declaration in source, fix type

  • Property mode set to 100644
File size: 2.8 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.org/license/LICENSE.
18 */
19
20#if HAVE_CONFIG_H
21#include "config.h"
22#endif
23
24#include <rtems/io.h>
25#include <rtems/rtems/intr.h>
26#include <rtems/score/threaddispatch.h>
27
28static inline bool rtems_io_is_empty_table(
29  const rtems_driver_address_table *table
30)
31{
32  return table->initialization_entry == NULL && table->open_entry == NULL;
33}
34
35static rtems_status_code rtems_io_obtain_major_number(
36  rtems_device_major_number *major
37)
38{
39  rtems_device_major_number n = _IO_Number_of_drivers;
40  rtems_device_major_number m = 0;
41
42  /* major is error checked by caller */
43
44  for ( m = 0; m < n; ++m ) {
45    rtems_driver_address_table *const table = _IO_Driver_address_table + m;
46
47    if ( rtems_io_is_empty_table( table ) )
48      break;
49  }
50
51  /* Assigns invalid value in case of failure */
52  *major = m;
53
54  if ( m != n )
55    return RTEMS_SUCCESSFUL;
56
57  return RTEMS_TOO_MANY;
58}
59
60rtems_status_code rtems_io_register_driver(
61  rtems_device_major_number         major,
62  const rtems_driver_address_table *driver_table,
63  rtems_device_major_number        *registered_major
64)
65{
66  rtems_device_major_number major_limit = _IO_Number_of_drivers;
67
68  if ( rtems_interrupt_is_in_progress() )
69    return RTEMS_CALLED_FROM_ISR;
70
71  if ( registered_major == NULL )
72    return RTEMS_INVALID_ADDRESS;
73
74  /* Set it to an invalid value */
75  *registered_major = major_limit;
76
77  if ( driver_table == NULL )
78    return RTEMS_INVALID_ADDRESS;
79
80  if ( rtems_io_is_empty_table( driver_table ) )
81    return RTEMS_INVALID_ADDRESS;
82
83  if ( major >= major_limit )
84    return RTEMS_INVALID_NUMBER;
85
86  _Thread_Disable_dispatch();
87
88  if ( major == 0 ) {
89    rtems_status_code sc = rtems_io_obtain_major_number( registered_major );
90
91    if ( sc != RTEMS_SUCCESSFUL ) {
92      _Thread_Enable_dispatch();
93      return sc;
94    }
95    major = *registered_major;
96  } else {
97    rtems_driver_address_table *const table = _IO_Driver_address_table + major;
98
99    if ( !rtems_io_is_empty_table( table ) ) {
100      _Thread_Enable_dispatch();
101      return RTEMS_RESOURCE_IN_USE;
102    }
103
104    *registered_major = major;
105  }
106
107  _IO_Driver_address_table [major] = *driver_table;
108
109  _Thread_Enable_dispatch();
110
111  if ( _IO_All_drivers_initialized ) {
112    /* Other drivers have already been initialized, we initialize
113     * the driver directly.
114     */
115    return rtems_io_initialize( major, 0, NULL );
116  } else {
117    /* The driver will be initialized together with all other drivers
118     * in a later stage by _IO_Initialize_all_drivers().
119     */
120    return RTEMS_SUCCESSFUL;
121  }
122}
Note: See TracBrowser for help on using the repository browser.