Exemplo n.º 1
0
 /**
 * starts the process of connecting to the target
 * sleeps untill the connection is established or rejected
 */
int iser_connect(struct iser_conn   *ib_conn,
		 struct sockaddr_in *src_addr,
		 struct sockaddr_in *dst_addr,
		 int                 non_blocking)
{
	struct sockaddr *src, *dst;
	int err = 0;

	sprintf(ib_conn->name, "%pI4:%d",
		&dst_addr->sin_addr.s_addr, dst_addr->sin_port);

	/* the device is known only --after-- address resolution */
	ib_conn->device = NULL;

	iser_err("connecting to: %pI4, port 0x%x\n",
		 &dst_addr->sin_addr, dst_addr->sin_port);

	ib_conn->state = ISER_CONN_PENDING;

	iser_conn_get(ib_conn); /* ref ib conn's cma id */
	ib_conn->cma_id = rdma_create_id(iser_cma_handler,
					     (void *)ib_conn,
					     RDMA_PS_TCP);
	if (IS_ERR(ib_conn->cma_id)) {
		err = PTR_ERR(ib_conn->cma_id);
		iser_err("rdma_create_id failed: %d\n", err);
		goto id_failure;
	}

	src = (struct sockaddr *)src_addr;
	dst = (struct sockaddr *)dst_addr;
	err = rdma_resolve_addr(ib_conn->cma_id, src, dst, 1000);
	if (err) {
		iser_err("rdma_resolve_addr failed: %d\n", err);
		goto addr_failure;
	}

	if (!non_blocking) {
		wait_event_interruptible(ib_conn->wait,
					 (ib_conn->state != ISER_CONN_PENDING));

		if (ib_conn->state != ISER_CONN_UP) {
			err =  -EIO;
			goto connect_failure;
		}
	}

	mutex_lock(&ig.connlist_mutex);
	list_add(&ib_conn->conn_list, &ig.connlist);
	mutex_unlock(&ig.connlist_mutex);
	return 0;

id_failure:
	ib_conn->cma_id = NULL;
addr_failure:
	ib_conn->state = ISER_CONN_DOWN;
connect_failure:
	iser_conn_release(ib_conn, 1);
	return err;
}
Exemplo n.º 2
0
int iser_conn_put(struct iser_conn *ib_conn, int can_destroy_id)
{
	if (atomic_dec_and_test(&ib_conn->refcount)) {
		iser_conn_release(ib_conn, can_destroy_id);
		return 1;
	}
	return 0;
}
Exemplo n.º 3
0
/**
 * triggers start of the disconnect procedures and wait for them to be done
 */
void iser_conn_terminate(struct iser_conn *ib_conn)
{
    int err = 0;

    /* change the ib conn state only if the conn is UP, however always call
     * rdma_disconnect since this is the only way to cause the CMA to change
     * the QP state to ERROR
     */

    iser_conn_state_comp_exch(ib_conn, ISER_CONN_UP, ISER_CONN_TERMINATING);
    err = rdma_disconnect(ib_conn->cma_id);
    if (err)
        iser_err("Failed to disconnect, conn: 0x%p err %d\n",
             ib_conn,err);

    wait_event_interruptible(ib_conn->wait,
                 ib_conn->state == ISER_CONN_DOWN);

    iser_conn_release(ib_conn);
}
Exemplo n.º 4
0
void iser_conn_put(struct iser_conn *ib_conn)
{
	if (atomic_dec_and_test(&ib_conn->refcount))
		iser_conn_release(ib_conn);
}