Index: c/src/lib/libbsp/unix/posix/shmsupp/getcfg.c
===================================================================
--- c/src/lib/libbsp/unix/posix/shmsupp/getcfg.c	(revision ad3bf6670f7db81bcdb0b5f2635a758948e856c0)
+++ c/src/lib/libbsp/unix/posix/shmsupp/getcfg.c	(revision aa9f19454a6912a337752fee5e0f98414de3e8a5)
@@ -12,15 +12,6 @@
  *    *shmcfg   - pointer to SHM Config Table
  *
- *  NOTES:  The MP interrupt used is the Runway bus' ability to directly
- *          address the control registers of up to four CPUs and cause
- *          interrupts on them.
- *
- *          The following table illustrates the configuration limitations:
- *
- *                                   BUS     MAX
- *                          MODE    ENDIAN  NODES
- *                        ========= ====== =======
- *                         POLLED    BIG    2+
- *                        INTERRUPT  BIG    2..4
+ *  NOTES:  This driver is capable of supporting a practically unlimited
+ *          number of nodes.
  *
  *  COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
@@ -44,10 +35,8 @@
 #include <errno.h>
 #include <unistd.h>
+#include <stdlib.h>
 #include <sys/ipc.h>
 #include <sys/shm.h>
 #include <sys/sem.h>
-
-#define INTERRUPT 0        /* can be interrupt or polling */
-#define POLLING   1
 
 shm_config_table BSP_shm_cfgtbl;
@@ -59,4 +48,94 @@
 );
 
