From patchwork Sat Aug 28 14:54:55 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eduard - Gabriel Munteanu X-Patchwork-Id: 139851 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id o7SEuxbj024795 for ; Sat, 28 Aug 2010 14:57:41 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751978Ab0H1O5B (ORCPT ); Sat, 28 Aug 2010 10:57:01 -0400 Received: from mail-bw0-f46.google.com ([209.85.214.46]:43443 "EHLO mail-bw0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751868Ab0H1O4y (ORCPT ); Sat, 28 Aug 2010 10:56:54 -0400 Received: by bwz11 with SMTP id 11so2652010bwz.19 for ; Sat, 28 Aug 2010 07:56:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:sender:from:to:cc:subject :date:message-id:x-mailer:in-reply-to:references; bh=FdcWfn674ftu+Ax9qpIkerw5dH8q7gVjirUyoQ3rMG4=; b=ESYnHgXKqx3MzkssQUOXXD9tvTQT4v2xnaHWOGhdLAjf5xkR7w/QPUiEMKFLYA6Z65 rRaWNetrHPpOa0/z1CLcOPfpPlrSx5/nXlUYGkM446SW8VeN2zLI5O+NpUxCrCKXVSGw LBDFgPsdJQKR9RnXShF9rf+eIgzy/Rxt2nVn0= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; b=cqLfgwces1wnzLA4WO40dqDk3xDq9Z6gdqAVz3l0OQZMGbqXpa6WNhATnFFnfolvKJ 3Wcck1iTcAxhmOepUZpFI67r6wilFmzLRUlWzU86PBZWoBXaUKwtqV11+vn+NHwXyFDl WHXEXFf1J/PE+HG2c5NrCYRv/RTbFI4AMXtqY= Received: by 10.204.161.212 with SMTP id s20mr1450967bkx.184.1283007412452; Sat, 28 Aug 2010 07:56:52 -0700 (PDT) Received: from localhost ([188.25.93.165]) by mx.google.com with ESMTPS id y2sm3511678bkx.20.2010.08.28.07.56.51 (version=SSLv3 cipher=RC4-MD5); Sat, 28 Aug 2010 07:56:51 -0700 (PDT) From: Eduard - Gabriel Munteanu To: mst@redhat.com Cc: joro@8bytes.org, blauwirbel@gmail.com, paul@codesourcery.com, avi@redhat.com, anthony@codemonkey.ws, av1474@comtv.ru, yamahata@valinux.co.jp, kvm@vger.kernel.org, qemu-devel@nongnu.org, Eduard - Gabriel Munteanu Subject: [PATCH 4/7] ide: use the PCI memory access interface Date: Sat, 28 Aug 2010 17:54:55 +0300 Message-Id: <1283007298-10942-5-git-send-email-eduard.munteanu@linux360.ro> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1283007298-10942-1-git-send-email-eduard.munteanu@linux360.ro> References: <1283007298-10942-1-git-send-email-eduard.munteanu@linux360.ro> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Sat, 28 Aug 2010 14:57:41 +0000 (UTC) diff --git a/dma-helpers.c b/dma-helpers.c index 712ed89..a0dcdb8 100644 --- a/dma-helpers.c +++ b/dma-helpers.c @@ -10,12 +10,36 @@ #include "dma.h" #include "block_int.h" -void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint) +static void *qemu_sglist_default_map(void *opaque, + QEMUSGInvalMapFunc *inval_cb, + void *inval_opaque, + target_phys_addr_t addr, + target_phys_addr_t *len, + int is_write) +{ + return cpu_physical_memory_map(addr, len, is_write); +} + +static void qemu_sglist_default_unmap(void *opaque, + void *buffer, + target_phys_addr_t len, + int is_write, + target_phys_addr_t access_len) +{ + cpu_physical_memory_unmap(buffer, len, is_write, access_len); +} + +void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint, + QEMUSGMapFunc *map, QEMUSGUnmapFunc *unmap, void *opaque) { qsg->sg = qemu_malloc(alloc_hint * sizeof(ScatterGatherEntry)); qsg->nsg = 0; qsg->nalloc = alloc_hint; qsg->size = 0; + + qsg->map = map ? map : qemu_sglist_default_map; + qsg->unmap = unmap ? unmap : qemu_sglist_default_unmap; + qsg->opaque = opaque; } void qemu_sglist_add(QEMUSGList *qsg, target_phys_addr_t base, @@ -73,12 +97,23 @@ static void dma_bdrv_unmap(DMAAIOCB *dbs) int i; for (i = 0; i < dbs->iov.niov; ++i) { - cpu_physical_memory_unmap(dbs->iov.iov[i].iov_base, - dbs->iov.iov[i].iov_len, !dbs->is_write, - dbs->iov.iov[i].iov_len); + dbs->sg->unmap(dbs->sg->opaque, + dbs->iov.iov[i].iov_base, + dbs->iov.iov[i].iov_len, !dbs->is_write, + dbs->iov.iov[i].iov_len); } } +static void dma_bdrv_cancel(void *opaque) +{ + DMAAIOCB *dbs = opaque; + + bdrv_aio_cancel(dbs->acb); + dma_bdrv_unmap(dbs); + qemu_iovec_destroy(&dbs->iov); + qemu_aio_release(dbs); +} + static void dma_bdrv_cb(void *opaque, int ret) { DMAAIOCB *dbs = (DMAAIOCB *)opaque; @@ -100,7 +135,8 @@ static void dma_bdrv_cb(void *opaque, int ret) while (dbs->sg_cur_index < dbs->sg->nsg) { cur_addr = dbs->sg->sg[dbs->sg_cur_index].base + dbs->sg_cur_byte; cur_len = dbs->sg->sg[dbs->sg_cur_index].len - dbs->sg_cur_byte; - mem = cpu_physical_memory_map(cur_addr, &cur_len, !dbs->is_write); + mem = dbs->sg->map(dbs->sg->opaque, dma_bdrv_cancel, dbs, + cur_addr, &cur_len, !dbs->is_write); if (!mem) break; qemu_iovec_add(&dbs->iov, mem, cur_len); diff --git a/dma.h b/dma.h index f3bb275..d48f35c 100644 --- a/dma.h +++ b/dma.h @@ -15,6 +15,19 @@ #include "hw/hw.h" #include "block.h" +typedef void QEMUSGInvalMapFunc(void *opaque); +typedef void *QEMUSGMapFunc(void *opaque, + QEMUSGInvalMapFunc *inval_cb, + void *inval_opaque, + target_phys_addr_t addr, + target_phys_addr_t *len, + int is_write); +typedef void QEMUSGUnmapFunc(void *opaque, + void *buffer, + target_phys_addr_t len, + int is_write, + target_phys_addr_t access_len); + typedef struct { target_phys_addr_t base; target_phys_addr_t len; @@ -25,9 +38,15 @@ typedef struct { int nsg; int nalloc; target_phys_addr_t size; + + QEMUSGMapFunc *map; + QEMUSGUnmapFunc *unmap; + void *opaque; } QEMUSGList; -void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint); +void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint, + QEMUSGMapFunc *map, QEMUSGUnmapFunc *unmap, + void *opaque); void qemu_sglist_add(QEMUSGList *qsg, target_phys_addr_t base, target_phys_addr_t len); void qemu_sglist_destroy(QEMUSGList *qsg); diff --git a/hw/ide/core.c b/hw/ide/core.c index af52c2c..024a125 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -436,7 +436,8 @@ static int dma_buf_prepare(BMDMAState *bm, int is_write) } prd; int l, len; - qemu_sglist_init(&s->sg, s->nsector / (IDE_PAGE_SIZE / 512) + 1); + qemu_sglist_init(&s->sg, s->nsector / (IDE_PAGE_SIZE / 512) + 1, + bm->map, bm->unmap, bm->opaque); s->io_buffer_size = 0; for(;;) { if (bm->cur_prd_len == 0) { @@ -444,7 +445,7 @@ static int dma_buf_prepare(BMDMAState *bm, int is_write) if (bm->cur_prd_last || (bm->cur_addr - bm->addr) >= IDE_PAGE_SIZE) return s->io_buffer_size != 0; - cpu_physical_memory_read(bm->cur_addr, (uint8_t *)&prd, 8); + bmdma_memory_read(bm, bm->cur_addr, (uint8_t *)&prd, 8); bm->cur_addr += 8; prd.addr = le32_to_cpu(prd.addr); prd.size = le32_to_cpu(prd.size); @@ -527,7 +528,7 @@ static int dma_buf_rw(BMDMAState *bm, int is_write) if (bm->cur_prd_last || (bm->cur_addr - bm->addr) >= IDE_PAGE_SIZE) return 0; - cpu_physical_memory_read(bm->cur_addr, (uint8_t *)&prd, 8); + bmdma_memory_read(bm, bm->cur_addr, (uint8_t *)&prd, 8); bm->cur_addr += 8; prd.addr = le32_to_cpu(prd.addr); prd.size = le32_to_cpu(prd.size); @@ -542,11 +543,11 @@ static int dma_buf_rw(BMDMAState *bm, int is_write) l = bm->cur_prd_len; if (l > 0) { if (is_write) { - cpu_physical_memory_write(bm->cur_prd_addr, - s->io_buffer + s->io_buffer_index, l); + bmdma_memory_write(bm, bm->cur_prd_addr, + s->io_buffer + s->io_buffer_index, l); } else { - cpu_physical_memory_read(bm->cur_prd_addr, - s->io_buffer + s->io_buffer_index, l); + bmdma_memory_read(bm, bm->cur_prd_addr, + s->io_buffer + s->io_buffer_index, l); } bm->cur_prd_addr += l; bm->cur_prd_len -= l; diff --git a/hw/ide/internal.h b/hw/ide/internal.h index 4165543..f686d38 100644 --- a/hw/ide/internal.h +++ b/hw/ide/internal.h @@ -477,6 +477,24 @@ struct IDEDeviceInfo { #define BM_CMD_START 0x01 #define BM_CMD_READ 0x08 +typedef void BMDMAInvalMapFunc(void *opaque); +typedef void BMDMARWFunc(void *opaque, + target_phys_addr_t addr, + uint8_t *buf, + target_phys_addr_t len, + int is_write); +typedef void *BMDMAMapFunc(void *opaque, + BMDMAInvalMapFunc *inval_cb, + void *inval_opaque, + target_phys_addr_t addr, + target_phys_addr_t *len, + int is_write); +typedef void BMDMAUnmapFunc(void *opaque, + void *buffer, + target_phys_addr_t len, + int is_write, + target_phys_addr_t access_len); + struct BMDMAState { uint8_t cmd; uint8_t status; @@ -496,8 +514,29 @@ struct BMDMAState { int64_t sector_num; uint32_t nsector; QEMUBH *bh; + + BMDMARWFunc *rw; + BMDMAMapFunc *map; + BMDMAUnmapFunc *unmap; + void *opaque; }; +static inline void bmdma_memory_read(BMDMAState *bm, + target_phys_addr_t addr, + uint8_t *buf, + target_phys_addr_t len) +{ + bm->rw(bm->opaque, addr, buf, len, 0); +} + +static inline void bmdma_memory_write(BMDMAState *bm, + target_phys_addr_t addr, + uint8_t *buf, + target_phys_addr_t len) +{ + bm->rw(bm->opaque, addr, buf, len, 1); +} + static inline IDEState *idebus_active_if(IDEBus *bus) { return bus->ifs + bus->unit; diff --git a/hw/ide/macio.c b/hw/ide/macio.c index bd1c73e..962ae13 100644 --- a/hw/ide/macio.c +++ b/hw/ide/macio.c @@ -79,7 +79,7 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret) s->io_buffer_size = io->len; - qemu_sglist_init(&s->sg, io->len / MACIO_PAGE_SIZE + 1); + qemu_sglist_init(&s->sg, io->len / MACIO_PAGE_SIZE + 1, NULL, NULL, NULL); qemu_sglist_add(&s->sg, io->addr, io->len); io->addr += io->len; io->len = 0; @@ -141,7 +141,7 @@ static void pmac_ide_transfer_cb(void *opaque, int ret) s->io_buffer_index = 0; s->io_buffer_size = io->len; - qemu_sglist_init(&s->sg, io->len / MACIO_PAGE_SIZE + 1); + qemu_sglist_init(&s->sg, io->len / MACIO_PAGE_SIZE + 1, NULL, NULL, NULL); qemu_sglist_add(&s->sg, io->addr, io->len); io->addr += io->len; io->len = 0; diff --git a/hw/ide/pci.c b/hw/ide/pci.c index 4d95cc5..5879044 100644 --- a/hw/ide/pci.c +++ b/hw/ide/pci.c @@ -183,4 +183,11 @@ void pci_ide_create_devs(PCIDevice *dev, DriveInfo **hd_table) continue; ide_create_drive(d->bus+bus[i], unit[i], hd_table[i]); } + + for (i = 0; i < 2; i++) { + d->bmdma[i].rw = (void *) pci_memory_rw; + d->bmdma[i].map = (void *) pci_memory_map; + d->bmdma[i].unmap = (void *) pci_memory_unmap; + d->bmdma[i].opaque = dev; + } }