qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/2] ahci: Fix CD-ROM signature
@ 2015-07-06 21:49 John Snow
  2015-07-06 21:49 ` [Qemu-devel] [PATCH 1/2] " John Snow
  2015-07-06 21:49 ` [Qemu-devel] [PATCH 2/2] ahci: fix signature generation John Snow
  0 siblings, 2 replies; 9+ messages in thread
From: John Snow @ 2015-07-06 21:49 UTC (permalink / raw)
  To: qemu-block; +Cc: pbonzini, John Snow, hare, stefanha, qemu-devel

As reported by Hannes Reinecke, the signature generation
in AHCI is a little goofy. Let's fix it up.

Patch 1 should be considered a bugfix for 2.4.
Patch 2 is mostly a tidying effort prompted by the first patch.

________________________________________________________________________________

For convenience, this branch is available at:
https://github.com/jnsnow/qemu.git branch ahci-sig
https://github.com/jnsnow/qemu/tree/ahci-sig

This version is tagged ahci-sig-v1:
https://github.com/jnsnow/qemu/releases/tag/ahci-sig-v1

Hannes Reinecke (1):
  ahci: Fix CD-ROM signature

John Snow (1):
  ahci: fix signature generation

 hw/ide/ahci.c | 33 ++++++++++++++++++++-------------
 hw/ide/ahci.h |  2 +-
 2 files changed, 21 insertions(+), 14 deletions(-)

-- 
2.1.0

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH 1/2] ahci: Fix CD-ROM signature
  2015-07-06 21:49 [Qemu-devel] [PATCH 0/2] ahci: Fix CD-ROM signature John Snow
@ 2015-07-06 21:49 ` John Snow
  2015-07-07 17:19   ` John Snow
  2015-07-06 21:49 ` [Qemu-devel] [PATCH 2/2] ahci: fix signature generation John Snow
  1 sibling, 1 reply; 9+ messages in thread
From: John Snow @ 2015-07-06 21:49 UTC (permalink / raw)
  To: qemu-block; +Cc: pbonzini, John Snow, hare, stefanha, qemu-devel

From: Hannes Reinecke <hare@suse.de>

The CD-ROM signature is 0xeb140101, not 0xeb140000.
Without this change OVMF/Duet runs into a timeout trying
to detect a SATA cdrom.

Signed-off-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: John Snow <jsnow@redhat.com>
---
 hw/ide/ahci.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/ide/ahci.h b/hw/ide/ahci.h
index 9f5b4d2..68d5074 100644
--- a/hw/ide/ahci.h
+++ b/hw/ide/ahci.h
@@ -166,7 +166,7 @@
 #define AHCI_CMD_HDR_CMD_FIS_LEN           0x1f
 #define AHCI_CMD_HDR_PRDT_LEN              16
 
-#define SATA_SIGNATURE_CDROM               0xeb140000
+#define SATA_SIGNATURE_CDROM               0xeb140101
 #define SATA_SIGNATURE_DISK                0x00000101
 
 #define AHCI_GENERIC_HOST_CONTROL_REGS_MAX_ADDR 0x20
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH 2/2] ahci: fix signature generation
  2015-07-06 21:49 [Qemu-devel] [PATCH 0/2] ahci: Fix CD-ROM signature John Snow
  2015-07-06 21:49 ` [Qemu-devel] [PATCH 1/2] " John Snow
@ 2015-07-06 21:49 ` John Snow
  2015-07-07  8:49   ` Stefan Hajnoczi
  1 sibling, 1 reply; 9+ messages in thread
From: John Snow @ 2015-07-06 21:49 UTC (permalink / raw)
  To: qemu-block; +Cc: pbonzini, John Snow, hare, stefanha, qemu-devel

The initial register device-to-host FIS no longer needs to specially
set certain fields, as these can be handled generically by setting those
fields explicitly with the signatures we want at port reset time.

(1) Signatures are decomposed into their four component registers and
    set upon (AHCI) port reset.
