Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 23 Jul 2009 15:32:30 +0200
From:      Roman Divacky <rdivacky@freebsd.org>
To:        current@freebsd.org
Subject:   [PATCH]: MPSAFE isa_dma* functions for i386/amd64
Message-ID:  <20090723133230.GA69577@freebsd.org>

next in thread | raw e-mail | index | archive | help

--gatW/ieO32f1wygP
Content-Type: multipart/mixed; boundary="LZvS9be/3tNcYl/X"
Content-Disposition: inline


--LZvS9be/3tNcYl/X
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

hi

I have a patch that makes isa_dma* routines MPSAFE on i386/amd64.
These routines are also present in ia64/sparc64. Sparc64 provides just
empty stubs and ia64 should be removed (according to Marcel Moolenaar).

there are some old drivers that use this - most prominently ppc(4) and fdc(4)

if you have this hardware please test the attached patch or you can download
it here:

	http://www.vlakno.cz/~rdivacky/isa_dma-locking.patch

the patch was reviewed by jhb@ but never tested on a real hw (as I have none).
most of the users of the isa_dma* routines are still covered by Giant because
they are used in drivers attach routines (which are Giant locked) but ppc/fdc
use those in the normal code as well

thank you very much for testing

	roman

--LZvS9be/3tNcYl/X
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="isa_dma-locking.patch"
Content-Transfer-Encoding: quoted-printable

Index: amd64/isa/isa_dma.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- amd64/isa/isa_dma.c	(revision 195829)
+++ amd64/isa/isa_dma.c	(working copy)
@@ -71,6 +71,8 @@
 static u_int8_t	dma_busy =3D 0;		/* Used in isa_dmastart() */
 static u_int8_t	dma_inuse =3D 0;		/* User for acquire/release */
 static u_int8_t dma_auto_mode =3D 0;
+static struct mtx isa_dma_lock;
+MTX_SYSINIT(isa_dma_lock, &isa_dma_lock, "isa DMA lock", MTX_DEF);
=20
 #define VALID_DMA_MASK (7)
=20
@@ -84,39 +86,56 @@
 isa_dma_init(int chan, u_int bouncebufsize, int flag)
 {
 	void *buf;
+	int contig;
=20
-	/*
-	 * If a DMA channel is shared, both drivers have to call isa_dma_init
-	 * since they don't know that the other driver will do it.
-	 * Just return if we're already set up good.
-	 * XXX: this only works if they agree on the bouncebuf size.  This
-	 * XXX: is typically the case since they are multiple instances of
-	 * XXX: the same driver.
-	 */
-	if (dma_bouncebuf[chan] !=3D NULL)
-		return (0);
-
 #ifdef DIAGNOSTIC
 	if (chan & ~VALID_DMA_MASK)
 		panic("isa_dma_init: channel out of range");
 #endif
=20
-	dma_bouncebufsize[chan] =3D bouncebufsize;
=20
 	/* Try malloc() first.  It works better if it works. */
 	buf =3D malloc(bouncebufsize, M_DEVBUF, flag);
 	if (buf !=3D NULL) {
-		if (isa_dmarangecheck(buf, bouncebufsize, chan) =3D=3D 0) {
-			dma_bouncebuf[chan] =3D buf;
-			return (0);
+		if (isa_dmarangecheck(buf, bouncebufsize, chan) !=3D 0) {
+			free(buf, M_DEVBUF);
+			buf =3D NULL;
 		}
-		free(buf, M_DEVBUF);
+		contig =3D 0;
 	}
-	buf =3D contigmalloc(bouncebufsize, M_DEVBUF, flag, 0ul, 0xfffffful,
+
+	if (buf =3D=3D NULL) {
+		buf =3D contigmalloc(bouncebufsize, M_DEVBUF, flag, 0ul, 0xfffffful,
 			   1ul, chan & 4 ? 0x20000ul : 0x10000ul);
+		contig =3D 1;
+	}
+
 	if (buf =3D=3D NULL)
 		return (ENOMEM);
+
+	mtx_lock(&isa_dma_lock);
+	/*
+	 * If a DMA channel is shared, both drivers have to call isa_dma_init
+	 * since they don't know that the other driver will do it.
+	 * Just return if we're already set up good.
+	 * XXX: this only works if they agree on the bouncebuf size.  This
+	 * XXX: is typically the case since they are multiple instances of
+	 * XXX: the same driver.
+	 */
+	if (dma_bouncebuf[chan] !=3D NULL) {
+		if (contig)
+			contigfree(buf, bouncebufsize, M_DEVBUF);
+		else
+			free(buf, M_DEVBUF);
+		mtx_unlock(&isa_dma_lock);
+		return (0);
+	}
+
+	dma_bouncebufsize[chan] =3D bouncebufsize;
 	dma_bouncebuf[chan] =3D buf;
+
+	mtx_unlock(&isa_dma_lock);
+
 	return (0);
 }
=20
@@ -133,12 +152,15 @@
 		panic("isa_dma_acquire: channel out of range");
 #endif
=20
+	mtx_lock(&isa_dma_lock);
 	if (dma_inuse & (1 << chan)) {
 		printf("isa_dma_acquire: channel %d already in use\n", chan);
+		mtx_unlock(&isa_dma_lock);
 		return (EBUSY);
 	}
 	dma_inuse |=3D (1 << chan);
 	dma_auto_mode &=3D ~(1 << chan);
+	mtx_unlock(&isa_dma_lock);
=20
 	return (0);
 }
@@ -155,8 +177,11 @@
 	if (chan & ~VALID_DMA_MASK)
 		panic("isa_dma_release: channel out of range");
=20
+	mtx_lock(&isa_dma_lock);
 	if ((dma_inuse & (1 << chan)) =3D=3D 0)
 		printf("isa_dma_release: channel %d not in use\n", chan);
+#else
+	mtx_lock(&isa_dma_lock);
 #endif
=20
 	if (dma_busy & (1 << chan)) {
@@ -171,6 +196,8 @@
=20
 	dma_inuse &=3D ~(1 << chan);
 	dma_auto_mode &=3D ~(1 << chan);
+
+	mtx_unlock(&isa_dma_lock);
 }
=20
 /*
@@ -186,6 +213,7 @@
 		panic("isa_dmacascade: channel out of range");
 #endif
=20
+	mtx_lock(&isa_dma_lock);
 	/* set dma channel mode, and set dma channel mode */
 	if ((chan & 4) =3D=3D 0) {
 		outb(DMA1_MODE, DMA37MD_CASCADE | chan);
@@ -194,6 +222,7 @@
 		outb(DMA2_MODE, DMA37MD_CASCADE | (chan & 3));
 		outb(DMA2_SMSK, chan & 3);
 	}
+	mtx_unlock(&isa_dma_lock);
 }
