File indexing completed on 2025-05-11 08:24:22
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 #ifdef HAVE_CONFIG_H
0041 #include "config.h"
0042 #endif
0043
0044 #include <rtems/ioimpl.h>
0045 #include <rtems/rtems/intr.h>
0046
0047 #if ISR_LOCK_NEEDS_OBJECT
0048 ISR_lock_Control _IO_Driver_registration_lock =
0049 ISR_LOCK_INITIALIZER( "IO Driver Registration" );
0050 #endif
0051
0052 static inline bool rtems_io_is_empty_table(
0053 const rtems_driver_address_table *table
0054 )
0055 {
0056 return table->initialization_entry == NULL && table->open_entry == NULL;
0057 }
0058
0059 static rtems_status_code rtems_io_obtain_major_number(
0060 rtems_device_major_number *major
0061 )
0062 {
0063 rtems_device_major_number n = _IO_Number_of_drivers;
0064 rtems_device_major_number m = 0;
0065
0066
0067
0068 for ( m = 0; m < n; ++m ) {
0069 rtems_driver_address_table *const table = _IO_Driver_address_table + m;
0070
0071 if ( rtems_io_is_empty_table( table ) )
0072 break;
0073 }
0074
0075
0076 *major = m;
0077
0078 if ( m != n )
0079 return RTEMS_SUCCESSFUL;
0080
0081 return RTEMS_TOO_MANY;
0082 }
0083
0084 rtems_status_code rtems_io_register_driver(
0085 rtems_device_major_number major,
0086 const rtems_driver_address_table *driver_table,
0087 rtems_device_major_number *registered_major
0088 )
0089 {
0090 rtems_device_major_number major_limit = _IO_Number_of_drivers;
0091 ISR_lock_Context lock_context;
0092
0093 if ( rtems_interrupt_is_in_progress() )
0094 return RTEMS_CALLED_FROM_ISR;
0095
0096 if ( registered_major == NULL )
0097 return RTEMS_INVALID_ADDRESS;
0098
0099
0100 *registered_major = major_limit;
0101
0102 if ( driver_table == NULL )
0103 return RTEMS_INVALID_ADDRESS;
0104
0105 if ( rtems_io_is_empty_table( driver_table ) )
0106 return RTEMS_INVALID_ADDRESS;
0107
0108 if ( major >= major_limit )
0109 return RTEMS_INVALID_NUMBER;
0110
0111 _IO_Driver_registration_acquire( &lock_context );
0112
0113 if ( major == 0 ) {
0114 rtems_status_code sc = rtems_io_obtain_major_number( registered_major );
0115
0116 if ( sc != RTEMS_SUCCESSFUL ) {
0117 _IO_Driver_registration_release( &lock_context );
0118 return sc;
0119 }
0120 major = *registered_major;
0121 } else {
0122 rtems_driver_address_table *const table = _IO_Driver_address_table + major;
0123
0124 if ( !rtems_io_is_empty_table( table ) ) {
0125 _IO_Driver_registration_release( &lock_context );
0126 return RTEMS_RESOURCE_IN_USE;
0127 }
0128
0129 *registered_major = major;
0130 }
0131
0132 _IO_Driver_address_table [major] = *driver_table;
0133
0134 _IO_Driver_registration_release( &lock_context );
0135
0136 if ( _IO_All_drivers_initialized ) {
0137
0138
0139
0140 return rtems_io_initialize( major, 0, NULL );
0141 } else {
0142
0143
0144
0145 return RTEMS_SUCCESSFUL;
0146 }
0147 }