Am 28.10.2013 um 17:43 hat Paolo Bonzini geschrieben: > AHCIDevice does not have a dma_status field. The add_status callback thus > does not make sense, start moving its functionality to new callbacks. > > Signed-off-by: Paolo Bonzini <pbonz...@redhat.com>
This whole add_status(BM_STATUS_INT) is weird and doesn't seem to make sense. For AHCI it triggers the actual IRQ, whereas for BMIDE it only sets the status register bit and requires a separate call to trigger the IRQ. This function is ide_set_irq(), which in turn ends up completely ignored by AHCI (ahci_irq_set() is an empty function). I think the right approach would be to let AHCI handle ide_set_irq() and remove the add_status/trigger_irq calls completely. > hw/ide/ahci.c | 12 ++++++++---- > hw/ide/atapi.c | 4 +++- > hw/ide/internal.h | 1 + > hw/ide/pci.c | 7 +++++++ > 4 files changed, 19 insertions(+), 5 deletions(-) > > diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c > index 23f3f22..7b47053 100644 > --- a/hw/ide/ahci.c > +++ b/hw/ide/ahci.c > @@ -1097,13 +1097,16 @@ static int ahci_dma_add_status(IDEDMA *dma, int > status) > AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma); > DPRINTF(ad->port_no, "set status: %x\n", status); > > - if (status & BM_STATUS_INT) { > - ahci_trigger_irq(ad->hba, ad, PORT_IRQ_STAT_DSS); > - } > - > return 0; > } > > +static void ahci_dma_trigger_irq(IDEDMA *dma) > +{ > + AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma); > + DPRINTF(ad->port_no, "trigger irq\n"); > + ahci_trigger_irq(ad->hba, ad, PORT_IRQ_STAT_DSS); > +} > + > static void ahci_async_cmd_done(IDEDMA *dma) > { > AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma); > @@ -1134,6 +1137,7 @@ static const IDEDMAOps ahci_dma_ops = { > .prepare_buf = ahci_dma_prepare_buf, > .rw_buf = ahci_dma_rw_buf, > .set_unit = ahci_dma_set_unit, > + .trigger_irq = ahci_dma_trigger_irq, > .add_status = ahci_dma_add_status, > .async_cmd_done = ahci_async_cmd_done, > .restart_cb = ahci_dma_restart_cb, > diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c > index a7688bf..814cffb 100644 > --- a/hw/ide/atapi.c > +++ b/hw/ide/atapi.c > @@ -355,7 +355,9 @@ static void ide_atapi_cmd_read_dma_cb(void *opaque, int > ret) > > eot: > bdrv_acct_done(s->bs, &s->acct); > - s->bus->dma->ops->add_status(s->bus->dma, BM_STATUS_INT); > + if (s->bus->dma->ops->trigger_irq) { > + s->bus->dma->ops->trigger_irq(s->bus->dma); > + } > ide_set_inactive(s); > } This function looks suspicious as well, because there seems to be a path where trigger_irq() can be called without actually triggering an IRQ. Kevin