(2) the signature cache register is no longer set manually per-each
    device type, but instead just once during ahci_init_d2h.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 hw/ide/ahci.c | 33 ++++++++++++++++++++-------------
 1 file changed, 20 insertions(+), 13 deletions(-)

diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index bb6a92f..f352dd7 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -537,20 +537,31 @@ static void ahci_init_d2h(AHCIDevice *ad)
 {
     uint8_t init_fis[20];
     IDEState *ide_state = &ad->port.ifs[0];
+    AHCIPortRegs *pr = &ad->port_regs;
 
     memset(init_fis, 0, sizeof(init_fis));
 
-    init_fis[4] = 1;
-    init_fis[12] = 1;
-
-    if (ide_state->drive_kind == IDE_CD) {
-        init_fis[5] = ide_state->lcyl;
-        init_fis[6] = ide_state->hcyl;
-    }
+    /* We're emulating receiving the first Reg H2D Fis from the device;
+     * Update the SIG register, but otherwise procede as normal. */
+    pr->sig = (ide_state->hcyl << 24) |
+        (ide_state->lcyl << 16) |
+        (ide_state->sector << 8) |
+        (ide_state->nsector & 0xFF);
 
     ahci_write_fis_d2h(ad, init_fis);
 }
 
+static void ahci_set_signature(AHCIDevice *ad, uint32_t sig)
+{
+    IDEState *s = &ad->port.ifs[0];
+    s->hcyl = sig >> 24 & 0xFF;
+    s->lcyl = sig >> 16 & 0xFF;
+    s->sector = sig >> 8 & 0xFF;
+    s->nsector = sig & 0xFF;
+
+    DPRINTF(ad->port_no, "set hcyl:lcyl:sect:nsect = 0x%08x\n", sig);
+}
+
 static void ahci_reset_port(AHCIState *s, int port)
 {
     AHCIDevice *d = &s->dev[port];
@@ -600,16 +611,12 @@ static void ahci_reset_port(AHCIState *s, int port)
 
     s->dev[port].port_state = STATE_RUN;
     if (!ide_state->blk) {
-        pr->sig = 0;
         ide_state->status = SEEK_STAT | WRERR_STAT;
     } else if (ide_state->drive_kind == IDE_CD) {
-        pr->sig = SATA_SIGNATURE_CDROM;
-        ide_state->lcyl = 0x14;
-        ide_state->hcyl = 0xeb;
-        DPRINTF(port, "set lcyl = %d\n", ide_state->lcyl);
+        ahci_set_signature(d, SATA_SIGNATURE_CDROM);
         ide_state->status = SEEK_STAT | WRERR_STAT | READY_STAT;
     } else {
-        pr->sig = SATA_SIGNATURE_DISK;
+        ahci_set_signature(d, SATA_SIGNATURE_DISK);
         ide_state->status = SEEK_STAT | WRERR_STAT;
     }
 
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH 2/2] ahci: fix signature generation
  2015-07-06 21:49 ` [Qemu-devel] [PATCH 2/2] ahci: fix signature generation John Snow
@ 2015-07-07  8:49   ` Stefan Hajnoczi
  2015-07-07 17:15     ` John Snow
  0 siblings, 1 reply; 9+ messages in thread
From: Stefan Hajnoczi @ 2015-07-07  8:49 UTC (permalink / raw)
  To: John Snow; +Cc: pbonzini, hare, qemu-block, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 3166 bytes --]

On Mon, Jul 06, 2015 at 05:49:52PM -0400, John Snow wrote:
> The initial register device-to-host FIS no longer needs to specially
> set certain fields, as these can be handled generically by setting those
> fields explicitly with the signatures we want at port reset time.
> 
> (1) Signatures are decomposed into their four component registers and
>     set upon (AHCI) port reset.
> (2) the signature cache register is no longer set manually per-each
>     device type, but instead just once during ahci_init_d2h.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>  hw/ide/ahci.c | 33 ++++++++++++++++++++-------------
>  1 file changed, 20 insertions(+), 13 deletions(-)

I see two code paths that call ahci_init_d2h().  Either
ahci_reset_port() does it (if a block device is attached) or it's called
when the guest writes to the PORT_CMD register.

I'm not sure the latter works.  The signature doesn't seem to be set
anywhere.

Any ideas?

> diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
> index bb6a92f..f352dd7 100644
> --- a/hw/ide/ahci.c
> +++ b/hw/ide/ahci.c
> @@ -537,20 +537,31 @@ static void ahci_init_d2h(AHCIDevice *ad)
>  {
>      uint8_t init_fis[20];
>      IDEState *ide_state = &ad->port.ifs[0];
> +    AHCIPortRegs *pr = &ad->port_regs;
>  
>      memset(init_fis, 0, sizeof(init_fis));
>  
> -    init_fis[4] = 1;
> -    init_fis[12] = 1;
> -
> -    if (ide_state->drive_kind == IDE_CD) {
> -        init_fis[5] = ide_state->lcyl;
> -        init_fis[6] = ide_state->hcyl;
> -    }
> +    /* We're emulating receiving the first Reg H2D Fis from the device;
> +     * Update the SIG register, but otherwise procede as normal. */
> +    pr->sig = (ide_state->hcyl << 24) |
> +        (ide_state->lcyl << 16) |
> +        (ide_state->sector << 8) |
> +        (ide_state->nsector & 0xFF);
>  
>      ahci_write_fis_d2h(ad, init_fis);
>  }
>  
> +static void ahci_set_signature(AHCIDevice *ad, uint32_t sig)
> +{
> +    IDEState *s = &ad->port.ifs[0];
> +    s->hcyl = sig >> 24 & 0xFF;
> +    s->lcyl = sig >> 16 & 0xFF;
> +    s->sector = sig >> 8 & 0xFF;
> +    s->nsector = sig & 0xFF;
> +
> +    DPRINTF(ad->port_no, "set hcyl:lcyl:sect:nsect = 0x%08x\n", sig);
> +}
> +
>  static void ahci_reset_port(AHCIState *s, int port)
>  {
>      AHCIDevice *d = &s->dev[port];
> @@ -600,16 +611,12 @@ static void ahci_reset_port(AHCIState *s, int port)
>  
>      s->dev[port].port_state = STATE_RUN;
>      if (!ide_state->blk) {
> -        pr->sig = 0;
>          ide_state->status = SEEK_STAT | WRERR_STAT;
>      } else if (ide_state->drive_kind == IDE_CD) {
> -        pr->sig = SATA_SIGNATURE_CDROM;
> -        ide_state->lcyl = 0x14;
> -        ide_state->hcyl = 0xeb;
> -        DPRINTF(port, "set lcyl = %d\n", ide_state->lcyl);
> +        ahci_set_signature(d, SATA_SIGNATURE_CDROM);
>          ide_state->status = SEEK_STAT | WRERR_STAT | READY_STAT;
>      } else {
> -        pr->sig = SATA_SIGNATURE_DISK;
> +        ahci_set_signature(d, SATA_SIGNATURE_DISK);
>          ide_state->status = SEEK_STAT | WRERR_STAT;
>      }
>  
> -- 
> 2.1.0
> 

[-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH 2/2] ahci: fix signature generation
  2015-07-07  8:49   ` Stefan Hajnoczi
