[openib-general] [PATCH][RFC] kDAPL: remove dat wrapper funct ion dat_ia_query()

Tom Duffy tduffy at sun.com
Fri Jun 10 10:23:57 PDT 2005


On Fri, 2005-06-10 at 08:33 +0300, Itamar Rabenstein wrote:
> I think that sp+psp+rsp should be one file dapl_sp.c

You are correct.  I should have done this the first time.  Here is a
patch to fix this.

Signed-off-by: Tom Duffy <tduffy at sun.com>

Index: linux-kernel/dat-provider/dapl_ia.c
===================================================================
--- linux-kernel/dat-provider/dapl_ia.c	(revision 2585)
+++ linux-kernel/dat-provider/dapl_ia.c	(working copy)
@@ -35,7 +35,7 @@
 #include "dapl_evd.h"
 #include "dapl_hca_util.h"
 #include "dapl_openib_util.h"
-#include "dapl_sp_util.h"
+#include "dapl_sp.h"
 #include "dapl_cr.h"
 
 struct dapl_ia *dapl_ia_alloc(struct dat_provider *provider,
Index: linux-kernel/dat-provider/Makefile
===================================================================
--- linux-kernel/dat-provider/Makefile	(revision 2585)
+++ linux-kernel/dat-provider/Makefile	(working copy)
@@ -28,13 +28,10 @@ PROVIDER_MODULES := \
         dapl_lmr                 	\
         dapl_mr_util                  	\
         dapl_provider                 	\
-        dapl_sp_util                  	\
-        dapl_psp                	\
         dapl_pz                         \
         dapl_ring_buffer_util         	\
         dapl_rmr                 	\
-        dapl_rsp 	              	\
-        dapl_sp_util                  	\
+        dapl_sp                  	\
         dapl_srq                 	\
 	dapl_util
 
Index: linux-kernel/dat-provider/dapl_psp.c
===================================================================
--- linux-kernel/dat-provider/dapl_psp.c	(revision 2585)
+++ linux-kernel/dat-provider/dapl_psp.c	(working copy)
@@ -1,445 +0,0 @@
-/*
- * Copyright (c) 2002-2005, Network Appliance, Inc. All rights reserved.
- *
- * This Software is licensed under one of the following licenses:
- *
- * 1) under the terms of the "Common Public License 1.0" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/cpl.php.
- *
- * 2) under the terms of the "The BSD License" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/bsd-license.php.
- *
- * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
- *    copy of which is available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/gpl-license.php.
- *
- * Licensee has the right to choose one of the above licenses.
- *
- * Redistributions of source code must retain the above copyright
- * notice and one of the license notices.
- *
- * Redistributions in binary form must reproduce both the above copyright
- * notice, one of the license notices in the documentation
- * and/or other materials provided with the distribution.
- */
-
-/*
- * $Id$
- */
-
-#include "dapl.h"
-#include "dapl_sp_util.h"
-#include "dapl_ia.h"
-#include "dapl_openib_util.h"
-
-/*
- * dapl_psp_create_any
- *
- * Create a persistent Public Service Point that can recieve multiple
- * requests for connections and generate multiple connection request
- * instances that wil be delivered to the specified Event Dispatcher
- * in a notification event. Differs from dapl_psp_create() in that
- * the conn_qual is selected by the implementation and returned to
- * the user.
- *
- * Input:
- * 	ia
- * 	evd
- * 	psp_flags
- *
- * Output:
- * 	conn_qual
- * 	psp
- *
- * Returns:
- * 	DAT_SUCCESS
- * 	DAT_INSUFFICIENT_RESOURCES
- * 	DAT_INVALID_HANDLE
- * 	DAT_INVALID_PARAMETER
- * 	DAT_CONN_QUAL_IN_USE
- * 	DAT_MODEL_NOT_SUPPORTED
- */
-u32 dapl_psp_create_any(struct dat_ia *ia, DAT_CONN_QUAL *conn_qual,
-			struct dat_evd *evd, enum dat_psp_flags psp_flags,
-			struct dat_sp **psp)
-{
-	static DAT_CONN_QUAL hint_conn_qual = 1000;	/* seed value */
-	struct dapl_ia *ia_ptr;
-	struct dapl_sp *sp_ptr;
-	struct dapl_evd *evd_ptr;
-	u32 status = DAT_SUCCESS;
-	int i;
-
-	ia_ptr = (struct dapl_ia *)ia;
-
-	if (!ia_ptr) {
-		status = DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_IA);
-		goto bail;
-	}
-	if (!evd) {
-		status =
-		    DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EVD_CR);
-		goto bail;
-	}
-
-	if (psp == NULL) {
-		status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG5);
-		goto bail;
-	}
-	if (conn_qual == NULL) {
-		status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG2);
-		goto bail;
-	}
-
-	evd_ptr = (struct dapl_evd *)evd;
-	if (!(evd_ptr->evd_flags & DAT_EVD_CR_FLAG)) {
-		status = DAT_ERROR(DAT_INVALID_HANDLE,
-				   DAT_INVALID_HANDLE_EVD_CR);
-		goto bail;
-	}
-
-	if (psp_flags != DAT_PSP_CONSUMER_FLAG &&
-	    psp_flags != DAT_PSP_PROVIDER_FLAG) {
-		status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG4);
-		goto bail;
-	}
-
-	/* Allocate PSP */
-	sp_ptr = dapl_sp_alloc(ia_ptr, TRUE);
-	if (sp_ptr == NULL) {
-		status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
-				   DAT_RESOURCE_MEMORY);
-		goto bail;
-	}
-
-	/*
-	 * Fill out the args for a PSP
-	 */
-	sp_ptr->ia = ia;
-	sp_ptr->evd = evd;
-	sp_ptr->psp_flags = psp_flags;
-	sp_ptr->ep = NULL;
-
-	/*
-	 * Take a reference on the EVD handle
-	 */
-	atomic_inc(&evd_ptr->evd_ref_count);
-
-	/* Link it onto the IA */
-	dapl_ia_link_psp(ia_ptr, sp_ptr);
-
-	/* 
-	 * Set up a listener for a connection. Connections can arrive
-	 * even before this call returns!
-	 */
-	sp_ptr->state = DAPL_SP_STATE_PSP_LISTENING;
-	sp_ptr->listening = TRUE;
-
-	/*
-	 * If we have a big number of tries and we still haven't
-	 * found a service_ID we can use, bail out with an error,
-	 * something is wrong!
-	 */
-	for (i = 0, sp_ptr->conn_qual = hint_conn_qual; i < 100000; i++) {
-		status = dapl_ib_setup_conn_listener(ia_ptr, sp_ptr);
-		if (DAT_SUCCESS == status)
-			break;
-		else 
-			sp_ptr->conn_qual++;
-	}
-	hint_conn_qual = sp_ptr->conn_qual + 1;
-
-	if (status != DAT_SUCCESS) {
-		atomic_dec(&evd_ptr->evd_ref_count);
-		sp_ptr->evd = NULL;
-		dapl_ia_unlink_sp(ia_ptr, sp_ptr);
-		dapl_sp_dealloc(sp_ptr);
-
-		dapl_dbg_log(DAPL_DBG_TYPE_ERR, 
-			"dapl_psp_create cannot set up conn listener: %x\n",
-			status);
-
-		goto bail;
-	}
-
-	/*
-	 * Return handle to the user
-	 */
-	*conn_qual = sp_ptr->conn_qual;
-	*psp = (struct dat_sp *) sp_ptr;
-
-bail:
-	return status;
-}
-
-/*
- * dapl_psp_create
- *
- * Create a persistent Public Service Point that can recieve multiple
- * requests for connections and generate multiple connection request
- * instances that wil be delivered to the specified Event Dispatcher
- * in a notification event.
- *
- * Input:
- * 	ia
- * 	conn_qual
- * 	evd
- * 	psp_flags
- *
- * Output:
- * 	psp
- *
- * Returns:
- * 	DAT_SUCCESS
- * 	DAT_INSUFFICIENT_RESOURCES
- * 	DAT_INVALID_PARAMETER
- * 	DAT_CONN_QUAL_IN_USE
- * 	DAT_MODEL_NOT_SUPPORTED
- */
-u32 dapl_psp_create(struct dat_ia *ia, DAT_CONN_QUAL conn_qual,
-		    struct dat_evd *evd, enum dat_psp_flags psp_flags,
-		    struct dat_sp **psp)
-{
-	struct dapl_ia *ia_ptr;
-	struct dapl_sp *sp_ptr;
-	struct dapl_evd *evd_ptr;
-	boolean_t sp_found;
-	u32 status = DAT_SUCCESS;
-
-	ia_ptr = (struct dapl_ia *)ia;
-
-	if (!ia_ptr) {
-		status = DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_IA);
-		goto bail;
-	}
-	if (!evd) {
-		status = DAT_ERROR(DAT_INVALID_HANDLE,
-				   DAT_INVALID_HANDLE_EVD_CR);
-		goto bail;
-	}
-
-	if (psp == NULL) {
-		status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG5);
-		goto bail;
-	}
-
-	evd_ptr = (struct dapl_evd *)evd;
-	if (!(evd_ptr->evd_flags & DAT_EVD_CR_FLAG)) {
-		status = DAT_ERROR(DAT_INVALID_HANDLE,
-				   DAT_INVALID_HANDLE_EVD_CR);
-		goto bail;
-	}
-
-	if (psp_flags != DAT_PSP_CONSUMER_FLAG &&
-	    psp_flags != DAT_PSP_PROVIDER_FLAG) {
-		status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG4);
-		goto bail;
-	}
-
-	/*
-	 * See if we have a quiescent listener to use for this PSP, else
-	 * create one and set it listening
-	 */
-	sp_ptr = dapl_ia_sp_search(ia_ptr, conn_qual, TRUE);
-	sp_found = TRUE;
-	if (sp_ptr == NULL) {
-		/* Allocate PSP */
-		sp_found = FALSE;
-		sp_ptr = dapl_sp_alloc(ia_ptr, TRUE);
-		if (sp_ptr == NULL) {
-			status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
-					   DAT_RESOURCE_MEMORY);
-			goto bail;
-		}
-	} else if (sp_ptr->listening == TRUE) {
-		status = DAT_ERROR(DAT_CONN_QUAL_IN_USE, 0);
-		goto bail;
-	}
-
-	/*
-	 * Fill out the args for a PSP
-	 */
-	sp_ptr->ia = ia;
-	sp_ptr->conn_qual = conn_qual;
-	sp_ptr->evd = evd;
-	sp_ptr->psp_flags = psp_flags;
-	sp_ptr->ep = NULL;
-
-	/*
-	 * Take a reference on the EVD handle
-	 */
-	atomic_inc(&evd_ptr->evd_ref_count);
-
-	/* 
-	 * Set up a listener for a connection. Connections can arrive
-	 * even before this call returns!
-	 */
-	sp_ptr->state = DAPL_SP_STATE_PSP_LISTENING;
-	sp_ptr->listening = TRUE;
-
-	/*
-	 * If this is a new sp we need to add it to the IA queue, and set up
-	 * a conn_listener.
-	 */
-	if (sp_found == FALSE) {
-		/*
-		 * Link it onto the IA before enabling it to receive conn
-		 * requests
-		 */
-		dapl_ia_link_psp(ia_ptr, sp_ptr);
-
-		status = dapl_ib_setup_conn_listener(ia_ptr, sp_ptr);
-
-		if (status != DAT_SUCCESS) {
-			/*
-			 * Have a problem setting up the connection, something
-			 * wrong!  Decrements the EVD refcount & release it.
-			 */
-			atomic_dec(&evd_ptr->evd_ref_count);
-			sp_ptr->evd = NULL;
-			dapl_ia_unlink_sp(ia_ptr, sp_ptr);
-			dapl_sp_dealloc(sp_ptr);
-
-			dapl_dbg_log(DAPL_DBG_TYPE_CM, "dapl_psp_create "
-				     "setup_conn_listener failed: %x\n", 
-				     status);
-
-			goto bail;
-		}
-	}
-
-	/*
-	 * Return handle to the user
-	 */
-	*psp = (struct dat_sp *) sp_ptr;
-
-bail:
-	return status;
-}
-
-/*
- * dapl_psp_free
- *
- * Destroy a specific instance of a Service Point.
- *
- * Input:
- * 	psp
- *
- * Output:
- * 	none
- *
- * Returns:
- * 	DAT_SUCCESS
- * 	DAT_INVALID_PARAMETER
- */
-u32 dapl_psp_free(struct dat_sp *psp)
-{
-	struct dapl_ia *ia_ptr;
-	struct dapl_sp *sp_ptr;
-	DAPL_SP_STATE save_state;
-	u32 status = DAT_SUCCESS;
-
-	sp_ptr = (struct dapl_sp *)psp;
-	/*
-	 * Verify handle
-	 */
-	dapl_dbg_log(DAPL_DBG_TYPE_CM, ">>> dapl_psp_free %p\n", psp);
-
-	if (!sp_ptr) {
-		status = DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_PSP);
-		goto bail;
-	}
-
-	ia_ptr = sp_ptr->common.owner_ia;
-	/* 
-	 * Remove the connection listener if it has been established
-	 * and there are no current connections in progress.
-	 * If we defer removing the sp it becomes something of a zombie
-	 * container until the last connection is disconnected, after
-	 * which it will be cleaned up.
-	 */
-	spin_lock_irqsave(&sp_ptr->common.lock, sp_ptr->common.flags);
-
-	sp_ptr->listening = FALSE;
-
-	/*
-	 * Release reference on EVD. If an error was encountered in a previous
-	 * free the evd will be NULL
-	 */
-	if (sp_ptr->evd) {
-		atomic_dec(&((struct dapl_evd *)sp_ptr->evd)->
-				   evd_ref_count);
-		sp_ptr->evd = NULL;
-	}
-
-	/*
-	 * Release the base resource if there are no outstanding
-	 * connections; else the last disconnect on this PSP will free it
-	 * up. The PSP is used to contain CR records for each connection,
-	 * which contain information necessary to disconnect.
-	 */
-	dapl_dbg_log(DAPL_DBG_TYPE_CM,
-		     ">>> dapl_psp_free: state %d cr_list_count %d\n",
-		     sp_ptr->state, sp_ptr->cr_list_count);
-	if ((sp_ptr->state == DAPL_SP_STATE_PSP_LISTENING ||
-	     sp_ptr->state == DAPL_SP_STATE_PSP_PENDING) &&
-	    sp_ptr->cr_list_count == 0) {
-		save_state = sp_ptr->state;
-		sp_ptr->state = DAPL_SP_STATE_FREE;
-		spin_unlock_irqrestore(&sp_ptr->common.lock,
-				       sp_ptr->common.flags);
-
-		status = dapl_ib_remove_conn_listener(ia_ptr, sp_ptr);
-		if (status != DAT_SUCCESS) {
-			/* revert to entry state on error */
-			sp_ptr->state = save_state;
-			goto bail;
-		}
-		dapl_ia_unlink_sp(ia_ptr, sp_ptr);
-		dapl_sp_dealloc(sp_ptr);
-	} else {
-		/*
-		 * The PSP is now in the pending state, where it will sit until
-		 * the last connection terminates or the app uses the same
-		 * ServiceID again, which will reactivate it.
-		 */
-		sp_ptr->state = DAPL_SP_STATE_PSP_PENDING;
-		spin_unlock_irqrestore(&sp_ptr->common.lock,
-				       sp_ptr->common.flags);
-		dapl_dbg_log(DAPL_DBG_TYPE_CM,
-			     ">>> dapl_psp_free: PSP PENDING\n");
-	}
-
-bail:
-	return status;
-}
-
-u32 dapl_psp_query(struct dat_sp *psp, struct dat_psp_param *psp_param)
-{
-	struct dapl_sp *sp_ptr;
-	u32 status;
-
-	if (!psp || ((struct dapl_sp *)psp)->listening != TRUE) {
-		status = DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_PSP);
-		goto bail;
-	}
-
-	if (NULL == psp_param) {
-		status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG3);
-		goto bail;
-	}
-
-	sp_ptr = (struct dapl_sp *)psp;
-
-	psp_param->ia = sp_ptr->ia;
-	psp_param->conn_qual = sp_ptr->conn_qual;
-	psp_param->evd = sp_ptr->evd;
-	psp_param->psp_flags = sp_ptr->psp_flags;
-
-	status = DAT_SUCCESS;
-
-bail:
-	return status;
-}
Index: linux-kernel/dat-provider/dapl_cr.c
===================================================================
--- linux-kernel/dat-provider/dapl_cr.c	(revision 2585)
+++ linux-kernel/dat-provider/dapl_cr.c	(working copy)
@@ -35,7 +35,7 @@
 #include "dapl_evd.h"
 #include "dapl_ia.h"
 #include "dapl_openib_util.h"
