Instead of tricky state machine it implements plain flow do_sweep()
function which uses wait_for_pending_transaction() blocker.

One of the goals of this patch is to preserve the original OpenSM
behavior.

Signed-off-by: Sasha Khapyorsky <[EMAIL PROTECTED]>
---
 opensm/include/opensm/osm_base.h    |   51 +--
 opensm/include/opensm/osm_sm.h      |    1 +
 opensm/opensm/osm_console.c         |   64 --
 opensm/opensm/osm_helper.c          |   51 +--
 opensm/opensm/osm_node_info_rcv.c   |   11 +-
 opensm/opensm/osm_perfmgr.c         |   12 +-
 opensm/opensm/osm_port_info_rcv.c   |    3 +-
 opensm/opensm/osm_sm.c              |    3 +
 opensm/opensm/osm_sm_mad_ctrl.c     |    6 +-
 opensm/opensm/osm_sminfo_rcv.c      |   17 +-
 opensm/opensm/osm_state_mgr.c       | 1176 ++++++++---------------------------
 opensm/opensm/osm_sw_info_rcv.c     |    3 +-
 opensm/opensm/osm_sweep_fail_ctrl.c |    2 +-
 13 files changed, 286 insertions(+), 1114 deletions(-)

diff --git a/opensm/include/opensm/osm_base.h b/opensm/include/opensm/osm_base.h
index aaf9930..6f784ca 100644
--- a/opensm/include/opensm/osm_base.h
+++ b/opensm/include/opensm/osm_base.h
@@ -753,39 +753,7 @@ typedef enum _osm_sm_state {
        OSM_SM_STATE_NO_STATE = 0,
        OSM_SM_STATE_INIT,
        OSM_SM_STATE_IDLE,
-       OSM_SM_STATE_SWEEP_LIGHT,
-       OSM_SM_STATE_SWEEP_LIGHT_WAIT,
-       OSM_SM_STATE_SWEEP_HEAVY_SELF,
-       OSM_SM_STATE_SWEEP_HEAVY_SUBNET,
-       OSM_SM_STATE_SET_SM_UCAST_LID,
-       OSM_SM_STATE_SET_SM_UCAST_LID_WAIT,
-       OSM_SM_STATE_SET_SM_UCAST_LID_DONE,
-       OSM_SM_STATE_SET_SUBNET_UCAST_LIDS,
-       OSM_SM_STATE_SET_SUBNET_UCAST_LIDS_WAIT,
-       OSM_SM_STATE_SET_SUBNET_UCAST_LIDS_DONE,
-       OSM_SM_STATE_SET_UCAST_TABLES,
-       OSM_SM_STATE_SET_UCAST_TABLES_WAIT,
-       OSM_SM_STATE_SET_UCAST_TABLES_DONE,
-       OSM_SM_STATE_SET_MCAST_TABLES,
-       OSM_SM_STATE_SET_MCAST_TABLES_WAIT,
-       OSM_SM_STATE_SET_MCAST_TABLES_DONE,
-       OSM_SM_STATE_SET_LINK_PORTS,
-       OSM_SM_STATE_SET_LINK_PORTS_WAIT,
-       OSM_SM_STATE_SET_LINK_PORTS_DONE,
-       OSM_SM_STATE_SET_ARMED,
-       OSM_SM_STATE_SET_ARMED_WAIT,
-       OSM_SM_STATE_SET_ARMED_DONE,
-       OSM_SM_STATE_SET_ACTIVE,
-       OSM_SM_STATE_SET_ACTIVE_WAIT,
        OSM_SM_STATE_STANDBY,
-       OSM_SM_STATE_SUBNET_UP,
-       OSM_SM_STATE_PROCESS_REQUEST,
-       OSM_SM_STATE_PROCESS_REQUEST_WAIT,
-       OSM_SM_STATE_PROCESS_REQUEST_DONE,
-       OSM_SM_STATE_MASTER_OR_HIGHER_SM_DETECTED,
-       OSM_SM_STATE_SET_PKEY,
-       OSM_SM_STATE_SET_PKEY_WAIT,
-       OSM_SM_STATE_SET_PKEY_DONE,
        OSM_SM_STATE_MAX
 } osm_sm_state_t;
 /***********/
