[openib-general] [PATCH][SDP] state transition simplification.

Libor Michalek libor at topspin.com
Tue Jun 7 13:36:16 PDT 2005


  This patch simplifies the state transitions for connection management
within SDP. Previously the connection state was maintained using two
variables 'istate' and 'state' with a combined total of 34 different
values. The patch merges the two into a single variable 'state' and 
removes redundancy for a total of 16 state values. Also the file
sdp_wall.c is removed who's original purpose was to keep the two state
variables synchronized.

  The simplification also paves the way for the next step, which is to
use the CM event for transitions instead of the current incorrest use
of CM state.

  The CQ event pending flags were moved from the connection flags field
to a new field in the event lock.

  Finally, I needed to ifdef out one of the send_dreq calls, because
I was seeing a problem when two DREQs would cross in flight and both
sides responded with a DREP.

  13 files changed, 404 insertions(+), 1045 deletions(-)

-Libor

Index: infiniband/ulp/sdp/sdp_rcvd.c
===================================================================
--- infiniband/ulp/sdp/sdp_rcvd.c	(revision 2564)
+++ infiniband/ulp/sdp/sdp_rcvd.c	(working copy)
@@ -37,54 +37,27 @@
 /*
  * Specific MID handler functions. (RECV)
  */
-
 static int sdp_rcvd_disconnect(struct sdp_opt *conn, struct sdpc_buff *buff)
 {
 	int result = 0;
+	int band;
 
 	sdp_dbg_ctrl(conn, "Disconnect msg received.");
 
 	switch (conn->state) {
 	case SDP_CONN_ST_ESTABLISHED:
-		/*
-		 * transition state
-		 */
 		SDP_CONN_ST_SET(conn, SDP_CONN_ST_DIS_RECV_1);
-		/*
-		 * initiate disconnect to framework
-		 */
-		result = sdp_wall_recv_close(conn);
-		if (result < 0) {
-			sdp_dbg_warn(conn, "Error <%d> closing connection",
-				     result);
-			goto error;
-		}
-
+		band = POLL_IN;
 		break;
-	case SDP_CONN_ST_DIS_PEND_1:
-		SDP_CONN_ST_SET(conn, SDP_CONN_ST_DIS_PEND_R);
-		break;
 	case SDP_CONN_ST_DIS_SEND_1:
 		SDP_CONN_ST_SET(conn, SDP_CONN_ST_DIS_RECV_R);
+		band = POLL_HUP;
 		break;
 	case SDP_CONN_ST_DIS_SENT_1:
-		/*
-		 * After receiving the final disconnet and posting the DREQ,
-		 * the next step is TIME_WAIT from the CM
-		 */
-		SDP_CONN_ST_SET(conn, SDP_CONN_ST_DIS_RECV_R);
 		SDP_CONN_ST_SET(conn, SDP_CONN_ST_TIME_WAIT_1);
+		band = POLL_HUP;
+#if 0 /* crossing DREQs appear not to work... */
 		/*
-		 * acknowledge disconnect to framework (we're in active
-		 * disconnect)
-		 */
-		result = sdp_wall_recv_closing(conn);
-		if (result < 0) {
-			sdp_dbg_warn(conn, "Error <%d> confirming conn close",
-				     result);
-			goto error;
-		}
-		/*
 		 * Begin IB/CM disconnect
 		 */
 		result = ib_send_cm_dreq(conn->cm_id, NULL, 0);
@@ -99,17 +72,28 @@
 			if (result != -EPROTO)
 				goto error;
 		}
-
+#endif
 		break;
 	default:
-		sdp_warn("Unexpected conn state. conn <%d> state <%04x:%04x>",
-			 conn->hashent, conn->istate, conn->state);
-
-		result = -EFAULT;
+		sdp_warn("Disconnect rcvd, unexpected state. <%d> <%04x>",
+			 conn->hashent, conn->state);
+		result = -EPROTO;
 		goto error;
 		break;
 	}
 
+	conn->shutdown |= RCV_SHUTDOWN;
+	/*
+	 * cancel all outstanding read AIO's since there will be
+	 * no more data from the peer.
+	 */
+	sdp_iocb_q_cancel_all_read(conn, 0);
+	/*
+	 * async notification. POLL_HUP on full duplex close only.
+	 */
+	sdp_inet_wake_generic(conn->sk);
+	sk_wake_async(conn->sk, 1, band);
+
 	return 0;
 error:
 	return result;
@@ -122,23 +106,17 @@
 	sdp_dbg_ctrl(conn, "Abort msg received.");
 	/*
 	 * Connection should be in some post DisConn recveived state.
-	 * Notify gateway interface about abort
 	 */
 	switch (conn->state) {
 	case SDP_CONN_ST_DIS_RECV_1:
-	case SDP_CONN_ST_DIS_PEND_R:
 	case SDP_CONN_ST_DIS_RECV_R:
-	case SDP_CONN_ST_DIS_PEND_2:
 	case SDP_CONN_ST_DIS_SEND_2:
-	case SDP_CONN_ST_DIS_SENT_2:
-		result = sdp_wall_abort(conn);
-		if (result < 0)
-			sdp_dbg_warn(conn, "Error <%d> during abort", result);
 
+		sdp_conn_abort(conn);
 		break;
 	default:
-		sdp_warn("Unexpected abort. conn <%d> state <%04x:%04x>",
-			 conn->hashent, conn->istate, conn->state);
+		sdp_warn("Unexpected abort. conn <%d> state <%04x>",
+			 conn->hashent, conn->state);
 		result = -EPROTO;
 	}
 
@@ -856,8 +834,7 @@
 		/*
 		 * abort connection (send reset)
 		 */
-		result = sdp_wall_abort(conn);
-		SDP_EXPECT(result >= 0);
+		sdp_conn_abort(conn);
 		/*
 		 * drop packet
 		 */
