Mercurial > illumos > illumos-gate
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.