All of lore.kernel.org
 help / color / mirror / Atom feed
From: Bin Meng <bmeng.cn@gmail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 13/27] virtio: Add block driver support
Date: Sun, 23 Sep 2018 06:42:11 -0700	[thread overview]
Message-ID: <1537710145-1888-14-git-send-email-bmeng.cn@gmail.com> (raw)
In-Reply-To: <1537710145-1888-1-git-send-email-bmeng.cn@gmail.com>

From: Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi>

This adds virtio block device driver support.

Signed-off-by: Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi>
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
---

 drivers/virtio/Kconfig      |   7 +++
 drivers/virtio/Makefile     |   1 +
 drivers/virtio/virtio_blk.c | 127 +++++++++++++++++++++++++++++++++++++++++++
 drivers/virtio/virtio_blk.h | 129 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 264 insertions(+)
 create mode 100644 drivers/virtio/virtio_blk.c
 create mode 100644 drivers/virtio/virtio_blk.h

diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
index ceea03a..01bd116 100644
--- a/drivers/virtio/Kconfig
+++ b/drivers/virtio/Kconfig
@@ -25,4 +25,11 @@ config VIRTIO_NET
 	  This is the virtual net driver for virtio. It can be used with
 	  QEMU based targets.
 
+config VIRTIO_BLK
+	bool "virtio block driver"
+	depends on VIRTIO
+	help
+	  This is the virtual block driver for virtio. It can be used with
+	  QEMU based targets.
+
 endmenu
diff --git a/drivers/virtio/Makefile b/drivers/virtio/Makefile
index b7764f1..5fe7428 100644
--- a/drivers/virtio/Makefile
+++ b/drivers/virtio/Makefile
@@ -6,3 +6,4 @@
 obj-y += virtio-uclass.o virtio_ring.o
 obj-$(CONFIG_VIRTIO_MMIO) += virtio_mmio.o
 obj-$(CONFIG_VIRTIO_NET) += virtio_net.o
