[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] AHCI Port Interrupt Enable register cleaning on soft re
From: |
Kevin Wolf |
Subject: |
Re: [Qemu-devel] AHCI Port Interrupt Enable register cleaning on soft reset |
Date: |
Mon, 19 Sep 2011 12:36:58 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:6.0.2) Gecko/20110906 Thunderbird/6.0.2 |
Am 12.09.2011 10:19, schrieb Alexander Motin:
> Alexander Graf wrote:
>> Am 11.09.2011 um 16:43 schrieb Alexander Motin <address@hidden>:
>>> 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.
>>>
>>> This patch fixes the problem for me:
>>> http://people.freebsd.org/~mav/qemu.ahci.patch
>>
>> Ah, cool! So FreeBSD works with AHCI using this patch?
>
> Yes. I haven't done deep testing to guarantee there is no other issues,
> but at least disk is properly detected now.
>
>> Please send it again as an inline patch (if really really hard not 100%
>> important) and add a signed-off-by line (very important) to the patch.
>
> OK. Here it is:
>
> Signed-off-by: Alexander Motin <address@hidden>
>
> --- hw/ide/ahci.c.prev 2011-09-11 16:39:53.000000000 +0300
> +++ hw/ide/ahci.c 2011-09-11 16:39:48.000000000 +0300
> @@ -505,10 +505,7 @@ static void ahci_reset_port(AHCIState *s
> 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;
> @@ -1157,12 +1154,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);
> }
> }
>
Thanks, applied to the block branch.
Kevin