qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] Fix ATA SMART and CHECK POWER MODE


From: Ryan Harper
Subject: Re: [Qemu-devel] [PATCH] Fix ATA SMART and CHECK POWER MODE
Date: Wed, 9 Feb 2011 13:43:06 -0600
User-agent: Mutt/1.5.6+20040907i

* Brian Wheeler <address@hidden> [2011-02-07 16:48]:
> This patch fixes two things:
> 
> 1) CHECK POWER MODE
> 
> The error return value wasn't always zero, so it would show up as
> offline.  Error is now explicitly set to zero.
> 
> 2) SMART
> 
> The smart values that were returned were invalid and tools like skdump
> would not recognize that the smart data was actually valid and would
> dump weird output.  The data has been fixed up and raw value support was
> added.  Tools like skdump and palimpsest work as expected.
> 
> Signed-of-by: Brian Wheeler <address@hidden>
> ---
> diff --git a/hw/ide/core.c b/hw/ide/core.c
> index dd63664..4d4ccfa 100644
> --- a/hw/ide/core.c
> +++ b/hw/ide/core.c
> @@ -34,15 +34,37 @@
> 
>  #include <hw/ide/internal.h>
> 
> -static const int smart_attributes[][5] = {
> -    /* id,  flags, val, wrst, thrsh */
> -    { 0x01, 0x03, 0x64, 0x64, 0x06}, /* raw read */
> -    { 0x03, 0x03, 0x64, 0x64, 0x46}, /* spin up */
> -    { 0x04, 0x02, 0x64, 0x64, 0x14}, /* start stop count */
> -    { 0x05, 0x03, 0x64, 0x64, 0x36}, /* remapped sectors */
> -    { 0x00, 0x00, 0x00, 0x00, 0x00}
> +/* These values were taking from a running system. */
> +static const int smart_attributes[][12] = {
> +    /* id,  flags, hflags, val, wrst, raw (up to 6 bytes) */
> +    /* raw read error rate*/
> +    { 0x01, 0x03, 0x00, 0x74, 0x63, 0x31, 0x6d, 0x3f, 0x0d},
> +    /* spin up */
> +    { 0x03, 0x03, 0x00, 0x61, 0x61},
> +    /* start stop count */
> +    { 0x04, 0x02, 0x00, 0x64, 0x64, 0x64},
> +    /* remapped sectors */
> +    { 0x05, 0x03, 0x00, 0x64, 0x64},
> +    /* power on hours */
> +    { 0x09, 0x03, 0x00, 0x61, 0x61, 0x68, 0x0a},
> +    /* power cycle count */
> +    { 0x0c, 0x03, 0x00, 0x64, 0x64, 0x32},
> +    /* airflow-temperature-celsius */
> +    { 190,  0x03, 0x00, 0x64, 0x64, 0x1f, 0x00, 0x16, 0x22},
> +    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
>  };
> 
> +static const int smart_thresholds[][2] = {
> +    { 0x01, 0x06},
> +    { 0x03, 0x00},
> +    { 0x04, 0x14},
> +    { 0x05, 0x24},
> +    { 0x09, 0x00},
> +    { 190,  0x32},
> +    { 0x00, 0x00}
> +};

Are these values from a specification or what?  WOuld be good to
document where we get the values that are being used.  If you are
selecting some defaults, what those values are and why.

> +
> +
>  /* XXX: DVDs that could fit on a CD will be reported as a CD */
>  static inline int media_present(IDEState *s)
>  {
> @@ -1843,6 +1865,7 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val)
>          break;
>      case WIN_CHECKPOWERMODE1:
G>      case WIN_CHECKPOWERMODE2:
> +        s->error = 0;
>          s->nsector = 0xff; /* device active or idle */
>          s->status = READY_STAT | SEEK_STAT;
>          ide_set_irq(s->bus);
> @@ -2068,24 +2091,24 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val)
>       case SMART_ATTR_AUTOSAVE:
>               switch (s->sector) {
>               case 0x00:
> -             s->smart_autosave = 0;
> -             break;
> +                 s->smart_autosave = 0;
> +                 break;
>               case 0xf1:
> -             s->smart_autosave = 1;
> -             break;
> +                 s->smart_autosave = 1;
> +                 break;
>               default:
> -             goto abort_cmd;
> +                 goto abort_cmd;

Did you edit fix these up automatically? tabs/spaces?

>               }
>               s->status = READY_STAT | SEEK_STAT;
>               ide_set_irq(s->bus);
>               break;
>       case SMART_STATUS:
>               if (!s->smart_errors) {
> -             s->hcyl = 0xc2;
> -             s->lcyl = 0x4f;
> +                 s->hcyl = 0xc2;
> +                 s->lcyl = 0x4f;
>               } else {
> -             s->hcyl = 0x2c;
> -             s->lcyl = 0xf4;
> +                 s->hcyl = 0x2c;
> +                 s->lcyl = 0xf4;

same

>               }
>               s->status = READY_STAT | SEEK_STAT;
>               ide_set_irq(s->bus);
> @@ -2094,13 +2117,13 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val)
>               memset(s->io_buffer, 0, 0x200);
>               s->io_buffer[0] = 0x01; /* smart struct version */
>               for (n=0; n<30; n++) {
> -             if (smart_attributes[n][0] == 0)
> +                 if (smart_attributes[n][0] == 0)
>                       break;

If you are going to touch the if, then CODING_STYLE wants braced ifs.

   if () {
   }

> -             s->io_buffer[2+0+(n*12)] = smart_attributes[n][0];
> -             s->io_buffer[2+1+(n*12)] = smart_attributes[n][4];
> +                 s->io_buffer[2+0+(n*12)] = smart_thresholds[n][0];
> +                 s->io_buffer[2+1+(n*12)] = smart_thresholds[n][1];
>               }
>               for (n=0; n<511; n++) /* checksum */
> -             s->io_buffer[511] += s->io_buffer[n];
> +                 s->io_buffer[511] += s->io_buffer[n];
>               s->io_buffer[511] = 0x100 - s->io_buffer[511];
>               s->status = READY_STAT | SEEK_STAT;
>               ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
> @@ -2110,21 +2133,22 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val)
>               memset(s->io_buffer, 0, 0x200);
>               s->io_buffer[0] = 0x01; /* smart struct version */
>               for (n=0; n<30; n++) {
> -             if (smart_attributes[n][0] == 0)
> +                 if (smart_attributes[n][0] == 0)

CODING_STYLE if()

>                       break;
> -             s->io_buffer[2+0+(n*12)] = smart_attributes[n][0];
> -             s->io_buffer[2+1+(n*12)] = smart_attributes[n][1];
> -             s->io_buffer[2+3+(n*12)] = smart_attributes[n][2];
> -             s->io_buffer[2+4+(n*12)] = smart_attributes[n][3];
> +                 int i;
> +                 for(i = 0; i < 12; i++) {
> +                     s->io_buffer[2+i+(n*12)] = smart_attributes[n][i];
> +                 }
>               }
> +

   whitespace