@ 2015-07-07 17:15     ` John Snow
  2015-07-08 12:56       ` Stefan Hajnoczi
  0 siblings, 1 reply; 9+ messages in thread
From: John Snow @ 2015-07-07 17:15 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: pbonzini, hare, qemu-block, qemu-devel



On 07/07/2015 04:49 AM, Stefan Hajnoczi wrote:
> On Mon, Jul 06, 2015 at 05:49:52PM -0400, John Snow wrote:
>> The initial register device-to-host FIS no longer needs to specially
>> set certain fields, as these can be handled generically by setting those
>> fields explicitly with the signatures we want at port reset time.
>>
>> (1) Signatures are decomposed into their four component registers and
>>     set upon (AHCI) port reset.
>> (2) the signature cache register is no longer set manually per-each
>>     device type, but instead just once during ahci_init_d2h.
>>
>> Signed-off-by: John Snow <jsnow@redhat.com>
>> ---
>>  hw/ide/ahci.c | 33 ++++++++++++++++++++-------------
>>  1 file changed, 20 insertions(+), 13 deletions(-)
> 
> I see two code paths that call ahci_init_d2h().  Either
> ahci_reset_port() does it (if a block device is attached) or it's called
> when the guest writes to the PORT_CMD register.
> 
> I'm not sure the latter works.  The signature doesn't seem to be set
> anywhere.
> 
> Any ideas?
> 

