svn commit: r194861 - head/sys/dev/sound/pci/hda

Alexander Motin mav at FreeBSD.org
Wed Jun 24 17:03:07 UTC 2009


Author: mav
Date: Wed Jun 24 17:03:06 2009
New Revision: 194861
URL: http://svn.freebsd.org/changeset/base/194861

Log:
  Some DMA related changes:
   - honor parent DMA tag limitations, as man page requires,
   - allow data buffer to be allocated within full 64bit address range, when
     support is announced by hardware,
   - add quirk, disabling 64bit addresses for broken chips, use it for MCP78.

Modified:
  head/sys/dev/sound/pci/hda/hdac.c

Modified: head/sys/dev/sound/pci/hda/hdac.c
==============================================================================
--- head/sys/dev/sound/pci/hda/hdac.c	Wed Jun 24 17:01:17 2009	(r194860)
+++ head/sys/dev/sound/pci/hda/hdac.c	Wed Jun 24 17:03:06 2009	(r194861)
@@ -87,7 +87,7 @@
 
 #include "mixer_if.h"
 
-#define HDA_DRV_TEST_REV	"20090614_0135"
+#define HDA_DRV_TEST_REV	"20090624_0136"
 
 SND_DECLARE_FILE("$FreeBSD$");
 
@@ -474,6 +474,7 @@ static uint32_t hdac_fmt[] = {
 static struct pcmchan_caps hdac_caps = {48000, 48000, hdac_fmt, 0};
 
 #define HDAC_NO_MSI	1
+#define HDAC_NO_64BIT	2
 
 static const struct {
 	uint32_t	model;
@@ -498,10 +499,10 @@ static const struct {
 	{ HDA_NVIDIA_MCP67_2, "NVidia MCP67",	0 },
 	{ HDA_NVIDIA_MCP73_1, "NVidia MCP73",	0 },
 	{ HDA_NVIDIA_MCP73_2, "NVidia MCP73",	0 },
-	{ HDA_NVIDIA_MCP78_1, "NVidia MCP78",	0 },
-	{ HDA_NVIDIA_MCP78_2, "NVidia MCP78",	0 },
-	{ HDA_NVIDIA_MCP78_3, "NVidia MCP78",	0 },
-	{ HDA_NVIDIA_MCP78_4, "NVidia MCP78",	0 },
+	{ HDA_NVIDIA_MCP78_1, "NVidia MCP78",	HDAC_NO_64BIT },
+	{ HDA_NVIDIA_MCP78_2, "NVidia MCP78",	HDAC_NO_64BIT },
+	{ HDA_NVIDIA_MCP78_3, "NVidia MCP78",	HDAC_NO_64BIT },
+	{ HDA_NVIDIA_MCP78_4, "NVidia MCP78",	HDAC_NO_64BIT },
 	{ HDA_NVIDIA_MCP79_1, "NVidia MCP79",	0 },
 	{ HDA_NVIDIA_MCP79_2, "NVidia MCP79",	0 },
 	{ HDA_NVIDIA_MCP79_3, "NVidia MCP79",	0 },
@@ -1593,22 +1594,21 @@ 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;
 
 	roundsz = roundup2(size, HDAC_DMA_ALIGNMENT);
-	lowaddr = (sc->support_64bit) ? BUS_SPACE_MAXADDR :
-	    BUS_SPACE_MAXADDR_32BIT;
 	bzero(dma, sizeof(*dma));
 
 	/*
 	 * Create a DMA tag
 	 */
-	result = bus_dma_tag_create(NULL,	/* parent */
+	result = bus_dma_tag_create(
+	    bus_get_dma_tag(sc->dev),		/* parent */
 	    HDAC_DMA_ALIGNMENT,			/* alignment */
 	    0,					/* boundary */
-	    lowaddr,				/* lowaddr */
+	    (sc->support_64bit) ? BUS_SPACE_MAXADDR :
+		BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
 	    BUS_SPACE_MAXADDR,			/* highaddr */
 	    NULL,				/* filtfunc */
 	    NULL,				/* fistfuncarg */
@@ -4044,29 +4044,6 @@ hdac_attach(device_t dev)
 	else
 		sc->polling = 0;
 
-	result = bus_dma_tag_create(NULL,	/* parent */
-	    HDAC_DMA_ALIGNMENT,			/* alignment */
-	    0,					/* boundary */
-	    BUS_SPACE_MAXADDR_32BIT,		/* lowaddr */
-	    BUS_SPACE_MAXADDR,			/* highaddr */
-	    NULL,				/* filtfunc */
-	    NULL,				/* fistfuncarg */
-	    HDA_BUFSZ_MAX, 			/* maxsize */
-	    1,					/* nsegments */
-	    HDA_BUFSZ_MAX, 			/* maxsegsz */
-	    0,					/* flags */
-	    NULL,				/* lockfunc */
-	    NULL,				/* lockfuncarg */
-	    &sc->chan_dmat);			/* dmat */
-	if (result != 0) {
-		device_printf(dev, "%s: bus_dma_tag_create failed (%x)\n",
-		     __func__, result);
-		snd_mtxfree(sc->lock);
-		free(sc, M_DEVBUF);
-		return (ENXIO);
-	}
-
-
 	sc->hdabus = NULL;
 	for (i = 0; i < HDAC_CODEC_MAX; i++)
 		sc->codecs[i] = NULL;
@@ -4163,6 +4140,9 @@ hdac_attach(device_t dev)
 	if (result != 0)
 		goto hdac_attach_fail;
 
+	if (devid >= 0 && (hdac_devices[devid].flags & HDAC_NO_64BIT))
+		sc->support_64bit = 0;
+
 	/* Allocate CORB and RIRB dma memory */
 	result = hdac_dma_alloc(sc, &sc->corb_dma,
 	    sc->corb_size * sizeof(uint32_t));
@@ -4173,6 +4153,28 @@ hdac_attach(device_t dev)
 	if (result != 0)
 		goto hdac_attach_fail;
 
+	result = bus_dma_tag_create(
+	    bus_get_dma_tag(sc->dev),		/* parent */
+	    HDAC_DMA_ALIGNMENT,			/* alignment */
+	    0,					/* boundary */
+	    (sc->support_64bit) ? BUS_SPACE_MAXADDR :
+		BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
+	    BUS_SPACE_MAXADDR,			/* highaddr */
+	    NULL,				/* filtfunc */
+	    NULL,				/* fistfuncarg */
+	    HDA_BUFSZ_MAX, 			/* maxsize */
+	    1,					/* nsegments */
+	    HDA_BUFSZ_MAX, 			/* maxsegsz */
+	    0,					/* flags */
+	    NULL,				/* lockfunc */
+	    NULL,				/* lockfuncarg */
+	    &sc->chan_dmat);			/* dmat */
+	if (result != 0) {
+		device_printf(dev, "%s: bus_dma_tag_create failed (%x)\n",
+		     __func__, result);
+		goto hdac_attach_fail;
+	}
+
 	/* Quiesce everything */
 	HDA_BOOTHVERBOSE(
 		device_printf(dev, "Reset controller...\n");


More information about the svn-src-head mailing list