>               s->io_buffer[362] = 0x02 | (s->smart_autosave?0x80:0x00);
>               if (s->smart_selftest_count == 0) {
> -             s->io_buffer[363] = 0;
> +                 s->io_buffer[363] = 0;
>               } else {
> -             s->io_buffer[363] =
> +                 s->io_buffer[363] =
>                       s->smart_selftest_data[3 + 
> -                                        (s->smart_selftest_count - 1) *
> -                                        24];
> +                                            (s->smart_selftest_count - 1) *
> +                                            24];
>               }
>               s->io_buffer[364] = 0x20; 
>               s->io_buffer[365] = 0x01; 
> @@ -2136,9 +2160,9 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val)
>               s->io_buffer[372] = 0x02; /* minutes for poll short test */
>               s->io_buffer[373] = 0x36; /* minutes for poll ext test */
>               s->io_buffer[374] = 0x01; /* minutes for poll conveyance */
> -
> -             for (n=0; n<511; n++) 
> -             s->io_buffer[511] += s->io_buffer[n];
> +             for (n=0; n<511; n++) { /* checksum */
> +                 s->io_buffer[511] += s->io_buffer[n];
> +             }
>               s->io_buffer[511] = 0x100 - s->io_buffer[511];
>               s->status = READY_STAT | SEEK_STAT;
>               ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
> @@ -2147,32 +2171,31 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val)
>       case SMART_READ_LOG:
>               switch (s->sector) {
>               case 0x01: /* summary smart error log */
> -             memset(s->io_buffer, 0, 0x200);
> -             s->io_buffer[0] = 0x01;
> -             s->io_buffer[1] = 0x00; /* no error entries */
> -             s->io_buffer[452] = s->smart_errors & 0xff;
> -             s->io_buffer[453] = (s->smart_errors & 0xff00) >> 8;
> -
> -             for (n=0; n<511; n++)
> +                 memset(s->io_buffer, 0, 0x200);
> +                 s->io_buffer[0] = 0x01;
> +                 s->io_buffer[1] = 0x00; /* no error entries */
> +                 s->io_buffer[452] = s->smart_errors & 0xff;
> +                 s->io_buffer[453] = (s->smart_errors & 0xff00) >> 8;
> +                 for (n=0; n<511; n++)

   brace

>                       s->io_buffer[511] += s->io_buffer[n];
> -             s->io_buffer[511] = 0x100 - s->io_buffer[511];
> -             break;
> +                 s->io_buffer[511] = 0x100 - s->io_buffer[511];
> +                 break;
>               case 0x06: /* smart self test log */
> -             memset(s->io_buffer, 0, 0x200);
> -             s->io_buffer[0] = 0x01;
> -             if (s->smart_selftest_count == 0) {
> +                 memset(s->io_buffer, 0, 0x200);
> +                 s->io_buffer[0] = 0x01;
> +                 if (s->smart_selftest_count == 0) {
>                       s->io_buffer[508] = 0;
> -             } else {
> +                 } else {
>                       s->io_buffer[508] = s->smart_selftest_count;
>                       for (n=2; n<506; n++) 
> -                     s->io_buffer[n] = s->smart_selftest_data[n];
> -             }
> -             for (n=0; n<511; n++)
> +                         s->io_buffer[n] = s->smart_selftest_data[n];
> +                 }
> +                 for (n=0; n<511; n++)

   brace

>                       s->io_buffer[511] += s->io_buffer[n];
> -             s->io_buffer[511] = 0x100 - s->io_buffer[511];
> -             break;
> +                 s->io_buffer[511] = 0x100 - s->io_buffer[511];
> +                 break;
>               default:
> -             goto abort_cmd;
> +                 goto abort_cmd;
>               }
>               s->status = READY_STAT | SEEK_STAT;
>               ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
> 

This patchset looks a lot larger than it should since there is a lot of
indentation movement, it would be good to see a version that just
implemented the changes needed, which AFAICT are mainly the additional
attributes and limits.

 
-- 
Ryan Harper
Software Engineer; Linux Technology Center
IBM Corp., Austin, Tx
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]