-#include "dapl_sp_util.h"
+#include "dapl_sp.h"
 
 /*
  * Create a CR. Part of the passive side of a connection
Index: linux-kernel/dat-provider/dapl_rsp.c
===================================================================
--- linux-kernel/dat-provider/dapl_rsp.c	(revision 2585)
+++ linux-kernel/dat-provider/dapl_rsp.c	(working copy)
@@ -1,314 +0,0 @@
-/*
- * Copyright (c) 2002-2005, Network Appliance, Inc. All rights reserved.
- *
- * This Software is licensed under one of the following licenses:
- *
- * 1) under the terms of the "Common Public License 1.0" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/cpl.php.
- *
- * 2) under the terms of the "The BSD License" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/bsd-license.php.
- *
- * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
- *    copy of which is available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/gpl-license.php.
- *
- * Licensee has the right to choose one of the above licenses.
- *
- * Redistributions of source code must retain the above copyright
- * notice and one of the license notices.
- *
- * Redistributions in binary form must reproduce both the above copyright
- * notice, one of the license notices in the documentation
- * and/or other materials provided with the distribution.
- */
-
-/*
- * $Id$
- */
-
-#include "dapl.h"
-#include "dapl_sp_util.h"
-#include "dapl_ia.h"
-#include "dapl_ep.h"
-#include "dapl_openib_util.h"
-
-/*
- * dapl_rsp_create
- *
- * Create a Resereved Service Point with the specified Endpoint
- * that generates at most one Connection Request that is
- * delivered to the specified Event Dispatcher in a notification
- * event
- *
- * Input:
- *	ia
- *	conn_qual
- *	ep
- *	evd
- *
- * Output:
- *	rsp
- *
- * Returns:
- *	DAT_SUCCESS
- *	DAT_INSUFFICIENT_RESOURCES
- *	DAT_INVALID_PARAMETER
- *	DAT_INVALID_STATE
- *	DAT_CONN_QUAL_IN_USE
- */
-u32 dapl_rsp_create(struct dat_ia *ia, DAT_CONN_QUAL conn_qual,
-		    struct dat_ep *ep, struct dat_evd *evd,
-		    struct dat_sp **rsp)
-{
-	struct dapl_ia *ia_ptr;
-	struct dapl_sp *sp_ptr;
-	struct dapl_evd *evd_ptr;
-	struct dapl_ep *ep_ptr;
-	boolean_t sp_found;
-	u32 status = DAT_SUCCESS;
-
-	ia_ptr = (struct dapl_ia *)ia;
-
-	dapl_dbg_log(DAPL_DBG_TYPE_CM,
-		     ">>> dapl_rsp_free conn_qual: %x EP: %p\n",
-		     conn_qual, ep);
-
-	if (!ia_ptr) {
-		status = DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_IA);
-		goto bail;
-	}
-	if (!ep) {
-		status = DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EP);
-		goto bail;
-	}
-	if (!evd) {
-		status = DAT_ERROR(DAT_INVALID_HANDLE,
-				   DAT_INVALID_HANDLE_EVD_CR);
-		goto bail;
-	}
-
-	if (rsp == NULL) {
-		status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG5);
-		goto bail;
-	}
-
-	ep_ptr = (struct dapl_ep *)ep;
-	if (ep_ptr->param.ep_state != DAT_EP_STATE_UNCONNECTED) {
-		status = DAT_ERROR(DAT_INVALID_STATE,
-				   dapl_ep_state_subtype(ep_ptr));
-		goto bail;
-	}
-
-	evd_ptr = (struct dapl_evd *)evd;
-	if (!(evd_ptr->evd_flags & DAT_EVD_CR_FLAG)) {
-		status = DAT_ERROR(DAT_INVALID_HANDLE,
-				   DAT_INVALID_HANDLE_EVD_CR);
-		goto bail;
-	}
-
-	sp_ptr = dapl_ia_sp_search(ia_ptr, conn_qual, FALSE);
-	sp_found = TRUE;
-	if (sp_ptr == NULL) {
-		sp_found = FALSE;
-
-		/* Allocate RSP */
-		sp_ptr = dapl_sp_alloc(ia_ptr, FALSE);
-		if (sp_ptr == NULL) {
-			status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
-					   DAT_RESOURCE_MEMORY);
-			goto bail;
-		}
-	}
-
-	/*
-	 * Fill out the RSP args
-	 */
-	sp_ptr->ia = ia;
-	sp_ptr->conn_qual = conn_qual;
-	sp_ptr->evd = evd;
-	sp_ptr->psp_flags = 0;
-	sp_ptr->ep = ep;
-
-	/*
-	 * Take a reference on the EVD handle
-	 */
-	atomic_inc(&evd_ptr->evd_ref_count);
-
-	/*
-	 * Update the EP state indicating the provider now owns it
-	 */
-	ep_ptr->param.ep_state = DAT_EP_STATE_RESERVED;
-
-	/* 
-	 * Set up a listener for a connection. Connections can arrive
-	 * even before this call returns!
-	 */
-	sp_ptr->state = DAPL_SP_STATE_RSP_LISTENING;
-	sp_ptr->listening = TRUE;
-
-	if (sp_found == FALSE) {
-		/* Link it onto the IA */
-		dapl_ia_link_rsp(ia_ptr, sp_ptr);
-
-		status = dapl_ib_setup_conn_listener(ia_ptr, sp_ptr);
-
-		if (status != DAT_SUCCESS) {
-			/*
-			 * Have a problem setting up the connection, something
-			 * wrong!  Decrements the EVD refcount & release it. Set 
-			 * the state to FREE, so we know the call failed.
-			 */
-			atomic_dec(&evd_ptr->evd_ref_count);
-			sp_ptr->evd = NULL;
-			sp_ptr->state = DAPL_SP_STATE_FREE;
-			dapl_ia_unlink_sp(ia_ptr, sp_ptr);
-			dapl_sp_dealloc(sp_ptr);
-
-			dapl_dbg_log(DAPL_DBG_TYPE_CM,
-				     "--> dapl_rsp_create setup_conn_listener failed: %x\n",
-				     status);
-
-			goto bail;
-		}
-	}
-
-	/*
-	 * Return handle to the user
-	 */
-	*rsp = (struct dat_sp *)sp_ptr;
-
-bail:
-	return status;
-}
-
-/*
- * dapl_rsp_free
- *
- * Destroy a specific instance of a Reserved Service Point.
- *
- * Input:
- *	rsp
- *
- * Output:
- *	none
- *
- * Returns:
- *	DAT_SUCCESS
- *	DAT_INVALID_HANDLE
- */
-u32 dapl_rsp_free(struct dat_sp *rsp)
-{
-	struct dapl_ia *ia_ptr;
-	struct dapl_sp *sp_ptr;
-	struct dapl_ep *ep_ptr;
-	u32 status = DAT_SUCCESS;
-
-	sp_ptr = (struct dapl_sp *)rsp;
-	/*
-	 * Verify handle
-	 */
-	dapl_dbg_log(DAPL_DBG_TYPE_CM, ">>> dapl_rsp_free %p\n", rsp);
-	if (!sp_ptr) {
-		status = DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_RSP);
-		goto bail;
-	}
-
-	ia_ptr = sp_ptr->common.owner_ia;
-
-	/*
-	 * Remove the connection listener if there are no connections.  If
-	 * we defer removing the sp it becomes something of a zombie
-	 * container until disconnection, after which it will be cleaned up.
-	 */
-	spin_lock_irqsave(&sp_ptr->common.lock, sp_ptr->common.flags);
-
-	/*
-	 * Make sure we don't leave a dangling EP. If the state is still
-	 * RESERVED then the RSP still owns it.
-	 */
-	ep_ptr = (struct dapl_ep *)sp_ptr->ep;
-	if (ep_ptr != NULL && ep_ptr->param.ep_state == DAT_EP_STATE_RESERVED)
-		ep_ptr->param.ep_state = DAT_EP_STATE_UNCONNECTED;
-	sp_ptr->ep = NULL;
-
-	/*
-	 * Release reference on EVD. If an error was encountered in a previous
-	 * free the evd will be NULL
-	 */
-	if (sp_ptr->evd) {
-		atomic_dec(&((struct dapl_evd *)sp_ptr->evd)->
-				   evd_ref_count);
-		sp_ptr->evd = NULL;
-	}
-
-	/*
-	 * Release the base resource if there are no outstanding connections;
-	 * else the last disconnect on this RSP will free it up. The RSP
-	 * is used to contain CR records for each connection, which 
-	 * contain information necessary to disconnect.
-	 * sp_ptr->listening will be TRUE if there has never been a
-	 * connection event, and FALSE if a connection attempt resulted
-	 * in a reject.
-	 */
-	if (sp_ptr->cr_list_count == 0) {
-		/* This RSP has never been used. Clean it up */
-		sp_ptr->listening = FALSE;
-		sp_ptr->state = DAPL_SP_STATE_FREE;
-		spin_unlock_irqrestore(&sp_ptr->common.lock, 
-				       sp_ptr->common.flags);
-
-		status = dapl_ib_remove_conn_listener(ia_ptr, sp_ptr);
-		if (status != DAT_SUCCESS) {
-			sp_ptr->state = DAPL_SP_STATE_RSP_LISTENING;
-			goto bail;
-		}
-		dapl_ia_unlink_sp(ia_ptr, sp_ptr);
-		dapl_sp_dealloc(sp_ptr);
-	} else {
-		/*
-		 * The RSP is now in the pending state, where it will sit until
-		 * the connection terminates or the app uses the same
-		 * ServiceID again, which will reactivate it.
-		 */
-		sp_ptr->state = DAPL_SP_STATE_RSP_PENDING;
-		spin_unlock_irqrestore(&sp_ptr->common.lock, 
-				       sp_ptr->common.flags);
-	}
-
-bail:
-	return status;
-}
-
-u32 dapl_rsp_query(struct dat_sp *rsp, struct dat_rsp_param *rsp_param)
-{
-	struct dapl_sp *sp_ptr;
-	u32 status;
-
-	if (!rsp) {
-		status = DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_RSP);
-		goto bail;
-	}
-
-	if (NULL == rsp_param) {
-		status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG3);
-		goto bail;
-	}
-
-	sp_ptr = (struct dapl_sp *)rsp;
-
-	/*
-	 * Fill in the RSP params
-	 */
-	rsp_param->ia = sp_ptr->ia;
-	rsp_param->conn_qual = sp_ptr->conn_qual;
-	rsp_param->evd = sp_ptr->evd;
-	rsp_param->ep = sp_ptr->ep;
-
-	status = DAT_SUCCESS;
-
-bail:
-	return status;
-}
Index: linux-kernel/dat-provider/dapl_ep.c
===================================================================
--- linux-kernel/dat-provider/dapl_ep.c	(revision 2585)
+++ linux-kernel/dat-provider/dapl_ep.c	(working copy)
@@ -39,7 +39,7 @@
 #include "dapl_openib_dto.h"
 #include "dapl_openib_util.h"
 #include "dapl_ring_buffer_util.h"
