Skip to content

Commit

Permalink
hw/block-common: Factor out fall back to legacy -drive cyls=...
Browse files Browse the repository at this point in the history
Signed-off-by: Markus Armbruster <[email protected]>
Signed-off-by: Kevin Wolf <[email protected]>
  • Loading branch information
Markus Armbruster authored and kevmw committed Jul 17, 2012
1 parent 577d0a3 commit b7eb0c9
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 85 deletions.
40 changes: 40 additions & 0 deletions hw/block-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include "blockdev.h"
#include "hw/block-common.h"
#include "qemu-error.h"

void blkconf_serial(BlockConf *conf, char **serial)
{
Expand All @@ -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;
}
2 changes: 2 additions & 0 deletions hw/block-common.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
/* Configuration helpers */

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 */

Expand Down
24 changes: 12 additions & 12 deletions hw/ide/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1935,18 +1935,6 @@ int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
s->drive_kind = kind;

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->heads = heads;
s->sectors = secs;
Expand Down Expand Up @@ -2094,6 +2082,18 @@ void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0,
} else if (trans == BIOS_ATA_TRANSLATION_AUTO) {
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,
dinfo->media_cd ? IDE_CD : IDE_HD,
NULL, dinfo->serial, NULL, 0,
Expand Down
19 changes: 2 additions & 17 deletions hw/ide/qdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,30 +142,15 @@ static int ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind)
{
IDEBus *bus = DO_UPCAST(IDEBus, qbus, dev->qdev.parent_bus);
IDEState *s = bus->ifs + dev->unit;
DriveInfo *dinfo;

if (dev->conf.discard_granularity && dev->conf.discard_granularity != 512) {
error_report("discard_granularity must be 512 for ide");
return -1;
}

blkconf_serial(&dev->conf, &dev->serial);

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(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 (blkconf_geometry(&dev->conf, &dev->chs_trans, 65536, 16, 255) < 0) {
return -1;
}

if (ide_init_drive(s, dev->conf.bs, kind,
Expand Down
31 changes: 3 additions & 28 deletions hw/scsi-disk.c
Original file line number Diff line number Diff line change
Expand Up @@ -1737,7 +1737,6 @@ static void scsi_disk_unit_attention_reported(SCSIDevice *dev)
static int scsi_initfn(SCSIDevice *dev)
{
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
DriveInfo *dinfo;

if (!s->qdev.conf.bs) {
error_report("drive property not set");
Expand All @@ -1750,34 +1749,10 @@ 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;
}
}

blkconf_serial(&s->qdev.conf, &s->serial);
if (blkconf_geometry(&dev->conf, NULL, 65535, 255, 255) < 0) {
return -1;
}

if (!s->version) {
s->version = g_strdup(qemu_get_version());
Expand Down
31 changes: 3 additions & 28 deletions hw/virtio-blk.c
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,6 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, VirtIOBlkConf *blk)
{
VirtIOBlock *s;
static int virtio_blk_id;
DriveInfo *dinfo;

if (!blk->conf.bs) {
error_report("drive property not set");
Expand All @@ -601,6 +600,9 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, VirtIOBlkConf *blk)
}

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,
sizeof(struct virtio_blk_config),
Expand All @@ -615,33 +617,6 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, VirtIOBlkConf *blk)
s->rq = NULL;
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);

qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s);
Expand Down

0 comments on commit b7eb0c9

Please sign in to comment.