changeset 12888:a534e180a8e7

6966540 asy panics calling delay while holding a spin lock on a uniprocessor machine
author Zach Kissel <Zachary.Kissel@Sun.COM>
date Tue, 20 Jul 2010 16:38:52 -0400
parents d6271820a7fb
children 69001e4756ae
files usr/src/uts/common/io/asy.c
diffstat 1 files changed, 12 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/io/asy.c	Tue Jul 20 12:46:19 2010 -0700
+++ b/usr/src/uts/common/io/asy.c	Tue Jul 20 16:38:52 2010 -0400
@@ -682,6 +682,12 @@
 		ddi_put8(asy->asy_iohandle, asy->asy_ioaddr + ICR, 0);
 		asy->asy_flags |= ASY_DDI_SUSPENDED;
 
+		/*
+		 * Hardware interrupts are disabled we can drop our high level
+		 * lock and proceed.
+		 */
+		mutex_exit(&asy->asy_excl_hi);
+
 		/* Process remaining RX characters and RX errors, if any */
 		lsr = ddi_get8(asy->asy_iohandle, asy->asy_ioaddr + LSR);
 		async_rxint(asy, lsr);
@@ -699,7 +705,6 @@
 			    "asy: transmitter wasn't drained before "
 			    "driver was suspended");
 
-		mutex_exit(&asy->asy_excl_hi);
 		mutex_exit(&asy->asy_excl);
 		mutex_exit(&asy->asy_soft_sr);
 		break;
@@ -2254,6 +2259,12 @@
 	}
 
 	mutex_enter(&asy->asy_excl_hi);
+
+	if (asy->asy_flags & ASY_DDI_SUSPENDED) {
+		mutex_exit(&asy->asy_excl_hi);
+		return (DDI_INTR_CLAIMED);
+	}
+
 	/*
 	 * We will loop until the interrupt line is pulled low. asy
 	 * interrupt is edge triggered.