AHCI Port Interrupt Enable register cleaning on soft reset
authorAlexander Motin <mav@FreeBSD.org>
Mon, 12 Sep 2011 08:19:25 +0000 (11:19 +0300)
committerKevin Wolf <kwolf@redhat.com>
Tue, 20 Sep 2011 10:27:44 +0000 (12:27 +0200)
I've found that FreeBSD AHCI driver doesn't work with AHCI hardware
emulation of QEMU 0.15.0. I believe the problem is on QEMU's side. As I
see, it clears port's Interrupt Enable register each time when reset of
any level happens. Is is reasonable for the global controller reset. It
is probably not good, but acceptable for FreeBSD driver for the port
hard reset. But it is IMO wrong for the device soft reset. None of real
hardware I know behaves that way.

Signed-off-by: Alexander Motin <mav@FreeBSD.org>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
hw/ide/ahci.c

index a8659cf..464c28b 100644 (file)
@@ -499,10 +499,7 @@ static void ahci_reset_port(AHCIState *s, int port)
     ide_bus_reset(&d->port);
     ide_state->ncq_queues = AHCI_MAX_CMDS;
 
-    pr->irq_stat = 0;
-    pr->irq_mask = 0;
     pr->scr_stat = 0;
-    pr->scr_ctl = 0;
     pr->scr_err = 0;
     pr->scr_act = 0;
     d->busy_slot = -1;
@@ -1159,12 +1156,17 @@ void ahci_uninit(AHCIState *s)
 void ahci_reset(void *opaque)
 {
     struct AHCIPCIState *d = opaque;
+    AHCIPortRegs *pr;
     int i;
 
     d->ahci.control_regs.irqstatus = 0;
     d->ahci.control_regs.ghc = 0;
 
     for (i = 0; i < d->ahci.ports; i++) {
+        pr = &d->ahci.dev[i].port_regs;
+        pr->irq_stat = 0;
+        pr->irq_mask = 0;
+        pr->scr_ctl = 0;
         ahci_reset_port(&d->ahci, i);
     }
 }