Home | History | Annotate | Download | only in io
      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 /*
     23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 /*
     28  * This module provides the dacf functions to be called after a device
     29  * of "ddi_network" node type has attached and before it detaches.
     30  * Specifically, net_postattach() will be called during the post-attach
     31  * process of each "ddi_network" device, and net_predetach() will be
     32  * called during the pre-detach process of each device.
     33  */
     34 #include <sys/modctl.h>
     35 #include <sys/sunddi.h>
     36 #include <sys/ddi.h>
     37 #include <sys/dacf.h>
     38 #include <sys/softmac.h>
     39 
     40 /*
     41  * DACF entry points
     42  */
     43 static int	net_postattach(dacf_infohdl_t, dacf_arghdl_t, int);
     44 static int	net_predetach(dacf_infohdl_t, dacf_arghdl_t, int);
     45 
     46 static dacf_op_t net_config_op[] = {
     47 	{ DACF_OPID_POSTATTACH,	net_postattach	},
     48 	{ DACF_OPID_PREDETACH,	net_predetach	},
     49 	{ DACF_OPID_END,	NULL		},
     50 };
     51 
     52 static dacf_opset_t opsets[] = {
     53 	{ "net_config", net_config_op 		},
     54 	{ NULL,		NULL 			}
     55 };
     56 
     57 static struct dacfsw dacfsw = {
     58 	DACF_MODREV_1,
     59 	opsets
     60 };
     61 
     62 static struct modldacf modldacf = {
     63 	&mod_dacfops,
     64 	"net DACF",
     65 	&dacfsw
     66 };
     67 
     68 static struct modlinkage modlinkage = {
     69 	MODREV_1, &modldacf, NULL
     70 };
     71 
     72 int
     73 _init(void)
     74 {
     75 	return (mod_install(&modlinkage));
     76 }
     77 
     78 int
     79 _fini(void)
     80 {
     81 	return (mod_remove(&modlinkage));
     82 }
     83 
     84 int
     85 _info(struct modinfo *modinfop)
     86 {
     87 	return (mod_info(&modlinkage, modinfop));
     88 }
     89 
     90 /*
     91  * Post-attach routine invoked for DDI_NT_NET drivers by DACF framework
     92  */
     93 /* ARGSUSED */
     94 static int
     95 net_postattach(dacf_infohdl_t info_hdl, dacf_arghdl_t arg_hdl, int flags)
     96 {
     97 	dev_info_t	*dip;
     98 	dev_t		dev;
     99 	int		err;
    100 
    101 	dip = dacf_devinfo_node(info_hdl);
    102 	dev = dacf_get_dev(info_hdl);
    103 
    104 	if ((err = softmac_create(dip, dev)) != 0) {
    105 		const char	*drvname;
    106 		int		ppa;
    107 
    108 		drvname = ddi_driver_name(dip);
    109 		ppa = i_ddi_devi_get_ppa(dip);
    110 		cmn_err(CE_WARN, "net_postattach: cannot create softmac "
    111 		    "for device %s%d (%d)", drvname, ppa, err);
    112 		return (DACF_FAILURE);
    113 	}
    114 
    115 	return (DACF_SUCCESS);
    116 }
    117 
    118 /*
    119  * Pre-detach routine invoked for DDI_NT_NET drivers by DACF framework
    120  */
    121 /* ARGSUSED */
    122 static int
    123 net_predetach(dacf_infohdl_t info_hdl, dacf_arghdl_t arg_hdl, int flags)
    124 {
    125 	dev_info_t	*dip;
    126 	dev_t		dev;
    127 
    128 	dip = dacf_devinfo_node(info_hdl);
    129 	dev = dacf_get_dev(info_hdl);
    130 
    131 	if (softmac_destroy(dip, dev) != 0)
    132 		return (DACF_FAILURE);
    133 
    134 	return (DACF_SUCCESS);
    135 }
    136