Index: cpukit/ChangeLog
===================================================================
--- cpukit/ChangeLog	(revision b3117727f502338f025ef1364c3c32b2e54726bd)
+++ cpukit/ChangeLog	(revision 7a03c09b43f0aea54cb59371a76875d3e693f7ea)
@@ -1,2 +1,10 @@
+2007-05-29	Joel Sherrill <joel.sherrill@OARcorp.com>
+
+	* sapi/include/confdefs.h, sapi/src/io.c: Readded code to copy driver
+	table into Workspace but now it is only done if the application needs
+	extra slots for dynamic driver registration. Cleaned up
+	rtems_io_register_driver and rtems_io_unregister_driver code and
+	added numerous error cases to register.
+
 2007-05-28	Joel Sherrill <joel.sherrill@OARcorp.com>
 
Index: cpukit/sapi/include/confdefs.h
===================================================================
--- cpukit/sapi/include/confdefs.h	(revision b3117727f502338f025ef1364c3c32b2e54726bd)
+++ cpukit/sapi/include/confdefs.h	(revision 7a03c09b43f0aea54cb59371a76875d3e693f7ea)
@@ -1031,9 +1031,9 @@
 
 #define CONFIGURE_MEMORY_FOR_SYSTEM_OVERHEAD \
-  ( CONFIGURE_MEMORY_FOR_TASKS(1) +    /* IDLE */ \
-    (256 * 12) +                       /* Ready chains */ \
-    256        +                       /* name/ptr table overhead */ \
-    CONFIGURE_INTERRUPT_STACK_MEMORY + /* interrupt stack */ \
-    CONFIGURE_API_MUTEX_MEMORY         /* allocation mutex */ \
+  ( CONFIGURE_MEMORY_FOR_TASKS(1) +                  /* IDLE */ \
+    ((PRIORITY_MAXIMUM+1) * sizeof(Chain_Control)) + /* Ready chains */ \
+    256 +                                 /* name/ptr table overhead */ \
+    CONFIGURE_INTERRUPT_STACK_MEMORY +    /* interrupt stack */ \
+    CONFIGURE_API_MUTEX_MEMORY            /* allocation mutex */ \
   )
 
Index: cpukit/sapi/src/io.c
===================================================================
--- cpukit/sapi/src/io.c	(revision b3117727f502338f025ef1364c3c32b2e54726bd)
+++ cpukit/sapi/src/io.c	(revision 7a03c09b43f0aea54cb59371a76875d3e693f7ea)
@@ -41,9 +41,43 @@
 )
 {
-  if ( number_of_drivers < drivers_in_table )
+  uint32_t index;
+
+  /*
+   *  If the user claims there are less drivers than are actually in
+   *  the table, then let's just go with the table's count.
+   */
+  if ( number_of_drivers <= drivers_in_table )
     number_of_drivers = drivers_in_table;
 
-  _IO_Driver_address_table = driver_table;
+  /*
+   *  If the maximum number of driver is the same as the number in the
+   *  table, then we do not have to copy the driver table.  They can't
+   *  register any dynamically.
+   */
+  if ( number_of_drivers == drivers_in_table ) {
+    _IO_Driver_address_table = driver_table;
+    _IO_Number_of_drivers = number_of_drivers;
+    return;
+  }
+
+  /*
+   *  The application requested extra slots in the driver table, so we
+   *  have to allocate a new driver table and copy theirs to it.
+   */
+
+  _IO_Driver_address_table = (rtems_driver_address_table *) 
+      _Workspace_Allocate_or_fatal_error(
+        sizeof( rtems_driver_address_table ) * ( number_of_drivers )
+      );
   _IO_Number_of_drivers = number_of_drivers;
+
+  memset(
+    _IO_Driver_address_table, 0,
+    sizeof( rtems_driver_address_table ) * ( number_of_drivers )
+  );
+
+  for ( index = 0 ; index < drivers_in_table ; index++ )
+    _IO_Driver_address_table[index] = driver_table[index];
+  number_of_drivers = drivers_in_table;
 }
 
@@ -85,10 +119,29 @@
 
 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_device_major_number   major,
+  rtems_driver_address_table *driver_table,
+  rtems_device_major_number  *registered_major
+)
+{
+
+  /*
+   *  Validate the pointer data and contents passed in
+   */
+  if ( !driver_table )
+    return RTEMS_INVALID_ADDRESS;
+
+  if ( !registered_major )
+    return RTEMS_INVALID_ADDRESS;
+
+  if ( !driver_table->initialization_entry && !driver_table->open_entry )
+    return RTEMS_INVALID_ADDRESS;
+
   *registered_major = 0;
+
+  /*
+   *  The requested major number is higher than what is configured.
+   */
+  if ( major >= _IO_Number_of_drivers )
+    return RTEMS_INVALID_NUMBER;
 
   /*
@@ -97,30 +150,29 @@
    */
 
-  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 )
+    boolean found = FALSE;
+    for ( major = _IO_Number_of_drivers - 1 ; major ; major-- ) {
+      if ( !_IO_Driver_address_table[major].initialization_entry &&
+           !_IO_Driver_address_table[major].open_entry ) {
+        found = TRUE;
         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 ( !found )
+      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;
+  if ( _IO_Driver_address_table[major].initialization_entry ||
+       _IO_Driver_address_table[major].open_entry )
+    return RTEMS_RESOURCE_IN_USE;
+
+
+  _IO_Driver_address_table[major] = *driver_table;
+  *registered_major               = major;
+
+  rtems_io_initialize( major, 0, NULL );
+
+  return RTEMS_SUCCESSFUL;
 }
 