+void fix_semaphores( void )
+{
+    rtems_unsigned32 maximum_nodes;
+    int          i;
+
+    int          shmid;
+    char        *shm_addr;
+    key_t        shm_key;
+    key_t        sem_key;
+    int          status;
+    int          shm_size;
+
+    if (getenv("RTEMS_SHM_KEY"))
+        shm_key = strtol(getenv("RTEMS_SHM_KEY"), 0, 0);
+    else
+#ifdef RTEMS_SHM_KEY
+        shm_key = RTEMS_SHM_KEY;
+#else
+        shm_key = 0xa000;
+#endif
+ 
+    if (getenv("RTEMS_SHM_SIZE"))
+        shm_size = strtol(getenv("RTEMS_SHM_SIZE"), 0, 0);
+    else
+#ifdef RTEMS_SHM_SIZE
+        shm_size = RTEMS_SHM_SIZE;
+#else
+        shm_size = 64 * KILOBYTE;
+#endif
+ 
+    if (getenv("RTEMS_SHM_SEMAPHORE_KEY"))
+        sem_key = strtol(getenv("RTEMS_SHM_SEMAPHORE_KEY"), 0, 0);
+    else
+#ifdef RTEMS_SHM_SEMAPHORE_KEY
+        sem_key = RTEMS_SHM_SEMAPHORE_KEY;
+#else
+        sem_key = 0xa001;
+#endif
+
+    shmid = shmget(shm_key, shm_size, IPC_CREAT | 0660);
+    if ( shmid == -1 ) {
+       fix_syscall_errno(); /* in case of newlib */
+       perror( "shmget" );
+       rtems_fatal_error_occurred(RTEMS_UNSATISFIED);
+    }
+
+    shm_addr = shmat(shmid, (char *)0, SHM_RND);
+    if ( shm_addr == (void *)-1 ) {
+       fix_syscall_errno(); /* in case of newlib */
+       perror( "shmat" );
+       rtems_fatal_error_occurred(RTEMS_UNSATISFIED);
+    }
+
+    maximum_nodes = Shm_RTEMS_MP_Configuration->maximum_nodes;
+    semid = semget(sem_key, maximum_nodes + 1, IPC_CREAT | 0660);
+    if ( semid == -1 ) {
+       fix_syscall_errno(); /* in case of newlib */
+       perror( "semget" );
+       rtems_fatal_error_occurred(RTEMS_UNSATISFIED);
+    }
+
+    if ( Shm_Is_master_node() ) {
+      for ( i=0 ; i <= maximum_nodes ; i++ ) {
+
+#if defined(solaris2)
+        union semun {
+          int val;
+          struct semid_ds *buf;
+          ushort *array;
+        } help;
+ 
+        help.val = 1;
+        semctl( semid, i, SETVAL, help );
+#endif
+#if defined(hpux)
+        semctl( semid, i, SETVAL, 1 );
+#endif
+
+        fix_syscall_errno(); /* in case of newlib */
+        if ( status == -1 ) {
+          fprintf( stderr, "Sem init failed %d\n", errno ); fflush( stderr );
+          rtems_fatal_error_occurred(RTEMS_UNSATISFIED);
+        }
+      }
+    }
+
+    BSP_shm_cfgtbl.base         = (vol_u32 *)shm_addr;
+    BSP_shm_cfgtbl.length       = shm_size;
+}
+
 void Shm_Get_configuration(
   rtems_unsigned32   localnode,
@@ -64,51 +143,6 @@
 )
 {
-    rtems_unsigned32 maximum_nodes;
-    int          i;
-    int          shmid;
-    char        *shm_addr;
-    key_t        shm_key;
-    key_t        sem_key;
-    struct sembuf  sb;
-    int          status;
+    fix_semaphores();
 
-    shm_key = 0xa000;
-
-    shmid = shmget(shm_key, 16 * KILOBYTE, IPC_CREAT | 0660);
-    if ( shmid == -1 ) {
-       perror( "shmget" );
-       exit( 0 );
-    }
-
-    shm_addr = shmat(shmid, (char *)0, SHM_RND);
-    if ( shm_addr == (void *)-1 ) {
-       perror( "shmat" );
-       exit( 0 );
-    }
-
-    sem_key = 0xa001;
-
-    maximum_nodes = Shm_RTEMS_MP_Configuration->maximum_nodes;
-    semid = semget(sem_key, maximum_nodes + 1, IPC_CREAT | 0660);
-    if ( semid == -1 ) {
-       perror( "semget" );
-       exit( 0 );
-    }
-
-    if ( Shm_Is_master_node() ) {
-      for ( i=0 ; i <= maximum_nodes ; i++ ) {
-        sb.sem_op  = 1;
-        sb.sem_num = i;
-        sb.sem_flg = 0;
-        status = semop( semid, &sb, 1 );
-        if ( status == -1 ) {
-          fprintf( stderr, "Sem init failed %d\n", errno ); fflush( stderr );
-          exit( 0 );
-        }
-      }
-    }
-
-    BSP_shm_cfgtbl.base         = (vol_u32 *)shm_addr;
-    BSP_shm_cfgtbl.length       = 16 * KILOBYTE;
     BSP_shm_cfgtbl.format       = SHM_BIG;
 
@@ -121,14 +155,14 @@
 #endif
 
-#if ( POLLING == 1 )
+#ifdef INTERRUPT_EXTERNAL_MPCI
+    BSP_shm_cfgtbl.poll_intr    = INTR_MODE;
+    BSP_shm_cfgtbl.Intr.address = (vol_u32 *) getpid();    /* process id */
+    BSP_shm_cfgtbl.Intr.value   = INTERRUPT_EXTERNAL_MPCI; /* signal to send */
+    BSP_shm_cfgtbl.Intr.length  = LONG;
+#else
     BSP_shm_cfgtbl.poll_intr    = POLLED_MODE;
     BSP_shm_cfgtbl.Intr.address = NO_INTERRUPT;
     BSP_shm_cfgtbl.Intr.value   = NO_INTERRUPT;
     BSP_shm_cfgtbl.Intr.length  = NO_INTERRUPT;
-#else
-    BSP_shm_cfgtbl.poll_intr    = INTR_MODE;
-    BSP_shm_cfgtbl.Intr.address = 0;    /* process id? */
-    BSP_shm_cfgtbl.Intr.value   = 0;    /* signal to send? */
-    BSP_shm_cfgtbl.Intr.length  = LONG;
 #endif
 