@@ -804,17 +772,14 @@ typedef enum _osm_sm_state {
 */
 #define OSM_SIGNAL_NONE                                0
 #define OSM_SIGNAL_SWEEP                       1
-#define OSM_SIGNAL_CHANGE_DETECTED             2
-#define OSM_SIGNAL_NO_PENDING_TRANSACTIONS     3
-#define OSM_SIGNAL_DONE                                4
-#define OSM_SIGNAL_DONE_PENDING                        5
-#define OSM_SIGNAL_LIGHT_SWEEP_FAIL            6
-#define OSM_SIGNAL_IDLE_TIME_PROCESS           7
-#define OSM_SIGNAL_IDLE_TIME_PROCESS_REQUEST   8
-#define OSM_SIGNAL_MASTER_OR_HIGHER_SM_DETECTED        9
-#define OSM_SIGNAL_EXIT_STBY                   10
-#define OSM_SIGNAL_PERFMGR_SWEEP               11
-#define OSM_SIGNAL_MAX                         12
+#define OSM_SIGNAL_IDLE_TIME_PROCESS_REQUEST   2
+#define OSM_SIGNAL_EXIT_STBY                   3
+#define OSM_SIGNAL_PERFMGR_SWEEP               4
+#define OSM_SIGNAL_MAX                         4
+
+/* status values for sweep managers - can be removed later */
+#define OSM_SIGNAL_DONE                16
+#define OSM_SIGNAL_DONE_PENDING        17
 
 typedef uintn_t osm_signal_t;
 /***********/
diff --git a/opensm/include/opensm/osm_sm.h b/opensm/include/opensm/osm_sm.h
index e0b3d01..2cdbdd0 100644
--- a/opensm/include/opensm/osm_sm.h
+++ b/opensm/include/opensm/osm_sm.h
@@ -120,6 +120,7 @@ typedef struct osm_sm {
        cl_timer_t sweep_timer;
        cl_event_wheel_t trap_aging_tracker;
        cl_thread_t sweeper;
+       unsigned master_sm_found;
        osm_subn_t *p_subn;
        osm_db_t *p_db;
        osm_vendor_t *p_vendor;
diff --git a/opensm/opensm/osm_console.c b/opensm/opensm/osm_console.c
index d0a632f..bb2a68d 100644
--- a/opensm/opensm/osm_console.c
+++ b/opensm/opensm/osm_console.c
@@ -300,72 +300,8 @@ static char *sm_state_mgr_str(osm_sm_state_t state)
                return ("Init");
        case OSM_SM_STATE_IDLE:
                return ("Idle");
-       case OSM_SM_STATE_SWEEP_LIGHT:
-               return ("Sweep Light");
-       case OSM_SM_STATE_SWEEP_LIGHT_WAIT:
-               return ("Sweep Light Wait");
-       case OSM_SM_STATE_SWEEP_HEAVY_SELF:
-               return ("Sweep Heavy Self");
-       case OSM_SM_STATE_SWEEP_HEAVY_SUBNET:
-               return ("Sweep Heavy Subnet");
-       case OSM_SM_STATE_SET_SM_UCAST_LID:
-               return ("Set SM UCAST LID");
-       case OSM_SM_STATE_SET_SM_UCAST_LID_WAIT:
-               return ("Set SM UCAST LID Wait");
-       case OSM_SM_STATE_SET_SM_UCAST_LID_DONE:
-               return ("Set SM UCAST LID Done");
-       case OSM_SM_STATE_SET_SUBNET_UCAST_LIDS:
-               return ("Set Subnet UCAST LIDS");
-       case OSM_SM_STATE_SET_SUBNET_UCAST_LIDS_WAIT:
-               return ("Set Subnet UCAST LIDS Wait");
-       case OSM_SM_STATE_SET_SUBNET_UCAST_LIDS_DONE:
-               return ("Set Subnet UCAST LIDS Done");
-       case OSM_SM_STATE_SET_UCAST_TABLES:
-               return ("Set UCAST Tables");
-       case OSM_SM_STATE_SET_UCAST_TABLES_WAIT:
-               return ("Set UCAST Tables Wait");
-       case OSM_SM_STATE_SET_UCAST_TABLES_DONE:
-               return ("Set UCAST Tables Done");
-       case OSM_SM_STATE_SET_MCAST_TABLES:
-               return ("Set MCAST Tables");
-       case OSM_SM_STATE_SET_MCAST_TABLES_WAIT:
-               return ("Set MCAST Tables Wait");
-       case OSM_SM_STATE_SET_MCAST_TABLES_DONE:
-               return ("Set MCAST Tables Done");
-       case OSM_SM_STATE_SET_LINK_PORTS:
-               return ("Set Link Ports");
-       case OSM_SM_STATE_SET_LINK_PORTS_WAIT:
-               return ("Set Link Ports Wait");
-       case OSM_SM_STATE_SET_LINK_PORTS_DONE:
-               return ("Set Link Ports Done");
-       case OSM_SM_STATE_SET_ARMED:
-               return ("Set Armed");
-       case OSM_SM_STATE_SET_ARMED_WAIT:
-               return ("Set Armed Wait");
-       case OSM_SM_STATE_SET_ARMED_DONE:
-               return ("Set Armed Done");
-       case OSM_SM_STATE_SET_ACTIVE:
-               return ("Set Active");
-       case OSM_SM_STATE_SET_ACTIVE_WAIT:
-               return ("Set Active Wait");
        case OSM_SM_STATE_STANDBY:
                return ("Standby");
-       case OSM_SM_STATE_SUBNET_UP:
-               return ("Subnet Up");
-       case OSM_SM_STATE_PROCESS_REQUEST:
-               return ("Process Request");
-       case OSM_SM_STATE_PROCESS_REQUEST_WAIT:
-               return ("Process Request Wait");
-       case OSM_SM_STATE_PROCESS_REQUEST_DONE:
-               return ("Process Request Done");
-       case OSM_SM_STATE_MASTER_OR_HIGHER_SM_DETECTED:
-               return ("Master or Higher SM Detected");
-       case OSM_SM_STATE_SET_PKEY:
-               return ("Set PKey");
-       case OSM_SM_STATE_SET_PKEY_WAIT:
-               return ("Set PKey Wait");
-       case OSM_SM_STATE_SET_PKEY_DONE:
-               return ("Set PKey Done");
        default:
                return ("Unknown State");
        }
diff --git a/opensm/opensm/osm_helper.c b/opensm/opensm/osm_helper.c
index 1ea86b9..bd345bc 100644
--- a/opensm/opensm/osm_helper.c
+++ b/opensm/opensm/osm_helper.c
@@ -2062,56 +2062,17 @@ const char *const __osm_sm_state_str[] = {
        "OSM_SM_STATE_NO_STATE",        /* 0 */
        "OSM_SM_STATE_INIT",    /* 1 */
        "OSM_SM_STATE_IDLE",    /* 2 */
-       "OSM_SM_STATE_SWEEP_LIGHT",     /* 3 */
-       "OSM_SM_STATE_SWEEP_LIGHT_WAIT",        /* 4 */
-       "OSM_SM_STATE_SWEEP_HEAVY_SELF",        /* 5 */
-       "OSM_SM_STATE_SWEEP_HEAVY_SUBNET",      /* 6 */
-       "OSM_SM_STATE_SET_SM_UCAST_LID",        /* 7 */
-       "OSM_SM_STATE_SET_SM_UCAST_LID_WAIT",   /* 8 */
-       "OSM_SM_STATE_SET_SM_UCAST_LID_DONE",   /* 9 */
-       "OSM_SM_STATE_SET_SUBNET_UCAST_LIDS",   /* 10 */
-       "OSM_SM_STATE_SET_SUBNET_UCAST_LIDS_WAIT",      /* 11 */
-       "OSM_SM_STATE_SET_SUBNET_UCAST_LIDS_DONE",      /* 12 */
-       "OSM_SM_STATE_SET_UCAST_TABLES",        /* 13 */
-       "OSM_SM_STATE_SET_UCAST_TABLES_WAIT",   /* 14 */
-       "OSM_SM_STATE_SET_UCAST_TABLES_DONE",   /* 15 */
-       "OSM_SM_STATE_SET_MCAST_TABLES",        /* 16 */
-       "OSM_SM_STATE_SET_MCAST_TABLES_WAIT",   /* 17 */
-       "OSM_SM_STATE_SET_MCAST_TABLES_DONE",   /* 18 */
-       "OSM_SM_STATE_SET_LINK_PORTS",  /* 19 */
-       "OSM_SM_STATE_SET_LINK_PORTS_WAIT",     /* 20 */
-       "OSM_SM_STATE_SET_LINK_PORTS_DONE",     /* 21 */
-       "OSM_SM_STATE_SET_ARMED",       /* 22 */
-       "OSM_SM_STATE_SET_ARMED_WAIT",  /* 23 */
-       "OSM_SM_STATE_SET_ARMED_DONE",  /* 24 */
-       "OSM_SM_STATE_SET_ACTIVE",      /* 25 */
-       "OSM_SM_STATE_SET_ACTIVE_WAIT", /* 26 */
-       "OSM_SM_STATE_STANDBY", /* 27 */
-       "OSM_SM_STATE_SUBNET_UP",       /* 28 */
-       "OSM_SM_STATE_PROCESS_REQUEST", /* 29 */
-       "OSM_SM_STATE_PROCESS_REQUEST_WAIT",    /* 30 */
-       "OSM_SM_STATE_PROCESS_REQUEST_DONE",    /* 31 */
-       "OSM_SM_STATE_MASTER_OR_HIGHER_SM_DETECTED",    /* 32 */
-       "OSM_SM_STATE_SET_PKEY",        /* 33 */
-       "OSM_SM_STATE_SET_PKEY_WAIT",   /* 34 */
-       "OSM_SM_STATE_SET_PKEY_DONE",   /* 35 */
-       "UNKNOWN STATE!!"       /* 36 */
+       "OSM_SM_STATE_STANDBY", /* 3 */
+       "UNKNOWN STATE!!"       /* 4 */
 };
 
 const char *const __osm_sm_signal_str[] = {
        "OSM_SIGNAL_NONE",      /* 0 */
        "OSM_SIGNAL_SWEEP",     /* 1 */
-       "OSM_SIGNAL_CHANGE_DETECTED",   /* 2 */
-       "OSM_SIGNAL_NO_PENDING_TRANSACTIONS",   /* 3 */
-       "OSM_SIGNAL_DONE",      /* 4 */
-       "OSM_SIGNAL_DONE_PENDING",      /* 5 */
-       "OSM_SIGNAL_LIGHT_SWEEP_FAIL",  /* 6 */
-       "OSM_SIGNAL_IDLE_TIME_PROCESS", /* 7 */
-       "OSM_SIGNAL_IDLE_TIME_PROCESS_REQUEST", /* 8 */
-       "OSM_SIGNAL_MASTER_OR_HIGHER_SM_DETECTED",      /* 9 */
-       "OSM_SIGNAL_EXIT_STBY", /* 10 */
-       "OSM_SIGNAL_PERFMGR_SWEEP",     /* 11 */
-       "UNKNOWN SIGNAL!!"      /* 12 */
+       "OSM_SIGNAL_IDLE_TIME_PROCESS_REQUEST", /* 2 */
+       "OSM_SIGNAL_EXIT_STBY", /* 3 */
+       "OSM_SIGNAL_PERFMGR_SWEEP",     /* 4 */
+       "UNKNOWN SIGNAL!!"      /* 5 */
 };
 
 /**********************************************************************
diff --git a/opensm/opensm/osm_node_info_rcv.c 
b/opensm/opensm/osm_node_info_rcv.c
index 3ac8d1f..2106aa2 100644
--- a/opensm/opensm/osm_node_info_rcv.c
+++ b/opensm/opensm/osm_node_info_rcv.c
@@ -814,7 +814,6 @@ void osm_ni_rcv_process(IN void *context, IN void *data)
        ib_node_info_t *p_ni;
        ib_smp_t *p_smp;
        osm_node_t *p_node;
-       boolean_t process_new_flag = FALSE;
 
        CL_ASSERT(sm);
 
@@ -856,20 +855,12 @@ void osm_ni_rcv_process(IN void *context, IN void *data)
 
        if (!p_node) {
                __osm_ni_rcv_process_new(sm, p_madw);
-               process_new_flag = TRUE;
+               sm->p_subn->force_heavy_sweep = 1;
        } else
                __osm_ni_rcv_process_existing(sm, p_node, p_madw);
 
        CL_PLOCK_RELEASE(sm->p_lock);
 
-       /*
-        * If we processed a new node - need to signal to the SM that
-        * change detected.
-        */
-       if (process_new_flag)
-               osm_sm_signal(&sm->p_subn->p_osm->sm,
-                             OSM_SIGNAL_CHANGE_DETECTED);
-
       Exit:
        OSM_LOG_EXIT(sm->p_log);
 }
diff --git a/opensm/opensm/osm_perfmgr.c b/opensm/opensm/osm_perfmgr.c
index dd6e662..9480ad7 100644
--- a/opensm/opensm/osm_perfmgr.c
+++ b/opensm/opensm/osm_perfmgr.c
@@ -740,7 +740,6 @@ static void reset_switch_count(cl_map_item_t * const 
p_map_item, void *cxt)
 
 static int perfmgr_discovery(osm_opensm_t * osm)
 {
-       unsigned signals = osm->sm.signal_mask;
        int ret;
 
        CL_PLOCK_ACQUIRE(&osm->lock);
@@ -772,17 +771,10 @@ static int perfmgr_discovery(osm_opensm_t * osm)
        if (wait_for_pending_transactions(&osm->stats))
                goto _exit;
 
-      _drop:
+_drop:
        osm_drop_mgr_process(&osm->sm.drop_mgr);
 
-      _exit:
-       /* dirty hack: cleanup signal mask -
-        * this will not be needed later with both discoveries merged */
-       cl_spinlock_acquire(&osm->sm.signal_lock);
-       osm->sm.signal_mask &= ~(OSM_SIGNAL_NO_PENDING_TRANSACTIONS |
-                                OSM_SIGNAL_CHANGE_DETECTED);
-       osm->sm.signal_mask |= signals;
-       cl_spinlock_release(&osm->sm.signal_lock);
+_exit:
        return ret;
 }
 
diff --git a/opensm/opensm/osm_port_info_rcv.c 
b/opensm/opensm/osm_port_info_rcv.c
index e56ba51..356cd56 100644
--- a/opensm/opensm/osm_port_info_rcv.c
+++ b/opensm/opensm/osm_port_info_rcv.c
@@ -578,8 +578,7 @@ void osm_pi_rcv_process(IN void *context, IN void *data)
                        "GUID 0x%" PRIx64 " port 0x%016" PRIx64
                        ", Commencing heavy sweep\n",
                        cl_ntoh64(node_guid), cl_ntoh64(port_guid));
