From 99874e8cedc6c0aad950a9a4ecf70734567f1028 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 27 Aug 2012 13:43:14 -0300 Subject: [RHEL6 qemu-kvm PATCH 4/5] ide: Adds wwn=hex qdev option RH-Author: Paolo Bonzini Message-id: <1346074994-12293-3-git-send-email-pbonzini@redhat.com> Patchwork-id: 41336 O-Subject: [RHEL 6.4 qemu-kvm PATCH 2/2] ide: Adds wwn=hex qdev option Bugzilla: 831102 RH-Acked-by: Laszlo Ersek RH-Acked-by: Miroslav Rezanina RH-Acked-by: Alex Williamson From: Floris Bos Bugzilla: 831102 Allow the user to specify a disk's World Wide Name. Linux guests can address disks by their unique World Wide Name number (e.g. /dev/disk/by-id/wwn-0x5001517959123522). This patch adds support for assigning a World Wide Name number to a virtual IDE disk. Cc: kwolf@redhat.com Signed-off-by: Floris Bos Signed-off-by: Kevin Wolf (cherry picked from commit 95ebda85e09ed2b7f00deb2adbdafa5ccf5db948) Conflicts: hw/ide/core.c hw/ide/internal.h hw/ide/qdev.c --- hw/ide/core.c | 29 +++++++++++++++++++++++------ hw/ide/internal.h | 5 ++++- hw/ide/qdev.c | 3 ++- 3 file modificati, 29 inserzioni(+), 8 rimozioni(-) Signed-off-by: Eduardo Habkost --- hw/ide/core.c | 29 +++++++++++++++++++++++------ hw/ide/internal.h | 5 ++++- hw/ide/qdev.c | 3 ++- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/hw/ide/core.c b/hw/ide/core.c index 0eb1da1..74e7831 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -119,8 +119,12 @@ static void ide_identify(IDEState *s) put_le16(p + 82, (1 << 14) | 1); /* 13=flush_cache_ext,12=flush_cache,10=lba48 */ put_le16(p + 83, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10)); - /* 14=set to 1, 1=SMART self test, 0=SMART error logging */ - put_le16(p + 84, (1 << 14) | 0); + /* 14=set to 1, 8=has WWN, 1=SMART self test, 0=SMART error logging */ + if (s->wwn) { + put_le16(p + 84, (1 << 14) | (1 << 8) | 0); + } else { + put_le16(p + 84, (1 << 14) | 0); + } /* 14 = NOP supported, 5=WCACHE enabled, 0=SMART feature set enabled */ if (bdrv_enable_write_cache(s->bs)) put_le16(p + 85, (1 << 14) | (1 << 5) | 1); @@ -128,8 +132,12 @@ static void ide_identify(IDEState *s) put_le16(p + 85, (1 << 14) | 1); /* 13=flush_cache_ext,12=flush_cache,10=lba48 */ put_le16(p + 86, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10)); - /* 14=set to 1, 1=smart self test, 0=smart error logging */ - put_le16(p + 87, (1 << 14) | 0); + /* 14=set to 1, 8=has WWN, 1=SMART self test, 0=SMART error logging */ + if (s->wwn) { + put_le16(p + 87, (1 << 14) | (1 << 8) | 0); + } else { + put_le16(p + 87, (1 << 14) | 0); + } put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */ put_le16(p + 93, 1 | (1 << 14) | 0x2000); put_le16(p + 100, s->nb_sectors); @@ -139,6 +147,13 @@ static void ide_identify(IDEState *s) dev = s->unit ? s->bus->slave : s->bus->master; if (dev && dev->conf.physical_block_size) put_le16(p + 106, 0x6000 | get_physical_block_exp(&dev->conf)); + if (s->wwn) { + /* LE 16-bit words 111-108 contain 64-bit World Wide Name */ + put_le16(p + 108, s->wwn >> 48); + put_le16(p + 109, s->wwn >> 32); + put_le16(p + 110, s->wwn >> 16); + put_le16(p + 111, s->wwn); + } memcpy(s->identify_data, p, sizeof(s->identify_data)); s->identify_set = 1; @@ -1853,7 +1868,8 @@ static const BlockDevOps ide_cd_block_ops = { .is_medium_locked = ide_cd_is_medium_locked, }; -int ide_init_drive(IDEState *s, BlockDriverState *bs, const char *version) +int ide_init_drive(IDEState *s, BlockDriverState *bs, const char *version, + uint64_t wwn) { int cylinders, heads, secs; uint64_t nb_sectors; @@ -1877,6 +1893,7 @@ int ide_init_drive(IDEState *s, BlockDriverState *bs, const char *version) s->heads = heads; s->sectors = secs; s->nb_sectors = nb_sectors; + s->wwn = wwn; /* The SMART values should be preserved across power cycles but they aren't. */ s->smart_enabled = 1; @@ -1952,7 +1969,7 @@ void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0, dinfo = i == 0 ? hd0 : hd1; ide_init1(bus, i); if (dinfo) { - if (ide_init_drive(&bus->ifs[i], dinfo->bdrv, NULL) < 0) { + if (ide_init_drive(&bus->ifs[i], dinfo->bdrv, NULL, 0) < 0) { error_report("Can't set up IDE drive %s", dinfo->id); exit(1); } diff --git a/hw/ide/internal.h b/hw/ide/internal.h index d0bfc7d..83ae6f0 100644 --- a/hw/ide/internal.h +++ b/hw/ide/internal.h @@ -399,6 +399,7 @@ struct IDEState { uint8_t identify_data[512]; int drive_serial; char drive_serial_str[21]; + uint64_t wwn; /* ide regs */ uint8_t feature; uint8_t error; @@ -485,6 +486,7 @@ struct IDEDevice { uint32_t unit; BlockConf conf; char *version; + uint64_t wwn; }; typedef int (*ide_qdev_initfn)(IDEDevice *dev); @@ -596,7 +598,8 @@ uint32_t ide_data_readw(void *opaque, uint32_t addr); void ide_data_writel(void *opaque, uint32_t addr, uint32_t val); uint32_t ide_data_readl(void *opaque, uint32_t addr); -int ide_init_drive(IDEState *s, BlockDriverState *bs, const char *version); +int ide_init_drive(IDEState *s, BlockDriverState *bs, const char *version, + uint64_t wwn); void ide_init2(IDEBus *bus, qemu_irq irq); void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0, DriveInfo *hd1, qemu_irq irq); diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c index 703de84..247f879 100644 --- a/hw/ide/qdev.c +++ b/hw/ide/qdev.c @@ -113,7 +113,7 @@ static int ide_drive_initfn(IDEDevice *dev) { IDEBus *bus = DO_UPCAST(IDEBus, qbus, dev->qdev.parent_bus); - if (ide_init_drive(bus->ifs + dev->unit, dev->conf.bs, dev->version) < 0) { + if (ide_init_drive(bus->ifs + dev->unit, dev->conf.bs, dev->version, dev->wwn) < 0) { return -1; } @@ -132,6 +132,7 @@ static IDEDeviceInfo ide_drive_info = { DEFINE_PROP_UINT32("unit", IDEDrive, dev.unit, -1), DEFINE_BLOCK_PROPERTIES(IDEDrive, dev.conf), DEFINE_PROP_STRING("ver", IDEDrive, dev.version), + DEFINE_PROP_HEX64("wwn", IDEDrive, dev.wwn, 0), DEFINE_PROP_END_OF_LIST(), } }; -- 1.7.11.4