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
5b0fc0e77Sgovinda * Common Development and Distribution License (the "License").
6b0fc0e77Sgovinda * 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*4f3b09fdSEvan Yan * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
237c478bd9Sstevel@tonic-gate * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate /*
277c478bd9Sstevel@tonic-gate * Interrupt Vector Table Configuration
287c478bd9Sstevel@tonic-gate */
297c478bd9Sstevel@tonic-gate
30b0fc0e77Sgovinda #include <sys/types.h>
317c478bd9Sstevel@tonic-gate #include <sys/cpuvar.h>
327c478bd9Sstevel@tonic-gate #include <sys/ivintr.h>
337c478bd9Sstevel@tonic-gate #include <sys/intreg.h>
347c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h>
357c478bd9Sstevel@tonic-gate #include <sys/privregs.h>
367c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
377c478bd9Sstevel@tonic-gate
387c478bd9Sstevel@tonic-gate /*
39b0fc0e77Sgovinda * Allocate an Interrupt Vector Table and some interrupt vector data structures
40b0fc0e77Sgovinda * for the reserved pool as part of the startup code. First try to allocate an
41b0fc0e77Sgovinda * interrupt vector data structure from the reserved pool, otherwise allocate it
42b0fc0e77Sgovinda * using kmem cache method.
437c478bd9Sstevel@tonic-gate */
44b0fc0e77Sgovinda static kmutex_t intr_vec_mutex; /* Protect interrupt vector table */
457c478bd9Sstevel@tonic-gate
467c478bd9Sstevel@tonic-gate /*
47b0fc0e77Sgovinda * Global softint linked list - used by softint mdb dcmd.
487c478bd9Sstevel@tonic-gate */
49b0fc0e77Sgovinda static kmutex_t softint_mutex; /* Protect global softint linked list */
50b0fc0e77Sgovinda intr_vec_t *softint_list = NULL;
51b0fc0e77Sgovinda
52b0fc0e77Sgovinda /* Reserved pool for interrupt allocation */
53b0fc0e77Sgovinda intr_vec_t *intr_vec_pool = NULL; /* For HW and single target SW intrs */
54b0fc0e77Sgovinda intr_vecx_t *intr_vecx_pool = NULL; /* For multi target SW intrs */
5560ab199eSgovinda static kmutex_t intr_vec_pool_mutex; /* Protect interrupt vector pool */
56b0fc0e77Sgovinda
57b0fc0e77Sgovinda /* Kmem cache handle for interrupt allocation */
58b0fc0e77Sgovinda kmem_cache_t *intr_vec_cache = NULL; /* For HW and single target SW intrs */
59*4f3b09fdSEvan Yan static kmutex_t intr_vec_cache_mutex; /* Protect intr_vec_cache usage */
607c478bd9Sstevel@tonic-gate
617c478bd9Sstevel@tonic-gate /*
62b0fc0e77Sgovinda * init_ivintr() - Initialize an Interrupt Vector Table.
637c478bd9Sstevel@tonic-gate */
647c478bd9Sstevel@tonic-gate void
init_ivintr()65b0fc0e77Sgovinda init_ivintr()
667c478bd9Sstevel@tonic-gate {
67b0fc0e77Sgovinda mutex_init(&intr_vec_mutex, NULL, MUTEX_DRIVER, NULL);
68b0fc0e77Sgovinda mutex_init(&softint_mutex, NULL, MUTEX_DRIVER, NULL);
6960ab199eSgovinda mutex_init(&intr_vec_pool_mutex, NULL, MUTEX_DRIVER, NULL);
70*4f3b09fdSEvan Yan mutex_init(&intr_vec_cache_mutex, NULL, MUTEX_DRIVER, NULL);
717c478bd9Sstevel@tonic-gate
72b0fc0e77Sgovinda /*
73b0fc0e77Sgovinda * Initialize the reserved interrupt vector data structure pools
74b0fc0e77Sgovinda * used for hardware and software interrupts.
75b0fc0e77Sgovinda */
76b0fc0e77Sgovinda intr_vec_pool = (intr_vec_t *)((caddr_t)intr_vec_table +
77b0fc0e77Sgovinda (MAXIVNUM * sizeof (intr_vec_t *)));
78b0fc0e77Sgovinda intr_vecx_pool = (intr_vecx_t *)((caddr_t)intr_vec_pool +
79b0fc0e77Sgovinda (MAX_RSVD_IV * sizeof (intr_vec_t)));
80b0fc0e77Sgovinda
81b0fc0e77Sgovinda bzero(intr_vec_table, MAXIVNUM * sizeof (intr_vec_t *));
82b0fc0e77Sgovinda bzero(intr_vec_pool, MAX_RSVD_IV * sizeof (intr_vec_t));
83b0fc0e77Sgovinda bzero(intr_vecx_pool, MAX_RSVD_IVX * sizeof (intr_vecx_t));
84b0fc0e77Sgovinda }
85b0fc0e77Sgovinda
86b0fc0e77Sgovinda /*
87b0fc0e77Sgovinda * fini_ivintr() - Uninitialize an Interrupt Vector Table.
88b0fc0e77Sgovinda */
89b0fc0e77Sgovinda void
fini_ivintr()90b0fc0e77Sgovinda fini_ivintr()
91b0fc0e77Sgovinda {
92*4f3b09fdSEvan Yan mutex_enter(&intr_vec_cache_mutex);
93*4f3b09fdSEvan Yan if (intr_vec_cache) {
94b0fc0e77Sgovinda kmem_cache_destroy(intr_vec_cache);
95*4f3b09fdSEvan Yan intr_vec_cache = NULL;
96*4f3b09fdSEvan Yan }
97*4f3b09fdSEvan Yan mutex_exit(&intr_vec_cache_mutex);
98b0fc0e77Sgovinda
9960ab199eSgovinda mutex_destroy(&intr_vec_pool_mutex);
100b0fc0e77Sgovinda mutex_destroy(&softint_mutex);
10160ab199eSgovinda mutex_destroy(&intr_vec_mutex);
102*4f3b09fdSEvan Yan mutex_destroy(&intr_vec_cache_mutex);
103b0fc0e77Sgovinda }
104b0fc0e77Sgovinda
105b0fc0e77Sgovinda /*
106b0fc0e77Sgovinda * iv_alloc() - Allocate an interrupt vector data structure.
107b0fc0e77Sgovinda *
108b0fc0e77Sgovinda * This function allocates an interrupt vector data structure for hardware
109b0fc0e77Sgovinda * and single or multi target software interrupts either from the reserved
110b0fc0e77Sgovinda * pool or using kmem cache method.
111b0fc0e77Sgovinda */
112b0fc0e77Sgovinda static intr_vec_t *
iv_alloc(softint_type_t type)113b0fc0e77Sgovinda iv_alloc(softint_type_t type)
114b0fc0e77Sgovinda {
115b0fc0e77Sgovinda intr_vec_t *iv_p;
116b0fc0e77Sgovinda int i, count;
117b0fc0e77Sgovinda
118b0fc0e77Sgovinda count = (type == SOFTINT_MT) ? MAX_RSVD_IVX : MAX_RSVD_IV;
119b0fc0e77Sgovinda
120b0fc0e77Sgovinda /*
121b0fc0e77Sgovinda * First try to allocate an interrupt vector data structure from the
122b0fc0e77Sgovinda * reserved pool, otherwise allocate it using kmem_cache_alloc().
123b0fc0e77Sgovinda */
12460ab199eSgovinda mutex_enter(&intr_vec_pool_mutex);
125b0fc0e77Sgovinda for (i = 0; i < count; i++) {
126b0fc0e77Sgovinda iv_p = (type == SOFTINT_MT) ?
127b0fc0e77Sgovinda (intr_vec_t *)&intr_vecx_pool[i] : &intr_vec_pool[i];
128b0fc0e77Sgovinda
12960ab199eSgovinda if (iv_p->iv_pil == 0) {
13060ab199eSgovinda iv_p->iv_pil = 1; /* Default PIL */
131b0fc0e77Sgovinda break;
132b0fc0e77Sgovinda }
13360ab199eSgovinda }
13460ab199eSgovinda mutex_exit(&intr_vec_pool_mutex);
135b0fc0e77Sgovinda
136b0fc0e77Sgovinda if (i < count)
137b0fc0e77Sgovinda return (iv_p);
138b0fc0e77Sgovinda
139b0fc0e77Sgovinda if (type == SOFTINT_MT)
140b0fc0e77Sgovinda cmn_err(CE_PANIC, "iv_alloc: exceeded number of multi "
141b0fc0e77Sgovinda "target software interrupts, %d", MAX_RSVD_IVX);
142b0fc0e77Sgovinda
143b0fc0e77Sgovinda /*
144b0fc0e77Sgovinda * If the interrupt vector data structure reserved pool is already
145b0fc0e77Sgovinda * exhausted, then allocate an interrupt vector data structure using
146b0fc0e77Sgovinda * kmem_cache_alloc(), but only for the hardware and single software
147b0fc0e77Sgovinda * interrupts. Create a kmem cache for the interrupt allocation,
148b0fc0e77Sgovinda * if it is not already available.
149b0fc0e77Sgovinda */
150*4f3b09fdSEvan Yan mutex_enter(&intr_vec_cache_mutex);
151b0fc0e77Sgovinda if (intr_vec_cache == NULL)
152b0fc0e77Sgovinda intr_vec_cache = kmem_cache_create("intr_vec_cache",
153b0fc0e77Sgovinda sizeof (intr_vec_t), 64, NULL, NULL, NULL, NULL, NULL, 0);
154*4f3b09fdSEvan Yan mutex_exit(&intr_vec_cache_mutex);
155b0fc0e77Sgovinda
156b0fc0e77Sgovinda iv_p = kmem_cache_alloc(intr_vec_cache, KM_SLEEP);
157b0fc0e77Sgovinda bzero(iv_p, sizeof (intr_vec_t));
158b0fc0e77Sgovinda iv_p->iv_flags = IV_CACHE_ALLOC;
15960ab199eSgovinda
160b0fc0e77Sgovinda return (iv_p);
161b0fc0e77Sgovinda }
162b0fc0e77Sgovinda
163b0fc0e77Sgovinda /*
164b0fc0e77Sgovinda * iv_free() - Free an interrupt vector data structure.
165b0fc0e77Sgovinda */
166b0fc0e77Sgovinda static void
iv_free(intr_vec_t * iv_p)167b0fc0e77Sgovinda iv_free(intr_vec_t *iv_p)
168b0fc0e77Sgovinda {
169b0fc0e77Sgovinda if (iv_p->iv_flags & IV_CACHE_ALLOC) {
170b0fc0e77Sgovinda ASSERT(!(iv_p->iv_flags & IV_SOFTINT_MT));
171b0fc0e77Sgovinda kmem_cache_free(intr_vec_cache, iv_p);
172b0fc0e77Sgovinda } else {
17360ab199eSgovinda mutex_enter(&intr_vec_pool_mutex);
17460ab199eSgovinda bzero(iv_p, (iv_p->iv_flags & IV_SOFTINT_MT) ?
17560ab199eSgovinda sizeof (intr_vecx_t) : sizeof (intr_vec_t));
17660ab199eSgovinda mutex_exit(&intr_vec_pool_mutex);
1777c478bd9Sstevel@tonic-gate }
1787c478bd9Sstevel@tonic-gate }
1797c478bd9Sstevel@tonic-gate
1807c478bd9Sstevel@tonic-gate /*
181b0fc0e77Sgovinda * add_ivintr() - Add an interrupt handler to the system
1827c478bd9Sstevel@tonic-gate */
1837c478bd9Sstevel@tonic-gate int
add_ivintr(uint_t inum,uint_t pil,intrfunc intr_handler,caddr_t intr_arg1,caddr_t intr_arg2,caddr_t intr_payload)1847c478bd9Sstevel@tonic-gate add_ivintr(uint_t inum, uint_t pil, intrfunc intr_handler,
185b0fc0e77Sgovinda caddr_t intr_arg1, caddr_t intr_arg2, caddr_t intr_payload)
1867c478bd9Sstevel@tonic-gate {
187b0fc0e77Sgovinda intr_vec_t *iv_p, *new_iv_p;
1887c478bd9Sstevel@tonic-gate
1897c478bd9Sstevel@tonic-gate if (inum >= MAXIVNUM || pil > PIL_MAX)
1907c478bd9Sstevel@tonic-gate return (EINVAL);
1917c478bd9Sstevel@tonic-gate
1927c478bd9Sstevel@tonic-gate ASSERT((uintptr_t)intr_handler > KERNELBASE);
193b0fc0e77Sgovinda
1947c478bd9Sstevel@tonic-gate /* Make sure the payload buffer address is 64 bit aligned */
1957c478bd9Sstevel@tonic-gate VERIFY(((uint64_t)intr_payload & 0x7) == 0);
1967c478bd9Sstevel@tonic-gate
197b0fc0e77Sgovinda new_iv_p = iv_alloc(SOFTINT_ST);
198b0fc0e77Sgovinda mutex_enter(&intr_vec_mutex);
1997c478bd9Sstevel@tonic-gate
200b0fc0e77Sgovinda for (iv_p = (intr_vec_t *)intr_vec_table[inum];
201b0fc0e77Sgovinda iv_p; iv_p = iv_p->iv_vec_next) {
202b0fc0e77Sgovinda if (iv_p->iv_pil == pil) {
203b0fc0e77Sgovinda mutex_exit(&intr_vec_mutex);
204b0fc0e77Sgovinda iv_free(new_iv_p);
2057c478bd9Sstevel@tonic-gate return (EINVAL);
206b0fc0e77Sgovinda }
207b0fc0e77Sgovinda }
2087c478bd9Sstevel@tonic-gate
209b0fc0e77Sgovinda ASSERT(iv_p == NULL);
210b0fc0e77Sgovinda
211b0fc0e77Sgovinda new_iv_p->iv_handler = intr_handler;
212b0fc0e77Sgovinda new_iv_p->iv_arg1 = intr_arg1;
213b0fc0e77Sgovinda new_iv_p->iv_arg2 = intr_arg2;
214b0fc0e77Sgovinda new_iv_p->iv_payload_buf = intr_payload;
215b0fc0e77Sgovinda new_iv_p->iv_pil = (ushort_t)pil;
216b0fc0e77Sgovinda new_iv_p->iv_inum = inum;
217b0fc0e77Sgovinda
218b0fc0e77Sgovinda new_iv_p->iv_vec_next = (intr_vec_t *)intr_vec_table[inum];
219b0fc0e77Sgovinda intr_vec_table[inum] = (uint64_t)new_iv_p;
220b0fc0e77Sgovinda
221b0fc0e77Sgovinda mutex_exit(&intr_vec_mutex);
2227c478bd9Sstevel@tonic-gate return (0);
2237c478bd9Sstevel@tonic-gate }
2247c478bd9Sstevel@tonic-gate
2257c478bd9Sstevel@tonic-gate /*
226b0fc0e77Sgovinda * rem_ivintr() - Remove an interrupt handler from the system
2277c478bd9Sstevel@tonic-gate */
228b0fc0e77Sgovinda int
rem_ivintr(uint_t inum,uint_t pil)229b0fc0e77Sgovinda rem_ivintr(uint_t inum, uint_t pil)
2307c478bd9Sstevel@tonic-gate {
231b0fc0e77Sgovinda intr_vec_t *iv_p, *prev_iv_p;
2327c478bd9Sstevel@tonic-gate
233b0fc0e77Sgovinda if (inum >= MAXIVNUM || pil > PIL_MAX)
234b0fc0e77Sgovinda return (EINVAL);
2357c478bd9Sstevel@tonic-gate
236b0fc0e77Sgovinda mutex_enter(&intr_vec_mutex);
2377c478bd9Sstevel@tonic-gate
238b0fc0e77Sgovinda for (iv_p = prev_iv_p = (intr_vec_t *)intr_vec_table[inum];
239b0fc0e77Sgovinda iv_p; prev_iv_p = iv_p, iv_p = iv_p->iv_vec_next)
240b0fc0e77Sgovinda if (iv_p->iv_pil == pil)
241b0fc0e77Sgovinda break;
242b0fc0e77Sgovinda
243b0fc0e77Sgovinda if (iv_p == NULL) {
244b0fc0e77Sgovinda mutex_exit(&intr_vec_mutex);
245b0fc0e77Sgovinda return (EIO);
2467c478bd9Sstevel@tonic-gate }
2477c478bd9Sstevel@tonic-gate
248b0fc0e77Sgovinda ASSERT(iv_p->iv_pil_next == NULL);
249b0fc0e77Sgovinda
250b0fc0e77Sgovinda if (prev_iv_p == iv_p)
251b0fc0e77Sgovinda intr_vec_table[inum] = (uint64_t)iv_p->iv_vec_next;
252b0fc0e77Sgovinda else
253b0fc0e77Sgovinda prev_iv_p->iv_vec_next = iv_p->iv_vec_next;
254b0fc0e77Sgovinda
255b0fc0e77Sgovinda mutex_exit(&intr_vec_mutex);
256b0fc0e77Sgovinda
257b0fc0e77Sgovinda iv_free(iv_p);
258b0fc0e77Sgovinda return (0);
2597c478bd9Sstevel@tonic-gate }
2607c478bd9Sstevel@tonic-gate
2617c478bd9Sstevel@tonic-gate /*
2627c478bd9Sstevel@tonic-gate * add_softintr() - add a software interrupt handler to the system
2637c478bd9Sstevel@tonic-gate */
264b0fc0e77Sgovinda uint64_t
add_softintr(uint_t pil,softintrfunc intr_handler,caddr_t intr_arg1,softint_type_t type)265b0fc0e77Sgovinda add_softintr(uint_t pil, softintrfunc intr_handler, caddr_t intr_arg1,
266b0fc0e77Sgovinda softint_type_t type)
2677c478bd9Sstevel@tonic-gate {
268b0fc0e77Sgovinda intr_vec_t *iv_p;
2697c478bd9Sstevel@tonic-gate
270b0fc0e77Sgovinda if (pil > PIL_MAX)
271b0fc0e77Sgovinda return (NULL);
2727c478bd9Sstevel@tonic-gate
273b0fc0e77Sgovinda iv_p = iv_alloc(type);
2747c478bd9Sstevel@tonic-gate
275b0fc0e77Sgovinda iv_p->iv_handler = (intrfunc)intr_handler;
276b0fc0e77Sgovinda iv_p->iv_arg1 = intr_arg1;
277b0fc0e77Sgovinda iv_p->iv_pil = (ushort_t)pil;
278b0fc0e77Sgovinda if (type == SOFTINT_MT)
279b0fc0e77Sgovinda iv_p->iv_flags |= IV_SOFTINT_MT;
2807c478bd9Sstevel@tonic-gate
281b0fc0e77Sgovinda mutex_enter(&softint_mutex);
282b0fc0e77Sgovinda if (softint_list)
283b0fc0e77Sgovinda iv_p->iv_vec_next = softint_list;
284b0fc0e77Sgovinda softint_list = iv_p;
285b0fc0e77Sgovinda mutex_exit(&softint_mutex);
2867c478bd9Sstevel@tonic-gate
287b0fc0e77Sgovinda return ((uint64_t)iv_p);
2887c478bd9Sstevel@tonic-gate }
2897c478bd9Sstevel@tonic-gate
2907c478bd9Sstevel@tonic-gate /*
2917c478bd9Sstevel@tonic-gate * rem_softintr() - remove a software interrupt handler from the system
2927c478bd9Sstevel@tonic-gate */
293b0fc0e77Sgovinda int
rem_softintr(uint64_t softint_id)294b0fc0e77Sgovinda rem_softintr(uint64_t softint_id)
2957c478bd9Sstevel@tonic-gate {
296b0fc0e77Sgovinda intr_vec_t *iv_p = (intr_vec_t *)softint_id;
2977c478bd9Sstevel@tonic-gate
298b0fc0e77Sgovinda ASSERT(iv_p != NULL);
299b0fc0e77Sgovinda
300b0fc0e77Sgovinda if (iv_p->iv_flags & IV_SOFTINT_PEND)
301b0fc0e77Sgovinda return (EIO);
302b0fc0e77Sgovinda
303b0fc0e77Sgovinda ASSERT(iv_p->iv_pil_next == NULL);
304b0fc0e77Sgovinda
305b0fc0e77Sgovinda mutex_enter(&softint_mutex);
306b0fc0e77Sgovinda if (softint_list == iv_p) {
307b0fc0e77Sgovinda softint_list = iv_p->iv_vec_next;
308b0fc0e77Sgovinda } else {
309b0fc0e77Sgovinda intr_vec_t *list = softint_list;
310b0fc0e77Sgovinda
311b0fc0e77Sgovinda while (list && (list->iv_vec_next != iv_p))
312b0fc0e77Sgovinda list = list->iv_vec_next;
313b0fc0e77Sgovinda
314b0fc0e77Sgovinda list->iv_vec_next = iv_p->iv_vec_next;
315b0fc0e77Sgovinda }
316b0fc0e77Sgovinda mutex_exit(&softint_mutex);
317b0fc0e77Sgovinda
318b0fc0e77Sgovinda iv_free(iv_p);
319b0fc0e77Sgovinda return (0);
3207c478bd9Sstevel@tonic-gate }
3217c478bd9Sstevel@tonic-gate
322b0fc0e77Sgovinda /*
323b0fc0e77Sgovinda * update_softint_arg2() - Update softint arg2.
324b0fc0e77Sgovinda *
325b0fc0e77Sgovinda * NOTE: Do not grab any mutex in this function since it may get called
326b0fc0e77Sgovinda * from the high-level interrupt context.
327b0fc0e77Sgovinda */
3287c478bd9Sstevel@tonic-gate int
update_softint_arg2(uint64_t softint_id,caddr_t intr_arg2)329b0fc0e77Sgovinda update_softint_arg2(uint64_t softint_id, caddr_t intr_arg2)
3307c478bd9Sstevel@tonic-gate {
331b0fc0e77Sgovinda intr_vec_t *iv_p = (intr_vec_t *)softint_id;
3327c478bd9Sstevel@tonic-gate
333b0fc0e77Sgovinda ASSERT(iv_p != NULL);
3347c478bd9Sstevel@tonic-gate
335b0fc0e77Sgovinda if (iv_p->iv_flags & IV_SOFTINT_PEND)
336b0fc0e77Sgovinda return (EIO);
3377c478bd9Sstevel@tonic-gate
338b0fc0e77Sgovinda iv_p->iv_arg2 = intr_arg2;
339b0fc0e77Sgovinda return (0);
3407c478bd9Sstevel@tonic-gate }
3417c478bd9Sstevel@tonic-gate
342b0fc0e77Sgovinda /*
343b0fc0e77Sgovinda * update_softint_pri() - Update softint priority.
344b0fc0e77Sgovinda */
3457c478bd9Sstevel@tonic-gate int
update_softint_pri(uint64_t softint_id,uint_t pil)346b0fc0e77Sgovinda update_softint_pri(uint64_t softint_id, uint_t pil)
3477c478bd9Sstevel@tonic-gate {
348b0fc0e77Sgovinda intr_vec_t *iv_p = (intr_vec_t *)softint_id;
3497c478bd9Sstevel@tonic-gate
350b0fc0e77Sgovinda ASSERT(iv_p != NULL);
3517c478bd9Sstevel@tonic-gate
352b0fc0e77Sgovinda if (pil > PIL_MAX)
353b0fc0e77Sgovinda return (EINVAL);
354b0fc0e77Sgovinda
355b0fc0e77Sgovinda iv_p->iv_pil = pil;
356b0fc0e77Sgovinda return (0);
3577c478bd9Sstevel@tonic-gate }
358