-#include "dapl_sp_util.h"
+#include "dapl_sp.h"
 
 static void dapl_ep_dealloc(struct dapl_ep *ep_ptr)
 {
Index: linux-kernel/dat-provider/dapl_sp_util.c
===================================================================
--- linux-kernel/dat-provider/dapl_sp_util.c	(revision 2585)
+++ linux-kernel/dat-provider/dapl_sp_util.c	(working copy)
@@ -1,240 +0,0 @@
-/*
- * Copyright (c) 2002-2005, Network Appliance, Inc. All rights reserved.
- *
- * This Software is licensed under one of the following licenses:
- *
- * 1) under the terms of the "Common Public License 1.0" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/cpl.php.
- *
- * 2) under the terms of the "The BSD License" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/bsd-license.php.
- *
- * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
- *    copy of which is available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/gpl-license.php.
- *
- * Licensee has the right to choose one of the above licenses.
- *
- * Redistributions of source code must retain the above copyright
- * notice and one of the license notices.
- *
- * Redistributions in binary form must reproduce both the above copyright
- * notice, one of the license notices in the documentation
- * and/or other materials provided with the distribution.
- */
-
-/*
- * $Id$
- */
-
-#include "dapl.h"
-#include "dapl_sp_util.h"
-#include "dapl_cr.h"
-
-/*
- * Local definitions
- */
-
-/*
- * dapl_sp_alloc
- *
- * alloc and initialize an SP 
- *
- * Input:
- * 	IA INFO struct ptr
- *
- * Output:
- * 	sp_ptr
- *
- * Returns:
- * 	NULL
- *	pointer to sp info struct
- *
- */
-struct dapl_sp *dapl_sp_alloc(struct dapl_ia *ia_ptr, boolean_t is_psp)
-{
-	struct dapl_sp *sp_ptr;
-
-	/* Allocate EP */
-	sp_ptr = kmalloc(sizeof *sp_ptr, GFP_ATOMIC);
-	if (!sp_ptr)
-		return NULL;
-
-	/* zero the structure */
-	memset(sp_ptr, 0, sizeof *sp_ptr);
-
-	sp_ptr->sp.common.provider = ia_ptr->ia.common.provider;
-	if (is_psp)
-		sp_ptr->sp.type = DAT_SP_TYPE_PSP;
-	else
-		sp_ptr->sp.type = DAT_SP_TYPE_RSP;
-	sp_ptr->common.owner_ia = ia_ptr;
-	dapl_llist_init_entry(&sp_ptr->common.ia_list_entry);
-	spin_lock_init(&sp_ptr->common.lock);
-
-	/*
-	 * Initialize the Body (set to NULL above)
-	 */
-	dapl_llist_init_head(&sp_ptr->cr_list_head);
-
-	return sp_ptr;
-}
-
-/*
- * dapl_sp_dealloc
- *
- * Free the passed in SP structure.
- *
- * Input:
- * 	entry point pointer
- *
- * Output:
- * 	none
- *
- * Returns:
- * 	none
- *
- */
-void dapl_sp_dealloc(struct dapl_sp *sp_ptr)
-{
-	dapl_os_assert(dapl_llist_is_empty(&sp_ptr->cr_list_head));
-
-	kfree(sp_ptr);
-}
-
-/*
- * dapl_cr_link_cr
- *
- * Add a cr to a PSP structure
- *
- * Input:
- *	sp_ptr
- *	cr_ptr
- *
- * Output:
- * 	none
- *
- * Returns:
- * 	none
- *
- */
-void dapl_sp_link_cr(struct dapl_sp *sp_ptr, struct dapl_cr *cr_ptr)
-{
-	spin_lock_irqsave(&sp_ptr->common.lock, sp_ptr->common.flags);
-	dapl_llist_add_tail(&sp_ptr->cr_list_head,
-			    &cr_ptr->common.ia_list_entry, cr_ptr);
-	sp_ptr->cr_list_count++;
-	spin_unlock_irqrestore(&sp_ptr->common.lock, sp_ptr->common.flags);
-}
-
-/*
- * dapl_sp_search_cr
- *
- * Search for a CR on the PSP cr_list with a matching cm_handle. When
- * found, remove it from the list and update fields.
- *
- * Must be called with the sp_ptr lock taken.
- *
- * Input:
- *	sp_ptr
- *	ib_cm_handle
- *
- * Output:
- * 	none
- *
- * Returns:
- * 	cr_ptr	Pointer to matching DAPL_CR
- *
- */
-struct dapl_cr *dapl_sp_search_cr(struct dapl_sp *sp_ptr,
-				  struct dapl_cm_id *ib_cm_handle)
-{
-	struct dapl_cr *cr_ptr;
-
-	if (dapl_llist_is_empty(&sp_ptr->cr_list_head))
-		return NULL;
-
-	cr_ptr = (struct dapl_cr *)dapl_llist_peek_head(&sp_ptr->cr_list_head);
-
-	do {
-		if (cr_ptr->ib_cm_handle == ib_cm_handle)
-			return cr_ptr;
-		
-		cr_ptr = cr_ptr->common.ia_list_entry.flink->data;
-	} while ((void *)cr_ptr != (void *)sp_ptr->cr_list_head->data);
-
-	return NULL;
-}
-
-/*
- * dapl_sp_remove_cr
- *
- * Remove the CR from the PSP. Done prior to freeing the CR resource.
- *
- * Must be called with the sp_ptr lock taken.
- *
- * Input:
- *	sp_ptr
- *	cr_ptr
- *
- * Output:
- * 	none
- *
- * Returns:
- * 	void
- *
- */
-void dapl_sp_remove_cr(struct dapl_sp *sp_ptr, struct dapl_cr *cr_ptr)
-{
-	if (dapl_llist_is_empty(&sp_ptr->cr_list_head)) {
-		dapl_dbg_log(DAPL_DBG_TYPE_ERR,
-			     "***dapl_sp_remove_cr: removing from empty queue! sp %p\n",
-			     sp_ptr);
-		return;
-	}
-
-	dapl_llist_remove_entry(&sp_ptr->cr_list_head,
-				&cr_ptr->common.ia_list_entry);
-	sp_ptr->cr_list_count--;
-}
-
-/*
- * dapl_sp_remove_ep
- *
- * Remove a CR from a PSP, given an EP.
- *
- *
- * Input:
- *	ep_ptr
- *
- * Output:
- * 	none
- *
- * Returns:
- * 	void
- *
- */
-void dapl_sp_remove_ep(struct dapl_ep *ep_ptr)
-{
-	struct dapl_sp *sp_ptr;
-	struct dapl_cr *cr_ptr;
-
-	cr_ptr = ep_ptr->cr_ptr;
-
-	if (cr_ptr != NULL) {
-		sp_ptr = cr_ptr->sp_ptr;
-
-		spin_lock_irqsave(&sp_ptr->common.lock, sp_ptr->common.flags);
-
-		/* Remove the CR from the queue */
-		dapl_sp_remove_cr(sp_ptr, cr_ptr);
-
-		spin_unlock_irqrestore(&sp_ptr->common.lock, 
-				       sp_ptr->common.flags);
-
-		/* free memory outside of the lock */
-		dapl_cr_free(cr_ptr);
-	}
-}
Index: linux-kernel/dat-provider/dapl_sp.c
===================================================================
--- linux-kernel/dat-provider/dapl_sp.c	(revision 0)
+++ linux-kernel/dat-provider/dapl_sp.c	(revision 0)
@@ -0,0 +1,931 @@
+/*
+ * Copyright (c) 2002-2005, Network Appliance, Inc. All rights reserved.
+ *
+ * This Software is licensed under one of the following licenses:
+ *
+ * 1) under the terms of the "Common Public License 1.0" a copy of which is
+ *    available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/cpl.php.
+ *
+ * 2) under the terms of the "The BSD License" a copy of which is
+ *    available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/bsd-license.php.
+ *
+ * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
+ *    copy of which is available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/gpl-license.php.
+ *
+ * Licensee has the right to choose one of the above licenses.
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice and one of the license notices.
+ *
+ * Redistributions in binary form must reproduce both the above copyright
+ * notice, one of the license notices in the documentation
+ * and/or other materials provided with the distribution.
+ */
+
+/*
+ * $Id: dapl_sp_util.c 2584 2005-06-10 15:31:30Z jlentini $
+ */
+
+#include "dapl.h"
+#include "dapl_sp.h"
+#include "dapl_cr.h"
+#include "dapl_ep.h"
+#include "dapl_ia.h"
+#include "dapl_openib_util.h"
+
+/*
+ * Local definitions
+ */
+
+/*
+ * dapl_sp_alloc
+ *
+ * alloc and initialize an SP 
+ *
+ * Input:
+ * 	IA INFO struct ptr
+ *
+ * Output:
+ * 	sp_ptr
+ *
+ * Returns:
+ * 	NULL
+ *	pointer to sp info struct
+ *
+ */
+struct dapl_sp *dapl_sp_alloc(struct dapl_ia *ia_ptr, boolean_t is_psp)
+{
+	struct dapl_sp *sp_ptr;
+
+	/* Allocate EP */
+	sp_ptr = kmalloc(sizeof *sp_ptr, GFP_ATOMIC);
+	if (!sp_ptr)
+		return NULL;
+
+	/* zero the structure */
+	memset(sp_ptr, 0, sizeof *sp_ptr);
+
+	sp_ptr->sp.common.provider = ia_ptr->ia.common.provider;
+	if (is_psp)
+		sp_ptr->sp.type = DAT_SP_TYPE_PSP;
+	else
+		sp_ptr->sp.type = DAT_SP_TYPE_RSP;
+	sp_ptr->common.owner_ia = ia_ptr;
+	dapl_llist_init_entry(&sp_ptr->common.ia_list_entry);
+	spin_lock_init(&sp_ptr->common.lock);
+
+	/*
+	 * Initialize the Body (set to NULL above)
+	 */
+	dapl_llist_init_head(&sp_ptr->cr_list_head);
+
+	return sp_ptr;
+}
+
+/*
+ * dapl_sp_dealloc
+ *
+ * Free the passed in SP structure.
+ *
+ * Input:
+ * 	entry point pointer
+ *
+ * Output:
+ * 	none
+ *
+ * Returns:
+ * 	none
+ *
+ */
+void dapl_sp_dealloc(struct dapl_sp *sp_ptr)
+{
+	dapl_os_assert(dapl_llist_is_empty(&sp_ptr->cr_list_head));
+
+	kfree(sp_ptr);
+}
+
+/*
+ * dapl_cr_link_cr
+ *
+ * Add a cr to a PSP structure
+ *
+ * Input:
+ *	sp_ptr
+ *	cr_ptr
+ *
+ * Output:
+ * 	none
+ *
+ * Returns:
+ * 	none
+ *
+ */
+void dapl_sp_link_cr(struct dapl_sp *sp_ptr, struct dapl_cr *cr_ptr)
+{
+	spin_lock_irqsave(&sp_ptr->common.lock, sp_ptr->common.flags);
+	dapl_llist_add_tail(&sp_ptr->cr_list_head,
+			    &cr_ptr->common.ia_list_entry, cr_ptr);
+	sp_ptr->cr_list_count++;
+	spin_unlock_irqrestore(&sp_ptr->common.lock, sp_ptr->common.flags);
+}
+
+/*
+ * dapl_sp_search_cr
+ *
+ * Search for a CR on the PSP cr_list with a matching cm_handle. When
+ * found, remove it from the list and update fields.
+ *
+ * Must be called with the sp_ptr lock taken.
+ *
+ * Input:
+ *	sp_ptr
+ *	ib_cm_handle
+ *
+ * Output:
+ * 	none
+ *
+ * Returns:
+ * 	cr_ptr	Pointer to matching DAPL_CR
+ *
+ */
+struct dapl_cr *dapl_sp_search_cr(struct dapl_sp *sp_ptr,
+				  struct dapl_cm_id *ib_cm_handle)
+{
+	struct dapl_cr *cr_ptr;
+
+	if (dapl_llist_is_empty(&sp_ptr->cr_list_head))
+		return NULL;
+
+	cr_ptr = (struct dapl_cr *)dapl_llist_peek_head(&sp_ptr->cr_list_head);
+
+	do {
+		if (cr_ptr->ib_cm_handle == ib_cm_handle)
+			return cr_ptr;
+		
+		cr_ptr = cr_ptr->common.ia_list_entry.flink->data;
+	} while ((void *)cr_ptr != (void *)sp_ptr->cr_list_head->data);
+
+	return NULL;
+}
+
+/*
+ * dapl_sp_remove_cr
+ *
+ * Remove the CR from the PSP. Done prior to freeing the CR resource.
+ *
+ * Must be called with the sp_ptr lock taken.
+ *
+ * Input:
+ *	sp_ptr
+ *	cr_ptr
+ *
+ * Output:
+ * 	none
+ *
+ * Returns:
+ * 	void
+ *
+ */
+void dapl_sp_remove_cr(struct dapl_sp *sp_ptr, struct dapl_cr *cr_ptr)
+{
+	if (dapl_llist_is_empty(&sp_ptr->cr_list_head)) {
+		dapl_dbg_log(DAPL_DBG_TYPE_ERR,
+			     "***dapl_sp_remove_cr: removing from empty queue! sp %p\n",
+			     sp_ptr);
+		return;
+	}
+
+	dapl_llist_remove_entry(&sp_ptr->cr_list_head,
+				&cr_ptr->common.ia_list_entry);
+	sp_ptr->cr_list_count--;
+}
+
+/*
+ * dapl_sp_remove_ep
+ *
+ * Remove a CR from a PSP, given an EP.
+ *
+ *
+ * Input:
+ *	ep_ptr
+ *
+ * Output:
+ * 	none
+ *
+ * Returns:
+ * 	void
+ *
+ */
+void dapl_sp_remove_ep(struct dapl_ep *ep_ptr)
+{
+	struct dapl_sp *sp_ptr;
+	struct dapl_cr *cr_ptr;
+
+	cr_ptr = ep_ptr->cr_ptr;
+
+	if (cr_ptr != NULL) {
+		sp_ptr = cr_ptr->sp_ptr;
+
+		spin_lock_irqsave(&sp_ptr->common.lock, sp_ptr->common.flags);
+
+		/* Remove the CR from the queue */
+		dapl_sp_remove_cr(sp_ptr, cr_ptr);
+
+		spin_unlock_irqrestore(&sp_ptr->common.lock, 
+				       sp_ptr->common.flags);
+
+		/* free memory outside of the lock */
+		dapl_cr_free(cr_ptr);
+	}
+}
+
+/*
+ * dapl_rsp_create
+ *
+ * Create a Resereved Service Point with the specified Endpoint
+ * that generates at most one Connection Request that is
+ * delivered to the specified Event Dispatcher in a notification
+ * event
+ *
+ * Input:
+ *	ia
+ *	conn_qual
+ *	ep
+ *	evd
+ *
+ * Output:
+ *	rsp
+ *
+ * Returns:
+ *	DAT_SUCCESS
+ *	DAT_INSUFFICIENT_RESOURCES
+ *	DAT_INVALID_PARAMETER
+ *	DAT_INVALID_STATE
+ *	DAT_CONN_QUAL_IN_USE
+ */
+u32 dapl_rsp_create(struct dat_ia *ia, DAT_CONN_QUAL conn_qual,
+		    struct dat_ep *ep, struct dat_evd *evd,
+		    struct dat_sp **rsp)
+{
+	struct dapl_ia *ia_ptr;
+	struct dapl_sp *sp_ptr;
+	struct dapl_evd *evd_ptr;
+	struct dapl_ep *ep_ptr;
+	boolean_t sp_found;
+	u32 status = DAT_SUCCESS;
+
+	ia_ptr = (struct dapl_ia *)ia;
+
+	dapl_dbg_log(DAPL_DBG_TYPE_CM,
+		     ">>> dapl_rsp_free conn_qual: %x EP: %p\n",
+		     conn_qual, ep);
+
+	if (!ia_ptr) {
+		status = DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_IA);
+		goto bail;
+	}
+	if (!ep) {
+		status = DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EP);
+		goto bail;
+	}
+	if (!evd) {
+		status = DAT_ERROR(DAT_INVALID_HANDLE,
+				   DAT_INVALID_HANDLE_EVD_CR);
+		goto bail;
+	}
+
+	if (rsp == NULL) {
+		status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG5);
+		goto bail;
+	}
+
+	ep_ptr = (struct dapl_ep *)ep;
+	if (ep_ptr->param.ep_state != DAT_EP_STATE_UNCONNECTED) {
+		status = DAT_ERROR(DAT_INVALID_STATE,
+				   dapl_ep_state_subtype(ep_ptr));
+		goto bail;
+	}
+
+	evd_ptr = (struct dapl_evd *)evd;
+	if (!(evd_ptr->evd_flags & DAT_EVD_CR_FLAG)) {
+		status = DAT_ERROR(DAT_INVALID_HANDLE,
+				   DAT_INVALID_HANDLE_EVD_CR);
+		goto bail;
+	}
+
+	sp_ptr = dapl_ia_sp_search(ia_ptr, conn_qual, FALSE);
+	sp_found = TRUE;
+	if (sp_ptr == NULL) {
+		sp_found = FALSE;
+
+		/* Allocate RSP */
+		sp_ptr = dapl_sp_alloc(ia_ptr, FALSE);
+		if (sp_ptr == NULL) {
+			status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
+					   DAT_RESOURCE_MEMORY);
+			goto bail;
+		}
+	}
+
+	/*
+	 * Fill out the RSP args
+	 */
+	sp_ptr->ia = ia;
+	sp_ptr->conn_qual = conn_qual;
+	sp_ptr->evd = evd;
+	sp_ptr->psp_flags = 0;
+	sp_ptr->ep = ep;
+
+	/*
+	 * Take a reference on the EVD handle
+	 */
+	atomic_inc(&evd_ptr->evd_ref_count);
+
+	/*
+	 * Update the EP state indicating the provider now owns it
+	 */
+	ep_ptr->param.ep_state = DAT_EP_STATE_RESERVED;
+
+	/* 
+	 * Set up a listener for a connection. Connections can arrive
+	 * even before this call returns!
+	 */
+	sp_ptr->state = DAPL_SP_STATE_RSP_LISTENING;
+	sp_ptr->listening = TRUE;
+
+	if (sp_found == FALSE) {
+		/* Link it onto the IA */
+		dapl_ia_link_rsp(ia_ptr, sp_ptr);
+
+		status = dapl_ib_setup_conn_listener(ia_ptr, sp_ptr);
+
+		if (status != DAT_SUCCESS) {
+			/*
+			 * Have a problem setting up the connection, something
+			 * wrong!  Decrements the EVD refcount & release it. Set 
+			 * the state to FREE, so we know the call failed.
+			 */
+			atomic_dec(&evd_ptr->evd_ref_count);
+			sp_ptr->evd = NULL;
+			sp_ptr->state = DAPL_SP_STATE_FREE;
+			dapl_ia_unlink_sp(ia_ptr, sp_ptr);
+			dapl_sp_dealloc(sp_ptr);
+
+			dapl_dbg_log(DAPL_DBG_TYPE_CM,
+				     "--> dapl_rsp_create setup_conn_listener failed: %x\n",
+				     status);
+
+			goto bail;
+		}
+	}
+
+	/*
+	 * Return handle to the user
+	 */
+	*rsp = (struct dat_sp *)sp_ptr;
+
+bail:
+	return status;
+}
+
+/*
+ * dapl_rsp_free
+ *
+ * Destroy a specific instance of a Reserved Service Point.
+ *
+ * Input:
+ *	rsp
+ *
+ * Output:
+ *	none
+ *
+ * Returns:
+ *	DAT_SUCCESS
+ *	DAT_INVALID_HANDLE
+ */
+u32 dapl_rsp_free(struct dat_sp *rsp)
+{
+	struct dapl_ia *ia_ptr;
+	struct dapl_sp *sp_ptr;
+	struct dapl_ep *ep_ptr;
+	u32 status = DAT_SUCCESS;
+
+	sp_ptr = (struct dapl_sp *)rsp;
+	/*
+	 * Verify handle
+	 */
+	dapl_dbg_log(DAPL_DBG_TYPE_CM, ">>> dapl_rsp_free %p\n", rsp);
+	if (!sp_ptr) {
+		status = DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_RSP);
+		goto bail;
+	}
+
+	ia_ptr = sp_ptr->common.owner_ia;
+
+	/*
+	 * Remove the connection listener if there are no connections.  If
+	 * we defer removing the sp it becomes something of a zombie
+	 * container until disconnection, after which it will be cleaned up.
+	 */
+	spin_lock_irqsave(&sp_ptr->common.lock, sp_ptr->common.flags);
+
+	/*
+	 * Make sure we don't leave a dangling EP. If the state is still
+	 * RESERVED then the RSP still owns it.
+	 */
+	ep_ptr = (struct dapl_ep *)sp_ptr->ep;
+	if (ep_ptr != NULL && ep_ptr->param.ep_state == DAT_EP_STATE_RESERVED)
+		ep_ptr->param.ep_state = DAT_EP_STATE_UNCONNECTED;
+	sp_ptr->ep = NULL;
+
+	/*
+	 * Release reference on EVD. If an error was encountered in a previous
+	 * free the evd will be NULL
+	 */
+	if (sp_ptr->evd) {
+		atomic_dec(&((struct dapl_evd *)sp_ptr->evd)->
+				   evd_ref_count);
+		sp_ptr->evd = NULL;
+	}
+
+	/*
+	 * Release the base resource if there are no outstanding connections;
+	 * else the last disconnect on this RSP will free it up. The RSP
+	 * is used to contain CR records for each connection, which 
+	 * contain information necessary to disconnect.
+	 * sp_ptr->listening will be TRUE if there has never been a
+	 * connection event, and FALSE if a connection attempt resulted
+	 * in a reject.
+	 */
+	if (sp_ptr->cr_list_count == 0) {
+		/* This RSP has never been used. Clean it up */
+		sp_ptr->listening = FALSE;
+		sp_ptr->state = DAPL_SP_STATE_FREE;
+		spin_unlock_irqrestore(&sp_ptr->common.lock, 
+				       sp_ptr->common.flags);
+
+		status = dapl_ib_remove_conn_listener(ia_ptr, sp_ptr);
+		if (status != DAT_SUCCESS) {
+			sp_ptr->state = DAPL_SP_STATE_RSP_LISTENING;
+			goto bail;
+		}
+		dapl_ia_unlink_sp(ia_ptr, sp_ptr);
+		dapl_sp_dealloc(sp_ptr);
+	} else {
+		/*
+		 * The RSP is now in the pending state, where it will sit until
+		 * the connection terminates or the app uses the same
+		 * ServiceID again, which will reactivate it.
+		 */
+		sp_ptr->state = DAPL_SP_STATE_RSP_PENDING;
+		spin_unlock_irqrestore(&sp_ptr->common.lock, 
+				       sp_ptr->common.flags);
+	}
+
+bail:
+	return status;
+}
+
+u32 dapl_rsp_query(struct dat_sp *rsp, struct dat_rsp_param *rsp_param)
+{
+	struct dapl_sp *sp_ptr;
+	u32 status;
+
+	if (!rsp) {
+		status = DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_RSP);
+		goto bail;
+	}
+
+	if (NULL == rsp_param) {
+		status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG3);
+		goto bail;
+	}
+
+	sp_ptr = (struct dapl_sp *)rsp;
+
+	/*
+	 * Fill in the RSP params
+	 */
+	rsp_param->ia = sp_ptr->ia;
+	rsp_param->conn_qual = sp_ptr->conn_qual;
+	rsp_param->evd = sp_ptr->evd;
+	rsp_param->ep = sp_ptr->ep;
+
+	status = DAT_SUCCESS;
+
+bail:
+	return status;
+}
+
+/*
+ * dapl_psp_create_any
+ *
+ * Create a persistent Public Service Point that can recieve multiple
+ * requests for connections and generate multiple connection request
+ * instances that wil be delivered to the specified Event Dispatcher
+ * in a notification event. Differs from dapl_psp_create() in that
+ * the conn_qual is selected by the implementation and returned to
+ * the user.
+ *
+ * Input:
+ * 	ia
+ * 	evd
+ * 	psp_flags
+ *
+ * Output:
+ * 	conn_qual
+ * 	psp
+ *
+ * Returns:
+ * 	DAT_SUCCESS
+ * 	DAT_INSUFFICIENT_RESOURCES
+ * 	DAT_INVALID_HANDLE
+ * 	DAT_INVALID_PARAMETER
+ * 	DAT_CONN_QUAL_IN_USE
+ * 	DAT_MODEL_NOT_SUPPORTED
+ */
+u32 dapl_psp_create_any(struct dat_ia *ia, DAT_CONN_QUAL *conn_qual,
+			struct dat_evd *evd, enum dat_psp_flags psp_flags,
+			struct dat_sp **psp)
+{
+	static DAT_CONN_QUAL hint_conn_qual = 1000;	/* seed value */
+	struct dapl_ia *ia_ptr;
+	struct dapl_sp *sp_ptr;
+	struct dapl_evd *evd_ptr;
+	u32 status = DAT_SUCCESS;
+	int i;
+
+	ia_ptr = (struct dapl_ia *)ia;
+
+	if (!ia_ptr) {
+		status = DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_IA);
+		goto bail;
+	}
+	if (!evd) {
+		status =
+		    DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EVD_CR);
+		goto bail;
+	}
+
+	if (psp == NULL) {
+		status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG5);
+		goto bail;
+	}
+	if (conn_qual == NULL) {
+		status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG2);
+		goto bail;
+	}
+
+	evd_ptr = (struct dapl_evd *)evd;
+	if (!(evd_ptr->evd_flags & DAT_EVD_CR_FLAG)) {
+		status = DAT_ERROR(DAT_INVALID_HANDLE,
+				   DAT_INVALID_HANDLE_EVD_CR);
+		goto bail;
+	}
+
+	if (psp_flags != DAT_PSP_CONSUMER_FLAG &&
+	    psp_flags != DAT_PSP_PROVIDER_FLAG) {
+		status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG4);
+		goto bail;
+	}
+
+	/* Allocate PSP */
+	sp_ptr = dapl_sp_alloc(ia_ptr, TRUE);
+	if (sp_ptr == NULL) {
+		status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
+				   DAT_RESOURCE_MEMORY);
+		goto bail;
+	}
+
+	/*
+	 * Fill out the args for a PSP
+	 */
+	sp_ptr->ia = ia;
+	sp_ptr->evd = evd;
+	sp_ptr->psp_flags = psp_flags;
+	sp_ptr->ep = NULL;
+
+	/*
+	 * Take a reference on the EVD handle
+	 */
+	atomic_inc(&evd_ptr->evd_ref_count);
+
+	/* Link it onto the IA */
+	dapl_ia_link_psp(ia_ptr, sp_ptr);
+
+	/* 
+	 * Set up a listener for a connection. Connections can arrive
+	 * even before this call returns!
+	 */
+	sp_ptr->state = DAPL_SP_STATE_PSP_LISTENING;
+	sp_ptr->listening = TRUE;
+
+	/*
+	 * If we have a big number of tries and we still haven't
+	 * found a service_ID we can use, bail out with an error,
+	 * something is wrong!
+	 */
+	for (i = 0, sp_ptr->conn_qual = hint_conn_qual; i < 100000; i++) {
+		status = dapl_ib_setup_conn_listener(ia_ptr, sp_ptr);
+		if (DAT_SUCCESS == status)
+			break;
+		else 
+			sp_ptr->conn_qual++;
+	}
+	hint_conn_qual = sp_ptr->conn_qual + 1;
+
+	if (status != DAT_SUCCESS) {
+		atomic_dec(&evd_ptr->evd_ref_count);
+		sp_ptr->evd = NULL;
+		dapl_ia_unlink_sp(ia_ptr, sp_ptr);
+		dapl_sp_dealloc(sp_ptr);
+
+		dapl_dbg_log(DAPL_DBG_TYPE_ERR, 
+			"dapl_psp_create cannot set up conn listener: %x\n",
+			status);
+
+		goto bail;
+	}
+
+	/*
+	 * Return handle to the user
+	 */
+	*conn_qual = sp_ptr->conn_qual;
+	*psp = (struct dat_sp *) sp_ptr;
+
+bail:
+	return status;
+}
+
+/*
+ * dapl_psp_create
+ *
+ * Create a persistent Public Service Point that can recieve multiple
+ * requests for connections and generate multiple connection request
+ * instances that wil be delivered to the specified Event Dispatcher
+ * in a notification event.
+ *
+ * Input:
+ * 	ia
+ * 	conn_qual
+ * 	evd
+ * 	psp_flags
+ *
+ * Output:
+ * 	psp
+ *
+ * Returns:
+ * 	DAT_SUCCESS
+ * 	DAT_INSUFFICIENT_RESOURCES
+ * 	DAT_INVALID_PARAMETER
+ * 	DAT_CONN_QUAL_IN_USE
+ * 	DAT_MODEL_NOT_SUPPORTED
+ */
+u32 dapl_psp_create(struct dat_ia *ia, DAT_CONN_QUAL conn_qual,
+		    struct dat_evd *evd, enum dat_psp_flags psp_flags,
+		    struct dat_sp **psp)
+{
+	struct dapl_ia *ia_ptr;
+	struct dapl_sp *sp_ptr;
+	struct dapl_evd *evd_ptr;
+	boolean_t sp_found;
+	u32 status = DAT_SUCCESS;
+
+	ia_ptr = (struct dapl_ia *)ia;
+
+	if (!ia_ptr) {
+		status = DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_IA);
+		goto bail;
+	}
+	if (!evd) {
+		status = DAT_ERROR(DAT_INVALID_HANDLE,
+				   DAT_INVALID_HANDLE_EVD_CR);
+		goto bail;
+	}
+
+	if (psp == NULL) {
+		status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG5);
+		goto bail;
+	}
+
+	evd_ptr = (struct dapl_evd *)evd;
+	if (!(evd_ptr->evd_flags & DAT_EVD_CR_FLAG)) {
+		status = DAT_ERROR(DAT_INVALID_HANDLE,
+				   DAT_INVALID_HANDLE_EVD_CR);
+		goto bail;
+	}
+
+	if (psp_flags != DAT_PSP_CONSUMER_FLAG &&
+	    psp_flags != DAT_PSP_PROVIDER_FLAG) {
+		status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG4);
+		goto bail;
+	}
+
+	/*
+	 * See if we have a quiescent listener to use for this PSP, else
+	 * create one and set it listening
+	 */
+	sp_ptr = dapl_ia_sp_search(ia_ptr, conn_qual, TRUE);
+	sp_found = TRUE;
+	if (sp_ptr == NULL) {
+		/* Allocate PSP */
+		sp_found = FALSE;
+		sp_ptr = dapl_sp_alloc(ia_ptr, TRUE);
+		if (sp_ptr == NULL) {
+			status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
+					   DAT_RESOURCE_MEMORY);
+			goto bail;
+		}
+	} else if (sp_ptr->listening == TRUE) {
+		status = DAT_ERROR(DAT_CONN_QUAL_IN_USE, 0);
+		goto bail;
+	}
+
+	/*
+	 * Fill out the args for a PSP
+	 */
+	sp_ptr->ia = ia;
+	sp_ptr->conn_qual = conn_qual;
+	sp_ptr->evd = evd;
+	sp_ptr->psp_flags = psp_flags;
+	sp_ptr->ep = NULL;
+
+	/*
+	 * Take a reference on the EVD handle
+	 */
+	atomic_inc(&evd_ptr->evd_ref_count);
+
+	/* 
+	 * Set up a listener for a connection. Connections can arrive
+	 * even before this call returns!
+	 */
+	sp_ptr->state = DAPL_SP_STATE_PSP_LISTENING;
+	sp_ptr->listening = TRUE;
+
+	/*
+	 * If this is a new sp we need to add it to the IA queue, and set up
+	 * a conn_listener.
+	 */
+	if (sp_found == FALSE) {
+		/*
+		 * Link it onto the IA before enabling it to receive conn
+		 * requests
+		 */
+		dapl_ia_link_psp(ia_ptr, sp_ptr);
+
+		status = dapl_ib_setup_conn_listener(ia_ptr, sp_ptr);
+
+		if (status != DAT_SUCCESS) {
+			/*
+			 * Have a problem setting up the connection, something
+			 * wrong!  Decrements the EVD refcount & release it.
+			 */
+			atomic_dec(&evd_ptr->evd_ref_count);
+			sp_ptr->evd = NULL;
+			dapl_ia_unlink_sp(ia_ptr, sp_ptr);
+			dapl_sp_dealloc(sp_ptr);
+
+			dapl_dbg_log(DAPL_DBG_TYPE_CM, "dapl_psp_create "
+				     "setup_conn_listener failed: %x\n", 
+				     status);
+
+			goto bail;
+		}
+	}
+
+	/*
+	 * Return handle to the user
+	 */
+	*psp = (struct dat_sp *) sp_ptr;
+
+bail:
+	return status;
+}
+
+/*
+ * dapl_psp_free
+ *
+ * Destroy a specific instance of a Service Point.
+ *
+ * Input:
+ * 	psp
+ *
+ * Output:
+ * 	none
+ *
+ * Returns:
+ * 	DAT_SUCCESS
+ * 	DAT_INVALID_PARAMETER
+ */
+u32 dapl_psp_free(struct dat_sp *psp)
+{
+	struct dapl_ia *ia_ptr;
+	struct dapl_sp *sp_ptr;
+	DAPL_SP_STATE save_state;
+	u32 status = DAT_SUCCESS;
+
+	sp_ptr = (struct dapl_sp *)psp;
+	/*
+	 * Verify handle
+	 */
+	dapl_dbg_log(DAPL_DBG_TYPE_CM, ">>> dapl_psp_free %p\n", psp);
+
+	if (!sp_ptr) {
+		status = DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_PSP);
+		goto bail;
+	}
+
+	ia_ptr = sp_ptr->common.owner_ia;
+	/* 
+	 * Remove the connection listener if it has been established
+	 * and there are no current connections in progress.
+	 * If we defer removing the sp it becomes something of a zombie
+	 * container until the last connection is disconnected, after
+	 * which it will be cleaned up.
+	 */
+	spin_lock_irqsave(&sp_ptr->common.lock, sp_ptr->common.flags);
+
+	sp_ptr->listening = FALSE;
+
+	/*
+	 * Release reference on EVD. If an error was encountered in a previous
+	 * free the evd will be NULL
+	 */
+	if (sp_ptr->evd) {
+		atomic_dec(&((struct dapl_evd *)sp_ptr->evd)->
+				   evd_ref_count);
+		sp_ptr->evd = NULL;
+	}
+
+	/*
+	 * Release the base resource if there are no outstanding
+	 * connections; else the last disconnect on this PSP will free it
+	 * up. The PSP is used to contain CR records for each connection,
+	 * which contain information necessary to disconnect.
+	 */
+	dapl_dbg_log(DAPL_DBG_TYPE_CM,
+		     ">>> dapl_psp_free: state %d cr_list_count %d\n",
+		     sp_ptr->state, sp_ptr->cr_list_count);
+	if ((sp_ptr->state == DAPL_SP_STATE_PSP_LISTENING ||
+	     sp_ptr->state == DAPL_SP_STATE_PSP_PENDING) &&
+	    sp_ptr->cr_list_count == 0) {
+		save_state = sp_ptr->state;
+		sp_ptr->state = DAPL_SP_STATE_FREE;
+		spin_unlock_irqrestore(&sp_ptr->common.lock,
+				       sp_ptr->common.flags);
+
+		status = dapl_ib_remove_conn_listener(ia_ptr, sp_ptr);
+		if (status != DAT_SUCCESS) {
+			/* revert to entry state on error */
+			sp_ptr->state = save_state;
+			goto bail;
+		}
+		dapl_ia_unlink_sp(ia_ptr, sp_ptr);
+		dapl_sp_dealloc(sp_ptr);
+	} else {
+		/*
+		 * The PSP is now in the pending state, where it will sit until
+		 * the last connection terminates or the app uses the same
+		 * ServiceID again, which will reactivate it.
+		 */
+		sp_ptr->state = DAPL_SP_STATE_PSP_PENDING;
+		spin_unlock_irqrestore(&sp_ptr->common.lock,
+				       sp_ptr->common.flags);
+		dapl_dbg_log(DAPL_DBG_TYPE_CM,
+			     ">>> dapl_psp_free: PSP PENDING\n");
+	}
+
+bail:
+	return status;
+}
+
+u32 dapl_psp_query(struct dat_sp *psp, struct dat_psp_param *psp_param)
+{
+	struct dapl_sp *sp_ptr;
+	u32 status;
+
+	if (!psp || ((struct dapl_sp *)psp)->listening != TRUE) {
+		status = DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_PSP);
+		goto bail;
+	}
+
+	if (NULL == psp_param) {
+		status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG3);
+		goto bail;
+	}
+
+	sp_ptr = (struct dapl_sp *)psp;
+
+	psp_param->ia = sp_ptr->ia;
+	psp_param->conn_qual = sp_ptr->conn_qual;
+	psp_param->evd = sp_ptr->evd;
+	psp_param->psp_flags = sp_ptr->psp_flags;
+
+	status = DAT_SUCCESS;
+
+bail:
+	return status;
+}
Index: linux-kernel/dat-provider/dapl_sp_util.h
===================================================================
--- linux-kernel/dat-provider/dapl_sp_util.h	(revision 2585)
+++ linux-kernel/dat-provider/dapl_sp_util.h	(working copy)
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2002-2005, Network Appliance, Inc. All rights reserved.
- *
- * This Software is licensed under one of the following licenses:
- *
- * 1) under the terms of the "Common Public License 1.0" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/cpl.php.
- *
- * 2) under the terms of the "The BSD License" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/bsd-license.php.
- *
- * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
- *    copy of which is available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/gpl-license.php.
- *
- * Licensee has the right to choose one of the above licenses.
- *
- * Redistributions of source code must retain the above copyright
- * notice and one of the license notices.
- *
- * Redistributions in binary form must reproduce both the above copyright
- * notice, one of the license notices in the documentation
- * and/or other materials provided with the distribution.
- */
-
-/*
- * $Id$
- */
-
-#ifndef DAPL_PSP_UTIL_H
-#define DAPL_PSP_UTIL_H
-
-struct dapl_sp *dapl_sp_alloc(struct dapl_ia *ia_ptr, boolean_t is_psp);
-
-void dapl_sp_dealloc(struct dapl_sp *sp_ptr);
-
-void dapl_sp_link_cr(struct dapl_sp *sp_ptr, struct dapl_cr *cr_ptr);
-
-struct dapl_cr *dapl_sp_search_cr(struct dapl_sp *sp_ptr,
-				  struct dapl_cm_id *ib_cm_handle);
-
-void dapl_sp_remove_cr(struct dapl_sp *sp_ptr, struct dapl_cr *cr_ptr);
-
-void dapl_sp_remove_ep(struct dapl_ep *ep_ptr);
-
-#endif /* DAPL_PSP_UTIL_H */
Index: linux-kernel/dat-provider/dapl_sp.h
===================================================================
--- linux-kernel/dat-provider/dapl_sp.h	(revision 2585)
+++ linux-kernel/dat-provider/dapl_sp.h	(working copy)
@@ -29,12 +29,8 @@
  * $Id$
  */
 
