diff mbox

[3/3] ide: Adds wwn=hex qdev option allowing the user to specify a disk's World Wide Name

Message ID 1331582711-12647-3-git-send-email-bos@je-eigen-domein.nl
State New
Headers show

Commit Message

Floris Bos March 12, 2012, 8:05 p.m. UTC
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 <dev@noc-ps.com>
---
 hw/ide/core.c     |   13 +++++++++++--
 hw/ide/internal.h |    5 ++++-
 hw/ide/qdev.c     |    3 ++-
 3 files changed, 17 insertions(+), 4 deletions(-)

Comments

Stefan Hajnoczi March 13, 2012, 10:29 a.m. UTC | #1
On Mon, Mar 12, 2012 at 8:05 PM, Floris Bos <bos@je-eigen-domein.nl> wrote:
> diff --git a/hw/ide/core.c b/hw/ide/core.c
> index 3e50c52..b48e5c2 100644
> --- a/hw/ide/core.c
> +++ b/hw/ide/core.c
> @@ -166,6 +166,13 @@ static void ide_identify(IDEState *s)
>     if (dev && dev->conf.discard_granularity) {
>         put_le16(p + 169, 1); /* TRIM support */
>     }
> +
> +    if (s->wwn) {
> +        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);
> +    }

Little-endian 16-bit seems weird at first but the spec requires it, so
it's fine.  A comment would be nice.

ATA8-ACS says:

"Bit 8 of word 84 shall be set to one indicating the mandatory World
Wide Name in words 108-111 is supported."

I think we're missing this.
Kevin Wolf March 13, 2012, 12:06 p.m. UTC | #2
Am 13.03.2012 11:29, schrieb Stefan Hajnoczi:
> On Mon, Mar 12, 2012 at 8:05 PM, Floris Bos <bos@je-eigen-domein.nl> wrote:
>> diff --git a/hw/ide/core.c b/hw/ide/core.c
>> index 3e50c52..b48e5c2 100644
>> --- a/hw/ide/core.c
>> +++ b/hw/ide/core.c
>> @@ -166,6 +166,13 @@ static void ide_identify(IDEState *s)
>>     if (dev && dev->conf.discard_granularity) {
>>         put_le16(p + 169, 1); /* TRIM support */
>>     }
>> +
>> +    if (s->wwn) {
>> +        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);
>> +    }
> 
> Little-endian 16-bit seems weird at first but the spec requires it, so
> it's fine.  A comment would be nice.
> 
> ATA8-ACS says:
> 
> "Bit 8 of word 84 shall be set to one indicating the mandatory World
> Wide Name in words 108-111 is supported."
> 
> I think we're missing this.

And this:

"Bit 8 of word 87 is a copy of word 84 bit 8."

Otherwise the series looks good to me.

Kevin
Floris Bos March 13, 2012, 12:29 p.m. UTC | #3
On 03/13/2012 01:06 PM, Kevin Wolf wrote:
> Am 13.03.2012 11:29, schrieb Stefan Hajnoczi:
>> On Mon, Mar 12, 2012 at 8:05 PM, Floris Bos<bos@je-eigen-domein.nl>  wrote:
>>> diff --git a/hw/ide/core.c b/hw/ide/core.c
>>> index 3e50c52..b48e5c2 100644
>>> --- a/hw/ide/core.c
>>> +++ b/hw/ide/core.c
>>> @@ -166,6 +166,13 @@ static void ide_identify(IDEState *s)
>>>      if (dev&&  dev->conf.discard_granularity) {
>>>          put_le16(p + 169, 1); /* TRIM support */
>>>      }
>>> +
>>> +    if (s->wwn) {
>>> +        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);
>>> +    }
>> Little-endian 16-bit seems weird at first but the spec requires it, so
>> it's fine.  A comment would be nice.
>>
>> ATA8-ACS says:
>>
>> "Bit 8 of word 84 shall be set to one indicating the mandatory World
>> Wide Name in words 108-111 is supported."
>>
>> I think we're missing this.
> And this:
>
> "Bit 8 of word 87 is a copy of word 84 bit 8."
>
> Otherwise the series looks good to me.
>
> Kevin

Oops, you are right, overlooked those bits.
Linux only seems to care that the WWN starts with a 5, and doesn't look 
at the bits, so it didn't turn up in my testing either.
Will send a fixed patch.

Yours sincerely,

Floris Bos
diff mbox

Patch

diff --git a/hw/ide/core.c b/hw/ide/core.c
index 3e50c52..b48e5c2 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -166,6 +166,13 @@  static void ide_identify(IDEState *s)
     if (dev && dev->conf.discard_granularity) {
         put_le16(p + 169, 1); /* TRIM support */
     }
+
+    if (s->wwn) {
+        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;
@@ -1834,7 +1841,8 @@  static const BlockDevOps ide_cd_block_ops = {
 };
 
 int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
-                   const char *version, const char *serial, const char *model)
+                   const char *version, const char *serial, const char *model,
+                   uint64_t wwn)
 {
     int cylinders, heads, secs;
     uint64_t nb_sectors;
@@ -1860,6 +1868,7 @@  int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
     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;
@@ -1994,7 +2003,7 @@  void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0,
             if (ide_init_drive(&bus->ifs[i], dinfo->bdrv,
                                dinfo->media_cd ? IDE_CD : IDE_HD, NULL,
                                *dinfo->serial ? dinfo->serial : NULL,
-                               NULL) < 0) {
+                               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 b1319dc..100efd3 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -349,6 +349,7 @@  struct IDEState {
     int drive_serial;
     char drive_serial_str[21];
     char drive_model_str[41];
+    uint64_t wwn;
     /* ide regs */
     uint8_t feature;
     uint8_t error;
@@ -470,6 +471,7 @@  struct IDEDevice {
     char *version;
     char *serial;
     char *model;
+    uint64_t wwn;
 };
 
 #define BM_STATUS_DMAING 0x01
@@ -536,7 +538,8 @@  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, IDEDriveKind kind,
-                   const char *version, const char *serial, const char *model);
+                   const char *version, const char *serial, const char *model,
+                   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 07227c7..a46578d 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -137,7 +137,7 @@  static int ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind)
     }
 
     if (ide_init_drive(s, dev->conf.bs, kind,
-                       dev->version, serial, dev->model) < 0) {
+                       dev->version, serial, dev->model, dev->wwn) < 0) {
         return -1;
     }
 
@@ -174,6 +174,7 @@  static int ide_drive_initfn(IDEDevice *dev)
 #define DEFINE_IDE_DEV_PROPERTIES()                     \
     DEFINE_BLOCK_PROPERTIES(IDEDrive, dev.conf),        \
     DEFINE_PROP_STRING("ver",  IDEDrive, dev.version),  \
+    DEFINE_PROP_HEX64("wwn",  IDEDrive, dev.wwn, 0),    \
     DEFINE_PROP_STRING("serial",  IDEDrive, dev.serial),\
     DEFINE_PROP_STRING("model", IDEDrive, dev.model)