aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/virtio_blk.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 78be6b8c89e0..84e064ffee52 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -157,10 +157,25 @@ static int virtblk_ioctl(struct inode *inode, struct file *filp,
157/* We provide getgeo only to please some old bootloader/partitioning tools */ 157/* We provide getgeo only to please some old bootloader/partitioning tools */
158static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo) 158static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo)
159{ 159{
160 /* some standard values, similar to sd */ 160 struct virtio_blk *vblk = bd->bd_disk->private_data;
161 geo->heads = 1 << 6; 161 struct virtio_blk_geometry vgeo;
162 geo->sectors = 1 << 5; 162 int err;
163 geo->cylinders = get_capacity(bd->bd_disk) >> 11; 163
164 /* see if the host passed in geometry config */
165 err = virtio_config_val(vblk->vdev, VIRTIO_BLK_F_GEOMETRY,
166 offsetof(struct virtio_blk_config, geometry),
167 &vgeo);
168
169 if (!err) {
170 geo->heads = vgeo.heads;
171 geo->sectors = vgeo.sectors;
172 geo->cylinders = vgeo.cylinders;
173 } else {
174 /* some standard values, similar to sd */
175 geo->heads = 1 << 6;
176 geo->sectors = 1 << 5;
177 geo->cylinders = get_capacity(bd->bd_disk) >> 11;
178 }
164 return 0; 179 return 0;
165} 180}
166 181
@@ -310,6 +325,7 @@ static struct virtio_device_id id_table[] = {
310 325
311static unsigned int features[] = { 326static unsigned int features[] = {
312 VIRTIO_BLK_F_BARRIER, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, 327 VIRTIO_BLK_F_BARRIER, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX,
328 VIRTIO_BLK_F_GEOMETRY,
313}; 329};
314 330
315static struct virtio_driver virtio_blk = { 331static struct virtio_driver virtio_blk = {