Patchwork [2/2] e1000: CTRL.RST emulation

login
register
mail settings
Submitter Michael S. Tsirkin
Date Sept. 27, 2011, 12:58 p.m.
Message ID <eb3a2eb12eb223f398c94f672caa83ee30aabacb.1317127818.git.mst@redhat.com>
Download mbox | patch
Permalink /patch/116599/
State New
Headers show

Comments

Michael S. Tsirkin - Sept. 27, 2011, 12:58 p.m.
e1000 spec says CTRL.RST write should have the same effect
as bus reset, except that is preserves PCI Config.
Reset device registers and interrupts.

Fix suggested by Andy Gospodarek <andy@greyhouse.net>
Similar fix proposed by Anthony PERARD <anthony.perard@citrix.com>

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/e1000.c |    9 +++++++--
 1 files changed, 7 insertions(+), 2 deletions(-)
Andy Gospodarek - Sept. 27, 2011, 3:33 p.m.
On Tue, Sep 27, 2011 at 8:58 AM, Michael S. Tsirkin <mst@redhat.com> wrote:
> e1000 spec says CTRL.RST write should have the same effect
> as bus reset, except that is preserves PCI Config.
> Reset device registers and interrupts.
>
> Fix suggested by Andy Gospodarek <andy@greyhouse.net>
> Similar fix proposed by Anthony PERARD <anthony.perard@citrix.com>
>
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> ---
>  hw/e1000.c |    9 +++++++--
>  1 files changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/hw/e1000.c b/hw/e1000.c
> index 87a1104..b51e089 100644
> --- a/hw/e1000.c
> +++ b/hw/e1000.c
> @@ -241,8 +241,13 @@ static void e1000_reset(void *opaque)
>  static void
>  set_ctrl(E1000State *s, int index, uint32_t val)
>  {
> -    /* RST is self clearing */
> -    s->mac_reg[CTRL] = val & ~E1000_CTRL_RST;
> +    if (val & E1000_CTRL_RST) {
> +        e1000_reset(s);
> +        qemu_set_irq(s->dev.irq[0], 0);
> +        return;
> +    }
> +
> +    s->mac_reg[CTRL] = val;
>  }
>
>  static void
> --
> 1.7.5.53.gc233e
>

Looks good to me.  Thanks for following up with this, Michael.

Patch

diff --git a/hw/e1000.c b/hw/e1000.c
index 87a1104..b51e089 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -241,8 +241,13 @@  static void e1000_reset(void *opaque)
 static void
 set_ctrl(E1000State *s, int index, uint32_t val)
 {
-    /* RST is self clearing */
-    s->mac_reg[CTRL] = val & ~E1000_CTRL_RST;
+    if (val & E1000_CTRL_RST) {
+        e1000_reset(s);
+        qemu_set_irq(s->dev.irq[0], 0);
+        return;
+    }
+
+    s->mac_reg[CTRL] = val;
 }
 
 static void