Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 20 Jan 2003 16:17:12 +0100
From:      Thomas Moestl <tmm@freebsd.org>
To:        Harti Brandt <brandt@fokus.gmd.de>
Cc:        sparc@freebsd.org
Subject:   Re: Problem with iommu_dvmamap_create
Message-ID:  <20030120151712.GA240@crow.dom2ip.de>
In-Reply-To: <20030120103814.X45050@beagle.fokus.gmd.de>
References:  <20030117151958.U715@beagle.fokus.gmd.de> <20030117160857.GB304@crow.dom2ip.de> <20030117171317.F44530@beagle.fokus.gmd.de> <20030117171111.GC304@crow.dom2ip.de> <20030117181111.R45050@beagle.fokus.gmd.de> <20030117173303.GD304@crow.dom2ip.de> <20030120103814.X45050@beagle.fokus.gmd.de>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, 2003/01/20 at 10:52:11 +0100, Harti Brandt wrote:
> On Fri, 17 Jan 2003, Thomas Moestl wrote:
> 
> TM>On Fri, 2003/01/17 at 18:19:59 +0100, Harti Brandt wrote:
> TM>> On Fri, 17 Jan 2003, Thomas Moestl wrote:
> TM>> TM>BUS_DMAMAP_NSEGS (and BUS_SPACE_MAXSIZE) is pretty arbitrary, the only
> TM>> TM>thing to limit is the stack space used by the segment array. In the
> TM>> TM>current setting, 272 bytes are used at most, which is less than 1.5
> TM>> TM>minimal function frames. Values such as 64 should still be OK.
> TM>>
> TM>> Would it be possible if you change it just there?
> TM>
> TM>Yes, I'll do that with the next update.
> 
> Thanks.
> 
> Just while I could not sleep last night, it occured to me, that the code
> should work without even this change when the kernel is compiled with gcc.
> The code in iommu.c and bus_machdep.c use #ifdef __GNUC__ to use dynamic
> arrays on stack that have size ddmat->dt_nsegements size. So if I create a
> tag with a number of segments large enough, the arrays should be large
> enough. The only problem should be, that the size check around line 823 in
> iommu.c should also be conditionalized (for __GCC__ BUS_DMAMAP_NSEGS
> should not be checked.) Well, for some reason, that seems not to work.

Hmmm, how does it fail?

> TM>So do I. Can you maybe put the full code of the driver in question
> TM>somewhere for download?
> 
> Ok, I've put if_hatm.tar.bz into
> ftp://ftp.fokus.gmd.de/pub/cats/usr/harti/ngatm. Beware, this is my
> working code. The tag in question is the tx_tag and is created in
> if_hatm.c:1699. The DMAMAPs with this tag are create in if_hatm.c:465.
> They are used then in if_hatm_tx.c. The bug is triggered, however, even by
> only creating them. The first sign of the bug is that the card does not
> update the interrupt status words. These are dma-ed into the queue
> controlled by the irq_0 member of struct hatm_softc. I suppose the DMA
> goes somewhere else, because soon after that usually something bad happens
> to the system.

From a quick inspection, I can see one class of problems (which might
or might not be the cause for this specific behaviour, but will cause
trouble in any case): you need to do endiannes conversions for memory
that is accessed by DMA and interpreted or written by the
adapter. Since it is a PCI card, it operates on little-endian
data. While the bus_space_* functions know the access size and will
automatically do endianess conversions for you (unless you use the
stream variants of them), there is no way to automatically do this for
DMA (unless we can guarantee that the access size is always the
desired datum size, which we cannot, and even then it would be
non-portable).
This would e.g. explain a bogus interrupt status word: since it is
written by the adapter, it needs to be converted to host byte order 
before it is interpreted; the following:

	while (q->head != tail) {
		status = q->irq[q->head];
		q->irq[q->head] = HE_REGM_ITYPE_INVALID;

would become:

	while (q->head != tail) {
		status = le32toh(q->irq[q->head]);
		q->irq[q->head] = htole32(HE_REGM_ITYPE_INVALID);

Similarly, the fields in the various descriptor structures defined in
if_hatmreg.h need to be converted (since it looks like the adapter
DMAs them to find out target addresses etc.). This would cause wrong
addresses to be used for DMA; it's not unlikely that those addresses
would be outside of the target address space of the host bridge, so
they could be interpreted as writes to other PCI devices (or cause bus
errors if there is no such target device).

	- Thomas

-- 
Thomas Moestl <tmoestl@gmx.net>	http://www.tu-bs.de/~y0015675/
              <tmm@FreeBSD.org>	http://people.FreeBSD.org/~tmm/
PGP fingerprint: 1C97 A604 2BD0 E492 51D0  9C0F 1FE6 4F1D 419C 776C

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




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