/* if last transition into FF (Fully Featured) state */ int isert_login_rsp_tx(struct iscsi_cmnd *login_rsp, int last, int discovery) { struct isert_connection *isert_conn = container_of(login_rsp->conn, struct isert_connection, iscsi); int err; if (last && !discovery) { err = isert_alloc_conn_resources(isert_conn); if (unlikely(err)) { pr_err("Failed to init conn resources\n"); return err; } isert_pdu_free(isert_conn->login_req_pdu); isert_conn->login_req_pdu = NULL; } else { err = isert_post_recv(isert_conn, &isert_conn->login_req_pdu->wr[0], 1); if (unlikely(err)) { pr_err("Failed to post recv login req rx buf, err:%d\n", err); return err; } } return isert_pdu_tx(login_rsp); }
void isert_free_conn_resources(struct isert_connection *isert_conn) { struct isert_cmnd *pdu; TRACE_ENTRY(); if (isert_conn->login_rsp_pdu) { isert_pdu_free(isert_conn->login_rsp_pdu); isert_conn->login_rsp_pdu = NULL; } if (isert_conn->login_req_pdu) { isert_pdu_free(isert_conn->login_req_pdu); isert_conn->login_req_pdu = NULL; } while (!list_empty(&isert_conn->rx_buf_list)) { pdu = list_first_entry(&isert_conn->rx_buf_list, struct isert_cmnd, pool_node); isert_pdu_free(pdu); /* releases buffer as well */ } spin_lock(&isert_conn->tx_lock); while (!list_empty(&isert_conn->tx_free_list)) { pdu = list_first_entry(&isert_conn->tx_free_list, struct isert_cmnd, pool_node); isert_pdu_free(pdu); /* releases buffer as well */ } while (!list_empty(&isert_conn->tx_busy_list)) { pdu = list_first_entry(&isert_conn->tx_busy_list, struct isert_cmnd, pool_node); isert_pdu_free(pdu); /* releases buffer as well */ } spin_unlock(&isert_conn->tx_lock); TRACE_EXIT(); }
static struct isert_connection *isert_conn_create(struct rdma_cm_id *cm_id, struct isert_device *isert_dev) { struct isert_connection *isert_conn; int err; struct isert_cq *cq; TRACE_ENTRY(); isert_conn = isert_conn_alloc(); if (unlikely(!isert_conn)) { pr_err("Unable to allocate iser conn, cm_id:%p\n", cm_id); err = -ENOMEM; goto fail_alloc; } isert_conn->state = ISER_CONN_INIT; isert_conn->cm_id = cm_id; isert_conn->isert_dev = isert_dev; /* * A quote from the OFED 1.5.3.1 release notes * (docs/release_notes/mthca_release_notes.txt), section "Known Issues": * In mem-free devices, RC QPs can be created with a maximum of * (max_sge - 1) entries only; UD QPs can be created with a maximum of * (max_sge - 3) entries. * A quote from the OFED 1.2.5 release notes * (docs/mthca_release_notes.txt), section "Known Issues": * In mem-free devices, RC QPs can be created with a maximum of * (max_sge - 3) entries only. */ isert_conn->max_sge = isert_dev->device_attr.max_sge - 3; WARN_ON(isert_conn->max_sge < 1); INIT_LIST_HEAD(&isert_conn->rx_buf_list); INIT_LIST_HEAD(&isert_conn->tx_free_list); INIT_LIST_HEAD(&isert_conn->tx_busy_list); spin_lock_init(&isert_conn->tx_lock); spin_lock_init(&isert_conn->post_recv_lock); isert_conn->login_req_pdu = isert_rx_pdu_alloc(isert_conn, ISER_MAX_LOGIN_RDSL); if (unlikely(!isert_conn->login_req_pdu)) { pr_err("Failed to init login req rx pdu\n"); err = -ENOMEM; goto fail_login_req_pdu; } isert_conn->login_rsp_pdu = isert_tx_pdu_alloc(isert_conn, ISER_MAX_LOGIN_RDSL); if (unlikely(!isert_conn->login_rsp_pdu)) { pr_err("Failed to init login rsp tx pdu\n"); err = -ENOMEM; goto fail_login_rsp_pdu; } err = isert_conn_qp_create(isert_conn); if (unlikely(err)) goto fail_qp; err = isert_post_recv(isert_conn, &isert_conn->login_req_pdu->wr[0], 1); if (unlikely(err)) { pr_err("Failed to post recv login req rx buf, err:%d\n", err); goto fail_post_recv; } kref_init(&isert_conn->kref); TRACE_EXIT(); return isert_conn; fail_post_recv: cq = isert_conn->qp->recv_cq->cq_context; mutex_lock(&dev_list_mutex); isert_dev->cq_qps[cq->idx]--; mutex_unlock(&dev_list_mutex); isert_conn_qp_destroy(isert_conn); fail_qp: isert_pdu_free(isert_conn->login_rsp_pdu); fail_login_rsp_pdu: isert_pdu_free(isert_conn->login_req_pdu); fail_login_req_pdu: isert_conn_kfree(isert_conn); fail_alloc: module_put(THIS_MODULE); TRACE_EXIT_RES(err); return ERR_PTR(err); }
static struct isert_connection *isert_conn_create(struct rdma_cm_id *cm_id, struct isert_device *isert_dev) { struct isert_connection *isert_conn; int err; struct isert_cq *cq; TRACE_ENTRY(); isert_conn = isert_conn_alloc(); if (unlikely(!isert_conn)) { pr_err("Unable to allocate iser conn, cm_id:%p\n", cm_id); err = -ENOMEM; goto fail_alloc; } isert_conn->state = ISER_CONN_INIT; isert_conn->cm_id = cm_id; isert_conn->isert_dev = isert_dev; INIT_LIST_HEAD(&isert_conn->rx_buf_list); INIT_LIST_HEAD(&isert_conn->tx_free_list); INIT_LIST_HEAD(&isert_conn->tx_busy_list); spin_lock_init(&isert_conn->tx_lock); spin_lock_init(&isert_conn->post_recv_lock); isert_conn->login_req_pdu = isert_rx_pdu_alloc(isert_conn, ISER_MAX_LOGIN_RDSL); if (unlikely(!isert_conn->login_req_pdu)) { pr_err("Failed to init login req rx pdu\n"); err = -ENOMEM; goto fail_login_req_pdu; } isert_conn->login_rsp_pdu = isert_tx_pdu_alloc(isert_conn, ISER_MAX_LOGIN_RDSL); if (unlikely(!isert_conn->login_rsp_pdu)) { pr_err("Failed to init login rsp tx pdu\n"); err = -ENOMEM; goto fail_login_rsp_pdu; } err = isert_conn_qp_create(isert_conn); if (unlikely(err)) goto fail_qp; err = isert_post_recv(isert_conn, &isert_conn->login_req_pdu->wr[0], 1); if (unlikely(err)) { pr_err("Failed to post recv login req rx buf, err:%d\n", err); goto fail_post_recv; } kref_init(&isert_conn->kref); TRACE_EXIT(); return isert_conn; fail_post_recv: cq = isert_conn->qp->recv_cq->cq_context; mutex_lock(&dev_list_mutex); isert_dev->cq_qps[cq->idx]--; mutex_unlock(&dev_list_mutex); isert_conn_qp_destroy(isert_conn); fail_qp: isert_pdu_free(isert_conn->login_rsp_pdu); fail_login_rsp_pdu: isert_pdu_free(isert_conn->login_req_pdu); fail_login_req_pdu: isert_conn_kfree(isert_conn); fail_alloc: module_put(THIS_MODULE); TRACE_EXIT_RES(err); return ERR_PTR(err); }