Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit de5b73f0 authored by Allen Pais's avatar Allen Pais Committed by David S. Miller
Browse files

sunvdc: compute vdisk geometry from capacity



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>
parent 9bce2182
Loading
Loading
Loading
Loading
+14 −9
Original line number Diff line number Diff line
@@ -70,7 +70,6 @@ struct vdc_port {

	char			disk_name[32];

	struct vio_disk_geom	geom;
	struct vio_disk_vtoc	label;
};

@@ -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)
{
	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->sectors = (u8) port->geom.num_sec;
	geo->cylinders = port->geom.num_cyl;
	geo->heads = 0xff;
	geo->sectors = 0x3f;
	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;
}
@@ -714,16 +717,18 @@ static int probe_disk(struct vdc_port *port)
		if (port->vdisk_size == -1)
			return -ENODEV;
	} else {
		struct vio_disk_geom geom;

		err = generic_request(port, VD_OP_GET_DISKGEOM,
				      &port->geom, sizeof(port->geom));
				      &geom, sizeof(geom));
		if (err < 0) {
			printk(KERN_ERR PFX "VD_OP_GET_DISKGEOM returns "
			       "error %d\n", err);
			return err;
		}
		port->vdisk_size = ((u64)port->geom.num_cyl *
				    (u64)port->geom.num_hd *
				    (u64)port->geom.num_sec);
		port->vdisk_size = ((u64)geom.num_cyl *
				    (u64)geom.num_hd *
				    (u64)geom.num_sec);
	}

	q = blk_init_queue(do_vdc_request, &port->vio.lock);