Index: infiniband/ulp/sdp/sdp_inet.c
===================================================================
--- infiniband/ulp/sdp/sdp_inet.c	(revision 2564)
+++ infiniband/ulp/sdp/sdp_inet.c	(working copy)
@@ -209,112 +209,78 @@
 }
 
 /*
- * internal socket/handle managment functions
- */
-
-/*
- * sdp_inet_abort - abort an existing connection
- */
-static int sdp_inet_abort(struct sdp_opt *conn)
-{
-	int result;
-
-	conn->send_buf = 0;
-
-	switch (conn->istate) {
-	case SDP_SOCK_ST_CONNECT:
-	case SDP_SOCK_ST_ACCEPTING:
-	case SDP_SOCK_ST_ACCEPTED:
-		sdp_dbg_warn(conn, "Unexpected abort");
-
-	case SDP_SOCK_ST_ESTABLISHED:
-	case SDP_SOCK_ST_CLOSE:
-	case SDP_SOCK_ST_DISCONNECT:
-	case SDP_SOCK_ST_CLOSING:
-		result = sdp_wall_abort(conn);
-		if (result < 0) {
-
-			result = -ECONNABORTED;
-			SDP_CONN_SET_ERR(conn, ECONNABORTED);
-			conn->istate = SDP_SOCK_ST_ERROR;
-		}
-
-		break;
-	case SDP_SOCK_ST_LISTEN:
-	case SDP_SOCK_ST_CLOSED:
-	case SDP_SOCK_ST_ERROR:
-		sdp_dbg_warn(conn, "Unhandled abort");
-
-		conn->istate = SDP_SOCK_ST_ERROR;
-		result = -EINVAL;
-		break;
-	default:
-		sdp_dbg_warn(conn, "Unknown abort state");
-
-		conn->istate = SDP_SOCK_ST_ERROR;
-		result = -EINVAL;
-		break;
-	}
-
-	return result;
-}
-
-/*
  * sdp_inet_disconnect - disconnect a connection
  */
 static int sdp_inet_disconnect(struct sdp_opt *conn)
 {
 	int result = 0;
+	/*
+	 * close buffered data transmission space
+	 */
+	conn->send_buf = 0;
+	/*
+	 * Generate a Disconnect message, and mark self as disconnecting.
+	 */
+	switch (conn->state) {
+	case SDP_CONN_ST_REQ_PATH:
+	case SDP_CONN_ST_REQ_SENT:
+		/*
+		 * outstanding request. Mark it in error, and
+		 * completions needs to complete the closing.
+		 */
+		SDP_CONN_ST_SET(conn, SDP_CONN_ST_ERROR);
+		SDP_CONN_SET_ERR(conn, ECONNRESET);
+		break;
+	case SDP_CONN_ST_REQ_RECV:
+        case SDP_CONN_ST_REP_RECV:
+	case SDP_CONN_ST_ESTABLISHED:
+		/*
+		 * Attempt to send a disconnect message
+		 */
+		SDP_CONN_ST_SET(conn, SDP_CONN_ST_DIS_SEND_1);
 
-	switch (conn->istate) {
-	case SDP_SOCK_ST_CONNECT:
-		result = sdp_wall_abort(conn);
+		result = sdp_send_ctrl_disconnect(conn);
 		if (result < 0) {
-			result = -ECONNABORTED;
-			SDP_CONN_SET_ERR(conn, ECONNABORTED);
-			conn->istate = SDP_SOCK_ST_ERROR;
+			sdp_dbg_warn(conn, 
+				     "Error <%d> send disconnect request",
+				     result);
+			goto error;
 		}
-		break;
-	case SDP_SOCK_ST_ESTABLISHED:
-	case SDP_SOCK_ST_ACCEPTED:
-		conn->istate = SDP_SOCK_ST_DISCONNECT;
-		result = sdp_wall_send_close(conn);
-		if (result < 0) {
-			result = -ECONNABORTED;
-			SDP_CONN_SET_ERR(conn, ECONNABORTED);
-			conn->istate = SDP_SOCK_ST_ERROR;
-		}
-		break;
-	case SDP_SOCK_ST_CLOSE:
-		conn->istate = SDP_SOCK_ST_CLOSING;
-		result = sdp_wall_send_closing(conn);
-		if (result < 0) {
-			result = -ECONNABORTED;
-			SDP_CONN_SET_ERR(conn, ECONNABORTED);
-			conn->istate = SDP_SOCK_ST_ERROR;
-		}
 
 		break;
-	case SDP_SOCK_ST_ACCEPTING:
-	case SDP_SOCK_ST_DISCONNECT:
-	case SDP_SOCK_ST_CLOSING:
+	case SDP_CONN_ST_DIS_RECV_1:
 		/*
-		 * nothing to do, and somewhat unexpected state
+		 * Change state, and send a disconnect request
 		 */
-		sdp_dbg_warn(conn, "Unexpected disconnect");
+		SDP_CONN_ST_SET(conn, SDP_CONN_ST_DIS_SEND_2);
 
+		result = sdp_send_ctrl_disconnect(conn);
+		if (result < 0) {
+			sdp_dbg_warn(conn,
+				     "Error <%d> send disconnect request",
+				     result);
+			goto error;
+		}
 		break;
-	case SDP_SOCK_ST_LISTEN:
-	case SDP_SOCK_ST_CLOSED:
-	case SDP_SOCK_ST_ERROR:
+	case SDP_CONN_ST_TIME_WAIT_1:
+	case SDP_CONN_ST_TIME_WAIT_2:
+	case SDP_CONN_ST_ERROR:
+	case SDP_CONN_ST_CLOSED:
 		break;
 	default:
-		sdp_dbg_warn(conn, "Unknown disconnect state");
-		conn->istate = SDP_SOCK_ST_ERROR;
-		result = -EINVAL;
-		break;
+		sdp_dbg_warn(conn, "Incorrect state for disconnect");
+		result = -EBADE;
+		goto error;
 	}
 
+	return 0;
+error:
+	/*
+	 * abortive close.
+	 */
+	sdp_conn_inet_error(conn, ECONNRESET);
+	(void)ib_send_cm_dreq(conn->cm_id, NULL, 0);
+
 	return result;
 }
 
@@ -353,7 +319,7 @@
 	sdp_conn_lock(conn);
 	conn->shutdown = SHUTDOWN_MASK;
 
-	if (conn->istate == SDP_SOCK_ST_LISTEN) {
+	if (conn->state == SDP_CONN_ST_LISTEN) {
 		/*
 		 * stop listening
 		 */
@@ -384,22 +350,16 @@
 		/*
 		 * abort.
 		 */
-		result = sdp_inet_abort(conn);
-		if (result < 0)
-			sdp_dbg_warn(conn, "Error <%d> while aborting socket",
-				     result);
-
+		sdp_conn_abort(conn);
 		goto done;
 	}
 	/*
-	 * disconnect. (state dependant)
+	 * disconnect. (state dependant) On error skip linger, since
+	 * the socket is already out of the normal path.
 	 */
 	result = sdp_inet_disconnect(conn);
-	if (result < 0) {
-		sdp_dbg_warn(conn, "Error <%d> while disconnecting socket",
-			     result);
+	if (result < 0)
 		goto done;
-	}
 	/*
 	 * Skip lingering/canceling if 
 	 * non-blocking and not exiting.
@@ -419,7 +379,7 @@
 			set_current_state(TASK_INTERRUPTIBLE);
 
 			while (timeout > 0 &&
-			       !(SDP_ST_MASK_CLOSED & conn->istate)) {
+			       !(SDP_ST_MASK_CLOSED & conn->state)) {
 				sdp_conn_unlock(conn);
 				timeout = schedule_timeout(timeout);
 				sdp_conn_lock(conn);
@@ -437,7 +397,7 @@
 		 * Cancel write and close again to force closing the
 		 * connection.
 		 */
-		if (SDP_ST_MASK_DRAIN & conn->istate) {
+		if (SDP_ST_MASK_DRAIN & conn->state) {
 
 			sdp_iocb_q_cancel_all_write(conn, -ECANCELED);
 
@@ -448,9 +408,6 @@
 	}
 
 done:
-	if (SDP_ST_MASK_CLOSED & conn->istate)
-		do {} while(0); /* pass */
-		
 	/*
 	 * finally drop socket reference. (socket API reference)
 	 */
@@ -513,7 +470,7 @@
 	 */
 	sdp_conn_lock(conn);
 
-	if (conn->istate != SDP_SOCK_ST_CLOSED || conn->src_port > 0) {
+	if (conn->state != SDP_CONN_ST_CLOSED || conn->src_port > 0) {
 		result = -EINVAL;
 		goto done;
 	}
@@ -590,7 +547,7 @@
 
 	switch (sock->state) {
 	case SS_UNCONNECTED:
-		if (!(SDP_ST_MASK_CLOSED & conn->istate)) {
+		if (conn->state != SDP_CONN_ST_CLOSED) {
 			result = -EISCONN;
 			goto done;
 		}
@@ -610,7 +567,6 @@
 		SDP_CONN_SET_ERR(conn, 0);
 
 		sock->state = SS_CONNECTING;
-		conn->istate = SDP_SOCK_ST_CONNECT;
 
 		conn->dst_addr = ntohl(addr->sin_addr.s_addr);
 		conn->dst_port = ntohs(addr->sin_port);
@@ -630,7 +586,7 @@
 			conn->dst_port = 0;
 
 			sock->state = SS_UNCONNECTED;
-			conn->istate = SDP_SOCK_ST_CLOSED;
+			conn->state = SDP_CONN_ST_CLOSED;
 
 			goto done;
 		}
@@ -660,7 +616,7 @@
 		add_wait_queue(sk->sk_sleep, &wait);
 		set_current_state(TASK_INTERRUPTIBLE);
 
-		while (timeout > 0 && conn->istate == SDP_SOCK_ST_CONNECT) {
+		while (timeout > 0 && (conn->state & SDP_ST_MASK_CONNECT)) {
 
 			sdp_conn_unlock(conn);
 			timeout = schedule_timeout(timeout);
@@ -675,7 +631,7 @@
 		set_current_state(TASK_RUNNING);
 		remove_wait_queue(sk->sk_sleep, &wait);
 
-		if (conn->istate == SDP_SOCK_ST_CONNECT) {
+		if (conn->state & SDP_ST_MASK_CONNECT) {
 
 			if (timeout > 0) {
 
@@ -691,16 +647,18 @@
 	 * point. In this case connect should return normally and allow
 	 * the normal mechnaism for detecting these states.
 	 */
-	switch (conn->istate) {
-	case SDP_SOCK_ST_CONNECT:
+	switch (conn->state) {
+	case SDP_CONN_ST_REQ_PATH:
+	case SDP_CONN_ST_REQ_SENT:
+	case SDP_CONN_ST_REP_RECV:
 		break;
-	case SDP_SOCK_ST_ESTABLISHED:
-	case SDP_SOCK_ST_CLOSE:
+	case SDP_CONN_ST_ESTABLISHED:
+	case SDP_CONN_ST_DIS_RECV_1:
 		sock->state = SS_CONNECTED;
 		result = 0;
 		break;
-	case SDP_SOCK_ST_CLOSED:
-	case SDP_SOCK_ST_ERROR:
+	case SDP_CONN_ST_CLOSED:
+	case SDP_CONN_ST_ERROR:
 		result = sdp_conn_error(conn) ? : -ECONNABORTED;
 		sock->state = SS_UNCONNECTED;
 		break;
@@ -711,7 +669,6 @@
 	}
 
 	sdp_dbg_ctrl(conn, "CONNECT complete");
-
 done:
 	sdp_conn_unlock(conn);
 	return result;
@@ -735,13 +692,13 @@
 	sdp_conn_lock(conn);
 
 	if (SS_UNCONNECTED != sock->state ||
-	    (conn->istate != SDP_SOCK_ST_CLOSED &&
-	     conn->istate != SDP_SOCK_ST_LISTEN)) {
+	    (conn->state != SDP_CONN_ST_CLOSED &&
+	     conn->state != SDP_CONN_ST_LISTEN)) {
 		result = -EINVAL;
 		goto done;
 	}
 
-	if (conn->istate != SDP_SOCK_ST_LISTEN) {
+	if (conn->state != SDP_CONN_ST_LISTEN) {
 		result = sdp_inet_listen_start(conn);
 		if (result < 0) {
 			sdp_dbg_warn(conn, "Error <%d> starting listen",
@@ -795,7 +752,7 @@
 
 	sdp_conn_lock(listen_conn);
 
-	if (listen_conn->istate != SDP_SOCK_ST_LISTEN) {
+	if (listen_conn->state != SDP_CONN_ST_LISTEN) {
 		result = -EINVAL;
 		goto listen_done;
 	}
@@ -816,7 +773,7 @@
 			set_current_state(TASK_INTERRUPTIBLE);
 
 			while (timeout > 0 &&
-			       listen_conn->istate == SDP_SOCK_ST_LISTEN &&
+			       listen_conn->state == SDP_CONN_ST_LISTEN &&
 			       !listen_conn->backlog_cnt) {
 				sdp_conn_unlock(listen_conn);
 				timeout = schedule_timeout(timeout);
@@ -834,7 +791,7 @@
 			if (!listen_conn->backlog_cnt) {
 				result = 0;
 
-				if (listen_conn->istate != SDP_SOCK_ST_LISTEN)
+				if (listen_conn->state != SDP_CONN_ST_LISTEN)
 					result = -EINVAL;
 				if (signal_pending(current))
 					result = sock_intr_errno(timeout);
@@ -846,47 +803,19 @@
 		} else {
 			accept_sk = accept_conn->sk;
 
-			switch (accept_conn->istate) {
-			case SDP_SOCK_ST_ACCEPTED:
+			switch (accept_conn->state) {
+			case SDP_CONN_ST_REQ_RECV:
+			case SDP_CONN_ST_ESTABLISHED:
+			case SDP_CONN_ST_DIS_RECV_1:
 				sock_graft(accept_sk, accept_sock);
 
 				accept_conn->pid = current->pid;
 				accept_sock->state = SS_CONNECTED;
 
-				accept_conn->istate =
-				    SDP_SOCK_ST_ESTABLISHED;
 				sdp_inet_wake_send(accept_sk);
 
 				break;
-			case SDP_SOCK_ST_ACCEPTING:
-				sock_graft(accept_sk, accept_sock);
-
-				accept_conn->pid = current->pid;
-				accept_sock->state = SS_CONNECTED;
-
-				accept_conn->istate = SDP_SOCK_ST_ACCEPTED;
-				/*
-				 * connection completion/establishment will
-				 * open this up
-				 */
-				set_bit(SOCK_NOSPACE, &accept_sock->flags);
-
-				break;
-			case SDP_SOCK_ST_CLOSE:
-				sock_graft(accept_sk, accept_sock);
-
-				accept_conn->pid = current->pid;
-				accept_sock->state = SS_CONNECTED;
-
-				sdp_inet_wake_send(accept_sk);
-
-				break;
 			default:
-				sdp_dbg_warn(accept_conn, "bad accept state");
-
-			case SDP_SOCK_ST_CLOSED:
-			case SDP_SOCK_ST_CLOSING:
-			case SDP_SOCK_ST_ERROR:
 				/*
 				 * this accept socket has problems, keep
 				 * trying.
@@ -950,7 +879,7 @@
 	addr->sin_family = proto_family;
 	if (peer > 0)
 		if (htons(conn->dst_port) > 0 &&
-		    !(SDP_ST_MASK_CLOSED & conn->istate)) {
+		    !(SDP_ST_MASK_CLOSED & conn->state)) {
 
 			addr->sin_port = htons(conn->dst_port);
 			addr->sin_addr.s_addr = htonl(conn->dst_addr);
@@ -996,17 +925,17 @@
 	/*
 	 * no locking, should be safe as is.
 	 */
-	switch (conn->istate) {
-	case SDP_SOCK_ST_LISTEN:
+	switch (conn->state) {
+	case SDP_CONN_ST_LISTEN:
 		mask |= (conn->backlog_cnt > 0) ? (POLLIN | POLLRDNORM) : 0;
 		break;
-	case SDP_SOCK_ST_ERROR:
+	case SDP_CONN_ST_ERROR:
 		mask |= POLLERR;
 		break;
-	case SDP_SOCK_ST_CLOSED:
+	case SDP_CONN_ST_CLOSED:
 		mask |= POLLHUP;
 		break;
-	case SDP_SOCK_ST_ESTABLISHED:
+	case SDP_CONN_ST_ESTABLISHED:
 		/*
 		 * fall through
 		 */
@@ -1131,7 +1060,7 @@
 	case SIOCINQ:
 		sdp_conn_lock(conn);
 
-		if (conn->istate != SDP_SOCK_ST_LISTEN) {
+		if (conn->state != SDP_CONN_ST_LISTEN) {
 			/*
 			 * TODO need to subtract/add URG (inline vs. OOB)
 			 */
@@ -1145,7 +1074,7 @@
 	case SIOCOUTQ:
 		sdp_conn_lock(conn);
 
-		if (conn->istate != SDP_SOCK_ST_LISTEN) {
+		if (conn->state != SDP_CONN_ST_LISTEN) {
 			value = conn->send_qud;
 			result = put_user(value, (int __user *) arg);
 		} else
@@ -1332,15 +1261,18 @@
 
 	conn->shutdown |= flag;
 
-	switch (conn->istate) {
-	case SDP_SOCK_ST_CLOSED:
-		result = -ENOTCONN;
-		break;
-	case SDP_SOCK_ST_LISTEN:
+	switch (conn->state) {
+	case SDP_CONN_ST_REQ_PATH:
+	case SDP_CONN_ST_REQ_SENT:
 		/*
-		 * Send shutdown is benign.
+		 * outstanding request. Mark it in error, and
+		 * completions needs to complete the closing.
 		 */
-		if (RCV_SHUTDOWN & flag) {
+		SDP_CONN_ST_SET(conn, SDP_CONN_ST_ERROR);
+		SDP_CONN_SET_ERR(conn, ECONNRESET);
+		break;
+	case SDP_CONN_ST_LISTEN:
+		if (flag & RCV_SHUTDOWN) {
 			result = sdp_inet_listen_stop(conn);
 			if (result < 0)
 				sdp_dbg_warn(conn, "listen stop error <%d>",
@@ -1348,52 +1280,22 @@
 		}
 
 		break;
-	case SDP_SOCK_ST_ERROR:
-		result = sdp_conn_error(conn);
-		result = (result < 0) ? result : -ECONNABORTED;
+	case SDP_CONN_ST_CLOSED:
+	case SDP_CONN_ST_ERROR:
+		result = -ENOTCONN;
 		break;
-	case SDP_SOCK_ST_ACCEPTED:
-	case SDP_SOCK_ST_CONNECT:
-		result = sdp_inet_abort(conn);
-		if (result < 0)
-			sdp_dbg_warn(conn, "Error <%d> aborting connection",
-				     result);
-		break;
-	case SDP_SOCK_ST_ESTABLISHED:
-	case SDP_SOCK_ST_CLOSE:
-		result = sdp_inet_disconnect(conn);
-		if (result < 0)
-			sdp_dbg_warn(conn, "Error <%d> disconnecting conn",
-				     result);
-		break;
-	case SDP_SOCK_ST_DISCONNECT:
-	case SDP_SOCK_ST_CLOSING:
-		/*
-		 * nothing.
-		 */
-		break;
-	case SDP_SOCK_ST_ACCEPTING:
-		sdp_dbg_warn(conn, "connection state error");
-
-		conn->istate = SDP_SOCK_ST_ERROR;
-		SDP_CONN_SET_ERR(conn, EPROTO);
-		result = -EFAULT;
-
-		break;
 	default:
-		sdp_warn("Unknown socket state. conn <%d> state <%04x:%04x>",
-			 conn->hashent, conn->istate, conn->state);
+		if (!(flag & RCV_SHUTDOWN)) {
+			result = sdp_inet_disconnect(conn);
+			if (result < 0)
+				sdp_dbg_warn(conn, "disconnect error <%d>",
+					     result);
+		}
 
-		conn->istate = SDP_SOCK_ST_ERROR;
-		SDP_CONN_SET_ERR(conn, EPROTO);
-		result = -EFAULT;
+		break;
 	}
 
-	if (result < 0)
-		sdp_inet_wake_generic(sock->sk);
-	else
-		sdp_inet_wake_error(sock->sk);
-
+	sdp_inet_wake_generic(sock->sk);
 	sdp_conn_unlock(conn);
 	return result;
 }
Index: infiniband/ulp/sdp/sdp_proto.h
===================================================================
--- infiniband/ulp/sdp/sdp_proto.h	(revision 2564)
+++ infiniband/ulp/sdp/sdp_proto.h	(working copy)
@@ -114,22 +114,10 @@
 /*
  * Wall between userspace protocol and SDP protocol proper
  */
-int sdp_wall_send_close(struct sdp_opt *conn);
+void sdp_conn_abort(struct sdp_opt *conn);
 
-int sdp_wall_send_closing(struct sdp_opt *conn);
+void sdp_conn_inet_error(struct sdp_opt *conn, int error);
 
-int sdp_wall_send_abort(struct sdp_opt *conn);
-
-int sdp_wall_recv_close(struct sdp_opt *conn);
-
-int sdp_wall_recv_closing(struct sdp_opt *conn);
-
-int sdp_wall_recv_abort(struct sdp_opt *conn);
-
-void sdp_wall_recv_drop(struct sdp_opt *conn);
-
-int sdp_wall_abort(struct sdp_opt *conn);
-
 int sdp_recv_buff(struct sdp_opt *conn, struct sdpc_buff *buff);
 
 /*
@@ -332,8 +320,6 @@
 /*
  * passive connect functions
  */
-void sdp_cm_pass_error(struct sdp_opt *conn, int error);
-
 int sdp_cm_pass_establish(struct sdp_opt *conn);
 
 int sdp_cm_req_handler(struct ib_cm_id *cm_id,
@@ -481,9 +467,9 @@
                 struct sdp_opt *x = (conn); \
                 if (x) { \
                         sdp_dbg_out(level, type, \
-                                      "<%d> <%04x:%04x> " format, \
-                                       x->hashent, x->istate, x->state , \
-                                       ## arg);                  \
+                                      "<%d> <%04x> " format,  \
+                                       x->hashent, x->state , \
+                                       ## arg);               \
                 } \
                 else {  \
                         sdp_dbg_out(level, type, format, ## arg); \
@@ -555,19 +541,18 @@
 static inline int sdp_inet_write_space(struct sdp_opt *conn, int urg)
 {
 	int size;
-
 	/*
-	 * Allow for more space if Urgent data is being considered
+	 * Allow for more space if Urgent data is being considered.
+	 * send_buf may be zero if we are holding data back, state
+	 * transition will open it.
 	 */
 	size = (conn->send_buf - conn->send_qud);
 	/*
 	 * write space is determined by amount of outstanding bytes of data
 	 * and number of buffers used for transmission by this connection
 	 */
-	if ((SDP_ST_MASK_OPEN & conn->istate) &&
-	    (conn->send_max >
-	     sdp_desc_q_types_size(&conn->send_queue,
-				   SDP_DESC_TYPE_BUFF)))
+	if (conn->send_max > sdp_desc_q_types_size(&conn->send_queue,
+						   SDP_DESC_TYPE_BUFF))
 		return ((SDP_INET_SEND_MARK < size || 1 < urg) ? size : 0);
 	else
 		return 0;
@@ -578,7 +563,7 @@
  */
 static inline int sdp_inet_writable(struct sdp_opt *conn)
 {
-	if (SDP_ST_MASK_OPEN & conn->istate)
+	if (conn->send_buf > 0)
 		return (sdp_inet_write_space(conn, 0) <
 			(conn->send_qud / 2)) ? 0 : 1;
 	else
Index: infiniband/ulp/sdp/Makefile
===================================================================
--- infiniband/ulp/sdp/Makefile	(revision 2564)
+++ infiniband/ulp/sdp/Makefile	(working copy)
@@ -12,7 +12,6 @@
 	sdp_sent.o \
 	sdp_read.o \
 	sdp_write.o \
-	sdp_wall.o \
 	sdp_proc.o \
 	sdp_inet.o \
 	sdp_iocb.o \
Index: infiniband/ulp/sdp/sdp_send.c
===================================================================
--- infiniband/ulp/sdp/sdp_send.c	(revision 2564)
+++ infiniband/ulp/sdp/sdp_send.c	(working copy)
@@ -1247,8 +1247,7 @@
 	buff = sdp_buff_pool_get();
 	if (!buff) {
 		sdp_dbg_warn(conn, "Failed to allocate buffer for control");
-		result = -ENOMEM;
-		goto error;
+		return -ENOMEM;
 	}
 	/*
 	 * setup header.
@@ -1282,7 +1281,6 @@
 		(void)sdp_buff_pool_put(buff);
 	}
 
-error:
 	return result;
 }
 
@@ -1301,8 +1299,7 @@
 	buff = sdp_buff_pool_get();
 	if (!buff) {
 		sdp_dbg_warn(conn, "Failed to allocate buffer for disconnect");
-		result = -ENOMEM;
-		goto error;
+		return -ENOMEM;
 	}
 	/*
 	 * setup header.
@@ -1316,20 +1313,18 @@
 	SDP_BUFF_F_CLR_SE(buff);
 	SDP_BUFF_F_CLR_UNSIG(buff);
 	/*
-	 * change state to reflect disconnect is queued.
-	 * DIS_PEND_X to DIS_SEND_X
-	 */
-	SDP_ST_PEND_2_SEND(conn);
-	/*
 	 * send
 	 */
 	result = sdp_send_ctrl_buff_buffered(conn, buff);
 	if (result < 0) {
 		sdp_dbg_warn(conn, "Error <%d> posting control message",
 			     result);
+		(void)sdp_buff_pool_put(buff);
 		goto error;
 	}
-	
+
+	conn->flags &= ~SDP_CONN_F_DIS_PEND;
+
 	return 0;
 error:
 	return result;
@@ -1340,8 +1335,7 @@
  */
 int sdp_send_ctrl_disconnect(struct sdp_opt *conn)
 {
-	int result;
-
+	int result = 0;
 	/*
 	 * Only create/post the message if there is no data in the data queue,
 	 * otherwise ignore the call. The flush queue will see to it, that a
@@ -1349,20 +1343,13 @@
 	 * clean. The state is now in a disconnect send, the message will be
 	 * sent once data is flushed.
 	 */
-	if (SDP_ST_MASK_DIS_PEND & conn->state) {
-		if (!(conn->flags & SDP_CONN_F_DIS_HOLD) &&
-		    !sdp_desc_q_size(&conn->send_queue) &&
-		    !conn->src_sent)
-			result = do_send_ctrl_disconnect(conn);
-		else {
-			sdp_dbg_ctrl(conn, "defer disconnect <%d:%d> <%08x>",
-				     sdp_desc_q_size(&conn->send_queue),
-				     conn->src_sent, conn->flags);
+	if ((conn->flags & SDP_CONN_F_DIS_HOLD) ||
+	    sdp_desc_q_size(&conn->send_queue) ||
+	    conn->src_sent) 
+		conn->flags |= SDP_CONN_F_DIS_PEND;
+	else
+		result = do_send_ctrl_disconnect(conn);
 
-			result = 0;
-		}
-	} else
-		result = -EPROTO;
 	return result;
 }
 
@@ -1995,8 +1982,8 @@
 	/*
 	 * disconnect flush
 	 */
-	if (SDP_ST_MASK_DIS_PEND & conn->state) {
-		result = do_send_ctrl_disconnect(conn);
+	if (conn->flags & SDP_CONN_F_DIS_PEND) {
+		result = sdp_send_ctrl_disconnect(conn);
 		if (result < 0) {
 			sdp_dbg_warn(conn, "Error <%d> flushing disconnect",
 				     result);
@@ -2049,8 +2036,9 @@
 	 * continue being processed, it'll wait below until the send window
 	 * is opened on sucessful connect, or error on an unsucessful attempt.
 	 */
-	if (SDP_ST_MASK_CLOSED & conn->istate) {
-		result = -EPIPE;
+	if (conn->state == SDP_CONN_ST_LISTEN ||
+	    conn->state == SDP_CONN_ST_CLOSED) {
+		result = -ENOTCONN;
 		goto done;
 	}
 	/*
@@ -2139,7 +2127,7 @@
 			break;
 		}
 
-		if (conn->istate == SDP_SOCK_ST_ERROR) {
+		if (conn->state == SDP_CONN_ST_ERROR) {
 			result = -EPROTO; /* error should always be set, but
 					     just in case */
 			break;
Index: infiniband/ulp/sdp/sdp_conn.c
===================================================================
--- infiniband/ulp/sdp/sdp_conn.c	(revision 2564)
+++ infiniband/ulp/sdp/sdp_conn.c	(working copy)
@@ -73,6 +73,101 @@
         return psn;
 }
 
+void sdp_conn_inet_error(struct sdp_opt *conn, int error)
+{
+	sdp_dbg_ctrl(conn, "report connection error <%d>", error);
+	/*
+	 * the connection has failed, move to error, and notify anyone
+	 * waiting of the state change. remove connection from listen
+	 * queue if possible.
+	 */
+	(void)sdp_inet_accept_q_remove(conn);
+
+	SDP_CONN_ST_SET(conn, SDP_CONN_ST_ERROR);
+	SDP_CONN_SET_ERR(conn, error);
+	conn->shutdown = SHUTDOWN_MASK;
+	conn->send_buf = 0;
+
+	if (conn->sk->sk_socket)
+		conn->sk->sk_socket->state = SS_UNCONNECTED;
+
+	sdp_iocb_q_cancel_all(conn, -error);
+	sdp_inet_wake_error(conn->sk);
+}
+
+void sdp_conn_abort(struct sdp_opt *conn)
+{
+	int result;
+	int error = ECONNRESET;
+
+	sdp_dbg_ctrl(conn, "Abort send. src <%08x:%04x> dst <%08x:%04x>",
+		     conn->src_addr, conn->src_port, 
+		     conn->dst_addr, conn->dst_port);
+
+	switch (conn->state) {
+	case SDP_CONN_ST_DIS_SENT_1:	/* IBTA v1.1 spec A4.5.3.2 */
+		/*
+		 * clear the pending control buffer.
+		 */
+		sdp_desc_q_clear(&conn->send_ctrl);
+		/*
+		 * fall through
+		 */
+	case SDP_CONN_ST_DIS_SEND_2:
+	case SDP_CONN_ST_DIS_SEND_1:
+		/*
+		 * don't touch control queue, diconnect message may 
+		 * still be queued.
+		 */
+		sdp_desc_q_clear(&conn->send_queue);
+		/*
+		 * post abort
+		 */
+		if (conn->flags & SDP_CONN_F_DIS_PEND)
+			result = -ECONNRESET;
+		else
+			result = sdp_send_ctrl_abort(conn);
+
+		if (!result)
+			break;
+
+		conn->flags &= ~SDP_CONN_F_DIS_PEND;
+	case SDP_CONN_ST_DIS_RECV_1:
+		error = EPIPE;
+	case SDP_CONN_ST_ESTABLISHED:
+		/*
+		 * abortive close.
+		 */
+		result = ib_send_cm_dreq(conn->cm_id, NULL, 0);
+		if (result)
+			sdp_dbg_warn(conn, "Error <%d> CM disconnect send",
+				     result);
+		break;
+	case SDP_CONN_ST_REQ_PATH:
+	case SDP_CONN_ST_REQ_SENT:
+	case SDP_CONN_ST_REQ_RECV:
+		/*
+		 * outstanding CM request. Mark it in error, and CM
+		 * completion needs to complete the closing.
+		 */
+		error = ECONNREFUSED;
+		break;
+	case SDP_CONN_ST_ERROR:
+	case SDP_CONN_ST_CLOSED:
+	case SDP_CONN_ST_TIME_WAIT_1:
+	case SDP_CONN_ST_TIME_WAIT_2:
+		break;
+	default:
+		/*
+		 * post abort
+		 */
+		sdp_dbg_warn(conn, "Unexpected connection state for abort");
+		break;
+	}
+
+	sdp_conn_inet_error(conn, error);
+	return;
+}
 /*
  * sdp_inet_accept_q_put - put a conn into a listen conn's accept Q.
  */
@@ -175,6 +270,8 @@
 	accept_conn->accept_prev = NULL;
 	accept_conn->parent = NULL;
 
+	sdp_conn_put(accept_conn); /* AcceptQueue INET reference */
+
 	return 0;
 }
 
@@ -185,12 +282,12 @@
 {
 	unsigned long flags;
 
-	if (conn->istate != SDP_SOCK_ST_CLOSED) {
+	if (conn->state != SDP_CONN_ST_CLOSED) {
 		sdp_dbg_warn(conn, "Incorrect connection state to listen.");
 		return -EBADFD;
 	}
 
-	conn->istate = SDP_SOCK_ST_LISTEN;
+	conn->state  = SDP_CONN_ST_LISTEN;
 	conn->accept_next = conn;
 	conn->accept_prev = conn;
 	/*
@@ -217,15 +314,14 @@
 int sdp_inet_listen_stop(struct sdp_opt *listen_conn)
 {
 	struct sdp_opt *accept_conn;
-	int result;
 	unsigned long flags;
 
-	if (listen_conn->istate != SDP_SOCK_ST_LISTEN) {
+	if (listen_conn->state != SDP_CONN_ST_LISTEN) {
 		sdp_dbg_warn(listen_conn, "Incorrect state to stop listen.");
 		return -EBADFD;
 	}
 
-	listen_conn->istate = SDP_SOCK_ST_CLOSED;
+	listen_conn->state  = SDP_CONN_ST_CLOSED;
 	/*
 	 * table lock
 	 */
@@ -252,13 +348,7 @@
 		 * Remember to unlock since the Get function will acquire
 		 * the lock.
 		 */
-		accept_conn->istate = SDP_SOCK_ST_CLOSED;
-
-		result = sdp_wall_send_abort(accept_conn);
-		if (result < 0)
-			sdp_dbg_warn(accept_conn, "Error <%d> during abort",
-				     result);
-
+		sdp_conn_abort(accept_conn);
 		/* AcceptQueueGet */
 		sdp_conn_unlock(accept_conn);
 		/* INET reference (AcceptQueuePut). */
@@ -341,7 +431,7 @@
 				 */
 				if (!sk->sk_reuse ||
 				    !srch->sk_reuse ||
-				    look->istate == SDP_SOCK_ST_LISTEN) {
+				    look->state == SDP_CONN_ST_LISTEN) {
 					/*
 					 * 5) neither socket is using a
 					 *    specific address
@@ -848,7 +938,7 @@
 			break;  /* exit CQ handler routine */
 	}
 
-	conn->flags &= ~SDP_CONN_F_MASK_EVENT;
+	conn->lock.event = 0;
 
 	spin_unlock_irqrestore(&conn->lock.slock, flags);
 }
@@ -902,7 +992,7 @@
 				     result);
 	}
 
-return calls;
+	return calls;
 }
 
 /*
@@ -914,15 +1004,13 @@
 	/*
 	 * poll CQs for events.
 	 */
-	if (conn) {
-		if (conn->flags & SDP_CONN_F_RECV_CQ_PEND)
-			calls += sdp_conn_cq_drain(conn->recv_cq, conn);
+	if (conn->lock.event & SDP_LOCK_F_RECV_CQ)
+		calls += sdp_conn_cq_drain(conn->recv_cq, conn);
 
-		if (conn->flags & SDP_CONN_F_SEND_CQ_PEND)
-			calls += sdp_conn_cq_drain(conn->send_cq, conn);
+	if (conn->lock.event & SDP_LOCK_F_SEND_CQ)
+		calls += sdp_conn_cq_drain(conn->send_cq, conn);
 
-		conn->flags &= ~SDP_CONN_F_MASK_EVENT;
-	}
+	conn->lock.event = 0;
 }
 
 /*
@@ -932,6 +1020,7 @@
 {
 	spin_lock_init(&(conn->lock.slock));
 	conn->lock.users = 0;
+	conn->lock.event = 0;
 	init_waitqueue_head(&(conn->lock.waitq));
 }
 
@@ -1176,7 +1265,6 @@
 	conn->pid       = 0;
 	conn->sk        = sk;
 	conn->hashent   = SDP_DEV_SK_INVALID;
-	conn->istate    = SDP_SOCK_ST_CLOSED;
 	conn->flags     = 0;
 	conn->shutdown  = 0;
 	conn->recv_mode = SDP_MODE_COMB;
@@ -1409,19 +1497,19 @@
 	return offset;
 }
 
-#define SDP_CONN_PROC_DATA_SIZE  176 /* output line size. */
+#define SDP_CONN_PROC_DATA_SIZE  171 /* output line size. */
 #define SDP_PROC_CONN_DATA_HEAD \
-	" ID  conn inet r s fl sh send_buf recv_buf send q'd recv q'd " \
+	" ID  conn r s fl sh send_buf recv_buf send q'd recv q'd " \
         "send_seq recv_seq advt_seq smax rmax recv_max lrcv " \
 	"lavt rrcv sd sc sp rd rp swqs rbuf sbuf " \
         "us cu send_oob rurg back maxb\n"
 #define SDP_PROC_CONN_DATA_SEP  \
-	"---- ---- ---- - - -- -- -------- -------- -------- -------- " \
+	"---- ---- - - -- -- -------- -------- -------- -------- " \
 	"-------- -------- -------- ---- ---- -------- ---- " \
 	"---- ---- -- -- -- -- -- ---- ---- ---- " \
 	"-- -- -------- ---- ---- ----\n"
 #define SDP_PROC_CONN_DATA_FORM \
-	"%04x %04x %04x %01x %01x %02x %02x " \
+	"%04x %04x %01x %01x %02x %02x " \
 	"%08x %08x %08x %08x %08x %08x " \
 	"%08x %04x %04x %08x %04x %04x %04x %02x %02x " \
 	"%02x %02x %02x %04x %04x %04x %02x %02x %08x %04x %04x %04x\n"
@@ -1470,7 +1558,6 @@
 		offset += sprintf((buffer + offset), SDP_PROC_CONN_DATA_FORM,
 				  conn->hashent,
 				  conn->state,
-				  conn->istate,
 				  conn->recv_mode,
 				  conn->send_mode,
 				  conn->flags,
Index: infiniband/ulp/sdp/sdp_actv.c
===================================================================
--- infiniband/ulp/sdp/sdp_actv.c	(revision 2564)
+++ infiniband/ulp/sdp/sdp_actv.c	(working copy)
@@ -49,19 +49,17 @@
 	 */
 	switch (conn->state) {
 	default:
-		sdp_dbg_warn(conn, "REP error in unknown connection state");
+		sdp_dbg_warn(conn, "Error in unknown connection state");
+	case SDP_CONN_ST_REQ_SENT:
 	case SDP_CONN_ST_REQ_PATH:
 		/*
 		 * CM message was never sent.
 		 */
-		conn->state = SDP_CONN_ST_CLOSED;
+		SDP_CONN_ST_SET(conn, SDP_CONN_ST_ERROR);
+	case SDP_CONN_ST_ERROR:
 	case SDP_CONN_ST_CLOSED:
 		break;
-	case SDP_CONN_ST_ERROR_STRM: /* socket has been destroyed. */
-		error = ECONNRESET;
-        case SDP_CONN_ST_REQ_SENT:
 	case SDP_CONN_ST_REP_RECV:
-	case SDP_CONN_ST_RTU_SENT:
 		/*
 		 * All four states we have gotten a REP and are now in
 		 * one of these states.
@@ -74,7 +72,7 @@
 			sdp_dbg_warn(conn, "Error <%d> sending CM REJ.",
 				     result);
 
-		conn->state = SDP_CONN_ST_CLOSED;
+		SDP_CONN_ST_SET(conn, SDP_CONN_ST_ERROR);
 		break;
 	case SDP_CONN_ST_ESTABLISHED:
 		/*
@@ -86,12 +84,11 @@
 			sdp_dbg_warn(NULL, "Error <%d> sending CM DREQ",
 				     result);
 
-		conn->state = SDP_CONN_ST_TIME_WAIT_1;
+		SDP_CONN_ST_SET(conn, SDP_CONN_ST_TIME_WAIT_1);
 		break;
 	}
 
 	SDP_CONN_SET_ERR(conn, error);
-	conn->istate = SDP_SOCK_ST_ERROR;
 	conn->shutdown = SHUTDOWN_MASK;
 	conn->send_buf = 0;
 
@@ -142,10 +139,6 @@
 		goto done;
 	}
 	/*
-	 * finalize connection acceptance.
-	 */
-	SDP_CONN_ST_SET(conn, SDP_CONN_ST_RTU_SENT);
-	/*
 	 * post receive buffers.
 	 */
 	result = sdp_recv_flush(conn);
@@ -183,7 +176,6 @@
 	SDP_CONN_ST_SET(conn, SDP_CONN_ST_ESTABLISHED);
 
 	sk->sk_socket->state = SS_CONNECTED;
-	conn->istate = SDP_SOCK_ST_ESTABLISHED;
 	conn->send_buf = SDP_INET_SEND_SIZE;
 	/*
 	 * release disconnects.
@@ -271,7 +263,7 @@
 		       struct sdp_opt *conn)
 {
 	struct sdp_msg_hello_ack *hello_ack;
-	int result = -EPROTO;
+	int result = -ECONNRESET;
 
 	if (cm_id != conn->cm_id) {
 		sdp_dbg_warn(conn, "REP comm ID mismatch. <%08x:%08x>",
@@ -286,6 +278,7 @@
 	if (conn->state != SDP_CONN_ST_REQ_SENT)
 		goto error;
 
+	SDP_CONN_ST_SET(conn, SDP_CONN_ST_REP_RECV);
 	/*
 	 * check Hello Header Ack, to determine if we want
 	 * the connection.
@@ -296,7 +289,6 @@
 		goto error;
 	}
 
-	SDP_CONN_ST_SET(conn, SDP_CONN_ST_REP_RECV);
 	/*
 	 * read remote information
 	 */
@@ -491,7 +483,7 @@
         param.local_cm_response_timeout  = 20;
         param.retry_count                = SDP_CM_PARAM_RETRY;
         param.rnr_retry_count            = SDP_CM_PARAM_RNR_RETRY;
-        param.max_cm_retries             = 15;
+        param.max_cm_retries             = 7;
 #if 0
 	/* XXX set timeout to default value of 14 */
 	path->packet_life = 13;
Index: infiniband/ulp/sdp/sdp_wall.c
===================================================================
--- infiniband/ulp/sdp/sdp_wall.c	(revision 2365)
+++ infiniband/ulp/sdp/sdp_wall.c	(working copy)
@@ -1,450 +0,0 @@
-/*
- * Copyright (c) 2005 Topspin Communications.  All rights reserved.
- *
- * This software is available to you under a choice of one of two
- * licenses.  You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- *     Redistribution and use in source and binary forms, with or
- *     without modification, are permitted provided that the following
- *     conditions are met:
- *
- *      - Redistributions of source code must retain the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer.
- *
- *      - Redistributions in binary form must reproduce the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer in the documentation and/or other materials
- *        provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * $Id$
- */
-
-#include "sdp_main.h"
-
-/*
- * SDP protocol (public functions)
- */
-
-/*
- * sdp_wall_send_close - callback to accept an active close
- */
-int sdp_wall_send_close(struct sdp_opt *conn)
-{
-	int result;
-
-	sdp_dbg_ctrl(conn, "Close send. src <%08x:%04x> dst <%08x:%04x>",
-		     conn->src_addr, conn->src_port, 
-		     conn->dst_addr, conn->dst_port);
-	/*
-	 * close buffered data transmission space
-	 */
-	conn->send_buf = 0;
-	/*
-	 * Generate a Disconnect message, and mark self as disconnecting.
-	 */
-	switch (conn->state) {
-	case SDP_CONN_ST_REP_SENT:
-		/*
-		 * clear out the sent HelloAck message
-		 */
-		(void)sdp_buff_pool_put(sdp_buff_q_get_head(&conn->send_post));
-		/*
-		 * fall through
-		 */
-	case SDP_CONN_ST_RTU_SENT:
-		/*
-		 * wait for established before attempting to send. this
-		 * way we'll reduce the number of state permutations.
-		 */
-		SDP_CONN_ST_SET(conn, SDP_CONN_ST_DIS_PEND_1);
-
-		break;
-	case SDP_CONN_ST_ESTABLISHED:
-		/*
-		 * Send a disconnect message
-		 */
-		SDP_CONN_ST_SET(conn, SDP_CONN_ST_DIS_PEND_1);
-
-		result = sdp_send_ctrl_disconnect(conn);
-		if (result < 0) {
-			sdp_dbg_warn(conn, 
-				     "Error <%d> send disconnect request",
-				     result);
-			goto error;
-		}
-
-		break;
-	default:
-		sdp_dbg_warn(conn, "Incorrect state for disconnect");
-		result = -EBADE;
-		goto error;
-	}
-
-	return 0;
-error:
-	/*
-	 * abortive close.
-	 */
-	result = sdp_wall_send_abort(conn);
-	if (result < 0)
-		sdp_dbg_warn(conn, "Error <%d> CM disconnect send", result);
-
-	return result;
-}
-
-/*
- * sdp_wall_send_closing - callback to confirm a passive close
- */
-int sdp_wall_send_closing(struct sdp_opt *conn)
-{
-	int result;
-
-	sdp_dbg_ctrl(conn, "Close confirm. src <%08x:%04x> dst <%08x:%04x>",
-		     conn->src_addr, conn->src_port, 
-		     conn->dst_addr, conn->dst_port);
-	/*
-	 * close buffered data transmission space
-	 */
-	conn->send_buf = 0;
-	/*
-	 * Generate a response Disconnect message, and mark self as such.
-	 */
-	switch (conn->state) {
-	case SDP_CONN_ST_DIS_RECV_1:
-		/*
-		 * Change state, and send a disconnect request
-		 */
-		SDP_CONN_ST_SET(conn, SDP_CONN_ST_DIS_PEND_2);
-
-		result = sdp_send_ctrl_disconnect(conn);
-		if (result < 0) {
-			sdp_dbg_warn(conn,
-				     "Error <%d> send disconnect request",
-				     result);
-			goto error;
-		}
-		break;
-	default:
-		sdp_dbg_warn(conn, "Incorrect state for disconnect");
-		result = -EBADE;
-		goto error;
-	}
-
-	return 0;
-error:
-	/*
-	 * abortive close.
-	 */
-	result = sdp_wall_send_abort(conn);
-	if (result < 0)
-		sdp_dbg_warn(conn, "Error <%d> CM disconnect send", result);
-
-	return result;
-}
-
-/*
- * sdp_wall_send_abort - callback to accept an active abort
- */
-int sdp_wall_send_abort(struct sdp_opt *conn)
-{
-	int result = 0;
-
-	sdp_dbg_ctrl(conn, "Abort send. src <%08x:%04x> dst <%08x:%04x>",
-		     conn->src_addr, conn->src_port, 
-		     conn->dst_addr, conn->dst_port);
-
-	switch (conn->state) {
-	case SDP_CONN_ST_DIS_SENT_1:	/* IBTA v1.1 spec A4.5.3.2 */
-		/*
-		 * clear the pending control buffer.
-		 */
-		sdp_desc_q_clear(&conn->send_ctrl);
-		/*
-		 * fall through
-		 */
-	case SDP_CONN_ST_DIS_SEND_1:	/* don't touch control queue, diconnect
-					   message may still be queued. */
-		sdp_desc_q_clear(&conn->send_queue);
-		/*
-		 * post abort
-		 */
-		result = sdp_send_ctrl_abort(conn);
-		if (result < 0) {
-			sdp_dbg_warn(conn, "Error <%d> send abort request",
-				     result);
-			goto error;
-		}
-		/*
-		 * state change, no more STRM interface calls from here on out.
-		 */
-		SDP_CONN_ST_SET(conn, SDP_CONN_ST_ERROR_STRM);
-
-		break;
-	case SDP_CONN_ST_CLOSED:
-	case SDP_CONN_ST_ERROR_CM:
-	case SDP_CONN_ST_TIME_WAIT_2:
-		/*
-		 * no more CM callbacks will be made.
-		 */
-		SDP_CONN_ST_SET(conn, SDP_CONN_ST_CLOSED);
-
-		break;
-	case SDP_CONN_ST_TIME_WAIT_1:
-		/*
-		 * waiting for idle.
-		 */
-		SDP_CONN_ST_SET(conn, SDP_CONN_ST_TIME_WAIT_2);
-
-		break;
-	case SDP_CONN_ST_REQ_PATH:
-		/*
-		 * cancel address resolution?
-		 *
-		 * instead of canceling allow the path completion to 
-		 * determine that the socket has moved to an error state.
-		 */
-		SDP_CONN_ST_SET(conn, SDP_CONN_ST_CLOSED);
-		break;
-	case SDP_CONN_ST_REQ_SENT:
-	case SDP_CONN_ST_REP_SENT:
-		/*
-		 * outstanding CM request. Mark it in error, and CM
-		 * completion needs to complete the closing.
-		 */
-		SDP_CONN_ST_SET(conn, SDP_CONN_ST_ERROR_STRM);
-
-		break;
-	case SDP_CONN_ST_ESTABLISHED: /* protocol errors and others. */
-	case SDP_CONN_ST_DIS_RECV_1:  /* Abort msg after disconnect msg */
-	case SDP_CONN_ST_DIS_PEND_1:  /* data recv after send/recv close */
-	case SDP_CONN_ST_ERROR_CQ:    /* begin CM level disconnect */
-		/*
-		 * post abort
-		 */
-		goto abort;
-	default:
-		/*
-		 * post abort
-		 */
-		sdp_dbg_warn(conn, "Unexpected connection state for abort");
-		goto error;
-	}
-
-	return 0;
-abort:
-error:
-	/*
-	 * abortive close.
-	 */
-	SDP_CONN_ST_SET(conn, SDP_CONN_ST_ERROR_STRM);
-
-	result = ib_send_cm_dreq(conn->cm_id, NULL, 0);
-	if (result)
-		sdp_dbg_warn(conn, "Error <%d> CM disconnect send", result);
-
-	return 0;
-}
-
-/*
- * SDP INET (public functions)
- */
-
-/*
- * sdp_wall_recv_close - callback to accept an active close
- */
-int sdp_wall_recv_close(struct sdp_opt *conn)
-{
-	sdp_dbg_ctrl(conn, "Close recv. src <%08x:%04x> dst <%08x:%04x>",
-		     conn->src_addr, conn->src_port, 
-		     conn->dst_addr, conn->dst_port);
-	/*
-	 * wake the closing connection, and change state to close received.
-	 */
-	switch (conn->istate) {
-	case SDP_SOCK_ST_ACCEPTING:
-	case SDP_SOCK_ST_ACCEPTED:
-		/*
-		 * shift to close.
-		 */
-		conn->istate = SDP_SOCK_ST_CLOSE;
-		conn->shutdown |= RCV_SHUTDOWN;
-
-		break;
-	default:
-		conn->istate = SDP_SOCK_ST_CLOSE;
-		conn->shutdown |= RCV_SHUTDOWN;
-		/*
-		 * cancel all outstanding read AIO's since there will be
-		 * no more data from the peer.
-		 */
-		sdp_iocb_q_cancel_all_read(conn, 0);
-		/*
-		 * async notification. POLL_HUP on full duplex close only.
-		 */
-		sdp_inet_wake_generic(conn->sk);
-		sk_wake_async(conn->sk, 1, POLL_IN);
-
-		break;
-	}
-
-	return 0;
-}
-
-/*
- * sdp_wall_recv_closing - callback for a close confirmation
- */
-int sdp_wall_recv_closing(struct sdp_opt *conn)
-{
-	sdp_dbg_ctrl(conn, "Closing recv. src <%08x:%04x> dst <%08x:%04x>",
-		     conn->src_addr, conn->src_port, 
-		     conn->dst_addr, conn->dst_port);
-	/*
-	 * change state, finalize the close, and wake the closer.
-	 */
-	SDP_EXPECT((conn->istate == SDP_SOCK_ST_DISCONNECT));
-
-	conn->send_buf = 0;
-	conn->istate = SDP_SOCK_ST_CLOSED;
-	conn->shutdown |= RCV_SHUTDOWN;
-	/*
-	 * cancel all outstanding read AIO's since there will be no more data
-	 * from the peer.
-	 */
-	sdp_iocb_q_cancel_all_read(conn, 0);
-	/*
-	 * async notification. POLL_HUP on full duplex close only.
-	 */
-	sdp_inet_wake_generic(conn->sk);
-	sk_wake_async(conn->sk, 1, POLL_HUP);
-
-	return 0;
-}
-
-/*
- * sdp_wall_recv_abort - abortive close notification
- */
-int sdp_wall_recv_abort(struct sdp_opt *conn)
-{
-	sdp_dbg_ctrl(conn, "Abort recv. src <%08x:%04x> dst <%08x:%04x>",
-		     conn->src_addr, conn->src_port, 
-		     conn->dst_addr, conn->dst_port);
-	/*
-	 * wake the connection in case it's doing anything, and mark it as
-	 * closed. Leave data in their buffers so the user can blead it
-	 * dry.
-	 */
-	switch (conn->istate) {
-	case SDP_SOCK_ST_CONNECT:
-	case SDP_SOCK_ST_ACCEPTING:
-	case SDP_SOCK_ST_ACCEPTED:
-		SDP_CONN_SET_ERR(conn, ECONNREFUSED);
-		break;
-	case SDP_SOCK_ST_CLOSE:
-		SDP_CONN_SET_ERR(conn, EPIPE);
-		break;
-	default:
-		SDP_CONN_SET_ERR(conn, ECONNRESET);
-		break;
-	}
-
-	conn->send_buf = 0;
-	conn->istate = SDP_SOCK_ST_ERROR;
-	conn->shutdown = SHUTDOWN_MASK;
-	/*
-	 * cancel all outstanding IOCBs
-	 */
-	sdp_iocb_q_cancel_all(conn, -ECONNRESET);
-
-	sdp_inet_wake_error(conn->sk);
-
-	return 0;
-}
-
-/*
- * sdp_wall_recv_drop - drop SDP protocol reference to socket
- */
-void sdp_wall_recv_drop(struct sdp_opt *conn)
-{
-	int result;
-
-	sdp_dbg_ctrl(conn, "Drop. src <%08x:%04x> dst <%08x:%04x>",
-		     conn->src_addr, conn->src_port, 
-		     conn->dst_addr, conn->dst_port);
-
-	conn->send_buf = 0;
-
-	switch (conn->istate) {
-	case SDP_SOCK_ST_ACCEPTING:
-		/*
-		 * pull the listen sockets accept queue.
-		 */
-		result = sdp_inet_accept_q_remove(conn);
-		if (result < 0)
-			sdp_dbg_warn(conn, 
-				     "Error <%d> removing from accept queue.",
-				     result);
-
-		conn->istate = SDP_SOCK_ST_CLOSED;
-
-		break;
-	case SDP_SOCK_ST_CLOSING:
-		conn->istate = SDP_SOCK_ST_CLOSED;
-		sdp_inet_wake_generic(conn->sk);
-
-		break;
-	default:
-		/*
-		 * wake the connection in case it's doing anything, and mark
-		 * it as closed. Leave data in their buffers so the user can
-		 * bleed it dry.
-		 */
-		SDP_CONN_SET_ERR(conn, ECONNRESET);
-		conn->istate = SDP_SOCK_ST_ERROR;
-		/*
-		 * cancel all outstanding IOCBs
-		 */
-		sdp_iocb_q_cancel_all(conn, -ECONNRESET);
-
-		sdp_inet_wake_error(conn->sk);
-
-		break;
-	}
-}
-
-/*
- * SDP common (public functions)
- */
-
-/*
- * sdp_wall_abort - intiate socket dropping
- */
-int sdp_wall_abort(struct sdp_opt *conn)
-{
-	int result;
-
-	/*
-	 * notify both halves of the wall that the connection is being aborted.
-	 */
-	result = sdp_wall_recv_abort(conn);
-	if (result < 0)
-		sdp_dbg_warn(conn, "Error <%d> recving abort request", result);
-	/* if */
-	result = sdp_wall_send_abort(conn);
-	if (result < 0)
-		sdp_dbg_warn(conn, "Error <%d> sending abort request", result);
-
-	return 0;
-}
Index: infiniband/ulp/sdp/sdp_recv.c
===================================================================
--- infiniband/ulp/sdp/sdp_recv.c	(revision 2564)
+++ infiniband/ulp/sdp/sdp_recv.c	(working copy)
@@ -828,8 +828,7 @@
 		/*
 		 * abort connection (send reset)
 		 */
-		result = sdp_wall_abort(conn);
-		SDP_EXPECT(result >= 0);
+		sdp_conn_abort(conn);
 		/*
 		 * drop packet
 		 */
@@ -1200,8 +1199,8 @@
 
 	sdp_conn_lock(conn);
 
-	if (conn->istate == SDP_SOCK_ST_LISTEN ||
-	    conn->istate == SDP_SOCK_ST_CLOSED) {
+	if (conn->state == SDP_CONN_ST_LISTEN ||
+	    conn->state == SDP_CONN_ST_CLOSED) {
 		result = -ENOTCONN;
 		goto done;
 	}
@@ -1393,7 +1392,7 @@
 			break;
 		}
 
-		if (conn->istate == SDP_SOCK_ST_ERROR) {
+		if (conn->state == SDP_CONN_ST_ERROR) {
 			result = -EPROTO; /* error should always be
 					     set, but just in case */
 			break;
Index: infiniband/ulp/sdp/sdp_conn.h
===================================================================
--- infiniband/ulp/sdp/sdp_conn.h	(revision 2564)
+++ infiniband/ulp/sdp/sdp_conn.h	(working copy)
@@ -48,18 +48,15 @@
  */
 #define SDP_CONN_COMM_ID_NULL   0xFFFFFFFF	/* when no id is available */
 
-#define SDP_CONN_F_SRC_CANCEL_L 0x0001 /* source cancel was issued */
-#define SDP_CONN_F_SRC_CANCEL_R 0x0002 /* source cancel was received */
-#define SDP_CONN_F_SRC_CANCEL_C 0x0004 /* source data cancelled */
-#define SDP_CONN_F_SNK_CANCEL   0x0008 /* sink cancel issued */
-#define SDP_CONN_F_DIS_HOLD     0x0010 /* Hold pending disconnects. */
-#define SDP_CONN_F_OOB_SEND     0x0020 /* OOB notification pending. */
-#define SDP_CONN_F_RECV_CQ_PEND 0x0040 /* recv CQ event is pending */
-#define SDP_CONN_F_SEND_CQ_PEND 0x0080 /* send CQ event is pending */
-#define SDP_CONN_F_DEAD         0xFFFF /* connection has been deleted */
+#define SDP_CONN_F_SRC_CANCEL_L 0x01 /* source cancel was issued */
+#define SDP_CONN_F_SRC_CANCEL_R 0x02 /* source cancel was received */
+#define SDP_CONN_F_SRC_CANCEL_C 0x04 /* source data cancelled */
+#define SDP_CONN_F_SNK_CANCEL   0x08 /* sink cancel issued */
+#define SDP_CONN_F_DIS_HOLD     0x10 /* Hold pending disconnects. */
+#define SDP_CONN_F_DIS_PEND     0x20 /* disconnect pending. */
+#define SDP_CONN_F_OOB_SEND     0x40 /* OOB notification pending. */
+#define SDP_CONN_F_DEAD         0xFF /* connection has been deleted */
 
-#define SDP_CONN_F_MASK_EVENT   (SDP_CONN_F_RECV_CQ_PEND| \
-				 SDP_CONN_F_SEND_CQ_PEND)
 /*
  * SDP states.
  */
@@ -71,77 +68,42 @@
 };
 
 /*
- * First two bytes are the primary state values. Third byte is a bit
- * field used for different mask operations, defined below. Fourth
- * byte are the mib values for the different states.
+ * First two bytes are the primary state values. Third and fourth
+ * byte are a bit field used for different mask operations, defined
+ * below.
  */
 #define SDP_CONN_ST_LISTEN      0x0100 /* listening */
 
-#define SDP_CONN_ST_ESTABLISHED 0x11B1 /* connected */
+#define SDP_CONN_ST_ESTABLISHED 0x1171 /* connected */
 
 #define SDP_CONN_ST_REQ_PATH    0x2100 /* active open, path record lookup */
 #define SDP_CONN_ST_REQ_SENT    0x2200 /* active open, Hello msg sent */
-#define SDP_CONN_ST_REQ_RECV    0x2300 /* passive open, Hello msg recv'd */
-#define SDP_CONN_ST_REP_SENT    0x2480 /* passive open, Hello ack sent */
-#define SDP_CONN_ST_REP_RECV    0x2500 /* active open, Hello ack recv'd */
-#define SDP_CONN_ST_RTU_SENT    0x2680 /* active open, Hello ack, acked */
+#define SDP_CONN_ST_REQ_RECV    0x2340 /* passive open, Hello msg recv'd */
+#define SDP_CONN_ST_REP_RECV    0x2440 /* active open, Hello ack recv'd */
 
-#define SDP_CONN_ST_DIS_RECV_1  0x31B1 /* recv disconnect, passive close */
-#define SDP_CONN_ST_DIS_PEND_1  0x32F1 /* pending disconn, active close */
-#define SDP_CONN_ST_DIS_SEND_1  0x33B1 /* send disconnect, active close */
-#define SDP_CONN_ST_DIS_SENT_1  0x34A1 /* disconnect sent, active close */
-#define SDP_CONN_ST_DIS_PEND_R  0x35F1 /* disconnect recv, active close */
-#define SDP_CONN_ST_DIS_RECV_R  0x36B1 /* disconnect recv, active close */
-#define SDP_CONN_ST_DIS_PEND_2  0x37F1 /* pending disconn, passive close */
-#define SDP_CONN_ST_DIS_SEND_2  0x38B1 /* send disconnect, passive close */
-#define SDP_CONN_ST_DIS_SENT_2  0x3901 /* disconnect sent, passive close */
-#define SDP_CONN_ST_TIME_WAIT_1 0x3A01 /* IB/gateway disconnect */
-#define SDP_CONN_ST_TIME_WAIT_2 0x3B01 /* waiting for idle close */
+#define SDP_CONN_ST_DIS_RECV_1  0x4171 /* recv disconnect, passive close */
+#define SDP_CONN_ST_DIS_SEND_1  0x4271 /* send disconnect, active close */
+#define SDP_CONN_ST_DIS_SENT_1  0x4361 /* disconnect sent, active close */
+#define SDP_CONN_ST_DIS_RECV_R  0x4471 /* disconnect recv, active close */
+#define SDP_CONN_ST_DIS_SEND_2  0x4571 /* send disconnect, passive close */
+#define SDP_CONN_ST_TIME_WAIT_1 0x4701 /* IB/gateway disconnect */
+#define SDP_CONN_ST_TIME_WAIT_2 0x4801 /* waiting for idle close */
 
-#define SDP_CONN_ST_ERROR_CM    0xFB03 /* CM error, waiting on gateway */
-#define SDP_CONN_ST_ERROR_CQ    0xFC03 /* gateway error, waiting on CM */
-#define SDP_CONN_ST_ERROR_STRM  0xFD01 /* gateway error, waiting on CM */
-#define SDP_CONN_ST_CLOSED      0xFE03 /* not connected */
-#define SDP_CONN_ST_INVALID     0xFF03 /* not connected */
+#define SDP_CONN_ST_CLOSED      0x8E01 /* not connected */
+#define SDP_CONN_ST_ERROR       0x8D01 /* not connected */
+#define SDP_CONN_ST_INVALID     0x8F01 /* not connected */
 
 /*
  * states masks for SDP
  */
+#define SDP_ST_MASK_CONNECT   0x2000    /* connection establishment states */
+#define SDP_ST_MASK_CLOSED    0x8000    /* all connection closed states. */
 #define SDP_ST_MASK_EVENTS    0x0001	/* event processing is allowed. */
-#define SDP_ST_MASK_ERROR     0x0002	/* protocol in error state. */
 #define SDP_ST_MASK_SEND_OK   0x0010	/* posting data for send */
 #define SDP_ST_MASK_CTRL_OK   0x0020	/* posting control for send */
-#define SDP_ST_MASK_DIS_PEND  0x0040	/* disconnect transmission pending. */
-#define SDP_ST_MASK_RCV_POST  0x0080	/* posting IB recv's is allowed. */
+#define SDP_ST_MASK_RCV_POST  0x0040	/* posting IB recv's is allowed. */
 
 /*
- * transition one of the disconnect pending states to disconnect send
- */
-#define SDP_ST_PEND_2_SEND(conn) \
-        ((conn)->state = ((conn)->state + 0x0100) & ~SDP_ST_MASK_DIS_PEND)
-
-/*
- * internal connection structure
- */
-#define SDP_SOCK_ST_CLOSED      0x0101
-#define SDP_SOCK_ST_CONNECT     0x0204
-#define SDP_SOCK_ST_ACCEPTING   0x0300
-#define SDP_SOCK_ST_ACCEPTED    0x0404 /* writable ? */
-#define SDP_SOCK_ST_ESTABLISHED 0x050E
-#define SDP_SOCK_ST_DISCONNECT  0x0602 /* active close request */
-#define SDP_SOCK_ST_CLOSE       0x070C /* passive close request */
-#define SDP_SOCK_ST_CLOSING     0x0800
-#define SDP_SOCK_ST_LISTEN      0x0901
-#define SDP_SOCK_ST_ERROR       0xFF01
-
-/*
- * state masks.
- */
-#define SDP_ST_MASK_CLOSED 0x0001 /* socket is not referenced by the GW. */
-#define SDP_ST_MASK_SEND   0x0004 /* valid state for API send */
-#define SDP_ST_MASK_OPEN   0x0008 /* send window is valid (writeable) */
-
-/*
  * event dispatch table
  */
 #define SDP_MSG_EVENT_TABLE_SIZE 0x20
@@ -205,11 +167,14 @@
  * connection lock
  */
 struct sdp_conn_lock {
-	__u32 users;
+	u16 users;
+	u16 event;
 	spinlock_t slock;
 	wait_queue_head_t waitq;
 };
 
+#define SDP_LOCK_F_RECV_CQ 0x01 /* recv CQ event is pending */
+#define SDP_LOCK_F_SEND_CQ 0x02 /* send CQ event is pending */
 /*
  * SDP Connection structure.
  */
@@ -245,7 +210,6 @@
 	s32 rwin_max;   /* maximum recveive window size */
 
 	u16 state;      /* connection state */
-	u16 istate;     /* inet connection state */
 
 	u8  flags;      /* single bit flags. */
 	u8  shutdown;   /* shutdown flag */
@@ -494,8 +458,7 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&conn->lock.slock, flags);
-	if ((conn->flags & SDP_CONN_F_MASK_EVENT) &&
-	    (SDP_ST_MASK_EVENTS & conn->state)) {
+	if (conn->lock.event && (conn->state & SDP_ST_MASK_EVENTS)) {
 
 		sdp_conn_internal_unlock(conn);
 	}
Index: infiniband/ulp/sdp/sdp_pass.c
===================================================================
--- infiniband/ulp/sdp/sdp_pass.c	(revision 2564)
+++ infiniband/ulp/sdp/sdp_pass.c	(working copy)
@@ -35,38 +35,6 @@
 #include "sdp_main.h"
 
 /*
- * handle incoming passive connection error. (REJ)
- */
-void sdp_cm_pass_error(struct sdp_opt *conn, int error)
-{
-	int result;
-
-	sdp_dbg_ctrl(conn, 
-		     "passive error. src <%08x:%04x> dst <%08x:%04x> <%d>",
-		     conn->src_addr, conn->src_port, 
-		     conn->dst_addr, conn->dst_port, error);
-	/*
-	 * the connection has failed, move to error, and notify anyone
-	 * waiting of the state change. remove connection from listen
-	 * queue if possible
-	 */
-	result = sdp_inet_accept_q_remove(conn);
-	if (!result)
-		sdp_conn_put(conn); /* AcceptQueue INET reference */
-
-	SDP_CONN_SET_ERR(conn, error);
-	conn->istate = SDP_SOCK_ST_ERROR;
-	conn->shutdown = SHUTDOWN_MASK;
-	conn->send_buf = 0;
-
-	if (conn->sk->sk_socket)
-		conn->sk->sk_socket->state = SS_UNCONNECTED;
-
-	sdp_iocb_q_cancel_all(conn, (0 - error));
-	sdp_inet_wake_error(conn->sk);
-}
-
-/*
  * handle incoming passive connection establishment. (RTU)
  */
 int sdp_cm_pass_establish(struct sdp_opt *conn)
@@ -82,8 +50,6 @@
 	 * free hello ack message
 	 */
 	(void)sdp_buff_pool_put(sdp_buff_q_get_head(&conn->send_post));
-	
-	SDP_CONN_ST_SET(conn, SDP_CONN_ST_ESTABLISHED);
 
         qp_attr = kmalloc(sizeof(*qp_attr), GFP_KERNEL);
         if (!qp_attr) {
@@ -109,15 +75,6 @@
 
 	conn->send_buf = SDP_INET_SEND_SIZE;
 
-	switch (conn->istate) {
-	case SDP_SOCK_ST_ACCEPTING:
-		conn->istate = SDP_SOCK_ST_ACCEPTED;
-		break;
-	case SDP_SOCK_ST_ACCEPTED:
-		conn->istate = SDP_SOCK_ST_ESTABLISHED;
-		break;
-	}
-
 	result = sdp_send_flush(conn);
 	if (0 > result) {
 		sdp_dbg_warn(conn, "Error <%d> flushing sends.", result);
@@ -137,9 +94,7 @@
 error:
         kfree(qp_attr);
 done:
-	sdp_cm_pass_error(conn, (0 - result));
-	SDP_CONN_ST_SET(conn, SDP_CONN_ST_ERROR_STRM);
-
+	sdp_conn_inet_error(conn, -result);
 	return result;
 }
 /*
@@ -247,10 +202,6 @@
 		goto error;
         }
 	/*
-	 * set connection state to allow recv buffer posts.
-	 */
-	SDP_CONN_ST_SET(conn, SDP_CONN_ST_REP_SENT);
-	/*
 	 * Post receive buffers for this connection
 	 */
 	result = sdp_recv_flush(conn);
@@ -342,8 +293,6 @@
 	 * insert accept socket into listen sockets list.
 	 * TODO: needs to be a FIFO not a LIFO, as is now.
 	 */
-	conn->istate = SDP_SOCK_ST_ACCEPTING;
-
 	inet_sk(sk)->num       = conn->src_port;
 	inet_sk(sk)->sport     = htons(conn->src_port);
 	inet_sk(sk)->rcv_saddr = htonl(conn->src_addr);
Index: infiniband/ulp/sdp/sdp_sent.c
===================================================================
--- infiniband/ulp/sdp/sdp_sent.c	(revision 2564)
+++ infiniband/ulp/sdp/sdp_sent.c	(working copy)
@@ -58,21 +58,6 @@
 
 		break;
 	case SDP_CONN_ST_DIS_SEND_2:
-		/*
-		 * passive disconnect message send
-		 */
-		SDP_CONN_ST_SET(conn, SDP_CONN_ST_DIS_SENT_2);
-		/*
-		 * Begin IB/CM disconnect
-		 */
-		result = ib_send_cm_dreq(conn->cm_id, NULL, 0);
-		if (result) {
-			sdp_dbg_warn(conn, "Error <%d> posting CM disconnect",
-				     result);
-			goto error;
-		}
-
-		break;
 	case SDP_CONN_ST_DIS_RECV_R:
 		/*
 		 * simultaneous disconnect. Received a disconnect, after we
@@ -81,15 +66,6 @@
 		 */
 		SDP_CONN_ST_SET(conn, SDP_CONN_ST_TIME_WAIT_1);
 		/*
-		 * acknowledge disconnect to framework
-		 */
-		result = sdp_wall_recv_closing(conn);
-		if (result < 0) {
-			sdp_dbg_warn(conn, "Error <%d> closing connection.",
-				     result);
-			goto error;
-		}
-		/*
 		 * Begin IB/CM disconnect
 		 */
 		result = ib_send_cm_dreq(conn->cm_id, NULL, 0);
@@ -102,10 +78,12 @@
 				     result);
 
 		break;
+	case SDP_CONN_ST_ERROR:
+		break;
 	default:
-		sdp_warn("Disconnect sent, unexpected state. <%d> <%04x:%04d>",
-			 conn->hashent, conn->istate, conn->state);
-		result = -EFAULT;
+		sdp_warn("Disconnect sent, unexpected state. <%d> <%04x>",
+			 conn->hashent, conn->state);
+		result = -EPROTO;
 		goto error;
 
 		break;
@@ -124,8 +102,7 @@
 	 * The gateway interface should be in error state, initiate CM
 	 * disconnect.
 	 */
-	SDP_EXPECT((conn->state == SDP_CONN_ST_ERROR_STRM));
-	SDP_CONN_ST_SET(conn, SDP_CONN_ST_ERROR_STRM);
+	SDP_CONN_ST_SET(conn, SDP_CONN_ST_CLOSED);
 
 	result = ib_send_cm_dreq(conn->cm_id, NULL, 0);
 	if (result)
Index: infiniband/ulp/sdp/sdp_event.c
===================================================================
--- infiniband/ulp/sdp/sdp_event.c	(revision 2564)
+++ infiniband/ulp/sdp/sdp_event.c	(working copy)
@@ -45,9 +45,9 @@
 {
 	int result = 0;
 
-	if (SDP_ST_MASK_ERROR & conn->state) {
+	if (SDP_ST_MASK_CLOSED & conn->state) {
 		/*
-		 * Ignore events in error state, connection is being 
+		 * Ignore events in closed state, connection is being 
 		 * terminated, connection cleanup will take care of freeing
 		 * posted buffers.
 		 */
@@ -112,12 +112,7 @@
 		/*
 		 * abort.
 		 */
-		SDP_CONN_ST_SET(conn, SDP_CONN_ST_ERROR_CQ);
-
-		result = sdp_wall_abort(conn);
-		if (result < 0)
-			sdp_dbg_warn(conn, "Error <%d> during abort", result);
-
+		sdp_conn_abort(conn);
 		return -EFAULT;
 	}
 
@@ -132,7 +127,7 @@
 {
 	s32 hashent = (unsigned long)arg;
 	struct sdp_opt *conn;
-	s32 result;
+	u16 event;
 	unsigned long flags;
 
 	sdp_dbg_data(NULL, "CQ event. hashent <%d>", hashent);
@@ -157,41 +152,42 @@
 	 * has been made, the act of unlocking the connection will
 	 * drain the CQ.
 	 */
-	if (!(SDP_ST_MASK_EVENTS & conn->state)) {
-		/*
-		 * passive and active connect respectively
-		 */
-		if (conn->state == SDP_CONN_ST_REP_SENT ||
-		    conn->state == SDP_CONN_ST_RTU_SENT) {
-			result = ib_cm_establish(conn->cm_id);
-			SDP_EXPECT(result >= 0);
-		}
-		else
-			sdp_dbg_warn(conn, "Unexpected locked state.");
+	event = (cq == conn->recv_cq) ? SDP_LOCK_F_RECV_CQ:SDP_LOCK_F_SEND_CQ;
 
-		conn->flags |= SDP_CONN_F_MASK_EVENT;
-		goto unlock;
+	if (!conn->lock.users) {
+		if (!(SDP_ST_MASK_EVENTS & conn->state)) {
+			/*
+			 * passive and active connect respectively
+			 */
+			if (conn->state == SDP_CONN_ST_REQ_RECV)
+				(void)ib_cm_establish(conn->cm_id);
+			else
+				sdp_dbg_warn(conn, "Unexpected event state.");
+		}
+		else {
+			/*
+			 * dispatch CQ completions.
+			 */
+			(void)sdp_conn_cq_drain(cq, conn);
+			event = 0;
+		}
 	}
+	/*
+	 * Mark the event which was received, for the unlock code to
+	 * process at a later time.
+	 */
+	conn->lock.event |= event;
 
-	if (!conn->lock.users)
-		/*
-		 * dispatch CQ completions.
-		 */
-		(void)sdp_conn_cq_drain(cq, conn);
-	else
-		/*
-		 * Mark the event which was received, for the unlock code to
-		 * process at a later time.
-		 */
-		conn->flags |= ((cq == conn->recv_cq) ?
-				SDP_CONN_F_RECV_CQ_PEND :
-				SDP_CONN_F_SEND_CQ_PEND);
-
-unlock:
 	SDP_CONN_UNLOCK_IRQ(conn, flags);
 	sdp_conn_put(conn);
 }
 
+static void sdp_cm_to_error(struct sdp_opt *conn)
+{
+	sdp_conn_inet_error(conn, ECONNRESET);
+	conn->cm_id = NULL;
+	sdp_conn_put(conn);	/* CM reference */
+}
 /*
  * Connection establishment IB/CM callback functions
  */
@@ -206,31 +202,27 @@
 	 */
 	switch (conn->state) {
 	case SDP_CONN_ST_REQ_SENT:
-		conn->state = SDP_CONN_ST_CLOSED;
-
 		sdp_cm_actv_error(conn, ECONNREFUSED);
 		break;
-	case SDP_CONN_ST_REP_SENT:
-		conn->state = SDP_CONN_ST_CLOSED;
-
-		sdp_cm_pass_error(conn, ECONNREFUSED);
+	case SDP_CONN_ST_REQ_RECV:
+	case SDP_CONN_ST_ESTABLISHED:
+		sdp_conn_inet_error(conn, ECONNREFUSED);
 		break;
 	case SDP_CONN_ST_TIME_WAIT_1:
-	case SDP_CONN_ST_ESTABLISHED:
 		sdp_dbg_warn(conn, "Unexpected connection state");
 		/*
 		 * fall through
 		 */
-	case SDP_CONN_ST_ERROR_STRM:
+	case SDP_CONN_ST_CLOSED:
+	case SDP_CONN_ST_ERROR:
 	case SDP_CONN_ST_TIME_WAIT_2:
 		/*
 		 * Connection is finally dead. Drop the CM reference
 		 */
-		sdp_wall_recv_drop(conn);
 		break;
 	default:
-		sdp_warn("Unknown conn state. conn <%d> state <%04x:%04x>",
-			 conn->hashent, conn->istate, conn->state);
+		sdp_warn("Unknown conn state. conn <%d> state <%04x>",
+			 conn->hashent, conn->state);
 		break;
 	}
 
@@ -254,14 +246,20 @@
 	 * check state
 	 */
 	switch (conn->state) {
-	case SDP_CONN_ST_REP_SENT:
+	case SDP_CONN_ST_REQ_RECV:
+		SDP_CONN_ST_SET(conn, SDP_CONN_ST_ESTABLISHED);
+	case SDP_CONN_ST_DIS_SEND_1:
+	case SDP_CONN_ST_DIS_RECV_R:
+	case SDP_CONN_ST_DIS_SEND_2:
+		/* bring QP to established state, and flush queues. */
 		result = sdp_cm_pass_establish(conn);
 		if (!result)
 			break;
 		/*
 		 * on error fall through to disconnect
 		 */
-	case SDP_CONN_ST_ERROR_STRM:
+	case SDP_CONN_ST_CLOSED:
+	case SDP_CONN_ST_ERROR:
 		/*
 		 * Begin abortive disconnect.
 		 * Leave state unchanged, time_wait and idle will handle the
@@ -269,29 +267,18 @@
 		 */
 		result = ib_send_cm_dreq(conn->cm_id, NULL, 0);
 		if (result) {
-			sdp_dbg_warn(NULL, "Error <%d> sending CM DREQ", 
+			sdp_dbg_warn(conn, "Error <%d> sending CM DREQ", 
 				     result);
-			goto done;
-		}
-
-		break;
-	case SDP_CONN_ST_DIS_PEND_1:
-		/* active open, and active close */
-	case SDP_CONN_ST_DIS_PEND_R:
-		/* active open, and active close, confirm */
-	case SDP_CONN_ST_DIS_PEND_2:
-		result = sdp_send_flush(conn);
-		if (result < 0) {
-			sdp_dbg_warn(conn, "Error <%d> flushing receives.",
-				     result);
 			goto error;
 		}
 
 		break;
+	case SDP_CONN_ST_ESTABLISHED:
+		break;
 	default:
 
-		sdp_warn("Unexpected conn state. conn <%d> state <%04x:%04x>",
-			 conn->hashent, conn->istate, conn->state);
+		sdp_warn("Unexpected conn state. conn <%d> state <%04x>",
+			 conn->hashent, conn->state);
 		result = -EINVAL;
 		goto error;
 		break;
@@ -299,10 +286,7 @@
 
 	return 0;
 error:
-	sdp_wall_recv_drop(conn);
-done:
-	conn->cm_id = NULL;
-	sdp_conn_put(conn);	/* CM reference */
+	sdp_cm_to_error(conn);
 	return result;
 }
 
@@ -319,11 +303,7 @@
 	result = ib_send_cm_drep(conn->cm_id, NULL, 0);
 	if (result) {
 		sdp_dbg_warn(conn, "Error <%d> sending CM DREP", result);
-
-		sdp_wall_recv_drop(conn);
-
-		conn->cm_id = NULL;
-		sdp_conn_put(conn);	/* CM reference */
+		sdp_cm_to_error(conn);
 	}
 
 	return result;
@@ -351,7 +331,8 @@
 	 * process state changes.
 	 */
 	switch (conn->state) {
-	case SDP_CONN_ST_ERROR_STRM:
+	case SDP_CONN_ST_CLOSED:
+	case SDP_CONN_ST_ERROR:
 		/*
 		 * error on stream interface, no more call to/from those
 		 * interfaces.
@@ -359,7 +340,6 @@
 		break;
 	case SDP_CONN_ST_DIS_RECV_R:
 	case SDP_CONN_ST_DIS_SEND_2:
-	case SDP_CONN_ST_DIS_SENT_2:
 	case SDP_CONN_ST_TIME_WAIT_1:
 		/*
 		 * SDP disconnect messages have been exchanged, and
@@ -367,7 +347,6 @@
 		 */
 		SDP_CONN_ST_SET(conn, SDP_CONN_ST_TIME_WAIT_2);
 		break;
-	case SDP_CONN_ST_DIS_PEND_1:
 	case SDP_CONN_ST_DIS_SEND_1:
 	case SDP_CONN_ST_DIS_SENT_1:
 	case SDP_CONN_ST_DIS_RECV_1:
@@ -380,29 +359,18 @@
 		 * Change state, so we only need to wait for the abort 
 		 * callback, and idle. Call the abort callback.
 		 */
-		SDP_CONN_ST_SET(conn, SDP_CONN_ST_TIME_WAIT_1);
+		SDP_CONN_ST_SET(conn, SDP_CONN_ST_TIME_WAIT_2);
 
-		result = sdp_wall_abort(conn);
-		if (result < 0) {
-			sdp_dbg_warn(conn, "Error <%d> during abort", result);
-			goto error;
-		}
-
+		sdp_conn_abort(conn);
 		break;
 	default:
-		sdp_warn("Unexpected conn state. conn <%d> state <%04x:%04x>",
-			 conn->hashent, conn->istate, conn->state);
+		sdp_warn("Unexpected conn state. conn <%d> state <%04x>",
+			 conn->hashent, conn->state);
+		sdp_cm_to_error(conn);
 		result = -EINVAL;
-		goto error;
 		break;
 	}
 
-	return 0;
-error:
-	sdp_wall_recv_drop(conn);
-
-	conn->cm_id = NULL;
-	sdp_conn_put(conn);	/* CM reference */
 	return result;
 }
 
@@ -460,7 +428,7 @@
 	 * if a socket was found, release the lock, and put the reference.
 	 */
 	if (conn) {
-		if (result < 0) {
+		if (result < 0 && event->event != IB_CM_TIMEWAIT_EXIT) {
 			sdp_dbg_warn(conn, 
 				     "CM state <%d> event <%d> error <%d>",
 				     cm_id->state, event->event, result);



More information about the general mailing list