-               osm_sm_signal(&sm->p_subn->p_osm->sm,
-                             OSM_SIGNAL_CHANGE_DETECTED);
+               sm->p_subn->force_heavy_sweep = 1;
                goto Exit;
        }
 
diff --git a/opensm/opensm/osm_sm.c b/opensm/opensm/osm_sm.c
index f2d259d..019fa51 100644
--- a/opensm/opensm/osm_sm.c
+++ b/opensm/opensm/osm_sm.c
@@ -121,6 +121,9 @@ static void __osm_sm_sweeper(IN void *p_ptr)
                        continue;
                }
 
+               if (osm_exit_flag)
+                       break;
+
                cl_spinlock_acquire(&p_sm->signal_lock);
                signals = p_sm->signal_mask;
                p_sm->signal_mask = 0;
diff --git a/opensm/opensm/osm_sm_mad_ctrl.c b/opensm/opensm/osm_sm_mad_ctrl.c
index c6624a1..efbe97a 100644
--- a/opensm/opensm/osm_sm_mad_ctrl.c
+++ b/opensm/opensm/osm_sm_mad_ctrl.c
@@ -103,11 +103,7 @@ __osm_sm_mad_ctrl_retire_trans_mad(IN osm_sm_mad_ctrl_t * 
const p_ctrl,
                   Signal the subnet manager.
                 */
                osm_log(p_ctrl->p_log, OSM_LOG_DEBUG,
-                       "__osm_sm_mad_ctrl_retire_trans_mad: "
-                       "signal OSM_SIGNAL_NO_PENDING_TRANSACTIONS\n");
-
-               osm_sm_signal(&p_ctrl->p_subn->p_osm->sm,
-                             OSM_SIGNAL_NO_PENDING_TRANSACTIONS);
+                       "__osm_sm_mad_ctrl_retire_trans_mad: wire is clean.\n");
 #ifdef HAVE_LIBPTHREAD
                pthread_cond_signal(&p_ctrl->p_stats->cond);
 #else
