From owner-freebsd-sparc Mon Jan 20 7:15:54 2003 Delivered-To: freebsd-sparc@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 8D55C37B405 for ; Mon, 20 Jan 2003 07:15:51 -0800 (PST) Received: from mail.gmx.net (mail.gmx.net [213.165.65.60]) by mx1.FreeBSD.org (Postfix) with SMTP id 4CDF543F13 for ; Mon, 20 Jan 2003 07:15:50 -0800 (PST) (envelope-from tmoestl@gmx.net) Received: (qmail 12392 invoked by uid 0); 20 Jan 2003 15:15:48 -0000 Received: from p508E7032.dip.t-dialin.net (HELO galatea.local) (80.142.112.50) by mail.gmx.net (mp002-rz3) with SMTP; 20 Jan 2003 15:15:48 -0000 Received: from localhost ([127.0.0.1] helo=galatea.local) by galatea.local with esmtp (Exim 4.12 #1) id 18adfu-0000Hl-00; Mon, 20 Jan 2003 16:17:22 +0100 Received: (from tmm@localhost) by galatea.local (8.12.6/8.12.6/Submit) id h0KFHCdJ001100; Mon, 20 Jan 2003 16:17:12 +0100 (CET) Date: Mon, 20 Jan 2003 16:17:12 +0100 From: Thomas Moestl To: Harti Brandt Cc: sparc@freebsd.org Subject: Re: Problem with iommu_dvmamap_create Message-ID: <20030120151712.GA240@crow.dom2ip.de> Mail-Followup-To: Harti Brandt , sparc@freebsd.org 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> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20030120103814.X45050@beagle.fokus.gmd.de> User-Agent: Mutt/1.4i Sender: owner-freebsd-sparc@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org 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 http://www.tu-bs.de/~y0015675/ 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