From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54651) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Y13Xd-0007oW-0o for qemu-devel@nongnu.org; Tue, 16 Dec 2014 20:36:47 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Y13XW-0002V9-8v for qemu-devel@nongnu.org; Tue, 16 Dec 2014 20:36:40 -0500 Received: from mx1.redhat.com ([209.132.183.28]:51715) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Y13XW-0002V3-0p for qemu-devel@nongnu.org; Tue, 16 Dec 2014 20:36:34 -0500 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id sBH1aXYp019163 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Tue, 16 Dec 2014 20:36:33 -0500 From: John Snow Date: Tue, 16 Dec 2014 20:35:56 -0500 Message-Id: <1418780167-16231-7-git-send-email-jsnow@redhat.com> In-Reply-To: <1418780167-16231-1-git-send-email-jsnow@redhat.com> References: <1418780167-16231-1-git-send-email-jsnow@redhat.com> Subject: [Qemu-devel] [PATCH v2 06/17] ide: move restart callback to common code List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: kwolf@redhat.com, mst@redhat.com, armbru@redhat.com, mreitz@redhat.com, stefanha@redhat.com, pbonzini@redhat.com, John Snow From: Paolo Bonzini With BMDMA specific excised from the restart functions, create a HBA-agnostic restart callback to be shared between the different HBAs. Change the callback registered with the vmstate_change handler to always point to ide_restart_cb instead of relying on the IDEDMAOps.restart_cb() member. Signed-off-by: Paolo Bonzini Signed-off-by: John Snow --- hw/ide/core.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- hw/ide/internal.h | 2 ++ hw/ide/pci.c | 68 ---------------------------------------------------- hw/ide/pci.h | 1 - 4 files changed, 72 insertions(+), 70 deletions(-) diff --git a/hw/ide/core.c b/hw/ide/core.c index a836626..15b6a3f 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -2314,6 +2314,10 @@ static int ide_nop_int(IDEDMA *dma, int x) return 0; } +static void ide_nop(IDEDMA *dma) +{ +} + static int32_t ide_nop_int32(IDEDMA *dma, int x) { return 0; @@ -2325,14 +2329,79 @@ static void ide_nop_restart(void *opaque, int x, RunState y) static const IDEDMAOps ide_dma_nop_ops = { .prepare_buf = ide_nop_int32, + .restart_dma = ide_nop, .rw_buf = ide_nop_int, .set_unit = ide_nop_int, .restart_cb = ide_nop_restart, }; +static void ide_restart_dma(IDEState *s, enum ide_dma_cmd dma_cmd) +{ + s->bus->dma->ops->restart_dma(s->bus->dma); + s->io_buffer_index = 0; + s->io_buffer_size = 0; + s->dma_cmd = dma_cmd; + ide_start_dma(s, ide_dma_cb); +} + +static void ide_restart_bh(void *opaque) +{ + IDEBus *bus = opaque; + IDEState *s; + bool is_read; + int error_status; + + qemu_bh_delete(bus->bh); + bus->bh = NULL; + + error_status = bus->error_status; + if (bus->error_status == 0) { + return; + } + + s = idebus_active_if(bus); + is_read = (bus->error_status & IDE_RETRY_READ) != 0; + + /* The error status must be cleared before resubmitting the request: The + * request may fail again, and this case can only be distinguished if the + * called function can set a new error status. */ + bus->error_status = 0; + + if (error_status & IDE_RETRY_DMA) { + if (error_status & IDE_RETRY_TRIM) { + ide_restart_dma(s, IDE_DMA_TRIM); + } else { + ide_restart_dma(s, is_read ? IDE_DMA_READ : IDE_DMA_WRITE); + } + } else if (error_status & IDE_RETRY_PIO) { + if (is_read) { + ide_sector_read(s); + } else { + ide_sector_write(s); + } + } else if (error_status & IDE_RETRY_FLUSH) { + ide_flush_cache(s); + } +} + +static void ide_restart_cb(void *opaque, int running, RunState state) +{ + IDEBus *bus = opaque; + + if (!running) + return; + + if (!bus->bh) { + bus->bh = qemu_bh_new(ide_restart_bh, bus); + qemu_bh_schedule(bus->bh); + } +} + void ide_register_restart_cb(IDEBus *bus) { - qemu_add_vm_change_state_handler(bus->dma->ops->restart_cb, bus); + if (bus->dma->ops->restart_dma) { + qemu_add_vm_change_state_handler(ide_restart_cb, bus); + } } static IDEDMA ide_dma_nop = { diff --git a/hw/ide/internal.h b/hw/ide/internal.h index 73c5e63..7ea64d1 100644 --- a/hw/ide/internal.h +++ b/hw/ide/internal.h @@ -454,6 +454,8 @@ struct IDEBus { IDEDevice *master; IDEDevice *slave; IDEState ifs[2]; + QEMUBH *bh; + int bus_id; int max_units; IDEDMA *dma; diff --git a/hw/ide/pci.c b/hw/ide/pci.c index e5caf11..cd1bbb0 100644 --- a/hw/ide/pci.c +++ b/hw/ide/pci.c @@ -194,73 +194,6 @@ static void bmdma_restart_dma(IDEDMA *dma) bm->cur_addr = bm->addr; } -static void ide_restart_dma(IDEState *s, enum ide_dma_cmd dma_cmd) -{ - if (s->bus->dma->ops->restart_dma) { - s->bus->dma->ops->restart_dma(s->bus->dma); - } - s->io_buffer_index = 0; - s->io_buffer_size = 0; - s->dma_cmd = dma_cmd; - ide_start_dma(s, ide_dma_cb); -} - -/* TODO This should be common IDE code */ -static void bmdma_restart_bh(void *opaque) -{ - IDEBus *bus = opaque; - BMDMAState *bm = DO_UPCAST(BMDMAState, dma, bus->dma); - IDEState *s; - bool is_read; - int error_status; - - qemu_bh_delete(bm->bh); - bm->bh = NULL; - - error_status = bus->error_status; - if (bus->error_status == 0) { - return; - } - - s = idebus_active_if(bus); - is_read = (bus->error_status & IDE_RETRY_READ) != 0; - - /* The error status must be cleared before resubmitting the request: The - * request may fail again, and this case can only be distinguished if the - * called function can set a new error status. */ - bus->error_status = 0; - - if (error_status & IDE_RETRY_DMA) { - if (error_status & IDE_RETRY_TRIM) { - ide_restart_dma(s, IDE_DMA_TRIM); - } else { - ide_restart_dma(s, is_read ? IDE_DMA_READ : IDE_DMA_WRITE); - } - } else if (error_status & IDE_RETRY_PIO) { - if (is_read) { - ide_sector_read(s); - } else { - ide_sector_write(s); - } - } else if (error_status & IDE_RETRY_FLUSH) { - ide_flush_cache(s); - } -} - -static void bmdma_restart_cb(void *opaque, int running, RunState state) -{ - IDEBus *bus = opaque; - BMDMAState *bm = DO_UPCAST(BMDMAState, dma, bus->dma); - - if (!running) - return; - - if (!bm->bh) { - bm->bh = qemu_bh_new(bmdma_restart_bh, bus); - qemu_bh_schedule(bm->bh); - } -} - static void bmdma_cancel(BMDMAState *bm) { if (bm->status & BM_STATUS_DMAING) { @@ -524,7 +457,6 @@ static const struct IDEDMAOps bmdma_ops = { .set_unit = bmdma_set_unit, .restart_dma = bmdma_restart_dma, .set_inactive = bmdma_set_inactive, - .restart_cb = bmdma_restart_cb, .reset = bmdma_reset, }; diff --git a/hw/ide/pci.h b/hw/ide/pci.h index 2e9314a..ea4e051 100644 --- a/hw/ide/pci.h +++ b/hw/ide/pci.h @@ -28,7 +28,6 @@ typedef struct BMDMAState { uint32_t nsector; MemoryRegion addr_ioport; MemoryRegion extra_io; - QEMUBH *bh; qemu_irq irq; /* Bit 0-2 and 7: BM status register -- 1.9.3