Example #1
0
void
cxgbit_get_r2t_ttt(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
		   struct iscsi_r2t *r2t)
{
	struct cxgbit_sock *csk = conn->context;
	struct cxgbit_device *cdev = csk->com.cdev;
	struct cxgbit_cmd *ccmd = iscsit_priv_cmd(cmd);
	struct cxgbi_task_tag_info *ttinfo = &ccmd->ttinfo;
	int ret = -EINVAL;

	if ((!ccmd->setup_ddp) ||
	    (!test_bit(CSK_DDP_ENABLE, &csk->com.flags)))
		goto out;

	ccmd->setup_ddp = false;

	ttinfo->sgl = cmd->se_cmd.t_data_sg;
	ttinfo->nents = cmd->se_cmd.t_data_nents;

	ret = cxgbit_ddp_reserve(csk, ttinfo, cmd->se_cmd.data_length);
	if (ret < 0) {
		pr_debug("csk 0x%p, cmd 0x%p, xfer len %u, sgcnt %u no ddp.\n",
			 csk, cmd, cmd->se_cmd.data_length, ttinfo->nents);

		ttinfo->sgl = NULL;
		ttinfo->nents = 0;
	} else {
		ccmd->release = true;
	}
out:
	pr_debug("cdev 0x%p, cmd 0x%p, tag 0x%x\n", cdev, cmd, ttinfo->tag);
	r2t->targ_xfer_tag = ttinfo->tag;
}
Example #2
0
void cxgbit_unmap_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd)
{
	struct cxgbit_cmd *ccmd = iscsit_priv_cmd(cmd);

	if (ccmd->release) {
		struct cxgbi_task_tag_info *ttinfo = &ccmd->ttinfo;

		if (ttinfo->sgl) {
			struct cxgbit_sock *csk = conn->context;
			struct cxgbit_device *cdev = csk->com.cdev;
			struct cxgbi_ppm *ppm = cdev2ppm(cdev);

			/* Abort the TCP conn if DDP is not complete to
			 * avoid any possibility of DDP after freeing
			 * the cmd.
			 */
			if (unlikely(cmd->write_data_done !=
				     cmd->se_cmd.data_length))
				cxgbit_abort_conn(csk);

			cxgbi_ppm_ppod_release(ppm, ttinfo->idx);

			dma_unmap_sg(&ppm->pdev->dev, ttinfo->sgl,
				     ttinfo->nents, DMA_FROM_DEVICE);
		} else {
			put_page(sg_page(&ccmd->sg));
		}

		ccmd->release = false;
	}
}
Example #3
0
void cxgbit_release_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd)
{
	struct cxgbit_cmd *ccmd = iscsit_priv_cmd(cmd);

	if (ccmd->release) {
		struct cxgbi_task_tag_info *ttinfo = &ccmd->ttinfo;

		if (ttinfo->sgl) {
			struct cxgbit_sock *csk = conn->context;
			struct cxgbit_device *cdev = csk->com.cdev;
			struct cxgbi_ppm *ppm = cdev2ppm(cdev);

			cxgbi_ppm_ppod_release(ppm, ttinfo->idx);

			dma_unmap_sg(&ppm->pdev->dev, ttinfo->sgl,
				     ttinfo->nents, DMA_FROM_DEVICE);
		} else {
			put_page(sg_page(&ccmd->sg));
		}

		ccmd->release = false;
	}
}