xref: /onnv-gate/usr/src/uts/sun4u/opl/io/oplmsu/oplmsu_ioctl_lrp.c (revision 11311:639e7bc0b42f)
11772Sjl139090 /*
21772Sjl139090  * CDDL HEADER START
31772Sjl139090  *
41772Sjl139090  * The contents of this file are subject to the terms of the
51772Sjl139090  * Common Development and Distribution License (the "License").
61772Sjl139090  * You may not use this file except in compliance with the License.
71772Sjl139090  *
81772Sjl139090  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
91772Sjl139090  * or http://www.opensolaris.org/os/licensing.
101772Sjl139090  * See the License for the specific language governing permissions
111772Sjl139090  * and limitations under the License.
121772Sjl139090  *
131772Sjl139090  * When distributing Covered Code, include this CDDL HEADER in each
141772Sjl139090  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
151772Sjl139090  * If applicable, add the following below this CDDL HEADER, with the
161772Sjl139090  * fields enclosed by brackets "[]" replaced with your own identifying
171772Sjl139090  * information: Portions Copyright [yyyy] [name of copyright owner]
181772Sjl139090  *
191772Sjl139090  * CDDL HEADER END
201772Sjl139090  */
21*11311SSurya.Prakki@Sun.COM 
221772Sjl139090 /*
231772Sjl139090  * All Rights Reserved, Copyright (c) FUJITSU LIMITED 2006
241772Sjl139090  */
251772Sjl139090 
261772Sjl139090 #include <sys/errno.h>
271772Sjl139090 #include <sys/modctl.h>
281772Sjl139090 #include <sys/stat.h>
291772Sjl139090 #include <sys/kmem.h>
301772Sjl139090 #include <sys/ksynch.h>
311772Sjl139090 #include <sys/stream.h>
321772Sjl139090 #include <sys/stropts.h>
331772Sjl139090 #include <sys/termio.h>
341772Sjl139090 #include <sys/ddi.h>
351772Sjl139090 #include <sys/file.h>
361772Sjl139090 #include <sys/disp.h>
371772Sjl139090 #include <sys/sunddi.h>
381772Sjl139090 #include <sys/sunldi.h>
391772Sjl139090 #include <sys/sunndi.h>
401772Sjl139090 #include <sys/prom_plat.h>
411772Sjl139090 #include <sys/oplmsu/oplmsu.h>
421772Sjl139090 #include <sys/oplmsu/oplmsu_proto.h>
431772Sjl139090 
441772Sjl139090 /*
451772Sjl139090  *	LOWER READ SERVICE PROCEDURE
461772Sjl139090  */
471772Sjl139090 
481772Sjl139090 /* termios ioctl response received */
491772Sjl139090 int
oplmsu_lrioctl_termios(queue_t * lrq,mblk_t * mp)501772Sjl139090 oplmsu_lrioctl_termios(queue_t *lrq, mblk_t *mp)
511772Sjl139090 {
521772Sjl139090 	upath_t		*upath, *altn_upath = NULL, *stp_upath = NULL;
531772Sjl139090 	lpath_t		*lpath, *altn_lpath = NULL, *stp_lpath = NULL;
541772Sjl139090 	struct iocblk	*iocp, *temp_iocp = NULL;
551772Sjl139090 	mblk_t		*hndl_mp, *nmp = NULL, *fmp = NULL;
561772Sjl139090 	queue_t		*dst_queue;
571772Sjl139090 	int		term_ioctl, term_stat, sts;
581772Sjl139090 	int		ack_flag, termio_flag, chkflag;
591772Sjl139090 	ulong_t		trad_sts;
601772Sjl139090 
611772Sjl139090 	rw_enter(&oplmsu_uinst->lock, RW_READER);
621772Sjl139090 	iocp = (struct iocblk *)mp->b_rptr;
631772Sjl139090 
641772Sjl139090 	mutex_enter(&oplmsu_uinst->u_lock);
651772Sjl139090 	mutex_enter(&oplmsu_uinst->l_lock);
661772Sjl139090 	lpath = (lpath_t *)lrq->q_ptr;
671772Sjl139090 	hndl_mp = lpath->hndl_mp;
681772Sjl139090 
691772Sjl139090 	upath = oplmsu_search_upath_info(lpath->path_no);
701772Sjl139090 	trad_sts = upath->traditional_status;
711772Sjl139090 	mutex_exit(&oplmsu_uinst->l_lock);
721772Sjl139090 	mutex_exit(&oplmsu_uinst->u_lock);
731772Sjl139090 
741772Sjl139090 	if (((iocp->ioc_cmd == TCSETS) && (trad_sts == MSU_WTCS_ACK)) ||
751772Sjl139090 	    ((iocp->ioc_cmd == TCSETSW) && (trad_sts == MSU_WTCS_ACK)) ||
761772Sjl139090 	    ((iocp->ioc_cmd == TCSETSF) && (trad_sts == MSU_WTCS_ACK)) ||
771772Sjl139090 	    ((iocp->ioc_cmd == TIOCMSET) && (trad_sts == MSU_WTMS_ACK)) ||
781772Sjl139090 	    ((iocp->ioc_cmd == TIOCSPPS) && (trad_sts == MSU_WPPS_ACK)) ||
791772Sjl139090 	    ((iocp->ioc_cmd == TIOCSWINSZ) && (trad_sts == MSU_WWSZ_ACK)) ||
801772Sjl139090 	    ((iocp->ioc_cmd == TIOCSSOFTCAR) && (trad_sts == MSU_WCAR_ACK))) {
811772Sjl139090 		if (mp->b_datap->db_type == M_IOCACK) {
821772Sjl139090 			ack_flag = ACK_RES;
831772Sjl139090 		} else {
841772Sjl139090 			ack_flag = NAK_RES;
851772Sjl139090 		}
861772Sjl139090 	} else {
871772Sjl139090 		rw_exit(&oplmsu_uinst->lock);
881772Sjl139090 		freemsg(mp);
891772Sjl139090 		cmn_err(CE_WARN, "oplmsu: lr-termios: "
901772Sjl139090 		    "Status of path is improper");
911772Sjl139090 		return (SUCCESS);
921772Sjl139090 	}
931772Sjl139090 
941772Sjl139090 	switch (trad_sts) {
951772Sjl139090 	case MSU_WTCS_ACK :
961772Sjl139090 		termio_flag = MSU_TIOS_TCSETS;
971772Sjl139090 		break;
981772Sjl139090 
991772Sjl139090 	case MSU_WTMS_ACK :
1001772Sjl139090 		termio_flag = MSU_TIOS_MSET;
1011772Sjl139090 		break;
1021772Sjl139090 
1031772Sjl139090 	case MSU_WPPS_ACK :
1041772Sjl139090 		termio_flag = MSU_TIOS_PPS;
1051772Sjl139090 		break;
1061772Sjl139090 
1071772Sjl139090 	case MSU_WWSZ_ACK :
1081772Sjl139090 		termio_flag = MSU_TIOS_WINSZP;
1091772Sjl139090 		break;
1101772Sjl139090 
1111772Sjl139090 	case MSU_WCAR_ACK :
1121772Sjl139090 		termio_flag = MSU_TIOS_SOFTCAR;
1131772Sjl139090 		break;
1141772Sjl139090 
1151772Sjl139090 	default :
1161772Sjl139090 		termio_flag = MSU_TIOS_END;
1171772Sjl139090 		break;
1181772Sjl139090 	}
1191772Sjl139090 
1201772Sjl139090 	if (hndl_mp == NULL) {
1211772Sjl139090 		switch (trad_sts) {
1221772Sjl139090 		case MSU_WTCS_ACK :	/* FALLTHRU */
1231772Sjl139090 		case MSU_WTMS_ACK :	/* FALLTHRU */
1241772Sjl139090 		case MSU_WPPS_ACK :	/* FALLTHRU */
1251772Sjl139090 		case MSU_WWSZ_ACK :	/* FALLTHRU */
1261772Sjl139090 		case MSU_WCAR_ACK :
1271772Sjl139090 			chkflag = MSU_CMD_STOP;
1281772Sjl139090 			break;
1291772Sjl139090 
1301772Sjl139090 		default :
1311772Sjl139090 			chkflag = FAILURE;
1321772Sjl139090 			break;
1331772Sjl139090 		}
1341772Sjl139090 	} else {
1351772Sjl139090 		/* xoff/xon received */
1361772Sjl139090 		if (hndl_mp->b_datap->db_type == M_DATA) {
1371772Sjl139090 			chkflag = MSU_CMD_ACTIVE;
1381772Sjl139090 		} else { /* Normal termios */
1391772Sjl139090 			temp_iocp = (struct iocblk *)hndl_mp->b_rptr;
1401772Sjl139090 			chkflag = temp_iocp->ioc_cmd;
1411772Sjl139090 		}
1421772Sjl139090 	}
1431772Sjl139090 
1441772Sjl139090 	if ((chkflag == MSU_CMD_ACTIVE) || (chkflag == MSU_CMD_STOP)) {
1451772Sjl139090 		if (ack_flag == ACK_RES) { /* M_IOCACK received */
1461772Sjl139090 			ctrl_t	*ctrl;
1471772Sjl139090 
1481772Sjl139090 			if (oplmsu_cmn_prechg_termio(lrq, mp, MSU_READ_SIDE,
1491772Sjl139090 			    termio_flag, &nmp, &term_stat) == FAILURE) {
1501772Sjl139090 				rw_exit(&oplmsu_uinst->lock);
1511772Sjl139090 				return (FAILURE);
1521772Sjl139090 			}
1531772Sjl139090 
1541772Sjl139090 			OPLMSU_RWLOCK_UPGRADE();
1551772Sjl139090 			mutex_enter(&oplmsu_uinst->u_lock);
1561772Sjl139090 			if (term_stat != MSU_WPTH_CHG) {
1571772Sjl139090 				upath->traditional_status = term_stat;
1581772Sjl139090 				mutex_exit(&oplmsu_uinst->u_lock);
1591772Sjl139090 				rw_exit(&oplmsu_uinst->lock);
1601772Sjl139090 				freemsg(mp);
1611772Sjl139090 
1621772Sjl139090 				OPLMSU_TRACE(RD(lrq), nmp, MSU_TRC_LO);
1631772Sjl139090 
1641772Sjl139090 				/* Continue sending termios ioctls */
1651772Sjl139090 				qreply(RD(lrq), nmp);
1661772Sjl139090 				return (SUCCESS);
1671772Sjl139090 			}
1681772Sjl139090 			freemsg(mp);
1691772Sjl139090 
1701772Sjl139090 			/* Change status of new active path */
1711772Sjl139090 			oplmsu_cmn_set_upath_sts(upath, MSU_PSTAT_ACTIVE,
1721772Sjl139090 			    upath->status, MSU_ACTIVE);
1731772Sjl139090 
1741772Sjl139090 			mutex_enter(&oplmsu_uinst->l_lock);
1751772Sjl139090 			lpath->uinst = oplmsu_uinst;
1761772Sjl139090 			dst_queue = lpath->hndl_uqueue;
1771772Sjl139090 
1781772Sjl139090 			ctrl = oplmsu_uinst->user_ctrl;
1791772Sjl139090 			if ((chkflag == MSU_CMD_ACTIVE) && (hndl_mp != NULL)) {
1801772Sjl139090 				/* Put a message(M_DATA) on a queue */
1811772Sjl139090 				if (ctrl != NULL) {
1821772Sjl139090 					mutex_enter(&oplmsu_uinst->c_lock);
183*11311SSurya.Prakki@Sun.COM 					(void) putq(RD(ctrl->queue), hndl_mp);
1841772Sjl139090 					mutex_exit(&oplmsu_uinst->c_lock);
1851772Sjl139090 				}
1861772Sjl139090 			}
1871772Sjl139090 
1881772Sjl139090 			oplmsu_clear_ioctl_path(lpath);
1891772Sjl139090 			stp_upath = lpath->src_upath;
1901772Sjl139090 			lpath->src_upath = NULL;
1911772Sjl139090 			lpath->status = MSU_EXT_NOTUSED;
1921772Sjl139090 
1931772Sjl139090 			/* Notify of the active path changing */
194*11311SSurya.Prakki@Sun.COM 			(void) prom_opl_switch_console(upath->ser_devcb.lsb);
1951772Sjl139090 
1961772Sjl139090 			/* Send XON to notify active path */
1971772Sjl139090 			(void) oplmsu_cmn_put_xoffxon(WR(lrq), MSU_XON_4);
1981772Sjl139090 
1991772Sjl139090 			stp_lpath = stp_upath->lpath;
2001772Sjl139090 			stp_lpath->uinst = NULL;
2011772Sjl139090 			oplmsu_clear_ioctl_path(stp_lpath);
2021772Sjl139090 			stp_lpath->src_upath = NULL;
2031772Sjl139090 			stp_lpath->status = MSU_EXT_NOTUSED;
2041772Sjl139090 
2051772Sjl139090 			/* Change status of stopped or old-active path */
2061772Sjl139090 			if (chkflag == MSU_CMD_STOP) {
2071772Sjl139090 				sts = MSU_PSTAT_STOP;
2081772Sjl139090 				trad_sts = MSU_STOP;
2091772Sjl139090 			} else { /* == MSU_CMD_ACTIVE */
2101772Sjl139090 				sts = MSU_PSTAT_STANDBY;
2111772Sjl139090 				trad_sts = MSU_STANDBY;
2121772Sjl139090 			}
2131772Sjl139090 			oplmsu_cmn_set_upath_sts(stp_upath, sts,
2141772Sjl139090 			    stp_upath->status, trad_sts);
2151772Sjl139090 
2161772Sjl139090 			/* Send XOFF to notify all standby paths */
2171772Sjl139090 			oplmsu_cmn_putxoff_standby();
2181772Sjl139090 			oplmsu_uinst->lower_queue = lrq;
2191772Sjl139090 			oplmsu_uinst->inst_status = oplmsu_get_inst_status();
2201772Sjl139090 			mutex_exit(&oplmsu_uinst->l_lock);
2211772Sjl139090 			mutex_exit(&oplmsu_uinst->u_lock);
2221772Sjl139090 
2231772Sjl139090 			/* Change active path of user node */
2241772Sjl139090 			if (ctrl != NULL) {
2251772Sjl139090 				queue_t	*temp_queue;
2261772Sjl139090 
2271772Sjl139090 				mutex_enter(&oplmsu_uinst->c_lock);
2281772Sjl139090 				temp_queue = WR(ctrl->queue);
2291772Sjl139090 				mutex_exit(&oplmsu_uinst->c_lock);
2301772Sjl139090 
2311772Sjl139090 				/* Reschedule a queue for service */
2321772Sjl139090 				enableok(temp_queue);
2331772Sjl139090 
2341772Sjl139090 				oplmsu_queue_flag = 0;
2351772Sjl139090 				oplmsu_wcmn_high_qenable(temp_queue, RW_WRITER);
2361772Sjl139090 			}
2371772Sjl139090 			rw_exit(&oplmsu_uinst->lock);
2381772Sjl139090 
2391772Sjl139090 			if (nmp != NULL) {
2401772Sjl139090 				freemsg(nmp);
2411772Sjl139090 			}
2421772Sjl139090 
2431772Sjl139090 			/* Wake up oplmsu_config_stop */
2441772Sjl139090 			mutex_enter(&oplmsu_uinst->l_lock);
2451772Sjl139090 			if (stp_lpath->sw_flag) {
2461772Sjl139090 				stp_lpath->sw_flag = 0;
2471772Sjl139090 				cv_signal(&stp_lpath->sw_cv);
2481772Sjl139090 			}
2491772Sjl139090 			mutex_exit(&oplmsu_uinst->l_lock);
2501772Sjl139090 			return (SUCCESS);
2511772Sjl139090 		} else { /* M_IOCNAK received */
2521772Sjl139090 			mutex_enter(&oplmsu_uinst->u_lock);
2531772Sjl139090 			mutex_enter(&oplmsu_uinst->l_lock);
2541772Sjl139090 			if ((chkflag == MSU_CMD_ACTIVE) &&
2551772Sjl139090 			    (lpath->hndl_uqueue == NULL)) {
2561772Sjl139090 				oplmsu_clear_ioctl_path(lpath);
2571772Sjl139090 				stp_upath = lpath->src_upath;
2581772Sjl139090 				lpath->src_upath = NULL;
2591772Sjl139090 				lpath->status = MSU_EXT_NOTUSED;
2601772Sjl139090 				mutex_exit(&oplmsu_uinst->l_lock);
2611772Sjl139090 
2621772Sjl139090 				oplmsu_cmn_set_upath_sts(upath,
2631772Sjl139090 				    MSU_PSTAT_STANDBY, upath->status,
2641772Sjl139090 				    MSU_STANDBY);
2651772Sjl139090 				mutex_exit(&oplmsu_uinst->u_lock);
2661772Sjl139090 
2671772Sjl139090 				if (hndl_mp != NULL) {
2681772Sjl139090 					freemsg(hndl_mp);
2691772Sjl139090 				}
2701772Sjl139090 
2711772Sjl139090 				OPLMSU_RWLOCK_UPGRADE();
2721772Sjl139090 				mutex_enter(&oplmsu_uinst->u_lock);
2731772Sjl139090 				oplmsu_uinst->inst_status =
2741772Sjl139090 				    oplmsu_get_inst_status();
2751772Sjl139090 				mutex_exit(&oplmsu_uinst->u_lock);
2761772Sjl139090 				rw_exit(&oplmsu_uinst->lock);
2771772Sjl139090 				return (SUCCESS);
2781772Sjl139090 			} else if ((chkflag == MSU_CMD_STOP) &&
2791772Sjl139090 			    (lpath->src_upath != NULL) &&
2801772Sjl139090 			    (lpath->src_upath->lpath->sw_flag)) {
2811772Sjl139090 			/* MSU_CMD_STOP for active path */
2821772Sjl139090 
2831772Sjl139090 				dst_queue = RD(lpath->hndl_uqueue);
2841772Sjl139090 				stp_upath = lpath->src_upath;
2851772Sjl139090 
2861772Sjl139090 				/* Search alternate path from standby paths */
2871772Sjl139090 				altn_upath = oplmsu_search_standby();
2881772Sjl139090 				if (altn_upath == NULL) {
2891772Sjl139090 					altn_upath = upath;
2901772Sjl139090 				}
2911772Sjl139090 
2921772Sjl139090 				mutex_exit(&oplmsu_uinst->l_lock);
2931772Sjl139090 				if (oplmsu_cmn_allocmb(lrq, mp, &fmp,
2941772Sjl139090 				    sizeof (char), MSU_READ_SIDE) == FAILURE) {
2951772Sjl139090 					mutex_exit(&oplmsu_uinst->u_lock);
2961772Sjl139090 					rw_exit(&oplmsu_uinst->lock);
2971772Sjl139090 					return (FAILURE);
2981772Sjl139090 				}
2991772Sjl139090 
3001772Sjl139090 				if (oplmsu_cmn_prechg(lrq, mp, MSU_READ_SIDE,
3011772Sjl139090 				    &nmp, &term_ioctl, &term_stat) == FAILURE) {
3021772Sjl139090 					mutex_exit(&oplmsu_uinst->u_lock);
3031772Sjl139090 					rw_exit(&oplmsu_uinst->lock);
3041772Sjl139090 					freeb(fmp);
3051772Sjl139090 					return (FAILURE);
3061772Sjl139090 				}
3071772Sjl139090 
3081772Sjl139090 				altn_upath->traditional_status = term_stat;
3091772Sjl139090 				altn_lpath = altn_upath->lpath;
3101772Sjl139090 
3111772Sjl139090 				mutex_enter(&oplmsu_uinst->l_lock);
3121772Sjl139090 				altn_lpath->hndl_mp = hndl_mp;
3131772Sjl139090 				altn_lpath->hndl_uqueue = dst_queue;
3141772Sjl139090 				altn_lpath->src_upath = stp_upath;
3151772Sjl139090 				altn_lpath->status = MSU_EXT_VOID;
3161772Sjl139090 				dst_queue = RD(altn_lpath->lower_queue);
3171772Sjl139090 
3181772Sjl139090 				oplmsu_cmn_set_upath_sts(upath, MSU_PSTAT_FAIL,
3191772Sjl139090 				    upath->status, MSU_FAIL);
3201772Sjl139090 
3211772Sjl139090 				oplmsu_clear_ioctl_path(lpath);
3221772Sjl139090 				lpath->src_upath = NULL;
3231772Sjl139090 				lpath->status = MSU_EXT_NOTUSED;
3241772Sjl139090 				mutex_exit(&oplmsu_uinst->l_lock);
3251772Sjl139090 				mutex_exit(&oplmsu_uinst->u_lock);
3261772Sjl139090 
3271772Sjl139090 				OPLMSU_RWLOCK_UPGRADE();
3281772Sjl139090 				mutex_enter(&oplmsu_uinst->u_lock);
3291772Sjl139090 				oplmsu_uinst->inst_status =
3301772Sjl139090 				    oplmsu_get_inst_status();
3311772Sjl139090 				mutex_exit(&oplmsu_uinst->u_lock);
3321772Sjl139090 				rw_exit(&oplmsu_uinst->lock);
3331772Sjl139090 				freemsg(mp);
3341772Sjl139090 				oplmsu_cmn_set_mflush(fmp);
3351772Sjl139090 
3361772Sjl139090 				OPLMSU_TRACE(dst_queue, fmp, MSU_TRC_LO);
3371772Sjl139090 				qreply(dst_queue, fmp);
3381772Sjl139090 
3391772Sjl139090 				OPLMSU_TRACE(dst_queue, nmp, MSU_TRC_LO);
3401772Sjl139090 				qreply(dst_queue, nmp);
3411772Sjl139090 				return (SUCCESS);
3421772Sjl139090 			}
3431772Sjl139090 		}
3441772Sjl139090 	} else if ((chkflag == TCSETS) || (chkflag == TCSETSW) ||
3451772Sjl139090 	    (chkflag == TCSETSF) || (chkflag == TIOCMSET) ||
3461772Sjl139090 	    (chkflag == TIOCSPPS) || (chkflag == TIOCSWINSZ) ||
3471772Sjl139090 	    (chkflag == TIOCSSOFTCAR)) {
3481772Sjl139090 		mutex_enter(&oplmsu_uinst->u_lock);
3491772Sjl139090 		mutex_enter(&oplmsu_uinst->l_lock);
3501772Sjl139090 
3511772Sjl139090 		if ((ack_flag == ACK_RES) &&
3521772Sjl139090 		    (lpath->hndl_uqueue != NULL)) { /* M_IOCACK received */
3531772Sjl139090 			mutex_exit(&oplmsu_uinst->l_lock);
3541772Sjl139090 			mutex_exit(&oplmsu_uinst->u_lock);
3551772Sjl139090 			if (oplmsu_cmn_copymb(lrq, mp, &nmp, hndl_mp,
3561772Sjl139090 			    MSU_READ_SIDE) == FAILURE) {
3571772Sjl139090 				rw_exit(&oplmsu_uinst->lock);
3581772Sjl139090 				return (FAILURE);
3591772Sjl139090 			}
3601772Sjl139090 
3611772Sjl139090 			OPLMSU_RWLOCK_UPGRADE();
3621772Sjl139090 			switch (chkflag) {
3631772Sjl139090 			case TCSETS :	/* FALLTHRU */
3641772Sjl139090 			case TCSETSW :	/* FALLTHRU */
3651772Sjl139090 			case TCSETSF :
3661772Sjl139090 				if (oplmsu_uinst->tcsets_p != NULL) {
3671772Sjl139090 					freemsg(oplmsu_uinst->tcsets_p);
3681772Sjl139090 				}
3691772Sjl139090 				oplmsu_uinst->tcsets_p = nmp;
3701772Sjl139090 				break;
3711772Sjl139090 
3721772Sjl139090 			case TIOCMSET :
3731772Sjl139090 				if (oplmsu_uinst->tiocmset_p != NULL) {
3741772Sjl139090 					freemsg(oplmsu_uinst->tiocmset_p);
3751772Sjl139090 				}
3761772Sjl139090 				oplmsu_uinst->tiocmset_p = nmp;
3771772Sjl139090 				break;
3781772Sjl139090 
3791772Sjl139090 			case TIOCSPPS :
3801772Sjl139090 				if (oplmsu_uinst->tiocspps_p != NULL) {
3811772Sjl139090 					freemsg(oplmsu_uinst->tiocspps_p);
3821772Sjl139090 				}
3831772Sjl139090 				oplmsu_uinst->tiocspps_p = nmp;
3841772Sjl139090 				break;
3851772Sjl139090 
3861772Sjl139090 			case TIOCSWINSZ :
3871772Sjl139090 				if (oplmsu_uinst->tiocswinsz_p != NULL) {
3881772Sjl139090 					freemsg(oplmsu_uinst->tiocswinsz_p);
3891772Sjl139090 				}
3901772Sjl139090 				oplmsu_uinst->tiocswinsz_p = nmp;
3911772Sjl139090 				break;
3921772Sjl139090 
3931772Sjl139090 			case TIOCSSOFTCAR :
3941772Sjl139090 				if (oplmsu_uinst->tiocssoftcar_p != NULL) {
3951772Sjl139090 					freemsg(oplmsu_uinst->tiocssoftcar_p);
3961772Sjl139090 				}
3971772Sjl139090 				oplmsu_uinst->tiocssoftcar_p = nmp;
3981772Sjl139090 				break;
3991772Sjl139090 			}
4001772Sjl139090 
4011772Sjl139090 			mutex_enter(&oplmsu_uinst->u_lock);
4021772Sjl139090 			mutex_enter(&oplmsu_uinst->l_lock);
4031772Sjl139090 			upath->traditional_status = lpath->status;
4041772Sjl139090 			nmp = lpath->hndl_mp;
4051772Sjl139090 			nmp->b_datap->db_type = M_IOCACK;
4061772Sjl139090 			dst_queue = RD(lpath->hndl_uqueue);
4071772Sjl139090 			bcopy(mp->b_rptr, nmp->b_rptr, sizeof (struct iocblk));
4081772Sjl139090 
4091772Sjl139090 			oplmsu_clear_ioctl_path(lpath);
4101772Sjl139090 			lpath->src_upath = NULL;
4111772Sjl139090 			lpath->status = MSU_EXT_NOTUSED;
4121772Sjl139090 			mutex_exit(&oplmsu_uinst->l_lock);
4131772Sjl139090 			mutex_exit(&oplmsu_uinst->u_lock);
4141772Sjl139090 			freemsg(mp);
415*11311SSurya.Prakki@Sun.COM 			(void) putq(dst_queue, nmp);
4161772Sjl139090 
4171772Sjl139090 			/* Check sleep flag and wake up thread */
4181772Sjl139090 			oplmsu_cmn_wakeup(dst_queue);
4191772Sjl139090 			rw_exit(&oplmsu_uinst->lock);
4201772Sjl139090 			return (SUCCESS);
4211772Sjl139090 		} else if ((ack_flag == NAK_RES) &&
4221772Sjl139090 		    (lpath->hndl_uqueue != NULL)) { /* M_IOCNAK received */
4231772Sjl139090 			upath->traditional_status = lpath->status;
4241772Sjl139090 
4251772Sjl139090 			nmp = lpath->hndl_mp;
4261772Sjl139090 			nmp->b_datap->db_type = M_IOCNAK;
4271772Sjl139090 			dst_queue = RD(lpath->hndl_uqueue);
4281772Sjl139090 
4291772Sjl139090 			oplmsu_clear_ioctl_path(lpath);
4301772Sjl139090 			lpath->src_upath = NULL;
4311772Sjl139090 			lpath->status = MSU_EXT_NOTUSED;
4321772Sjl139090 			mutex_exit(&oplmsu_uinst->l_lock);
4331772Sjl139090 			mutex_exit(&oplmsu_uinst->u_lock);
4341772Sjl139090 			freemsg(mp);
435*11311SSurya.Prakki@Sun.COM 			(void) putq(dst_queue, nmp);
4361772Sjl139090 
4371772Sjl139090 			/* Check sleep flag and wake up thread */
4381772Sjl139090 			oplmsu_cmn_wakeup(dst_queue);
4391772Sjl139090 			rw_exit(&oplmsu_uinst->lock);
4401772Sjl139090 			return (SUCCESS);
4411772Sjl139090 		}
4421772Sjl139090 	}
4431772Sjl139090 
4441772Sjl139090 	mutex_enter(&oplmsu_uinst->u_lock);
4451772Sjl139090 	switch (upath->status) {
4461772Sjl139090 	case MSU_PSTAT_FAIL :
4471772Sjl139090 		upath->traditional_status = MSU_FAIL;
4481772Sjl139090 		break;
4491772Sjl139090 
4501772Sjl139090 	case MSU_PSTAT_STOP :
4511772Sjl139090 		upath->traditional_status = MSU_STOP;
4521772Sjl139090 		break;
4531772Sjl139090 
4541772Sjl139090 	case MSU_PSTAT_STANDBY :
4551772Sjl139090 		upath->traditional_status = MSU_STANDBY;
4561772Sjl139090 		break;
4571772Sjl139090 
4581772Sjl139090 	case MSU_PSTAT_ACTIVE :
4591772Sjl139090 		upath->traditional_status = MSU_ACTIVE;
4601772Sjl139090 		break;
4611772Sjl139090 	}
4621772Sjl139090 
4631772Sjl139090 	mutex_enter(&oplmsu_uinst->l_lock);
4641772Sjl139090 	oplmsu_clear_ioctl_path(lpath);
4651772Sjl139090 	mutex_exit(&oplmsu_uinst->l_lock);
4661772Sjl139090 	mutex_exit(&oplmsu_uinst->u_lock);
4671772Sjl139090 	rw_exit(&oplmsu_uinst->lock);
4681772Sjl139090 	freemsg(mp);
4691772Sjl139090 	return (SUCCESS);
4701772Sjl139090 }
4711772Sjl139090 
4721772Sjl139090 /* M_ERROR or M_HANGUP response received */
4731772Sjl139090 int
oplmsu_lrmsg_error(queue_t * lrq,mblk_t * mp)4741772Sjl139090 oplmsu_lrmsg_error(queue_t *lrq, mblk_t *mp)
4751772Sjl139090 {
4761772Sjl139090 	upath_t	*upath, *altn_upath = NULL;
4771772Sjl139090 	lpath_t	*lpath, *altn_lpath = NULL;
4781772Sjl139090 	mblk_t	*nmp = NULL, *fmp = NULL;
4791772Sjl139090 	queue_t	*dst_queue = NULL;
4801772Sjl139090 	ctrl_t	*ctrl;
4811772Sjl139090 	int	term_stat, term_ioctl;
4821772Sjl139090 
4831772Sjl139090 	rw_enter(&oplmsu_uinst->lock, RW_READER);
4841772Sjl139090 	mutex_enter(&oplmsu_uinst->c_lock);
4851772Sjl139090 	ctrl = oplmsu_uinst->user_ctrl;
4861772Sjl139090 	if (ctrl != NULL) {
4871772Sjl139090 		dst_queue = RD(ctrl->queue);
4881772Sjl139090 	}
4891772Sjl139090 	mutex_exit(&oplmsu_uinst->c_lock);
4901772Sjl139090 
4911772Sjl139090 	mutex_enter(&oplmsu_uinst->u_lock);
4921772Sjl139090 	mutex_enter(&oplmsu_uinst->l_lock);
4931772Sjl139090 	lpath = (lpath_t *)lrq->q_ptr;
4941772Sjl139090 	upath = oplmsu_search_upath_info(lpath->path_no);
4951772Sjl139090 
4961873Sraghuram 	if (upath == NULL) {
4971873Sraghuram 		mutex_exit(&oplmsu_uinst->l_lock);
4981873Sraghuram 		mutex_exit(&oplmsu_uinst->u_lock);
4991873Sraghuram 		rw_exit(&oplmsu_uinst->lock);
5001873Sraghuram 		freemsg(mp);
5011873Sraghuram 		return (SUCCESS);
5021873Sraghuram 	}
5031873Sraghuram 
5041772Sjl139090 	if ((lpath->status == MSU_LINK_NU) ||
5051772Sjl139090 	    (lpath->status == MSU_SETID_NU) ||
5061772Sjl139090 	    (upath->traditional_status == MSU_WSTR_ACK) ||
5071772Sjl139090 	    (upath->traditional_status == MSU_WTCS_ACK) ||
5081772Sjl139090 	    (upath->traditional_status == MSU_WTMS_ACK) ||
5091772Sjl139090 	    (upath->traditional_status == MSU_WPPS_ACK) ||
5101772Sjl139090 	    (upath->traditional_status == MSU_WWSZ_ACK) ||
5111772Sjl139090 	    (upath->traditional_status == MSU_WCAR_ACK) ||
5121772Sjl139090 	    (upath->traditional_status == MSU_WSTP_ACK) ||
5131772Sjl139090 	    (upath->traditional_status == MSU_WPTH_CHG)) {
5141772Sjl139090 		mutex_exit(&oplmsu_uinst->l_lock);
5151772Sjl139090 		mutex_exit(&oplmsu_uinst->u_lock);
5161772Sjl139090 		rw_exit(&oplmsu_uinst->lock);
5171772Sjl139090 		freemsg(mp);
5181772Sjl139090 	} else if ((upath->traditional_status == MSU_MAKE_INST) ||
5191772Sjl139090 	    (upath->traditional_status == MSU_STOP) ||
5201772Sjl139090 	    (upath->traditional_status == MSU_STANDBY) ||
5211772Sjl139090 	    (upath->traditional_status == MSU_SETID) ||
5221772Sjl139090 	    (upath->traditional_status == MSU_LINK)) {
5231772Sjl139090 		oplmsu_cmn_set_upath_sts(upath, MSU_PSTAT_FAIL, upath->status,
5241772Sjl139090 		    MSU_FAIL);
5251772Sjl139090 		mutex_exit(&oplmsu_uinst->l_lock);
5261772Sjl139090 		mutex_exit(&oplmsu_uinst->u_lock);
5271772Sjl139090 		rw_exit(&oplmsu_uinst->lock);
5281772Sjl139090 		freemsg(mp);
5291772Sjl139090 	} else if (upath->traditional_status == MSU_FAIL) {
5301772Sjl139090 		mutex_exit(&oplmsu_uinst->l_lock);
5311772Sjl139090 		mutex_exit(&oplmsu_uinst->u_lock);
5321772Sjl139090 		rw_exit(&oplmsu_uinst->lock);
5331772Sjl139090 		freemsg(mp);
5341772Sjl139090 	} else if (upath->traditional_status == MSU_ACTIVE) {
5351772Sjl139090 		altn_upath = oplmsu_search_standby();
5361772Sjl139090 		if (altn_upath == NULL) {
5371772Sjl139090 			oplmsu_cmn_set_upath_sts(upath, MSU_PSTAT_FAIL,
5381772Sjl139090 			    upath->status, MSU_FAIL);
5391772Sjl139090 
5401772Sjl139090 			oplmsu_clear_ioctl_path(lpath);
5411772Sjl139090 			lpath->src_upath = NULL;
5421772Sjl139090 			lpath->status = MSU_EXT_NOTUSED;
5431772Sjl139090 			lpath->uinst = NULL;
5441772Sjl139090 			mutex_exit(&oplmsu_uinst->l_lock);
5451772Sjl139090 			mutex_exit(&oplmsu_uinst->u_lock);
5461772Sjl139090 
5471772Sjl139090 			OPLMSU_RWLOCK_UPGRADE();
5481772Sjl139090 			oplmsu_uinst->lower_queue = NULL;
5491772Sjl139090 			rw_exit(&oplmsu_uinst->lock);
5501772Sjl139090 			freemsg(mp);
5511772Sjl139090 			return (SUCCESS);
5521772Sjl139090 		}
5531772Sjl139090 
5541772Sjl139090 		mutex_exit(&oplmsu_uinst->l_lock);
5551772Sjl139090 		if (oplmsu_cmn_allocmb(lrq, mp, &fmp, sizeof (char),
5561772Sjl139090 		    MSU_READ_SIDE) == FAILURE) {
5571772Sjl139090 			mutex_exit(&oplmsu_uinst->u_lock);
5581772Sjl139090 			rw_exit(&oplmsu_uinst->lock);
5591772Sjl139090 			return (FAILURE);
5601772Sjl139090 		}
5611772Sjl139090 
5621772Sjl139090 		if (oplmsu_cmn_prechg(lrq, mp, MSU_READ_SIDE, &nmp, &term_ioctl,
5631772Sjl139090 		    &term_stat) == FAILURE) {
5641772Sjl139090 			mutex_exit(&oplmsu_uinst->u_lock);
5651772Sjl139090 			rw_exit(&oplmsu_uinst->lock);
5661772Sjl139090 			freeb(fmp);
5671772Sjl139090 			return (FAILURE);
5681772Sjl139090 		}
5691772Sjl139090 
5701772Sjl139090 		oplmsu_cmn_set_upath_sts(upath, MSU_PSTAT_FAIL,
5711772Sjl139090 		    upath->status, MSU_FAIL);
5721772Sjl139090 
5731772Sjl139090 		mutex_enter(&oplmsu_uinst->l_lock);
5741772Sjl139090 		lpath->uinst = NULL;
5751772Sjl139090 
5761772Sjl139090 		altn_upath->traditional_status = term_stat;
5771772Sjl139090 		altn_lpath = altn_upath->lpath;
5781772Sjl139090 
5791772Sjl139090 		altn_lpath->hndl_mp = NULL;
5801772Sjl139090 		altn_lpath->hndl_uqueue = NULL;
5811772Sjl139090 		altn_lpath->src_upath = upath;
5821772Sjl139090 		altn_lpath->status = MSU_EXT_VOID;
5831772Sjl139090 		dst_queue = RD(altn_lpath->lower_queue);
5841772Sjl139090 		mutex_exit(&oplmsu_uinst->l_lock);
5851772Sjl139090 		mutex_exit(&oplmsu_uinst->u_lock);
5861772Sjl139090 
5871772Sjl139090 		OPLMSU_RWLOCK_UPGRADE();
5881772Sjl139090 		oplmsu_uinst->lower_queue = NULL;
5891772Sjl139090 		oplmsu_cmn_set_mflush(fmp);
5901772Sjl139090 
5911772Sjl139090 		if (ctrl != NULL) {
5921772Sjl139090 			mutex_enter(&oplmsu_uinst->c_lock);
5931772Sjl139090 			noenable(WR(ctrl->queue));
5941772Sjl139090 			mutex_exit(&oplmsu_uinst->c_lock);
5951772Sjl139090 
5961772Sjl139090 			oplmsu_queue_flag = 1;
5971772Sjl139090 		}
5981772Sjl139090 
5991772Sjl139090 		rw_exit(&oplmsu_uinst->lock);
6001772Sjl139090 		freemsg(mp);
6011772Sjl139090 
6021772Sjl139090 		OPLMSU_TRACE(dst_queue, fmp, MSU_TRC_LO);
6031772Sjl139090 		qreply(dst_queue, fmp);
6041772Sjl139090 		OPLMSU_TRACE(dst_queue, nmp, MSU_TRC_LO);
6051772Sjl139090 		qreply(dst_queue, nmp);
6061772Sjl139090 	}
6071772Sjl139090 	return (SUCCESS);
6081772Sjl139090 }
6091772Sjl139090 
6101772Sjl139090 /* M_DATA[xoff/xon] was received from serial port */
6111772Sjl139090 int
oplmsu_lrdata_xoffxon(queue_t * lrq,mblk_t * mp)6121772Sjl139090 oplmsu_lrdata_xoffxon(queue_t *lrq, mblk_t *mp)
6131772Sjl139090 {
6141772Sjl139090 	upath_t	*upath, *stp_upath = NULL;
6151772Sjl139090 	lpath_t	*lpath, *stp_lpath = NULL;
6161772Sjl139090 	mblk_t	*nmp = NULL, *fmp = NULL;
6171772Sjl139090 	ctrl_t	*ctrl;
6181772Sjl139090 	int	term_stat, term_ioctl;
6191772Sjl139090 
6201772Sjl139090 	rw_enter(&oplmsu_uinst->lock, RW_READER);
6211772Sjl139090 	mutex_enter(&oplmsu_uinst->u_lock);
6221772Sjl139090 	mutex_enter(&oplmsu_uinst->l_lock);
6231772Sjl139090 
6241772Sjl139090 	if (oplmsu_uinst->lower_queue != NULL) {
6251772Sjl139090 		/* Get lower path of active status */
6261772Sjl139090 		stp_lpath = (lpath_t *)oplmsu_uinst->lower_queue->q_ptr;
6271772Sjl139090 		if (stp_lpath != NULL) {
6281772Sjl139090 			stp_upath =
6291772Sjl139090 			    oplmsu_search_upath_info(stp_lpath->path_no);
6301772Sjl139090 		}
6311772Sjl139090 	}
6321772Sjl139090 
6331772Sjl139090 	lpath = (lpath_t *)lrq->q_ptr;
6341772Sjl139090 	upath = oplmsu_search_upath_info(lpath->path_no);
6351772Sjl139090 
6361873Sraghuram 	if (upath == NULL) {
6371873Sraghuram 		mutex_exit(&oplmsu_uinst->l_lock);
6381873Sraghuram 		mutex_exit(&oplmsu_uinst->u_lock);
6391873Sraghuram 		rw_exit(&oplmsu_uinst->lock);
6401873Sraghuram 		freemsg(mp);
6411873Sraghuram 		return (SUCCESS);
6421873Sraghuram 	}
6431873Sraghuram 
6441772Sjl139090 	if ((stp_upath != NULL) && (stp_upath != upath)) {
6451772Sjl139090 		if ((stp_upath->status != MSU_PSTAT_ACTIVE) ||
6461772Sjl139090 		    (stp_upath->traditional_status != MSU_ACTIVE)) {
6471772Sjl139090 			mutex_exit(&oplmsu_uinst->l_lock);
6481772Sjl139090 			mutex_exit(&oplmsu_uinst->u_lock);
6491772Sjl139090 			rw_exit(&oplmsu_uinst->lock);
650*11311SSurya.Prakki@Sun.COM 			(void) putbq(lrq, mp);
6511772Sjl139090 			return (FAILURE);
6521772Sjl139090 		}
6531772Sjl139090 	}
6541772Sjl139090 
6551772Sjl139090 	if ((upath->status == MSU_PSTAT_ACTIVE) &&
6561772Sjl139090 	    ((upath->traditional_status == MSU_ACTIVE) ||
6571772Sjl139090 	    (upath->traditional_status == MSU_WTCS_ACK) ||
6581772Sjl139090 	    (upath->traditional_status == MSU_WTMS_ACK) ||
6591772Sjl139090 	    (upath->traditional_status == MSU_WPPS_ACK) ||
6601772Sjl139090 	    (upath->traditional_status == MSU_WWSZ_ACK) ||
6611772Sjl139090 	    (upath->traditional_status == MSU_WCAR_ACK))) {
6621772Sjl139090 		mutex_exit(&oplmsu_uinst->l_lock);
6631772Sjl139090 		mutex_exit(&oplmsu_uinst->u_lock);
664*11311SSurya.Prakki@Sun.COM 		(void) oplmsu_rcmn_through_hndl(lrq, mp, MSU_NORM);
6651772Sjl139090 		rw_exit(&oplmsu_uinst->lock);
6661772Sjl139090 		return (SUCCESS);
6671772Sjl139090 	} else if ((upath->status != MSU_PSTAT_STANDBY) ||
6681772Sjl139090 	    (upath->traditional_status != MSU_STANDBY)) {
6691772Sjl139090 		mutex_exit(&oplmsu_uinst->l_lock);
6701772Sjl139090 		mutex_exit(&oplmsu_uinst->u_lock);
6711772Sjl139090 		rw_exit(&oplmsu_uinst->lock);
6721772Sjl139090 		freemsg(mp);
6731772Sjl139090 		cmn_err(CE_WARN, "oplmsu: lr-xoffxon: "
6741772Sjl139090 		    "Can't change to specified path");
6751772Sjl139090 		return (SUCCESS);
6761772Sjl139090 	}
6771772Sjl139090 	mutex_exit(&oplmsu_uinst->l_lock);
6781772Sjl139090 
6791772Sjl139090 	if (oplmsu_cmn_allocmb(lrq, mp, &fmp, sizeof (char), MSU_READ_SIDE) ==
6801772Sjl139090 	    FAILURE) {
6811772Sjl139090 		mutex_exit(&oplmsu_uinst->u_lock);
6821772Sjl139090 		rw_exit(&oplmsu_uinst->lock);
6831772Sjl139090 		return (FAILURE);
6841772Sjl139090 	}
6851772Sjl139090 
6861772Sjl139090 	if (oplmsu_cmn_prechg(lrq, mp, MSU_READ_SIDE, &nmp, &term_ioctl,
6871772Sjl139090 	    &term_stat) == FAILURE) {
6881772Sjl139090 		mutex_exit(&oplmsu_uinst->u_lock);
6891772Sjl139090 		rw_exit(&oplmsu_uinst->lock);
6901772Sjl139090 		freeb(fmp);
6911772Sjl139090 		return (FAILURE);
6921772Sjl139090 	}
6931772Sjl139090 
6941772Sjl139090 	oplmsu_cmn_set_mflush(fmp);
6951772Sjl139090 	upath->traditional_status = term_stat;
6961772Sjl139090 
6971772Sjl139090 	mutex_enter(&oplmsu_uinst->l_lock);
6981772Sjl139090 	lpath->hndl_mp = mp;
6991772Sjl139090 	lpath->hndl_uqueue = NULL;
7001772Sjl139090 	lpath->src_upath = stp_upath;
7011772Sjl139090 	lpath->status = MSU_EXT_VOID;
7021772Sjl139090 
7031772Sjl139090 	mutex_enter(&oplmsu_uinst->c_lock);
7041772Sjl139090 	ctrl = oplmsu_uinst->user_ctrl;
7051772Sjl139090 	if (term_stat != MSU_WPTH_CHG) {
7061772Sjl139090 		/*
7071772Sjl139090 		 * Send termios to new active path and wait response
7081772Sjl139090 		 */
7091772Sjl139090 		if (ctrl != NULL) {
7101772Sjl139090 			noenable(WR(ctrl->queue));
7111772Sjl139090 		}
7121772Sjl139090 		mutex_exit(&oplmsu_uinst->c_lock);
7131772Sjl139090 		mutex_exit(&oplmsu_uinst->l_lock);
7141772Sjl139090 		mutex_exit(&oplmsu_uinst->u_lock);
7151772Sjl139090 		rw_exit(&oplmsu_uinst->lock);
7161772Sjl139090 
7171772Sjl139090 		OPLMSU_TRACE(RD(lrq), fmp, MSU_TRC_LO);
7181772Sjl139090 		qreply(RD(lrq), fmp);
7191772Sjl139090 		OPLMSU_TRACE(RD(lrq), nmp, MSU_TRC_LO);
7201772Sjl139090 		qreply(RD(lrq), nmp);
7211772Sjl139090 	} else {
7221772Sjl139090 		/*
7231772Sjl139090 		 * No termios messages are received. Change active path.
7241772Sjl139090 		 */
7251772Sjl139090 
7261772Sjl139090 		oplmsu_cmn_set_upath_sts(upath, MSU_PSTAT_ACTIVE, upath->status,
7271772Sjl139090 		    MSU_ACTIVE);
7281772Sjl139090 
7291772Sjl139090 		lpath->uinst = oplmsu_uinst;
7301772Sjl139090 		lpath->src_upath = NULL;
7311772Sjl139090 		lpath->status = MSU_EXT_NOTUSED;
7321772Sjl139090 
7331772Sjl139090 		/* Notify of the active path changing */
734*11311SSurya.Prakki@Sun.COM 		(void) prom_opl_switch_console(upath->ser_devcb.lsb);
7351772Sjl139090 
736*11311SSurya.Prakki@Sun.COM 		(void) putq(WR(lrq), fmp);
7371772Sjl139090 
7381772Sjl139090 		/* Send XON to notify active path */
7391772Sjl139090 		(void) oplmsu_cmn_put_xoffxon(WR(lrq), MSU_XON_4);
7401772Sjl139090 
7411772Sjl139090 		if (lpath->hndl_mp != NULL) {
7421772Sjl139090 			/* Put a message(M_DATA) on a queue */
7431772Sjl139090 			if (ctrl != NULL) {
744*11311SSurya.Prakki@Sun.COM 				(void) putq(RD(ctrl->queue), lpath->hndl_mp);
7451772Sjl139090 			}
7461772Sjl139090 		}
7471772Sjl139090 
7481772Sjl139090 		oplmsu_clear_ioctl_path(lpath);
7491772Sjl139090 
7501772Sjl139090 		if (ctrl != NULL) {
7511772Sjl139090 			noenable(WR(ctrl->queue));
7521772Sjl139090 		}
7531772Sjl139090 
7541772Sjl139090 		if ((stp_upath != NULL) && (stp_lpath != NULL)) {
7551772Sjl139090 			/* Change the status of stop path */
7561772Sjl139090 			oplmsu_cmn_set_upath_sts(stp_upath, MSU_PSTAT_STANDBY,
7571772Sjl139090 			    stp_upath->status, MSU_STANDBY);
7581772Sjl139090 
7591772Sjl139090 			oplmsu_clear_ioctl_path(stp_lpath);
7601772Sjl139090 			stp_lpath->uinst = NULL;
7611772Sjl139090 			stp_lpath->src_upath = NULL;
7621772Sjl139090 			stp_lpath->status = MSU_EXT_NOTUSED;
7631772Sjl139090 		}
7641772Sjl139090 #ifdef DEBUG
7651772Sjl139090 		oplmsu_cmn_prt_pathname(upath->ser_devcb.dip);
7661772Sjl139090 #endif
7671772Sjl139090 		/* Send XOFF to notify all standby paths */
7681772Sjl139090 		oplmsu_cmn_putxoff_standby();
7691772Sjl139090 		mutex_exit(&oplmsu_uinst->c_lock);
7701772Sjl139090 		mutex_exit(&oplmsu_uinst->l_lock);
7711772Sjl139090 		mutex_exit(&oplmsu_uinst->u_lock);
7721772Sjl139090 
7731772Sjl139090 		OPLMSU_RWLOCK_UPGRADE();
7741772Sjl139090 		mutex_enter(&oplmsu_uinst->u_lock);
7751772Sjl139090 		oplmsu_uinst->lower_queue = lrq;
7761772Sjl139090 		oplmsu_uinst->inst_status = oplmsu_get_inst_status();
7771772Sjl139090 		mutex_exit(&oplmsu_uinst->u_lock);
7781772Sjl139090 
7791772Sjl139090 		if (ctrl != NULL) {
7801772Sjl139090 			queue_t *temp_queue;
7811772Sjl139090 
7821772Sjl139090 			mutex_enter(&oplmsu_uinst->c_lock);
7831772Sjl139090 			temp_queue = WR(ctrl->queue);
7841772Sjl139090 			mutex_exit(&oplmsu_uinst->c_lock);
7851772Sjl139090 
7861772Sjl139090 			/* Reschedule a queue for service */
7871772Sjl139090 			enableok(temp_queue);
7881772Sjl139090 
7891772Sjl139090 			oplmsu_queue_flag = 0;
7901772Sjl139090 			oplmsu_wcmn_high_qenable(temp_queue, RW_WRITER);
7911772Sjl139090 		}
7921772Sjl139090 		rw_exit(&oplmsu_uinst->lock);
7931772Sjl139090 	}
7941772Sjl139090 	return (SUCCESS);
7951772Sjl139090 }
796