[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 19/32] scsi-hd: qdev properties for disk geometry
From: |
Markus Armbruster |
Subject: |
[Qemu-devel] [PATCH 19/32] scsi-hd: qdev properties for disk geometry |
Date: |
Fri, 6 Jul 2012 08:57:57 +0200 |
Geometry needs to be qdev properties, because it belongs to the
disk's guest part.
Maintain backward compatibility exactly like for serial: fall back to
DriveInfo's geometry, set with -drive cyls=...
Do this only for scsi-hd. scsi-disk is legacy. scsi-cd doesn't have
a geometry. scsi-block should get geometry from the host disk.
Bonus: info qtree now shows the geometry.
Signed-off-by: Markus Armbruster <address@hidden>
---
hw/scsi-disk.c | 69 +++++++++++++++++++++++++++++++++++++------------------
1 files changed, 46 insertions(+), 23 deletions(-)
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index bb758f2..b48a4fa 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -925,9 +925,6 @@ static int mode_sense_page(SCSIDiskState *s, int page,
uint8_t **p_outbuf,
[MODE_PAGE_AUDIO_CTL] = (1 << TYPE_ROM),
[MODE_PAGE_CAPABILITIES] = (1 << TYPE_ROM),
};
-
- BlockDriverState *bdrv = s->qdev.conf.bs;
- uint32_t cylinders, heads, secs;
uint8_t *p = *p_outbuf;
if ((mode_sense_valid[page] & (1 << s->qdev.type)) == 0) {
@@ -949,19 +946,18 @@ static int mode_sense_page(SCSIDiskState *s, int page,
uint8_t **p_outbuf,
break;
}
/* if a geometry hint is available, use it */
- hd_geometry_guess(bdrv, &cylinders, &heads, &secs, NULL);
- p[2] = (cylinders >> 16) & 0xff;
- p[3] = (cylinders >> 8) & 0xff;
- p[4] = cylinders & 0xff;
- p[5] = heads & 0xff;
+ p[2] = (s->qdev.conf.cyls >> 16) & 0xff;
+ p[3] = (s->qdev.conf.cyls >> 8) & 0xff;
+ p[4] = s->qdev.conf.cyls & 0xff;
+ p[5] = s->qdev.conf.heads & 0xff;
/* Write precomp start cylinder, disabled */
- p[6] = (cylinders >> 16) & 0xff;
- p[7] = (cylinders >> 8) & 0xff;
- p[8] = cylinders & 0xff;
+ p[6] = (s->qdev.conf.cyls >> 16) & 0xff;
+ p[7] = (s->qdev.conf.cyls >> 8) & 0xff;
+ p[8] = s->qdev.conf.cyls & 0xff;
/* Reduced current start cylinder, disabled */
- p[9] = (cylinders >> 16) & 0xff;
- p[10] = (cylinders >> 8) & 0xff;
- p[11] = cylinders & 0xff;
+ p[9] = (s->qdev.conf.cyls >> 16) & 0xff;
+ p[10] = (s->qdev.conf.cyls >> 8) & 0xff;
+ p[11] = s->qdev.conf.cyls & 0xff;
/* Device step rate [ns], 200ns */
p[12] = 0;
p[13] = 200;
@@ -983,18 +979,17 @@ static int mode_sense_page(SCSIDiskState *s, int page,
uint8_t **p_outbuf,
p[2] = 5000 >> 8;
p[3] = 5000 & 0xff;
/* if a geometry hint is available, use it */
- hd_geometry_guess(bdrv, &cylinders, &heads, &secs, NULL);
- p[4] = heads & 0xff;
- p[5] = secs & 0xff;
+ p[4] = s->qdev.conf.heads & 0xff;
+ p[5] = s->qdev.conf.secs & 0xff;
p[6] = s->qdev.blocksize >> 8;
- p[8] = (cylinders >> 8) & 0xff;
- p[9] = cylinders & 0xff;
+ p[8] = (s->qdev.conf.cyls >> 8) & 0xff;
+ p[9] = s->qdev.conf.cyls & 0xff;
/* Write precomp start cylinder, disabled */
- p[10] = (cylinders >> 8) & 0xff;
- p[11] = cylinders & 0xff;
+ p[10] = (s->qdev.conf.cyls >> 8) & 0xff;
+ p[11] = s->qdev.conf.cyls & 0xff;
/* Reduced current start cylinder, disabled */
- p[12] = (cylinders >> 8) & 0xff;
- p[13] = cylinders & 0xff;
+ p[12] = (s->qdev.conf.cyls >> 8) & 0xff;
+ p[13] = s->qdev.conf.cyls & 0xff;
/* Device step rate [100us], 100us */
p[14] = 0;
p[15] = 1;
@@ -1707,6 +1702,33 @@ static int scsi_initfn(SCSIDevice *dev)
return -1;
}
+ if (!dev->conf.cyls && !dev->conf.heads && !dev->conf.secs) {
+ /* try to fall back to value set with legacy -drive cyls=... */
+ dinfo = drive_get_by_blockdev(s->qdev.conf.bs);
+ dev->conf.cyls = dinfo->cyls;
+ dev->conf.heads = dinfo->heads;
+ dev->conf.secs = dinfo->secs;
+ }
+ if (!dev->conf.cyls && !dev->conf.heads && !dev->conf.secs) {
+ hd_geometry_guess(s->qdev.conf.bs,
+ &dev->conf.cyls, &dev->conf.heads, &dev->conf.secs,
+ NULL);
+ }
+ if (dev->conf.cyls || dev->conf.heads || dev->conf.secs) {
+ if (dev->conf.cyls < 1 || dev->conf.cyls > 65535) {
+ error_report("cyls must be between 1 and 65535");
+ return -1;
+ }
+ if (dev->conf.heads < 1 || dev->conf.heads > 255) {
+ error_report("heads must be between 1 and 255");
+ return -1;
+ }
+ if (dev->conf.secs < 1 || dev->conf.secs > 255) {
+ error_report("secs must be between 1 and 255");
+ return -1;
+ }
+ }
+
if (!s->serial) {
/* try to fall back to value set with legacy -drive serial=... */
dinfo = drive_get_by_blockdev(s->qdev.conf.bs);
@@ -1926,6 +1948,7 @@ static Property scsi_hd_properties[] = {
SCSI_DISK_F_REMOVABLE, false),
DEFINE_PROP_BIT("dpofua", SCSIDiskState, features,
SCSI_DISK_F_DPOFUA, false),
+ DEFINE_BLOCK_CHS_PROPERTIES(SCSIDiskState, qdev.conf),
DEFINE_PROP_END_OF_LIST(),
};
--
1.7.6.5
- [Qemu-devel] [PATCH 00/32] Disk geometry cleanup, Markus Armbruster, 2012/07/06
- [Qemu-devel] [PATCH 16/32] blockdev: Save geometry in DriveInfo, Markus Armbruster, 2012/07/06
- [Qemu-devel] [PATCH 10/32] hd-geometry: Unnest conditional in hd_geometry_guess(), Markus Armbruster, 2012/07/06
- [Qemu-devel] [PATCH 14/32] hd-geometry: Cut out block layer translation middleman, Markus Armbruster, 2012/07/06
- [Qemu-devel] [PATCH 19/32] scsi-hd: qdev properties for disk geometry,
Markus Armbruster <=
- [Qemu-devel] [PATCH 13/32] hd-geometry: Clean up confusing use of prior translation hint, Markus Armbruster, 2012/07/06
- [Qemu-devel] [PATCH 04/32] vvfat: Do not clobber the user's geometry, Markus Armbruster, 2012/07/06
- [Qemu-devel] [PATCH 05/32] qtest: Tidy up temporary files properly, Markus Armbruster, 2012/07/06
- [Qemu-devel] [PATCH 06/32] qtest: Add hard disk geometry test, Markus Armbruster, 2012/07/06
- [Qemu-devel] [PATCH 11/32] hd-geometry: Factor out guess_chs_for_size(), Markus Armbruster, 2012/07/06
- [Qemu-devel] [PATCH 22/32] qtest: Cover qdev properties for disk geometry, Markus Armbruster, 2012/07/06
- [Qemu-devel] [PATCH 03/32] vvfat: Fix partition table, Markus Armbruster, 2012/07/06