qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] add function DMA_set_return and delete bh_sched


From: Paolo Bonzini
Subject: Re: [Qemu-devel] [PATCH] add function DMA_set_return and delete bh_schedule in dma.c
Date: Tue, 17 Apr 2012 10:46:37 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:11.0) Gecko/20120329 Thunderbird/11.0.1

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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]