hw/block-common: Factor out fall back to legacy -drive cyls=...

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Markus Armbruster 2012-07-11 15:08:39 +02:00 committed by Kevin Wolf
parent 577d0a3807
commit b7eb0c9f95
6 changed files with 62 additions and 85 deletions

View File

@ -9,6 +9,7 @@
#include "blockdev.h" #include "blockdev.h"
#include "hw/block-common.h" #include "hw/block-common.h"
#include "qemu-error.h"
void blkconf_serial(BlockConf *conf, char **serial) void blkconf_serial(BlockConf *conf, char **serial)
{ {
@ -22,3 +23,42 @@ void blkconf_serial(BlockConf *conf, char **serial)
} }
} }
} }
int blkconf_geometry(BlockConf *conf, int *ptrans,
unsigned cyls_max, unsigned heads_max, unsigned secs_max)
{
DriveInfo *dinfo;
if (!conf->cyls && !conf->heads && !conf->secs) {
/* try to fall back to value set with legacy -drive cyls=... */
dinfo = drive_get_by_blockdev(conf->bs);
conf->cyls = dinfo->cyls;
conf->heads = dinfo->heads;
conf->secs = dinfo->secs;
if (ptrans) {
*ptrans = dinfo->trans;
}
}
if (!conf->cyls && !conf->heads && !conf->secs) {
hd_geometry_guess(conf->bs,
&conf->cyls, &conf->heads, &conf->secs,
ptrans);
} else if (ptrans && *ptrans == BIOS_ATA_TRANSLATION_AUTO) {
*ptrans = hd_bios_chs_auto_trans(conf->cyls, conf->heads, conf->secs);
}
if (conf->cyls || conf->heads || conf->secs) {
if (conf->cyls < 1 || conf->cyls > cyls_max) {
error_report("cyls must be between 1 and %u", cyls_max);
return -1;
}
if (conf->heads < 1 || conf->heads > heads_max) {
error_report("heads must be between 1 and %u", heads_max);
return -1;
}
if (conf->secs < 1 || conf->secs > secs_max) {
error_report("secs must be between 1 and %u", secs_max);
return -1;
}
}
return 0;
}

View File

@ -60,6 +60,8 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
/* Configuration helpers */ /* Configuration helpers */
void blkconf_serial(BlockConf *conf, char **serial); void blkconf_serial(BlockConf *conf, char **serial);
int blkconf_geometry(BlockConf *conf, int *trans,
unsigned cyls_max, unsigned heads_max, unsigned secs_max);
/* Hard disk geometry */ /* Hard disk geometry */

View File