I've never been super clear on this, but the reset functions are called
during bringup and not (apparently) the result of explicit guest
interaction with the HBA or ICH9, and as far as I can tell we've always
been relying on it:

#0  0x0000555555828501 in ahci_reset (s=0x5555576b55a0) at
/home/bos/jhuston/src/qemu/hw/ide/ahci.c:1498
#1  0x0000555555828cb7 in pci_ich9_reset (dev=0x5555576b4d20) at
/home/bos/jhuston/src/qemu/hw/ide/ich.c:98
#2  0x00005555557dc0c4 in device_reset (dev=0x5555576b4d20) at
/home/bos/jhuston/src/qemu/hw/core/qdev.c:1269
#3  0x00005555557d996f in qdev_reset_one (dev=0x5555576b4d20,
opaque=0x0) at /home/bos/jhuston/src/qemu/hw/core/qdev.c:309
#4  0x00005555557da5b1 in qdev_walk_children (dev=0x5555576b4d20,
pre_devfn=0x0, pre_busfn=0x0, post_devfn=0x5555557d9953
<qdev_reset_one>, post_busfn=0x5555557d9976 <qbus_reset_one>,
opaque=0x0) at /home/bos/jhuston/src/qemu/hw/core/qdev.c:637
#5  0x00005555557da4a4 in qbus_walk_children (bus=0x555556626890,
pre_devfn=0x0, pre_busfn=0x0, post_devfn=0x5555557d9953
<qdev_reset_one>, post_busfn=0x5555557d9976 <qbus_reset_one>,
opaque=0x0) at /home/bos/jhuston/src/qemu/hw/core/qdev.c:595
#6  0x00005555557da575 in qdev_walk_children (dev=0x5555565cc5c0,
pre_devfn=0x0, pre_busfn=0x0, post_devfn=0x5555557d9953
<qdev_reset_one>, post_busfn=0x5555557d9976 <qbus_reset_one>,
opaque=0x0) at /home/bos/jhuston/src/qemu/hw/core/qdev.c:629
#7  0x00005555557da4a4 in qbus_walk_children (bus=0x555556451a30,
pre_devfn=0x0, pre_busfn=0x0, post_devfn=0x5555557d9953
<qdev_reset_one>, post_busfn=0x5555557d9976 <qbus_reset_one>,
opaque=0x0) at /home/bos/jhuston/src/qemu/hw/core/qdev.c:595
#8  0x00005555557d9a4b in qbus_reset_all (bus=0x555556451a30) at
/home/bos/jhuston/src/qemu/hw/core/qdev.c:330
#9  0x00005555557d9a6d in qbus_reset_all_fn (opaque=0x555556451a30) at
/home/bos/jhuston/src/qemu/hw/core/qdev.c:336
#10 0x0000555555749f81 in qemu_devices_reset () at
/home/bos/jhuston/src/qemu/vl.c:1703
#11 0x000055555574a01f in qemu_system_reset (report=false) at
/home/bos/jhuston/src/qemu/vl.c:1716
#12 0x00005555557524c3 in main (argc=10, argv=0x7fffffffdd88,
envp=0x7fffffffdde0) at /home/bos/jhuston/src/qemu/vl.c:4595

So on initial boot, we call ahci_init_d2h and set pr->sig, then call
ahci_write_fis_d2h. However, since the FIS RX engine (PxFRE) is off, we
don't actually generate the FIS because there's nowhere to store it.

Later, when the guest activates the PxFRE bit, we call init_d2h again
and succeed this time.

As the original comment notes, this is kind of hacky. I decided not to
interfere with this for now because "it works" and is reasonably close
to the real behavior.

