예제 #1
0
static int htifblk_segment(struct htifblk_device *dev,
	struct request *req)
{
	static struct htifblk_request pkt __aligned(HTIF_ALIGN);
	u64 offset, size, end;

	offset = (blk_rq_pos(req) << SECTOR_SIZE_SHIFT);
	size = (blk_rq_cur_sectors(req) << SECTOR_SIZE_SHIFT);

	end = offset + size;
	if (unlikely(end < offset || end > dev->size)) {
		dev_err(&dev->dev->dev, "out-of-bounds access:"
			" offset=%llu size=%llu\n", offset, size);
		return -EINVAL;
	}

	rmb();
	pkt.addr = __pa(bio_data(req->bio));
	pkt.offset = offset;
	pkt.size = size;
	pkt.tag = dev->tag;

	dev->req = req;
	dev->msg_buf.dev = dev->dev->index;
	dev->msg_buf.cmd = (rq_data_dir(req) == READ) ?
		HTIF_CMD_READ : HTIF_CMD_WRITE;
	dev->msg_buf.data = __pa(&pkt);
	htif_tohost(&dev->msg_buf);
	return 0;
}
예제 #2
0
static void htifbd_transfer(struct htifbd_dev *dev, unsigned long sector,
	unsigned long nsect, char *buf, int direction)
{
	/* HTIF disk address packet */
	volatile struct htifbd_dap {
		unsigned long address;
		unsigned long offset;	/* offset in bytes */
		unsigned long length;	/* length in bytes */
		unsigned long tag;
	} req;
	unsigned long offset, length;
	unsigned long htif_cmd;

	offset = (sector << SECTOR_SIZE_SHIFT);
	length = (nsect << SECTOR_SIZE_SHIFT);

	if ((offset + length) > dev->size) {
		pr_notice(DRIVER_NAME "out-of-bounds access to %s with"
			"offset=%lx length=%lx\n",
			dev->gd->disk_name, offset, length);
		return;
	}

	req.address = (unsigned long)__pa(buf);
	req.offset = offset;
	req.length = length;
	req.tag = 0;

	if (direction == READ) {
		htif_cmd = HTIF_CMD_READ;
	} else if (direction == WRITE) {
		htif_cmd = HTIF_CMD_WRITE;
	} else {
		return;
	}

	mb();
	htif_tohost(dev->dev->minor, htif_cmd, __pa(&req));
	htif_fromhost();
	mb();
}
예제 #3
0
static int htifblk_segment(struct htifblk_device *dev,
	struct request *req)
{
	static struct htifblk_request pkt __aligned(HTIF_ALIGN);
	u64 offset, size, end;
	unsigned long cmd;

	offset = (blk_rq_pos(req) << SECTOR_SIZE_SHIFT);
	size = (blk_rq_cur_sectors(req) << SECTOR_SIZE_SHIFT);

	end = offset + size;
	if (unlikely(end < offset || end > dev->size)) {
		dev_err(&dev->dev->dev, "out-of-bounds access:"
			" offset=%llu size=%llu\n", offset, size);
		return -EINVAL;
	}

	rmb();
	pkt.addr = __pa(req->buffer);
	pkt.offset = offset;
	pkt.size = size;
	pkt.tag = dev->tag;

	switch (rq_data_dir(req)) {
	case READ:
		cmd = HTIF_CMD_READ;
		break;
	case WRITE:
		cmd = HTIF_CMD_WRITE;
		break;
	default:
		return -EINVAL;
	}

	dev->req = req;
	htif_tohost(dev->dev->index, cmd, __pa(&pkt));
	return 0;
}
예제 #4
0
static inline void __init early_htif_putc(unsigned char ch)
{
	/* FIXME: Device ID should not be hard-coded. */
	htif_tohost(HTIF_DEV_CONSOLE, HTIF_CMD_WRITE, ch);
}