/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include /* * Null operations; used for uninitialized and "misc" modules. */ static int mod_null(struct modlmisc *, struct modlinkage *); static int mod_infonull(void *, struct modlinkage *, int *); /* * Cryptographic Modules */ struct mod_ops mod_cryptoops = { mod_null, mod_null, mod_infonull }; /* * Null operation; return 0. */ static int mod_null(struct modlmisc *modl, struct modlinkage *modlp) { return (0); } /* * Status for User modules. */ static int mod_infonull(void *modl, struct modlinkage *modlp, int *p0) { *p0 = -1; /* for modinfo display */ return (0); } /* * Install a module. * (This routine is in the Solaris SPARC DDI/DKI) */ int mod_install(struct modlinkage *modlp) { int retval = -1; /* No linkage structures */ struct modlmisc **linkpp; struct modlmisc **linkpp1; if (modlp->ml_rev != MODREV_1) { cmn_err(CE_WARN, "mod_install: " "modlinkage structure is not MODREV_1\n"); return (EINVAL); } linkpp = (struct modlmisc **)&modlp->ml_linkage[0]; while (*linkpp != NULL) { if ((retval = MODL_INSTALL(*linkpp, modlp)) != 0) { linkpp1 = (struct modlmisc **)&modlp->ml_linkage[0]; while (linkpp1 != linkpp) { MODL_REMOVE(*linkpp1, modlp); /* clean up */ linkpp1++; } break; } linkpp++; } return (retval); } static char *reins_err = "Could not reinstall %s\nReboot to correct the problem"; /* * Remove a module. This is called by the module wrapper routine. * (This routine is in the Solaris SPARC DDI/DKI) */ int mod_remove(struct modlinkage *modlp) { int retval = 0; struct modlmisc **linkpp, *last_linkp; linkpp = (struct modlmisc **)&modlp->ml_linkage[0]; while (*linkpp != NULL) { if ((retval = MODL_REMOVE(*linkpp, modlp)) != 0) { last_linkp = *linkpp; linkpp = (struct modlmisc **)&modlp->ml_linkage[0]; while (*linkpp != last_linkp) { if (MODL_INSTALL(*linkpp, modlp) != 0) { cmn_err(CE_WARN, reins_err, (*linkpp)->misc_linkinfo); break; } linkpp++; } break; } linkpp++; } return (retval); } /* * Get module status. * (This routine is in the Solaris SPARC DDI/DKI) */ int mod_info(struct modlinkage *modlp, struct modinfo *modinfop) { int i; int retval = 0; struct modspecific_info *msip; struct modlmisc **linkpp; modinfop->mi_rev = modlp->ml_rev; linkpp = (struct modlmisc **)modlp->ml_linkage; msip = &modinfop->mi_msinfo[0]; for (i = 0; i < MODMAXLINK; i++) { if (*linkpp == NULL) { msip->msi_linkinfo[0] = '\0'; } else { (void) strncpy(msip->msi_linkinfo, (*linkpp)->misc_linkinfo, MODMAXLINKINFOLEN); retval = MODL_INFO(*linkpp, modlp, &msip->msi_p0); if (retval != 0) break; linkpp++; } msip++; } if (modinfop->mi_info == MI_INFO_LINKAGE) { /* * Slight kludge used to extract the address of the * modlinkage structure from the module (just after * loading a module for the very first time) */ modinfop->mi_base = (void *)modlp; } if (retval == 0) return (1); return (0); }