Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 11 Apr 2000 21:57:35 -0600
From:      Warner Losh <imp@village.org>
To:        freebsd-hackers@freebsd.org
Subject:   PCI DMA Questions
Message-ID:  <200004120357.VAA34787@harmony.village.org>

next in thread | raw e-mail | index | archive | help

I'm debugging a hunk of PCI hardware that I have under NDA.  It
doesn't seem to be initiating DMA transfers.  This may be a hardware
problem, but before I go back to the vendor, I want to make sure that
I'm doing the DMA initialization right.  It was my understanding that
DMA just happened on the PCI bus and nothing special was needed.

Here's what I'm doing in my attach routine.  Most of this code was
culled from ahc.c and friends.

	/* Create "master" or parent dma tag for all dma entities */
	/* XXX Should be child of pci bus dma tag */
	err = bus_dma_tag_create(NULL, 1, 0, BUS_SPACE_MAXADDR_32BIT,
	    BUS_SPACE_MAXADDR, NULL, NULL, MAXBSIZE, NSEG,
	    DMA_TRANSFER_SIZE, BUS_DMA_ALLOCNOW, &sc->parent_dmat);
	if (err) { bail; }
	sc->dma_init_level = 1;
	/* Create the dma tags for our data */
	err = bus_dma_tag_create(sc->parent_dmat, 4, 0, 
	    BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
	    MAX_DATUM_SIZE, DATUM_COUNT, 
	    BUS_SPACE_MAXSIZE_32BIT, 0, &sc->datum_dmat);
	if (err) { bail; }
	sc->dma_init_level++;
	for (i = 0; i < BUFFER_COUNT; i++) {
		/* Allocate them */
		if (bus_dmamem_alloc(sc->datum_dmat, 
		    (void *) &sc->BM_buf[i], BUS_DMA_NOWAIT,
		    &sc->datum_dmamap[i]) != 0) { bail; }

		/* And permanently map them */
		bus_dmamap_load(sc->datum_dmat, sc->datum_dmamap[i], 
		    sc->BM_buf[i], MAX_DATUM_SIZE, mydmamapcb,
		    &sc->phy_add[i], 0);
	}
	sc->dma_init_level++;

When I want to do DMA from the chip, I pass sc->phy_add[i] to the DMA
target address register on the pci card.  I then copyout the data that 
BM_buf[i] points to in a ioctl.

Trouble is, the hardware interrupts, but its DMA target length
register (which acts like uio->uio_resid) hasn't changed, indicating
that no data was transferred.

So, I thought I'd post here asking to see if I'm using this
undocumented interface correctly.  The NetBSD man pages describe a
later version of this interface, and I can't seem to find a
description of the old interface.  Likely a good thing since this
interface won't cope well on machine that don't have a coherent cache
wrt DMA (think MIPS).

Am I doing this right?  Is there something unobviously named that is
used to "start" the DMA or tell some DMA controller that DMA is going
to happen?  I didn't see anything in any of the pci drivers, and I
don't recall ever having to deal with this in the past.

If I get enough help, I'll do a followup article to the "how to write
a bog-simple newbus/busspaced driver on FreeBSD 4 or newer" talking
about the dma busspace in freebsd. :-)

Warner


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200004120357.VAA34787>