From f6f151a8e1ea49daaa7cfb9a703100eef1213289 Mon Sep 17 00:00:00 2001 From: wangyongrong Date: Mon, 3 Jun 2024 15:39:17 +0800 Subject: [PATCH] virtio-blk: add VIRTIO_BLK_F_BLK_SIZE feature Support configure the virtio block device block size to other value (default value is 512) Signed-off-by: wangyongrong --- drivers/virtio/virtio-blk.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/virtio/virtio-blk.c b/drivers/virtio/virtio-blk.c index 0e1d74e47ab..7301313fc7e 100644 --- a/drivers/virtio/virtio-blk.c +++ b/drivers/virtio/virtio-blk.c @@ -44,6 +44,7 @@ /* Block feature bits */ #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_FLUSH 9 /* Cache flush command support */ /* Block request type */ @@ -60,7 +61,8 @@ /* Block device sector size */ -#define VIRTIO_BLK_SECTOR_SIZE 512 +#define VIRTIO_BLK_SECTOR_BITS 9 +#define VIRTIO_BLK_SECTOR_SIZE (1UL << VIRTIO_BLK_SECTOR_BITS) /**************************************************************************** * Private Types @@ -117,6 +119,7 @@ struct virtio_blk_priv_s FAR struct virtio_blk_resp_s *resp; /* Virtio block in header */ mutex_t lock; /* Lock */ uint64_t nsectors; /* Sectore numbers */ + uint32_t block_size; /* Block size */ char name[NAME_MAX]; /* Device name */ }; @@ -250,7 +253,8 @@ static ssize_t virtio_blk_rdwr(FAR struct virtio_blk_priv_s *priv, priv->req->type = write ? VIRTIO_BLK_T_OUT : VIRTIO_BLK_T_IN; priv->req->reserved = 0; - priv->req->sector = startsector; + priv->req->sector = startsector * + priv->block_size >> VIRTIO_BLK_SECTOR_BITS; priv->resp->status = VIRTIO_BLK_S_IOERR; /* Fill the virtqueue buffer: @@ -262,7 +266,7 @@ static ssize_t virtio_blk_rdwr(FAR struct virtio_blk_priv_s *priv, vb[0].buf = priv->req; vb[0].len = VIRTIO_BLK_REQ_HEADER_SIZE; vb[1].buf = buffer; - vb[1].len = nsectors * VIRTIO_BLK_SECTOR_SIZE; + vb[1].len = nsectors * priv->block_size; vb[2].buf = priv->resp; vb[2].len = VIRTIO_BLK_RESP_HEADER_SIZE; readnum = write ? 2 : 1; @@ -392,7 +396,7 @@ static int virtio_blk_geometry(FAR struct inode *inode, geometry->geo_mediachanged = false; geometry->geo_writeenabled = true; geometry->geo_nsectors = priv->nsectors; - geometry->geo_sectorsize = VIRTIO_BLK_SECTOR_SIZE; + geometry->geo_sectorsize = priv->block_size; ret = OK; } @@ -528,6 +532,7 @@ static int virtio_blk_init(FAR struct virtio_blk_priv_s *priv, virtio_set_status(vdev, VIRTIO_CONFIG_STATUS_DRIVER); virtio_negotiate_features(vdev, (1UL << VIRTIO_BLK_F_RO) | + (1UL << VIRTIO_BLK_F_BLK_SIZE) | (1UL << VIRTIO_BLK_F_FLUSH)); virtio_set_status(vdev, VIRTIO_CONFIG_FEATURES_OK); @@ -601,6 +606,17 @@ static int virtio_blk_probe(FAR struct virtio_device *vdev) &priv->nsectors); vrtinfo("Virio blk capacity=%" PRIu64 " sectors\n", priv->nsectors); + if (virtio_has_feature(vdev, VIRTIO_BLK_F_BLK_SIZE)) + { + virtio_read_config_member(priv->vdev, struct virtio_blk_config_s, + blk_size, &priv->block_size); + vrtinfo("Virio blk block_size=%" PRIu32 "\n", priv->block_size); + } + else + { + priv->block_size = VIRTIO_BLK_SECTOR_SIZE; + } + /* Register block driver */ snprintf(priv->name, NAME_MAX, "/dev/virtblk%d", g_virtio_blk_idx);