mirror of
https://github.com/qemu/qemu.git
synced 2024-12-16 16:53:28 +08:00
hw/dma/xilinx_axidma: mm2s: Stream descriptor by descriptor
Stream descriptor by descriptor from memory instead of buffering entire packets before pushing. This enables non-packet streaming clients to work and also lifts the limitation that our internal DMA buffer needs to be able to hold entire packets. Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Message-Id: <20200506082513.18751-8-edgar.iglesias@gmail.com>
This commit is contained in:
parent
2a4f26350c
commit
471fe8a252
@ -111,7 +111,6 @@ struct Stream {
|
||||
int nr;
|
||||
|
||||
struct SDesc desc;
|
||||
int pos;
|
||||
unsigned int complete_cnt;
|
||||
uint32_t regs[R_MAX];
|
||||
uint8_t app[20];
|
||||
@ -267,7 +266,9 @@ static void stream_process_mem2s(struct Stream *s, StreamSlave *tx_data_dev,
|
||||
StreamSlave *tx_control_dev)
|
||||
{
|
||||
uint32_t prev_d;
|
||||
unsigned int txlen;
|
||||
uint32_t txlen;
|
||||
uint64_t addr;
|
||||
bool eop;
|
||||
|
||||
if (!stream_running(s) || stream_idle(s)) {
|
||||
return;
|
||||
@ -282,24 +283,26 @@ static void stream_process_mem2s(struct Stream *s, StreamSlave *tx_data_dev,
|
||||
}
|
||||
|
||||
if (stream_desc_sof(&s->desc)) {
|
||||
s->pos = 0;
|
||||
stream_push(tx_control_dev, s->desc.app, sizeof(s->desc.app), true);
|
||||
}
|
||||
|
||||
txlen = s->desc.control & SDESC_CTRL_LEN_MASK;
|
||||
if ((txlen + s->pos) > sizeof s->txbuf) {
|
||||
hw_error("%s: too small internal txbuf! %d\n", __func__,
|
||||
txlen + s->pos);
|
||||
|
||||
eop = stream_desc_eof(&s->desc);
|
||||
addr = s->desc.buffer_address;
|
||||
while (txlen) {
|
||||
unsigned int len;
|
||||
|
||||
len = txlen > sizeof s->txbuf ? sizeof s->txbuf : txlen;
|
||||
address_space_read(&s->dma->as, addr,
|
||||
MEMTXATTRS_UNSPECIFIED,
|
||||
s->txbuf, len);
|
||||
stream_push(tx_data_dev, s->txbuf, len, eop && len == txlen);
|
||||
txlen -= len;
|
||||
addr += len;
|
||||
}
|
||||
|
||||
address_space_read(&s->dma->as, s->desc.buffer_address,
|
||||
MEMTXATTRS_UNSPECIFIED,
|
||||
s->txbuf + s->pos, txlen);
|
||||
s->pos += txlen;
|
||||
|
||||
if (stream_desc_eof(&s->desc)) {
|
||||
stream_push(tx_data_dev, s->txbuf, s->pos, true);
|
||||
s->pos = 0;
|
||||
if (eop) {
|
||||
stream_complete(s);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user