@ -1935,18 +1935,6 @@ int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
s->drive_kind = kind; s->drive_kind = kind;
bdrv_get_geometry(bs, &nb_sectors); bdrv_get_geometry(bs, &nb_sectors);
if (cylinders < 1 || cylinders > 65535) {
error_report("cyls must be between 1 and 65535");
return -1;
}
if (heads < 1 || heads > 16) {
error_report("heads must be between 1 and 16");
return -1;
}
if (secs < 1 || secs > 255) {
error_report("secs must be between 1 and 255");
return -1;
}
s->cylinders = cylinders; s->cylinders = cylinders;
s->heads = heads; s->heads = heads;
s->sectors = secs; s->sectors = secs;
@ -2094,6 +2082,18 @@ void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0,
} else if (trans == BIOS_ATA_TRANSLATION_AUTO) { } else if (trans == BIOS_ATA_TRANSLATION_AUTO) {
trans = hd_bios_chs_auto_trans(cyls, heads, secs); trans = hd_bios_chs_auto_trans(cyls, heads, secs);
} }
if (cyls < 1 || cyls > 65535) {
error_report("cyls must be between 1 and 65535");
exit(1);
}
if (heads < 1 || heads > 16) {
error_report("heads must be between 1 and 16");
exit(1);
}
if (secs < 1 || secs > 255) {
error_report("secs must be between 1 and 255");
exit(1);
}
if (ide_init_drive(&bus->ifs[i], dinfo->bdrv, if (ide_init_drive(&bus->ifs[i], dinfo->bdrv,
dinfo->media_cd ? IDE_CD : IDE_HD, dinfo->media_cd ? IDE_CD : IDE_HD,
NULL, dinfo->serial, NULL, 0, NULL, dinfo->serial, NULL, 0,

View File

@ -142,7 +142,6 @@ static int ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind)
{ {
IDEBus *bus = DO_UPCAST(IDEBus, qbus, dev->qdev.parent_bus); IDEBus *bus = DO_UPCAST(IDEBus, qbus, dev->qdev.parent_bus);
IDEState *s = bus->ifs + dev->unit; IDEState *s = bus->ifs + dev->unit;
DriveInfo *dinfo;
if (dev->conf.discard_granularity && dev->conf.discard_granularity != 512) { if (dev->conf.discard_granularity && dev->conf.discard_granularity != 512) {
error_report("discard_granularity must be 512 for ide"); error_report("discard_granularity must be 512 for ide");
@ -150,22 +149,8 @@ static int ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind)
} }
blkconf_serial(&dev->conf, &dev->serial); blkconf_serial(&dev->conf, &dev->serial);
if (blkconf_geometry(&dev->conf, &dev->chs_trans, 65536, 16, 255) < 0) {
if (!dev->conf.cyls && !dev->conf.heads && !dev->conf.secs) { return -1;
/* try to fall back to value set with legacy -drive cyls=... */
dinfo = drive_get_by_blockdev(dev->conf.bs);
dev->conf.cyls = dinfo->cyls;
dev->conf.heads = dinfo->heads;
dev->conf.secs = dinfo->secs;
dev->chs_trans = dinfo->trans;
}
if (!dev->conf.cyls && !dev->conf.heads && !dev->conf.secs) {
hd_geometry_guess(dev->conf.bs,
&dev->conf.cyls, &dev->conf.heads, &dev->conf.secs,
&dev->chs_trans);
} else if (dev->chs_trans == BIOS_ATA_TRANSLATION_AUTO) {
dev->chs_trans = hd_bios_chs_auto_trans(dev->conf.cyls,
dev->conf.heads, dev->conf.secs);
} }
if (ide_init_drive(s, dev->conf.bs, kind, if (ide_init_drive(s, dev->conf.bs, kind,

View File

@ -1737,7 +1737,6 @@ static void scsi_disk_unit_attention_reported(SCSIDevice *dev)
static int scsi_initfn(SCSIDevice *dev) static int scsi_initfn(SCSIDevice *dev)
{ {
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
DriveInfo *dinfo;
if (!s->qdev.conf.bs) { if (!s->qdev.conf.bs) {
error_report("drive property not set"); error_report("drive property not set");
@ -1750,34 +1749,10 @@ static int scsi_initfn(SCSIDevice *dev)
return -1; 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;
}
}
blkconf_serial(&s->qdev.conf, &s->serial); blkconf_serial(&s->qdev.conf, &s->serial);
if (blkconf_geometry(&dev->conf, NULL, 65535, 255, 255) < 0) {
return -1;
}
if (!s->version) { if (!s->version) {
s->version = g_strdup(qemu_get_version()); s->version = g_strdup(qemu_get_version());

View File

@ -589,7 +589,6 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, VirtIOBlkConf *blk)
{ {
VirtIOBlock *s; VirtIOBlock *s;
static int virtio_blk_id; static int virtio_blk_id;
DriveInfo *dinfo;
if (!blk->conf.bs) { if (!blk->conf.bs) {
error_report("drive property not set"); error_report("drive property not set");
@ -601,6 +600,9 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, VirtIOBlkConf *blk)
} }
blkconf_serial(&blk->conf, &blk->serial); blkconf_serial(&blk->conf, &blk->serial);
if (blkconf_geometry(&blk->conf, NULL, 65535, 255, 255) < 0) {
return NULL;
}
s = (VirtIOBlock *)virtio_common_init("virtio-blk", VIRTIO_ID_BLOCK, s = (VirtIOBlock *)virtio_common_init("virtio-blk", VIRTIO_ID_BLOCK,
sizeof(struct virtio_blk_config), sizeof(struct virtio_blk_config),
@ -615,33 +617,6 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, VirtIOBlkConf *blk)
s->rq = NULL; s->rq = NULL;
s->sector_mask = (s->conf->logical_block_size / BDRV_SECTOR_SIZE) - 1; s->sector_mask = (s->conf->logical_block_size / BDRV_SECTOR_SIZE) - 1;
if (!blk->conf.cyls && !blk->conf.heads && !blk->conf.secs) {
/* try to fall back to value set with legacy -drive cyls=... */
dinfo = drive_get_by_blockdev(blk->conf.bs);
blk->conf.cyls = dinfo->cyls;
blk->conf.heads = dinfo->heads;
blk->conf.secs = dinfo->secs;
}
if (!blk->conf.cyls && !blk->conf.heads && !blk->conf.secs) {
hd_geometry_guess(s->bs,
&blk->conf.cyls, &blk->conf.heads, &blk->conf.secs,
NULL);
}
if (blk->conf.cyls || blk->conf.heads || blk->conf.secs) {
if (blk->conf.cyls < 1 || blk->conf.cyls > 65535) {
error_report("cyls must be between 1 and 65535");
return NULL;
}
if (blk->conf.heads < 1 || blk->conf.heads > 255) {
error_report("heads must be between 1 and 255");
return NULL;
}
if (blk->conf.secs < 1 || blk->conf.secs > 255) {
error_report("secs must be between 1 and 255");
return NULL;
}
}
s->vq = virtio_add_queue(&s->vdev, 128, virtio_blk_handle_output); s->vq = virtio_add_queue(&s->vdev, 128, virtio_blk_handle_output);
qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s); qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s);