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*d62bc4baSyz147064 * Common Development and Distribution License (the "License"). 6*d62bc4baSyz147064 * 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*d62bc4baSyz147064 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23*d62bc4baSyz147064 * 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 /* 297c478bd9Sstevel@tonic-gate * DACF (Device Autoconfiguration Framework) client code. 307c478bd9Sstevel@tonic-gate * 317c478bd9Sstevel@tonic-gate * DACF has two clients. the first is dacf modules which implement 327c478bd9Sstevel@tonic-gate * configuration operations; the second is the set of hooks in the kernel 337c478bd9Sstevel@tonic-gate * which do rule matching and invoke configuration operations. 347c478bd9Sstevel@tonic-gate * 357c478bd9Sstevel@tonic-gate * This file implements the second part, the kernel hooks. 367c478bd9Sstevel@tonic-gate * 377c478bd9Sstevel@tonic-gate * Currently implemented are post-attach and pre-detach handlers, and the hook 387c478bd9Sstevel@tonic-gate * for ddi_create_minor_common() which sets up post-attach and pre-detach 397c478bd9Sstevel@tonic-gate * reservations. 407c478bd9Sstevel@tonic-gate * 417c478bd9Sstevel@tonic-gate * This code depends on the core dacf code (in dacf.c) but the converse should 427c478bd9Sstevel@tonic-gate * never be true. 437c478bd9Sstevel@tonic-gate * 447c478bd9Sstevel@tonic-gate * This file also implements '__kernel', the kernel-supplied dacf module. 457c478bd9Sstevel@tonic-gate * For now, this is pretty much empty, except under DEBUG, in which case it 467c478bd9Sstevel@tonic-gate * contains some debugging code. 477c478bd9Sstevel@tonic-gate */ 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate #include <sys/param.h> 507c478bd9Sstevel@tonic-gate #include <sys/modctl.h> 517c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 527c478bd9Sstevel@tonic-gate #include <sys/kmem.h> 537c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h> 547c478bd9Sstevel@tonic-gate #include <sys/pathname.h> 557c478bd9Sstevel@tonic-gate #include <sys/ddi_impldefs.h> 567c478bd9Sstevel@tonic-gate #include <sys/sunddi.h> 577c478bd9Sstevel@tonic-gate #include <sys/autoconf.h> 587c478bd9Sstevel@tonic-gate #include <sys/modhash.h> 597c478bd9Sstevel@tonic-gate #include <sys/dacf_impl.h> 607c478bd9Sstevel@tonic-gate #include <sys/systm.h> 617c478bd9Sstevel@tonic-gate #include <sys/debug.h> 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate /* 647c478bd9Sstevel@tonic-gate * dacfc_match_create_minor() 657c478bd9Sstevel@tonic-gate * Check to see if this minor node creation sequence matches a dacf 667c478bd9Sstevel@tonic-gate * (device autoconfiguration framework) rule. If so make a reservation 677c478bd9Sstevel@tonic-gate * for the operation to be invoked at post-attach and/or pre-detach time. 687c478bd9Sstevel@tonic-gate */ 697c478bd9Sstevel@tonic-gate void 707c478bd9Sstevel@tonic-gate dacfc_match_create_minor(char *name, char *node_type, dev_info_t *dip, 717c478bd9Sstevel@tonic-gate struct ddi_minor_data *dmdp, int flag) 727c478bd9Sstevel@tonic-gate { 737c478bd9Sstevel@tonic-gate dacf_rule_t *r; 747c478bd9Sstevel@tonic-gate char *dev_path, *dev_pathp, *drv_mname = NULL; 757c478bd9Sstevel@tonic-gate dacf_rsrvlist_t *pa_rsrv, *pd_rsrv; 767c478bd9Sstevel@tonic-gate 77*d62bc4baSyz147064 /* 78*d62bc4baSyz147064 * Check the dacf rule for non-clone devices or for network devices. 79*d62bc4baSyz147064 */ 80*d62bc4baSyz147064 if ((flag & CLONE_DEV) && (strcmp(node_type, DDI_NT_NET) != 0)) { 817c478bd9Sstevel@tonic-gate return; 827c478bd9Sstevel@tonic-gate } 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate /* 857c478bd9Sstevel@tonic-gate * Because dacf currently only implements post-attach and pre-detach 867c478bd9Sstevel@tonic-gate * processing, we only care about minor nodes created during attach. 877c478bd9Sstevel@tonic-gate * However, there is no restriction on drivers about when to create 887c478bd9Sstevel@tonic-gate * minor nodes. 897c478bd9Sstevel@tonic-gate */ 907c478bd9Sstevel@tonic-gate if (!DEVI_IS_ATTACHING(dmdp->dip)) { 917c478bd9Sstevel@tonic-gate return; 927c478bd9Sstevel@tonic-gate } 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate dev_path = kmem_alloc(MAXPATHLEN, KM_SLEEP); 957c478bd9Sstevel@tonic-gate dev_pathp = ddi_pathname(dip, dev_path); 967c478bd9Sstevel@tonic-gate pa_rsrv = kmem_alloc(sizeof (dacf_rsrvlist_t), KM_SLEEP); 977c478bd9Sstevel@tonic-gate pd_rsrv = kmem_alloc(sizeof (dacf_rsrvlist_t), KM_SLEEP); 987c478bd9Sstevel@tonic-gate 997c478bd9Sstevel@tonic-gate if (name) { 1007c478bd9Sstevel@tonic-gate const char *drv_name = ddi_driver_name(dip); 1017c478bd9Sstevel@tonic-gate if (drv_name == NULL) 1027c478bd9Sstevel@tonic-gate drv_name = "???"; 1037c478bd9Sstevel@tonic-gate drv_mname = kmem_alloc(MAXPATHLEN, KM_SLEEP); 1047c478bd9Sstevel@tonic-gate (void) snprintf(drv_mname, MAXPATHLEN, "%s:%s", drv_name, name); 1057c478bd9Sstevel@tonic-gate } 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gate mutex_enter(&dacf_lock); 1087c478bd9Sstevel@tonic-gate 1097c478bd9Sstevel@tonic-gate /* 1107c478bd9Sstevel@tonic-gate * Ensure that we don't wind up in a 'matching loop' against a devinfo 1117c478bd9Sstevel@tonic-gate * node, which could cause deadlock. This could happen as follows: 1127c478bd9Sstevel@tonic-gate * 1137c478bd9Sstevel@tonic-gate * We match (just below) 1147c478bd9Sstevel@tonic-gate * We invoke a task (later, at the end of devi_attach) 1157c478bd9Sstevel@tonic-gate * this means we have taken the per-devinfo lock 1167c478bd9Sstevel@tonic-gate * The task invoke winds up causing the same driver (that has 1177c478bd9Sstevel@tonic-gate * just finished attaching) to create another minor node. 1187c478bd9Sstevel@tonic-gate * We try to re-acquire the per-devinfo list lock again in the 1197c478bd9Sstevel@tonic-gate * process of making another reservation 1207c478bd9Sstevel@tonic-gate */ 1217c478bd9Sstevel@tonic-gate mutex_enter(&(DEVI(dip)->devi_lock)); 1227c478bd9Sstevel@tonic-gate if (DEVI_IS_INVOKING_DACF(dip)) { 1237c478bd9Sstevel@tonic-gate mutex_exit(&(DEVI(dip)->devi_lock)); 1247c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, 1257c478bd9Sstevel@tonic-gate "!dacf detected deadlock, aborting matching procedure\n"); 1267c478bd9Sstevel@tonic-gate mutex_exit(&dacf_lock); 1277c478bd9Sstevel@tonic-gate kmem_free(pa_rsrv, sizeof (dacf_rsrvlist_t)); 1287c478bd9Sstevel@tonic-gate kmem_free(pd_rsrv, sizeof (dacf_rsrvlist_t)); 1297c478bd9Sstevel@tonic-gate kmem_free(dev_path, MAXPATHLEN); 1307c478bd9Sstevel@tonic-gate if (drv_mname) { 1317c478bd9Sstevel@tonic-gate kmem_free(drv_mname, MAXPATHLEN); 1327c478bd9Sstevel@tonic-gate } 1337c478bd9Sstevel@tonic-gate return; 1347c478bd9Sstevel@tonic-gate } 1357c478bd9Sstevel@tonic-gate mutex_exit(&(DEVI(dip)->devi_lock)); 1367c478bd9Sstevel@tonic-gate 1377c478bd9Sstevel@tonic-gate /* 1387c478bd9Sstevel@tonic-gate * Do rule matching. It's possible to construct two rules that would 1397c478bd9Sstevel@tonic-gate * match against the same minor node, so we match from most to least 1407c478bd9Sstevel@tonic-gate * specific: 1417c478bd9Sstevel@tonic-gate * device path 1427c478bd9Sstevel@tonic-gate * minor node name (concatenation of drv_name:name 1437c478bd9Sstevel@tonic-gate * node type 1447c478bd9Sstevel@tonic-gate * 1457c478bd9Sstevel@tonic-gate * Future additions to the set of device-specifiers should be 1467c478bd9Sstevel@tonic-gate * sensitive to this ordering. 1477c478bd9Sstevel@tonic-gate */ 1487c478bd9Sstevel@tonic-gate 1497c478bd9Sstevel@tonic-gate /* 1507c478bd9Sstevel@tonic-gate * post-attach matching 1517c478bd9Sstevel@tonic-gate */ 1527c478bd9Sstevel@tonic-gate r = NULL; 1537c478bd9Sstevel@tonic-gate if (dev_pathp) { 1547c478bd9Sstevel@tonic-gate r = dacf_match(DACF_OPID_POSTATTACH, DACF_DS_DEV_PATH, 1557c478bd9Sstevel@tonic-gate dev_pathp); 1567c478bd9Sstevel@tonic-gate } 1577c478bd9Sstevel@tonic-gate if (!r && drv_mname) { 1587c478bd9Sstevel@tonic-gate r = dacf_match(DACF_OPID_POSTATTACH, DACF_DS_DRV_MNAME, 1597c478bd9Sstevel@tonic-gate drv_mname); 1607c478bd9Sstevel@tonic-gate } 1617c478bd9Sstevel@tonic-gate if (!r && node_type) { 1627c478bd9Sstevel@tonic-gate r = dacf_match(DACF_OPID_POSTATTACH, DACF_DS_MIN_NT, node_type); 1637c478bd9Sstevel@tonic-gate } 1647c478bd9Sstevel@tonic-gate if (r) { 1657c478bd9Sstevel@tonic-gate dacf_rsrv_make(pa_rsrv, r, dmdp, &(DEVI(dip)->devi_dacf_tasks)); 1667c478bd9Sstevel@tonic-gate 1677c478bd9Sstevel@tonic-gate if (dacfdebug & DACF_DBG_MSGS) 1687c478bd9Sstevel@tonic-gate printf("dacf: made 'post-attach' reservation for " 1697c478bd9Sstevel@tonic-gate "%s, %s, %s\n", name, node_type, dev_pathp); 1707c478bd9Sstevel@tonic-gate } else { 1717c478bd9Sstevel@tonic-gate kmem_free(pa_rsrv, sizeof (dacf_rsrvlist_t)); 1727c478bd9Sstevel@tonic-gate } 1737c478bd9Sstevel@tonic-gate 1747c478bd9Sstevel@tonic-gate /* 1757c478bd9Sstevel@tonic-gate * pre-detach matching 1767c478bd9Sstevel@tonic-gate */ 1777c478bd9Sstevel@tonic-gate r = NULL; 1787c478bd9Sstevel@tonic-gate if (dev_pathp) { 1797c478bd9Sstevel@tonic-gate r = dacf_match(DACF_OPID_PREDETACH, DACF_DS_DEV_PATH, 1807c478bd9Sstevel@tonic-gate dev_pathp); 1817c478bd9Sstevel@tonic-gate } 1827c478bd9Sstevel@tonic-gate if (!r && drv_mname) { 1837c478bd9Sstevel@tonic-gate r = dacf_match(DACF_OPID_PREDETACH, DACF_DS_DRV_MNAME, 1847c478bd9Sstevel@tonic-gate drv_mname); 1857c478bd9Sstevel@tonic-gate } 1867c478bd9Sstevel@tonic-gate if (!r && node_type) { 1877c478bd9Sstevel@tonic-gate r = dacf_match(DACF_OPID_PREDETACH, DACF_DS_MIN_NT, node_type); 1887c478bd9Sstevel@tonic-gate } 1897c478bd9Sstevel@tonic-gate if (r) { 1907c478bd9Sstevel@tonic-gate dacf_rsrv_make(pd_rsrv, r, dmdp, &(DEVI(dip)->devi_dacf_tasks)); 1917c478bd9Sstevel@tonic-gate 1927c478bd9Sstevel@tonic-gate if (dacfdebug & DACF_DBG_MSGS) { 1937c478bd9Sstevel@tonic-gate printf("dacf: made 'pre-detach' reservation for " 1947c478bd9Sstevel@tonic-gate "%s, %s, %s\n", name, node_type, dev_pathp); 1957c478bd9Sstevel@tonic-gate } 1967c478bd9Sstevel@tonic-gate } else { 1977c478bd9Sstevel@tonic-gate kmem_free(pd_rsrv, sizeof (dacf_rsrvlist_t)); 1987c478bd9Sstevel@tonic-gate } 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate mutex_exit(&dacf_lock); 2017c478bd9Sstevel@tonic-gate kmem_free(dev_path, MAXPATHLEN); 2027c478bd9Sstevel@tonic-gate if (drv_mname) { 2037c478bd9Sstevel@tonic-gate kmem_free(drv_mname, MAXPATHLEN); 2047c478bd9Sstevel@tonic-gate } 2057c478bd9Sstevel@tonic-gate } 2067c478bd9Sstevel@tonic-gate 2077c478bd9Sstevel@tonic-gate /* 2087c478bd9Sstevel@tonic-gate * dacfc_postattach() 2097c478bd9Sstevel@tonic-gate * autoconfiguration for post-attach events. 2107c478bd9Sstevel@tonic-gate * 2117c478bd9Sstevel@tonic-gate * strategy: try to configure. If some of the configuration operations 2127c478bd9Sstevel@tonic-gate * fail, emit a warning. 2137c478bd9Sstevel@tonic-gate */ 2147c478bd9Sstevel@tonic-gate int 2157c478bd9Sstevel@tonic-gate dacfc_postattach(dev_info_t *devi) 2167c478bd9Sstevel@tonic-gate { 2177c478bd9Sstevel@tonic-gate int err = DACF_SUCCESS; 2187c478bd9Sstevel@tonic-gate char *path, *pathp; 2197c478bd9Sstevel@tonic-gate dacf_rsrvlist_t **opsp, *op; 2207c478bd9Sstevel@tonic-gate ASSERT(MUTEX_HELD(&dacf_lock)); 2217c478bd9Sstevel@tonic-gate 2227c478bd9Sstevel@tonic-gate /* 2237c478bd9Sstevel@tonic-gate * Instruct dacf_process_rsrvs() to invoke each POSTATTACH op. 2247c478bd9Sstevel@tonic-gate */ 2257c478bd9Sstevel@tonic-gate opsp = &DEVI(devi)->devi_dacf_tasks; 2267c478bd9Sstevel@tonic-gate dacf_process_rsrvs(opsp, DACF_OPID_POSTATTACH, DACF_PROC_INVOKE); 2277c478bd9Sstevel@tonic-gate 2287c478bd9Sstevel@tonic-gate /* 2297c478bd9Sstevel@tonic-gate * Check to see that all POSTATTACH's succeeded. 2307c478bd9Sstevel@tonic-gate */ 2317c478bd9Sstevel@tonic-gate for (op = *opsp; op != NULL; op = op->rsrv_next) { 2327c478bd9Sstevel@tonic-gate if (op->rsrv_rule->r_opid != DACF_OPID_POSTATTACH) 2337c478bd9Sstevel@tonic-gate continue; 2347c478bd9Sstevel@tonic-gate if (op->rsrv_result == DACF_SUCCESS) 2357c478bd9Sstevel@tonic-gate continue; 2367c478bd9Sstevel@tonic-gate if (dacfdebug & DACF_DBG_DEVI) { 2377c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "op failed, err = %d\n", 2387c478bd9Sstevel@tonic-gate op->rsrv_result); 2397c478bd9Sstevel@tonic-gate } 2407c478bd9Sstevel@tonic-gate err = DACF_FAILURE; 2417c478bd9Sstevel@tonic-gate break; 2427c478bd9Sstevel@tonic-gate } 2437c478bd9Sstevel@tonic-gate 2447c478bd9Sstevel@tonic-gate /* 2457c478bd9Sstevel@tonic-gate * If one or more postattach's failed, give up. 2467c478bd9Sstevel@tonic-gate */ 2477c478bd9Sstevel@tonic-gate if ((err == DACF_FAILURE) && (dacfdebug & DACF_DBG_DEVI)) { 2487c478bd9Sstevel@tonic-gate path = kmem_alloc(MAXPATHLEN, KM_SLEEP); 2497c478bd9Sstevel@tonic-gate if ((pathp = ddi_pathname(devi, path)) == NULL) 2507c478bd9Sstevel@tonic-gate pathp = "<unknown>"; 2517c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "%s attached, but failed to auto-configure", 2527c478bd9Sstevel@tonic-gate pathp); 2537c478bd9Sstevel@tonic-gate kmem_free(path, MAXPATHLEN); 2547c478bd9Sstevel@tonic-gate } 2557c478bd9Sstevel@tonic-gate 2567c478bd9Sstevel@tonic-gate return (err); 2577c478bd9Sstevel@tonic-gate } 2587c478bd9Sstevel@tonic-gate 2597c478bd9Sstevel@tonic-gate /* 2607c478bd9Sstevel@tonic-gate * dacfc_predetach() 2617c478bd9Sstevel@tonic-gate * auto-unconfiguration for pre-detach events. 2627c478bd9Sstevel@tonic-gate * 2637c478bd9Sstevel@tonic-gate * strategy: call the pre-detach operation for all matching reservations. 2647c478bd9Sstevel@tonic-gate * If any of these fail, make (one) attempt to reconfigure things back 2657c478bd9Sstevel@tonic-gate * into a sane state. if that fails, our state is uncertain. 2667c478bd9Sstevel@tonic-gate */ 2677c478bd9Sstevel@tonic-gate int 2687c478bd9Sstevel@tonic-gate dacfc_predetach(dev_info_t *devi) 2697c478bd9Sstevel@tonic-gate { 2707c478bd9Sstevel@tonic-gate int err = DDI_SUCCESS; 2717c478bd9Sstevel@tonic-gate char *path, *pathp; 2727c478bd9Sstevel@tonic-gate dacf_rsrvlist_t **opsp, *op; 2737c478bd9Sstevel@tonic-gate ASSERT(MUTEX_HELD(&dacf_lock)); 2747c478bd9Sstevel@tonic-gate 2757c478bd9Sstevel@tonic-gate /* 2767c478bd9Sstevel@tonic-gate * Instruct dacf_process_rsrvs() to invoke each PREDETACH op. 2777c478bd9Sstevel@tonic-gate */ 2787c478bd9Sstevel@tonic-gate opsp = &DEVI(devi)->devi_dacf_tasks; 2797c478bd9Sstevel@tonic-gate dacf_process_rsrvs(opsp, DACF_OPID_PREDETACH, DACF_PROC_INVOKE); 2807c478bd9Sstevel@tonic-gate 2817c478bd9Sstevel@tonic-gate /* 2827c478bd9Sstevel@tonic-gate * Check to see that all PREDETACH's succeeded. 2837c478bd9Sstevel@tonic-gate */ 2847c478bd9Sstevel@tonic-gate for (op = *opsp; op != NULL; op = op->rsrv_next) { 2857c478bd9Sstevel@tonic-gate if (op->rsrv_rule->r_opid != DACF_OPID_PREDETACH) 2867c478bd9Sstevel@tonic-gate continue; 2877c478bd9Sstevel@tonic-gate if (op->rsrv_result == 0) 2887c478bd9Sstevel@tonic-gate continue; 2897c478bd9Sstevel@tonic-gate err = DDI_FAILURE; 2907c478bd9Sstevel@tonic-gate break; 2917c478bd9Sstevel@tonic-gate } 2927c478bd9Sstevel@tonic-gate 2937c478bd9Sstevel@tonic-gate /* 2947c478bd9Sstevel@tonic-gate * If one or more predetach's failed, make one attempt to fix things 2957c478bd9Sstevel@tonic-gate * by re-running all of the POST-ATTACH operations. If any of those 2967c478bd9Sstevel@tonic-gate * fail, give up. 2977c478bd9Sstevel@tonic-gate */ 2987c478bd9Sstevel@tonic-gate if (err == DDI_FAILURE) { 2997c478bd9Sstevel@tonic-gate int pa_err; 3007c478bd9Sstevel@tonic-gate 3017c478bd9Sstevel@tonic-gate if (dacfdebug & DACF_DBG_DEVI) { 3027c478bd9Sstevel@tonic-gate path = kmem_alloc(MAXPATHLEN, KM_SLEEP); 3037c478bd9Sstevel@tonic-gate if ((pathp = ddi_pathname(devi, path)) == NULL) 3047c478bd9Sstevel@tonic-gate pathp = "<unknown>"; 3057c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "%s failed to auto-unconfigure, " 3067c478bd9Sstevel@tonic-gate "attempting to reconfigure...", pathp); 3077c478bd9Sstevel@tonic-gate kmem_free(path, MAXPATHLEN); 3087c478bd9Sstevel@tonic-gate } 3097c478bd9Sstevel@tonic-gate 3107c478bd9Sstevel@tonic-gate pa_err = dacfc_postattach(devi); 3117c478bd9Sstevel@tonic-gate 3127c478bd9Sstevel@tonic-gate if (dacfdebug & DACF_DBG_DEVI) { 3137c478bd9Sstevel@tonic-gate path = kmem_alloc(MAXPATHLEN, KM_SLEEP); 3147c478bd9Sstevel@tonic-gate if ((pathp = ddi_pathname(devi, path)) == NULL) 3157c478bd9Sstevel@tonic-gate pathp = "<unknown>"; 3167c478bd9Sstevel@tonic-gate 3177c478bd9Sstevel@tonic-gate if (pa_err == DDI_FAILURE) { 3187c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "%s failed to " 3197c478bd9Sstevel@tonic-gate "auto-unconfigure, and could not be " 3207c478bd9Sstevel@tonic-gate "re-autoconfigured.", pathp); 3217c478bd9Sstevel@tonic-gate } else { 3227c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "%s failed to " 3237c478bd9Sstevel@tonic-gate "auto-unconfigure, but was successfully " 3247c478bd9Sstevel@tonic-gate "re-autoconfigured.", pathp); 3257c478bd9Sstevel@tonic-gate } 3267c478bd9Sstevel@tonic-gate kmem_free(path, MAXPATHLEN); 3277c478bd9Sstevel@tonic-gate } 3287c478bd9Sstevel@tonic-gate } 3297c478bd9Sstevel@tonic-gate 3307c478bd9Sstevel@tonic-gate return (err); 3317c478bd9Sstevel@tonic-gate } 3327c478bd9Sstevel@tonic-gate 3337c478bd9Sstevel@tonic-gate /* 3347c478bd9Sstevel@tonic-gate * kmod_dacfsw: 3357c478bd9Sstevel@tonic-gate * This is the declaration for the kernel-supplied '__kernel' dacf module. 3367c478bd9Sstevel@tonic-gate * DACF supplies a framework based around loadable modules. However, it 3377c478bd9Sstevel@tonic-gate * may be convenient (in the future) to have a module provided by the 3387c478bd9Sstevel@tonic-gate * kernel. This is useful in cases when a module can't be loaded (early in 3397c478bd9Sstevel@tonic-gate * boot), or for code that would never get unloaded anyway. 3407c478bd9Sstevel@tonic-gate */ 3417c478bd9Sstevel@tonic-gate #ifdef DEBUG 3427c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 3437c478bd9Sstevel@tonic-gate static int 3447c478bd9Sstevel@tonic-gate kmod_test_postattach(dacf_infohdl_t info_hdl, dacf_arghdl_t arg_hdl, int flags) 3457c478bd9Sstevel@tonic-gate { 3467c478bd9Sstevel@tonic-gate const char *verbose = dacf_get_arg(arg_hdl, "verbose"); 3477c478bd9Sstevel@tonic-gate if (verbose && (strcmp(verbose, "true") == 0)) { 3487c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "got kmod_test_postattach\n"); 3497c478bd9Sstevel@tonic-gate } 3507c478bd9Sstevel@tonic-gate return (0); 3517c478bd9Sstevel@tonic-gate } 3527c478bd9Sstevel@tonic-gate #endif 3537c478bd9Sstevel@tonic-gate 3547c478bd9Sstevel@tonic-gate static dacf_op_t kmod_op_test[] = { 3557c478bd9Sstevel@tonic-gate #ifdef DEBUG 3567c478bd9Sstevel@tonic-gate { DACF_OPID_POSTATTACH, kmod_test_postattach }, 3577c478bd9Sstevel@tonic-gate #endif 3587c478bd9Sstevel@tonic-gate { DACF_OPID_END, NULL }, 3597c478bd9Sstevel@tonic-gate }; 3607c478bd9Sstevel@tonic-gate 3617c478bd9Sstevel@tonic-gate static dacf_opset_t kmod_opsets[] = { 3627c478bd9Sstevel@tonic-gate #ifdef DEBUG 3637c478bd9Sstevel@tonic-gate { "kmod_test", kmod_op_test }, 3647c478bd9Sstevel@tonic-gate #endif 3657c478bd9Sstevel@tonic-gate { NULL, NULL }, 3667c478bd9Sstevel@tonic-gate }; 3677c478bd9Sstevel@tonic-gate 3687c478bd9Sstevel@tonic-gate struct dacfsw kmod_dacfsw = { 3697c478bd9Sstevel@tonic-gate DACF_MODREV_1, kmod_opsets 3707c478bd9Sstevel@tonic-gate }; 371