1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21/* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26#include <sys/zfs_context.h> 27#include <sys/modctl.h> 28 29/* 30 * Null operations; used for uninitialized and "misc" modules. 31 */ 32static int mod_null(struct modlmisc *, struct modlinkage *); 33static int mod_infonull(void *, struct modlinkage *, int *); 34 35/* 36 * Cryptographic Modules 37 */ 38struct mod_ops mod_cryptoops = { 39 .modm_install = mod_null, 40 .modm_remove = mod_null, 41 .modm_info = mod_infonull 42}; 43 44/* 45 * Null operation; return 0. 46 */ 47static int 48mod_null(struct modlmisc *modl, struct modlinkage *modlp) 49{ 50 return (0); 51} 52 53/* 54 * Status for User modules. 55 */ 56static int 57mod_infonull(void *modl, struct modlinkage *modlp, int *p0) 58{ 59 *p0 = -1; /* for modinfo display */ 60 return (0); 61} 62 63/* 64 * Install a module. 65 * (This routine is in the Solaris SPARC DDI/DKI) 66 */ 67int 68mod_install(struct modlinkage *modlp) 69{ 70 int retval = -1; /* No linkage structures */ 71 struct modlmisc **linkpp; 72 struct modlmisc **linkpp1; 73 74 if (modlp->ml_rev != MODREV_1) { 75 cmn_err(CE_WARN, "mod_install: " 76 "modlinkage structure is not MODREV_1\n"); 77 return (EINVAL); 78 } 79 linkpp = (struct modlmisc **)&modlp->ml_linkage[0]; 80 81 while (*linkpp != NULL) { 82 if ((retval = MODL_INSTALL(*linkpp, modlp)) != 0) { 83 linkpp1 = (struct modlmisc **)&modlp->ml_linkage[0]; 84 85 while (linkpp1 != linkpp) { 86 MODL_REMOVE(*linkpp1, modlp); /* clean up */ 87 linkpp1++; 88 } 89 break; 90 } 91 linkpp++; 92 } 93 return (retval); 94} 95 96static char *reins_err = 97 "Could not reinstall %s\nReboot to correct the problem"; 98 99/* 100 * Remove a module. This is called by the module wrapper routine. 101 * (This routine is in the Solaris SPARC DDI/DKI) 102 */ 103int 104mod_remove(struct modlinkage *modlp) 105{ 106 int retval = 0; 107 struct modlmisc **linkpp, *last_linkp; 108 109 linkpp = (struct modlmisc **)&modlp->ml_linkage[0]; 110 111 while (*linkpp != NULL) { 112 if ((retval = MODL_REMOVE(*linkpp, modlp)) != 0) { 113 last_linkp = *linkpp; 114 linkpp = (struct modlmisc **)&modlp->ml_linkage[0]; 115 while (*linkpp != last_linkp) { 116 if (MODL_INSTALL(*linkpp, modlp) != 0) { 117 cmn_err(CE_WARN, reins_err, 118 (*linkpp)->misc_linkinfo); 119 break; 120 } 121 linkpp++; 122 } 123 break; 124 } 125 linkpp++; 126 } 127 return (retval); 128} 129 130/* 131 * Get module status. 132 * (This routine is in the Solaris SPARC DDI/DKI) 133 */ 134int 135mod_info(struct modlinkage *modlp, struct modinfo *modinfop) 136{ 137 int i; 138 int retval = 0; 139 struct modspecific_info *msip; 140 struct modlmisc **linkpp; 141 142 modinfop->mi_rev = modlp->ml_rev; 143 144 linkpp = (struct modlmisc **)modlp->ml_linkage; 145 msip = &modinfop->mi_msinfo[0]; 146 147 for (i = 0; i < MODMAXLINK; i++) { 148 if (*linkpp == NULL) { 149 msip->msi_linkinfo[0] = '\0'; 150 } else { 151 (void) strlcpy(msip->msi_linkinfo, 152 (*linkpp)->misc_linkinfo, MODMAXLINKINFOLEN); 153 retval = MODL_INFO(*linkpp, modlp, &msip->msi_p0); 154 if (retval != 0) 155 break; 156 linkpp++; 157 } 158 msip++; 159 } 160 161 if (modinfop->mi_info == MI_INFO_LINKAGE) { 162 /* 163 * Slight kludge used to extract the address of the 164 * modlinkage structure from the module (just after 165 * loading a module for the very first time) 166 */ 167 modinfop->mi_base = (void *)modlp; 168 } 169 170 if (retval == 0) 171 return (1); 172 return (0); 173} 174