On 2012年04月17日 16:46, Paolo Bonzini wrote:
Il 16/04/2012 14:14, Stefan Hajnoczi ha scritto:
Why are you removing the rearm behavior? I'm pretty sure other ISA
devices rely on this otherwise the code wouldn't exist.
Li is correct in that the code can be simplified a lot, but indeed his
axe went a bit too far. :)
With the exception of the floppy all other DMA devices do not reenter
DMA_run, and do not need the idle bottom half hack because DMA is done
once per interrupt. And now that the floppy is asynchronous it doesn't
need the idle bottom half hack, either.
So DMA_run can call channel_run from a while loop like this:
while ((0 == (d->mask& mask))&& (0 != (d->status& (mask<< 4)))) {
// pseudo-code, channel_running and channel_is_asynchronous
// would be fields in dma_regs
if (channel_running[ichan]) {
assert(channel_is_asynchronous[ichan]);
break;
}
channel_running[ichan]++;
channel_run (icont, ichan);
// channel_is_asynchronous would be set by a new function
// DMA_register_channel_async.
if (channel_is_asynchronous[ichan]) {
break;
}
channel_running[ichan]--;
}
and DMA_set_return needs to do a tail call to "complete" the while loop:
assert(channel_is_asynchronous[ichan]);
assert(channel_running[ichan] == 1);
channel_running[ichan]--;
if ((0 == (d->mask& mask))&& (0 != (d->status& (mask<< 4)))) {
channel_run (icont, ichan);
}
Paolo
Thank you very much for giving me suggestions, I have tried the method,
it works well. But I also have another idea, I modify fdc.c by adding a
flag to avoid re-enter, I have tested it. I will send a patch later. If
you have any comments, please give me your opinion. thanks.