=20
 /*
@@ -206,8 +235,11 @@
 	vm_paddr_t phys;
 	int waport;
 	caddr_t newaddr;
+	int dma_range_checked;
=20
-	GIANT_REQUIRED;
+	/* translate to physical */
+	phys =3D pmap_extract(kernel_pmap, (vm_offset_t)addr);
+	dma_range_checked =3D isa_dmarangecheck(addr, nbytes, chan);
=20
 #ifdef DIAGNOSTIC
 	if (chan & ~VALID_DMA_MASK)
@@ -217,8 +249,11 @@
 	    || (chan >=3D 4 && (nbytes > (1<<17) || (uintptr_t)addr & 1)))
 		panic("isa_dmastart: impossible request");
=20
+	mtx_lock(&isa_dma_lock);
 	if ((dma_inuse & (1 << chan)) =3D=3D 0)
 		printf("isa_dmastart: channel %d not acquired\n", chan);
+#else
+	mtx_lock(&isa_dma_lock);
 #endif
=20
 #if 0
@@ -233,7 +268,7 @@
=20
 	dma_busy |=3D (1 << chan);
=20
-	if (isa_dmarangecheck(addr, nbytes, chan)) {
+	if (dma_range_checked) {
 		if (dma_bouncebuf[chan] =3D=3D NULL
 		    || dma_bouncebufsize[chan] < nbytes)
 			panic("isa_dmastart: bad bounce buffer");=20
@@ -246,9 +281,6 @@
 		addr =3D newaddr;
 	}
=20
-	/* translate to physical */
-	phys =3D pmap_extract(kernel_pmap, (vm_offset_t)addr);
-
 	if (flags & ISADMA_RAW) {
 	    dma_auto_mode |=3D (1 << chan);
 	} else {=20
@@ -323,6 +355,7 @@
 		/* unmask channel */
 		outb(DMA2_SMSK, chan & 3);
 	}
+	mtx_unlock(&isa_dma_lock);
 }
=20
 void
@@ -336,6 +369,7 @@
 		printf("isa_dmadone: channel %d not acquired\n", chan);
 #endif
