xref: /onnv-gate/usr/src/uts/common/io/scsi/impl/scsi_transport.c (revision 12045:c8a185097d95)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
51998Staylor  * Common Development and Distribution License (the "License").
61998Staylor  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
21*12045SLi.He@Sun.COM 
220Sstevel@tonic-gate /*
23*12045SLi.He@Sun.COM  * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate /*
270Sstevel@tonic-gate  * Main Transport Routine for SCSA
280Sstevel@tonic-gate  */
290Sstevel@tonic-gate #include <sys/scsi/scsi.h>
300Sstevel@tonic-gate #include <sys/thread.h>
316640Scth #include <sys/bitmap.h>
320Sstevel@tonic-gate 
330Sstevel@tonic-gate #define	A_TO_TRAN(ap)	((ap)->a_hba_tran)
340Sstevel@tonic-gate #define	P_TO_TRAN(pkt)	((pkt)->pkt_address.a_hba_tran)
350Sstevel@tonic-gate #define	P_TO_ADDR(pkt)	(&((pkt)->pkt_address))
360Sstevel@tonic-gate 
370Sstevel@tonic-gate #ifdef DEBUG
380Sstevel@tonic-gate #define	SCSI_POLL_STAT
390Sstevel@tonic-gate #endif
400Sstevel@tonic-gate 
410Sstevel@tonic-gate #ifdef SCSI_POLL_STAT
420Sstevel@tonic-gate int	scsi_poll_user;
430Sstevel@tonic-gate int	scsi_poll_intr;
440Sstevel@tonic-gate #endif
450Sstevel@tonic-gate 
466640Scth int			scsi_pkt_bad_alloc_msg = 1;
476640Scth extern	ulong_t		*scsi_pkt_bad_alloc_bitmap;
480Sstevel@tonic-gate extern	kmutex_t	scsi_flag_nointr_mutex;
490Sstevel@tonic-gate extern	kcondvar_t	scsi_flag_nointr_cv;
500Sstevel@tonic-gate 
516640Scth extern int		do_polled_io;
526640Scth 
53*12045SLi.He@Sun.COM extern int		scsi_pkt_allow_naca;
54*12045SLi.He@Sun.COM extern uchar_t		scsi_cdb_size[];
55*12045SLi.He@Sun.COM #define	NACA_IS_SET(cdb)						\
56*12045SLi.He@Sun.COM 	(((cdb)[scsi_cdb_size[GETGROUP((union scsi_cdb *)(cdb))] - 1]	\
57*12045SLi.He@Sun.COM 	& CDB_FLAG_NACA) ? 1 : 0)
58*12045SLi.He@Sun.COM 
590Sstevel@tonic-gate /*
600Sstevel@tonic-gate  * we used to set the callback_done value to NULL after the callback
610Sstevel@tonic-gate  * but this interfered with esp/fas drivers that also set the callback
620Sstevel@tonic-gate  * to NULL to prevent callbacks during error recovery
6310967SRandall.Ralphs@Sun.COM  * to prevent confusion, create a truly unique value.
6410967SRandall.Ralphs@Sun.COM  * The scsi_callback_done() function is used to detect a packet
6510967SRandall.Ralphs@Sun.COM  * completion being called a second time.
660Sstevel@tonic-gate  */
6710967SRandall.Ralphs@Sun.COM /* ARGSUSED */
6810967SRandall.Ralphs@Sun.COM void
scsi_callback_done(struct scsi_pkt * pkt)6910967SRandall.Ralphs@Sun.COM scsi_callback_done(struct scsi_pkt *pkt)
7010967SRandall.Ralphs@Sun.COM {
7110967SRandall.Ralphs@Sun.COM 	cmn_err(CE_PANIC,
7210967SRandall.Ralphs@Sun.COM 	    "%s: duplicate scsi_callback_done() on same scsi_pkt(9s)",
7310967SRandall.Ralphs@Sun.COM 	    mod_containing_pc(caller()));
7410967SRandall.Ralphs@Sun.COM }
7510967SRandall.Ralphs@Sun.COM 
7610967SRandall.Ralphs@Sun.COM #define	CALLBACK_DONE (scsi_callback_done)
770Sstevel@tonic-gate 
780Sstevel@tonic-gate static void
scsi_flag_nointr_comp(struct scsi_pkt * pkt)790Sstevel@tonic-gate scsi_flag_nointr_comp(struct scsi_pkt *pkt)
800Sstevel@tonic-gate {
810Sstevel@tonic-gate 	mutex_enter(&scsi_flag_nointr_mutex);
820Sstevel@tonic-gate 	pkt->pkt_comp = CALLBACK_DONE;
830Sstevel@tonic-gate 	/*
840Sstevel@tonic-gate 	 * We need cv_broadcast, because there can be more
850Sstevel@tonic-gate 	 * than one thread sleeping on the cv. We
860Sstevel@tonic-gate 	 * will wake all of them. The correct  one will
870Sstevel@tonic-gate 	 * continue and the rest will again go to sleep.
880Sstevel@tonic-gate 	 */
890Sstevel@tonic-gate 	cv_broadcast(&scsi_flag_nointr_cv);
900Sstevel@tonic-gate 	mutex_exit(&scsi_flag_nointr_mutex);
910Sstevel@tonic-gate }
920Sstevel@tonic-gate 
930Sstevel@tonic-gate /*
940Sstevel@tonic-gate  * A packet can have FLAG_NOINTR set because of target driver or
950Sstevel@tonic-gate  * scsi_poll(). If FLAG_NOINTR is set and we are in user context,
960Sstevel@tonic-gate  * we can avoid busy waiting in HBA by replacing the callback
970Sstevel@tonic-gate  * function with our own function and resetting FLAG_NOINTR. We
980Sstevel@tonic-gate  * can't do this in interrupt context because cv_wait will
990Sstevel@tonic-gate  * sleep with CPU priority raised high and in case of some failure,
1000Sstevel@tonic-gate  * the CPU will be stuck in high priority.
1010Sstevel@tonic-gate  */
1020Sstevel@tonic-gate 
1030Sstevel@tonic-gate int
scsi_transport(struct scsi_pkt * pkt)1040Sstevel@tonic-gate scsi_transport(struct scsi_pkt *pkt)
1050Sstevel@tonic-gate {
1060Sstevel@tonic-gate 	struct scsi_address	*ap = P_TO_ADDR(pkt);
1076640Scth 	int			rval = TRAN_ACCEPT;
1086640Scth 	major_t			major;
1096640Scth 
1106640Scth 	/*
111*12045SLi.He@Sun.COM 	 * Add an assertion check for debugging as use of the NACA flag
112*12045SLi.He@Sun.COM 	 * can cause problems. If an initiator sets it but does not clear
113*12045SLi.He@Sun.COM 	 * it, other initiators would end up waiting indefinitely for the
114*12045SLi.He@Sun.COM 	 * first to clear ACA.
115*12045SLi.He@Sun.COM 	 */
116*12045SLi.He@Sun.COM 	if (!scsi_pkt_allow_naca) {
117*12045SLi.He@Sun.COM 		ASSERT(!NACA_IS_SET(pkt->pkt_cdbp));
118*12045SLi.He@Sun.COM 	}
119*12045SLi.He@Sun.COM 
120*12045SLi.He@Sun.COM 	/*
1216640Scth 	 * The DDI does not allow drivers to allocate their own scsi_pkt(9S),
1226640Scth 	 * a driver can't have *any* compiled in dependencies on the
1236640Scth 	 * "sizeof (struct scsi_pkt)". While this has been the case for years,
1246640Scth 	 * many drivers have still not been fixed (or have regressed - tempted
1256640Scth 	 * by kmem_cache_alloc()).  The correct way to allocate a scsi_pkt
1266640Scth 	 * is by calling scsi_hba_pkt_alloc(9F), or by implementing the
1276640Scth 	 * tran_setup_pkt(9E) interfaces.
1286640Scth 	 *
1296640Scth 	 * The code below will identify drivers that violate this rule, and
1306640Scth 	 * print a message. The message will identify broken drivers, and
1316640Scth 	 * encourage getting these drivers fixed - after which this code
1326640Scth 	 * can be removed. Getting HBA drivers fixed is important because
1336640Scth 	 * broken drivers are an impediment to SCSA enhancement.
1346640Scth 	 *
1356640Scth 	 * We use the scsi_pkt_allocated_correctly() to determine if the
1366640Scth 	 * scsi_pkt we are about to start was correctly allocated. The
1376640Scth 	 * scsi_pkt_bad_alloc_bitmap is used to limit messages to one per
1386640Scth 	 * driver per reboot, and with non-debug code we only check the
1396640Scth 	 * first scsi_pkt.
1406640Scth 	 */
1416640Scth 	if (scsi_pkt_bad_alloc_msg) {
1426640Scth 		major = ddi_driver_major(P_TO_TRAN(pkt)->tran_hba_dip);
1436640Scth 		if (!BT_TEST(scsi_pkt_bad_alloc_bitmap, major) &&
1446640Scth 		    !scsi_pkt_allocated_correctly(pkt)) {
1456640Scth 			BT_SET(scsi_pkt_bad_alloc_bitmap, major);
1466640Scth 			cmn_err(CE_WARN, "%s: violates DDI scsi_pkt(9S) "
1476640Scth 			    "allocation rules",
1486640Scth 			    ddi_driver_name(P_TO_TRAN(pkt)->tran_hba_dip));
1496640Scth 		}
1506640Scth #ifndef	DEBUG
1516640Scth 		/* On non-debug kernel, only check the first packet */
1526640Scth 		BT_SET(scsi_pkt_bad_alloc_bitmap, major);
1536640Scth #endif	/* DEBUG */
1546640Scth 	}
1550Sstevel@tonic-gate 
15610967SRandall.Ralphs@Sun.COM 	/* Some retryed packets come with this flag not cleared */
15710967SRandall.Ralphs@Sun.COM 	pkt->pkt_flags &= ~FLAG_PKT_COMP_CALLED;
15810967SRandall.Ralphs@Sun.COM 
1590Sstevel@tonic-gate 	/*
1600Sstevel@tonic-gate 	 * Check if we are required to do polled I/O. We can
1610Sstevel@tonic-gate 	 * get scsi_pkts that don't have the FLAG_NOINTR bit
1620Sstevel@tonic-gate 	 * set in the pkt_flags. When do_polled_io is set
1630Sstevel@tonic-gate 	 * we will probably be at a high IPL and not get any
1640Sstevel@tonic-gate 	 * command completion interrupts. We force polled I/Os
1650Sstevel@tonic-gate 	 * for such packets and do a callback of the completion
1660Sstevel@tonic-gate 	 * routine ourselves.
1670Sstevel@tonic-gate 	 */
1680Sstevel@tonic-gate 	if (!do_polled_io && ((pkt->pkt_flags & FLAG_NOINTR) == 0)) {
1690Sstevel@tonic-gate 		return (*A_TO_TRAN(ap)->tran_start)(ap, pkt);
1700Sstevel@tonic-gate 	} else if ((curthread->t_flag & T_INTR_THREAD) || do_polled_io) {
1710Sstevel@tonic-gate #ifdef SCSI_POLL_STAT
1720Sstevel@tonic-gate 		mutex_enter(&scsi_flag_nointr_mutex);
1730Sstevel@tonic-gate 		scsi_poll_intr++;
1740Sstevel@tonic-gate 		mutex_exit(&scsi_flag_nointr_mutex);
1750Sstevel@tonic-gate #endif
1760Sstevel@tonic-gate 		/*
1770Sstevel@tonic-gate 		 * If its an interrupt thread or we already have the
1780Sstevel@tonic-gate 		 * the FLAG_NOINTR flag set, we go ahead and call the
1790Sstevel@tonic-gate 		 * the hba's start routine directly. We force polling
1800Sstevel@tonic-gate 		 * only if we have do_polled_io set and FLAG_NOINTR
1810Sstevel@tonic-gate 		 * not set.
1820Sstevel@tonic-gate 		 */
1830Sstevel@tonic-gate 		if (!do_polled_io || (pkt->pkt_flags & FLAG_NOINTR)) {
1840Sstevel@tonic-gate 			return ((*A_TO_TRAN(ap)->tran_start)(ap, pkt));
1850Sstevel@tonic-gate 		} else {
1860Sstevel@tonic-gate 			uint_t		savef;
1870Sstevel@tonic-gate 			void		(*savec)();
1880Sstevel@tonic-gate 			/*
1890Sstevel@tonic-gate 			 * save the completion routine and pkt_flags
1900Sstevel@tonic-gate 			 */
1910Sstevel@tonic-gate 			savef = pkt->pkt_flags;
1920Sstevel@tonic-gate 			savec = pkt->pkt_comp;
1930Sstevel@tonic-gate 			pkt->pkt_flags |= FLAG_NOINTR;
1940Sstevel@tonic-gate 			pkt->pkt_comp = 0;
1950Sstevel@tonic-gate 
1960Sstevel@tonic-gate 			rval = (*A_TO_TRAN(ap)->tran_start)(ap, pkt);
1970Sstevel@tonic-gate 
1980Sstevel@tonic-gate 			/* only continue of transport accepted request */
1990Sstevel@tonic-gate 			if (rval == TRAN_ACCEPT) {
2000Sstevel@tonic-gate 				/*
2010Sstevel@tonic-gate 				 * Restore the pkt_completion routine
2020Sstevel@tonic-gate 				 * and pkt flags and call the completion
2030Sstevel@tonic-gate 				 * routine.
2040Sstevel@tonic-gate 				 */
2050Sstevel@tonic-gate 				pkt->pkt_comp = savec;
2060Sstevel@tonic-gate 				pkt->pkt_flags = savef;
2078660SSrivijitha.Dugganapalli@Sun.COM 				scsi_hba_pkt_comp(pkt);
2080Sstevel@tonic-gate 				return (rval);
2090Sstevel@tonic-gate 			}
2100Sstevel@tonic-gate 
2110Sstevel@tonic-gate 			/*
2120Sstevel@tonic-gate 			 * rval was not TRAN_ACCEPT -- don't want command
2130Sstevel@tonic-gate 			 * to be retried
2140Sstevel@tonic-gate 			 */
2150Sstevel@tonic-gate 			return (TRAN_FATAL_ERROR);
2160Sstevel@tonic-gate 		}
2170Sstevel@tonic-gate 	} else {
2180Sstevel@tonic-gate 		uint_t	savef;
2190Sstevel@tonic-gate 		void	(*savec)();
2200Sstevel@tonic-gate 
2210Sstevel@tonic-gate #ifdef SCSI_POLL_STAT
2220Sstevel@tonic-gate 		mutex_enter(&scsi_flag_nointr_mutex);
2230Sstevel@tonic-gate 		scsi_poll_user++;
2240Sstevel@tonic-gate 		mutex_exit(&scsi_flag_nointr_mutex);
2250Sstevel@tonic-gate #endif
2260Sstevel@tonic-gate 		savef = pkt->pkt_flags;
2270Sstevel@tonic-gate 		savec = pkt->pkt_comp;
2280Sstevel@tonic-gate 
2290Sstevel@tonic-gate 		pkt->pkt_comp = scsi_flag_nointr_comp;
2300Sstevel@tonic-gate 		pkt->pkt_flags &= ~FLAG_NOINTR;
2310Sstevel@tonic-gate 		pkt->pkt_flags |= FLAG_IMMEDIATE_CB;
2320Sstevel@tonic-gate 
23310696SDavid.Hollister@Sun.COM 		if ((rval = (*A_TO_TRAN(ap)->tran_start)(ap, pkt)) ==
2346640Scth 		    TRAN_ACCEPT) {
2350Sstevel@tonic-gate 			mutex_enter(&scsi_flag_nointr_mutex);
2360Sstevel@tonic-gate 			while (pkt->pkt_comp != CALLBACK_DONE) {
2370Sstevel@tonic-gate 				cv_wait(&scsi_flag_nointr_cv,
2386640Scth 				    &scsi_flag_nointr_mutex);
2390Sstevel@tonic-gate 			}
2400Sstevel@tonic-gate 			mutex_exit(&scsi_flag_nointr_mutex);
2410Sstevel@tonic-gate 		}
2420Sstevel@tonic-gate 
2430Sstevel@tonic-gate 		pkt->pkt_flags = savef;
2440Sstevel@tonic-gate 		pkt->pkt_comp = savec;
24510696SDavid.Hollister@Sun.COM 		return (rval);
2460Sstevel@tonic-gate 	}
2470Sstevel@tonic-gate }
248