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*1e45ea5aSblakej * Common Development and Distribution License (the "License"). 6*1e45ea5aSblakej * 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*1e45ea5aSblakej * Copyright 2007 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 #include <sys/types.h> 297c478bd9Sstevel@tonic-gate #include <sys/systm.h> 307c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 317c478bd9Sstevel@tonic-gate #include <sys/kobj.h> 327c478bd9Sstevel@tonic-gate #include <sys/membar.h> 337c478bd9Sstevel@tonic-gate #include <sys/dmv.h> 347c478bd9Sstevel@tonic-gate #include <sys/prom_debug.h> 357c478bd9Sstevel@tonic-gate #include <sys/machsystm.h> 36*1e45ea5aSblakej #include <vm/vm_dep.h> 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate /* 397c478bd9Sstevel@tonic-gate * Implementation of databearing mondo vector handler registration routines. 407c478bd9Sstevel@tonic-gate * See PSARC 1998/222 for more details. 417c478bd9Sstevel@tonic-gate */ 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate /* 447c478bd9Sstevel@tonic-gate * The dmv_interface_*_version variables are provided to protect a 457c478bd9Sstevel@tonic-gate * driver against changes in the databearing mondo interfaces. 467c478bd9Sstevel@tonic-gate * 477c478bd9Sstevel@tonic-gate * The major version is incremented when an incompatible change 487c478bd9Sstevel@tonic-gate * is made to an interface; for instance, a routine which used to take 497c478bd9Sstevel@tonic-gate * 3 parameters now takes 4, or a routine which used have the semantics 507c478bd9Sstevel@tonic-gate * "do X" now has the semantics "do Y". Before calling any of the 517c478bd9Sstevel@tonic-gate * databearing mondo routines, a driver must check the major version 527c478bd9Sstevel@tonic-gate * it was compiled with (i.e., the constant DMV_INTERFACE_MAJOR_VERSION) 537c478bd9Sstevel@tonic-gate * against the contents of dmv_interface_major_version. If the two 547c478bd9Sstevel@tonic-gate * are different, the driver must refuse to operate. 557c478bd9Sstevel@tonic-gate * 567c478bd9Sstevel@tonic-gate * The minor version is incremented when an upward-compatible change 577c478bd9Sstevel@tonic-gate * is made to an interface; for instance, a routine now supports a new 587c478bd9Sstevel@tonic-gate * flag bit (in an existing flags argument). A client can use the 597c478bd9Sstevel@tonic-gate * minor version to see whether a feature it depends on is available 607c478bd9Sstevel@tonic-gate * in its environment; in order to enable this, the documentation 617c478bd9Sstevel@tonic-gate * for new features should note which major and minor version the 627c478bd9Sstevel@tonic-gate * feature first appears in. 637c478bd9Sstevel@tonic-gate */ 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate int dmv_interface_major_version = DMV_INTERFACE_MAJOR_VERSION; 667c478bd9Sstevel@tonic-gate int dmv_interface_minor_version = DMV_INTERFACE_MINOR_VERSION; 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate /* 697c478bd9Sstevel@tonic-gate * These are where the number of hardware and software DMV inums are kept. 707c478bd9Sstevel@tonic-gate * If they're zero, we use the platform's default values. (These are not 717c478bd9Sstevel@tonic-gate * patchable in /etc/system, since the dispatch table is allocated before 727c478bd9Sstevel@tonic-gate * /etc/system is loaded; however, you could patch them by adb'ing unix.) 737c478bd9Sstevel@tonic-gate */ 747c478bd9Sstevel@tonic-gate 757c478bd9Sstevel@tonic-gate uint_t dmv_hwint = 0; 767c478bd9Sstevel@tonic-gate uint_t dmv_swint = 0; 777c478bd9Sstevel@tonic-gate uint_t dmv_totalints = 0; 787c478bd9Sstevel@tonic-gate 797c478bd9Sstevel@tonic-gate struct dmv_disp *dmv_dispatch_table = (struct dmv_disp *)0; 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate /* 827c478bd9Sstevel@tonic-gate * dmv_disp_lock protects the dispatch table from being modified by two 837c478bd9Sstevel@tonic-gate * threads concurrently. It is not used to protect the table from being 847c478bd9Sstevel@tonic-gate * modified while being used by the actual interrupt dispatch code; see 857c478bd9Sstevel@tonic-gate * comments at the end of dmv.h for the rationale. 867c478bd9Sstevel@tonic-gate */ 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate kmutex_t dmv_disp_lock; 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate /* 917c478bd9Sstevel@tonic-gate * dmv_add_intr is called to add a databearing mondo interrupt handler 927c478bd9Sstevel@tonic-gate * for a real device to the system. Only one handler may be registered 937c478bd9Sstevel@tonic-gate * for a dmv_inum at any one time. 947c478bd9Sstevel@tonic-gate * 957c478bd9Sstevel@tonic-gate * Note that if a processor receives a databearing mondo interrupt 967c478bd9Sstevel@tonic-gate * for which a handler has not been registered, the behavior is 977c478bd9Sstevel@tonic-gate * undefined. (Current practice for normal mondos which are unhandled 987c478bd9Sstevel@tonic-gate * depends on whether DEBUG is on; a DEBUG kernel prints an error 997c478bd9Sstevel@tonic-gate * and breaks to OBP, while a non-DEBUG kernel simply panics. This 1007c478bd9Sstevel@tonic-gate * model will likely be followed for databearing mondos.) 1017c478bd9Sstevel@tonic-gate * 1027c478bd9Sstevel@tonic-gate * Parameters: 1037c478bd9Sstevel@tonic-gate * dmv_inum interrupt number for the device. 1047c478bd9Sstevel@tonic-gate * 1057c478bd9Sstevel@tonic-gate * routine pointer to the device's vectored interrupt 1067c478bd9Sstevel@tonic-gate * handler. This routine is subject to the 1077c478bd9Sstevel@tonic-gate * constraints outlined below in "Handler 1087c478bd9Sstevel@tonic-gate * Characteristics and Environment". 1097c478bd9Sstevel@tonic-gate * 1107c478bd9Sstevel@tonic-gate * arg argument which will be passed to the device's 1117c478bd9Sstevel@tonic-gate * handler. 1127c478bd9Sstevel@tonic-gate * 1137c478bd9Sstevel@tonic-gate * Return value: 0 if the handler was added successfully, -1 if 1147c478bd9Sstevel@tonic-gate * handler was already registered for the given 1157c478bd9Sstevel@tonic-gate * dmv_inum. 1167c478bd9Sstevel@tonic-gate * 1177c478bd9Sstevel@tonic-gate * Handler Characteristics and Environment 1187c478bd9Sstevel@tonic-gate * 1197c478bd9Sstevel@tonic-gate * Handler Entry: 1207c478bd9Sstevel@tonic-gate * 1217c478bd9Sstevel@tonic-gate * On entry to the handler, the %g registers are set as follows: 1227c478bd9Sstevel@tonic-gate * 1237c478bd9Sstevel@tonic-gate * %g1 The argument (arg) passed to dmv_add_intr(). 1247c478bd9Sstevel@tonic-gate * %g2 Word 0 of the incoming mondo vector. 1257c478bd9Sstevel@tonic-gate * 1267c478bd9Sstevel@tonic-gate * 1277c478bd9Sstevel@tonic-gate * Handler Constraints: 1287c478bd9Sstevel@tonic-gate * 1297c478bd9Sstevel@tonic-gate * While executing, the handler must obey the following rules: 1307c478bd9Sstevel@tonic-gate * 1317c478bd9Sstevel@tonic-gate * 1. The handler is limited to the use of registers %g1 through 1327c478bd9Sstevel@tonic-gate * %g7. 1337c478bd9Sstevel@tonic-gate * 1347c478bd9Sstevel@tonic-gate * 2. The handler may not modify %cwp (i.e., may not execute a 1357c478bd9Sstevel@tonic-gate * SAVE or RESTORE instruction). 1367c478bd9Sstevel@tonic-gate * 1377c478bd9Sstevel@tonic-gate * 3. The handler may not read or write the stack. 1387c478bd9Sstevel@tonic-gate * 1397c478bd9Sstevel@tonic-gate * 4. The handler may not call any other DDI or kernel routines. 1407c478bd9Sstevel@tonic-gate * 1417c478bd9Sstevel@tonic-gate * 5. The handler may not call any other routines inside the 1427c478bd9Sstevel@tonic-gate * handler's own driver, since this would modify %o7; however, 1437c478bd9Sstevel@tonic-gate * it is permissible to jump to a routine within the handler's 1447c478bd9Sstevel@tonic-gate * driver. 1457c478bd9Sstevel@tonic-gate * 1467c478bd9Sstevel@tonic-gate * 6. The handler may read the Incoming Interrupt Vector Data 1477c478bd9Sstevel@tonic-gate * registers, and the Interrupt Vector Receive register, but 1487c478bd9Sstevel@tonic-gate * must not modify these registers. (Note: symbols for the 1497c478bd9Sstevel@tonic-gate * ASIs and addresses of these registers are in <sys/spitasi.h> 1507c478bd9Sstevel@tonic-gate * and <sys/intreg.h>.) 1517c478bd9Sstevel@tonic-gate * 1527c478bd9Sstevel@tonic-gate * 7. The handler may read or write driver-private data 1537c478bd9Sstevel@tonic-gate * structures; in order to protect against simultaneous 1547c478bd9Sstevel@tonic-gate * modification by other driver routines, nonblocking data 1557c478bd9Sstevel@tonic-gate * sharing algorithms must be used. (For instance, 1567c478bd9Sstevel@tonic-gate * compare-and-swap could be used to update counters or add 1577c478bd9Sstevel@tonic-gate * entries to linked lists; producer-consumer queues are 1587c478bd9Sstevel@tonic-gate * another possibility.) 1597c478bd9Sstevel@tonic-gate * 1607c478bd9Sstevel@tonic-gate * 8. The handler should neither read nor write any other 1617c478bd9Sstevel@tonic-gate * processor register nor kernel data item which is not 1627c478bd9Sstevel@tonic-gate * explicitly mentioned in this list. [Yes, this is rather 1637c478bd9Sstevel@tonic-gate * strict; the intent here is that as handler implementations 1647c478bd9Sstevel@tonic-gate * are done, and more experience is gained, additional items 1657c478bd9Sstevel@tonic-gate * may be permitted.] 1667c478bd9Sstevel@tonic-gate * 1677c478bd9Sstevel@tonic-gate * 1687c478bd9Sstevel@tonic-gate * Handler Exit: 1697c478bd9Sstevel@tonic-gate * 1707c478bd9Sstevel@tonic-gate * When the handler's processing is complete, the handler must 1717c478bd9Sstevel@tonic-gate * exit by jumping to the label dmv_finish_intr. At this time, 1727c478bd9Sstevel@tonic-gate * the handler may optionally request the execution of a soft 1737c478bd9Sstevel@tonic-gate * interrupt routine in order to do further processing at normal 1747c478bd9Sstevel@tonic-gate * interrupt level. It is strongly advised that drivers do 1757c478bd9Sstevel@tonic-gate * minimal processing in their databearing mondo handlers; 1767c478bd9Sstevel@tonic-gate * whenever possible, tasks should be postponed to a later 1777c478bd9Sstevel@tonic-gate * soft interrupt routine. (This is analogous to the DDI 1787c478bd9Sstevel@tonic-gate * "high-level interrupt" concept, although a databearing mondo 1797c478bd9Sstevel@tonic-gate * handler's environment is even more restrictive than that of 1807c478bd9Sstevel@tonic-gate * a high-level interrupt routine.) 1817c478bd9Sstevel@tonic-gate * 1827c478bd9Sstevel@tonic-gate * Soft interrupt routines should be registered by calling 1837c478bd9Sstevel@tonic-gate * add_softintr(), which will return an interrupt number. This 1847c478bd9Sstevel@tonic-gate * interrupt number should be saved in a driver-private data 1857c478bd9Sstevel@tonic-gate * structure for later use. 1867c478bd9Sstevel@tonic-gate * 1877c478bd9Sstevel@tonic-gate * The contents of %g1 on entry to dmv_finish_intr determine 1887c478bd9Sstevel@tonic-gate * whether a soft interrupt routine will be called, as follows: 1897c478bd9Sstevel@tonic-gate * 1907c478bd9Sstevel@tonic-gate * If %g1 is less than zero, no interrupt will be queued. 1917c478bd9Sstevel@tonic-gate * 1927c478bd9Sstevel@tonic-gate * Otherwise, %g1 is assumed to be an interrupt number 1937c478bd9Sstevel@tonic-gate * obtained from add_softintr. This interrupt routine 1947c478bd9Sstevel@tonic-gate * will be executed in the normal way at the requested 1957c478bd9Sstevel@tonic-gate * priority. (Note that this routine may or may not 1967c478bd9Sstevel@tonic-gate * execute on the same CPU as the current handler.) 1977c478bd9Sstevel@tonic-gate */ 1987c478bd9Sstevel@tonic-gate 1997c478bd9Sstevel@tonic-gate int 2007c478bd9Sstevel@tonic-gate dmv_add_intr(int dmv_inum, void (*routine)(), void *arg) 2017c478bd9Sstevel@tonic-gate { 2027c478bd9Sstevel@tonic-gate if (dmv_inum < 0 || dmv_inum >= dmv_hwint) 2037c478bd9Sstevel@tonic-gate return (-1); 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate mutex_enter(&dmv_disp_lock); 2067c478bd9Sstevel@tonic-gate 2077c478bd9Sstevel@tonic-gate if (dmv_dispatch_table[dmv_inum].dmv_func != 0) { 2087c478bd9Sstevel@tonic-gate mutex_exit(&dmv_disp_lock); 2097c478bd9Sstevel@tonic-gate return (-1); 2107c478bd9Sstevel@tonic-gate } 2117c478bd9Sstevel@tonic-gate 2127c478bd9Sstevel@tonic-gate dmv_dispatch_table[dmv_inum].dmv_arg = arg; 2137c478bd9Sstevel@tonic-gate 2147c478bd9Sstevel@tonic-gate membar_sync(); 2157c478bd9Sstevel@tonic-gate 2167c478bd9Sstevel@tonic-gate dmv_dispatch_table[dmv_inum].dmv_func = routine; 2177c478bd9Sstevel@tonic-gate 2187c478bd9Sstevel@tonic-gate mutex_exit(&dmv_disp_lock); 2197c478bd9Sstevel@tonic-gate return (0); 2207c478bd9Sstevel@tonic-gate } 2217c478bd9Sstevel@tonic-gate 2227c478bd9Sstevel@tonic-gate /* 2237c478bd9Sstevel@tonic-gate * dmv_add_softintr is called to add a databearing mondo interrupt 2247c478bd9Sstevel@tonic-gate * handler for a pseudo-device to the system. 2257c478bd9Sstevel@tonic-gate * 2267c478bd9Sstevel@tonic-gate * Parameters: 2277c478bd9Sstevel@tonic-gate * routine pointer to the device's vectored interrupt 2287c478bd9Sstevel@tonic-gate * handler. This routine is subject to the 2297c478bd9Sstevel@tonic-gate * constraints outlined above in "Handler 2307c478bd9Sstevel@tonic-gate * Characteristics and Environment". 2317c478bd9Sstevel@tonic-gate * 2327c478bd9Sstevel@tonic-gate * arg argument which will be passed to the device's 2337c478bd9Sstevel@tonic-gate * handler. 2347c478bd9Sstevel@tonic-gate * 2357c478bd9Sstevel@tonic-gate * Return value: dmv_inum allocated if one was available, -1 if 2367c478bd9Sstevel@tonic-gate * all soft dmv_inums are already allocated 2377c478bd9Sstevel@tonic-gate */ 2387c478bd9Sstevel@tonic-gate 2397c478bd9Sstevel@tonic-gate int 2407c478bd9Sstevel@tonic-gate dmv_add_softintr(void (*routine)(void), void *arg) 2417c478bd9Sstevel@tonic-gate { 2427c478bd9Sstevel@tonic-gate int i; 2437c478bd9Sstevel@tonic-gate 2447c478bd9Sstevel@tonic-gate mutex_enter(&dmv_disp_lock); 2457c478bd9Sstevel@tonic-gate 2467c478bd9Sstevel@tonic-gate for (i = dmv_hwint; i < dmv_totalints; i++) { 2477c478bd9Sstevel@tonic-gate if (dmv_dispatch_table[i].dmv_func == 0) { 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate dmv_dispatch_table[i].dmv_arg = arg; 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate membar_sync(); 2527c478bd9Sstevel@tonic-gate 2537c478bd9Sstevel@tonic-gate dmv_dispatch_table[i].dmv_func = routine; 2547c478bd9Sstevel@tonic-gate 2557c478bd9Sstevel@tonic-gate mutex_exit(&dmv_disp_lock); 2567c478bd9Sstevel@tonic-gate return (i); 2577c478bd9Sstevel@tonic-gate } 2587c478bd9Sstevel@tonic-gate } 2597c478bd9Sstevel@tonic-gate 2607c478bd9Sstevel@tonic-gate mutex_exit(&dmv_disp_lock); 2617c478bd9Sstevel@tonic-gate return (-1); 2627c478bd9Sstevel@tonic-gate } 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate /* 2657c478bd9Sstevel@tonic-gate * dmv_rem_intr is called to remove a databearing interrupt handler 2667c478bd9Sstevel@tonic-gate * from the system. 2677c478bd9Sstevel@tonic-gate * 2687c478bd9Sstevel@tonic-gate * Parameters: 2697c478bd9Sstevel@tonic-gate * dmv_inum interrupt number for the device. 2707c478bd9Sstevel@tonic-gate * 2717c478bd9Sstevel@tonic-gate * Return value: 0 if the handler was removed successfully, -1 2727c478bd9Sstevel@tonic-gate * if no handler was registered for the given 2737c478bd9Sstevel@tonic-gate * dmv_inum. 2747c478bd9Sstevel@tonic-gate */ 2757c478bd9Sstevel@tonic-gate 2767c478bd9Sstevel@tonic-gate int 2777c478bd9Sstevel@tonic-gate dmv_rem_intr(int dmv_inum) 2787c478bd9Sstevel@tonic-gate { 2797c478bd9Sstevel@tonic-gate if (dmv_inum < 0 || dmv_inum >= (dmv_totalints)) 2807c478bd9Sstevel@tonic-gate return (-1); 2817c478bd9Sstevel@tonic-gate 2827c478bd9Sstevel@tonic-gate mutex_enter(&dmv_disp_lock); 2837c478bd9Sstevel@tonic-gate 2847c478bd9Sstevel@tonic-gate if (dmv_dispatch_table[dmv_inum].dmv_func == 0) { 2857c478bd9Sstevel@tonic-gate mutex_exit(&dmv_disp_lock); 2867c478bd9Sstevel@tonic-gate return (-1); 2877c478bd9Sstevel@tonic-gate } 2887c478bd9Sstevel@tonic-gate 2897c478bd9Sstevel@tonic-gate dmv_dispatch_table[dmv_inum].dmv_func = 0; 2907c478bd9Sstevel@tonic-gate 2917c478bd9Sstevel@tonic-gate mutex_exit(&dmv_disp_lock); 2927c478bd9Sstevel@tonic-gate return (0); 2937c478bd9Sstevel@tonic-gate } 2947c478bd9Sstevel@tonic-gate 2957c478bd9Sstevel@tonic-gate 2967c478bd9Sstevel@tonic-gate /* 2977c478bd9Sstevel@tonic-gate * Allocate the dmv dispatch table from nucleus data memory. 2987c478bd9Sstevel@tonic-gate */ 2997c478bd9Sstevel@tonic-gate int 3007c478bd9Sstevel@tonic-gate ndata_alloc_dmv(struct memlist *ndata) 3017c478bd9Sstevel@tonic-gate { 3027c478bd9Sstevel@tonic-gate size_t alloc_sz; 3037c478bd9Sstevel@tonic-gate 3047c478bd9Sstevel@tonic-gate uint_t plat_hwint = 0; 3057c478bd9Sstevel@tonic-gate uint_t plat_swint = 0; 3067c478bd9Sstevel@tonic-gate 3077c478bd9Sstevel@tonic-gate void (*plat_dmv_params)(uint_t *, uint_t *); 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gate 3107c478bd9Sstevel@tonic-gate /* 3117c478bd9Sstevel@tonic-gate * Get platform default values, if they exist 3127c478bd9Sstevel@tonic-gate */ 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate plat_dmv_params = (void (*)(uint_t *, uint_t *)) 3157c478bd9Sstevel@tonic-gate kobj_getsymvalue("plat_dmv_params", 0); 3167c478bd9Sstevel@tonic-gate 3177c478bd9Sstevel@tonic-gate if (plat_dmv_params) 3187c478bd9Sstevel@tonic-gate (*plat_dmv_params)(&plat_hwint, &plat_swint); 3197c478bd9Sstevel@tonic-gate 3207c478bd9Sstevel@tonic-gate /* 3217c478bd9Sstevel@tonic-gate * Set sizes to platform defaults if user hasn't set them 3227c478bd9Sstevel@tonic-gate */ 3237c478bd9Sstevel@tonic-gate 3247c478bd9Sstevel@tonic-gate if (dmv_hwint == 0) 3257c478bd9Sstevel@tonic-gate dmv_hwint = plat_hwint; 3267c478bd9Sstevel@tonic-gate 3277c478bd9Sstevel@tonic-gate if (dmv_swint == 0) 3287c478bd9Sstevel@tonic-gate dmv_swint = plat_swint; 3297c478bd9Sstevel@tonic-gate 3307c478bd9Sstevel@tonic-gate /* 3317c478bd9Sstevel@tonic-gate * Allocate table if we need it 3327c478bd9Sstevel@tonic-gate */ 3337c478bd9Sstevel@tonic-gate dmv_totalints = dmv_hwint + dmv_swint; 3347c478bd9Sstevel@tonic-gate 3357c478bd9Sstevel@tonic-gate if (dmv_totalints != 0) { 3367c478bd9Sstevel@tonic-gate 3377c478bd9Sstevel@tonic-gate alloc_sz = sizeof (struct dmv_disp) * (dmv_totalints + 1); 3387c478bd9Sstevel@tonic-gate 3397c478bd9Sstevel@tonic-gate dmv_dispatch_table = ndata_alloc(ndata, alloc_sz, 3407c478bd9Sstevel@tonic-gate sizeof (struct dmv_disp)); 3417c478bd9Sstevel@tonic-gate 3427c478bd9Sstevel@tonic-gate if (dmv_dispatch_table == NULL) 3437c478bd9Sstevel@tonic-gate return (-1); 3447c478bd9Sstevel@tonic-gate 3457c478bd9Sstevel@tonic-gate bzero(dmv_dispatch_table, alloc_sz); 346264d6c47Seota /* use uintptr_t to suppress the gcc warning */ 347264d6c47Seota PRM_DEBUG((uintptr_t)dmv_dispatch_table); 3487c478bd9Sstevel@tonic-gate } 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate return (0); 3517c478bd9Sstevel@tonic-gate } 352