+obj-$(CONFIG_VIRTIO_BLK) += virtio_blk.o
diff --git a/drivers/virtio/virtio_blk.c b/drivers/virtio/virtio_blk.c
new file mode 100644
index 0000000..9601abb
--- /dev/null
+++ b/drivers/virtio/virtio_blk.c
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi>
+ * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+ */
+
+#include <common.h>
+#include <blk.h>
+#include <dm.h>
+#include <virtio.h>
+#include <virtio_ring.h>
+#include "virtio_blk.h"
+
+struct virtio_blk_priv {
+	struct virtqueue *vq;
+};
+
+static ulong virtio_blk_do_req(struct udevice *dev, u64 sector,
+			       lbaint_t blkcnt, void *buffer, u32 type)
+{
+	struct virtio_blk_priv *priv = dev_get_priv(dev);
+	unsigned int num_out = 0, num_in = 0;
+	struct virtio_sg *sgs[3];
+	u8 status;
+	int ret;
+
+	struct virtio_blk_outhdr out_hdr = {
+		.type = cpu_to_virtio32(dev, type),
+		.sector = cpu_to_virtio64(dev, sector),
+	};
+	struct virtio_sg hdr_sg = { &out_hdr, sizeof(out_hdr) };
+	struct virtio_sg data_sg = { buffer, blkcnt * 512 };
+	struct virtio_sg status_sg = { &status, sizeof(status) };
+
+	sgs[num_out++] = &hdr_sg;
+
+	if (type & VIRTIO_BLK_T_OUT)
+		sgs[num_out++] = &data_sg;
+	else
+		sgs[num_out + num_in++] = &data_sg;
+
+	sgs[num_out + num_in++] = &status_sg;
+
+	ret = virtqueue_add(priv->vq, sgs, num_out, num_in);
+	if (ret)
+		return ret;
+
+	virtqueue_kick(priv->vq);
+
+	while (!virtqueue_get_buf(priv->vq, NULL))
+		;
+
+	return status == VIRTIO_BLK_S_OK ? blkcnt : -EIO;
+}
+
+static ulong virtio_blk_read(struct udevice *dev, lbaint_t start,
+			     lbaint_t blkcnt, void *buffer)
+{
+	return virtio_blk_do_req(dev, start, blkcnt, buffer,
+				 VIRTIO_BLK_T_IN);
+}
+
+static ulong virtio_blk_write(struct udevice *dev, lbaint_t start,
+			      lbaint_t blkcnt, const void *buffer)
+{
+	return virtio_blk_do_req(dev, start, blkcnt, (void *)buffer,
+				 VIRTIO_BLK_T_OUT);
+}
+
+static int virtio_blk_bind(struct udevice *dev)
+{
+	struct virtio_dev_priv *uc_priv = dev_get_uclass_priv(dev->parent);
+	struct blk_desc *desc = dev_get_uclass_platdata(dev);
+	int devnum;
+
+	desc->if_type = IF_TYPE_VIRTIO;
+	/*
+	 * Initialize the devnum to -ENODEV. This is to make sure that
+	 * blk_next_free_devnum() works as expected, since the default
+	 * value 0 is a valid devnum.
+	 */
+	desc->devnum = -ENODEV;
+	devnum = blk_next_free_devnum(IF_TYPE_VIRTIO);
+	if (devnum < 0)
+		return devnum;
+	desc->devnum = devnum;
+	desc->part_type = PART_TYPE_UNKNOWN;
+	sprintf(desc->vendor, "%s", (char *)&uc_priv->vendor);
+	desc->bdev = dev;
+
+	/* Indicate what driver features we support */
+	virtio_driver_features_init(uc_priv, NULL, 0, NULL, 0);
+
+	return 0;
+}
+
+static int virtio_blk_probe(struct udevice *dev)
+{
+	struct virtio_blk_priv *priv = dev_get_priv(dev);
+	struct blk_desc *desc = dev_get_uclass_platdata(dev);
+	u64 cap;
+	int ret;
+
+	ret = virtio_find_vqs(dev, 1, &priv->vq);
+	if (ret)
+		return ret;
+
+	desc->blksz = 512;
+	virtio_cread(dev, struct virtio_blk_config, capacity, &cap);
+	desc->lba = cap;
+
+	return 0;
+}
+
+static const struct blk_ops virtio_blk_ops = {
+	.read	= virtio_blk_read,
+	.write	= virtio_blk_write,
+};
+
+U_BOOT_DRIVER(virtio_blk) = {
+	.name	= VIRTIO_BLK_DRV_NAME,
+	.id	= UCLASS_BLK,
+	.ops	= &virtio_blk_ops,
+	.bind	= virtio_blk_bind,
+	.probe	= virtio_blk_probe,
+	.priv_auto_alloc_size = sizeof(struct virtio_blk_priv),
+};
diff --git a/drivers/virtio/virtio_blk.h b/drivers/virtio/virtio_blk.h
new file mode 100644
index 0000000..8d8e02f
--- /dev/null
+++ b/drivers/virtio/virtio_blk.h
@@ -0,0 +1,129 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (C) 2018, Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi>
+ * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * From Linux kernel include/uapi/linux/virtio_blk.h
+ */
+
+#ifndef _LINUX_VIRTIO_BLK_H
+#define _LINUX_VIRTIO_BLK_H
+
+/* Feature bits */
+#define VIRTIO_BLK_F_SIZE_MAX	1	/* Indicates maximum segment size */
+#define VIRTIO_BLK_F_SEG_MAX	2	/* Indicates maximum # of segments */
+#define VIRTIO_BLK_F_GEOMETRY	4	/* Legacy geometry available */
+#define VIRTIO_BLK_F_RO		5	/* Disk is read-only */
+#define VIRTIO_BLK_F_BLK_SIZE	6	/* Block size of disk is available */
+#define VIRTIO_BLK_F_TOPOLOGY	10	/* Topology information is available */
+#define VIRTIO_BLK_F_MQ		12	/* Support more than one vq */
+
+/* Legacy feature bits */
+#ifndef VIRTIO_BLK_NO_LEGACY
+#define VIRTIO_BLK_F_BARRIER	0	/* Does host support barriers? */
+#define VIRTIO_BLK_F_SCSI	7	/* Supports scsi command passthru */
+#define VIRTIO_BLK_F_FLUSH	9	/* Flush command supported */
+#define VIRTIO_BLK_F_CONFIG_WCE	11	/* Writeback mode available in config */
+#ifndef __KERNEL__
+/* Old (deprecated) name for VIRTIO_BLK_F_FLUSH */
+#define VIRTIO_BLK_F_WCE	VIRTIO_BLK_F_FLUSH
+#endif
+#endif /* !VIRTIO_BLK_NO_LEGACY */
+
+#define VIRTIO_BLK_ID_BYTES	20	/* ID string length */
+
+struct __packed virtio_blk_config {
+	/* The capacity (in 512-byte sectors) */
+	__u64 capacity;
+	/* The maximum segment size (if VIRTIO_BLK_F_SIZE_MAX) */
+	__u32 size_max;
+	/* The maximum number of segments (if VIRTIO_BLK_F_SEG_MAX) */
+	__u32 seg_max;
+	/* geometry of the device (if VIRTIO_BLK_F_GEOMETRY) */
+	struct virtio_blk_geometry {
+		__u16 cylinders;
+		__u8 heads;
+		__u8 sectors;
+	} geometry;
+
+	/* block size of device (if VIRTIO_BLK_F_BLK_SIZE) */
+	__u32 blk_size;
+
+	/* the next 4 entries are guarded by VIRTIO_BLK_F_TOPOLOGY */
+	/* exponent for physical block per logical block */
+	__u8 physical_block_exp;
+	/* alignment offset in logical blocks */
+	__u8 alignment_offset;
+	/* minimum I/O size without performance penalty in logical blocks */
+	__u16 min_io_size;
+	/* optimal sustained I/O size in logical blocks */
+	__u32 opt_io_size;
+
+	/* writeback mode (if VIRTIO_BLK_F_CONFIG_WCE) */
+	__u8 wce;
+	__u8 unused;
+
+	/* number of vqs, only available when VIRTIO_BLK_F_MQ is set */
+	__u16 num_queues;
+};
+
+/*
+ * Command types
+ *
+ * Usage is a bit tricky as some bits are used as flags and some are not.
+ *
+ * Rules:
+ *   VIRTIO_BLK_T_OUT may be combined with VIRTIO_BLK_T_SCSI_CMD or
+ *   VIRTIO_BLK_T_BARRIER. VIRTIO_BLK_T_FLUSH is a command of its own
+ *   and may not be combined with any of the other flags.
+ */
+
+/* These two define direction */
+#define VIRTIO_BLK_T_IN		0
+#define VIRTIO_BLK_T_OUT	1
+
+#ifndef VIRTIO_BLK_NO_LEGACY
+/* This bit says it's a scsi command, not an actual read or write */
+#define VIRTIO_BLK_T_SCSI_CMD	2
+#endif /* VIRTIO_BLK_NO_LEGACY */
+
+/* Cache flush command */
+#define VIRTIO_BLK_T_FLUSH	4
+
+/* Get device ID command */
+#define VIRTIO_BLK_T_GET_ID	8
+
+#ifndef VIRTIO_BLK_NO_LEGACY
+/* Barrier before this op */
+#define VIRTIO_BLK_T_BARRIER	0x80000000
+#endif /* !VIRTIO_BLK_NO_LEGACY */
+
+/*
+ * This comes first in the read scatter-gather list.
+ * For legacy virtio, if VIRTIO_F_ANY_LAYOUT is not negotiated,
+ * this is the first element of the read scatter-gather list.
+ */
+struct virtio_blk_outhdr {
+	/* VIRTIO_BLK_T* */
+	__virtio32 type;
+	/* io priority */
+	__virtio32 ioprio;
+	/* Sector (ie. 512 byte offset) */
+	__virtio64 sector;
+};
+
+#ifndef VIRTIO_BLK_NO_LEGACY
+struct virtio_scsi_inhdr {
+	__virtio32 errors;
+	__virtio32 data_len;
+	__virtio32 sense_len;
+	__virtio32 residual;
+};
+#endif /* !VIRTIO_BLK_NO_LEGACY */
+
+/* And this is the final byte of the write scatter-gather list */
+#define VIRTIO_BLK_S_OK		0
+#define VIRTIO_BLK_S_IOERR	1
+#define VIRTIO_BLK_S_UNSUPP	2
+
+#endif /* _LINUX_VIRTIO_BLK_H */
-- 
2.7.4

  parent reply	other threads:[~2018-09-23 13:42 UTC|newest]