=20
+	mtx_lock(&isa_dma_lock);
 	if (((dma_busy & (1 << chan)) =3D=3D 0) &&=20
 	    (dma_auto_mode & (1 << chan)) =3D=3D 0 )
 		printf("isa_dmadone: channel %d not busy\n", chan);
@@ -351,6 +385,7 @@
 		dma_bounced &=3D ~(1 << chan);
 	}
 	dma_busy &=3D ~(1 << chan);
+	mtx_unlock(&isa_dma_lock);
 }
=20
 /*
@@ -367,8 +402,6 @@
 	vm_offset_t endva;
 	u_int dma_pgmsk =3D (chan & 4) ?  ~(128*1024-1) : ~(64*1024-1);
=20
-	GIANT_REQUIRED;
-
 	endva =3D (vm_offset_t)round_page((vm_offset_t)va + length);
 	for (; va < (caddr_t) endva ; va +=3D PAGE_SIZE) {
 		phys =3D trunc_page(pmap_extract(kernel_pmap, (vm_offset_t)va));
@@ -420,13 +453,15 @@
  * or -1 if the channel requested is not active.
  *
  */
-int
-isa_dmastatus(int chan)
+static int
+isa_dmastatus_locked(int chan)
 {
 	u_long	cnt =3D 0;
 	int	ffport, waport;
 	u_long	low1, high1, low2, high2;
=20
+	mtx_assert(&isa_dma_lock, MA_OWNED);
+
 	/* channel active? */
 	if ((dma_inuse & (1 << chan)) =3D=3D 0) {
 		printf("isa_dmastatus: channel %d not active\n", chan);
@@ -472,6 +507,18 @@
 	return(cnt);
 }
=20
+int
+isa_dmastatus(int chan)
+{
+	int status;
+
+	mtx_lock(&isa_dma_lock);
+	status =3D isa_dmastatus_locked(chan);
+	mtx_unlock(&isa_dma_lock);
+
+	return (status);
+}
+
 /*
  * Reached terminal count yet ?
  */
@@ -491,12 +538,16 @@
 int
 isa_dmastop(int chan)=20
 {
+	int status;
+
+	mtx_lock(&isa_dma_lock);
 	if ((dma_inuse & (1 << chan)) =3D=3D 0)
 		printf("isa_dmastop: channel %d not acquired\n", chan); =20
=20
 	if (((dma_busy & (1 << chan)) =3D=3D 0) &&
 	    ((dma_auto_mode & (1 << chan)) =3D=3D 0)) {
 		printf("chan %d not busy\n", chan);
+		mtx_unlock(&isa_dma_lock);
 		return -2 ;
 	}
    =20
@@ -505,7 +556,12 @@
 	} else {
 		outb(DMA2_SMSK, (chan & 3) | 4 /* disable mask */);
 	}
-	return(isa_dmastatus(chan));
+
+	status =3D isa_dmastatus_locked(chan);
+
+	mtx_unlock(&isa_dma_lock);
+
+	return (status);
 }
=20
 /*
Index: i386/isa/isa_dma.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- i386/isa/isa_dma.c	(revision 195829)
+++ i386/isa/isa_dma.c	(working copy)
@@ -69,6 +69,8 @@
 static u_int8_t	dma_busy =3D 0;		/* Used in isa_dmastart() */
 static u_int8_t	dma_inuse =3D 0;		/* User for acquire/release */
 static u_int8_t dma_auto_mode =3D 0;
+static struct mtx isa_dma_lock;
+MTX_SYSINIT(isa_dma_lock, &isa_dma_lock, "isa DMA lock", MTX_DEF);
=20
 #define VALID_DMA_MASK (7)