-#ifndef DAPL_PSP_UTIL_H
-#define DAPL_PSP_UTIL_H
-
-struct dapl_sp *dapl_sp_alloc(struct dapl_ia *ia_ptr, boolean_t is_psp);
-
-void dapl_sp_dealloc(struct dapl_sp *sp_ptr);
+#ifndef DAPL_SP_H
+#define DAPL_SP_H
 
 void dapl_sp_link_cr(struct dapl_sp *sp_ptr, struct dapl_cr *cr_ptr);
 
@@ -45,4 +41,4 @@ void dapl_sp_remove_cr(struct dapl_sp *s
 
 void dapl_sp_remove_ep(struct dapl_ep *ep_ptr);
 
-#endif /* DAPL_PSP_UTIL_H */
+#endif /* DAPL_SP_H */
Index: linux-kernel/patches/alt_dat_provider_makefile
===================================================================
--- linux-kernel/patches/alt_dat_provider_makefile	(revision 2585)
+++ linux-kernel/patches/alt_dat_provider_makefile	(working copy)
@@ -22,13 +22,10 @@ PROVIDER_MODULES := \
         dapl_lmr                 	\
         dapl_mr_util                  	\
         dapl_provider                 	\
-        dapl_sp_util                  	\
-        dapl_psp                	\
+        dapl_sp                  	\
         dapl_pz                  	\
         dapl_ring_buffer_util         	\
         dapl_rmr                        \
-        dapl_rsp                	\
-        dapl_sp_util                  	\
         dapl_srq                 	\
 	dapl_util
 




More information about the general mailing list