lkml.org 
[lkml]   [2005]   [Dec]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: Strange delay on PCI-DMA-transfer completion by wait_event_interruptible()
>On Tue, 13 Dec 2005, [iso-8859-1] Burkhard Schölpen wrote:
>
>> Thanks a lot for your answer!
>> I just tried out interruptible_sleep_on(), but couriously I got the same
>> delay as before. On the hardware side, everything seems to be okay, because
>> the data I'm transferring is relayed to a printhead of a laser printer (by an
>> FPGA on the PCI-Board), whose LEDs light up as expected. The programmer of
>> the FPGA (sitting next to me) says there would be no interrupt in the case of
>> an error (so probably I should sleep with a timeout). But as there is an
>> interrupt (and MY_DMA_COUNT_REGISTER contains really 0) in fact, I think the
>> dma transfer succeeds, or could that be misleading? The only problem seems
>> to be, that the interrupt comes much later, if I put the user process to
>> sleep than let it do busy waiting. Do you have any idea, what could cause
>> this strange behaviour? Could it be concerned with my SMP kernel (I use a
>> processor with 2 cores)?
>>
"linux-os \(Dick Johnson\)" <linux-os@analogic.com> schrieb am 13.12.05 15:30:33:
>
>I think I know what is happening. You are writing the count across the
>PCI bus, thinking this will start the DMA transfer. However, the count
>won't actually get to the device until the PCI interface is flushed
>(it's a FIFO, waiting for more activity). You need to force that
>write to occur NOW, by performing a dummy read in your address-space
>on the PCI bus.
>
>Then, you should find that the DMA seems to occur instantly and you
>get your interrupt when you expect it. We use the PLX PCI 9656BA
>for PCI interface on our datalink boards so I have a lot of
>experience in this area.
>
>In the case where you were polling the interface, the first read
>if its status actually flushed the PCI bus and started the DMA
>transfer. In the cases where you weren't polling, the count
>got to the device whenever the PCI interface timed-out or when
>there was other activity such as network.

Thank you for your help! The dummy read was a very helpful hint to get the DMA stuff more reliable (although the fpga programmer had to admit that there was some other problem in the hardware after all). I think it should work fine soon.

I'm glad to meet somebody with dma experience, because I have some other difficulties concerning DMA buffers in RAM. The PCI-Board is to be applied in a large size copying machine, so it essentially has to transfer tons of data in 2 directions very fast without wasting cpu time (because the cpu has to run many image processing algorithms meanwhile on this data). So my approach is to allocate a quite large ringbuffer in kernel space (or more precisely one ringbuffer for each direction) which is capable of dma. Afterwards I would map this buffer to user space to avoid unnecessary memcopies/cpu usage. My problem is for now to get such a large DMA buffer. I tried out several things I read in O'Reilly's book, but they all failed so far. My current attempt is to take a high memory area with ioremap:

buffer_addr = ioremap( virt_to_phys(high_memory), large_size );

Mapping this buffer to user space works, but it does not seem to be DMA capable. Maybe it's just wrong to use ioremap() for that? I would be very glad for getting some advice.

Kind regards,
Burkhard

______________________________________________________________
Verschicken Sie romantische, coole und witzige Bilder per SMS!
Jetzt bei WEB.DE FreeMail: http://f.web.de/?mc=021193

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-12-14 09:01    [W:0.712 / U:0.688 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site