From 059a371409f8e35a635e412cd9061a41d4cf7c46 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Tue, 16 Oct 2001 19:05:29 +0000 Subject: 2001-10-16 Chris Johns * include/confdefs.h, include/rtems/config.h, include/rtems/io.h, optman/no-io.c, src/exinit.c, src/io.c: Added a device driver register/unregister interface to allow device drivers to be installed and removed at runtime. This means you do not need devices present in the device table when you build. --- cpukit/sapi/ChangeLog | 8 +++ cpukit/sapi/include/confdefs.h | 10 +++ cpukit/sapi/include/rtems/config.h | 1 + cpukit/sapi/include/rtems/io.h | 29 +++++++++ cpukit/sapi/src/exinit.c | 1 + cpukit/sapi/src/io.c | 130 ++++++++++++++++++++++++++++++++++--- 6 files changed, 170 insertions(+), 9 deletions(-) (limited to 'cpukit') diff --git a/cpukit/sapi/ChangeLog b/cpukit/sapi/ChangeLog index 46595a89b9..e64a906f1b 100644 --- a/cpukit/sapi/ChangeLog +++ b/cpukit/sapi/ChangeLog @@ -1,3 +1,11 @@ +2001-10-16 Chris Johns + + * include/confdefs.h, include/rtems/config.h, include/rtems/io.h, + optman/no-io.c, src/exinit.c, src/io.c: Added a device driver + register/unregister interface to allow device drivers to be + installed and removed at runtime. This means you do not need devices + present in the device table when you build. + 2001-10-16 Ralf Corsepius * include/rtems/Makefile.am: Remove. diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h index 0dda508462..75e6a23a19 100644 --- a/cpukit/sapi/include/confdefs.h +++ b/cpukit/sapi/include/confdefs.h @@ -299,6 +299,15 @@ rtems_driver_address_table Device_drivers[] = { #endif /* CONFIGURE_HAS_OWN_DEVICE_DRIVER_TABLE */ +/* + * Default the number of drivers per node. This value may be + * overridden by the user. + */ + +#ifndef CONFIGURE_MAXIMUM_DRIVERS +#define CONFIGURE_MAXIMUM_DRIVERS 10 +#endif + /* * Default the number of devices per device driver. This value may be * overridden by the user. @@ -993,6 +1002,7 @@ rtems_configuration_table Configuration = { CONFIGURE_MICROSECONDS_PER_TICK, CONFIGURE_TICKS_PER_TIMESLICE, CONFIGURE_MAXIMUM_DEVICES, + CONFIGURE_MAXIMUM_DRIVERS, sizeof (Device_drivers)/ sizeof(rtems_driver_address_table), /* number of device drivers */ Device_drivers, /* pointer to driver table */ diff --git a/cpukit/sapi/include/rtems/config.h b/cpukit/sapi/include/rtems/config.h index bd8d972fc2..eba53a6818 100644 --- a/cpukit/sapi/include/rtems/config.h +++ b/cpukit/sapi/include/rtems/config.h @@ -104,6 +104,7 @@ typedef struct { unsigned32 microseconds_per_tick; unsigned32 ticks_per_timeslice; unsigned32 maximum_devices; + unsigned32 maximum_drivers; unsigned32 number_of_device_drivers; rtems_driver_address_table *Device_driver_table; unsigned32 number_of_initial_extensions; diff --git a/cpukit/sapi/include/rtems/io.h b/cpukit/sapi/include/rtems/io.h index 4d8b3c027c..60d7ea2d53 100644 --- a/cpukit/sapi/include/rtems/io.h +++ b/cpukit/sapi/include/rtems/io.h @@ -100,10 +100,39 @@ SAPI_EXTERN rtems_driver_name_t *_IO_Driver_name_table; void _IO_Manager_initialization( rtems_driver_address_table *driver_table, + unsigned32 drivers_in_table, unsigned32 number_of_drivers, unsigned32 number_of_devices ); +/* + * rtems_io_register_driver + * + * DESCRIPTION: + * + * Register a driver into the device driver table. + * + */ + +rtems_status_code rtems_io_register_driver( + rtems_device_major_number major, + rtems_driver_address_table *driver_table, + rtems_device_major_number *registered_major +); + +/* + * rtems_io_unregister_driver + * + * DESCRIPTION: + * + * Unregister a driver from the device driver table. + * + */ + +rtems_status_code rtems_io_unregister_driver( + rtems_device_major_number major +); + /* * rtems_io_register_name * diff --git a/cpukit/sapi/src/exinit.c b/cpukit/sapi/src/exinit.c index 034b3ce4ab..b44f06df64 100644 --- a/cpukit/sapi/src/exinit.c +++ b/cpukit/sapi/src/exinit.c @@ -205,6 +205,7 @@ rtems_interrupt_level rtems_initialize_executive_early( _IO_Manager_initialization( configuration_table->Device_driver_table, configuration_table->number_of_device_drivers, + configuration_table->maximum_drivers, configuration_table->maximum_devices ); diff --git a/cpukit/sapi/src/io.c b/cpukit/sapi/src/io.c index ff876f663d..8d98253393 100644 --- a/cpukit/sapi/src/io.c +++ b/cpukit/sapi/src/io.c @@ -24,22 +24,44 @@ * * _IO_Manager_initialization * + * The IO manager has been extended to support runtime driver + * registration. The driver table is now allocated in the + * workspace. + * */ - + void _IO_Manager_initialization( - rtems_driver_address_table *driver_table, - unsigned32 number_of_drivers, - unsigned32 number_of_devices + rtems_driver_address_table *driver_table, + unsigned32 drivers_in_table, + unsigned32 number_of_drivers, + unsigned32 number_of_devices ) { void *tmp; unsigned32 index; rtems_driver_name_t *np; + + if ( number_of_drivers < drivers_in_table ) + number_of_drivers = drivers_in_table; + + tmp = _Workspace_Allocate_or_fatal_error( + sizeof( rtems_driver_address_table ) * ( number_of_drivers ) + ); - _IO_Driver_address_table = driver_table; - _IO_Number_of_drivers = number_of_drivers; - _IO_Number_of_devices = number_of_devices; - + _IO_Driver_address_table = (rtems_driver_address_table *) tmp; + + memset( + _IO_Driver_address_table, 0, + sizeof( rtems_driver_address_table ) * ( number_of_drivers ) + ); + + if ( drivers_in_table ) + for ( index = 0 ; index < drivers_in_table ; index++ ) + _IO_Driver_address_table[index] = driver_table[index]; + + _IO_Number_of_drivers = number_of_drivers; + _IO_Number_of_devices = number_of_devices; + tmp = _Workspace_Allocate_or_fatal_error( sizeof( rtems_driver_name_t ) * ( number_of_devices + 1 ) ); @@ -75,6 +97,96 @@ void _IO_Initialize_all_drivers( void ) (void) rtems_io_initialize( major, 0, NULL); } +/*PAGE + * + * rtems_io_register_driver + * + * Register a driver into the device driver table. + * + * Input Paramters: + * major - device major number (0 means allocate + * a number) + * driver_table - driver callout function table + * registered_major - the major number which is registered + * + * Output Parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_io_register_driver( + rtems_device_major_number major, + rtems_driver_address_table *driver_table, + rtems_device_major_number *registered_major +) +{ + *registered_major = 0; + + /* + * Test for initialise/open being present to indicate the driver slot is + * in use. + */ + + if ( major >= _IO_Number_of_drivers ) + return RTEMS_INVALID_NUMBER; + + if ( major == 0 ) + { + for ( major = _IO_Number_of_drivers - 1 ; major ; major-- ) + if ( _IO_Driver_address_table[major].initialization_entry == 0 && + _IO_Driver_address_table[major].open_entry == 0 ) + break; + + if (( major == 0 ) && + ( _IO_Driver_address_table[major].initialization_entry == 0 && + _IO_Driver_address_table[major].open_entry == 0 )) + return RTEMS_TOO_MANY; + } + + if ( _IO_Driver_address_table[major].initialization_entry == 0 && + _IO_Driver_address_table[major].open_entry == 0 ) + { + _IO_Driver_address_table[major] = *driver_table; + *registered_major = major; + + rtems_io_initialize( major, 0, NULL); + + return RTEMS_SUCCESSFUL; + } + + return RTEMS_RESOURCE_IN_USE; +} + +/*PAGE + * + * rtems_io_unregister_driver + * + * Unregister a driver from the device driver table. + * + * Input Paramters: + * major - device major number + * + * Output Parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_io_unregister_driver( + rtems_device_major_number major +) +{ + if ( major < _IO_Number_of_drivers ) + { + memset( + &_IO_Driver_address_table[major], + 0, + sizeof( rtems_driver_address_table ) + ); + return RTEMS_SUCCESSFUL; + } + return RTEMS_UNSATISFIED; +} + /*PAGE * * rtems_io_register_name @@ -184,7 +296,7 @@ rtems_status_code rtems_io_lookup_name( rtems_status_code rtems_io_initialize( rtems_device_major_number major, rtems_device_minor_number minor, - void *argument + void *argument ) { rtems_device_driver_entry callout; -- cgit v1.2.3