Esempio n. 1
0
/**
 * iscsi_iser_cleanup_task() - cleanup an iscsi-iser task
 * @task: iscsi task
 *
 * Notes: In case the RDMA device is already NULL (might have
 *        been removed in DEVICE_REMOVAL CM event it will bail-out
 *        without doing dma unmapping.
 */
static void iscsi_iser_cleanup_task(struct iscsi_task *task)
{
	struct iscsi_iser_task *iser_task = task->dd_data;
	struct iser_tx_desc *tx_desc = &iser_task->desc;
	struct iser_conn *iser_conn = task->conn->dd_data;
	struct iser_device *device = iser_conn->ib_conn.device;

	/* DEVICE_REMOVAL event might have already released the device */
	if (!device)
		return;

	if (likely(tx_desc->mapped)) {
		ib_dma_unmap_single(device->ib_device, tx_desc->dma_addr,
				    ISER_HEADERS_LEN, DMA_TO_DEVICE);
		tx_desc->mapped = false;
	}

	/* mgmt tasks do not need special cleanup */
	if (!task->sc)
		return;

	if (iser_task->status == ISER_TASK_STATUS_STARTED) {
		iser_task->status = ISER_TASK_STATUS_COMPLETED;
		iser_task_rdma_finalize(iser_task);
	}
}
Esempio n. 2
0
static void iscsi_iser_cleanup_task(struct iscsi_task *task)
{
	struct iscsi_iser_task *iser_task = task->dd_data;

	/* mgmt tasks do not need special cleanup */
	if (!task->sc)
		return;

	if (iser_task->status == ISER_TASK_STATUS_STARTED) {
		iser_task->status = ISER_TASK_STATUS_COMPLETED;
		iser_task_rdma_finalize(iser_task);
	}
}
Esempio n. 3
0
static void iscsi_iser_cleanup_task(struct iscsi_task *task)
{
	struct iscsi_iser_task *iser_task = task->dd_data;

	/*
	 * mgmt tasks do not need special cleanup and we do not
	 * allocate anything in the init task callout
	 */
	if (!task->sc || task->state == ISCSI_TASK_PENDING)
		return;

	if (iser_task->status == ISER_TASK_STATUS_STARTED) {
		iser_task->status = ISER_TASK_STATUS_COMPLETED;
		iser_task_rdma_finalize(iser_task);
	}
}
Esempio n. 4
0
static void iscsi_iser_cleanup_task(struct iscsi_task *task)
{
	struct iscsi_iser_task *iser_task = task->dd_data;
	struct iser_tx_desc    *tx_desc   = &iser_task->desc;
	struct iser_conn       *ib_conn	  = task->conn->dd_data;
	struct iser_device     *device	  = ib_conn->device;

	ib_dma_unmap_single(device->ib_device,
		tx_desc->dma_addr, ISER_HEADERS_LEN, DMA_TO_DEVICE);

	/* mgmt tasks do not need special cleanup */
	if (!task->sc)
		return;

	if (iser_task->status == ISER_TASK_STATUS_STARTED) {
		iser_task->status = ISER_TASK_STATUS_COMPLETED;
		iser_task_rdma_finalize(iser_task);
	}
}
Esempio n. 5
0
/**
 * iser_rcv_dto_completion - recv DTO completion
 */
void iser_rcv_completion(struct iser_desc *rx_desc,
			 unsigned long dto_xfer_len)
{
	struct iser_dto *dto = &rx_desc->dto;
	struct iscsi_iser_conn *conn = dto->ib_conn->iser_conn;
	struct iscsi_task *task;
	struct iscsi_iser_task *iser_task;
	struct iscsi_hdr *hdr;
	char   *rx_data = NULL;
	int     rx_data_len = 0;
	unsigned char opcode;

	hdr = &rx_desc->iscsi_header;

	iser_dbg("op 0x%x itt 0x%x\n", hdr->opcode,hdr->itt);

	if (dto_xfer_len > ISER_TOTAL_HEADERS_LEN) { /* we have data */
		rx_data_len = dto_xfer_len - ISER_TOTAL_HEADERS_LEN;
		rx_data     = dto->regd[1]->virt_addr;
		rx_data    += dto->offset[1];
	}

	opcode = hdr->opcode & ISCSI_OPCODE_MASK;

	if (opcode == ISCSI_OP_SCSI_CMD_RSP) {
		spin_lock(&conn->iscsi_conn->session->lock);
		task = iscsi_itt_to_ctask(conn->iscsi_conn, hdr->itt);
		if (task)
			__iscsi_get_task(task);
		spin_unlock(&conn->iscsi_conn->session->lock);

		if (!task)
			iser_err("itt can't be matched to task!!! "
				 "conn %p opcode %d itt %d\n",
				 conn->iscsi_conn, opcode, hdr->itt);
		else {
			iser_task = task->dd_data;
			iser_dbg("itt %d task %p\n",hdr->itt, task);
			iser_task->status = ISER_TASK_STATUS_COMPLETED;
			iser_task_rdma_finalize(iser_task);
			iscsi_put_task(task);
		}
	}
	iser_dto_buffs_release(dto);

	iscsi_iser_recv(conn->iscsi_conn, hdr, rx_data, rx_data_len);

	kfree(rx_desc->data);
	kmem_cache_free(ig.desc_cache, rx_desc);

	/* decrementing conn->post_recv_buf_count only --after-- freeing the   *
	 * task eliminates the need to worry on tasks which are completed in   *
	 * parallel to the execution of iser_conn_term. So the code that waits *
	 * for the posted rx bufs refcount to become zero handles everything   */
	atomic_dec(&conn->ib_conn->post_recv_buf_count);

	/*
	 * if an unexpected PDU was received then the recv wr consumed must
	 * be replaced, this is done in the next send of a control-type PDU
	 */
	if (opcode == ISCSI_OP_NOOP_IN && hdr->itt == RESERVED_ITT) {
		/* nop-in with itt = 0xffffffff */
		atomic_inc(&conn->ib_conn->unexpected_pdu_count);
	}
	else if (opcode == ISCSI_OP_ASYNC_EVENT) {
		/* asyncronous message */
		atomic_inc(&conn->ib_conn->unexpected_pdu_count);
	}
	/* a reject PDU consumes the recv buf posted for the response */
}