/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
*
* MODULE: dapls_cr_callback.c
*
* PURPOSE: implements passive side connection callbacks
*
* Description: Accepts asynchronous callbacks from the Communications Manager
* for EVDs that have been specified as the connection_evd.
*
* $Id: dapl_cr_callback.c,v 1.58 2003/08/20 14:55:39 sjs2 Exp $
*/
#include "dapl.h"
#include "dapl_evd_util.h"
#include "dapl_cr_util.h"
#include "dapl_ia_util.h"
#include "dapl_sp_util.h"
#include "dapl_ep_util.h"
#include "dapl_adapter_util.h"
/*
* Prototypes
*/
/*
* dapls_cr_callback
*
* The callback function registered with verbs for passive side of
* connection requests. The interface is specified by cm_api.h
*
*
* Input:
* ib_cm_handle, Handle to CM
* ib_cm_event Specific CM event
* instant_data Private data with DAT ADDRESS header
* context SP pointer
*
* Output:
* None
*
*/
void
{
"--> dapls_cr_callback! context: 0x%p "
"event: %d cm_handle 0x%llx magic 0x%x\n",
return;
}
/*
* Passive side of the connection, context is a SP and
* we need to look up the EP.
*/
/*
* CONNECT_REQUEST events create an event on the PSP
* EVD, which will trigger connection processing. The
* sequence is:
* CONNECT_REQUEST Event to SP
* CONNECTED Event to EP
* DISCONNECT Event to EP
*
* Obtain the EP if required and set an event up on the correct EVD.
*/
if (ib_cm_event == IB_CME_CONNECTION_REQUEST_PENDING ||
} else {
" dapls_cr_callback cont: ep 0x%p evd 0x%p\n",
}
switch (ib_cm_event) {
/*
* Requests arriving on a disabled SP are immediatly rejected
*/
"---> dapls_cr_callback: conn event on down SP\n");
return;
}
/*
* RSP connections only allow a single connection. Close
* it down NOW so we reject any further connections.
*/
}
/*
* Only occurs on the passive side of a connection
* dapli_connection_request will post the connection
* event if appropriate.
*/
break;
}
case IB_CME_CONNECTED: {
/*
* This is just a notification the connection is now
* established, there isn't any private data to deal with.
*
* Update the EP state and cache a copy of the cm handle,
* then let the user know we are ready to go.
*/
/*
* If someone pulled the plug on the connection, just
* exit
*/
break;
}
(DAT_HANDLE) ep_ptr,
/*
* post them to the recv evd now.
* there is a race here - if events arrive after we change
* the ep state to connected and before we process premature
* events
*/
break;
}
case IB_CME_DISCONNECTED:
case IB_CME_DISCONNECTED_ON_LINK_DOWN: {
/*
* EP is now fully disconnected; initiate any post processing
* to reset the underlying QP and get the EP ready for
* another connection
*/
/* DTO error caused this */
} else {
}
/*
* If the user has done an ep_free of the EP, we have been
* waiting for the disconnect event; just clean it up now.
*/
(void) dapl_ep_free(ep_ptr);
}
/* If the EP has been freed, the evd_ptr will be NULL */
}
break;
}
case IB_CME_DESTINATION_UNREACHABLE: {
/*
* After posting an accept the requesting node has
* stopped talking.
*/
(DAT_HANDLE) ep_ptr, 0, 0);
break;
}
/*
* DAPL does not deal with this IB error. There is a
* separate OVERFLOW event error if we try to post too many
* events, but we don't propagate this provider error. Not
* all providers generate this error.
*/
break;
}
case IB_CME_LOCAL_FAILURE: {
(DAT_HANDLE) ep_ptr, 0, 0);
break;
}
case IB_CME_TIMED_OUT: {
(DAT_HANDLE) ep_ptr, 0, 0);
break;
}
default:
dapl_os_assert(0); /* shouldn't happen */
break;
}
if (dat_status != DAT_SUCCESS) {
/* The event post failed; take appropriate action. */
return;
}
}
/*
* dapli_connection_request
*
* Process a connection request on the Passive side of a connection.
* Create a CR record and link it on to the SP so we can update it
* and free it later. Create an EP if specified by the PSP flags.
*
* Input:
* ib_cm_handle,
* sp_ptr
* event_ptr
* prd_ptr
*
* Output:
* None
*
* Returns
* DAT_INSUFFICIENT_RESOURCES
* DAT_SUCCESS
*
*/
{
/* Invoking function will call dapls_ib_cm_reject() */
return (DAT_INSUFFICIENT_RESOURCES);
}
/*
* Set up the CR
*/
/*
* Copy the remote address and private data out of the private_data
* payload and put them in a local structure
*/
case AF_INET:
break;
case AF_INET6:
break;
default:
break;
}
/* EP will be NULL unless RSP service point */
/*
* Never true for RSP connections
*
* Create an EP for the user. If we can't allocate an
* EP we are out of resources and need to tell the
* requestor that we cant help them.
*/
/* Invoking function will call dapls_ib_cm_reject() */
return (DAT_INSUFFICIENT_RESOURCES);
}
/* Link the EP onto the IA */
}
/* Assign valid EP fields: RSP and PSP_PROVIDER_FLAG only */
} else { /* RSP */
}
}
/* Post the event. */
/* assign sp_ptr to union to avoid typecast errors from compilers */
if (dat_status != DAT_SUCCESS) {
return (DAT_INSUFFICIENT_RESOURCES);
}
/* link the CR onto the SP so we can pick it up later */
return (DAT_SUCCESS);
}
/*
* dapli_get_sp_ep
*
* Passive side of a connection is now fully established. Clean
* up resources and obtain the EP pointer associated with a CR in
* the SP
*
* Input:
* ib_cm_handle,
* sp_ptr
*
* Output:
* none
*
* Returns
* ep_ptr
*
*/
DAPL_EP *
{
/*
* There are potentially multiple connections in progress. Need to
* go through the list and find the one we are interested
* in. There is no guarantee of order. dapl_sp_search_cr
* leaves the CR on the SP queue.
*/
dapl_os_assert(0);
return (NULL);
}
if (ib_cm_event == IB_CME_DISCONNECTED ||
/* Remove the CR from the queue */
/*
* Last event, time to clean up and dispose of the resource
*/
/*
* If this SP has been removed from service, free it
* up after the last CR is removed
*/
sp_ptr->cr_list_count == 0 &&
"--> dapli_get_sp_ep! disconnect dump sp: %p \n",
sp_ptr);
(void) dapls_ib_remove_conn_listener(sp_ptr->
sp_ptr);
} else {
}
}
return (ep_ptr);
}