*/
 int xprt_rdma_bc_send_reply(struct rpc_rqst *rqst)
 {
-       struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(rqst->rq_xprt);
+       struct rpc_xprt *xprt = rqst->rq_xprt;
+       struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
        struct rpcrdma_req *req = rpcr_to_rdmar(rqst);
        int rc;
 
-       if (!xprt_connected(rqst->rq_xprt))
-               goto drop_connection;
+       if (!xprt_connected(xprt))
+               return -ENOTCONN;
 
-       if (!xprt_request_get_cong(rqst->rq_xprt, rqst))
+       if (!xprt_request_get_cong(xprt, rqst))
                return -EBADSLT;
 
        rc = rpcrdma_bc_marshal_reply(rqst);
        if (rc != -ENOTCONN)
                return rc;
 drop_connection:
-       xprt_disconnect_done(rqst->rq_xprt);
+       xprt_rdma_close(xprt);
        return -ENOTCONN;
 }
 
 
 out_overflow:
        pr_warn("RPC/RDMA backchannel overflow\n");
-       xprt_disconnect_done(xprt);
+       xprt_force_disconnect(xprt);
        /* This receive buffer gets reposted automatically
         * when the connection is re-established.
         */
 
                svc_rdma_send_ctxt_put(rdma, ctxt);
                goto drop_connection;
        }
-       return rc;
+       return 0;
 
 drop_connection:
        dprintk("svcrdma: failed to send bc call\n");
-       xprt_disconnect_done(xprt);
        return -ENOTCONN;
 }
 
 
        ret = -ENOTCONN;
        rdma = container_of(sxprt, struct svcxprt_rdma, sc_xprt);
-       if (!test_bit(XPT_DEAD, &sxprt->xpt_flags))
+       if (!test_bit(XPT_DEAD, &sxprt->xpt_flags)) {
                ret = rpcrdma_bc_send_request(rdma, rqst);
+               if (ret == -ENOTCONN)
+                       svc_close_xprt(sxprt);
+       }
 
        mutex_unlock(&sxprt->xpt_mutex);
 
 
  * Caller holds @xprt's send lock to prevent activity on this
  * transport while the connection is torn down.
  */
-static void
-xprt_rdma_close(struct rpc_xprt *xprt)
+void xprt_rdma_close(struct rpc_xprt *xprt)
 {
        struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
        struct rpcrdma_ep *ep = &r_xprt->rx_ep;
 
        if (test_and_clear_bit(RPCRDMA_IAF_REMOVING, &ia->ri_flags)) {
                rpcrdma_ia_remove(ia);
-               return;
+               goto out;
        }
+
        if (ep->rep_connected == -ENODEV)
                return;
        if (ep->rep_connected > 0)
                xprt->reestablish_timeout = 0;
-       xprt_disconnect_done(xprt);
        rpcrdma_ep_disconnect(ep, ia);
 
        /* Prepare @xprt for the next connection by reinitializing
         */
        r_xprt->rx_buf.rb_credits = 1;
        xprt->cwnd = RPC_CWNDSHIFT;
+
+out:
+       ++xprt->connect_cookie;
+       xprt_disconnect_done(xprt);
 }
 
 /**
 #endif /* CONFIG_SUNRPC_BACKCHANNEL */
 
        if (!xprt_connected(xprt))
-               goto drop_connection;
+               return -ENOTCONN;
 
        if (!xprt_request_get_cong(xprt, rqst))
                return -EBADSLT;
        if (rc != -ENOTCONN)
                return rc;
 drop_connection:
-       xprt_disconnect_done(xprt);
-       return -ENOTCONN;       /* implies disconnect */
+       xprt_rdma_close(xprt);
+       return -ENOTCONN;
 }
 
 void xprt_rdma_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
 
                        ep->rep_connected = -EAGAIN;
                goto disconnected;
        case RDMA_CM_EVENT_DISCONNECTED:
-               ++xprt->connect_cookie;
                ep->rep_connected = -ECONNABORTED;
 disconnected:
                xprt_force_disconnect(xprt);
 
 extern unsigned int xprt_rdma_max_inline_read;
 void xprt_rdma_format_addresses(struct rpc_xprt *xprt, struct sockaddr *sap);
 void xprt_rdma_free_addresses(struct rpc_xprt *xprt);
+void xprt_rdma_close(struct rpc_xprt *xprt);
 void xprt_rdma_print_stats(struct rpc_xprt *xprt, struct seq_file *seq);
 int xprt_rdma_init(void);
 void xprt_rdma_cleanup(void);