static bool nvmf_process_connect(struct spdk_nvmf_request *req) { struct spdk_nvmf_fabric_connect_cmd *connect; struct spdk_nvmf_fabric_connect_data *connect_data; struct spdk_nvmf_fabric_connect_rsp *response; struct spdk_nvmf_conn *conn = req->conn; struct nvmf_session *session; if (req->length < sizeof(struct spdk_nvmf_fabric_connect_data)) { SPDK_ERRLOG("Connect command data length 0x%x too small\n", req->length); req->rsp->nvme_cpl.status.sc = SPDK_NVME_SC_INVALID_FIELD; return true; } connect = &req->cmd->connect_cmd; connect_data = (struct spdk_nvmf_fabric_connect_data *)req->data; RTE_VERIFY(connect_data != NULL); SPDK_TRACELOG(SPDK_TRACE_NVMF, "Connect cmd: cid 0x%x recfmt 0x%x qid %u sqsize %u\n", connect->cid, connect->recfmt, connect->qid, connect->sqsize); SPDK_TRACELOG(SPDK_TRACE_NVMF, "Connect data:\n"); SPDK_TRACELOG(SPDK_TRACE_NVMF, " cntlid: 0x%04x\n", connect_data->cntlid); SPDK_TRACELOG(SPDK_TRACE_NVMF, " hostid: %08x-%04x-%04x-%02x%02x-%04x%08x ***\n", ntohl(*(uint32_t *)&connect_data->hostid[0]), ntohs(*(uint16_t *)&connect_data->hostid[4]), ntohs(*(uint16_t *)&connect_data->hostid[6]), connect_data->hostid[8], connect_data->hostid[9], ntohs(*(uint16_t *)&connect_data->hostid[10]), ntohl(*(uint32_t *)&connect_data->hostid[12])); SPDK_TRACELOG(SPDK_TRACE_NVMF, " subnqn: \"%s\"\n", (char *)&connect_data->subnqn[0]); SPDK_TRACELOG(SPDK_TRACE_NVMF, " hostnqn: \"%s\"\n", (char *)&connect_data->hostnqn[0]); response = &req->rsp->connect_rsp; session = nvmf_connect((void *)conn, connect, connect_data, response); if (session != NULL) { conn->sess = session; conn->qid = connect->qid; if (connect->qid > 0) { conn->type = CONN_TYPE_IOQ; /* I/O Connection */ } else { /* When session first created, set some attributes */ nvmf_init_conn_properites(conn, session, response); } } /* Allocate RDMA reqs according to the queue depth and conn type*/ if (spdk_nvmf_rdma_alloc_reqs(conn)) { SPDK_ERRLOG("Unable to allocate sufficient RDMA work requests\n"); req->rsp->nvme_cpl.status.sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR; return true; } SPDK_TRACELOG(SPDK_TRACE_NVMF, "connect capsule response: cntlid = 0x%04x\n", response->status_code_specific.success.cntlid); return true; }
static void nvmf_connect_continue(struct spdk_nvmf_conn *conn, struct nvme_qp_tx_desc *tx_desc) { struct nvme_qp_rx_desc *rx_desc; struct nvmf_request *req; struct spdk_nvmf_fabric_connect_cmd *connect; struct spdk_nvmf_fabric_connect_data *connect_data; struct spdk_nvmf_fabric_connect_rsp *response; struct nvmf_session *session; int ret; if (tx_desc == NULL) { SPDK_TRACELOG(SPDK_TRACE_DEBUG, " tx_desc does not exist!\n"); return; } rx_desc = tx_desc->rx_desc; if (rx_desc == NULL) { SPDK_TRACELOG(SPDK_TRACE_DEBUG, " rx_desc does not exist!\n"); return; } connect = (struct spdk_nvmf_fabric_connect_cmd *)&rx_desc->msg_buf; connect_data = (struct spdk_nvmf_fabric_connect_data *)rx_desc->bb; req = &tx_desc->req_state; /* clear the SGL details for any RDMA previously performed */ req->length = 0; SPDK_TRACELOG(SPDK_TRACE_NVMF, " *** Connect Capsule Data *** %p\n", connect_data); SPDK_TRACELOG(SPDK_TRACE_NVMF, " *** cntlid = %x ***\n", connect_data->cntlid); SPDK_TRACELOG(SPDK_TRACE_NVMF, " *** hostid = %04x%04x-%04x-%04x-%04x-%04x%04x%04x ***\n", htons(*(unsigned short *) &connect_data->hostid[0]), htons(*(unsigned short *) &connect_data->hostid[2]), htons(*(unsigned short *) &connect_data->hostid[4]), htons(*(unsigned short *) &connect_data->hostid[6]), htons(*(unsigned short *) &connect_data->hostid[8]), htons(*(unsigned short *) &connect_data->hostid[10]), htons(*(unsigned short *) &connect_data->hostid[12]), htons(*(unsigned short *) &connect_data->hostid[14])); SPDK_TRACELOG(SPDK_TRACE_NVMF, " *** subsiqn = %s ***\n", (char *)&connect_data->subnqn[0]); SPDK_TRACELOG(SPDK_TRACE_NVMF, " *** hostiqn = %s ***\n", (char *)&connect_data->hostnqn[0]); response = &req->rsp->connect_rsp; session = nvmf_connect((void *)conn, connect, connect_data, response); if (session != NULL) { conn->sess = session; conn->qid = connect->qid; if (connect->qid > 0) { conn->type = CONN_TYPE_IOQ; /* I/O Connection */ } else { /* When session first created, set some attributes */ nvmf_init_conn_properites(conn, session, response); } } /* synchronous call, nvmf library expected to init response status. */ SPDK_TRACELOG(SPDK_TRACE_NVMF, "send connect capsule response\n"); SPDK_TRACELOG(SPDK_TRACE_NVMF, " *** cntlid = %x ***\n", response->status_code_specific.success.cntlid); ret = spdk_nvmf_send_response(conn, req); if (ret) { SPDK_ERRLOG("Unable to send aq qp tx descriptor\n"); goto connect_error; } return; connect_error: /* recover the tx_desc */ if (tx_desc != NULL) { tx_desc->rx_desc = NULL; nvmf_deactive_tx_desc(tx_desc); } }