Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 14 Jun 2009 13:47:54 -0500
From:      "Rick C. Petty" <rick-freebsd2008@kiwi-computer.com>
To:        Alexander Motin <mav@FreeBSD.org>
Cc:        freebsd-multimedia@freebsd.org
Subject:   Re: snd_hda works on i386, fails on amd64 (RELENG_7)
Message-ID:  <20090614184754.GA72664@keira.kiwi-computer.com>
In-Reply-To: <4A34A663.2010503@FreeBSD.org>
References:  <1242609781.00113421.1242598202@10.7.7.3> <4A122B72.80206@FreeBSD.org> <20090519184150.GA990@keira.kiwi-computer.com> <20090605020054.GA67365@keira.kiwi-computer.com> <4A28D79C.6070406@FreeBSD.org> <20090614050211.GA67556@keira.kiwi-computer.com> <20090614062157.GA67705@keira.kiwi-computer.com> <4A34A663.2010503@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, Jun 14, 2009 at 10:27:31AM +0300, Alexander Motin wrote:
> Rick C. Petty wrote:
> >
> >Hmm, I looked at the place that queries support_64bit, in hdac_dma_alloc as
> >part of the lowaddr to the bus_dma_tag_create(9) call:
> >
> >	lowaddr = (sc->support_64bit) ? BUS_SPACE_MAXADDR :
> >	    BUS_SPACE_MAXADDR_32BIT;
> >	...
> >
> >On a whim, I tried manually setting lowaddr to BUS_SPACE_MAXADDR_24BIT and
> >it worked!  A binary search revealed that it breaks for me when
> >lowaddr > 0x7FFFFFFF ... perhaps a 32-bit overflow bug related to DMA?
> 
> You are right. There is definitely overflow. Try this:
> 
> --- hdac.c.prev 2009-04-01 21:55:08.000000000 +0300
> +++ hdac.c      2009-06-14 10:24:18.000000000 +0300
> @@ -1589,9 +1589,9 @@ hdac_dma_cb(void *callback_arg, bus_dma_
>  static int
>  hdac_dma_alloc(struct hdac_softc *sc, struct hdac_dma *dma, bus_size_t 
> size)
>  {
> +       bus_addr_t lowaddr;
>         bus_size_t roundsz;
>         int result;
> -       int lowaddr;
> 
>         roundsz = roundup2(size, HDAC_DMA_ALIGNMENT);
>         lowaddr = (sc->support_64bit) ? BUS_SPACE_MAXADDR :

That helped.  I still need to set sc->support_64bit to 0 in
hdac_get_capabilities().

I added code so I can override this setting using device.hints.  Could you
maybe see about getting the following code committed?  Feel free to fix it
up as necessary.  Thank you,

-- Rick C. Petty


--- src/sys/dev/sound/pci/hda/hdac.c.orig	2009-03-30 05:18:43.000000000 -0500
+++ src/sys/dev/sound/pci/hda/hdac.c	2009-06-14 13:15:14.000000000 -0500
@@ -1510,6 +1510,7 @@
 static int
 hdac_get_capabilities(struct hdac_softc *sc)
 {
+	uint32_t flags;
 	uint16_t gcap;
 	uint8_t corbsize, rirbsize;
 
@@ -1519,6 +1520,9 @@
 	sc->num_bss = HDAC_GCAP_BSS(gcap);
 
 	sc->support_64bit = HDA_FLAG_MATCH(gcap, HDAC_GCAP_64OK);
+	flags = device_get_flags(sc->dev);
+	if (flags & 32)
+		sc->support_64bit = 0;
 
 	corbsize = HDAC_READ_1(&sc->mem, HDAC_CORBSIZE);
 	if ((corbsize & HDAC_CORBSIZE_CORBSZCAP_256) ==
@@ -1591,9 +1595,9 @@
 static int
 hdac_dma_alloc(struct hdac_softc *sc, struct hdac_dma *dma, bus_size_t size)
 {
+	bus_addr_t lowaddr;
 	bus_size_t roundsz;
 	int result;
-	int lowaddr;
 
 	roundsz = roundup2(size, HDAC_DMA_ALIGNMENT);
 	lowaddr = (sc->support_64bit) ? BUS_SPACE_MAXADDR :

--- /usr/src/share/man/man4/snd_hda.4.orig	2009-01-11 09:43:13.000000000 -0600
+++ /usr/src/share/man/man4/snd_hda.4	2009-06-14 13:44:38.000000000 -0500
@@ -145,6 +145,16 @@
 or as a set of space-separated
 .Dq Ar option Ns = Ns Ar value
 pairs.
+.It Va hint.hdac.%d.flags
+Additional configuration settings.
+.El
+.Pp
+Meaning of
+.Ar flags :
+.Bl -tag -width "0x00" -offset indent -compact
+.It 0x20
+Force device to use 32-bit DMA address (under 4GB), even if the device
+capabilities states that the device supports 64-bit operation.
 .El
 .Pp
 Pin configuration is the UAA driver's main source of information about codec



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