summaryrefslogtreecommitdiffstats
path: root/cpukit
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit')
-rw-r--r--cpukit/sapi/ChangeLog8
-rw-r--r--cpukit/sapi/include/confdefs.h10
-rw-r--r--cpukit/sapi/include/rtems/config.h1
-rw-r--r--cpukit/sapi/include/rtems/io.h29
-rw-r--r--cpukit/sapi/src/exinit.c1
-rw-r--r--cpukit/sapi/src/io.c130
6 files changed, 170 insertions, 9 deletions
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 <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.
+
2001-10-16 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* 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
@@ -300,6 +300,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,11 +100,40 @@ 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
*
* DESCRIPTION:
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 )
);
@@ -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;