Unfortunately, we have no capacity now to test this patch thoroughly enough. If you feel confident with this fix, I can commit it to the trunk. It would be great, if someone from the community could test it in his environment.
> -----Original Message----- > From: [EMAIL PROTECTED] > [mailto:[EMAIL PROTECTED] On Behalf Of Alex Estrin > Sent: Wednesday, April 02, 2008 6:59 AM > To: [email protected] > Subject: [ofw][SRP] recovery thread updated > > I got back to the patch and found session recovery thread > could be signaled more than once during recovery. > Updated code a bit to provide strict connection states set and check. > Please review. > > Thanks, > Alex Estrin > > > Index: srp/kernel/srp_connection.c > =================================================================== > --- srp/kernel/srp_connection.c (revision 1026) > +++ srp/kernel/srp_connection.c (working copy) > @@ -51,6 +51,12 @@ > > #include <complib/cl_math.h> > > +#if DBG > + > +extern void* gp_session[SRP_MAX_SERVICE_ENTRIES]; > + > +#endif > + > /* __srp_create_cqs */ > /*! > Creates the send/recv completion queues to be used by this > connection @@ -284,28 +290,11 @@ > srp_hba_t *p_hba = p_srp_session->p_hba; > ib_cm_drep_t cm_drep; > ib_api_status_t status; > - int i; > - int retry_count = 0; > > SRP_ENTER( SRP_DBG_PNP ); > > - SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_DEBUG, > - ("Target has issued a disconnect request.\n") ); > - > - if ( p_hba->adapter_paused == FALSE ) > - { > - p_hba->adapter_paused = TRUE; > - StorPortBusy( p_hba->p_ext, (ULONG)-1 ); > - StorPortCompleteRequest( p_hba->p_ext, > - > SP_UNTAGGED, > - > SP_UNTAGGED, > - > SP_UNTAGGED, > - > SRB_STATUS_BUSY ); > - SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_DEBUG, > ("Pausing Adapter for %s.\n", p_hba->ioc_info.profile.id_string) ); > - } > - > cl_obj_lock( &p_srp_session->obj ); > - p_srp_session->connection.state = SRP_TARGET_DISCONNECTING; > + p_srp_session->connection.state = SRP_CONNECT_FAILURE; > cl_obj_unlock( &p_srp_session->obj ); > > cm_drep.p_drep_pdata = NULL; > @@ -318,90 +307,16 @@ > ("Cannot respond to target disconnect request. > Status = %d\n", status) ); > } > > - cl_obj_lock( &p_hba->obj ); > + SRP_PRINT( TRACE_LEVEL_WARNING, SRP_DBG_PNP, > + ("Target has issued a disconnect request for Session %d > ref_cnt = %d.\n", > + > p_srp_session->target_id, > + > p_srp_session->obj.ref_cnt) ); > > - for ( i = 0; i < SRP_MAX_SERVICE_ENTRIES; i++ ) > + if( !p_hba->adapter_stopped ) > { > - if ( p_srp_session == p_hba->session_list[i] ) > - { > - p_hba->session_list[i] = NULL; > - break; > - } > + srp_session_failed( p_srp_session ); > } > > - cl_obj_unlock( &p_hba->obj ); > - > - SRP_PRINT( TRACE_LEVEL_VERBOSE, SRP_DBG_DEBUG, > - ("Session Object ref_cnt = %d\n", > p_srp_session->obj.ref_cnt) ); > - cl_obj_destroy( &p_srp_session->obj ); > - > - do > - { > - retry_count++; > - > - SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_DEBUG, > - ("Attempting to reconnect %s. Connection Attempt > Count = %d.\n", > - p_hba->ioc_info.profile.id_string, > - retry_count) ); > - > - SRP_PRINT( TRACE_LEVEL_VERBOSE, SRP_DBG_DEBUG, > - ("Creating New Session For Service Entry Index > %d.\n", > - p_hba->ioc_info.profile.num_svc_entries)); > - p_srp_session = srp_new_session( > - p_hba, &p_hba->p_svc_entries[i], &status ); > - if ( p_srp_session == NULL ) > - { > - status = IB_INSUFFICIENT_MEMORY; > - break; > - } > - > - SRP_PRINT( TRACE_LEVEL_VERBOSE, SRP_DBG_DEBUG, > - ("New Session For Service Entry Index %d > Created.\n", > - p_hba->ioc_info.profile.num_svc_entries)); > - SRP_PRINT( TRACE_LEVEL_VERBOSE, SRP_DBG_DEBUG, > - ("Logging Into Session.\n")); > - status = srp_session_login( p_srp_session ); > - if ( status == IB_SUCCESS ) > - { > - if ( p_hba->max_sg > > p_srp_session->connection.max_scatter_gather_entries ) > - { > - p_hba->max_sg = > p_srp_session->connection.max_scatter_gather_entries; > - } > - > - if ( p_hba->max_srb_ext_sz > > p_srp_session->connection.init_to_targ_iu_sz ) > - { > - p_hba->max_srb_ext_sz = > - sizeof( srp_send_descriptor_t ) > - > - SRP_MAX_IU_SIZE + > - > p_srp_session->connection.init_to_targ_iu_sz; > - } > - > - cl_obj_lock( &p_hba->obj ); > - p_hba->session_list[i] = p_srp_session; > - cl_obj_unlock( &p_hba->obj ); > - > - SRP_PRINT( TRACE_LEVEL_VERBOSE, SRP_DBG_DEBUG, > - ("Session Login Issued > Successfully.\n")); > - } > - else > - { > - SRP_PRINT( TRACE_LEVEL_ERROR, SRP_DBG_ERROR, > - ("Session Login Failure Status = %d.\n", > status)); > - SRP_PRINT( TRACE_LEVEL_VERBOSE, SRP_DBG_DEBUG, > - ("Session Object ref_cnt = %d\n", > p_srp_session->obj.ref_cnt) ); > - cl_obj_destroy( &p_srp_session->obj ); > - } > - } while ( (status != IB_SUCCESS) && (retry_count < 3) ); > - > - if ( status == IB_SUCCESS ) > - { > - SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_DEBUG, > - ("Resuming Adapter for %s.\n", > p_hba->ioc_info.profile.id_string) ); > - p_hba->adapter_paused = FALSE; > - StorPortReady( p_hba->p_ext ); > -// StorPortNotification( BusChangeDetected, p_hba->p_ext, 0 > ); > - } > - > SRP_EXIT( SRP_DBG_PNP ); > } > > @@ -443,22 +358,26 @@ > > p_connection->request_limit = > MIN( get_srp_login_response_request_limit_delta( > p_srp_login_rsp ), SRP_DEFAULT_RECV_Q_DEPTH ); > + > + if( ib_ioc_profile_get_vend_id( > &p_srp_session->p_hba->ioc_info.profile) == 0x00066a && > + cl_ntoh32( > p_srp_session->p_hba->ioc_info.profile.subsys_id ) == 0x38 ) > + { > + /* workaround for FVIC */ > + p_connection->request_limit /= 2; > + } > > + p_connection->max_limit = p_connection->request_limit; > p_connection->request_threashold = 2; > #if DBG > p_srp_session->x_req_limit = > p_connection->request_limit; #endif > - SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_DEBUG, > - ( "request_limit_delta %d, SRP_DEFAULT_RECV_Q_DEPTH %d, > request_threashold %d\n", > - get_srp_login_response_request_limit_delta( > p_srp_login_rsp ), > - SRP_DEFAULT_RECV_Q_DEPTH, > p_connection->request_threashold )); > > p_connection->send_queue_depth = p_connection->request_limit; > p_connection->recv_queue_depth = p_connection->request_limit; > p_connection->init_to_targ_iu_sz = > get_srp_login_response_max_init_to_targ_iu( p_srp_login_rsp ); > p_connection->targ_to_init_iu_sz = > get_srp_login_response_max_targ_to_init_iu( p_srp_login_rsp ); > > - p_connection->signaled_send_completion_count = > p_connection->send_queue_depth / 2; > + p_connection->signaled_send_completion_count = 32; > > if (( p_connection->descriptor_format & > DBDF_INDIRECT_DATA_BUFFER_DESCRIPTORS ) == > DBDF_INDIRECT_DATA_BUFFER_DESCRIPTORS ) > { > @@ -735,9 +654,9 @@ > > cm_req.init_depth = send_msg_depth; > > - cm_req.remote_resp_timeout = 15; > + cm_req.remote_resp_timeout = ib_path_rec_pkt_life( > p_connection->p_path_rec ) + 1; > cm_req.flow_ctrl = FALSE; > - cm_req.local_resp_timeout = 16; > + cm_req.local_resp_timeout = ib_path_rec_pkt_life( > p_connection->p_path_rec ) + 1; > cm_req.retry_cnt = 1; > cm_req.rnr_nak_timeout = 0; /* 655.36 ms */ > cm_req.rnr_retry_cnt = 6; > @@ -900,6 +819,13 @@ > status = IB_ERROR; > goto exit; > } > + > + cl_thread_init( &p_session->recovery_thread, > + > (cl_pfn_thread_callback_t)srp_session_recovery_thread, > + (void *)p_session, "srp_thread" > ); > +#if DBG > + gp_session[p_session->target_id] = p_session; #endif > > exit: > SRP_EXIT( SRP_DBG_PNP ); > Index: srp/kernel/srp_connection.h > =================================================================== > --- srp/kernel/srp_connection.h (revision 1026) > +++ srp/kernel/srp_connection.h (working copy) > @@ -80,6 +80,7 @@ > > atomic32_t tag; > atomic32_t request_limit; > + atomic32_t max_limit; > int32_t request_threashold; > uint32_t init_to_targ_iu_sz; > uint32_t targ_to_init_iu_sz; > Index: srp/kernel/srp_data_path.c > =================================================================== > --- srp/kernel/srp_data_path.c (revision 1026) > +++ srp/kernel/srp_data_path.c (working copy) > @@ -210,6 +210,7 @@ > ib_api_status_t status; > ib_wc_t *p_wc_done_list = NULL; > ib_wc_t *p_wc; > + BOOLEAN to_recover = FALSE; > > SRP_ENTER( SRP_DBG_DATA ); > > @@ -230,8 +231,8 @@ > { > SRP_PRINT_EXIT( TRACE_LEVEL_ERROR, SRP_DBG_ERROR, > ("ib_poll_cq() failed!, status 0x%x\n", > status) ); > - > - // TODO: Kill session and inform port driver link down > scsiportnotification > + > + p_srp_session->connection.state = SRP_CONNECT_FAILURE; > cl_obj_unlock( &p_srp_session->obj ); > return; > } > @@ -254,7 +255,8 @@ > case IB_WCS_SUCCESS: > break; > case IB_WCS_WR_FLUSHED_ERR: > - // TODO: Kill session and inform port > driver link down scsiportnotification > + if( !to_recover ) > + to_recover = TRUE; > SRP_PRINT( > TRACE_LEVEL_INFORMATION, SRP_DBG_DATA, > ("Send Completion Status %s > Vendore Status = 0x%x, \n", > > p_srp_session->p_hba->ifc.get_wc_status_str( p_wc->status ), > @@ -271,7 +273,7 @@ > get_srp_command_tag( > (srp_cmd_t *)p_send_descriptor->data_segment )) ); > break; > default: > - // TODO: Kill session and inform port > driver link down scsiportnotification > + to_recover = TRUE; > SRP_PRINT( TRACE_LEVEL_ERROR, > SRP_DBG_ERROR, > ("Send Completion Status %s > Vendore Status = 0x%x, \n", > > p_srp_session->p_hba->ifc.get_wc_status_str( p_wc->status ), > @@ -299,15 +301,22 @@ > p_wc = p_wc_done_list; > } > > - /* Re-arm the CQ for more completions */ > - status = p_srp_session->p_hba->ifc.rearm_cq( > + if( !to_recover ) > + { > + /* Re-arm the CQ for more completions */ > + status = p_srp_session->p_hba->ifc.rearm_cq( > p_srp_session->connection.h_send_cq, FALSE ); > - if ( status != IB_SUCCESS) > + if ( status != IB_SUCCESS) > + { > + SRP_PRINT( TRACE_LEVEL_ERROR, SRP_DBG_ERROR, > + ("ib_rearm_cq() failed!, status 0x%x\n", > status) ); > + p_srp_session->connection.state = > SRP_CONNECT_FAILURE; > + to_recover = TRUE; > + } > + } > + if( to_recover == TRUE ) > { > - SRP_PRINT( TRACE_LEVEL_ERROR, SRP_DBG_ERROR, > - ("ib_rearm_cq() failed!, status 0x%x\n", status) > ); > - > - // TODO: Kill session and inform port driver link down > scsiportnotification > + p_srp_session->connection.state = SRP_CONNECT_FAILURE; > } > > cl_obj_deref( &p_srp_session->obj ); > @@ -336,6 +345,14 @@ > > __srp_process_session_send_completions( p_srp_session ); > > + if( p_srp_session->connection.state == SRP_CONNECT_FAILURE ) > + { > + if( !p_srp_session->p_hba->adapter_stopped ) > + { > + srp_session_failed( p_srp_session ); > + } > + } > + > SRP_EXIT( SRP_DBG_DATA ); > } > > @@ -355,7 +372,7 @@ > return status; > } > > -void > +ib_api_status_t > __srp_post_io_request( > IN PVOID p_dev_ext, > IN OUT PSCSI_REQUEST_BLOCK p_srb, > @@ -390,7 +407,7 @@ > > SRP_PRINT( TRACE_LEVEL_ERROR, SRP_DBG_ERROR, > ("Returning SrbStatus > %s(0x%x) for Function = %s(0x%x), Path = 0x%x, " > - "Target = 0x%x, Lun = 0x%x, tag > 0x%I64xn", > + "Target = 0x%x, Lun = 0x%x, tag > 0x%I64x\n", > g_srb_status_name[p_srb->SrbStatus], > p_srb->SrbStatus, > g_srb_function_name[p_srb->Function], > @@ -413,16 +430,18 @@ > > exit: > SRP_EXIT( SRP_DBG_DATA ); > + return status; > } > > static > -void > +ib_api_status_t > __srp_repost_io_request( > IN srp_session_t *p_srp_session ) > { > srp_hba_t *p_hba; > srp_send_descriptor_t *p_send_descriptor = NULL; > srp_descriptors_t *p_descriptors = > &p_srp_session->descriptors; > + ib_api_status_t ib_status = IB_SUCCESS; > > SRP_ENTER( SRP_DBG_DATA ); > > @@ -463,13 +482,14 @@ > /* post the request */ > p_hba = p_srp_session->p_hba; > p_send_descriptor = PARENT_STRUCT(p_list_item, > srp_send_descriptor_t,list_item); > - __srp_post_io_request( p_hba->p_ext, > p_send_descriptor->p_srb, p_srp_session ); > + ib_status = __srp_post_io_request( p_hba->p_ext, > p_send_descriptor->p_srb, p_srp_session ); > } > > cl_atomic_dec( &p_srp_session->repost_is_on ); > > exit: > SRP_EXIT( SRP_DBG_DATA ); > + return ib_status; > } > > static inline void > @@ -500,6 +520,8 @@ > srp_rsp_t *p_srp_rsp; > uint8_t response_status; > srp_send_descriptor_t *p_send_descriptor; > + uint64_t response_tag; > + BOOLEAN session_recover = FALSE; > > SRP_ENTER( SRP_DBG_DATA ); > > @@ -508,10 +530,10 @@ > set_srp_response_from_network_to_host( p_srp_rsp ); > > response_status = get_srp_response_status( p_srp_rsp ); > - > + response_tag = get_srp_response_tag( (srp_rsp_t > *)p_recv_descriptor->p_data_segment ); > + > p_send_descriptor = srp_find_matching_send_descriptor( > - &p_srp_session->descriptors, > - get_srp_response_tag( (srp_rsp_t > *)p_recv_descriptor->p_data_segment ) ); > + &p_srp_session->descriptors, response_tag ); > if ( p_send_descriptor == NULL ) > { > /* Repost the recv descriptor */ > @@ -521,21 +543,27 @@ > { > SRP_PRINT( TRACE_LEVEL_ERROR, SRP_DBG_ERROR, > ("Failed to post send > descriptor. Status = %d.\n", status) ); > - // TODO: Kill session and inform port driver > link down scsiportnotification > } > - > - __srp_fix_request_limit( p_srp_session, p_srp_rsp ); > - __srp_repost_io_request( p_srp_session ); > - > + else > + { > + __srp_fix_request_limit( p_srp_session, > p_srp_rsp ); > + } > SRP_PRINT( TRACE_LEVEL_WARNING, SRP_DBG_DATA, > - ("Matching Send Descriptor Not Found.\n") ); > - > - goto exit; > + ("Matching Send Descriptor not Found: tag > %#I64x\n", response_tag ) ); > + > + if( status == IB_SUCCESS && > + !cl_qlist_count( > &p_srp_session->descriptors.sent_descriptors ) ) > + { > + /* Seem all commands from sent queue were > aborted by timeout already */ > + /* most likely Target get stuck. schedule > session recovery */ > + status = IB_ERROR; > + } > + return ( status ); > } > > SRP_PRINT( TRACE_LEVEL_VERBOSE, SRP_DBG_DATA, > ("Recv Completion Received for > Function = %s(0x%x), " > - "Path = 0x%x, Target = 0x%x, Lun = 0x%x, tag > 0x%I64xn", > + "Path = 0x%x, Target = 0x%x, Lun = 0x%x, tag > 0x%I64x\n", > > g_srb_function_name[p_send_descriptor->p_srb->Function], > p_send_descriptor->p_srb->Function, > p_send_descriptor->p_srb->PathId, @@ > -551,7 +579,6 @@ > > set_srp_tsk_mgmt_from_network_to_host( > p_srp_tsk_mgmt ); > > - > if(response_status == SCSISTAT_GOOD) > { > > p_send_descriptor->p_srb->SrbStatus = SRB_STATUS_SUCCESS; @@ > -561,7 +588,7 @@ > > p_send_descriptor->p_srb->SrbStatus = SRB_STATUS_ABORT_FAILED; > SRP_PRINT( TRACE_LEVEL_WARNING, > SRP_DBG_DATA, > ("Scsi Error %s (%#x) > Received for Function = %s(0x%x), " > - "Path = 0x%x, Target = 0x%x, > Lun = 0x%x, tag 0x%I64xn", > + "Path = 0x%x, Target = 0x%x, > Lun = 0x%x, tag 0x%I64x\n", > > g_srb_scsi_status_name[response_status], > response_status, > > g_srb_function_name[p_send_descriptor->p_srb->Function], > @@ -579,29 +606,13 @@ > p_srp_session->connection.h_qp, > &p_recv_descriptor->wr, NULL ); > if ( status != IB_SUCCESS ) > { > + session_recover = TRUE; > SRP_PRINT( TRACE_LEVEL_ERROR, > SRP_DBG_ERROR, > ("Failed to post recv > descriptor. Status = %d.\n", status) ); > - // TODO: Kill session and inform > port driver link down storportnotification > } > > - __srp_fix_request_limit( p_srp_session, > p_srp_rsp ); > - __srp_repost_io_request( p_srp_session > ); > - > - __srp_dump_srb_info( p_send_descriptor); > - > - status = __srp_clean_send_descriptor( > p_send_descriptor, p_srp_session ); > - if ( status != IB_SUCCESS ) > - { > - SRP_PRINT( TRACE_LEVEL_ERROR, > SRP_DBG_ERROR, > - ("Failed to unmap FMR > Status = %d.\n", status) ); > - // TODO: Kill session and inform > port driver link down storportnotification > - } > - > - StorPortNotification( RequestComplete, > p_srp_session->p_hba->p_ext, p_send_descriptor->p_srb ); > } > > - > - > break; > } > > @@ -616,7 +627,7 @@ > > p_send_descriptor->p_srb->SrbStatus = SRB_STATUS_ABORT_FAILED; > SRP_PRINT( TRACE_LEVEL_WARNING, > SRP_DBG_DATA, > ("Scsi Error %s (%#x) > Received for Function = %s(0x%x), " > - "Path = 0x%x, Target = 0x%x, > Lun = 0x%x, tag 0x%I64xn", > + "Path = 0x%x, Target = 0x%x, > Lun = 0x%x, tag 0x%I64x\n", > > g_srb_scsi_status_name[response_status], > response_status, > > g_srb_function_name[p_send_descriptor->p_srb->Function], > @@ -676,7 +687,7 @@ > > p_send_descriptor->p_srb->SenseInfoBufferLength ) ); > SRP_PRINT( TRACE_LEVEL_WARNING, > SRP_DBG_DATA, > ("Sense Data > SENSE_KEY 0x%02x ADDITIONAL_SENSE_CODE" > - "0x%02x > ADDITIONAL_SENSE_QUILIFIER 0x%02x.\n", > + "0x%02x > ADDITIONAL_SENSE_QUALIFIER 0x%02x.\n", > > p_sense_data[2],p_sense_data[12],p_sense_data[13]) ); > > if ( ((p_sense_data[2]&0xf) == > 0x0b /*ABORTED_COMMAND*/) && > @@ -686,15 +697,19 @@ > { > /* probably a problem > with the Vfx FC san like wire pull*/ > /* initiate session > recovery */ > - SRP_PRINT( > TRACE_LEVEL_WARNING, SRP_DBG_DATA, > - ("Sense Data > indicates FC link connectivity has been lost.\n") ); > - StorPortPauseDevice( > p_srp_session->p_hba->p_ext, > - > p_send_descriptor->p_srb->PathId, > - > p_send_descriptor->p_srb->TargetId, > - > p_send_descriptor->p_srb->Lun, > - > 5 ); > + session_recover = TRUE; > + if( > p_srp_session->p_hba->session_paused[p_srp_session->target_id] > == FALSE > ) > + { > + > p_srp_session->p_hba->session_paused[p_srp_session->target_id] = TRUE; > + SRP_PRINT( > TRACE_LEVEL_WARNING, SRP_DBG_DATA, > + ("Sense > Data indicates FC link connectivity has been lost.\n") ); > + > StorPortDeviceBusy( p_srp_session->p_hba->p_ext, > + > SP_UNTAGGED, > + > p_srp_session->target_id, > + > SP_UNTAGGED, > + > (ULONG)-1 ); > + } > } > - > } > > if ( get_srp_response_di_over( p_srp_rsp > ) || get_srp_response_do_over( p_srp_rsp ) ) @@ -717,25 +732,11 @@ > p_srp_session->connection.h_qp, > &p_recv_descriptor->wr, NULL ); > if ( status != IB_SUCCESS ) > { > + session_recover = TRUE; > SRP_PRINT( TRACE_LEVEL_ERROR, > SRP_DBG_ERROR, > ("Failed to post recv > descriptor. Status = %d.\n", status) ); > - // TODO: Kill session and inform port > driver link down storportnotification > } > > - __srp_fix_request_limit( p_srp_session, > p_srp_rsp ); > - __srp_repost_io_request( p_srp_session ); > - > - __srp_dump_srb_info( p_send_descriptor); > - > - status = __srp_clean_send_descriptor( > p_send_descriptor, p_srp_session ); > - if ( status != IB_SUCCESS ) > - { > - SRP_PRINT( TRACE_LEVEL_ERROR, > SRP_DBG_ERROR, > - ("Failed to unmap FMR Status = > %d.\n", status) ); > - // TODO: Kill session and inform port > driver link down storportnotification > - } > - > - StorPortNotification( RequestComplete, > p_srp_session->p_hba->p_ext, p_send_descriptor->p_srb ); > break; > > case SRP_LOGIN_REQ: > @@ -743,11 +744,33 @@ > case SRP_CRED_RSP: > case SRP_AER_RSP: > default: > - CL_ASSERT ( 0 ); > + SRP_PRINT( TRACE_LEVEL_ERROR, SRP_DBG_ERROR, > + ("Illegal SRP IU CMD/RSP %#x > received\n", > + get_srp_iu_buffer_type( (srp_iu_buffer_t > *)p_send_descriptor->data_segment ) ) ); > + session_recover = TRUE; > break; > } > > -exit: > + status = __srp_clean_send_descriptor( p_send_descriptor, > p_srp_session ); > + if ( status != IB_SUCCESS ) > + { > + session_recover = TRUE; > + } > + > + if( session_recover == TRUE ) > + { > + status = IB_ERROR; > + } > + else > + { > + __srp_fix_request_limit( p_srp_session, p_srp_rsp ); > + status = __srp_repost_io_request( p_srp_session ); > + } > + > + __srp_dump_srb_info( p_send_descriptor); > + > + StorPortNotification( RequestComplete, > p_srp_session->p_hba->p_ext, p_send_descriptor->p_srb ); > + > SRP_EXIT( SRP_DBG_DATA ); > > return ( status ); > @@ -782,7 +805,8 @@ > SRP_PRINT( TRACE_LEVEL_ERROR, SRP_DBG_ERROR, > ("ib_poll_cq() failed!, status 0x%x\n", > status) ); > > - // TODO: Kill session and inform port driver link down > scsiportnotification > + p_srp_session->connection.state = SRP_CONNECT_FAILURE; > + > SRP_EXIT( SRP_DBG_DATA ); > cl_obj_unlock( &p_srp_session->obj ); > return; > @@ -806,7 +830,9 @@ > status = __srp_process_recv_completion( > p_recv_descriptor, p_srp_session ); > if ( status != IB_SUCCESS ) > { > - // TODO: Kill session and inform port > driver link down scsiportnotification > + p_srp_session->connection.state = > SRP_CONNECT_FAILURE; > + cl_obj_deref( &p_srp_session->obj ); > + return; > } > } > else > @@ -825,6 +851,10 @@ > > p_srp_session->p_hba->ifc.get_wc_status_str( p_wc->status ))); > > } > + > + p_srp_session->connection.state = > SRP_CONNECT_FAILURE; > + cl_obj_deref( &p_srp_session->obj ); > + return; > } > > /* Put onto head of free list */ > @@ -844,8 +874,10 @@ > { > SRP_PRINT( TRACE_LEVEL_ERROR, SRP_DBG_ERROR, > ("ib_rearm_cq() failed!, status > 0x%x\n", status) ); > + p_srp_session->connection.state = SRP_CONNECT_FAILURE; > > - // TODO: Kill session and inform port driver link down > scsiportnotification > + cl_obj_deref( &p_srp_session->obj ); > + return; > } > > cl_obj_deref( &p_srp_session->obj ); > @@ -873,7 +905,10 @@ > UNUSED_PARAM( h_cq ); > > __srp_process_session_recv_completions( p_srp_session ); > - > + if( p_srp_session->connection.state == SRP_CONNECT_FAILURE ) > + { > + srp_session_failed( p_srp_session ); > + } > SRP_EXIT( SRP_DBG_DATA ); > } > > @@ -887,7 +922,7 @@ > @return - none > */ > static inline > -void > +BOOLEAN > __srp_build_cmd( > IN PVOID p_dev_ext, > IN OUT PSCSI_REQUEST_BLOCK p_srb, > @@ -1124,6 +1159,7 @@ > //set_srp_command_from_host_to_network( p_srp_cmd ); > > SRP_EXIT( SRP_DBG_DATA ); > + return TRUE; > } > > /* srp_format_io_request */ > @@ -1159,7 +1195,9 @@ > > p_srp_session = p_hba->session_list[p_srb->TargetId]; > > - if ( p_srp_session != NULL ) > + if ( p_srp_session != NULL && > + p_srp_session->connection.state == SRP_CONNECTED && > + !p_hba->session_paused[p_srb->TargetId] ) > { > srp_conn_info_t srp_conn_info; > > @@ -1180,19 +1218,24 @@ > > srp_build_send_descriptor( p_dev_ext, p_srb, > &srp_conn_info ); > > - __srp_build_cmd( p_dev_ext, p_srb, &srp_conn_info ); > + result = __srp_build_cmd( p_dev_ext, p_srb, > &srp_conn_info ); > + > + if( result != TRUE ) > + SRP_PRINT( TRACE_LEVEL_ERROR, SRP_DBG_ERROR, > + ("BUILD command %#x failed = %#x tag > %#I64x\n", > + p_srb->Cdb[0], p_srb->SrbStatus, > srp_conn_info.tag ) ); > } > else > { > // Handle the error case here > SRP_PRINT( TRACE_LEVEL_ERROR, SRP_DBG_ERROR, > ("Cannot Find Session For Target ID = %d\n", > p_srb->TargetId) ); > + > + p_srb->SrbStatus = SRB_STATUS_INVALID_TARGET_ID; > cl_obj_unlock( &p_hba->obj ); > - p_srb->SrbStatus = SRB_STATUS_INVALID_TARGET_ID; > result = FALSE; > } > > - > SRP_EXIT( SRP_DBG_DATA ); > return ( result ); > } > @@ -1214,8 +1257,16 @@ > > p_srp_session = p_hba->session_list[p_srb->TargetId]; > > - if ( p_srp_session != NULL ) > + if( p_hba->session_paused[p_srb->TargetId] == TRUE ) > { > + cl_obj_unlock( &p_hba->obj ); > + p_srb->SrbStatus = SRB_STATUS_BUSY; > + goto err; > + } > + > + if ( p_srp_session != NULL && > + p_srp_session->connection.state == SRP_CONNECTED ) > + { > cl_obj_ref( &p_srp_session->obj ); > cl_obj_unlock( &p_hba->obj ); > > @@ -1226,14 +1277,26 @@ > !cl_is_qlist_empty( > &p_descriptors->pending_descriptors ) || > p_srp_session->repost_is_on ) > { > + int32_t num_pending_desc = > (int32_t)cl_qlist_count( &p_descriptors->pending_descriptors ); > cl_spinlock_release ( > &p_descriptors->pending_list_lock ); > srp_add_pending_descriptor( > p_descriptors, p_send_descriptor ); > + > + /* don't allow pending queue grow indefinitely > */ > + if( num_pending_desc >= > p_srp_session->connection.max_limit ) > + { > + StorPortDeviceBusy( p_dev_ext, > + > p_srb->PathId, > + > p_srb->TargetId, > + > p_srb->Lun, > + > 1 ); > + } > + > cl_obj_deref( &p_srp_session->obj ); > goto exit; > } > cl_spinlock_release ( > &p_descriptors->pending_list_lock ); > > - __srp_post_io_request( p_dev_ext, p_srb, p_srp_session > ); > + status = __srp_post_io_request( p_dev_ext, p_srb, > p_srp_session ); > cl_obj_deref( &p_srp_session->obj ); > goto exit; > } > @@ -1247,7 +1310,7 @@ > err: > SRP_PRINT( TRACE_LEVEL_ERROR, SRP_DBG_ERROR, > ("Returning SrbStatus %s(0x%x) for > Function = %s(0x%x), Path = 0x%x, " > - "Target = 0x%x, Lun = 0x%x, tag 0x%I64xn", > + "Target = 0x%x, Lun = 0x%x, tag 0x%I64x\n", > g_srb_status_name[p_srb->SrbStatus], > p_srb->SrbStatus, > g_srb_function_name[p_srb->Function], > @@ -1268,6 +1331,11 @@ > StorPortNotification( RequestComplete, p_dev_ext, p_srb ); > > exit: > + if( status != IB_SUCCESS ) > + { > + p_srp_session->connection.state = SRP_CONNECT_FAILURE; > + srp_session_failed( p_srp_session ); > + } > SRP_EXIT( SRP_DBG_DATA ); > } > > @@ -1483,7 +1551,8 @@ > { > srp_session_t *p_srp_session = p_session; > > - if (p_srp_session == NULL) > + if (p_srp_session == NULL || > + p_srp_session->connection.state != SRP_CONNECTED ) > return; > > p_srp_session->x_pkt_fmr = 0; > @@ -1506,7 +1575,8 @@ > { > srp_session_t *p_srp_session = p_session; > > - if (p_srp_session == NULL) > + if (p_srp_session == NULL || > + p_srp_session->connection.state != SRP_CONNECTED ) > return; > > SRP_PRINT( TRACE_LEVEL_ERROR, SRP_DBG_DATA, > Index: srp/kernel/srp_driver.c > =================================================================== > --- srp/kernel/srp_driver.c (revision 1026) > +++ srp/kernel/srp_driver.c (working copy) > @@ -265,7 +265,7 @@ > srp_x_clean( > IN void *p_session ); > > -void *gp_session = NULL; > +void* gp_session[SRP_MAX_SERVICE_ENTRIES]; > > #endif > > @@ -548,7 +548,7 @@ > ("KeReleaseMutex status = %d.\n", > release_status) ); > } > > - #if DBG > + #if DBG_STATISTICS > /* statistics */ > > /* this function is called sometimes in the begging of > the test with @@ -557,11 +557,14 @@ > /* sometimes it's called once in 50msec, so > we'll print once in 20 times */ > static int interval = 40; /* 2 sec */ > static int cnt = 0; > + static int i; > if (++cnt >= interval) > { > cnt = 0; > - srp_x_print( gp_session ); > - srp_x_clean( gp_session ); > + if(i > 3 ) i = 0; > + srp_x_print( gp_session[i] ); > + srp_x_clean( gp_session[i] ); > + i++; > } > } > > @@ -712,24 +715,13 @@ > > if ( (p_srb->Lun == 0) && (p_srp_session != > NULL) ) > { > - p_hba->session_list[p_srb->TargetId] = > NULL; > - > - CL_ASSERT( p_srp_session != NULL ); > - > p_srp_session->p_shutdown_srb = p_srb; > - cl_obj_destroy( &p_srp_session->obj ); > > - SRP_PRINT( TRACE_LEVEL_INFORMATION, > SRP_DBG_DATA, > - ("Returning SrbStatus > %s(0x%x) for " > - "Function = %s(0x%x), > Path = 0x%x, " > - "Target = 0x%x, Lun = > 0x%x\n", > - > g_srb_status_name[p_srb->SrbStatus], > - p_srb->SrbStatus, > - > g_srb_function_name[p_srb->Function], > - p_srb->Function, > - p_srb->PathId, > - p_srb->TargetId, > - p_srb->Lun) ); > + if( !p_hba->adapter_stopped ) > + { > + p_hba->adapter_stopped = TRUE; > + srp_disconnect_sessions( p_hba > ); > + } > } > else > { > @@ -831,8 +823,9 @@ > SRP_ENTER( SRP_DBG_PNP ); > > UNUSED_PARAM( p_dev_ext ); > - UNUSED_PARAM( path_id ); > > + StorPortCompleteRequest( p_dev_ext, (UCHAR)path_id, SP_UNTAGGED, > SP_UNTAGGED, SRB_STATUS_NO_HBA ); > + > SRP_EXIT( SRP_DBG_PNP ); > return FALSE; > } > @@ -873,6 +866,9 @@ > { > SRP_PRINT( TRACE_LEVEL_VERBOSE, SRP_DBG_DEBUG, > ("HBA Object ref_cnt = %d\n", > p_ext->p_hba->obj.ref_cnt) ); > + if( !p_ext->p_hba->adapter_stopped ) > + p_ext->p_hba->adapter_stopped = TRUE; > + srp_disconnect_sessions( p_ext->p_hba ); > cl_obj_destroy( &p_ext->p_hba->obj ); > p_ext->p_hba = NULL; > } > Index: srp/kernel/srp_hba.c > =================================================================== > --- srp/kernel/srp_hba.c (revision 1026) > +++ srp/kernel/srp_hba.c (working copy) > @@ -730,29 +730,29 @@ > { > int retry_count = 0; > > - SRP_PRINT( TRACE_LEVEL_VERBOSE, SRP_DBG_PNP, > - ("Creating New Session For Service Entry Index > %d.\n", > - p_hba->ioc_info.profile.num_svc_entries)); > + do{ > + retry_count++; > > - p_session = srp_new_session( > - p_hba, &p_hba->p_svc_entries[i], &status ); > - if( p_session == NULL ) > - { > - status = IB_INSUFFICIENT_MEMORY; > - continue; > - } > + SRP_PRINT( TRACE_LEVEL_VERBOSE, SRP_DBG_PNP, > + ("Creating New Session For Service Entry Index > %d.\n", i )); > > - SRP_PRINT( TRACE_LEVEL_VERBOSE, SRP_DBG_PNP, > - ("New Session For Service Entry Index %d > Created.\n", > - p_hba->ioc_info.profile.num_svc_entries)); > + p_session = srp_new_session( > + p_hba, > + > &p_hba->p_svc_entries[i], > + > &p_hba->p_srp_path_record->path_rec, > + &status ); > + if( p_session == NULL ) > + { > + status = IB_INSUFFICIENT_MEMORY; > + break; > + } > > - do > - { > - retry_count++; > + SRP_PRINT( TRACE_LEVEL_VERBOSE, SRP_DBG_PNP, > + ("New Session For Service Entry Index %d > Created.\n", i )); > > SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_PNP, > - ("Attempting to connect %s. Connection > Attempt Count = %d.\n", > - p_hba->ioc_info.profile.id_string, > + ("Attempting to connect %s. Svc Idx %d; > Connection Attempt Count = %d.\n", > + p_hba->ioc_info.profile.id_string, i, > retry_count) ); > SRP_PRINT( TRACE_LEVEL_VERBOSE, SRP_DBG_PNP, > ("Logging Into Session.\n")); > @@ -761,23 +761,10 @@ > { > any_ioc_connected = TRUE; > > - if ( (p_hba->max_sg > > - > p_session->connection.max_scatter_gather_entries) > - && > !(p_session->connection.descriptor_format & > - > DBDF_INDIRECT_DATA_BUFFER_DESCRIPTORS) ) > - { > - p_hba->max_sg = > p_session->connection.max_scatter_gather_entries; > - } > + srp_session_adjust_params( p_session ); > > - if ( p_hba->max_srb_ext_sz > > p_session->connection.init_to_targ_iu_sz ) > - { > - p_hba->max_srb_ext_sz = > - sizeof( > srp_send_descriptor_t ) - > - SRP_MAX_IU_SIZE + > - > p_session->connection.init_to_targ_iu_sz; > - } > - > cl_obj_lock( &p_hba->obj ); > + p_session->target_id = (UCHAR)i; > p_hba->session_list[i] = p_session; > cl_obj_unlock( &p_hba->obj ); > > @@ -787,29 +774,32 @@ > else > { > SRP_PRINT( TRACE_LEVEL_ERROR, > SRP_DBG_PNP, > - ("Session Login Failure Status = > %d.\n", status)); > + ("Session Login for Service Idx > %d Failure Status = %d.\n", i, status)); > + cl_obj_destroy( &p_session->obj ); > } > + > } while ( (status != IB_SUCCESS) && (retry_count < 3) ); > > - if( status != IB_SUCCESS ) > - { > - SRP_PRINT( TRACE_LEVEL_VERBOSE, SRP_DBG_PNP, > - ("Session Object ref_cnt = %d\n", > p_session->obj.ref_cnt) ); > - cl_obj_destroy( &p_session->obj ); > - } > } > > if ( any_ioc_connected == TRUE ) > { > status = IB_SUCCESS; > - if ( p_hba->adapter_paused == TRUE ) > + for( i = 0; i < p_hba->ioc_info.profile.num_svc_entries; > i++ ) > { > - SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_PNP, > - ("Resuming Adapter for %s.\n", > - p_hba->ioc_info.profile.id_string) ); > - p_hba->adapter_paused = FALSE; > - StorPortReady( p_hba->p_ext ); > - //StorPortNotification( BusChangeDetected, > p_hba->p_ext, 0 ); > + p_session = p_hba->session_list[i]; > + > + if( p_session != NULL && > + p_session->connection.state == > SRP_CONNECTED && > + p_hba->session_paused[i] == TRUE ) > + { > + SRP_PRINT( TRACE_LEVEL_INFORMATION, > SRP_DBG_PNP, > + ("Resuming Adapter Session %d for > %s.\n", i, > + > p_hba->ioc_info.profile.id_string) ); > + > + p_hba->session_paused[i] = FALSE; > + StorPortDeviceReady( p_hba->p_ext, > SP_UNTAGGED, (UCHAR)i, SP_UNTAGGED ); > + } > } > } > > @@ -818,10 +808,9 @@ > return status; > } > > -static void > -__srp_disconnect_sessions( > - IN srp_hba_t > *p_hba, > - IN BOOLEAN > pause_adapter ) > +void > +srp_disconnect_sessions( > + IN srp_hba_t > *p_hba ) > { > uint32_t i; > srp_session_t *p_session; > @@ -834,72 +823,15 @@ > { > if ( p_hba->session_list[i] != NULL ) > { > - break; > + p_session = p_hba->session_list[i]; > + p_hba->session_list[i] = NULL; > + p_session->connection.state = > SRP_CONNECT_FAILURE; > + srp_session_failed( p_session ); > } > } > > cl_obj_unlock( &p_hba->obj ); > > - if ( i == p_hba->ioc_info.profile.num_svc_entries ) > - { > - SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_PNP, > - ("No current connections to %s.\n", > - p_hba->ioc_info.profile.id_string) ); > - goto exit; > - } > - > - SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_PNP, > - ("Current path to %s has been lost.\n", > - p_hba->ioc_info.profile.id_string) ); > - > - p_hba->p_srp_path_record = NULL; > - > - if ( pause_adapter == TRUE ) > - { > - if ( p_hba->adapter_paused == FALSE ) > - { > - p_hba->adapter_paused = TRUE; > - StorPortBusy( p_hba->p_ext, (ULONG)-1 ); > - StorPortCompleteRequest( p_hba->p_ext, > - > SP_UNTAGGED, > - > SP_UNTAGGED, > - > SP_UNTAGGED, > - > SRB_STATUS_BUSY ); > - SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_PNP, > - ("Pausing Adapter for %s.\n", > - p_hba->ioc_info.profile.id_string) ); > - } > - } > - > - /* Destroy all the connections. */ > - SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_PNP, > - ("Destroy all connections to %s.\n", > - p_hba->ioc_info.profile.id_string) ); > - > - for ( i = 0; i < p_hba->ioc_info.profile.num_svc_entries; i++ ) > - { > - cl_obj_lock( &p_hba->obj ); > - p_session = p_hba->session_list[i]; > - p_hba->session_list[i] = NULL; > - cl_obj_unlock( &p_hba->obj ); > - > - if ( p_session != NULL ) > - { > - SRP_PRINT( TRACE_LEVEL_VERBOSE, SRP_DBG_PNP, > - ("Session Object ref_cnt = %d\n", > p_session->obj.ref_cnt) ); > - __srp_cleanup_session ( &p_session->obj ); > - cl_obj_destroy( &p_session->obj ); > - } > - else > - { > - SRP_PRINT( TRACE_LEVEL_WARNING, SRP_DBG_PNP, > - ("Session for Target ID %d on %s is > NULL.\n", > - i, > - p_hba->ioc_info.profile.id_string) ); > // <-- OK in a shutdown or target disconnect > - } > - } > - > -exit: > SRP_EXIT( SRP_DBG_PNP ); > } > > @@ -1040,11 +972,16 @@ > > SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_PNP, > ("Hey!!! Our IOC went away.\n") ); > - > - __srp_disconnect_sessions( p_hba, FALSE ); > + > + if( !p_hba->adapter_stopped ) > + p_hba->adapter_stopped = TRUE; > + > + srp_disconnect_sessions( p_hba ); > __srp_remove_path_records( p_hba ); > + > SRP_PRINT( TRACE_LEVEL_VERBOSE, SRP_DBG_PNP, > - ("HBA Object ref_cnt = %d\n", > p_hba->obj.ref_cnt) ); > + ("IB_PNP_IOC_REMOVE HBA Object ref_cnt = > %d\n", p_hba->obj.ref_cnt ) ); > + > break; > > case IB_PNP_IOC_PATH_ADD: > @@ -1068,6 +1005,9 @@ > > p_hba->ioc_info.profile.id_string) ); > status = __srp_connect_path( p_hba ); > } > + > + SRP_PRINT( TRACE_LEVEL_VERBOSE, SRP_DBG_PNP, > + (" IOC_PATH ADD HBA Object ref_cnt = > %d\n", p_hba->obj.ref_cnt ) ); > break; > > case IB_PNP_IOC_PATH_REMOVE: > @@ -1088,13 +1028,8 @@ > > if ( g_srp_system_shutdown == > FALSE ) > { > - > __srp_disconnect_sessions( p_hba, TRUE ); > - status = > __srp_connect_path( p_hba ); > + srp_disconnect_sessions( > p_hba ); > } > - else > - { > - > __srp_disconnect_sessions( p_hba, FALSE ); > - } > } > > cl_free( p_srp_path_record ); > Index: srp/kernel/srp_hba.h > =================================================================== > --- srp/kernel/srp_hba.h (revision 1026) > +++ srp/kernel/srp_hba.h (working copy) > @@ -74,13 +74,13 @@ > srp_path_record_t *p_srp_path_record; > cl_qlist_t path_record_list; > cl_spinlock_t path_record_list_lock; > - BOOLEAN adapter_paused; > + BOOLEAN adapter_stopped; > > uint32_t max_sg; > uint32_t max_srb_ext_sz; > - > /* List of sessions indexed by target id */ > p_srp_session_t > session_list[SRP_MAX_SERVICE_ENTRIES]; > + BOOLEAN > session_paused[SRP_MAX_SERVICE_ENTRIES]; > } srp_hba_t; > > > @@ -93,4 +93,8 @@ > IN cl_obj_t* const > p_drv_obj, > OUT struct _srp_ext* const > p_ext ); > > +void > +srp_disconnect_sessions( > + IN srp_hba_t > *p_hba ); > + > #endif /* _SRP_HBA_H_ */ > Index: srp/kernel/srp_session.c > =================================================================== > --- srp/kernel/srp_session.c (revision 1026) > +++ srp/kernel/srp_session.c (working copy) > @@ -40,10 +40,6 @@ > #include "srp_session.h" > #include <stdlib.h> > > -#if DBG > -extern void *gp_session; > -#endif > - > /* __srp_destroying_session */ > /*! > Called when session has been marked for destruction @@ > -230,6 +226,8 @@ > @param p_hba - pointer to the hba associated with the > new session > @param ioc_guid - pointer to the target's ioc guid > @param p_svc_entry - pointer to the service entry > [EMAIL PROTECTED] p_path_rec - pointer to path record to use. > + > @param p_status - pointer to the reason code > > @return - Pointer to new session or NULL if failure. See > p_status for reason code. > @@ -238,6 +236,7 @@ > srp_new_session( > IN srp_hba_t *p_hba, > IN ib_svc_entry_t *p_svc_entry, > + IN ib_path_rec_t *p_path_rec, > OUT ib_api_status_t *p_status ) > { > uint64_t target_id_extension; > @@ -252,6 +251,11 @@ > goto exit; > } > > + if( p_path_rec == NULL ) > + { > + goto exit; > + } > + > p_srp_session = (srp_session_t*)cl_zalloc( > sizeof(srp_session_t) ); > if ( p_srp_session == NULL ) > { > @@ -267,8 +271,8 @@ > > &p_hba->ioc_info.profile, > > p_hba->info.ca_guid, > > target_id_extension, > - > &p_hba->p_srp_path_record->path_rec, > - > p_svc_entry->id ); > + > p_path_rec, > + > p_svc_entry->id ); > if ( *p_status != IB_SUCCESS ) > { > cl_free( p_srp_session ); > @@ -306,11 +310,6 @@ > SRP_PRINT( TRACE_LEVEL_VERBOSE, SRP_DBG_DEBUG, > ("After Insert Rel Session Object ref_cnt = %d\n", > p_srp_session->obj.ref_cnt) ); > - > -#if DBG > - gp_session = p_srp_session; > -#endif > - > exit: > SRP_EXIT( SRP_DBG_SESSION ); > > @@ -348,13 +347,243 @@ > > (uint8_t)p_srp_session->p_hba->ioc_info.profile.send_msg_depth, > p_srp_session ); > > - if ( status != IB_SUCCESS ) > - { // clean resources, taken upon login > - srp_close_ca( &p_srp_session->hca ); > - srp_destroy_descriptors( &p_srp_session->descriptors ); > - } > - > exit: > SRP_EXIT( SRP_DBG_SESSION ); > return ( status ); > } > + > +void > +srp_session_failed( > +IN srp_session_t* p_srp_session ) > +{ > + > + SRP_ENTER( SRP_DBG_SESSION ); > + > + if( !p_srp_session ) > + return; > + > + cl_obj_lock( &p_srp_session->obj ); > + > + if( p_srp_session->obj.state != CL_INITIALIZED ) > + { > + cl_obj_unlock( &p_srp_session->obj ); > + return; > + } > + > + if( p_srp_session->connection.state != SRP_CONNECT_FAILURE ) > + { > + cl_obj_unlock( &p_srp_session->obj ); > + return; > + } > + p_srp_session->connection.state = SRP_CONNECTION_CLOSING; > + > + cl_obj_unlock( &p_srp_session->obj ); > + > + SRP_PRINT( TRACE_LEVEL_WARNING, SRP_DBG_DATA, > + ("Session Idx %d failed\n", p_srp_session->target_id ) > ); > + > + cl_event_signal( &p_srp_session->offload_event ); } > + > +ib_api_status_t > +srp_session_connect( > + IN srp_hba_t *p_hba, > + IN OUT p_srp_session_t *pp_srp_session, > + IN UCHAR svc_idx ) > +{ > + ib_api_status_t ib_status; > + srp_path_record_t *p_srp_path_rec; > + srp_session_t *p_session; > + uint64_t target_id_extension; > + > + SRP_ENTER( SRP_DBG_SESSION ); > + > + if( *pp_srp_session != NULL ) > + { > + return IB_ERROR; > + } > + > + cl_spinlock_acquire( &p_hba->path_record_list_lock ); > + if( !cl_qlist_count( &p_hba->path_record_list ) ) > + { > + cl_spinlock_release( &p_hba->path_record_list_lock ); > + return IB_NOT_FOUND; > + } > + > + p_srp_path_rec = (srp_path_record_t *)cl_qlist_head( > &p_hba->path_record_list ); > + > + cl_spinlock_release( &p_hba->path_record_list_lock ); > + > + if( p_srp_path_rec == (srp_path_record_t *)cl_qlist_end( > &p_hba->path_record_list ) ) > + { > + return IB_NOT_FOUND; > + } > + > + ib_status = __srp_validate_service_entry( > &p_hba->p_svc_entries[svc_idx], &target_id_extension ); > + if( ib_status != IB_SUCCESS ) > + { > + SRP_PRINT( TRACE_LEVEL_WARNING, SRP_DBG_SESSION, > + ("Failed validate service entry status %x\n", > ib_status )); > + return ib_status; > + } > + > + p_session = srp_new_session( p_hba, > + &p_hba->p_svc_entries[svc_idx], > + &p_srp_path_rec->path_rec, > + &ib_status ); > + > + if( ib_status != IB_SUCCESS || p_session == NULL ) > + { > + SRP_PRINT( TRACE_LEVEL_ERROR, SRP_DBG_SESSION, > + ("Failed create Session for SVC idx %d status > %x\n", svc_idx, ib_status )); > + > + *pp_srp_session = NULL; > + > + return ib_status; > + } > + > + ib_status = srp_session_login( p_session ); > + if( ib_status != IB_SUCCESS ) > + { > + SRP_PRINT( TRACE_LEVEL_ERROR, SRP_DBG_SESSION, > + ("Failed Session Login status %x\n", ib_status > )); > + > + *pp_srp_session = NULL; > + > + cl_obj_destroy( &p_session->obj ); > + > + return ib_status; > + } > + srp_session_adjust_params( p_session ); > + > + cl_obj_lock( &p_hba->obj ); > + > + p_session->target_id = svc_idx; > + > + *pp_srp_session = p_session; > + > + cl_obj_unlock( &p_hba->obj ); > + > + > + SRP_EXIT( SRP_DBG_SESSION ); > + return ib_status; > +} > + > +void > +srp_session_adjust_params( > + IN srp_session_t *p_session ) > +{ > + > + if ( ( p_session->p_hba->max_sg > > p_session->connection.max_scatter_gather_entries ) > + && !( p_session->connection.descriptor_format & > DBDF_INDIRECT_DATA_BUFFER_DESCRIPTORS) ) > + { > + p_session->p_hba->max_sg = > p_session->connection.max_scatter_gather_entries; > + } > + > + if ( p_session->p_hba->max_srb_ext_sz > > p_session->connection.init_to_targ_iu_sz ) > + { > + p_session->p_hba->max_srb_ext_sz = > + sizeof( srp_send_descriptor_t ) - > + SRP_MAX_IU_SIZE + > + p_session->connection.init_to_targ_iu_sz; > + } > +} > + > +static void > +__srp_session_recovery( > +IN srp_session_t* p_failed_session , > +IN BOOLEAN reconnect_request ) > +{ > + ib_api_status_t ib_status; > + srp_hba_t* p_hba; > + srp_session_t* p_new; > + srp_session_t* p_old; > + UCHAR target_id; > + int retry_count; > + > + SRP_ENTER( SRP_DBG_SESSION ); > + > + if( !p_failed_session ) > + return; > + if ( ( p_hba = p_failed_session->p_hba ) == NULL ) > + return; > + > + p_old = p_failed_session; > + target_id = p_old->target_id; > + p_hba->session_list[target_id] = NULL; > + > + if( !reconnect_request ) > + { > + /* we're done here */ > + SRP_PRINT( TRACE_LEVEL_WARNING, SRP_DBG_DATA, > + ("Session Id: %d won't recover\n", > p_old->target_id ) ); > + cl_obj_destroy( &p_old->obj ); > + return; > + } > + > + if( !p_hba->session_paused[target_id] ) > + { > + p_hba->session_paused[target_id] = TRUE; > + > + StorPortDeviceBusy( p_hba->p_ext, > + SP_UNTAGGED, > + target_id, > + SP_UNTAGGED, > + (ULONG)-1 ); > + } > + > + SRP_PRINT( TRACE_LEVEL_WARNING, SRP_DBG_DATA, > + ("Pausing Adapter Session %d\n", target_id ) ); > + > + cl_obj_destroy( &p_old->obj ); > + > + for( retry_count=0; retry_count < 3 ; retry_count++ ) > + { > + ib_status = srp_session_connect( p_hba, &p_new, > target_id ); > + > + if( ib_status != IB_SUCCESS ) > + { > + SRP_PRINT( TRACE_LEVEL_WARNING, SRP_DBG_DATA, > + ("Failed session idx %d connect\n", > target_id ) ); > + > + continue; > + } > + > + p_hba->session_list[target_id] = p_new; > + > + SRP_PRINT( TRACE_LEVEL_WARNING, SRP_DBG_DATA, > + ("Session idx %d connected. Resuming\n", > target_id ) ); > + > + StorPortDeviceReady( p_hba->p_ext, > + SP_UNTAGGED, > + target_id, > + SP_UNTAGGED ); > + > + p_hba->session_paused[target_id] = FALSE; > + > + return; > + } > + > + /* what do we do now ? */ > + SRP_PRINT( TRACE_LEVEL_WARNING, SRP_DBG_DATA, > + ("Session idx %d recovery failed\n", target_id) > ); > + > + return; > +} > + > +void > +srp_session_recovery_thread( > + IN void* const context ) > +{ > + srp_session_t* p_session = (srp_session_t *)context; > + cl_status_t status; > + > + if( p_session == NULL ) > + return; > + > + cl_event_init( &p_session->offload_event, FALSE); > + > + status = cl_event_wait_on( &p_session->offload_event, > EVENT_NO_TIMEOUT, FALSE ); > + > + __srp_session_recovery( p_session, > !p_session->p_hba->adapter_stopped ); > +} > Index: srp/kernel/srp_session.h > =================================================================== > --- srp/kernel/srp_session.h (revision 1026) > +++ srp/kernel/srp_session.h (working copy) > @@ -58,6 +58,11 @@ > > SCSI_REQUEST_BLOCK *p_shutdown_srb; > > + /* keep session level SCSI address */ > + UCHAR target_id; > + cl_event_t offload_event; > + cl_thread_t recovery_thread; > + > #if DBG > /* statistics */ > > @@ -95,6 +100,7 @@ > srp_new_session( > IN srp_hba_t *p_hba, > IN ib_svc_entry_t *p_svc_entry, > + IN ib_path_rec_t *p_path_rec, > OUT ib_api_status_t *p_status ); > > ib_api_status_t > @@ -105,4 +111,22 @@ > __srp_cleanup_session( > IN cl_obj_t *p_obj ); > > +ib_api_status_t > +srp_session_connect( > + IN srp_hba_t *p_hba, > + IN OUT p_srp_session_t *pp_srp_session, > + IN UCHAR svc_idx ); > + > +void > +srp_session_adjust_params( > + IN srp_session_t *p_session ); > + > +void > +srp_session_failed( > +IN srp_session_t* p_srp_session ); > + > +void > +srp_session_recovery_thread( > +IN void* const context ); > + > #endif /* _SRP_SESSION_H_ */ > _______________________________________________ ofw mailing list [email protected] http://lists.openfabrics.org/cgi-bin/mailman/listinfo/ofw
