Commit b2210eb6 authored by Allen Pais's avatar Allen Pais Committed by Luis Henriques

sunvdc: compute vdisk geometry from capacity

commit de5b73f0 upstream.

The LDom diskserver doesn't return reliable geometry data. In addition,
the types for all fields in the vio_disk_geom are u16, which were being
truncated in the cast into the u8's of the Linux struct hd_geometry.

Modify vdc_getgeo() to compute the geometry from the disk's capacity in a
manner consistent with xen-blkfront::blkif_getgeo().
Signed-off-by: default avatarDwight Engen <dwight.engen@oracle.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarLuis Henriques <luis.henriques@canonical.com>
parent 39a83081
...@@ -70,7 +70,6 @@ struct vdc_port { ...@@ -70,7 +70,6 @@ struct vdc_port {
char disk_name[32]; char disk_name[32];
struct vio_disk_geom geom;
struct vio_disk_vtoc label; struct vio_disk_vtoc label;
}; };
...@@ -103,11 +102,15 @@ static inline u32 vdc_tx_dring_avail(struct vio_dring_state *dr) ...@@ -103,11 +102,15 @@ static inline u32 vdc_tx_dring_avail(struct vio_dring_state *dr)
static int vdc_getgeo(struct block_device *bdev, struct hd_geometry *geo) static int vdc_getgeo(struct block_device *bdev, struct hd_geometry *geo)
{ {
struct gendisk *disk = bdev->bd_disk; struct gendisk *disk = bdev->bd_disk;
struct vdc_port *port = disk->private_data; sector_t nsect = get_capacity(disk);
sector_t cylinders = nsect;
geo->heads = (u8) port->geom.num_hd; geo->heads = 0xff;
geo->sectors = (u8) port->geom.num_sec; geo->sectors = 0x3f;
geo->cylinders = port->geom.num_cyl; sector_div(cylinders, geo->heads * geo->sectors);
geo->cylinders = cylinders;
if ((sector_t)(geo->cylinders + 1) * geo->heads * geo->sectors < nsect)
geo->cylinders = 0xffff;
return 0; return 0;
} }
...@@ -714,16 +717,18 @@ static int probe_disk(struct vdc_port *port) ...@@ -714,16 +717,18 @@ static int probe_disk(struct vdc_port *port)
if (port->vdisk_size == -1) if (port->vdisk_size == -1)
return -ENODEV; return -ENODEV;
} else { } else {
struct vio_disk_geom geom;
err = generic_request(port, VD_OP_GET_DISKGEOM, err = generic_request(port, VD_OP_GET_DISKGEOM,
&port->geom, sizeof(port->geom)); &geom, sizeof(geom));
if (err < 0) { if (err < 0) {
printk(KERN_ERR PFX "VD_OP_GET_DISKGEOM returns " printk(KERN_ERR PFX "VD_OP_GET_DISKGEOM returns "
"error %d\n", err); "error %d\n", err);
return err; return err;
} }
port->vdisk_size = ((u64)port->geom.num_cyl * port->vdisk_size = ((u64)geom.num_cyl *
(u64)port->geom.num_hd * (u64)geom.num_hd *
(u64)port->geom.num_sec); (u64)geom.num_sec);
} }
q = blk_init_queue(do_vdc_request, &port->vio.lock); q = blk_init_queue(do_vdc_request, &port->vio.lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment