summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzk194757 <none@none>2006-06-16 06:36:44 -0700
committerzk194757 <none@none>2006-06-16 06:36:44 -0700
commit90a71dbd6171b99962dbe46ca472342a3b307ba6 (patch)
treebbb469ae2162792d9fb599033ed23c9c428b1784
parent9902c40f3ca30b020918420df0b057454e487055 (diff)
downloadillumos-gate-90a71dbd6171b99962dbe46ca472342a3b307ba6.tar.gz
6334314 su driver can hang in certain ioctls (TCSETA) when asy_isbusy is true
-rw-r--r--usr/src/uts/sun4/io/su_driver.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/usr/src/uts/sun4/io/su_driver.c b/usr/src/uts/sun4/io/su_driver.c
index 86652eeaff..d8b2ab208d 100644
--- a/usr/src/uts/sun4/io/su_driver.c
+++ b/usr/src/uts/sun4/io/su_driver.c
@@ -2599,6 +2599,7 @@ async_ioctl(struct asyncline *async, queue_t *wq, mblk_t *mp, boolean_t iswput)
register tty_common_t *tp = &async->async_ttycommon;
register struct iocblk *iocp;
register unsigned datasize;
+ size_t ioc_count;
mblk_t *datamp;
int error = 0;
uchar_t val, icr;
@@ -2621,6 +2622,12 @@ async_ioctl(struct asyncline *async, queue_t *wq, mblk_t *mp, boolean_t iswput)
iocp = (struct iocblk *)mp->b_rptr;
/*
+ * Save off the ioc count in case we need to restore it
+ * because we are queuing a message block.
+ */
+ ioc_count = iocp->ioc_count;
+
+ /*
* For TIOCMGET, TIOCMBIC, TIOCMBIS, TIOCMSET, and PPS, do NOT call
* ttycommon_ioctl() because this function frees up the message block
* (mp->b_cont) that contains the address of the user variable where
@@ -2680,6 +2687,18 @@ async_ioctl(struct asyncline *async, queue_t *wq, mblk_t *mp, boolean_t iswput)
asy->asy_lom_console)) {
mutex_enter(asy->asy_excl_hi);
if (iswput && asy_isbusy(asy)) {
+ /*
+ * ttycommon_ioctl sets the db_type to
+ * M_IOCACK and ioc_count to zero
+ * we need to undo this when we
+ * queue a control message. This will
+ * allow the control messages to be
+ * processed again when the chip
+ * becomes available.
+ */
+ mp->b_datap->db_type = M_IOCTL;
+ iocp->ioc_count = ioc_count;
+
if (putq(wq, mp) == 0)
freemsg(mp);
mutex_exit(asy->asy_excl_hi);