@@ -807,6 +807,29 @@ int64_t bdrv_getlength(BlockDriverState *bs)
return drv->bdrv_getlength(bs);
}
+/**
+ * Maximum length of an I/O in sectors. Return -1 if not specified.
+ */
+void bdrv_get_max_sectors(BlockDriverState *bs, uint32_t *sectors_max)
+{
+ BlockDriver *drv = bs->drv;
+ if ((!drv) || (!drv->bdrv_get_max_sectors))
+ *sectors_max = -1;
+ else
+ *sectors_max = drv->bdrv_get_max_sectors(bs);
+}
+
+/**
+ * Check if the bdrv driver implements bdrv_get_max_sectors.
+ */
+int bdrv_uses_max_sectors(BlockDriverState *bs)
+{
+ BlockDriver *drv = bs->drv;
+ if ((drv) && (drv->bdrv_get_max_sectors))
+ return 1;
+ return 0;
+}
+
/* return 0 as number of sectors if no device present or error */
void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr)
{
@@ -79,6 +79,8 @@ int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
const void *buf, int count);
int bdrv_truncate(BlockDriverState *bs, int64_t offset);
int64_t bdrv_getlength(BlockDriverState *bs);
+void bdrv_get_max_sectors(BlockDriverState *bs, uint32_t *sectors_max);
+int bdrv_uses_max_sectors(BlockDriverState *bs);
void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads,
int *psecs);
int bdrv_commit(BlockDriverState *bs);
@@ -81,6 +81,7 @@ struct BlockDriver {
const char *protocol_name;
int (*bdrv_truncate)(BlockDriverState *bs, int64_t offset);
int64_t (*bdrv_getlength)(BlockDriverState *bs);
+ uint32_t (*bdrv_get_max_sectors)(BlockDriverState *bs);
int (*bdrv_write_compressed)(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors);
@@ -416,13 +416,16 @@ static void virtio_blk_update_config(VirtIODevice
*vdev, uint8_t *config)
struct virtio_blk_config blkcfg;
uint64_t capacity;
int cylinders, heads, secs;
+ uint32_t sectors_max;
bdrv_get_geometry(s->bs, &capacity);
bdrv_get_geometry_hint(s->bs, &cylinders, &heads, &secs);
+ bdrv_get_max_sectors(s->bs, §ors_max);
memset(&blkcfg, 0, sizeof(blkcfg));
stq_raw(&blkcfg.capacity, capacity);
stl_raw(&blkcfg.seg_max, 128 - 2);
stw_raw(&blkcfg.cylinders, cylinders);
+ stl_raw(&blkcfg.sectors_max, sectors_max);
blkcfg.heads = heads;
blkcfg.sectors = secs;
blkcfg.size_max = 0;
@@ -451,6 +454,9 @@ static uint32_t virtio_blk_get_features(VirtIODevice
*vdev)
if (bdrv_is_read_only(s->bs))
features |= 1 << VIRTIO_BLK_F_RO;
+ if (bdrv_uses_max_sectors(s->bs))
+ features |= 1 << VIRTIO_BLK_F_SECTOR_MAX;
+
return features;
}
@@ -494,7 +500,7 @@ VirtIODevice *virtio_blk_init(DeviceState *dev,
DriveInfo *dinfo)
static int virtio_blk_id;
char *ps = (char *)drive_get_serial(dinfo->bdrv);
size_t size = strlen(ps) ? sizeof(struct virtio_blk_config) :
- offsetof(struct virtio_blk_config, _blk_size);
+ offsetof(struct virtio_blk_config, identify);
s = (VirtIOBlock *)virtio_common_init("virtio-blk", VIRTIO_ID_BLOCK,
size,
@@ -32,6 +32,7 @@
#define VIRTIO_BLK_F_SCSI 7 /* Supports scsi command passthru
*/
#define VIRTIO_BLK_F_IDENTIFY 8 /* ATA IDENTIFY supported */
#define VIRTIO_BLK_F_WCACHE 9 /* write cache enabled */
+#define VIRTIO_BLK_F_SECTOR_MAX 10 /* Maximum total sectors in an I/O */
#define VIRTIO_BLK_ID_LEN 256 /* length of identify u16 array */