xref: /titanic_52/usr/src/uts/sun4/io/ivintr.c (revision b0fc0e77220f1fa4c933fd58a4e1dedcd650b0f1)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*b0fc0e77Sgovinda  * Common Development and Distribution License (the "License").
6*b0fc0e77Sgovinda  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*b0fc0e77Sgovinda  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate /*
297c478bd9Sstevel@tonic-gate  * Interrupt Vector Table Configuration
307c478bd9Sstevel@tonic-gate  */
317c478bd9Sstevel@tonic-gate 
32*b0fc0e77Sgovinda #include <sys/types.h>
337c478bd9Sstevel@tonic-gate #include <sys/cpuvar.h>
347c478bd9Sstevel@tonic-gate #include <sys/ivintr.h>
357c478bd9Sstevel@tonic-gate #include <sys/intreg.h>
367c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h>
377c478bd9Sstevel@tonic-gate #include <sys/privregs.h>
387c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate /*
41*b0fc0e77Sgovinda  * Allocate an Interrupt Vector Table and some interrupt vector data structures
42*b0fc0e77Sgovinda  * for the reserved pool as part of the startup code. First try to allocate an
43*b0fc0e77Sgovinda  * interrupt vector data structure from the reserved pool, otherwise allocate it
44*b0fc0e77Sgovinda  * using kmem cache method.
457c478bd9Sstevel@tonic-gate  */
46*b0fc0e77Sgovinda static	kmutex_t intr_vec_mutex;	/* Protect interrupt vector table */
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate /*
49*b0fc0e77Sgovinda  * Global softint linked list - used by softint mdb dcmd.
507c478bd9Sstevel@tonic-gate  */
51*b0fc0e77Sgovinda static	kmutex_t softint_mutex;		/* Protect global softint linked list */
52*b0fc0e77Sgovinda intr_vec_t	*softint_list = NULL;
53*b0fc0e77Sgovinda 
54*b0fc0e77Sgovinda /* Reserved pool for interrupt allocation */
55*b0fc0e77Sgovinda intr_vec_t	*intr_vec_pool = NULL;	/* For HW and single target SW intrs */
56*b0fc0e77Sgovinda intr_vecx_t	*intr_vecx_pool = NULL;	/* For multi target SW intrs */
57*b0fc0e77Sgovinda 
58*b0fc0e77Sgovinda /* Kmem cache handle for interrupt allocation */
59*b0fc0e77Sgovinda kmem_cache_t	*intr_vec_cache = NULL;	/* For HW and single target SW intrs */
607c478bd9Sstevel@tonic-gate 
617c478bd9Sstevel@tonic-gate /*
62*b0fc0e77Sgovinda  * init_ivintr() - Initialize an Interrupt Vector Table.
637c478bd9Sstevel@tonic-gate  */
647c478bd9Sstevel@tonic-gate void
65*b0fc0e77Sgovinda init_ivintr()
667c478bd9Sstevel@tonic-gate {
67*b0fc0e77Sgovinda 	mutex_init(&intr_vec_mutex, NULL, MUTEX_DRIVER, NULL);
68*b0fc0e77Sgovinda 	mutex_init(&softint_mutex, NULL, MUTEX_DRIVER, NULL);
697c478bd9Sstevel@tonic-gate 
70*b0fc0e77Sgovinda 	/*
71*b0fc0e77Sgovinda 	 * Initialize the reserved interrupt vector data structure pools
72*b0fc0e77Sgovinda 	 * used for hardware and software interrupts.
73*b0fc0e77Sgovinda 	 */
74*b0fc0e77Sgovinda 	intr_vec_pool = (intr_vec_t *)((caddr_t)intr_vec_table +
75*b0fc0e77Sgovinda 	    (MAXIVNUM * sizeof (intr_vec_t *)));
76*b0fc0e77Sgovinda 	intr_vecx_pool = (intr_vecx_t *)((caddr_t)intr_vec_pool +
77*b0fc0e77Sgovinda 	    (MAX_RSVD_IV * sizeof (intr_vec_t)));
78*b0fc0e77Sgovinda 
79*b0fc0e77Sgovinda 	bzero(intr_vec_table, MAXIVNUM * sizeof (intr_vec_t *));
80*b0fc0e77Sgovinda 	bzero(intr_vec_pool, MAX_RSVD_IV * sizeof (intr_vec_t));
81*b0fc0e77Sgovinda 	bzero(intr_vecx_pool, MAX_RSVD_IVX * sizeof (intr_vecx_t));
82*b0fc0e77Sgovinda }
83*b0fc0e77Sgovinda 
84*b0fc0e77Sgovinda /*
85*b0fc0e77Sgovinda  * fini_ivintr() - Uninitialize an Interrupt Vector Table.
86*b0fc0e77Sgovinda  */
87*b0fc0e77Sgovinda void
88*b0fc0e77Sgovinda fini_ivintr()
89*b0fc0e77Sgovinda {
90*b0fc0e77Sgovinda 	if (intr_vec_cache)
91*b0fc0e77Sgovinda 		kmem_cache_destroy(intr_vec_cache);
92*b0fc0e77Sgovinda 
93*b0fc0e77Sgovinda 	mutex_destroy(&intr_vec_mutex);
94*b0fc0e77Sgovinda 	mutex_destroy(&softint_mutex);
95*b0fc0e77Sgovinda }
96*b0fc0e77Sgovinda 
97*b0fc0e77Sgovinda /*
98*b0fc0e77Sgovinda  * iv_alloc() - Allocate an interrupt vector data structure.
99*b0fc0e77Sgovinda  *
100*b0fc0e77Sgovinda  * This function allocates an interrupt vector data structure for hardware
101*b0fc0e77Sgovinda  * and single or multi target software interrupts either from the reserved
102*b0fc0e77Sgovinda  * pool or using kmem cache method.
103*b0fc0e77Sgovinda  */
104*b0fc0e77Sgovinda static intr_vec_t *
105*b0fc0e77Sgovinda iv_alloc(softint_type_t type)
106*b0fc0e77Sgovinda {
107*b0fc0e77Sgovinda 	intr_vec_t	*iv_p;
108*b0fc0e77Sgovinda 	int		i, count;
109*b0fc0e77Sgovinda 
110*b0fc0e77Sgovinda 	count = (type == SOFTINT_MT) ? MAX_RSVD_IVX : MAX_RSVD_IV;
111*b0fc0e77Sgovinda 
112*b0fc0e77Sgovinda 	/*
113*b0fc0e77Sgovinda 	 * First try to allocate an interrupt vector data structure from the
114*b0fc0e77Sgovinda 	 * reserved pool, otherwise allocate it using kmem_cache_alloc().
115*b0fc0e77Sgovinda 	 */
116*b0fc0e77Sgovinda 	for (i = 0; i < count; i++) {
117*b0fc0e77Sgovinda 		iv_p = (type == SOFTINT_MT) ?
118*b0fc0e77Sgovinda 		    (intr_vec_t *)&intr_vecx_pool[i] : &intr_vec_pool[i];
119*b0fc0e77Sgovinda 
120*b0fc0e77Sgovinda 		if (iv_p->iv_pil == 0)
121*b0fc0e77Sgovinda 			break;
122*b0fc0e77Sgovinda 	}
123*b0fc0e77Sgovinda 
124*b0fc0e77Sgovinda 	if (i < count)
125*b0fc0e77Sgovinda 		return (iv_p);
126*b0fc0e77Sgovinda 
127*b0fc0e77Sgovinda 	if (type == SOFTINT_MT)
128*b0fc0e77Sgovinda 		cmn_err(CE_PANIC, "iv_alloc: exceeded number of multi "
129*b0fc0e77Sgovinda 		    "target software interrupts, %d", MAX_RSVD_IVX);
130*b0fc0e77Sgovinda 
131*b0fc0e77Sgovinda 	/*
132*b0fc0e77Sgovinda 	 * If the interrupt vector data structure reserved pool is already
133*b0fc0e77Sgovinda 	 * exhausted, then allocate an interrupt vector data structure using
134*b0fc0e77Sgovinda 	 * kmem_cache_alloc(), but only for the hardware and single software
135*b0fc0e77Sgovinda 	 * interrupts. Create a kmem cache for the interrupt allocation,
136*b0fc0e77Sgovinda 	 * if it is not already available.
137*b0fc0e77Sgovinda 	 */
138*b0fc0e77Sgovinda 	if (intr_vec_cache == NULL)
139*b0fc0e77Sgovinda 		intr_vec_cache = kmem_cache_create("intr_vec_cache",
140*b0fc0e77Sgovinda 		    sizeof (intr_vec_t), 64, NULL, NULL, NULL, NULL, NULL, 0);
141*b0fc0e77Sgovinda 
142*b0fc0e77Sgovinda 	iv_p = kmem_cache_alloc(intr_vec_cache, KM_SLEEP);
143*b0fc0e77Sgovinda 	bzero(iv_p, sizeof (intr_vec_t));
144*b0fc0e77Sgovinda 
145*b0fc0e77Sgovinda 	iv_p->iv_flags =  IV_CACHE_ALLOC;
146*b0fc0e77Sgovinda 	return (iv_p);
147*b0fc0e77Sgovinda }
148*b0fc0e77Sgovinda 
149*b0fc0e77Sgovinda /*
150*b0fc0e77Sgovinda  * iv_free() - Free an interrupt vector data structure.
151*b0fc0e77Sgovinda  */
152*b0fc0e77Sgovinda static void
153*b0fc0e77Sgovinda iv_free(intr_vec_t *iv_p)
154*b0fc0e77Sgovinda {
155*b0fc0e77Sgovinda 	if (iv_p->iv_flags & IV_CACHE_ALLOC) {
156*b0fc0e77Sgovinda 		ASSERT(!(iv_p->iv_flags & IV_SOFTINT_MT));
157*b0fc0e77Sgovinda 		kmem_cache_free(intr_vec_cache, iv_p);
158*b0fc0e77Sgovinda 	} else {
159*b0fc0e77Sgovinda 		(iv_p->iv_flags & IV_SOFTINT_MT) ?
160*b0fc0e77Sgovinda 		    bzero(iv_p, sizeof (intr_vecx_t)) :
161*b0fc0e77Sgovinda 		    bzero(iv_p, sizeof (intr_vec_t));
1627c478bd9Sstevel@tonic-gate 	}
1637c478bd9Sstevel@tonic-gate }
1647c478bd9Sstevel@tonic-gate 
1657c478bd9Sstevel@tonic-gate /*
166*b0fc0e77Sgovinda  * add_ivintr() - Add an interrupt handler to the system
1677c478bd9Sstevel@tonic-gate  */
1687c478bd9Sstevel@tonic-gate int
1697c478bd9Sstevel@tonic-gate add_ivintr(uint_t inum, uint_t pil, intrfunc intr_handler,
170*b0fc0e77Sgovinda     caddr_t intr_arg1, caddr_t intr_arg2, caddr_t intr_payload)
1717c478bd9Sstevel@tonic-gate {
172*b0fc0e77Sgovinda 	intr_vec_t	*iv_p, *new_iv_p;
1737c478bd9Sstevel@tonic-gate 
1747c478bd9Sstevel@tonic-gate 	if (inum >= MAXIVNUM || pil > PIL_MAX)
1757c478bd9Sstevel@tonic-gate 		return (EINVAL);
1767c478bd9Sstevel@tonic-gate 
1777c478bd9Sstevel@tonic-gate 	ASSERT((uintptr_t)intr_handler > KERNELBASE);
178*b0fc0e77Sgovinda 
1797c478bd9Sstevel@tonic-gate 	/* Make sure the payload buffer address is 64 bit aligned */
1807c478bd9Sstevel@tonic-gate 	VERIFY(((uint64_t)intr_payload & 0x7) == 0);
1817c478bd9Sstevel@tonic-gate 
182*b0fc0e77Sgovinda 	new_iv_p = iv_alloc(SOFTINT_ST);
183*b0fc0e77Sgovinda 	mutex_enter(&intr_vec_mutex);
1847c478bd9Sstevel@tonic-gate 
185*b0fc0e77Sgovinda 	for (iv_p = (intr_vec_t *)intr_vec_table[inum];
186*b0fc0e77Sgovinda 	    iv_p; iv_p = iv_p->iv_vec_next) {
187*b0fc0e77Sgovinda 		if (iv_p->iv_pil == pil) {
188*b0fc0e77Sgovinda 			mutex_exit(&intr_vec_mutex);
189*b0fc0e77Sgovinda 			iv_free(new_iv_p);
1907c478bd9Sstevel@tonic-gate 			return (EINVAL);
191*b0fc0e77Sgovinda 		}
192*b0fc0e77Sgovinda 	}
1937c478bd9Sstevel@tonic-gate 
194*b0fc0e77Sgovinda 	ASSERT(iv_p == NULL);
195*b0fc0e77Sgovinda 
196*b0fc0e77Sgovinda 	new_iv_p->iv_handler = intr_handler;
197*b0fc0e77Sgovinda 	new_iv_p->iv_arg1 = intr_arg1;
198*b0fc0e77Sgovinda 	new_iv_p->iv_arg2 = intr_arg2;
199*b0fc0e77Sgovinda 	new_iv_p->iv_payload_buf = intr_payload;
200*b0fc0e77Sgovinda 	new_iv_p->iv_pil = (ushort_t)pil;
201*b0fc0e77Sgovinda 	new_iv_p->iv_inum = inum;
202*b0fc0e77Sgovinda 
203*b0fc0e77Sgovinda 	new_iv_p->iv_vec_next = (intr_vec_t *)intr_vec_table[inum];
204*b0fc0e77Sgovinda 	intr_vec_table[inum] = (uint64_t)new_iv_p;
205*b0fc0e77Sgovinda 
206*b0fc0e77Sgovinda 	mutex_exit(&intr_vec_mutex);
2077c478bd9Sstevel@tonic-gate 	return (0);
2087c478bd9Sstevel@tonic-gate }
2097c478bd9Sstevel@tonic-gate 
2107c478bd9Sstevel@tonic-gate /*
211*b0fc0e77Sgovinda  * rem_ivintr() - Remove an interrupt handler from the system
2127c478bd9Sstevel@tonic-gate  */
213*b0fc0e77Sgovinda int
214*b0fc0e77Sgovinda rem_ivintr(uint_t inum, uint_t pil)
2157c478bd9Sstevel@tonic-gate {
216*b0fc0e77Sgovinda 	intr_vec_t	*iv_p, *prev_iv_p;
2177c478bd9Sstevel@tonic-gate 
218*b0fc0e77Sgovinda 	if (inum >= MAXIVNUM || pil > PIL_MAX)
219*b0fc0e77Sgovinda 		return (EINVAL);
2207c478bd9Sstevel@tonic-gate 
221*b0fc0e77Sgovinda 	mutex_enter(&intr_vec_mutex);
2227c478bd9Sstevel@tonic-gate 
223*b0fc0e77Sgovinda 	for (iv_p = prev_iv_p = (intr_vec_t *)intr_vec_table[inum];
224*b0fc0e77Sgovinda 	    iv_p; prev_iv_p = iv_p, iv_p = iv_p->iv_vec_next)
225*b0fc0e77Sgovinda 		if (iv_p->iv_pil == pil)
226*b0fc0e77Sgovinda 			break;
227*b0fc0e77Sgovinda 
228*b0fc0e77Sgovinda 	if (iv_p == NULL) {
229*b0fc0e77Sgovinda 		mutex_exit(&intr_vec_mutex);
230*b0fc0e77Sgovinda 		return (EIO);
2317c478bd9Sstevel@tonic-gate 	}
2327c478bd9Sstevel@tonic-gate 
233*b0fc0e77Sgovinda 	ASSERT(iv_p->iv_pil_next == NULL);
234*b0fc0e77Sgovinda 
235*b0fc0e77Sgovinda 	if (prev_iv_p == iv_p)
236*b0fc0e77Sgovinda 		intr_vec_table[inum] = (uint64_t)iv_p->iv_vec_next;
237*b0fc0e77Sgovinda 	else
238*b0fc0e77Sgovinda 		prev_iv_p->iv_vec_next = iv_p->iv_vec_next;
239*b0fc0e77Sgovinda 
240*b0fc0e77Sgovinda 	mutex_exit(&intr_vec_mutex);
241*b0fc0e77Sgovinda 
242*b0fc0e77Sgovinda 	iv_free(iv_p);
243*b0fc0e77Sgovinda 	return (0);
2447c478bd9Sstevel@tonic-gate }
2457c478bd9Sstevel@tonic-gate 
2467c478bd9Sstevel@tonic-gate /*
2477c478bd9Sstevel@tonic-gate  * add_softintr() - add a software interrupt handler to the system
2487c478bd9Sstevel@tonic-gate  */
249*b0fc0e77Sgovinda uint64_t
250*b0fc0e77Sgovinda add_softintr(uint_t pil, softintrfunc intr_handler, caddr_t intr_arg1,
251*b0fc0e77Sgovinda     softint_type_t type)
2527c478bd9Sstevel@tonic-gate {
253*b0fc0e77Sgovinda 	intr_vec_t	*iv_p;
2547c478bd9Sstevel@tonic-gate 
255*b0fc0e77Sgovinda 	if (pil > PIL_MAX)
256*b0fc0e77Sgovinda 		return (NULL);
2577c478bd9Sstevel@tonic-gate 
258*b0fc0e77Sgovinda 	iv_p = iv_alloc(type);
2597c478bd9Sstevel@tonic-gate 
260*b0fc0e77Sgovinda 	iv_p->iv_handler = (intrfunc)intr_handler;
261*b0fc0e77Sgovinda 	iv_p->iv_arg1 = intr_arg1;
262*b0fc0e77Sgovinda 	iv_p->iv_pil = (ushort_t)pil;
263*b0fc0e77Sgovinda 	if (type == SOFTINT_MT)
264*b0fc0e77Sgovinda 		iv_p->iv_flags |=  IV_SOFTINT_MT;
2657c478bd9Sstevel@tonic-gate 
266*b0fc0e77Sgovinda 	mutex_enter(&softint_mutex);
267*b0fc0e77Sgovinda 	if (softint_list)
268*b0fc0e77Sgovinda 		iv_p->iv_vec_next = softint_list;
269*b0fc0e77Sgovinda 	softint_list = iv_p;
270*b0fc0e77Sgovinda 	mutex_exit(&softint_mutex);
2717c478bd9Sstevel@tonic-gate 
272*b0fc0e77Sgovinda 	return ((uint64_t)iv_p);
2737c478bd9Sstevel@tonic-gate }
2747c478bd9Sstevel@tonic-gate 
2757c478bd9Sstevel@tonic-gate /*
2767c478bd9Sstevel@tonic-gate  * rem_softintr() - remove a software interrupt handler from the system
2777c478bd9Sstevel@tonic-gate  */
278*b0fc0e77Sgovinda int
279*b0fc0e77Sgovinda rem_softintr(uint64_t softint_id)
2807c478bd9Sstevel@tonic-gate {
281*b0fc0e77Sgovinda 	intr_vec_t	*iv_p = (intr_vec_t *)softint_id;
2827c478bd9Sstevel@tonic-gate 
283*b0fc0e77Sgovinda 	ASSERT(iv_p != NULL);
284*b0fc0e77Sgovinda 
285*b0fc0e77Sgovinda 	if (iv_p->iv_flags & IV_SOFTINT_PEND)
286*b0fc0e77Sgovinda 		return (EIO);
287*b0fc0e77Sgovinda 
288*b0fc0e77Sgovinda 	ASSERT(iv_p->iv_pil_next == NULL);
289*b0fc0e77Sgovinda 
290*b0fc0e77Sgovinda 	mutex_enter(&softint_mutex);
291*b0fc0e77Sgovinda 	if (softint_list == iv_p) {
292*b0fc0e77Sgovinda 		softint_list = iv_p->iv_vec_next;
293*b0fc0e77Sgovinda 	} else {
294*b0fc0e77Sgovinda 		intr_vec_t	*list = softint_list;
295*b0fc0e77Sgovinda 
296*b0fc0e77Sgovinda 		while (list && (list->iv_vec_next != iv_p))
297*b0fc0e77Sgovinda 			list = list->iv_vec_next;
298*b0fc0e77Sgovinda 
299*b0fc0e77Sgovinda 		list->iv_vec_next = iv_p->iv_vec_next;
300*b0fc0e77Sgovinda 	}
301*b0fc0e77Sgovinda 	mutex_exit(&softint_mutex);
302*b0fc0e77Sgovinda 
303*b0fc0e77Sgovinda 	iv_free(iv_p);
304*b0fc0e77Sgovinda 	return (0);
3057c478bd9Sstevel@tonic-gate }
3067c478bd9Sstevel@tonic-gate 
307*b0fc0e77Sgovinda /*
308*b0fc0e77Sgovinda  * update_softint_arg2() - Update softint arg2.
309*b0fc0e77Sgovinda  *
310*b0fc0e77Sgovinda  * NOTE: Do not grab any mutex in this function since it may get called
311*b0fc0e77Sgovinda  *	 from the high-level interrupt context.
312*b0fc0e77Sgovinda  */
3137c478bd9Sstevel@tonic-gate int
314*b0fc0e77Sgovinda update_softint_arg2(uint64_t softint_id, caddr_t intr_arg2)
3157c478bd9Sstevel@tonic-gate {
316*b0fc0e77Sgovinda 	intr_vec_t	*iv_p = (intr_vec_t *)softint_id;
3177c478bd9Sstevel@tonic-gate 
318*b0fc0e77Sgovinda 	ASSERT(iv_p != NULL);
3197c478bd9Sstevel@tonic-gate 
320*b0fc0e77Sgovinda 	if (iv_p->iv_flags & IV_SOFTINT_PEND)
321*b0fc0e77Sgovinda 		return (EIO);
3227c478bd9Sstevel@tonic-gate 
323*b0fc0e77Sgovinda 	iv_p->iv_arg2 = intr_arg2;
324*b0fc0e77Sgovinda 	return (0);
3257c478bd9Sstevel@tonic-gate }
3267c478bd9Sstevel@tonic-gate 
327*b0fc0e77Sgovinda /*
328*b0fc0e77Sgovinda  * update_softint_pri() - Update softint priority.
329*b0fc0e77Sgovinda  */
3307c478bd9Sstevel@tonic-gate int
331*b0fc0e77Sgovinda update_softint_pri(uint64_t softint_id, uint_t pil)
3327c478bd9Sstevel@tonic-gate {
333*b0fc0e77Sgovinda 	intr_vec_t	*iv_p = (intr_vec_t *)softint_id;
3347c478bd9Sstevel@tonic-gate 
335*b0fc0e77Sgovinda 	ASSERT(iv_p != NULL);
3367c478bd9Sstevel@tonic-gate 
337*b0fc0e77Sgovinda 	if (pil > PIL_MAX)
338*b0fc0e77Sgovinda 		return (EINVAL);
339*b0fc0e77Sgovinda 
340*b0fc0e77Sgovinda 	iv_p->iv_pil = pil;
341*b0fc0e77Sgovinda 	return (0);
3427c478bd9Sstevel@tonic-gate }
343