Revision 37b7842c
b/dma-helpers.c | ||
---|---|---|
39 | 39 |
} |
40 | 40 |
|
41 | 41 |
typedef struct { |
42 |
BlockDriverAIOCB common; |
|
42 | 43 |
BlockDriverState *bs; |
43 | 44 |
BlockDriverAIOCB *acb; |
44 | 45 |
QEMUSGList *sg; |
... | ... | |
48 | 49 |
target_phys_addr_t sg_cur_byte; |
49 | 50 |
QEMUIOVector iov; |
50 | 51 |
QEMUBH *bh; |
51 |
} DMABlockState;
|
|
52 |
} DMAAIOCB;
|
|
52 | 53 |
|
53 | 54 |
static void dma_bdrv_cb(void *opaque, int ret); |
54 | 55 |
|
55 | 56 |
static void reschedule_dma(void *opaque) |
56 | 57 |
{ |
57 |
DMABlockState *dbs = (DMABlockState *)opaque;
|
|
58 |
DMAAIOCB *dbs = (DMAAIOCB *)opaque;
|
|
58 | 59 |
|
59 | 60 |
qemu_bh_delete(dbs->bh); |
60 | 61 |
dbs->bh = NULL; |
... | ... | |
63 | 64 |
|
64 | 65 |
static void continue_after_map_failure(void *opaque) |
65 | 66 |
{ |
66 |
DMABlockState *dbs = (DMABlockState *)opaque;
|
|
67 |
DMAAIOCB *dbs = (DMAAIOCB *)opaque;
|
|
67 | 68 |
|
68 | 69 |
dbs->bh = qemu_bh_new(reschedule_dma, dbs); |
69 | 70 |
qemu_bh_schedule(dbs->bh); |
... | ... | |
71 | 72 |
|
72 | 73 |
static void dma_bdrv_cb(void *opaque, int ret) |
73 | 74 |
{ |
74 |
DMABlockState *dbs = (DMABlockState *)opaque;
|
|
75 |
DMAAIOCB *dbs = (DMAAIOCB *)opaque;
|
|
75 | 76 |
target_phys_addr_t cur_addr, cur_len; |
76 | 77 |
void *mem; |
77 | 78 |
int i; |
78 | 79 |
|
80 |
dbs->acb = NULL; |
|
79 | 81 |
dbs->sector_num += dbs->iov.size / 512; |
80 | 82 |
for (i = 0; i < dbs->iov.niov; ++i) { |
81 | 83 |
cpu_physical_memory_unmap(dbs->iov.iov[i].iov_base, |
... | ... | |
85 | 87 |
qemu_iovec_reset(&dbs->iov); |
86 | 88 |
|
87 | 89 |
if (dbs->sg_cur_index == dbs->sg->nsg || ret < 0) { |
88 |
dbs->acb->cb(dbs->acb->opaque, ret);
|
|
90 |
dbs->common.cb(dbs->common.opaque, ret);
|
|
89 | 91 |
qemu_iovec_destroy(&dbs->iov); |
90 |
qemu_aio_release(dbs->acb); |
|
91 |
qemu_free(dbs); |
|
92 |
qemu_aio_release(dbs); |
|
92 | 93 |
return; |
93 | 94 |
} |
94 | 95 |
|
... | ... | |
112 | 113 |
} |
113 | 114 |
|
114 | 115 |
if (dbs->is_write) { |
115 |
bdrv_aio_writev(dbs->bs, dbs->sector_num, &dbs->iov, |
|
116 |
dbs->iov.size / 512, dma_bdrv_cb, dbs); |
|
116 |
dbs->acb = bdrv_aio_writev(dbs->bs, dbs->sector_num, &dbs->iov,
|
|
117 |
dbs->iov.size / 512, dma_bdrv_cb, dbs);
|
|
117 | 118 |
} else { |
118 |
bdrv_aio_readv(dbs->bs, dbs->sector_num, &dbs->iov, |
|
119 |
dbs->iov.size / 512, dma_bdrv_cb, dbs); |
|
119 |
dbs->acb = bdrv_aio_readv(dbs->bs, dbs->sector_num, &dbs->iov,
|
|
120 |
dbs->iov.size / 512, dma_bdrv_cb, dbs);
|
|
120 | 121 |
} |
121 | 122 |
} |
122 | 123 |
|
... | ... | |
125 | 126 |
BlockDriverCompletionFunc *cb, void *opaque, |
126 | 127 |
int is_write) |
127 | 128 |
{ |
128 |
DMABlockState *dbs = qemu_malloc(sizeof(*dbs));
|
|
129 |
DMAAIOCB *dbs = qemu_aio_get_pool(&dma_aio_pool, bs, cb, opaque);
|
|
129 | 130 |
|
131 |
dbs->acb = NULL; |
|
130 | 132 |
dbs->bs = bs; |
131 |
dbs->acb = qemu_aio_get_pool(&dma_aio_pool, bs, cb, opaque); |
|
132 | 133 |
dbs->sg = sg; |
133 | 134 |
dbs->sector_num = sector_num; |
134 | 135 |
dbs->sg_cur_index = 0; |
... | ... | |
137 | 138 |
dbs->bh = NULL; |
138 | 139 |
qemu_iovec_init(&dbs->iov, sg->nsg); |
139 | 140 |
dma_bdrv_cb(dbs, 0); |
140 |
return dbs->acb;
|
|
141 |
return &dbs->common;
|
|
141 | 142 |
} |
142 | 143 |
|
143 | 144 |
|
... | ... | |
157 | 158 |
|
158 | 159 |
static void dma_aio_cancel(BlockDriverAIOCB *acb) |
159 | 160 |
{ |
160 |
DMABlockState *dbs = (DMABlockState *)acb->opaque;
|
|
161 |
DMAAIOCB *dbs = container_of(acb, DMAAIOCB, common);
|
|
161 | 162 |
|
162 |
bdrv_aio_cancel(dbs->acb); |
|
163 |
if (dbs->acb) { |
|
164 |
bdrv_aio_cancel(dbs->acb); |
|
165 |
} |
|
163 | 166 |
} |
164 | 167 |
|
165 | 168 |
void dma_helper_init(void) |
166 | 169 |
{ |
167 |
aio_pool_init(&dma_aio_pool, sizeof(BlockDriverAIOCB), dma_aio_cancel);
|
|
170 |
aio_pool_init(&dma_aio_pool, sizeof(DMAAIOCB), dma_aio_cancel);
|
|
168 | 171 |
} |
Also available in: Unified diff