Thread overview: 82+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-23 13:41 [U-Boot] [PATCH 00/27] virtio: Introduce VirtIO driver support Bin Meng
2018-09-23 13:41 ` [U-Boot] [PATCH 01/27] dm: core: Allow uclass to set up a device's child after it is probed Bin Meng
2018-09-27 13:41   ` Simon Glass
2018-10-11  5:14     ` Bin Meng
2018-09-23 13:42 ` [U-Boot] [PATCH 02/27] dm: Add a new uclass driver for VirtIO transport devices Bin Meng
2018-09-27 13:42   ` Simon Glass
2018-10-11  9:08     ` Bin Meng
2018-09-27 22:10   ` Tuomas Tynkkynen
2018-10-11  9:09     ` Bin Meng
2018-09-23 13:42 ` [U-Boot] [PATCH 03/27] virtio: Add codes for virtual queue/ring management Bin Meng
2018-09-27 13:42   ` Simon Glass
2018-10-11  9:50     ` Bin Meng
2018-10-12  0:00       ` Simon Glass
2018-09-27 22:11   ` Tuomas Tynkkynen
2018-10-02 15:46     ` Bin Meng
2018-09-23 13:42 ` [U-Boot] [PATCH 04/27] virtio: Add virtio over mmio transport driver Bin Meng
2018-09-27 13:42   ` Simon Glass
2018-09-23 13:42 ` [U-Boot] [PATCH 05/27] virtio: Add net driver support Bin Meng
2018-09-27 13:42   ` Simon Glass
2018-09-27 22:12   ` Tuomas Tynkkynen
2018-10-02 16:10     ` Bin Meng
2018-10-22 23:09   ` Joe Hershberger
2018-09-23 13:42 ` [U-Boot] [PATCH 06/27] test: dm: blk: Correct blk_base test case Bin Meng
2018-09-27 13:42   ` Simon Glass
2018-09-23 13:42 ` [U-Boot] [PATCH 07/27] sandbox: blk: Switch to use platdata_auto_alloc_size for the driver data Bin Meng
2018-09-27 13:42   ` Simon Glass
2018-09-23 13:42 ` [U-Boot] [PATCH 08/27] efi_driver: " Bin Meng
2018-09-27 13:42   ` Simon Glass
2018-09-23 13:42 ` [U-Boot] [PATCH 09/27] blk: Call part_init() in the post_probe() method Bin Meng
2018-09-27 13:42   ` Simon Glass
2018-09-23 13:42 ` [U-Boot] [PATCH 10/27] blk: Drop blk_prepare_device() Bin Meng
2018-09-27 13:42   ` Simon Glass
2018-09-23 13:42 ` [U-Boot] [PATCH 11/27] blk: Make blk_next_free_devnum() public Bin Meng
2018-09-27 13:42   ` Simon Glass
2018-09-23 13:42 ` [U-Boot] [PATCH 12/27] blk: Introduce IF_TYPE_VIRTIO Bin Meng
2018-09-27 13:42   ` Simon Glass
2018-09-23 13:42 ` Bin Meng [this message]
2018-09-27 13:42   ` [U-Boot] [PATCH 13/27] virtio: Add block driver support Simon Glass
2018-09-27 22:12     ` Tuomas Tynkkynen
2018-09-23 13:42 ` [U-Boot] [PATCH 14/27] virtio: cmd: Add virtio command for virtio block devices Bin Meng
2018-09-27 13:42   ` Simon Glass
2018-09-23 13:42 ` [U-Boot] [PATCH 15/27] arm: qemu: Add a Kconfig in the board directory Bin Meng
2018-09-27 13:42   ` Simon Glass
2018-09-23 13:42 ` [U-Boot] [PATCH 16/27] arm: qemu: Enumerate virtio bus during early boot Bin Meng
2018-09-27 13:42   ` Simon Glass
2018-10-11 13:21     ` Bin Meng
2018-09-27 22:13   ` Tuomas Tynkkynen
2018-10-11 13:28     ` Bin Meng
2018-09-23 13:42 ` [U-Boot] [PATCH 17/27] riscv: " Bin Meng
2018-09-27 13:42   ` Simon Glass
2018-09-23 13:42 ` [U-Boot] [PATCH 18/27] riscv: qemu: Include some useful commands Bin Meng
2018-09-27 13:42   ` Simon Glass
2018-09-27 22:14   ` Tuomas Tynkkynen
2018-10-02 16:03     ` Bin Meng
2018-09-23 13:42 ` [U-Boot] [PATCH 19/27] kconfig: Introduce HAVE_ARCH_IOMAP Bin Meng
2018-09-27 13:42   ` Simon Glass
2018-09-23 13:42 ` [U-Boot] [PATCH 20/27] x86: Implement arch-specific io accessor routines Bin Meng
2018-09-27 13:42   ` Simon Glass
2018-10-11 13:33     ` Bin Meng
2018-09-23 13:42 ` [U-Boot] [PATCH 21/27] virtio: Add virtio over pci transport driver Bin Meng
2018-09-27 13:42   ` Simon Glass
2018-10-11 13:39     ` Bin Meng
2018-09-23 13:42 ` [U-Boot] [PATCH 22/27] x86: qemu: Imply virtio PCI transport and device drivers Bin Meng
2018-09-27 13:42   ` Simon Glass
2018-09-23 13:42 ` [U-Boot] [PATCH 23/27] dm: pci: Add APIs to find next capability and extended capability Bin Meng
2018-09-27 13:42   ` Simon Glass
2018-09-23 13:42 ` [U-Boot] [PATCH 24/27] test: dm: pci: Add cases for finding next PCI capability APIs Bin Meng
2018-09-27 13:42   ` Simon Glass
2018-09-23 13:42 ` [U-Boot] [PATCH 25/27] virtio: pci: Support non-legacy PCI transport device Bin Meng
2018-09-27 13:42   ` Simon Glass
2018-10-11 13:41     ` Bin Meng
2018-09-23 13:42 ` [U-Boot] [PATCH 26/27] virtio: net: Support non-legacy device Bin Meng
2018-09-27 13:43   ` Simon Glass
2018-10-15 21:59   ` Joe Hershberger
2018-09-23 13:42 ` [U-Boot] [PATCH 27/27] doc: Document virtio support Bin Meng
2018-09-27 13:43   ` Simon Glass
2018-09-27 13:43 ` [U-Boot] [PATCH 00/27] virtio: Introduce VirtIO driver support Simon Glass
2018-09-27 22:19   ` Tuomas Tynkkynen
2018-10-02 11:21     ` Simon Glass
2018-10-04  7:00       ` Bin Meng
2018-10-09 16:20         ` Simon Glass
2018-10-10 15:35           ` Bin Meng

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1537710145-1888-14-git-send-email-bmeng.cn@gmail.com \
    --to=bmeng.cn@gmail.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.