=20
@@ -82,39 +84,56 @@
 isa_dma_init(int chan, u_int bouncebufsize, int flag)
 {
 	void *buf;
+	int contig;
=20
-	/*
-	 * If a DMA channel is shared, both drivers have to call isa_dma_init
-	 * since they don't know that the other driver will do it.
-	 * Just return if we're already set up good.
-	 * XXX: this only works if they agree on the bouncebuf size.  This
-	 * XXX: is typically the case since they are multiple instances of
-	 * XXX: the same driver.
-	 */
-	if (dma_bouncebuf[chan] !=3D NULL)
-		return (0);
-
 #ifdef DIAGNOSTIC
 	if (chan & ~VALID_DMA_MASK)
 		panic("isa_dma_init: channel out of range");
 #endif
=20
-	dma_bouncebufsize[chan] =3D bouncebufsize;
=20
 	/* Try malloc() first.  It works better if it works. */
 	buf =3D malloc(bouncebufsize, M_DEVBUF, flag);
 	if (buf !=3D NULL) {
-		if (isa_dmarangecheck(buf, bouncebufsize, chan) =3D=3D 0) {
-			dma_bouncebuf[chan] =3D buf;
-			return (0);
+		if (isa_dmarangecheck(buf, bouncebufsize, chan) !=3D 0) {
+			free(buf, M_DEVBUF);
+			buf =3D NULL;
 		}
-		free(buf, M_DEVBUF);
+		contig =3D 0;
 	}
-	buf =3D contigmalloc(bouncebufsize, M_DEVBUF, flag, 0ul, 0xfffffful,
+
+	if (buf =3D=3D NULL) {
+		buf =3D contigmalloc(bouncebufsize, M_DEVBUF, flag, 0ul, 0xfffffful,
 			   1ul, chan & 4 ? 0x20000ul : 0x10000ul);
+		contig =3D 1;
+	}
+
 	if (buf =3D=3D NULL)
 		return (ENOMEM);
+
+	mtx_lock(&isa_dma_lock);
+	/*
+	 * If a DMA channel is shared, both drivers have to call isa_dma_init
+	 * since they don't know that the other driver will do it.
+	 * Just return if we're already set up good.
+	 * XXX: this only works if they agree on the bouncebuf size.  This
+	 * XXX: is typically the case since they are multiple instances of
+	 * XXX: the same driver.
+	 */
+	if (dma_bouncebuf[chan] !=3D NULL) {
+		if (contig)
+			contigfree(buf, bouncebufsize, M_DEVBUF);
+		else
+			free(buf, M_DEVBUF);
+		mtx_unlock(&isa_dma_lock);
+		return (0);
+	}
+
+	dma_bouncebufsize[chan] =3D bouncebufsize;
 	dma_bouncebuf[chan] =3D buf;
+
+	mtx_unlock(&isa_dma_lock);
+
 	return (0);
 }
=20
@@ -131,12 +150,15 @@
 		panic("isa_dma_acquire: channel out of range");
 #endif
=20
+	mtx_lock(&isa_dma_lock);
 	if (dma_inuse & (1 << chan)) {
 		printf("isa_dma_acquire: channel %d already in use\n", chan);
+		mtx_unlock(&isa_dma_lock);
 		return (EBUSY);
 	}
 	dma_inuse |=3D (1 << chan);
 	dma_auto_mode &=3D ~(1 << chan);
+	mtx_unlock(&isa_dma_lock);
=20
 	return (0);
 }
@@ -153,8 +175,11 @@
 	if (chan & ~VALID_DMA_MASK)
 		panic("isa_dma_release: channel out of range");
=20
+	mtx_lock(&isa_dma_lock);
 	if ((dma_inuse & (1 << chan)) =3D=3D 0)
 		printf("isa_dma_release: channel %d not in use\n", chan);
+#else
+	mtx_lock(&isa_dma_lock);
 #endif
=20
 	if (dma_busy & (1 << chan)) {
@@ -169,6 +194,8 @@
=20
 	dma_inuse &=3D ~(1 << chan);
 	dma_auto_mode &=3D ~(1 << chan);
+
+	mtx_unlock(&isa_dma_lock);
 }
=20
 /*
@@ -184,6 +211,7 @@
 		panic("isa_dmacascade: channel out of range");
 #endif
=20
+	mtx_lock(&isa_dma_lock);
 	/* set dma channel mode, and set dma channel mode */
 	if ((chan & 4) =3D=3D 0) {
 		outb(DMA1_MODE, DMA37MD_CASCADE | chan);
@@ -192,6 +220,7 @@
 		outb(DMA2_MODE, DMA37MD_CASCADE | (chan & 3));
 		outb(DMA2_SMSK, chan & 3);
 	}
+	mtx_unlock(&isa_dma_lock);
 }
=20
 /*
@@ -204,8 +233,11 @@
 	vm_paddr_t phys;
 	int waport;
 	caddr_t newaddr;
+	int dma_range_checked;
=20
-	GIANT_REQUIRED;
+	/* translate to physical */
+	phys =3D pmap_extract(kernel_pmap, (vm_offset_t)addr);
+	dma_range_checked =3D isa_dmarangecheck(addr, nbytes, chan);
=20
 #ifdef DIAGNOSTIC
 	if (chan & ~VALID_DMA_MASK)
@@ -215,8 +247,11 @@
 	    || (chan >=3D 4 && (nbytes > (1<<17) || (u_int)addr & 1)))
 		panic("isa_dmastart: impossible request");