diff --git a/opensm/opensm/osm_sminfo_rcv.c b/opensm/opensm/osm_sminfo_rcv.c
index 63cc393..4b4c2b1 100644
--- a/opensm/opensm/osm_sminfo_rcv.c
+++ b/opensm/opensm/osm_sminfo_rcv.c
@@ -346,7 +346,6 @@ __osm_sminfo_rcv_process_get_sm(IN osm_sm_t * sm,
                                IN const osm_remote_sm_t * const p_sm)
 {
        const ib_sm_info_t *p_smi;
-       osm_signal_t ret_val = OSM_SIGNAL_NONE;
 
        OSM_LOG_ENTER(sm->p_log, __osm_sminfo_rcv_process_get_sm);
 
@@ -370,7 +369,7 @@ __osm_sminfo_rcv_process_get_sm(IN osm_sm_t * sm,
                case IB_SMINFO_STATE_NOTACTIVE:
                        break;
                case IB_SMINFO_STATE_MASTER:
-                       ret_val = OSM_SIGNAL_MASTER_OR_HIGHER_SM_DETECTED;
+                       sm->master_sm_found = 1;
                        /* save on the p_sm_state_mgr the guid of the current 
master. */
                        osm_log(sm->p_log, OSM_LOG_VERBOSE,
                                "__osm_sminfo_rcv_process_get_sm: "
@@ -383,8 +382,7 @@ __osm_sminfo_rcv_process_get_sm(IN osm_sm_t * sm,
                        if (__osm_sminfo_rcv_remote_sm_is_higher(sm, p_smi)
                            == TRUE) {
                                /* the remote is a higher sm - need to stop 
sweeping */
-                               ret_val =
-                                   OSM_SIGNAL_MASTER_OR_HIGHER_SM_DETECTED;
+                               sm->master_sm_found = 1;
                                /* save on the sm_state_mgr the guid of the 
higher SM we found - */
                                /* we will poll it - as long as it lives - we 
should be in Standby. */
                                osm_log(sm->p_log, OSM_LOG_VERBOSE,
@@ -456,7 +454,7 @@ __osm_sminfo_rcv_process_get_sm(IN osm_sm_t * sm,
        }
 
        OSM_LOG_EXIT(sm->p_log);
-       return ret_val;
+       return 0;
 }
 
 /**********************************************************************
@@ -471,7 +469,6 @@ __osm_sminfo_rcv_process_get_response(IN osm_sm_t * sm,
        osm_port_t *p_port;
        ib_net64_t port_guid;
        osm_remote_sm_t *p_sm;
-       osm_signal_t process_get_sm_ret_val = OSM_SIGNAL_NONE;
 
        OSM_LOG_ENTER(sm->p_log, __osm_sminfo_rcv_process_get_response);
 
@@ -558,17 +555,11 @@ __osm_sminfo_rcv_process_get_response(IN osm_sm_t * sm,
                 */
                p_sm->smi = *p_smi;
 
-       process_get_sm_ret_val = __osm_sminfo_rcv_process_get_sm(sm, p_sm);
+       __osm_sminfo_rcv_process_get_sm(sm, p_sm);
 
       _unlock_and_exit:
        CL_PLOCK_RELEASE(sm->p_lock);
 
-       /* If process_get_sm_ret_val != OSM_SIGNAL_NONE then we have to signal
-        * to the SM with that signal. */
-       if (process_get_sm_ret_val != OSM_SIGNAL_NONE)
-               osm_sm_signal(&sm->p_subn->p_osm->sm,
-                             process_get_sm_ret_val);
-
       Exit:
        OSM_LOG_EXIT(sm->p_log);
 }
diff --git a/opensm/opensm/osm_state_mgr.c b/opensm/opensm/osm_state_mgr.c
index 3746389..4dcb584 100644
--- a/opensm/opensm/osm_state_mgr.c
+++ b/opensm/opensm/osm_state_mgr.c
@@ -1332,998 +1332,336 @@ int wait_for_pending_transactions(osm_stats_t * stats)
        return osm_exit_flag;
 }
 
-void osm_state_mgr_process(IN osm_state_mgr_t * const p_mgr,
-                          IN osm_signal_t signal)
+static void do_sweep(osm_sm_t * sm)
 {
        ib_api_status_t status;
        osm_remote_sm_t *p_remote_sm;
-       osm_signal_t tmp_signal;
 
-       CL_ASSERT(p_mgr);
-
-       OSM_LOG_ENTER(p_mgr->p_log, osm_state_mgr_process);
+       sm->master_sm_found = 0;
 
-       /* if we are exiting do nothing */
-       if (osm_exit_flag)
-               signal = OSM_SIGNAL_NONE;
-
-       while (signal != OSM_SIGNAL_NONE) {
-               if (osm_log_is_active(p_mgr->p_log, OSM_LOG_DEBUG)) {
-                       osm_log(p_mgr->p_log, OSM_LOG_DEBUG,
-                               "osm_state_mgr_process: "
-                               "Received signal %s in state %s\n",
-                               osm_get_sm_signal_str(signal),
-                               osm_get_sm_state_str(p_mgr->state));
+       /*
+        * If we already have switches, then try a light sweep.
+        * Otherwise, this is probably our first discovery pass
+        * or we are connected in loopback. In both cases do a
+        * heavy sweep.
+        * Note: If we are connected in loopback we want a heavy
+        * sweep, since we will not be getting any traps if there is
+        * a lost connection.
+        */
+       /*  if we are in DISCOVERING state - this means it is either in
+        *  initializing or wake up from STANDBY - run the heavy sweep */
+       if (cl_qmap_count(&sm->p_subn->sw_guid_tbl)
+           && sm->p_subn->sm_state != IB_SMINFO_STATE_DISCOVERING
+           && sm->p_subn->opt.force_heavy_sweep == FALSE
+           && sm->p_subn->force_heavy_sweep == FALSE
+           && sm->p_subn->subnet_initialization_error == FALSE
+           && (__osm_state_mgr_light_sweep_start(&sm->state_mgr) == 
IB_SUCCESS)) {
+               if (wait_for_pending_transactions(&sm->p_subn->p_osm->stats))
+                       return;
+               if (!sm->p_subn->force_heavy_sweep) {
+                       __osm_state_mgr_light_sweep_done_msg(&sm->state_mgr);
+                       return;
                }
+       }
 
-               /*
-                * If we're already sweeping and we get the signal to sweep,
-                * just ignore it harmlessly.
-                */
-               if ((p_mgr->state != OSM_SM_STATE_IDLE)
-                   && (p_mgr->state != OSM_SM_STATE_STANDBY)
-                   && (signal == OSM_SIGNAL_SWEEP)) {
-                       break;
-               }
+       /* go to heavy sweep */
+_repeat_discovery:
 
-               switch (p_mgr->state) {
-               case OSM_SM_STATE_IDLE:
-                       switch (signal) {
-                       case OSM_SIGNAL_SWEEP:
-                               /*
-                                * If the osm_sm_state_mgr is in NOT-ACTIVE 
state -
-                                * stay in IDLE
-                                */
-                               if (p_mgr->p_subn->sm_state == 
IB_SMINFO_STATE_NOTACTIVE) {
-                                       
osm_vendor_set_sm(p_mgr->p_mad_ctrl->h_bind, FALSE);
-                                       goto Idle;
-                               }
+       /* First of all - unset all flags */
+       sm->p_subn->force_heavy_sweep = FALSE;
+       sm->p_subn->subnet_initialization_error = FALSE;
 
-                               /*
-                                * If the osm_sm_state_mgr is in INIT state - 
signal
-                                * it with a INIT signal to move it to 
DISCOVERY state.
-                                */
-                               if (p_mgr->p_subn->sm_state == 
IB_SMINFO_STATE_INIT)
-                                       osm_sm_state_mgr_process(p_mgr->
-                                                                p_sm_state_mgr,
-                                                                
OSM_SM_SIGNAL_INIT);
-
-                               /*
-                                * If we already have switches, then try a 
light sweep.
-                                * Otherwise, this is probably our first 
discovery pass
-                                * or we are connected in loopback. In both 
cases do a
-                                * heavy sweep.
-                                * Note: If we are connected in loopback we 
want a heavy
-                                * sweep, since we will not be getting any 
traps if there is
-                                * a lost connection.
-                                */
-                               /*  if we are in DISCOVERING state - this means 
it is either in
-                                *  initializing or wake up from STANDBY - run 
the heavy sweep */
-                               if (cl_qmap_count(&p_mgr->p_subn->sw_guid_tbl)
-                                   && p_mgr->p_subn->sm_state !=
-                                   IB_SMINFO_STATE_DISCOVERING
-                                   && p_mgr->p_subn->opt.force_heavy_sweep ==
-                                   FALSE
-                                   && p_mgr->p_subn->force_heavy_sweep == FALSE
-                                   && 
p_mgr->p_subn->subnet_initialization_error == FALSE) {
-                                       if 
(__osm_state_mgr_light_sweep_start(p_mgr) == IB_SUCCESS) {
-                                               p_mgr->state = 
OSM_SM_STATE_SWEEP_LIGHT;
-                                       }
-                               } else {
-                                       /* First of all - if force_heavy_sweep 
is TRUE then
-                                        * need to unset it */
-                                       p_mgr->p_subn->force_heavy_sweep = 
FALSE;
-                                       /* If subnet_initialization_error is 
TRUE then
-                                        * need to unset it. */
-                                       
p_mgr->p_subn->subnet_initialization_error = FALSE;
-
-                                       /* rescan configuration updates */
-                                       status = 
osm_subn_rescan_conf_files(p_mgr->p_subn);
-                                       if (status != IB_SUCCESS) {
-                                               osm_log(p_mgr->p_log,
-                                                       OSM_LOG_ERROR,
-                                                       "osm_state_mgr_process: 
ERR 331A: "
-                                                       
"osm_subn_rescan_conf_file failed\n");
-                                       }
-
-                                       if (p_mgr->p_subn->sm_state != 
IB_SMINFO_STATE_MASTER)
-                                               p_mgr->p_subn->need_update = 1;
-
-                                       status = 
__osm_state_mgr_sweep_hop_0(p_mgr);
-                                       if (status == IB_SUCCESS) {
-                                               p_mgr->state = 
OSM_SM_STATE_SWEEP_HEAVY_SELF;
-                                       }
-                               }
-                             Idle:
-                               signal = OSM_SIGNAL_NONE;
-                               break;
+       /* rescan configuration updates */
+       status = osm_subn_rescan_conf_files(sm->p_subn);
+       if (status != IB_SUCCESS)
+               osm_log(sm->p_log, OSM_LOG_ERROR,
+                       "osm_state_mgr_process: ERR 331A: "
+                       "osm_subn_rescan_conf_file failed\n");
 
-                       case OSM_SIGNAL_IDLE_TIME_PROCESS_REQUEST:
-                               p_mgr->state = OSM_SM_STATE_PROCESS_REQUEST;
-                               signal = OSM_SIGNAL_IDLE_TIME_PROCESS;
-                               break;
+       if (sm->p_subn->sm_state != IB_SMINFO_STATE_MASTER)
+               sm->p_subn->need_update = 1;
 
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-                       }
-                       break;
+       status = __osm_state_mgr_sweep_hop_0(&sm->state_mgr);
+       if (status != IB_SUCCESS ||
+           wait_for_pending_transactions(&sm->p_subn->p_osm->stats))
+               return;
 
-               case OSM_SM_STATE_PROCESS_REQUEST:
-                       switch (signal) {
-                       case OSM_SIGNAL_IDLE_TIME_PROCESS:
-                               signal = 
osm_mcast_mgr_process_mgroups(p_mgr->p_mcast_mgr);
-                               switch (signal) {
-                               case OSM_SIGNAL_NONE:
-                                       p_mgr->state = OSM_SM_STATE_IDLE;
-                                       break;
-
-                               case OSM_SIGNAL_DONE_PENDING:
-                                       p_mgr->state = 
OSM_SM_STATE_PROCESS_REQUEST_WAIT;
-                                       signal = OSM_SIGNAL_NONE;
-                                       break;
-
-                               case OSM_SIGNAL_DONE:
-                                       p_mgr->state = 
OSM_SM_STATE_PROCESS_REQUEST_DONE;
-                                       break;
-
-                               default:
-                                       __osm_state_mgr_signal_error(p_mgr, 
signal);
-                                       signal = OSM_SIGNAL_NONE;
-                                       break;
-                               }
-                               break;
+       if (__osm_state_mgr_is_sm_port_down(&sm->state_mgr) == TRUE) {
+               __osm_state_mgr_sm_port_down_msg(&sm->state_mgr);
 
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-                       }
-                       break;
-
-               case OSM_SM_STATE_PROCESS_REQUEST_WAIT:
-                       switch (signal) {
-                       case OSM_SIGNAL_NO_PENDING_TRANSACTIONS:
-                               p_mgr->state = 
OSM_SM_STATE_PROCESS_REQUEST_DONE;
-                               break;
+               /* Run the drop manager - we want to clear all records */
+               osm_drop_mgr_process(&sm->drop_mgr);
 
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-                       }
-                       break;
-
-               case OSM_SM_STATE_PROCESS_REQUEST_DONE:
-                       switch (signal) {
-                       case OSM_SIGNAL_NO_PENDING_TRANSACTIONS:
-                       case OSM_SIGNAL_DONE:
-                               if (p_mgr->p_subn->force_heavy_sweep) {
-                                       /*
-                                        * Do not read next item from the idle 
queue.
-                                        * Immediate heavy sweep is requested, 
so it's
-                                        * more important.
-                                        * Besides, there is a chance that 
after the
-                                        * heavy sweep complition, idle queue 
processing
-                                        * that SM would have performed here 
will be obsolete.
-                                        */
-                                       if (osm_log_is_active(p_mgr->p_log, 
OSM_LOG_DEBUG))
-                                               osm_log(p_mgr->p_log, 
OSM_LOG_DEBUG,
-                                               "osm_state_mgr_process: "
-                                               "interrupting idle time queue 
processing - heavy sweep requested\n");
-                                       signal = OSM_SIGNAL_NONE;
-                                       p_mgr->state = OSM_SM_STATE_IDLE;
-                                       break;
-                               }
-                               signal = OSM_SIGNAL_IDLE_TIME_PROCESS;
-                               p_mgr->state = OSM_SM_STATE_PROCESS_REQUEST;
-                               break;
-
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-                       }
-                       break;
-
-               case OSM_SM_STATE_SWEEP_LIGHT:
-                       switch (signal) {
-                       case OSM_SIGNAL_LIGHT_SWEEP_FAIL:
-                       case OSM_SIGNAL_CHANGE_DETECTED:
-                               /*
-                                * Nothing else to do yet except change state.
-                                */
-                               p_mgr->state = OSM_SM_STATE_SWEEP_LIGHT_WAIT;
-                               signal = OSM_SIGNAL_NONE;
-                               break;
+               /* Move to DISCOVERING state */
+               osm_sm_state_mgr_process(&sm->sm_state_mgr,
+                                        OSM_SM_SIGNAL_DISCOVER);
+               return;
+       }
 
-                       case OSM_SIGNAL_NO_PENDING_TRANSACTIONS:
-                               /*
-                                * No change was detected on the subnet.
-                                * We can return to the idle state.
-                                */
-                               __osm_state_mgr_light_sweep_done_msg(p_mgr);
-                               p_mgr->state = OSM_SM_STATE_PROCESS_REQUEST;
-                               signal = OSM_SIGNAL_IDLE_TIME_PROCESS;
-                               break;
+       status = __osm_state_mgr_sweep_hop_1(&sm->state_mgr);
+       if (status != IB_SUCCESS ||
+           wait_for_pending_transactions(&sm->p_subn->p_osm->stats))
+               return;
 
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-                       }
-                       break;
+       /* discovery completed - check other sm presense */
+       if (sm->master_sm_found) {
+               sm->state_mgr.state = OSM_SM_STATE_STANDBY;
+               /*
+                * Call the sm_state_mgr with signal
+                * MASTER_OR_HIGHER_SM_DETECTED_DONE
+                */
+               osm_sm_state_mgr_process(&sm->sm_state_mgr,
+                                        
OSM_SM_SIGNAL_MASTER_OR_HIGHER_SM_DETECTED_DONE);
+               __osm_state_mgr_standby_msg(&sm->state_mgr);
+               return;
+       }
 
-               case OSM_SM_STATE_SWEEP_LIGHT_WAIT:
-                       switch (signal) {
-                       case OSM_SIGNAL_LIGHT_SWEEP_FAIL:
-                       case OSM_SIGNAL_CHANGE_DETECTED:
-                               /*
-                                * Nothing to do here. One subnet change 
typcially
-                                * begets another.... But need to wait for all 
transactions to
-                                * complete
-                                */
-                               break;
+       /* if new sweep requested - don't bother with the rest */
+       if (sm->p_subn->force_heavy_sweep)
+               goto _repeat_discovery;
 
-                       case OSM_SIGNAL_NO_PENDING_TRANSACTIONS:
-                               /*
-                                * A change was detected on the subnet.
-                                * Initiate a heavy sweep.
-                                */
-                               if (__osm_state_mgr_sweep_hop_0(p_mgr) == 
IB_SUCCESS) {
-                                       p_mgr->state = 
OSM_SM_STATE_SWEEP_HEAVY_SELF;
-                               }
-                               break;
+       __osm_state_mgr_sweep_heavy_done_msg(&sm->state_mgr);
 
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               break;
+       /* If we are MASTER - get the highest remote_sm, and
+        * see if it is higher than our local sm.
+        */
+       if (sm->p_subn->sm_state == IB_SMINFO_STATE_MASTER) {
+               p_remote_sm = __osm_state_mgr_get_highest_sm(&sm->state_mgr);
+               if (p_remote_sm != NULL) {
+                       /* report new ports (trap 64) before leaving MASTER */
+                       __osm_state_mgr_report_new_ports(&sm->state_mgr);
+
+                       /* need to handover the mastership
+                        * to the remote sm, and move to standby */
+                       __osm_state_mgr_send_handover(&sm->state_mgr, 
p_remote_sm);
+                       osm_sm_state_mgr_process(&sm->sm_state_mgr,
+                                                OSM_SM_SIGNAL_HANDOVER_SENT);
+                       sm->state_mgr.state = OSM_SM_STATE_STANDBY;
+                       return;
+               } else {
+                       /* We are the highest sm - check to see if there is
+                        * a remote SM that is in master state. */
+                       p_remote_sm =
+                           
__osm_state_mgr_exists_other_master_sm(&sm->state_mgr);
+                       if (p_remote_sm != NULL) {
+                               /* There is a remote SM that is master.
+                                * need to wait for that SM to relinquish 
control
+                                * of its portion of the subnet. C14-60.2.1.
+                                * Also - need to start polling on that SM. */
+                               sm->sm_state_mgr.p_polling_sm = p_remote_sm;
+                               osm_sm_state_mgr_process(&sm->sm_state_mgr,
+                                    OSM_SM_SIGNAL_WAIT_FOR_HANDOVER);
+                               return;
                        }
-                       signal = OSM_SIGNAL_NONE;
-                       break;
+               }
+       }
 
-               case OSM_SM_STATE_SWEEP_HEAVY_SELF:
-                       switch (signal) {
-                       case OSM_SIGNAL_CHANGE_DETECTED:
-                               /*
-                                * Nothing to do here. One subnet change 
typcially
-                                * begets another.... But need to wait for all 
transactions
-                                */
-                               signal = OSM_SIGNAL_NONE;
-                               break;
+       /* Need to continue with lid assignment */
+       osm_drop_mgr_process(&sm->drop_mgr);
 
-                       case OSM_SIGNAL_NO_PENDING_TRANSACTIONS:
-                               if (__osm_state_mgr_is_sm_port_down(p_mgr) == 
TRUE) {
-                                       __osm_state_mgr_sm_port_down_msg(p_mgr);
-
-                                       /* Run the drop manager - we want to 
clear all records */
-                                       osm_drop_mgr_process(p_mgr->p_drop_mgr);
-
-                                       /* Move to DISCOVERING state */
-                                       osm_sm_state_mgr_process(p_mgr->
-                                                                p_sm_state_mgr,
-                                                                
OSM_SM_SIGNAL_DISCOVER);
-
-                                       p_mgr->state = 
OSM_SM_STATE_PROCESS_REQUEST;
-                                       signal = OSM_SIGNAL_IDLE_TIME_PROCESS;
-                               } else {
-                                       if (__osm_state_mgr_sweep_hop_1(p_mgr)
-                                           == IB_SUCCESS) {
-                                               p_mgr->state = 
OSM_SM_STATE_SWEEP_HEAVY_SUBNET;
-                                       }
-                                       signal = OSM_SIGNAL_NONE;
-                               }
-                               break;
+       /*
+        * If we are not MASTER already - this means that we are
+        * in discovery state. call osm_sm_state_mgr with signal
+        * DISCOVERY_COMPLETED
+        */
+       if (sm->p_subn->sm_state == IB_SMINFO_STATE_DISCOVERING)
+               osm_sm_state_mgr_process(&sm->sm_state_mgr,
+                                        OSM_SM_SIGNAL_DISCOVERY_COMPLETED);
 
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-                       }
-                       break;
+       osm_pkey_mgr_process(sm->p_subn->p_osm);
 
-                       /*
-                        * There is no 'OSM_SM_STATE_SWEEP_HEAVY_WAIT' state 
since we
-                        * know that there are outstanding transactions on the 
wire already...
-                        */
-               case OSM_SM_STATE_SWEEP_HEAVY_SUBNET:
-                       switch (signal) {
-                       case OSM_SIGNAL_CHANGE_DETECTED:
-                               /*
-                                * Nothing to do here. One subnet change 
typically
-                                * begets another....
-                                */
-                               signal = OSM_SIGNAL_NONE;
-                               break;
+       osm_qos_setup(sm->p_subn->p_osm);
 
-                       case OSM_SIGNAL_MASTER_OR_HIGHER_SM_DETECTED:
-                               p_mgr->state = 
OSM_SM_STATE_MASTER_OR_HIGHER_SM_DETECTED;
-                               break;
+       /* try to restore SA DB (this should be before lid_mgr
+          because we may want to disable clients reregistration
+          when SA DB is restored) */
+       osm_sa_db_file_load(sm->p_subn->p_osm);
 
-                       case OSM_SIGNAL_NO_PENDING_TRANSACTIONS:
-                               /* if new sweep requiested - don't bother with 
the rest */
-                               if (p_mgr->p_subn->force_heavy_sweep) {
-                                       p_mgr->state = OSM_SM_STATE_IDLE;
-                                       signal = OSM_SIGNAL_SWEEP;
-                                       break;
-                               }
+       if (wait_for_pending_transactions(&sm->p_subn->p_osm->stats))
+               return;
 
-                               __osm_state_mgr_sweep_heavy_done_msg(p_mgr);
-
-                               /* If we are MASTER - get the highest 
remote_sm, and
-                                * see if it is higher than our local sm. If
-                                */
-                               if (p_mgr->p_subn->sm_state == 
IB_SMINFO_STATE_MASTER) {
-                                       p_remote_sm = 
__osm_state_mgr_get_highest_sm(p_mgr);
-                                       if (p_remote_sm != NULL) {
-                                               /* report new ports (trap 64) 
before leaving MASTER */
-                                               
__osm_state_mgr_report_new_ports(p_mgr);
-
-                                               /* need to handover the 
mastership
-                                                * to the remote sm, and move 
to standby */
-                                               
__osm_state_mgr_send_handover(p_mgr, p_remote_sm);
-                                               osm_sm_state_mgr_process(p_mgr->
-                                                                        
p_sm_state_mgr,
-                                                                        
OSM_SM_SIGNAL_HANDOVER_SENT);
-                                               p_mgr->state = 
OSM_SM_STATE_STANDBY;
-                                               signal = OSM_SIGNAL_NONE;
-                                               break;
-                                       } else {
-                                               /* We are the highest sm - 
check to see if there is
-                                                * a remote SM that is in 
master state. */
-                                               p_remote_sm =
-                                                   
__osm_state_mgr_exists_other_master_sm(p_mgr);
-                                               if (p_remote_sm != NULL) {
-                                                       /* There is a remote SM 
that is master.
-                                                        * need to wait for 
that SM to relinquish control
-                                                        * of its portion of 
the subnet. C14-60.2.1.
-                                                        * Also - need to start 
polling on that SM. */
-                                                       p_mgr->p_sm_state_mgr->
-                                                           p_polling_sm = 
p_remote_sm;
-                                                       osm_sm_state_mgr_process
-                                                           (p_mgr->
-                                                            p_sm_state_mgr,
-                                                            
OSM_SM_SIGNAL_WAIT_FOR_HANDOVER);
-                                                       p_mgr->state = 
OSM_SM_STATE_PROCESS_REQUEST;
-                                                       signal = 
OSM_SIGNAL_IDLE_TIME_PROCESS;
-                                                       break;
-                                               }
-                                       }
-                               }
+       osm_lid_mgr_process_sm(&sm->lid_mgr);
+       if (wait_for_pending_transactions(&sm->p_subn->p_osm->stats))
+               return;
 
-                               /* Need to continue with lid assignment */
-                               osm_drop_mgr_process(p_mgr->p_drop_mgr);
+       __osm_state_mgr_set_sm_lid_done_msg(&sm->state_mgr);
+       __osm_state_mgr_notify_lid_change(&sm->state_mgr);
 
-                               p_mgr->state = OSM_SM_STATE_SET_PKEY;
+       osm_lid_mgr_process_subnet(&sm->lid_mgr);
+       if (wait_for_pending_transactions(&sm->p_subn->p_osm->stats))
+               return;
 
-                               /*
-                                * If we are not MASTER already - this means 
that we are
-                                * in discovery state. call osm_sm_state_mgr 
with signal
-                                * DISCOVERY_COMPLETED
-                                */
-                               if (p_mgr->p_subn->sm_state == 
IB_SMINFO_STATE_DISCOVERING)
-                                       osm_sm_state_mgr_process(p_mgr->
-                                                                p_sm_state_mgr,
-                                                                
OSM_SM_SIGNAL_DISCOVERY_COMPLETED);
+       /* At this point we need to check the consistency of
+        * the port_lid_tbl under the subnet. There might be
+        * errors in it if PortInfo Set reqeusts didn't reach
+        * their destination. */
+       __osm_state_mgr_check_tbl_consistency(&sm->state_mgr);
 
-                               /* the returned signal might be DONE or 
DONE_PENDING */
-                               signal = 
osm_pkey_mgr_process(p_mgr->p_subn->p_osm);
+       __osm_state_mgr_lid_assign_msg(&sm->state_mgr);
 
-                               /* the returned signal is always DONE */
-                               tmp_signal = 
osm_qos_setup(p_mgr->p_subn->p_osm);
+       /*
+        * Proceed with unicast forwarding table configuration.
+        * First - send trap 64 on newly discovered endports
+        */
+       __osm_state_mgr_report_new_ports(&sm->state_mgr);
 
-                               if (tmp_signal == OSM_SIGNAL_DONE_PENDING)
-                                       signal = OSM_SIGNAL_DONE_PENDING;
+       osm_ucast_mgr_process(&sm->ucast_mgr);
+       if (wait_for_pending_transactions(&sm->p_subn->p_osm->stats))
+               return;
 
-                               /* try to restore SA DB (this should be before 
lid_mgr
-                                  because we may want to disable clients 
reregistration
-                                  when SA DB is restored) */
-                               osm_sa_db_file_load(p_mgr->p_subn->p_osm);
+       /* We are done setting all LFTs so clear the ignore existing.
+        * From now on, as long as we are still master, we want to
+        * take into account these lfts. */
+       sm->p_subn->ignore_existing_lfts = FALSE;
 
-                               break;
+       __osm_state_mgr_switch_config_msg(&sm->state_mgr);
 
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-                       }
-                       break;
+       if (!sm->p_subn->opt.disable_multicast) {
+               osm_mcast_mgr_process(&sm->mcast_mgr);
+               if (wait_for_pending_transactions(&sm->p_subn->p_osm->stats))
+                       return;
+               __osm_state_mgr_multicast_config_msg(&sm->state_mgr);
+       }
 
-               case OSM_SM_STATE_SET_PKEY:
-                       switch (signal) {
-                       case OSM_SIGNAL_DONE:
-                               p_mgr->state = OSM_SM_STATE_SET_PKEY_DONE;
-                               break;
+       /*
+        * The LINK_PORTS state is required since we can not count on
+        * the port state change MADs to succeed. This is an artifact
+        * of the spec defining state change from state X to state X
+        * as an error. The hardware then is not required to process
+        * other parameters provided by the Set(PortInfo) Packet.
+        */
 
-                       case OSM_SIGNAL_DONE_PENDING:
-                               /*
-                                * There are outstanding transactions, so we
-                                * must wait for the wire to clear.
-                                */
-                               p_mgr->state = OSM_SM_STATE_SET_PKEY_WAIT;
-                               signal = OSM_SIGNAL_NONE;
-                               break;
+       osm_link_mgr_process(&sm->link_mgr, IB_LINK_NO_CHANGE);
+       if (wait_for_pending_transactions(&sm->p_subn->p_osm->stats))
+               return;
 
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-                       }
-                       break;
+       __osm_state_mgr_links_ports_msg(&sm->state_mgr);
 
-               case OSM_SM_STATE_SET_PKEY_WAIT:
-                       switch (signal) {
-                       case OSM_SIGNAL_NO_PENDING_TRANSACTIONS:
-                               p_mgr->state = OSM_SM_STATE_SET_PKEY_DONE;
-                               break;
+       osm_link_mgr_process(&sm->link_mgr, IB_LINK_ARMED);
+       if (wait_for_pending_transactions(&sm->p_subn->p_osm->stats))
+               return;
 
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-                       }
-                       break;
+       __osm_state_mgr_links_armed_msg(&sm->state_mgr);
 
-               case OSM_SM_STATE_SET_PKEY_DONE:
-                       switch (signal) {
-                       case OSM_SIGNAL_NO_PENDING_TRANSACTIONS:
-                       case OSM_SIGNAL_DONE:
-                               p_mgr->state = OSM_SM_STATE_SET_SM_UCAST_LID;
-                               signal = 
osm_lid_mgr_process_sm(p_mgr->p_lid_mgr);
-                               break;
+       osm_link_mgr_process(&sm->link_mgr, IB_LINK_ACTIVE);
+       if (wait_for_pending_transactions(&sm->p_subn->p_osm->stats))
+               return;
 
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-                       }
-                       break;
+       /*
+        * The sweep completed!
+        */
 
-               case OSM_SM_STATE_SET_SM_UCAST_LID:
-                       switch (signal) {
-                       case OSM_SIGNAL_DONE:
-                               p_mgr->state = 
OSM_SM_STATE_SET_SM_UCAST_LID_DONE;
-                               break;
+       /* in any case we zero this flag */
+       sm->p_subn->coming_out_of_standby = FALSE;
 
-                       case OSM_SIGNAL_DONE_PENDING:
-                               /*
-                                * There are outstanding transactions, so we
-                                * must wait for the wire to clear.
-                                */
-                               p_mgr->state = 
OSM_SM_STATE_SET_SM_UCAST_LID_WAIT;
-                               signal = OSM_SIGNAL_NONE;
-                               break;
+       /* If there were errors - then the subnet is not really up */
+       if (sm->p_subn->subnet_initialization_error == TRUE)
+               __osm_state_mgr_init_errors_msg(&sm->state_mgr);
+       else {
+               /* The subnet is up correctly - set the first_time_master_sweep
+                * flag (if it is on) to FALSE. */
+               if (sm->p_subn->first_time_master_sweep == TRUE)
+                       sm->p_subn->first_time_master_sweep = FALSE;
+                       sm->p_subn->need_update = 0;
 
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-                       }
-                       break;
+               osm_dump_all(sm->p_subn->p_osm);
+               __osm_state_mgr_up_msg(&sm->state_mgr);
 
-               case OSM_SM_STATE_SET_SM_UCAST_LID_WAIT:
-                       switch (signal) {
-                       case OSM_SIGNAL_NO_PENDING_TRANSACTIONS:
-                               p_mgr->state = 
OSM_SM_STATE_SET_SM_UCAST_LID_DONE;
-                               break;
+               if (osm_log_is_active(sm->p_log, OSM_LOG_VERBOSE))
+                       osm_sa_db_file_dump(sm->p_subn->p_osm);
+       }
 
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-                       }
-                       break;
+       /*
+        * Finally signal the subnet up event
+        */
+       cl_event_signal(&sm->subnet_up_event);
 
-               case OSM_SM_STATE_SET_SM_UCAST_LID_DONE:
-                       switch (signal) {
-                       case OSM_SIGNAL_NO_PENDING_TRANSACTIONS:
-                       case OSM_SIGNAL_DONE:
-                               __osm_state_mgr_set_sm_lid_done_msg(p_mgr);
-                               __osm_state_mgr_notify_lid_change(p_mgr);
-                               p_mgr->state = 
OSM_SM_STATE_SET_SUBNET_UCAST_LIDS;
-                               signal = 
osm_lid_mgr_process_subnet(p_mgr->p_lid_mgr);
-                               break;
+       /* if we got a signal to force heavy sweep or errors
+        * in the middle of the sweep - try another sweep. */
+       if (sm->p_subn->force_heavy_sweep
+           || sm->p_subn->subnet_initialization_error)
+               osm_sm_signal(sm, OSM_SIGNAL_SWEEP);
+}
 
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-                       }
-                       break;
+static void do_process_mgrp_queue(osm_sm_t * sm)
+{
+       osm_mcast_mgr_process_mgroups(&sm->mcast_mgr);
+       wait_for_pending_transactions(&sm->p_subn->p_osm->stats);
+}
 
-               case OSM_SM_STATE_SET_SUBNET_UCAST_LIDS:
-                       switch (signal) {
-                       case OSM_SIGNAL_DONE:
-                               /*
-                                * The LID Manager is done processing.
-                                * There are no outstanding transactions, so we
-                                * can move on to configuring the forwarding 
tables.
-                                */
-                               p_mgr->state = 
OSM_SM_STATE_SET_SUBNET_UCAST_LIDS_DONE;
-                               break;
+void osm_state_mgr_process(IN osm_state_mgr_t * const p_mgr,
+                          IN osm_signal_t signal)
+{
+       CL_ASSERT(p_mgr);
 
-                       case OSM_SIGNAL_DONE_PENDING:
-                               /*
-                                * The LID Manager is done processing.
-                                * There are outstanding transactions, so we
-                                * must wait for the wire to clear.
-                                */
-                               p_mgr->state = 
OSM_SM_STATE_SET_SUBNET_UCAST_LIDS_WAIT;
-                               signal = OSM_SIGNAL_NONE;
-                               break;
+       OSM_LOG_ENTER(p_mgr->p_log, osm_state_mgr_process);
 
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-                       }
-                       break;
+       if (osm_log_is_active(p_mgr->p_log, OSM_LOG_DEBUG))
+               osm_log(p_mgr->p_log, OSM_LOG_DEBUG,
+                       "osm_state_mgr_process: "
+                       "Received signal %s in state %s\n",
+                       osm_get_sm_signal_str(signal),
+                       osm_get_sm_state_str(p_mgr->state));
 
+       switch (p_mgr->state) {
+       case OSM_SM_STATE_IDLE:
+               switch (signal) {
+               case OSM_SIGNAL_SWEEP:
                        /*
-                        * In this state, the Unicast Manager has completed 
processing,
-                        * but there are still transactions on the wire.  
Therefore,
-                        * wait here until the wire clears.
+                        * If the osm_sm_state_mgr is in NOT-ACTIVE state -
+                        * stay in IDLE
                         */
-               case OSM_SM_STATE_SET_SUBNET_UCAST_LIDS_WAIT:
-                       switch (signal) {
-                       case OSM_SIGNAL_NO_PENDING_TRANSACTIONS:
-                               /*
-                                * The LID Manager is done processing.
-                                * There are no outstanding transactions, so we
-                                * can move on to configuring the forwarding 
tables.
-                                */
-                               p_mgr->state = 
OSM_SM_STATE_SET_SUBNET_UCAST_LIDS_DONE;
-                               break;
-
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-                       }
-                       break;
-
-               case OSM_SM_STATE_SET_SUBNET_UCAST_LIDS_DONE:
-                       switch (signal) {
-                       case OSM_SIGNAL_DONE:
-                       case OSM_SIGNAL_NO_PENDING_TRANSACTIONS:
-                               /* At this point we need to check the 
consistency of
-                                * the port_lid_tbl under the subnet. There 
might be
-                                * errors in it if PortInfo Set reqeusts didn't 
reach
-                                * their destination. */
-                               __osm_state_mgr_check_tbl_consistency(p_mgr);
-
-                               __osm_state_mgr_lid_assign_msg(p_mgr);
-
-                               /*
-                                * OK, the wire is clear, so proceed with
-                                * unicast forwarding table configuration.
-                                * First - send trap 64 on newly discovered 
endports
-                                */
-                               __osm_state_mgr_report_new_ports(p_mgr);
-
-                               p_mgr->state = OSM_SM_STATE_SET_UCAST_TABLES;
-                               signal = 
osm_ucast_mgr_process(p_mgr->p_ucast_mgr);
-
-                               break;
-
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-                       }
-                       break;
-
-               case OSM_SM_STATE_SET_UCAST_TABLES:
-                       switch (signal) {
-                       case OSM_SIGNAL_DONE:
-                               p_mgr->state = 
OSM_SM_STATE_SET_UCAST_TABLES_DONE;
-                               break;
-
-                       case OSM_SIGNAL_DONE_PENDING:
-                               /*
-                                * The Unicast Manager is done processing.
-                                * There are outstanding transactions, so we
-                                * must wait for the wire to clear.
-                                */
-                               p_mgr->state = 
OSM_SM_STATE_SET_UCAST_TABLES_WAIT;
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-                       }
-                       break;
-
-               case OSM_SM_STATE_SET_UCAST_TABLES_WAIT:
-                       switch (signal) {
-                       case OSM_SIGNAL_NO_PENDING_TRANSACTIONS:
-                               p_mgr->state = 
OSM_SM_STATE_SET_UCAST_TABLES_DONE;
-                               break;
-
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
+                       if (p_mgr->p_subn->sm_state == 
IB_SMINFO_STATE_NOTACTIVE) {
+                               osm_vendor_set_sm(p_mgr->p_mad_ctrl->h_bind, 
FALSE);
                                break;
                        }
-                       break;
-
-               case OSM_SM_STATE_SET_UCAST_TABLES_DONE:
-                       switch (signal) {
-                       case OSM_SIGNAL_NO_PENDING_TRANSACTIONS:
-                       case OSM_SIGNAL_DONE:
-                               /* We are done setting all LFTs so clear the 
ignore existing.
-                                * From now on, as long as we are still master, 
we want to
-                                * take into account these lfts. */
-                               p_mgr->p_subn->ignore_existing_lfts = FALSE;
-
-                               __osm_state_mgr_switch_config_msg(p_mgr);
-
-                               if (!p_mgr->p_subn->opt.disable_multicast) {
-                                       p_mgr->state = 
OSM_SM_STATE_SET_MCAST_TABLES;
-                                       signal = 
osm_mcast_mgr_process(p_mgr->p_mcast_mgr);
-                               } else {
-                                       p_mgr->state = 
OSM_SM_STATE_SET_LINK_PORTS;
-                                       signal =
-                                           osm_link_mgr_process(p_mgr->
-                                                                p_link_mgr, 
IB_LINK_NO_CHANGE);
-                               }
-                               break;
-
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-                       }
-                       break;
-
-               case OSM_SM_STATE_SET_MCAST_TABLES:
-                       switch (signal) {
-                       case OSM_SIGNAL_DONE:
-                               p_mgr->state = 
OSM_SM_STATE_SET_MCAST_TABLES_DONE;
-                               break;
-
-                       case OSM_SIGNAL_DONE_PENDING:
-                               /*
-                                * The Multicast Manager is done processing.
-                                * There are outstanding transactions, so we
-                                * must wait for the wire to clear.
-                                */
-                               p_mgr->state = 
OSM_SM_STATE_SET_MCAST_TABLES_WAIT;
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-                       }
-                       break;
-
-               case OSM_SM_STATE_SET_MCAST_TABLES_WAIT:
-                       switch (signal) {
-                       case OSM_SIGNAL_NO_PENDING_TRANSACTIONS:
-                               p_mgr->state = 
OSM_SM_STATE_SET_MCAST_TABLES_DONE;
-                               break;
-
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-                       }
-                       break;
-
-               case OSM_SM_STATE_SET_MCAST_TABLES_DONE:
-                       switch (signal) {
-                       case OSM_SIGNAL_NO_PENDING_TRANSACTIONS:
-                       case OSM_SIGNAL_DONE:
-                               __osm_state_mgr_multicast_config_msg(p_mgr);
-
-                               p_mgr->state = OSM_SM_STATE_SET_LINK_PORTS;
-                               signal = 
osm_link_mgr_process(p_mgr->p_link_mgr, IB_LINK_NO_CHANGE);
-                               break;
-
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-                       }
-                       break;
 
                        /*
-                        * The LINK_PORTS state is required since we can not 
count on
-                        * the port state change MADs to succeed. This is an 
artifact
-                        * of the spec defining state change from state X to 
state X
-                        * as an error. The hardware then is not required to 
process
-                        * other parameters provided by the Set(PortInfo) 
Packet.
+                        * If the osm_sm_state_mgr is in INIT state - signal
+                        * it with a INIT signal to move it to DISCOVERY state.
                         */
-               case OSM_SM_STATE_SET_LINK_PORTS:
-                       switch (signal) {
-                       case OSM_SIGNAL_DONE:
-                               p_mgr->state = OSM_SM_STATE_SET_LINK_PORTS_DONE;
-                               break;
-
-                       case OSM_SIGNAL_DONE_PENDING:
-                               /*
-                                * The Link Manager is done processing.
-                                * There are outstanding transactions, so we
-                                * must wait for the wire to clear.
-                                */
-                               p_mgr->state = OSM_SM_STATE_SET_LINK_PORTS_WAIT;
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-                       }
-                       break;
-
-               case OSM_SM_STATE_SET_LINK_PORTS_WAIT:
-                       switch (signal) {
-                       case OSM_SIGNAL_NO_PENDING_TRANSACTIONS:
-                               p_mgr->state = OSM_SM_STATE_SET_LINK_PORTS_DONE;
-                               break;
-
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-                       }
-                       break;
-
-               case OSM_SM_STATE_SET_LINK_PORTS_DONE:
-                       switch (signal) {
-                       case OSM_SIGNAL_NO_PENDING_TRANSACTIONS:
-                       case OSM_SIGNAL_DONE:
-
-                               __osm_state_mgr_links_ports_msg(p_mgr);
-
-                               p_mgr->state = OSM_SM_STATE_SET_ARMED;
-                               signal = 
osm_link_mgr_process(p_mgr->p_link_mgr, IB_LINK_ARMED);
-                               break;
-
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-                       }
-                       break;
-
-               case OSM_SM_STATE_SET_ARMED:
-                       switch (signal) {
-                       case OSM_SIGNAL_DONE:
-                               p_mgr->state = OSM_SM_STATE_SET_ARMED_DONE;
-                               break;
-
-                       case OSM_SIGNAL_DONE_PENDING:
-                               /*
-                                * The Link Manager is done processing.
-                                * There are outstanding transactions, so we
-                                * must wait for the wire to clear.
-                                */
-                               p_mgr->state = OSM_SM_STATE_SET_ARMED_WAIT;
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-                       }
-                       break;
-
-               case OSM_SM_STATE_SET_ARMED_WAIT:
-                       switch (signal) {
-                       case OSM_SIGNAL_NO_PENDING_TRANSACTIONS:
-                               p_mgr->state = OSM_SM_STATE_SET_ARMED_DONE;
-                               break;
-
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-                       }
-                       break;
-
-               case OSM_SM_STATE_SET_ARMED_DONE:
-                       switch (signal) {
-                       case OSM_SIGNAL_NO_PENDING_TRANSACTIONS:
-                       case OSM_SIGNAL_DONE:
-
-                               __osm_state_mgr_links_armed_msg(p_mgr);
-
-                               p_mgr->state = OSM_SM_STATE_SET_ACTIVE;
-                               signal = 
osm_link_mgr_process(p_mgr->p_link_mgr, IB_LINK_ACTIVE);
-                               break;
-
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-                       }
-                       break;
-
-               case OSM_SM_STATE_SET_ACTIVE:
-                       switch (signal) {
-                       case OSM_SIGNAL_DONE:
-                               /*
-                                * Don't change the signal, just the state.
-                                */
-                               p_mgr->state = OSM_SM_STATE_SUBNET_UP;
-                               break;
-
-                       case OSM_SIGNAL_DONE_PENDING:
-                               /*
-                                * The Link Manager is done processing.
-                                * There are outstanding transactions, so we
-                                * must wait for the wire to clear.
-                                */
-                               p_mgr->state = OSM_SM_STATE_SET_ACTIVE_WAIT;
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-                       }
-                       break;
-
-               case OSM_SM_STATE_SET_ACTIVE_WAIT:
-                       switch (signal) {
-                       case OSM_SIGNAL_NO_PENDING_TRANSACTIONS:
-                               /*
-                                * Don't change the signal, just the state.
-                                */
-                               p_mgr->state = OSM_SM_STATE_SUBNET_UP;
-                               break;
-
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-                       }
-                       break;
-
-               case OSM_SM_STATE_SUBNET_UP:
-                       switch (signal) {
-                       case OSM_SIGNAL_NO_PENDING_TRANSACTIONS:
-                       case OSM_SIGNAL_DONE:
-                               /*
-                                * The sweep completed!
-                                */
-
-                               /* in any case we zero this flag */
-                               p_mgr->p_subn->coming_out_of_standby = FALSE;
-
-                               /* If there were errors - then the subnet is 
not really up */
-                               if (p_mgr->p_subn->subnet_initialization_error 
== TRUE) {
-                                       __osm_state_mgr_init_errors_msg(p_mgr);
-                               } else {
-                                       /* The subnet is up correctly - set the 
first_time_master_sweep flag
-                                        * (if it is on) to FALSE. */
-                                       if 
(p_mgr->p_subn->first_time_master_sweep == TRUE) {
-                                               
p_mgr->p_subn->first_time_master_sweep = FALSE;
-                                       }
-                                       p_mgr->p_subn->need_update = 0;
-
-                                       osm_dump_all(p_mgr->p_subn->p_osm);
-                                       __osm_state_mgr_up_msg(p_mgr);
-
-                                       if (osm_log_is_active(p_mgr->p_log, 
OSM_LOG_VERBOSE))
-                                               
osm_sa_db_file_dump(p_mgr->p_subn->p_osm);
-                               }
-                               p_mgr->state = OSM_SM_STATE_PROCESS_REQUEST;
-                               signal = OSM_SIGNAL_IDLE_TIME_PROCESS;
-
-                               /*
-                                * Finally signal the subnet up event
-                                */
-                               status =
-                                   cl_event_signal(p_mgr->p_subnet_up_event);
-                               if (status != IB_SUCCESS) {
-                                       osm_log(p_mgr->p_log, OSM_LOG_ERROR,
-                                               "osm_state_mgr_process: ERR 
3319: "
-                                               "Invalid SM state %u\n",
-                                               p_mgr->state);
-                               }
-                               break;
-
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-                       }
-                       break;
-
-               case OSM_SM_STATE_MASTER_OR_HIGHER_SM_DETECTED:
-                       switch (signal) {
-                       case OSM_SIGNAL_CHANGE_DETECTED:
-                               /*
-                                * Nothing to do here. One subnet change 
typically
-                                * begets another....
-                                */
-                               break;
-
-                       case OSM_SIGNAL_MASTER_OR_HIGHER_SM_DETECTED:
-                               /*
-                                * If we lost once, we might lose again. 
Nothing to do.
-                                */
-                               break;
-
-                       case OSM_SIGNAL_NO_PENDING_TRANSACTIONS:
-                               p_mgr->state = OSM_SM_STATE_STANDBY;
-                               /*
-                                * Call the sm_state_mgr with signal
-                                * MASTER_OR_HIGHER_SM_DETECTED_DONE
-                                */
+                       if (p_mgr->p_subn->sm_state == IB_SMINFO_STATE_INIT)
                                osm_sm_state_mgr_process(p_mgr->p_sm_state_mgr,
-                                                        
OSM_SM_SIGNAL_MASTER_OR_HIGHER_SM_DETECTED_DONE);
-                               __osm_state_mgr_standby_msg(p_mgr);
-                               break;
+                                                        OSM_SM_SIGNAL_INIT);
 
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               break;
-                       }
-                       signal = OSM_SIGNAL_NONE;
+                       do_sweep(p_mgr->sm);
                        break;
 
-               case OSM_SM_STATE_STANDBY:
-                       switch (signal) {
-                       case OSM_SIGNAL_EXIT_STBY:
-                               /*
-                                * Need to force re-write of sm_base_lid to all 
ports
-                                * to do that we want all the ports to be 
considered
-                                * foriegn
-                                */
-                               signal = OSM_SIGNAL_SWEEP;
-                               __osm_state_mgr_clean_known_lids(p_mgr);
-                               p_mgr->state = OSM_SM_STATE_IDLE;
-                               break;
-
-                       case OSM_SIGNAL_NO_PENDING_TRANSACTIONS:
-                               /*
-                                * Nothing to do here - need to stay at this 
state
-                                */
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-
-                       default:
-                               __osm_state_mgr_signal_error(p_mgr, signal);
-                               signal = OSM_SIGNAL_NONE;
-                               break;
-                       }
-                       /* stay with the same signal - so we can start the 
sweep */
+               case OSM_SIGNAL_IDLE_TIME_PROCESS_REQUEST:
+                       do_process_mgrp_queue(p_mgr->sm);
                        break;
 
                default:
-                       CL_ASSERT(FALSE);
-                       osm_log(p_mgr->p_log, OSM_LOG_ERROR,
-                               "osm_state_mgr_process: ERR 3320: "
-                               "Invalid SM state %u\n", p_mgr->state);
-                       p_mgr->state = OSM_SM_STATE_IDLE;
-                       signal = OSM_SIGNAL_NONE;
+                       __osm_state_mgr_signal_error(p_mgr, signal);
                        break;
                }
+               break;
 
-               /* if we got a signal to force immediate heavy sweep in the 
middle of the sweep -
-                * try another sweep. */
-               if ((p_mgr->p_subn->force_heavy_sweep) &&
-                   (p_mgr->state == OSM_SM_STATE_IDLE)) {
-                       signal = OSM_SIGNAL_SWEEP;
-               }
-               /* if we got errors during the initialization in the middle of 
the sweep -
-                * try another sweep. */
-               if ((p_mgr->p_subn->subnet_initialization_error) &&
-                   (p_mgr->state == OSM_SM_STATE_IDLE)) {
-                       signal = OSM_SIGNAL_SWEEP;
+       case OSM_SM_STATE_STANDBY:
+               switch (signal) {
+               case OSM_SIGNAL_EXIT_STBY:
+                       /*
+                        * Need to force re-write of sm_base_lid to all ports
+                        * to do that we want all the ports to be considered
+                        * foriegn
+                        */
+                       __osm_state_mgr_clean_known_lids(p_mgr);
+                       p_mgr->state = OSM_SM_STATE_IDLE;
+                       osm_sm_signal(p_mgr->sm, OSM_SIGNAL_SWEEP);
+                       break;
+               default:
+                       __osm_state_mgr_signal_error(p_mgr, signal);
+                       break;
                }
+               /* stay with the same signal - so we can start the sweep */
+               break;
 
+       default:
+               CL_ASSERT(FALSE);
+               osm_log(p_mgr->p_log, OSM_LOG_ERROR,
+                       "osm_state_mgr_process: ERR 3320: "
+                       "Invalid SM state %u\n", p_mgr->state);
+               break;
        }
 
        OSM_LOG_EXIT(p_mgr->p_log);
diff --git a/opensm/opensm/osm_sw_info_rcv.c b/opensm/opensm/osm_sw_info_rcv.c
index dbf8b8c..2cc887a 100644
--- a/opensm/opensm/osm_sw_info_rcv.c
+++ b/opensm/opensm/osm_sw_info_rcv.c
@@ -562,8 +562,7 @@ void osm_si_rcv_process(IN void *context, IN void *data)
                        if (__osm_si_rcv_process_existing
                            (sm, p_node, p_madw)) {
                                CL_PLOCK_RELEASE(sm->p_lock);
-                               osm_sm_signal(&sm->p_subn->p_osm->sm,
-                                             OSM_SIGNAL_CHANGE_DETECTED);
+                               sm->p_subn->force_heavy_sweep = 1;
                                goto Exit;
                        }
                }
diff --git a/opensm/opensm/osm_sweep_fail_ctrl.c 
b/opensm/opensm/osm_sweep_fail_ctrl.c
index 92b3165..3a5190f 100644
--- a/opensm/opensm/osm_sweep_fail_ctrl.c
+++ b/opensm/opensm/osm_sweep_fail_ctrl.c
@@ -65,7 +65,7 @@ static void __osm_sweep_fail_ctrl_disp_callback(IN void 
*context,
        /*
           Notify the state manager that we had a light sweep failure.
         */
-       osm_sm_signal(p_ctrl->sm, OSM_SIGNAL_LIGHT_SWEEP_FAIL);
+       p_ctrl->sm->p_subn->force_heavy_sweep = 1;
 
        OSM_LOG_EXIT(p_ctrl->sm->p_log);
 }
-- 
1.5.4.rc2.60.gb2e62

_______________________________________________
general mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to