As far as I can tell, what's /supposed/ to happen is this:

(A) "START is off, but we received the Hello from the device" (Start
being off implies that FRE /should/ also be off, but this is not required.)

P:Init --> P:NotRunning --> NDR:Entry --> NDR:Accept --> P:RegFisUpdate
--> [P:NotRunning / P:RegFisPostToMem]

i.e. receive the FIS, update PxSIG, then trash the FIS or, if FRE is on
for whatever reason, go ahead and post it to memory. If FRE is off,
stash the D2H Reg FIS in the FIFO queue.

(B) "START is on, and we received the Hello FIS from the device"

P:Init --> P:NotRunning --> P:Idle --> NDR:Entry --> NDR:Accept -->
RegFIS:Entry --> ... -->
RegFIS:UpdateSig --> RegFIS:SetSig --> PM:Aggr ... --> P:Idle

This is a normal path to encounter during a COMRESET, perhaps, but not
likely to occur in QEMU because the disk and the HBA are not really
independent. The Initial D2H Register FIS gets posted immediately as
normal, taking care to update the signature.

(C) "PxFRE was enabled, but there's a D2H Register FIS in the FIFO"

P:Init --> P:NotRunning --> P:RegFisPostToMem

i.e, the device said hello before the guest told us where we can store
the FIS (quite probable) so once the FRE bit is turned on, we reveal the
FIS and update the shadow registers here.




It looks like what should happen in QEMU, effectively, is:

(1) Generate the Initial FIS and update pr->sig regardless of the
current HBA state.
(2) Wait for the guest to enable PxFRE
(3) Send the initial FIS and update shadow registers.

What we do now is pretty close, with the exception of updating the
shadow registers whether or not PxFRE is enabled during the
ahci_port_reset phase, but it's been like that for quite some time.

--js

>> diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
>> index bb6a92f..f352dd7 100644
>> --- a/hw/ide/ahci.c
>> +++ b/hw/ide/ahci.c
>> @@ -537,20 +537,31 @@ static void ahci_init_d2h(AHCIDevice *ad)
>>  {
>>      uint8_t init_fis[20];
>>      IDEState *ide_state = &ad->port.ifs[0];
>> +    AHCIPortRegs *pr = &ad->port_regs;
>>  
>>      memset(init_fis, 0, sizeof(init_fis));
>>  
>> -    init_fis[4] = 1;
>> -    init_fis[12] = 1;
>> -
>> -    if (ide_state->drive_kind == IDE_CD) {
>> -        init_fis[5] = ide_state->lcyl;
>> -        init_fis[6] = ide_state->hcyl;
>> -    }
>> +    /* We're emulating receiving the first Reg H2D Fis from the device;
>> +     * Update the SIG register, but otherwise procede as normal. */
>> +    pr->sig = (ide_state->hcyl << 24) |
>> +        (ide_state->lcyl << 16) |
>> +        (ide_state->sector << 8) |
>> +        (ide_state->nsector & 0xFF);
>>  
>>      ahci_write_fis_d2h(ad, init_fis);
>>  }
>>  
>> +static void ahci_set_signature(AHCIDevice *ad, uint32_t sig)
>> +{
>> +    IDEState *s = &ad->port.ifs[0];
>> +    s->hcyl = sig >> 24 & 0xFF;
>> +    s->lcyl = sig >> 16 & 0xFF;
>> +    s->sector = sig >> 8 & 0xFF;
>> +    s->nsector = sig & 0xFF;
>> +
>> +    DPRINTF(ad->port_no, "set hcyl:lcyl:sect:nsect = 0x%08x\n", sig);
>> +}
>> +
>>  static void ahci_reset_port(AHCIState *s, int port)
>>  {
>>      AHCIDevice *d = &s->dev[port];
>> @@ -600,16 +611,12 @@ static void ahci_reset_port(AHCIState *s, int port)
>>  
>>      s->dev[port].port_state = STATE_RUN;
>>      if (!ide_state->blk) {
>> -        pr->sig = 0;
>>          ide_state->status = SEEK_STAT | WRERR_STAT;
>>      } else if (ide_state->drive_kind == IDE_CD) {
>> -        pr->sig = SATA_SIGNATURE_CDROM;
>> -        ide_state->lcyl = 0x14;
>> -        ide_state->hcyl = 0xeb;
>> -        DPRINTF(port, "set lcyl = %d\n", ide_state->lcyl);
>> +        ahci_set_signature(d, SATA_SIGNATURE_CDROM);
>>          ide_state->status = SEEK_STAT | WRERR_STAT | READY_STAT;
>>      } else {
>> -        pr->sig = SATA_SIGNATURE_DISK;
>> +        ahci_set_signature(d, SATA_SIGNATURE_DISK);
>>          ide_state->status = SEEK_STAT | WRERR_STAT;
>>      }
>>  
>> -- 
>> 2.1.0
>>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH 1/2] ahci: Fix CD-ROM signature
  2015-07-06 21:49 ` [Qemu-devel] [PATCH 1/2] " John Snow
@ 2015-07-07 17:19   ` John Snow
  2015-07-08  9:26     ` [Qemu-devel] [Qemu-block] " Kevin Wolf
  0 siblings, 1 reply; 9+ messages in thread
From: John Snow @ 2015-07-07 17:19 UTC (permalink / raw)
  To: qemu-block; +Cc: pbonzini, hare, stefanha, qemu-devel



On 07/06/2015 05:49 PM, John Snow wrote:
> From: Hannes Reinecke <hare@suse.de>
> 
> The CD-ROM signature is 0xeb140101, not 0xeb140000.
> Without this change OVMF/Duet runs into a timeout trying
> to detect a SATA cdrom.
> 
> Signed-off-by: Hannes Reinecke <hare@suse.de>
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>  hw/ide/ahci.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/ide/ahci.h b/hw/ide/ahci.h
> index 9f5b4d2..68d5074 100644
> --- a/hw/ide/ahci.h
> +++ b/hw/ide/ahci.h
> @@ -166,7 +166,7 @@
>  #define AHCI_CMD_HDR_CMD_FIS_LEN           0x1f
>  #define AHCI_CMD_HDR_PRDT_LEN              16
>  
> -#define SATA_SIGNATURE_CDROM               0xeb140000
> +#define SATA_SIGNATURE_CDROM               0xeb140101
>  #define SATA_SIGNATURE_DISK                0x00000101
>  
>  #define AHCI_GENERIC_HOST_CONTROL_REGS_MAX_ADDR 0x20
> 

FWIW for review purposes, this is based on ATA8 AC3, Table 184 "Device
Signatures for Normal Output" and is very straightforward.

For how the component fields there (LBA and Count) become a single 4
byte signature, see AHCI 1.3 section 3.3.9 (PxSIG) and this is the value
we are emulating here with the #define.

I gave this patch a soft ACK in the past, but it feels wrong to give it
an R-B when I'm sending it out myself :)

--js

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [Qemu-block] [PATCH 1/2] ahci: Fix CD-ROM signature
  2015-07-07 17:19   ` John Snow