=20
+	mtx_lock(&isa_dma_lock);
 	if ((dma_inuse & (1 << chan)) =3D=3D 0)
 		printf("isa_dmastart: channel %d not acquired\n", chan);
+#else
+	mtx_lock(&isa_dma_lock);
 #endif
=20
 #if 0
@@ -231,7 +266,7 @@
=20
 	dma_busy |=3D (1 << chan);
=20
-	if (isa_dmarangecheck(addr, nbytes, chan)) {
+	if (dma_range_checked) {
 		if (dma_bouncebuf[chan] =3D=3D NULL
 		    || dma_bouncebufsize[chan] < nbytes)
 			panic("isa_dmastart: bad bounce buffer");=20
@@ -244,9 +279,6 @@
 		addr =3D newaddr;
 	}
=20
-	/* translate to physical */
-	phys =3D pmap_extract(kernel_pmap, (vm_offset_t)addr);
-
 	if (flags & ISADMA_RAW) {
 	    dma_auto_mode |=3D (1 << chan);
 	} else {=20
@@ -321,6 +353,7 @@
 		/* unmask channel */
 		outb(DMA2_SMSK, chan & 3);
 	}
+	mtx_unlock(&isa_dma_lock);
 }
=20
 void
@@ -334,6 +367,7 @@
 		printf("isa_dmadone: channel %d not acquired\n", chan);
 #endif
=20
+	mtx_lock(&isa_dma_lock);
 	if (((dma_busy & (1 << chan)) =3D=3D 0) &&=20
 	    (dma_auto_mode & (1 << chan)) =3D=3D 0 )
 		printf("isa_dmadone: channel %d not busy\n", chan);
@@ -349,6 +383,7 @@
 		dma_bounced &=3D ~(1 << chan);
 	}
 	dma_busy &=3D ~(1 << chan);
+	mtx_unlock(&isa_dma_lock);
 }
=20
 /*
@@ -365,8 +400,6 @@
 	vm_offset_t endva;
 	u_int dma_pgmsk =3D (chan & 4) ?  ~(128*1024-1) : ~(64*1024-1);
=20
-	GIANT_REQUIRED;
-
 	endva =3D (vm_offset_t)round_page((vm_offset_t)va + length);
 	for (; va < (caddr_t) endva ; va +=3D PAGE_SIZE) {
 		phys =3D trunc_page(pmap_extract(kernel_pmap, (vm_offset_t)va));
@@ -419,13 +452,15 @@
  * or -1 if the channel requested is not active.
  *
  */
-int
-isa_dmastatus(int chan)
+static int
+isa_dmastatus_locked(int chan)
 {
 	u_long	cnt =3D 0;
 	int	ffport, waport;
 	u_long	low1, high1, low2, high2;
=20
+	mtx_assert(&isa_dma_lock, MA_OWNED);
+
 	/* channel active? */
 	if ((dma_inuse & (1 << chan)) =3D=3D 0) {
 		printf("isa_dmastatus: channel %d not active\n", chan);
@@ -471,6 +506,18 @@
 	return(cnt);
 }
=20
+int
+isa_dmastatus(int chan)
+{
+	int status;
+
+	mtx_lock(&isa_dma_lock);
+	status =3D isa_dmastatus_locked(chan);
+	mtx_unlock(&isa_dma_lock);
+
+	return (status);
+}
+
 /*
  * Reached terminal count yet ?
  */
@@ -490,12 +537,16 @@
 int
 isa_dmastop(int chan)=20
 {
+	int status;
+
+	mtx_lock(&isa_dma_lock);
 	if ((dma_inuse & (1 << chan)) =3D=3D 0)
 		printf("isa_dmastop: channel %d not acquired\n", chan); =20
=20
 	if (((dma_busy & (1 << chan)) =3D=3D 0) &&
 	    ((dma_auto_mode & (1 << chan)) =3D=3D 0)) {
 		printf("chan %d not busy\n", chan);
+		mtx_unlock(&isa_dma_lock);
 		return -2 ;
 	}
    =20
@@ -504,7 +555,12 @@
 	} else {
 		outb(DMA2_SMSK, (chan & 3) | 4 /* disable mask */);
 	}
-	return(isa_dmastatus(chan));
+
+	status =3D isa_dmastatus_locked(chan);
+
+	mtx_unlock(&isa_dma_lock);
+
+	return (status);
 }
