/* * iser_conn_destroy() * Tear down an initiator or target connection. */ static void iser_conn_destroy(idm_conn_t *ic) { iser_conn_t *iser_conn; iser_conn = (iser_conn_t *)ic->ic_transport_private; iser_internal_conn_destroy(iser_conn); ic->ic_transport_private = NULL; }
/* * Handle EVENT FAILURE */ static ibt_cm_status_t iser_handle_cm_event_failure(ibt_cm_event_t *evp) { iser_chan_t *chan; chan = (iser_chan_t *)ibt_get_chan_private(evp->cm_channel); ISER_LOG(CE_NOTE, "iser_handle_cm_event_failure: chan (0x%p): " "code: %d msg: %d reason: %d", (void *)chan, evp->cm_event.failed.cf_code, evp->cm_event.failed.cf_msg, evp->cm_event.failed.cf_reason); if ((evp->cm_channel == NULL) || (chan == NULL)) { /* channel not established yet */ return (IBT_CM_ACCEPT); } if ((evp->cm_event.failed.cf_code != IBT_CM_FAILURE_STALE) && (evp->cm_event.failed.cf_msg == IBT_CM_FAILURE_REQ)) { /* * This end is active, just ignore, ibt_open_rc_channel() * caller will take care of cleanup. */ return (IBT_CM_ACCEPT); } /* handle depending upon our connection state */ mutex_enter(&chan->ic_conn->ic_lock); switch (chan->ic_conn->ic_stage) { case ISER_CONN_STAGE_UNDEFINED: case ISER_CONN_STAGE_CLOSED: /* do nothing, just drop the lock */ mutex_exit(&chan->ic_conn->ic_lock); break; case ISER_CONN_STAGE_ALLOCATED: /* * We blew up or were offlined during connection * establishment. Teardown the iSER conn and chan * handles. */ mutex_exit(&chan->ic_conn->ic_lock); iser_internal_conn_destroy(chan->ic_conn); break; case ISER_CONN_STAGE_IC_DISCONNECTED: case ISER_CONN_STAGE_IC_FREED: case ISER_CONN_STAGE_CLOSING: /* update to CLOSED, then drop the lock */ chan->ic_conn->ic_stage = ISER_CONN_STAGE_CLOSED; mutex_exit(&chan->ic_conn->ic_lock); break; case ISER_CONN_STAGE_IC_CONNECTED: case ISER_CONN_STAGE_HELLO_SENT: case ISER_CONN_STAGE_HELLO_SENT_FAIL: case ISER_CONN_STAGE_HELLO_WAIT: case ISER_CONN_STAGE_HELLO_RCV: case ISER_CONN_STAGE_HELLO_RCV_FAIL: case ISER_CONN_STAGE_HELLOREPLY_SENT: case ISER_CONN_STAGE_HELLOREPLY_SENT_FAIL: case ISER_CONN_STAGE_HELLOREPLY_RCV: case ISER_CONN_STAGE_HELLOREPLY_RCV_FAIL: case ISER_CONN_STAGE_LOGGED_IN: /* fail the transport and move the conn to CLOSING */ idm_conn_event(chan->ic_conn->ic_idmc, CE_TRANSPORT_FAIL, IDM_STATUS_FAIL); chan->ic_conn->ic_stage = ISER_CONN_STAGE_CLOSING; mutex_exit(&chan->ic_conn->ic_lock); break; default: mutex_exit(&chan->ic_conn->ic_lock); ASSERT(0); } /* accept the event */ return (IBT_CM_ACCEPT); }
static ibt_cm_status_t iser_handle_cm_conn_closed(ibt_cm_event_t *evp) { iser_chan_t *chan; chan = (iser_chan_t *)ibt_get_chan_private(evp->cm_channel); ISER_LOG(CE_NOTE, "iser_handle_cm_conn_closed: chan (0x%p) " "reason (0x%x)", (void *)chan, evp->cm_event.closed); switch (evp->cm_event.closed) { case IBT_CM_CLOSED_DREP_RCVD: /* we requested a disconnect */ case IBT_CM_CLOSED_ALREADY: /* duplicate close */ /* ignore these */ return (IBT_CM_ACCEPT); case IBT_CM_CLOSED_DREQ_RCVD: /* request to close the channel */ case IBT_CM_CLOSED_REJ_RCVD: /* reject after conn establishment */ case IBT_CM_CLOSED_DREQ_TIMEOUT: /* our close request timed out */ case IBT_CM_CLOSED_DUP: /* duplicate close request */ case IBT_CM_CLOSED_ABORT: /* aborted connection establishment */ case IBT_CM_CLOSED_STALE: /* stale / unref connection */ /* handle these depending upon our connection state */ mutex_enter(&chan->ic_conn->ic_lock); switch (chan->ic_conn->ic_stage) { case ISER_CONN_STAGE_UNDEFINED: case ISER_CONN_STAGE_CLOSED: /* do nothing, just drop the lock */ mutex_exit(&chan->ic_conn->ic_lock); break; case ISER_CONN_STAGE_ALLOCATED: /* * We blew up or were offlined during connection * establishment. Teardown the iSER conn and chan * handles. */ mutex_exit(&chan->ic_conn->ic_lock); iser_internal_conn_destroy(chan->ic_conn); break; case ISER_CONN_STAGE_IC_DISCONNECTED: case ISER_CONN_STAGE_IC_FREED: case ISER_CONN_STAGE_CLOSING: /* we're down, set CLOSED */ chan->ic_conn->ic_stage = ISER_CONN_STAGE_CLOSED; mutex_exit(&chan->ic_conn->ic_lock); break; case ISER_CONN_STAGE_IC_CONNECTED: case ISER_CONN_STAGE_HELLO_SENT: case ISER_CONN_STAGE_HELLO_SENT_FAIL: case ISER_CONN_STAGE_HELLO_WAIT: case ISER_CONN_STAGE_HELLO_RCV: case ISER_CONN_STAGE_HELLO_RCV_FAIL: case ISER_CONN_STAGE_HELLOREPLY_SENT: case ISER_CONN_STAGE_HELLOREPLY_SENT_FAIL: case ISER_CONN_STAGE_HELLOREPLY_RCV: case ISER_CONN_STAGE_HELLOREPLY_RCV_FAIL: case ISER_CONN_STAGE_LOGGED_IN: /* for all other stages, fail the transport */ idm_conn_event(chan->ic_conn->ic_idmc, CE_TRANSPORT_FAIL, IDM_STATUS_FAIL); chan->ic_conn->ic_stage = ISER_CONN_STAGE_CLOSING; mutex_exit(&chan->ic_conn->ic_lock); break; default: mutex_exit(&chan->ic_conn->ic_lock); ASSERT(0); } /* accept the event */ return (IBT_CM_ACCEPT); default: /* unknown event */ ISER_LOG(CE_NOTE, "iser_handle_cm_conn_closed: unknown closed " "event: (0x%x)", evp->cm_event.closed); return (IBT_CM_REJECT); } }