aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/block/virtio_blk.c24
-rw-r--r--include/linux/virtio_blk.h7
2 files changed, 27 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 = {
diff --git a/include/linux/virtio_blk.h b/include/linux/virtio_blk.h
index c75a9e82b924..d4695a3356d0 100644
--- a/include/linux/virtio_blk.h
+++ b/include/linux/virtio_blk.h
@@ -9,6 +9,7 @@
9#define VIRTIO_BLK_F_BARRIER 0 /* Does host support barriers? */ 9#define VIRTIO_BLK_F_BARRIER 0 /* Does host support barriers? */
10#define VIRTIO_BLK_F_SIZE_MAX 1 /* Indicates maximum segment size */ 10#define VIRTIO_BLK_F_SIZE_MAX 1 /* Indicates maximum segment size */
11#define VIRTIO_BLK_F_SEG_MAX 2 /* Indicates maximum # of segments */ 11#define VIRTIO_BLK_F_SEG_MAX 2 /* Indicates maximum # of segments */
12#define VIRTIO_BLK_F_GEOMETRY 4 /* Legacy geometry available */
12 13
13struct virtio_blk_config 14struct virtio_blk_config
14{ 15{
@@ -18,6 +19,12 @@ struct virtio_blk_config
18 __le32 size_max; 19 __le32 size_max;
19 /* The maximum number of segments (if VIRTIO_BLK_F_SEG_MAX) */ 20 /* The maximum number of segments (if VIRTIO_BLK_F_SEG_MAX) */
20 __le32 seg_max; 21 __le32 seg_max;
22 /* geometry the device (if VIRTIO_BLK_F_GEOMETRY) */
23 struct virtio_blk_geometry {
24 __le16 cylinders;
25 __u8 heads;
26 __u8 sectors;
27 } geometry;
21} __attribute__((packed)); 28} __attribute__((packed));
22 29
23/* These two define direction. */ 30/* These two define direction. */