xref: /illumos-gate/usr/src/uts/sun4/io/ivintr.c (revision 12551037)
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 /*
224f3b09fdSEvan 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 */
594f3b09fdSEvan 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  */
64b0fc0e77Sgovinda void
init_ivintr()65b0fc0e77Sgovinda init_ivintr()
66b0fc0e77Sgovinda {
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);
704f3b09fdSEvan Yan 	mutex_init(&intr_vec_cache_mutex, NULL, MUTEX_DRIVER, NULL);
71b0fc0e77Sgovinda 
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 }
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate /*
87b0fc0e77Sgovinda  * fini_ivintr() - Uninitialize an Interrupt Vector Table.
887c478bd9Sstevel@tonic-gate  */
89b0fc0e77Sgovinda void
fini_ivintr()90b0fc0e77Sgovinda fini_ivintr()
91b0fc0e77Sgovinda {
924f3b09fdSEvan Yan 	mutex_enter(&intr_vec_cache_mutex);
934f3b09fdSEvan Yan 	if (intr_vec_cache) {
94b0fc0e77Sgovinda 		kmem_cache_destroy(intr_vec_cache);
954f3b09fdSEvan Yan 		intr_vec_cache = NULL;
964f3b09fdSEvan Yan 	}
974f3b09fdSEvan Yan 	mutex_exit(&intr_vec_cache_mutex);
987c478bd9Sstevel@tonic-gate 
9960ab199eSgovinda 	mutex_destroy(&intr_vec_pool_mutex);
100b0fc0e77Sgovinda 	mutex_destroy(&softint_mutex);
10160ab199eSgovinda 	mutex_destroy(&intr_vec_mutex);
1024f3b09fdSEvan Yan 	mutex_destroy(&intr_vec_cache_mutex);
103b0fc0e77Sgovinda }
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate /*
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.
1117c478bd9Sstevel@tonic-gate  */
112b0fc0e77Sgovinda static intr_vec_t *
iv_alloc(softint_type_t type)113b0fc0e77Sgovinda iv_alloc(softint_type_t type)
1147c478bd9Sstevel@tonic-gate {
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;
13260ab199eSgovinda 		}
1337c478bd9Sstevel@tonic-gate 	}
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 	 */
1504f3b09fdSEvan 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);
1544f3b09fdSEvan 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);
1617c478bd9Sstevel@tonic-gate }
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate /*
164b0fc0e77Sgovinda  * iv_free() - Free an interrupt vector data structure.
1657c478bd9Sstevel@tonic-gate  */
166b0fc0e77Sgovinda static void
iv_free(intr_vec_t * iv_p)167b0fc0e77Sgovinda iv_free(intr_vec_t *iv_p)
1687c478bd9Sstevel@tonic-gate {
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);
205b0fc0e77Sgovinda 			return (EINVAL);
206b0fc0e77Sgovinda 		}
207b0fc0e77Sgovinda 	}
208b0fc0e77Sgovinda 
209b0fc0e77Sgovinda 	ASSERT(iv_p == NULL);
2107c478bd9Sstevel@tonic-gate 
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;
232b0fc0e77Sgovinda 
233b0fc0e77Sgovinda 	if (inum >= MAXIVNUM || pil > PIL_MAX)
234b0fc0e77Sgovinda 		return (EINVAL);
235b0fc0e77Sgovinda 
236b0fc0e77Sgovinda 	mutex_enter(&intr_vec_mutex);
237b0fc0e77Sgovinda 
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)
271*12551037SToomas Soome 		return ((uint64_t)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;
297b0fc0e77Sgovinda 
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;
3137c478bd9Sstevel@tonic-gate 
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;
349b0fc0e77Sgovinda 
350b0fc0e77Sgovinda 	ASSERT(iv_p != NULL);
3517c478bd9Sstevel@tonic-gate 
352b0fc0e77Sgovinda 	if (pil > PIL_MAX)
353b0fc0e77Sgovinda 		return (EINVAL);
3547c478bd9Sstevel@tonic-gate 
355b0fc0e77Sgovinda 	iv_p->iv_pil = pil;
356b0fc0e77Sgovinda 	return (0);
3577c478bd9Sstevel@tonic-gate }
358