@ 2015-07-08  9:26     ` Kevin Wolf
  0 siblings, 0 replies; 9+ messages in thread
From: Kevin Wolf @ 2015-07-08  9:26 UTC (permalink / raw)
  To: John Snow; +Cc: pbonzini, stefanha, hare, qemu-block, qemu-devel

Am 07.07.2015 um 19:19 hat John Snow geschrieben:
> 
> 
> On 07/06/2015 05:49 PM, John Snow wrote:
> > From: Hannes Reinecke <hare@suse.de>
> > 
> > The CD-ROM signature is 0xeb140101, not 0xeb140000.
> > Without this change OVMF/Duet runs into a timeout trying
> > to detect a SATA cdrom.
> > 
> > Signed-off-by: Hannes Reinecke <hare@suse.de>
> > Signed-off-by: John Snow <jsnow@redhat.com>
> > ---
> >  hw/ide/ahci.h | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/hw/ide/ahci.h b/hw/ide/ahci.h
> > index 9f5b4d2..68d5074 100644
> > --- a/hw/ide/ahci.h
> > +++ b/hw/ide/ahci.h
> > @@ -166,7 +166,7 @@
> >  #define AHCI_CMD_HDR_CMD_FIS_LEN           0x1f
> >  #define AHCI_CMD_HDR_PRDT_LEN              16
> >  
> > -#define SATA_SIGNATURE_CDROM               0xeb140000
> > +#define SATA_SIGNATURE_CDROM               0xeb140101
> >  #define SATA_SIGNATURE_DISK                0x00000101
> >  
> >  #define AHCI_GENERIC_HOST_CONTROL_REGS_MAX_ADDR 0x20
> > 
> 
> FWIW for review purposes, this is based on ATA8 AC3, Table 184 "Device
> Signatures for Normal Output" and is very straightforward.

It is. The only thing that confuses me about this is that I thought it
had been fixed for a while already. My AHCI driver has a comment "Broken
value in qemu < 2.2" at the workaround, and I seem to remember that I
didn't need it for a newer qemu version indeed. Strange. Or perhaps I
only fixed it locally and then forgot to send the patch?

Anyway, the fix is obviously correct:

Reviewed-by: Kevin Wolf <kwolf@redhat.com>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH 2/2] ahci: fix signature generation
  2015-07-07 17:15     ` John Snow
@ 2015-07-08 12:56       ` Stefan Hajnoczi
  2015-07-08 15:18         ` John Snow
  0 siblings, 1 reply; 9+ messages in thread
From: Stefan Hajnoczi @ 2015-07-08 12:56 UTC (permalink / raw)
  To: John Snow; +Cc: pbonzini, hare, qemu-block, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 2112 bytes --]

On Tue, Jul 07, 2015 at 01:15:02PM -0400, John Snow wrote:
> 
> 
> On 07/07/2015 04:49 AM, Stefan Hajnoczi wrote:
> > On Mon, Jul 06, 2015 at 05:49:52PM -0400, John Snow wrote:
> >> The initial register device-to-host FIS no longer needs to specially
> >> set certain fields, as these can be handled generically by setting those
> >> fields explicitly with the signatures we want at port reset time.
> >>
> >> (1) Signatures are decomposed into their four component registers and
> >>     set upon (AHCI) port reset.
> >> (2) the signature cache register is no longer set manually per-each
> >>     device type, but instead just once during ahci_init_d2h.
> >>
> >> Signed-off-by: John Snow <jsnow@redhat.com>
> >> ---
> >>  hw/ide/ahci.c | 33 ++++++++++++++++++++-------------
> >>  1 file changed, 20 insertions(+), 13 deletions(-)
> > 
> > I see two code paths that call ahci_init_d2h().  Either
> > ahci_reset_port() does it (if a block device is attached) or it's called
> > when the guest writes to the PORT_CMD register.
> > 
> > I'm not sure the latter works.  The signature doesn't seem to be set
> > anywhere.
> > 
> > Any ideas?
...
> So on initial boot, we call ahci_init_d2h and set pr->sig, then call
> ahci_write_fis_d2h. However, since the FIS RX engine (PxFRE) is off, we
> don't actually generate the FIS because there's nowhere to store it.

My question is about the ide_state->blk == NULL case:

ahci_reset_port() is contradictory:

static void ahci_reset_port(AHCIState *s, int port)
{
    ...
    ide_state = &s->dev[port].port.ifs[0];
    if (!ide_state->blk) {
        return;
    }

    ...

    s->dev[port].port_state = STATE_RUN;
    if (!ide_state->blk) { <-- deadcode?
        pr->sig = 0;
        ide_state->status = SEEK_STAT | WRERR_STAT;
    }

Does code after the first "if (!ide_state->blk)" in ahci_reset_port()
ever execute in a drive hotplug scenario?

If it doesn't execute then sig is never filled in.

Your patch does not include a regression but either something is broken
here or I don't understand the code.

[-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH 2/2] ahci: fix signature generation
  2015-07-08 12:56       ` Stefan Hajnoczi
@ 2015-07-08 15:18         ` John Snow
  0 siblings, 0 replies; 9+ messages in thread
From: John Snow @ 2015-07-08 15:18 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: pbonzini, hare, qemu-block, qemu-devel



On 07/08/2015 08:56 AM, Stefan Hajnoczi wrote:
> On Tue, Jul 07, 2015 at 01:15:02PM -0400, John Snow wrote:
>>
>>
>> On 07/07/2015 04:49 AM, Stefan Hajnoczi wrote:
>>> On Mon, Jul 06, 2015 at 05:49:52PM -0400, John Snow wrote:
>>>> The initial register device-to-host FIS no longer needs to specially
>>>> set certain fields, as these can be handled generically by setting those
>>>> fields explicitly with the signatures we want at port reset time.
>>>>
>>>> (1) Signatures are decomposed into their four component registers and
>>>>     set upon (AHCI) port reset.
>>>> (2) the signature cache register is no longer set manually per-each
>>>>     device type, but instead just once during ahci_init_d2h.
>>>>
>>>> Signed-off-by: John Snow <jsnow@redhat.com>
>>>> ---
>>>>  hw/ide/ahci.c | 33 ++++++++++++++++++++-------------
>>>>  1 file changed, 20 insertions(+), 13 deletions(-)
>>>
>>> I see two code paths that call ahci_init_d2h().  Either
>>> ahci_reset_port() does it (if a block device is attached) or it's called
>>> when the guest writes to the PORT_CMD register.
>>>
>>> I'm not sure the latter works.  The signature doesn't seem to be set
>>> anywhere.
>>>
>>> Any ideas?
> ...
>> So on initial boot, we call ahci_init_d2h and set pr->sig, then call
>> ahci_write_fis_d2h. However, since the FIS RX engine (PxFRE) is off, we
>> don't actually generate the FIS because there's nowhere to store it.
> 
> My question is about the ide_state->blk == NULL case:
> 
> ahci_reset_port() is contradictory:
> 
> static void ahci_reset_port(AHCIState *s, int port)
> {
>     ...
>     ide_state = &s->dev[port].port.ifs[0];
>     if (!ide_state->blk) {
>         return;
>     }
> 
>     ...
> 
>     s->dev[port].port_state = STATE_RUN;
>     if (!ide_state->blk) { <-- deadcode?
>         pr->sig = 0;
>         ide_state->status = SEEK_STAT | WRERR_STAT;
>     }
> 
> Does code after the first "if (!ide_state->blk)" in ahci_reset_port()
> ever execute in a drive hotplug scenario?
> 
> If it doesn't execute then sig is never filled in.
> 
> Your patch does not include a regression but either something is broken
> here or I don't understand the code.
> 

I'm sorry, I misunderstood you...

Haven't really played with the hotplugging much so I don't know it to
work. I'll throw it on the list.

Actually, since I need to start focusing on non-legacy devices, I'll
start a wiki page of all the bugs and quirks I know about and that way
if I forget to get back to it (or my plane disappears over the Bermuda
Triangle) my understanding of existing problems will be documented.

I'll stage patch #1 here (Reviewed by Kevin) for inclusion in 2.4, #2 is
also a bug fix but it's more subtle and isn't known to break anything
and could possibly benefit from a more comprehensive fix so I'll leave
it for now.

Thanks,
--js

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2015-07-08 15:18 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-07-06 21:49 [Qemu-devel] [PATCH 0/2] ahci: Fix CD-ROM signature John Snow
2015-07-06 21:49 ` [Qemu-devel] [PATCH 1/2] " John Snow
2015-07-07 17:19   ` John Snow
2015-07-08  9:26     ` [Qemu-devel] [Qemu-block] " Kevin Wolf
2015-07-06 21:49 ` [Qemu-devel] [PATCH 2/2] ahci: fix signature generation John Snow
2015-07-07  8:49   ` Stefan Hajnoczi
2015-07-07 17:15     ` John Snow
2015-07-08 12:56       ` Stefan Hajnoczi
2015-07-08 15:18         ` John Snow

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).