[ofw][SRP] recovery thread updated
Alex Estrin
alex.estrin at qlogic.com
Tue Apr 1 20:58:41 PDT 2008
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
+ at param 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_ */
-------------- next part --------------
A non-text attachment was scrubbed...
Name: srp_recovery_thread_updated.diff
Type: application/octet-stream
Size: 44787 bytes
Desc: srp_recovery_thread_updated.diff
URL: <http://lists.openfabrics.org/pipermail/ofw/attachments/20080401/962234c4/attachment.obj>
More information about the ofw
mailing list