Garbage inserted in DMA transmission

Sebastien Bourdeauducq sebastien.bourdeauducq at gmail.com
Mon Nov 27 10:17:48 PST 2006


Hello,

I'm trying to send data to a device over PCI DMA. I set up the buffer
and the map as follows :

pci_enable_busmaster(dev);
bus_dma_tag_create(NULL, 4, 0, BUS_SPACE_MAXADDR_32BIT,
BUS_SPACE_MAXADDR, NULL, NULL, sizeof(struct isl38xx_cb), 1,
sizeof(struct isl38xx_cb), 0, NULL, NULL, &sc->bus.pci.cb_tag);
bus_dmamem_alloc(sc->bus.pci.cb_tag, (void **)&sc->bus.pci.cb,
BUS_DMA_NOWAIT|BUS_DMA_ZERO|BUS_DMA_COHERENT, &sc->bus.pci.cb_map);
bus_dmamap_load(sc->bus.pci.cb_tag, sc->bus.pci.cb_map,
&sc->bus.pci.cb, sizeof(struct isl38xx_cb), p54u_dma_map_addr,
&sc->bus.pci.cb_dma_addr, BUS_DMA_NOWAIT);

The callback function of bus_dmamap_load is :
static void p54u_dma_map_addr(void *arg, bus_dma_segment_t *segs, int
nseg, int error)
{
	uint32_t *paddr;

	if(error) return;

	paddr = arg;
	*paddr = segs->ds_addr;
}

Then, I write data to sc->bus.pci.cb, issue a PRE_WRITE sync request
and make the device download the frame. However, where the device
should read 0 ; 1 ; 0 ; 0 ; 0 ; 0 ; 0 ; ... (32-bit words) it instead
gets :
0000: c2c23800 00000000 038c9020 00000001
0010: c4690c00 00000000 c2bcf100 c4727d00
0020: 00000000 c4727d40 00000000 c47398c0
0030: 00000000 c4739b00 00000000 c4727cc0
0040: 00000000 c474fb00 00000000 c474fac0
0050: 00000000 c474fa80 00000000 c474fa40
....

When reading sc->bus.pci.cb from the host, I get the good values, not
those strange words.

038c9020 is the PCI address of the mapping, I don't know what the
other weird values are (c2c23800, c4690c00 ...). Any idea ? Looks like
the device is reading data from the wrong place and gets some PCI
configuration stuff instead...

Full source code of the driver is at
http://svnweb.tuxfamily.org/listing.php?repname=p54u+%28prism54%29&path=%2F&sc=0
See p54u.c, function p54u_attach(), and transport.c, function
p54u_pci_dma_submit().

Regards,

Sebastien


More information about the freebsd-drivers mailing list