From patchwork Fri Oct 14 11:41:06 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Cave-Ayland X-Patchwork-Id: 9376421 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id BEE7760779 for ; Fri, 14 Oct 2016 11:42:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AEBAC2A652 for ; Fri, 14 Oct 2016 11:42:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A34FC2A658; Fri, 14 Oct 2016 11:42:11 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id C39542A657 for ; Fri, 14 Oct 2016 11:42:10 +0000 (UTC) Received: from localhost ([::1]:46660 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bv0sM-0001Mv-06 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 14 Oct 2016 07:42:10 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53460) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bv0rr-0001L7-Ko for qemu-devel@nongnu.org; Fri, 14 Oct 2016 07:41:41 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bv0rp-0008Cf-RJ for qemu-devel@nongnu.org; Fri, 14 Oct 2016 07:41:39 -0400 Received: from chuckie.co.uk ([82.165.15.123]:58598 helo=s16892447.onlinehome-server.info) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bv0rp-00089s-HY; Fri, 14 Oct 2016 07:41:37 -0400 Received: from host86-138-220-226.range86-138.btcentralplus.com ([86.138.220.226] helo=kentang.home) by s16892447.onlinehome-server.info with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.76) (envelope-from ) id 1bv0re-0002s3-4i; Fri, 14 Oct 2016 12:41:28 +0100 From: Mark Cave-Ayland To: keith.busch@intel.com, kwolf@redhat.com, mreitz@redhat.com, jsnow@redhat.com, pbonzini@redhat.com, qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Fri, 14 Oct 2016 12:41:06 +0100 Message-Id: <1476445266-27503-3-git-send-email-mark.cave-ayland@ilande.co.uk> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1476445266-27503-1-git-send-email-mark.cave-ayland@ilande.co.uk> References: <1476445266-27503-1-git-send-email-mark.cave-ayland@ilande.co.uk> X-SA-Exim-Connect-IP: 86.138.220.226 X-SA-Exim-Mail-From: mark.cave-ayland@ilande.co.uk X-SA-Exim-Version: 4.2.1 (built Sun, 08 Jan 2012 02:45:44 +0000) X-SA-Exim-Scanned: Yes (on s16892447.onlinehome-server.info) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 82.165.15.123 Subject: [Qemu-devel] [PATCHv2 2/2] macio: switch over to new byte-aligned DMA helpers X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Now that the DMA helpers are byte-aligned they can be called directly from the macio routines rather than emulating byte-aligned accesses via multiple block-level accesses. Signed-off-by: Mark Cave-Ayland Reviewed-by: Eric Blake Reviewed-by: John Snow --- hw/ide/macio.c | 213 ++++++++------------------------------------------------ 1 file changed, 28 insertions(+), 185 deletions(-) diff --git a/hw/ide/macio.c b/hw/ide/macio.c index 76f97c2..9742c00 100644 --- a/hw/ide/macio.c +++ b/hw/ide/macio.c @@ -52,187 +52,6 @@ static const int debug_macio = 0; #define MACIO_PAGE_SIZE 4096 -/* - * Unaligned DMA read/write access functions required for OS X/Darwin which - * don't perform DMA transactions on sector boundaries. These functions are - * modelled on bdrv_co_preadv()/bdrv_co_pwritev() and so should be easy to - * remove if the unaligned block APIs are ever exposed. - */ - -static void pmac_dma_read(BlockBackend *blk, - int64_t offset, unsigned int bytes, - void (*cb)(void *opaque, int ret), void *opaque) -{ - DBDMA_io *io = opaque; - MACIOIDEState *m = io->opaque; - IDEState *s = idebus_active_if(&m->bus); - dma_addr_t dma_addr; - int64_t sector_num; - int nsector; - uint64_t align = BDRV_SECTOR_SIZE; - size_t head_bytes, tail_bytes; - - qemu_iovec_destroy(&io->iov); - qemu_iovec_init(&io->iov, io->len / MACIO_PAGE_SIZE + 1); - - sector_num = (offset >> 9); - nsector = (io->len >> 9); - - MACIO_DPRINTF("--- DMA read transfer (0x%" HWADDR_PRIx ",0x%x): " - "sector_num: %" PRId64 ", nsector: %d\n", io->addr, io->len, - sector_num, nsector); - - dma_addr = io->addr; - io->dir = DMA_DIRECTION_FROM_DEVICE; - io->dma_len = io->len; - io->dma_mem = dma_memory_map(&address_space_memory, dma_addr, &io->dma_len, - io->dir); - - if (offset & (align - 1)) { - head_bytes = offset & (align - 1); - - MACIO_DPRINTF("--- DMA unaligned head: sector %" PRId64 ", " - "discarding %zu bytes\n", sector_num, head_bytes); - - qemu_iovec_add(&io->iov, &io->head_remainder, head_bytes); - - bytes += offset & (align - 1); - offset = offset & ~(align - 1); - } - - qemu_iovec_add(&io->iov, io->dma_mem, io->len); - - if ((offset + bytes) & (align - 1)) { - tail_bytes = (offset + bytes) & (align - 1); - - MACIO_DPRINTF("--- DMA unaligned tail: sector %" PRId64 ", " - "discarding bytes %zu\n", sector_num, tail_bytes); - - qemu_iovec_add(&io->iov, &io->tail_remainder, align - tail_bytes); - bytes = ROUND_UP(bytes, align); - } - - s->io_buffer_size -= io->len; - s->io_buffer_index += io->len; - - io->len = 0; - - MACIO_DPRINTF("--- Block read transfer - sector_num: %" PRIx64 " " - "nsector: %x\n", (offset >> 9), (bytes >> 9)); - - s->bus->dma->aiocb = blk_aio_preadv(blk, offset, &io->iov, 0, cb, io); -} - -static void pmac_dma_write(BlockBackend *blk, - int64_t offset, int bytes, - void (*cb)(void *opaque, int ret), void *opaque) -{ - DBDMA_io *io = opaque; - MACIOIDEState *m = io->opaque; - IDEState *s = idebus_active_if(&m->bus); - dma_addr_t dma_addr; - int64_t sector_num; - int nsector; - uint64_t align = BDRV_SECTOR_SIZE; - size_t head_bytes, tail_bytes; - bool unaligned_head = false, unaligned_tail = false; - - qemu_iovec_destroy(&io->iov); - qemu_iovec_init(&io->iov, io->len / MACIO_PAGE_SIZE + 1); - - sector_num = (offset >> 9); - nsector = (io->len >> 9); - - MACIO_DPRINTF("--- DMA write transfer (0x%" HWADDR_PRIx ",0x%x): " - "sector_num: %" PRId64 ", nsector: %d\n", io->addr, io->len, - sector_num, nsector); - - dma_addr = io->addr; - io->dir = DMA_DIRECTION_TO_DEVICE; - io->dma_len = io->len; - io->dma_mem = dma_memory_map(&address_space_memory, dma_addr, &io->dma_len, - io->dir); - - if (offset & (align - 1)) { - head_bytes = offset & (align - 1); - sector_num = ((offset & ~(align - 1)) >> 9); - - MACIO_DPRINTF("--- DMA unaligned head: pre-reading head sector %" - PRId64 "\n", sector_num); - - blk_pread(s->blk, (sector_num << 9), &io->head_remainder, align); - - qemu_iovec_add(&io->iov, &io->head_remainder, head_bytes); - qemu_iovec_add(&io->iov, io->dma_mem, io->len); - - bytes += offset & (align - 1); - offset = offset & ~(align - 1); - - unaligned_head = true; - } - - if ((offset + bytes) & (align - 1)) { - tail_bytes = (offset + bytes) & (align - 1); - sector_num = (((offset + bytes) & ~(align - 1)) >> 9); - - MACIO_DPRINTF("--- DMA unaligned tail: pre-reading tail sector %" - PRId64 "\n", sector_num); - - blk_pread(s->blk, (sector_num << 9), &io->tail_remainder, align); - - if (!unaligned_head) { - qemu_iovec_add(&io->iov, io->dma_mem, io->len); - } - - qemu_iovec_add(&io->iov, &io->tail_remainder + tail_bytes, - align - tail_bytes); - - bytes = ROUND_UP(bytes, align); - - unaligned_tail = true; - } - - if (!unaligned_head && !unaligned_tail) { - qemu_iovec_add(&io->iov, io->dma_mem, io->len); - } - - s->io_buffer_size -= io->len; - s->io_buffer_index += io->len; - - io->len = 0; - - MACIO_DPRINTF("--- Block write transfer - sector_num: %" PRIx64 " " - "nsector: %x\n", (offset >> 9), (bytes >> 9)); - - s->bus->dma->aiocb = blk_aio_pwritev(blk, offset, &io->iov, 0, cb, io); -} - -static void pmac_dma_trim(BlockBackend *blk, - int64_t offset, int bytes, - void (*cb)(void *opaque, int ret), void *opaque) -{ - DBDMA_io *io = opaque; - MACIOIDEState *m = io->opaque; - IDEState *s = idebus_active_if(&m->bus); - dma_addr_t dma_addr; - - qemu_iovec_destroy(&io->iov); - qemu_iovec_init(&io->iov, io->len / MACIO_PAGE_SIZE + 1); - - dma_addr = io->addr; - io->dir = DMA_DIRECTION_TO_DEVICE; - io->dma_len = io->len; - io->dma_mem = dma_memory_map(&address_space_memory, dma_addr, &io->dma_len, - io->dir); - - qemu_iovec_add(&io->iov, io->dma_mem, io->len); - s->io_buffer_size -= io->len; - s->io_buffer_index += io->len; - io->len = 0; - - s->bus->dma->aiocb = ide_issue_trim(offset, &io->iov, cb, io, blk); -} - static void pmac_ide_atapi_transfer_cb(void *opaque, int ret) { DBDMA_io *io = opaque; @@ -244,6 +63,7 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret) if (ret < 0) { MACIO_DPRINTF("DMA error: %d\n", ret); + qemu_sglist_destroy(&s->sg); ide_atapi_io_error(s, ret); goto done; } @@ -258,6 +78,7 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret) if (s->io_buffer_size <= 0) { MACIO_DPRINTF("End of IDE transfer\n"); + qemu_sglist_destroy(&s->sg); ide_atapi_cmd_ok(s); m->dma_active = false; goto done; @@ -282,7 +103,15 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret) /* Calculate current offset */ offset = ((int64_t)s->lba << 11) + s->io_buffer_index; - pmac_dma_read(s->blk, offset, io->len, pmac_ide_atapi_transfer_cb, io); + qemu_sglist_init(&s->sg, DEVICE(m), io->len / MACIO_PAGE_SIZE + 1, + &address_space_memory); + qemu_sglist_add(&s->sg, io->addr, io->len); + s->io_buffer_size -= io->len; + s->io_buffer_index += io->len; + io->len = 0; + + s->bus->dma->aiocb = dma_blk_read(s->blk, &s->sg, offset, 0x1, + pmac_ide_atapi_transfer_cb, io); return; done: @@ -310,6 +139,7 @@ static void pmac_ide_transfer_cb(void *opaque, int ret) if (ret < 0) { MACIO_DPRINTF("DMA error: %d\n", ret); + qemu_sglist_destroy(&s->sg); ide_dma_error(s); goto done; } @@ -324,6 +154,7 @@ static void pmac_ide_transfer_cb(void *opaque, int ret) if (s->io_buffer_size <= 0) { MACIO_DPRINTF("End of IDE transfer\n"); + qemu_sglist_destroy(&s->sg); s->status = READY_STAT | SEEK_STAT; ide_set_irq(s->bus); m->dma_active = false; @@ -338,15 +169,27 @@ static void pmac_ide_transfer_cb(void *opaque, int ret) /* Calculate number of sectors */ offset = (ide_get_sector(s) << 9) + s->io_buffer_index; + qemu_sglist_init(&s->sg, DEVICE(m), io->len / MACIO_PAGE_SIZE + 1, + &address_space_memory); + qemu_sglist_add(&s->sg, io->addr, io->len); + s->io_buffer_size -= io->len; + s->io_buffer_index += io->len; + io->len = 0; + switch (s->dma_cmd) { case IDE_DMA_READ: - pmac_dma_read(s->blk, offset, io->len, pmac_ide_transfer_cb, io); + s->bus->dma->aiocb = dma_blk_read(s->blk, &s->sg, offset, 0x1, + pmac_ide_atapi_transfer_cb, io); break; case IDE_DMA_WRITE: - pmac_dma_write(s->blk, offset, io->len, pmac_ide_transfer_cb, io); + s->bus->dma->aiocb = dma_blk_write(s->blk, &s->sg, offset, 0x1, + pmac_ide_transfer_cb, io); break; case IDE_DMA_TRIM: - pmac_dma_trim(s->blk, offset, io->len, pmac_ide_transfer_cb, io); + s->bus->dma->aiocb = dma_blk_io(blk_get_aio_context(s->blk), &s->sg, + offset, 0x1, ide_issue_trim, s->blk, + pmac_ide_transfer_cb, io, + DMA_DIRECTION_TO_DEVICE); break; default: abort();