)
{
AL_ENTER( AL_DBG_NDI );
- if (Irp)
- {
- cl_ioctl_complete( Irp, code, 0 );
- deref_al_obj( &h_qp->obj );
- h_qp->p_irp_que->h_ioctl = NULL; /* mark IRP as cancelled */
- }
- else
- AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR, ("Irp is NULL - not completed !\n") );
+
+ CL_ASSERT( Irp );
+
+ cl_ioctl_complete( Irp, code, 0 );
+ deref_al_obj( &h_qp->obj ); /* release IRP life reference */
+ h_qp->p_irp_que->h_ioctl = NULL; /* mark IRP as cancelled */
+
AL_EXIT( AL_DBG_NDI );
}
AL_ENTER( AL_DBG_NDI );
h_qp->p_irp_que->state = new_state;
Irp = IoCsqRemoveNextIrp( &h_qp->p_irp_que->csq, NULL );
- __ndi_complete_irp( h_qp, Irp, code );
- deref_al_obj( &h_qp->obj ); /* release the extra reference */
+ if ( Irp )
+ __ndi_complete_irp( h_qp, Irp, code );
AL_EXIT( AL_DBG_NDI );
}
while( Irp = IoCsqRemoveNextIrp( &p_ndi_csq->csq, NULL ) )
{
AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,
- ("h_qp %I64x, ref_cnt %d\n", (uint64_t)p_ndi_csq->h_qp,
+ ("h_qp %#I64x, uhdl %#I64x, ref_cnt %d\n",
+ (uint64_t)p_ndi_csq->h_qp, p_ndi_csq->h_qp->obj.hdl,
p_ndi_csq->h_qp->obj.ref_cnt ) );
cl_ioctl_complete( Irp, completion_code, 0 );
- deref_al_obj( &p_ndi_csq->h_qp->obj );
+ deref_al_obj( &p_ndi_csq->h_qp->obj ); /* release IRP life reference */
}
}
#pragma warning(default:4706)
AL_ENTER( AL_DBG_NDI );
__ndi_flush_que( h_qp->p_irp_que, STATUS_CANCELLED );
AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,
- ("h_qp %I64x, ref_cnt %d\n", (uint64_t)h_qp, h_qp->obj.ref_cnt ) );
+ ("h_qp %#I64x, uhdl %#I64x, ref_cnt %d\n",
+ (uint64_t)h_qp, h_qp->obj.hdl, h_qp->obj.ref_cnt ) );
AL_EXIT( AL_DBG_NDI );
}
AL_ENTER( AL_DBG_NDI );
+ if ( h_qp->type == IB_QPT_UNRELIABLE_CONN )
+ {
+ status = STATUS_NOT_SUPPORTED;
+ goto exit;
+ }
+
h_qp->p_irp_que = (ndi_qp_csq_t*)cl_zalloc(sizeof(ndi_qp_csq_t));
if (!h_qp->p_irp_que)
{
h_qp->p_irp_que->state = NDI_CM_IDLE;
status = STATUS_SUCCESS;
+AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,
+ ("Creating h_qp %#I64x, uhdl %#I64x \n",
+ (uint64_t)h_qp, h_qp->obj.hdl ) );
+
exit:
AL_EXIT( AL_DBG_NDI );
return status;
if (h_qp->type == IB_QPT_RELIABLE_CONN && h_qp->p_irp_que)
{
AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,
- ("Destroying h_qp %I64x. h_ioctl %p\n",
- (uint64_t)h_qp, h_qp->p_irp_que->h_ioctl ) );
+ ("Destroying h_qp %#I64x, uhdl %#I64x, h_ioctl %p, cid %d\n",
+ (uint64_t)h_qp, h_qp->obj.hdl, h_qp->p_irp_que->h_ioctl, ((al_conn_qp_t*)h_qp)->cid ) );
/* cancel pending IRPS for NDI type CQ */
ndi_qp_flush_ques( h_qp );
IN DEVICE_OBJECT* p_dev_obj,
IN void* context )
{
- net32_t cid;
NTSTATUS status;
ib_qp_handle_t h_qp = (ib_qp_handle_t)context;
UNUSED_PARAM(p_dev_obj);
__cep_timewait_qp( h_qp );
- cid = cl_atomic_xchg(
- &((al_conn_qp_t*)h_qp)->cid, AL_INVALID_CID );
- ref_al_obj( &h_qp->obj );
- if( cid == AL_INVALID_CID || al_destroy_cep(
- h_qp->obj.h_al, cid, deref_al_obj ) != IB_SUCCESS )
- {
- deref_al_obj( &h_qp->obj );
- }
-
h_qp->p_irp_que->state = NDI_CM_IDLE;
status = (h_qp->p_irp_que->state == NDI_CM_CONNECTED) ? STATUS_CONNECTION_DISCONNECTED : STATUS_CONNECTION_REFUSED;
__ndi_complete_irp( h_qp, h_qp->p_irp_que->h_ioctl, status );
- deref_al_obj( &h_qp->obj ); /* release the extra reference */
+ deref_al_obj( &h_qp->obj ); /* release IRP SA reference */
AL_EXIT( AL_DBG_NDI );
}
*/
-void
+static void
__ndi_proc_rej(
IN const ib_cm_handle_t* const p_cm,
IN const mad_cm_rej_t* const p_rej )
{
net32_t cid;
NTSTATUS status;
- ndi_qp_csq_t *p_ndi_csq = p_cm->h_qp->p_irp_que;
+ ib_qp_handle_t h_qp = p_cm->h_qp;
+ ndi_qp_csq_t *p_ndi_csq = h_qp->p_irp_que;
AL_ENTER( AL_DBG_NDI );
- AL_PRINT(TRACE_LEVEL_INFORMATION, AL_DBG_NDI,
- ("p_rej %p, h_qp %p connect reject, reason=%d\n",
- p_rej, p_cm->h_qp, cl_ntoh16(p_rej->reason) ) );
+ AL_PRINT(TRACE_LEVEL_ERROR, AL_DBG_ERROR,
+ ("p_rej %p, h_qp %#I64x, uhdl %#I64x, connect reject, reason=%hd\n",
+ p_rej, (uint64_t)h_qp, h_qp->obj.hdl, cl_ntoh16(p_rej->reason) ) );
- ref_al_obj( &p_cm->h_qp->obj );
- cid = cl_atomic_xchg( &((al_conn_qp_t*)p_cm->h_qp)->cid, AL_INVALID_CID );
- CL_ASSERT( cid == p_cm->cid || cid == AL_INVALID_CID );
+ ref_al_obj( &h_qp->obj );
+ cid = cl_atomic_xchg( &((al_conn_qp_t*)h_qp)->cid, AL_INVALID_CID );
+ CL_ASSERT( cid == p_cm->cid || cid == AL_RESERVED_CID || cid == AL_INVALID_CID );
if( cid == AL_INVALID_CID ||
al_destroy_cep( p_cm->h_al, cid, deref_al_obj ) != IB_SUCCESS )
{
- deref_al_obj( &p_cm->h_qp->obj );
+ deref_al_obj( &h_qp->obj );
}
switch (p_ndi_csq->state)
{
case NDI_CM_CONNECTING_REQ_SENT:
al_cep_set_pdata( p_cm->h_al, p_cm->cid, IB_REJ_PDATA_SIZE, (uint8_t*)p_rej->pdata );
- AL_PRINT(TRACE_LEVEL_ERROR ,AL_DBG_ERROR ,
+ AL_PRINT(TRACE_LEVEL_INFORMATION, AL_DBG_NDI ,
("set %d of REQ pdata to CEP with cid %d, h_al %p\n",
IB_REJ_PDATA_SIZE, p_cm->cid, p_cm->h_al ));
status = (p_rej->reason == IB_REJ_TIMEOUT) ? STATUS_TIMEOUT : STATUS_CONNECTION_REFUSED;
- __ndi_complete_irp_ex( p_cm->h_qp, status, NDI_CM_CONNECTING_REJ_RCVD );
+ __ndi_complete_irp_ex( h_qp, status, NDI_CM_CONNECTING_REJ_RCVD );
break;
case NDI_CM_CONNECTED:
We are treating this case it like a DREQ */
{
IO_STACK_LOCATION *p_io_stack;
- PIO_WORKITEM p_workitem;
cl_ioctl_handle_t h_ioctl;
- h_ioctl = IoCsqRemoveNextIrp( &p_cm->h_qp->p_irp_que->csq, NULL );
+ h_ioctl = IoCsqRemoveNextIrp( &h_qp->p_irp_que->csq, NULL );
if (!h_ioctl)
{ /* IRP has been cancelled */
- //TODO: don't know where to take DeviceObject */
- AL_PRINT(TRACE_LEVEL_INFORMATION, AL_DBG_NDI,
- ("Not handled REJ case: ndi_state %d\n",
- p_ndi_csq->state ) );
+ // TODO: no QP flash
+ AL_PRINT(TRACE_LEVEL_INFORMATION, AL_DBG_NDI ,
+ ( "IRP cancelled: Can't flush the QP %p, ndi_state %d\n",
+ h_qp, p_ndi_csq->state ) );
+ h_qp->p_irp_que->state = NDI_CM_IDLE;
// ASSERT(FALSE);
- break;
- }
- p_io_stack = IoGetCurrentIrpStackLocation( h_ioctl );
- p_workitem = IoAllocateWorkItem( p_io_stack->DeviceObject );
- if ( p_workitem )
- { /* asyncronous performing */
- p_cm->h_qp->p_irp_que->p_workitem = p_workitem;
- IoQueueWorkItem( p_workitem, __ndi_req_cm_wi, DelayedWorkQueue, p_cm->h_qp );
- break;
}
else
- { /* syncronous performing */
- //TODO: what can we do here ?
- AL_PRINT(TRACE_LEVEL_INFORMATION, AL_DBG_NDI,
- ("Not handled REJ case: ndi_state %d\n",
- p_ndi_csq->state ) );
-// ASSERT(FALSE);
- break;
+ {
+ p_io_stack = IoGetCurrentIrpStackLocation( h_ioctl );
+ h_qp->p_irp_que->p_workitem = IoAllocateWorkItem( p_io_stack->DeviceObject );
+ if ( h_qp->p_irp_que->p_workitem )
+ { /* asyncronous performing */
+ IoQueueWorkItem( h_qp->p_irp_que->p_workitem,
+ __ndi_req_cm_wi, DelayedWorkQueue, h_qp );
+ }
+ else
+ { /* syncronous performing */
+ // TODO: no QP flash
+ AL_PRINT(TRACE_LEVEL_ERROR ,AL_DBG_ERROR ,
+ ( "Can't flush the QP %p, ndi_state %d\n",
+ h_qp, p_ndi_csq->state ) );
+ h_qp->p_irp_que->state = NDI_CM_IDLE;
+ status = (h_qp->p_irp_que->state == NDI_CM_CONNECTED) ? STATUS_CONNECTION_DISCONNECTED : STATUS_CONNECTION_REFUSED;
+ __ndi_complete_irp( h_qp, h_ioctl, status );
+ deref_al_obj( &h_qp->obj ); /* release IRP SA reference */
+ h_qp->p_irp_que->h_ioctl = NULL;
+ }
}
+ break;
}
default:
AL_ENTER( AL_DBG_NDI );
- AL_PRINT(TRACE_LEVEL_INFORMATION ,AL_DBG_NDI ,("h_qp = 0x%p\n", p_cm->h_qp));
+ AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI ,("h_qp = 0x%p\n", p_cm->h_qp));
if ( p_ndi_csq->state != NDI_CM_CONNECTING_REQ_SENT)
{
ib_mad_t*p_mad = ib_get_mad_buf( p_mad_el );
ib_qp_handle_t h_qp = (ib_qp_handle_t)context;
- h_cm.h_al = h_al;
- h_cm.h_qp = h_qp;
- h_cm.cid = cid;
-
if( p_mad_el->status != IB_SUCCESS )
{
switch( p_mad->attr_id )
{
case CM_REQ_ATTR_ID:
+ AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,
+ ("REQ timeouted for CEP with cid %d, h_al %p, context %p, new_cid %d .\n",
+ cid, h_al, h_qp, new_cid ) );
__ndi_complete_irp_ex( h_qp, STATUS_TIMEOUT, NDI_CM_IDLE );
break;
case CM_REP_ATTR_ID:
+ AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,
+ ("REP timeouted for CEP with cid %d, h_al %p, context %p, new_cid %d .\n",
+ cid, h_al, h_qp, new_cid ) );
__ndi_complete_irp_ex( h_qp, STATUS_CONNECTION_ABORTED, NDI_CM_IDLE );
break;
case CM_DREQ_ATTR_ID:
- __ndi_complete_irp_ex( h_qp, STATUS_SUCCESS, NDI_CM_IDLE );
- break;
-
default:
AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,
- ("Invalid CM send MAD attribute ID %d.\n", p_mad->attr_id) );
+ ("Unhandled MAD attr ID %d for CEP with cid %d, h_al %p, context %p, new_cid %d .\n",
+ p_mad->attr_id, cid, h_al, h_qp, new_cid ) );
break;
}
}
else
{
+ h_cm.h_al = h_al;
+ h_cm.h_qp = h_qp;
+ h_cm.cid = cid;
+
switch( p_mad->attr_id )
{
case CM_REP_ATTR_ID:
- // TODO: how to prevent calling this handler with QP destroyed ?
- if( ((al_conn_qp_t*)h_qp)->cid == (int32_t)cid ||
- ((al_conn_qp_t*)h_qp)->cid == AL_INVALID_CID )
- {
- __ndi_proc_rep( &h_cm, (mad_cm_rep_t*)p_mad );
- }
- else
- {
- AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,
- ("REP received when QP destroyed, cid %d:%d .\n",
- ((al_conn_qp_t*)h_qp)->cid, cid ) );
- }
+ AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,
+ ("REP received for CEP with cid %d, h_al %p, context %p, new_cid %d .\n",
+ cid, h_al, h_qp, new_cid ) );
+ CL_ASSERT( ((al_conn_qp_t*)h_qp)->cid == (int32_t)cid ||
+ ((al_conn_qp_t*)h_qp)->cid == AL_INVALID_CID ||
+ ((al_conn_qp_t*)h_qp)->cid == AL_RESERVED_CID );
+ __ndi_proc_rep( &h_cm, (mad_cm_rep_t*)p_mad );
break;
case CM_REJ_ATTR_ID:
+ AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,
+ ("REJ received for CEP with cid %d, h_al %p, context %p, new_cid %d .\n",
+ cid, h_al, h_qp, new_cid ) );
__ndi_proc_rej( &h_cm, (mad_cm_rej_t*)p_mad );
break;
case CM_DREQ_ATTR_ID:
- // TODO: how to prevent calling this handler with QP destroyed ?
- if( ((al_conn_qp_t*)h_qp)->cid == (int32_t)cid ||
- ((al_conn_qp_t*)h_qp)->cid == AL_INVALID_CID )
- {
- __ndi_proc_dreq( &h_cm, (mad_cm_dreq_t*)p_mad );
- }
- else
- {
- AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,
- ("DREQ received when QP destroyed, cid %d:%d .\n",
- ((al_conn_qp_t*)h_qp)->cid, cid ) );
- }
+ AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,
+ ("DREQ received for CEP with cid %d, h_al %p, context %p, new_cid %d .\n",
+ cid, h_al, h_qp, new_cid ) );
+ CL_ASSERT( ((al_conn_qp_t*)h_qp)->cid == (int32_t)cid ||
+ ((al_conn_qp_t*)h_qp)->cid == AL_INVALID_CID ||
+ ((al_conn_qp_t*)h_qp)->cid == AL_RESERVED_CID );
+ __ndi_proc_dreq( &h_cm, (mad_cm_dreq_t*)p_mad );
break;
default:
AL_ENTER( AL_DBG_NDI );
- AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,
+ AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,
("status is %d, count is %d, context %p\n", p_query_rec->status,
p_query_rec->result_cnt, p_query_rec->query_context) );
("al_create_cep returned %s.\n", ib_get_err_str( status )) );
goto err_irp_complete;
}
+ AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,
+ ("Created Active CEP with cid %d, h_al %p, context %p\n",
+ cid, qp_get_al( h_qp ), h_qp ) );
/* See if this QP has already been connected. */
old_cid = cl_atomic_comp_xchg( &((al_conn_qp_t*)h_qp)->cid, AL_INVALID_CID, cid );
- if( old_cid != AL_INVALID_CID )
+ if( old_cid != AL_INVALID_CID || h_qp->obj.state == CL_DESTROYING )
goto err_cep_destroy;
/* Format ib_cm_req_t structure */
if( status != IB_SUCCESS )
goto err_irp_remove;
+ /* we can release it now. In case of QP destroy __destroying_qp will remove CEP */
+ deref_al_obj( &h_qp->obj ); /* release IRP SA reference */
+
/* SUCCESS ! */
goto exit;
err_irp_complete:
h_qp->p_irp_que->state = NDI_CM_IDLE;
- __ndi_complete_irp( h_qp, h_ioctl, STATUS_HOST_UNREACHABLE );
- deref_al_obj( &h_qp->obj ); /* release the extra reference */
+ /* the IRP "has" 2 QP references, taken in __ndi_ats_query */
+ if ( h_ioctl )
+ __ndi_complete_irp( h_qp, h_ioctl, STATUS_HOST_UNREACHABLE );
+ deref_al_obj( &h_qp->obj ); /* release IRP SA reference */
exit:
cl_free( p_req );
user_query.src_gid.unicast.interface_id = p_req->guid;
user_query.dest_gid = *p_dest_gid;
- AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,
+ AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,
("Query for path from %I64x to %I64x\n",
p_req->guid, ib_gid_get_guid( p_dest_gid )) );
if( status != IB_SUCCESS )
{
AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR, ("ib_query failed (%d)\n", status) );
+ cl_free( p_req );
__ndi_complete_irp_ex( h_qp, CL_ERROR, NDI_CM_IDLE );
+ /* relase additional reference, taken in __ndi_ats_query */
+ deref_al_obj( &h_qp->obj ); /* release IRP SA reference */
}
AL_EXIT( AL_DBG_NDI );
if( !h_ioctl || p_query_rec->status != IB_SUCCESS || !p_query_rec->result_cnt )
{
h_qp->p_irp_que->state = NDI_CM_IDLE;
- __ndi_complete_irp( h_qp, h_ioctl, STATUS_HOST_UNREACHABLE );
- deref_al_obj( &h_qp->obj ); /* release the extra reference */
+ if ( h_ioctl )
+ __ndi_complete_irp( h_qp, h_ioctl, STATUS_HOST_UNREACHABLE );
+ deref_al_obj( &h_qp->obj ); /* release IRP SA reference */
cl_free( p_req );
goto exit; /* ATS request failed */
}
AL_EXIT( AL_DBG_NDI );
}
-/* Synchronously query the SA for a GUID. Return 0 on success. */
-cl_status_t
+/* Send asynchronous query to SA for a GUID. Return STATUS_PENDING on success. */
+NTSTATUS
__ndi_ats_query(
IN ib_qp_handle_t const h_qp,
IN cl_ioctl_handle_t h_ioctl,
ib_service_record_t service_record;
ib_query_req_t query_req;
ib_api_status_t status;
- cl_status_t cl_status = CL_PENDING;
+ NTSTATUS nt_status = STATUS_PENDING;
AL_ENTER( AL_DBG_NDI );
service_record.service_data8[15]
) );
- h_qp->p_irp_que->state = NDI_CM_CONNECTING_ATS_SENT;
- /* prevent destroying QP after cancelling of the IRP and before ib_query calback*/
AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,
- ("h_qp %I64x, ref_cnt %d\n", (uint64_t)h_qp, h_qp->obj.ref_cnt ) );
- ref_al_obj( &h_qp->obj ); /* take the extra reference */
+ ("h_qp %#I64x, uhdl %#I64x, ref_cnt %d\n",
+ (uint64_t)h_qp, h_qp->obj.hdl, h_qp->obj.ref_cnt ) );
+
+ // preserve QP for the life of this IOCTL
+ ref_al_obj( &h_qp->obj ); /* take IRP life reference */
/* insert IRP in the queue */
IoCsqInsertIrp( &h_qp->p_irp_que->csq, h_ioctl, NULL );
+ /* prevent destroying QP after cancelling of the IRP and before ib_query calback*/
+ ref_al_obj( &h_qp->obj ); /* take IRP SA reference */
+
/* query SA */
status = ib_query( qp_get_al( h_qp ), &query_req, &h_qp->p_irp_que->h_query );
if( status != IB_SUCCESS )
{
AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR, ("ib_query failed (%d)\n", status) );
- __ndi_complete_irp_ex( h_qp, CL_ERROR, NDI_CM_IDLE );
- cl_status = CL_COMPLETED;
+ deref_al_obj( &h_qp->obj ); /* release IRP SA reference */
+ h_ioctl = IoCsqRemoveNextIrp( &h_qp->p_irp_que->csq, NULL );
+ if ( h_ioctl )
+ { /* IOCTL should be released in the caller */
+ deref_al_obj( &h_qp->obj ); /* release IRP life reference */
+ nt_status = STATUS_DRIVER_INTERNAL_ERROR;
+ }
}
AL_EXIT( AL_DBG_NDI );
- return cl_status;
+ return nt_status;
}
NTSTATUS
if ( h_qp->p_irp_que->h_ioctl )
{
AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,
- ("STATUS_CONNECTION_ACTIVE: h_qp %I64x, ref_cnt %d\n",
- (uint64_t)h_qp, h_qp->obj.ref_cnt ) );
+ ("STATUS_CONNECTION_ACTIVE: h_qp %#I64x, uhdl %#I64x, ref_cnt %d\n",
+ (uint64_t)h_qp, h_qp->obj.hdl, h_qp->obj.ref_cnt ) );
nt_status = STATUS_CONNECTION_ACTIVE;
__ndi_release_lock( &h_qp->p_irp_que->csq, 0 );
goto exit;
nt_status = __ndi_ats_query( h_qp, h_ioctl, p_req );
exit:
+ if ( nt_status != STATUS_PENDING )
+ {
+ cl_free( p_req );
+ h_qp->p_irp_que->state = NDI_CM_IDLE;
+ h_qp->p_irp_que->h_ioctl = NULL; /* mark IRP as present */
+ cl_ioctl_complete( h_ioctl, nt_status, 0 );
+ }
AL_EXIT( AL_DBG_NDI );
- return nt_status;
+ return STATUS_PENDING;
}
if( cid != AL_INVALID_CID )
{
ref_al_obj( &h_qp->obj );
- if( al_destroy_cep( qp_get_al( h_qp ),
- ((al_conn_qp_t*)h_qp)->cid, deref_al_obj ) != IB_SUCCESS )
+ if( al_destroy_cep( qp_get_al( h_qp ), cid, deref_al_obj ) != IB_SUCCESS )
{
deref_al_obj( &h_qp->obj );
}
}
- AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,
+ AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,
("al_cep_rtu returned %s.\n", ib_get_err_str( status )) );
h_qp->p_irp_que->state = NDI_CM_IDLE;
nt_status = STATUS_DRIVER_INTERNAL_ERROR;
nt_status = STATUS_SUCCESS;
exit:
+ /* release the reference only for async case */
+ if ( p_irp->Tail.Overlay.DriverContext[1] )
+ deref_al_obj( &h_qp->obj );
+
p_irp->IoStatus.Status = nt_status;
IoCompleteRequest( p_irp, IO_NO_INCREMENT );
- deref_al_obj( &h_qp->obj );
AL_EXIT( AL_DBG_NDI );
}
p_irp->Tail.Overlay.DriverContext[1] = IoAllocateWorkItem( p_io_stack->DeviceObject );
if ( p_irp->Tail.Overlay.DriverContext[1] )
{ /* asyncronous performing */
+ /* take a ref to prevent QP destroy before calling work item */
+ ref_al_obj( &h_qp->obj );
IoMarkIrpPending( p_irp );
IoQueueWorkItem( p_irp->Tail.Overlay.DriverContext[1],
__ndi_rtu_cm, DelayedWorkQueue, p_irp );
nt_status = STATUS_SUCCESS;
exit:
+ /* release the reference only for async case */
+ if ( p_irp->Tail.Overlay.DriverContext[1] )
+ deref_al_obj( &h_qp->obj );
+
p_irp->IoStatus.Status = nt_status;
IoCompleteRequest( p_irp, IO_NO_INCREMENT );
- deref_al_obj( &h_qp->obj );
AL_EXIT( AL_DBG_NDI );
}
/* Format ib_cm_req_t structure */
__ndi_fill_cm_rep( h_qp, p_rep, &cm_rep );
- /* prepare CEP for connection */
+ /* prepare Passive CEP for connection */
status = al_cep_pre_rep_ex( qp_get_al( h_qp ), cid, __ndi_cm_handler, h_qp, &cm_rep, &qp_mod );
if( status != IB_SUCCESS )
{
goto err_cep_destroy;
}
+ AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,
+ ("Prepared Passive CEP with cid %d, h_al %p, context %p\n",
+ cid, qp_get_al( h_qp ), h_qp ) );
+
/* See if this QP has already been connected. */
old_cid = cl_atomic_comp_xchg( &((al_conn_qp_t*)h_qp)->cid, AL_INVALID_CID, cid );
if( old_cid != AL_INVALID_CID )
p_irp->Tail.Overlay.DriverContext[1] = IoAllocateWorkItem( p_io_stack->DeviceObject );
if ( p_irp->Tail.Overlay.DriverContext[1] )
{ /* asyncronous performing */
+ /* take a ref to prevent QP destroy before calling work item */
+ ref_al_obj( &h_qp->obj );
IoMarkIrpPending( p_irp );
IoQueueWorkItem( p_irp->Tail.Overlay.DriverContext[1],
__ndi_rep_cm, DelayedWorkQueue, p_irp );
al_destroy_cep( qp_get_al( h_qp ), cid, NULL );
h_qp->p_irp_que->state = NDI_CM_IDLE;
- __ndi_complete_irp( h_qp, p_irp, nt_status );
+ cl_ioctl_complete( p_irp, nt_status, 0 );
exit:
AL_EXIT( AL_DBG_NDI );
if( cid != AL_INVALID_CID )
{
ref_al_obj( &h_qp->obj );
- if( al_destroy_cep( qp_get_al( h_qp ),
- ((al_conn_qp_t*)h_qp)->cid, deref_al_obj ) != IB_SUCCESS )
+ if( al_destroy_cep( qp_get_al( h_qp ), cid, deref_al_obj ) != IB_SUCCESS )
{
deref_al_obj( &h_qp->obj );
}