[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 02/39] dma: keep a device alive while it has SGLists
From: |
Paolo Bonzini |
Subject: |
[Qemu-devel] [PATCH 02/39] dma: keep a device alive while it has SGLists |
Date: |
Tue, 4 Jun 2013 20:51:57 +0200 |
A QEMUSGList has a reference to a device's address space. Keep
the device alive while the QEMUSGList exists.
Signed-off-by: Paolo Bonzini <address@hidden>
---
dma-helpers.c | 6 +++++-
hw/ide/ahci.c | 3 ++-
hw/ide/macio.c | 4 ++--
hw/scsi/megasas.c | 4 ++--
hw/scsi/virtio-scsi.c | 10 ++++++----
hw/usb/hcd-ehci.c | 4 ++--
include/hw/pci/pci.h | 2 +-
include/sysemu/dma.h | 4 +++-
8 files changed, 23 insertions(+), 14 deletions(-)
diff --git a/dma-helpers.c b/dma-helpers.c
index 5afba47..499550f 100644
--- a/dma-helpers.c
+++ b/dma-helpers.c
@@ -34,13 +34,16 @@ int dma_memory_set(AddressSpace *as, dma_addr_t addr,
uint8_t c, dma_addr_t len)
return error;
}
-void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint, AddressSpace *as)
+void qemu_sglist_init(QEMUSGList *qsg, DeviceState *dev, int alloc_hint,
+ AddressSpace *as)
{
qsg->sg = g_malloc(alloc_hint * sizeof(ScatterGatherEntry));
qsg->nsg = 0;
qsg->nalloc = alloc_hint;
qsg->size = 0;
qsg->as = as;
+ qsg->dev = dev;
+ object_ref(OBJECT(dev));
}
void qemu_sglist_add(QEMUSGList *qsg, dma_addr_t base, dma_addr_t len)
@@ -57,6 +60,7 @@ void qemu_sglist_add(QEMUSGList *qsg, dma_addr_t base,
dma_addr_t len)
void qemu_sglist_destroy(QEMUSGList *qsg)
{
+ object_unref(OBJECT(qsg->dev));
g_free(qsg->sg);
memset(qsg, 0, sizeof(*qsg));
}
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 1adfa0b..6b87549 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -691,7 +691,8 @@ static int ahci_populate_sglist(AHCIDevice *ad, QEMUSGList
*sglist, int offset)
goto out;
}
- qemu_sglist_init(sglist, (sglist_alloc_hint - off_idx), ad->hba->as);
+ qemu_sglist_init(sglist, DEVICE(ad->hba), (sglist_alloc_hint -
off_idx),
+ ad->hba->as);
qemu_sglist_add(sglist, le64_to_cpu(tbl[off_idx].addr + off_pos),
le32_to_cpu(tbl[off_idx].flags_size) + 1 - off_pos);
diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index a1952b0..84288ae 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -70,7 +70,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, DEVICE(m), io->len / MACIO_PAGE_SIZE + 1,
&address_space_memory);
qemu_sglist_add(&s->sg, io->addr, io->len);
io->addr += io->len;
@@ -127,7 +127,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, DEVICE(m), io->len / MACIO_PAGE_SIZE + 1,
&address_space_memory);
qemu_sglist_add(&s->sg, io->addr, io->len);
io->addr += io->len;
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index 7ee7d97..65ccb09 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -232,7 +232,7 @@ static int megasas_map_sgl(MegasasState *s, MegasasCmd
*cmd, union mfi_sgl *sgl)
MEGASAS_MAX_SGE);
return iov_count;
}
- qemu_sglist_init(&cmd->qsg, iov_count, pci_get_address_space(&s->dev));
+ pci_dma_sglist_init(&cmd->qsg, &s->dev, iov_count);
for (i = 0; i < iov_count; i++) {
dma_addr_t iov_pa, iov_size_p;
@@ -628,7 +628,7 @@ static int megasas_map_dcmd(MegasasState *s, MegasasCmd
*cmd)
}
iov_pa = megasas_sgl_get_addr(cmd, &cmd->frame->dcmd.sgl);
iov_size = megasas_sgl_get_len(cmd, &cmd->frame->dcmd.sgl);
- qemu_sglist_init(&cmd->qsg, 1, pci_get_address_space(&s->dev));
+ pci_dma_sglist_init(&cmd->qsg, &s->dev, 1);
qemu_sglist_add(&cmd->qsg, iov_pa, iov_size);
cmd->iov_size = iov_size;
return cmd->iov_size;
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index b8a0abf..712f0ad 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -77,10 +77,12 @@ static void virtio_scsi_bad_req(void)
exit(1);
}
-static void qemu_sgl_init_external(QEMUSGList *qsgl, struct iovec *sg,
+static void qemu_sgl_init_external(VirtIOSCSIReq *req, struct iovec *sg,
hwaddr *addr, int num)
{
- qemu_sglist_init(qsgl, num, &address_space_memory);
+ QEMUSGList *qsgl = &req->qsgl;
+
+ qemu_sglist_init(qsgl, DEVICE(req->dev), num, &address_space_memory);
while (num--) {
qemu_sglist_add(qsgl, *(addr++), (sg++)->iov_len);
}
@@ -99,11 +101,11 @@ static void virtio_scsi_parse_req(VirtIOSCSI *s, VirtQueue
*vq,
req->resp.buf = req->elem.in_sg[0].iov_base;
if (req->elem.out_num > 1) {
- qemu_sgl_init_external(&req->qsgl, &req->elem.out_sg[1],
+ qemu_sgl_init_external(req, &req->elem.out_sg[1],
&req->elem.out_addr[1],
req->elem.out_num - 1);
} else {
- qemu_sgl_init_external(&req->qsgl, &req->elem.in_sg[1],
+ qemu_sgl_init_external(req, &req->elem.in_sg[1],
&req->elem.in_addr[1],
req->elem.in_num - 1);
}
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 1ad2159..79caa63 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -1245,7 +1245,7 @@ static int ehci_init_transfer(EHCIPacket *p)
cpage = get_field(p->qtd.token, QTD_TOKEN_CPAGE);
bytes = get_field(p->qtd.token, QTD_TOKEN_TBYTES);
offset = p->qtd.bufptr[0] & ~QTD_BUFPTR_MASK;
- qemu_sglist_init(&p->sgl, 5, p->queue->ehci->as);
+ qemu_sglist_init(&p->sgl, DEVICE(p->queue->ehci), 5, p->queue->ehci->as);
while (bytes > 0) {
if (cpage > 4) {
@@ -1484,7 +1484,7 @@ static int ehci_process_itd(EHCIState *ehci,
return -1;
}
- qemu_sglist_init(&ehci->isgl, 2, ehci->as);
+ qemu_sglist_init(&ehci->isgl, DEVICE(ehci), 2, ehci->as);
if (off + len > 4096) {
/* transfer crosses page border */
uint32_t len2 = off + len - 4096;
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 6ef1f97..de406d6 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -702,7 +702,7 @@ static inline void pci_dma_unmap(PCIDevice *dev, void
*buffer, dma_addr_t len,
static inline void pci_dma_sglist_init(QEMUSGList *qsg, PCIDevice *dev,
int alloc_hint)
{
- qemu_sglist_init(qsg, alloc_hint, pci_get_address_space(dev));
+ qemu_sglist_init(qsg, DEVICE(dev), alloc_hint, pci_get_address_space(dev));
}
extern const VMStateDescription vmstate_pci_device;
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
index 031d1f5..00f21f3 100644
--- a/include/sysemu/dma.h
+++ b/include/sysemu/dma.h
@@ -29,6 +29,7 @@ struct QEMUSGList {
int nsg;
int nalloc;
size_t size;
+ DeviceState *dev;
AddressSpace *as;
};
@@ -189,7 +190,8 @@ struct ScatterGatherEntry {
dma_addr_t len;
};
-void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint, AddressSpace *as);
+void qemu_sglist_init(QEMUSGList *qsg, DeviceState *dev, int alloc_hint,
+ AddressSpace *as);
void qemu_sglist_add(QEMUSGList *qsg, dma_addr_t base, dma_addr_t len);
void qemu_sglist_destroy(QEMUSGList *qsg);
#endif
--
1.8.1.4
- [Qemu-devel] [PATCH 00/39] Delay destruction of memory regions to instance_finalize, Paolo Bonzini, 2013/06/04
- [Qemu-devel] [PATCH 01/39] scsi: keep device alive while it has requests, Paolo Bonzini, 2013/06/04
- [Qemu-devel] [PATCH 02/39] dma: keep a device alive while it has SGLists,
Paolo Bonzini <=
- [Qemu-devel] [PATCH 03/39] pci: split exit and finalize, Paolo Bonzini, 2013/06/04
- [Qemu-devel] [PATCH 04/39] ac97: use instance_finalize instead of exit, Paolo Bonzini, 2013/06/04
- [Qemu-devel] [PATCH 05/39] es1370: use instance_finalize instead of exit, Paolo Bonzini, 2013/06/04
- [Qemu-devel] [PATCH 06/39] hda: split exit and instance_finalize, Paolo Bonzini, 2013/06/04
- [Qemu-devel] [PATCH 07/39] serial: split exit and instance_finalize, Paolo Bonzini, 2013/06/04
- [Qemu-devel] [PATCH 08/39] tpci200: use instance_finalize instead of exit, Paolo Bonzini, 2013/06/04
- [Qemu-devel] [PATCH 09/39] pci-assign: split exit and instance_finalize, Paolo Bonzini, 2013/06/04