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; }
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(); }
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; }
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); }