snd_hda works on i386, fails on amd64 (RELENG_7)

Alexander Motin mav at FreeBSD.org
Sun Jun 14 07:27:51 UTC 2009


Rick C. Petty wrote:
> On Fri, Jun 05, 2009 at 11:30:20AM +0300, Alexander Motin wrote:
> 
>> Also you may try to change
>> 	sc->support_64bit = HDA_FLAG_MATCH(gcap, HDAC_GCAP_64OK);
>> line to
>> 	sc->support_64bit = 0;
>> , to strictly limit driver to 32bit addresses ignoring hardware
>> capabilities.
> 
> 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 :

-- 
Alexander Motin


More information about the freebsd-multimedia mailing list