summaryrefslogtreecommitdiffstats
path: root/cpukit/sapi/src/io.c
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2001-10-16 19:05:29 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2001-10-16 19:05:29 +0000
commit059a371409f8e35a635e412cd9061a41d4cf7c46 (patch)
tree6ad23cf6cbe3906006b3f802d0ee92c56026bdc8 /cpukit/sapi/src/io.c
parent2001-10-16 Ralf Corsepius <corsepiu@faw.uni-ulm.de> (diff)
downloadrtems-059a371409f8e35a635e412cd9061a41d4cf7c46.tar.bz2
2001-10-16 Chris Johns <ccj@acm.org>
* 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.
Diffstat (limited to 'cpukit/sapi/src/io.c')
-rw-r--r--cpukit/sapi/src/io.c130
1 files changed, 121 insertions, 9 deletions
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 )
);
@@ -77,6 +99,96 @@ void _IO_Initialize_all_drivers( void )
/*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
*
* Associate a name with a driver
@@ -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;