Ejemplo n.º 1
0
static void isert_rx_pdu_parse_headers(struct isert_cmnd *isert_pdu)
{
	struct iscsi_cmnd *iscsi_cmnd = &isert_pdu->iscsi;
	struct isert_buf *isert_buf = &isert_pdu->buf;
	u8 *addr = isert_buf->addr;
	struct isert_hdr *isert_hdr = (struct isert_hdr *)addr;
	struct iscsi_hdr *bhs = (struct iscsi_hdr *)(addr + sizeof(*isert_hdr));
	unsigned int data_offset = ISER_HDRS_SZ;
	unsigned int ahssize;

	TRACE_ENTRY();

	isert_pdu->isert_hdr = isert_hdr;
	isert_pdu->isert_opcode = isert_hdr->flags & 0xf0;
	isert_pdu->is_rstag_valid = isert_hdr->flags & ISER_RSV ? 1 : 0;
	isert_pdu->is_wstag_valid = isert_hdr->flags & ISER_WSV ? 1 : 0;

	if (isert_pdu->is_rstag_valid) {
		isert_pdu->rem_read_stag = be32_to_cpu(isert_hdr->read_stag);
		isert_pdu->rem_read_va = be64_to_cpu(isert_hdr->read_va);
	}

	if (isert_pdu->is_wstag_valid) {
		isert_pdu->rem_write_stag = be32_to_cpu(isert_hdr->write_stag);
		isert_pdu->rem_write_va = be64_to_cpu(isert_hdr->write_va);
	}

	isert_pdu->bhs = bhs;
	isert_pdu->iscsi_opcode = bhs->opcode & ISCSI_OPCODE_MASK;

	memcpy(&iscsi_cmnd->pdu.bhs, bhs, sizeof(iscsi_cmnd->pdu.bhs));
	iscsi_cmnd_get_length(&iscsi_cmnd->pdu); /* get ahssize and datasize */

	ahssize = isert_pdu->iscsi.pdu.ahssize;
	if (likely(!ahssize)) {
		isert_pdu->ahs = NULL;
	} else {
		isert_pdu->ahs = addr + ISER_HDRS_SZ;
		data_offset += ahssize;
	}
	iscsi_cmnd->pdu.ahs = isert_pdu->ahs;

	iscsi_cmnd->bufflen = iscsi_cmnd->pdu.datasize;
	iscsi_cmnd->bufflen = (iscsi_cmnd->bufflen + 3) & ~3;
	if (iscsi_cmnd->bufflen) {
		iscsi_cmnd->sg_cnt = isert_pdu->buf.sg_cnt;
		iscsi_cmnd->sg = isert_pdu->buf.sg;
	} else {
		iscsi_cmnd->sg = NULL;
	}

	TRACE_EXIT();
}
Ejemplo n.º 2
0
static ssize_t isert_write(struct file *filp, const char __user *buf,
			   size_t count, loff_t *f_pos)
{
	struct isert_conn_dev *dev = filp->private_data;
	size_t to_write;

	if (dev->state == CS_DISCONNECTED)
		return -EPIPE;

	to_write = min(count, dev->write_len);
	if (copy_from_user(dev->write_buf, buf, to_write))
		return -EFAULT;

	dev->write_len -= to_write;
	dev->write_buf += to_write;

	switch (dev->state) {
	case CS_RSP_BHS:
		if (dev->write_len == 0) {
			dev->state = CS_RSP_DATA;
			dev->sg_virt = isert_vmap_sg(dev->pages,
						     dev->login_rsp->sg,
						     dev->login_rsp->sg_cnt);
			if (!dev->sg_virt)
				return -ENOMEM;
			dev->write_buf = dev->sg_virt + ISER_HDRS_SZ;
			dev->write_len = dev->login_rsp->bufflen -
					 sizeof(dev->login_rsp->pdu.bhs);
			iscsi_cmnd_get_length(&dev->login_rsp->pdu);
		}
		break;

	case CS_RSP_DATA:
		break;

	default:
		PRINT_ERROR("Invalid state in %s (%d)\n", __func__,
			    dev->state);
		to_write = 0;
	}

	return to_write;
}