Subject: troubles with DMA
To: None <tech-kern@NetBSD.org>
From: Filka Michal <michal.filka@strom.cz>
List: tech-kern
Date: 03/14/2006 13:07:26
Hi all,
I have troubles with DMA in driver for proprietary device
(developed by company I work for). I got things as far as I could
according to man pages and J.Thorpe's paper, but it's still not working
and I have no more ideas.
The device uses DMA for subscribing interrupt vector(s) on particular
interrupt type (of course it generates one interrupt on PIC but there is
an additional info in one of device's register which). Problem is that
when I try to read it in my interrupt handler I have no data in assigned
memory (it is zero-filled).
Any ideas are very welcome.
DMA initialization (reduced) as done in attach callback:
bus_dmamem_alloc( munInfo->pciInfo.pa_dmat, BUF_BUF_SIZE,
PAGE_SIZE,&munInfo->dmaMem[ 0], 1, &munInfo->dmaSegs, 0)
=09
bus_dmamem_map( munInfo->pciInfo.pa_dmat, munInfo->dmaMem,
munInfo->dmaSegs, BUF_BUF_SIZE,=20
&munInfo->dmaBuf, BUS_DMA_NOWAIT | BUS_DMA_NOCACHE )
bus_dmamap_create(
munInfo->pciInfo.pa_dmat,BUF_BUF_SIZE,1,BUF_BUF_SIZE,0,=20
0, &munInfo->dmaMap)
bus_dmamap_load( munInfo->pciInfo.pa_dmat, munInfo->dmaMap,
munInfo->dmaBuf, BUF_BUF_SIZE, NULL, 0)
Next thing I do is that I configure device's DMA related registers.
E.g for the first interrupt queue: pulIntQueue[0]=3DmunInfo->dmaBuf + 0
For the second interrupt queue: pulIntQueue[1]=3DmunInfo->dmaBuf +
INT_QUEUE_SIZE
And so on ... and write those pulIntQueue[ i] into device ...
But as I already said, when I read it in interrupt handler there is
nothing in the pulIntQueue queues=20
(I do PRExxx and POSTxxx before/after each access related code:
DMA_READ_BEGIN( md, md->pulIntQueue[1][uActual]);
while ((ulVect.all =3D md->pulIntQueue[1][uActual])!=3D0)
{
if ((ulVect.mapped.Magic&0xEF)!=3D0xC1)
{
printf("Munich256 (PortInt): ...Magic &
0xEF\n");
continue;
}
if (ulVect.mapped.ASYN)
printf("Munich256 (PortInt): ASYN\n");
if (ulVect.mapped.SYN)
printf("Munich256 (PortInt): SYN\n");
// DMA Read - end
DMA_READ_END( md, md->pulIntQueue[1][uActual]);
// equal to: bus_dmamap_sync( md->pciInfo.pa_dmat,=20
// md->dmaMap,=20
// md->pulIntQueue[1][uActual],
// sizeof( md->pulIntQueue[1][uActual]),=20
// BUS_DMASYNC_PREREAD);
=09
// DMA Write - start
DMA_WRITE_BEGIN( md, md->pulIntQueue[1][uActual]);
// equal to: bus_dmamap_sync( md->pciInfo.pa_dmat,=20
// md->dmaMap,=20
// md->pulIntQueue[1][uActual],
// sizeof( md->pulIntQueue[1][uActual]),=20
// BUS_DMASYNC_PREWRITE);
md->pulIntQueue[1][uActual]=3D0;
// DMA Write - end
DMA_WRITE_END( md, md->pulIntQueue[1][uActual]);
uActual =3D (uActual+1) % INT_QUEUE_SIZE;
// DMA Read - start (for the next iteration) =09
DMA_READ_BEGIN( md, md->pulIntQueue[1][uActual]);
=09
}
DMA_READ_END( md, md->pulIntQueue[1][uActual]);
I know that the device can work (I'm able to run it in an other OS
(Pharlap OS)).
Thank's for answers
Michal Filka