=20
 /*
Index: dev/ieee488/ibfoo.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- dev/ieee488/ibfoo.c	(revision 195829)
+++ dev/ieee488/ibfoo.c	(working copy)
@@ -397,18 +397,14 @@
 	KASSERT(u->dmachan >=3D 0, ("Bogus dmachan %d", u->dmachan));
 	ib =3D u->ibfoo;
 	ib->mode =3D DMA_IDATA;
-	mtx_lock(&Giant);
 	isa_dmastart(ISADMA_READ, data, len, u->dmachan);
-	mtx_unlock(&Giant);
 	mtx_lock(&u->mutex);
 	upd7210_wr(u, IMR1, IXR1_ENDRX);
 	upd7210_wr(u, IMR2, IMR2_DMAI);
 	gpib_ib_wait_xfer(u, ib);
 	mtx_unlock(&u->mutex);
-	mtx_lock(&Giant);
 	j =3D isa_dmastatus(u->dmachan);
 	isa_dmadone(ISADMA_READ, data, len, u->dmachan);
-	mtx_unlock(&Giant);
 	return (len - j);
 }
=20
@@ -790,14 +786,12 @@
 	mtx_unlock(&u->mutex);
=20
 	if (u->dmachan >=3D 0) {
-		mtx_lock(&Giant);
 		error =3D isa_dma_acquire(u->dmachan);
 		if (!error) {
 			error =3D isa_dma_init(u->dmachan, PAGE_SIZE, M_WAITOK);
 			if (error)
 				isa_dma_release(u->dmachan);
 		}
-		mtx_unlock(&Giant);
 	}
=20
 	if (error) {
@@ -855,9 +849,7 @@
 	free(ib, M_IBFOO);
=20
 	if (u->dmachan >=3D 0) {
-		mtx_lock(&Giant);
 		isa_dma_release(u->dmachan);
-		mtx_unlock(&Giant);
 	}
 	mtx_lock(&u->mutex);
 	u->busy =3D 0;
Index: dev/fdc/fdc.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- dev/fdc/fdc.c	(revision 195829)
+++ dev/fdc/fdc.c	(working copy)
@@ -781,11 +781,9 @@
=20
 	/* Disable ISADMA if we bailed while it was active */
 	if (fd !=3D NULL && (fd->flags & FD_ISADMA)) {
-		mtx_lock(&Giant);
 		isa_dmadone(
 		    bp->bio_cmd & BIO_READ ? ISADMA_READ : ISADMA_WRITE,
 		    fd->fd_ioptr, fd->fd_iosize, fdc->dmachan);
-		mtx_unlock(&Giant);
 		mtx_lock(&fdc->fdc_mtx);
 		fd->flags &=3D ~FD_ISADMA;
 		mtx_unlock(&fdc->fdc_mtx);
@@ -958,11 +956,9 @@
 	/* Setup ISADMA if we need it and have it */
 	if ((bp->bio_cmd & (BIO_READ|BIO_WRITE|BIO_FMT))
 	     && !(fdc->flags & FDC_NODMA)) {
-		mtx_lock(&Giant);
 		isa_dmastart(
 		    bp->bio_cmd & BIO_READ ? ISADMA_READ : ISADMA_WRITE,
 		    fd->fd_ioptr, fd->fd_iosize, fdc->dmachan);
-		mtx_unlock(&Giant);
 		mtx_lock(&fdc->fdc_mtx);
 		fd->flags |=3D FD_ISADMA;
 		mtx_unlock(&fdc->fdc_mtx);
@@ -1040,11 +1036,9 @@
=20
 	/* Finish DMA */
 	if (fd->flags & FD_ISADMA) {
-		mtx_lock(&Giant);
 		isa_dmadone(
 		    bp->bio_cmd & BIO_READ ? ISADMA_READ : ISADMA_WRITE,
 		    fd->fd_ioptr, fd->fd_iosize, fdc->dmachan);
-		mtx_unlock(&Giant);
 		mtx_lock(&fdc->fdc_mtx);
 		fd->flags &=3D ~FD_ISADMA;
 		mtx_unlock(&fdc->fdc_mtx);

--LZvS9be/3tNcYl/X--

--gatW/ieO32f1wygP
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.12 (FreeBSD)

iEYEARECAAYFAkpoZm4ACgkQLVEj6D3CBExhmgCffL74DHfSYRKmwzY254c1+wSY
hmcAni9yjfOzPfu7fc+eNhMecrBnVTcL
=SI4E
-----END PGP SIGNATURE-----

--gatW/ieO32f1wygP--



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