Merge remote-tracking branch 'origin/master'
[unleashed/lotheac.git] / usr / src / uts / common / io / ppp / sppptun / sppptun_mod.c
blob528ffc1fe86c1683047cc181bd34dc4a9fe3d152
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 * sppptun_mod.c - modload support for PPP multiplexing tunnel driver.
31 #include <sys/types.h>
32 #include <sys/param.h>
33 #include <sys/stat.h>
34 #include <sys/systm.h>
35 #include <sys/socket.h>
36 #include <sys/stream.h>
37 #include <sys/stropts.h>
38 #include <sys/time.h>
39 #include <sys/conf.h>
40 #include <sys/kstat.h>
41 #include <sys/sunddi.h>
42 #include <net/sppptun.h>
43 #include <netinet/in.h>
45 #include "sppptun_mod.h"
48 * Descriptions for flags values in cb_flags field:
50 * D_MTQPAIR:
51 * An inner perimeter that spans the queue pair.
52 * D_MTOUTPERIM:
53 * An outer perimeter that spans over all queues in the module.
54 * D_MTOCEXCL:
55 * Open & close procedures are entered exclusively at outer perimeter.
56 * D_MTPUTSHARED:
57 * Entry to put procedures are done with SHARED (reader) acess
58 * and not EXCLUSIVE (writer) access.
60 * Therefore:
62 * 1. Open and close procedures are entered with EXCLUSIVE (writer)
63 * access at the inner perimeter, and with EXCLUSIVE (writer) access at
64 * the outer perimeter.
66 * 2. Put procedures are entered with SHARED (reader) access at the inner
67 * perimeter, and with SHARED (reader) access at the outer perimeter.
69 * 3. Service procedures are entered with EXCLUSIVE (writer) access at
70 * the inner perimeter, and with SHARED (reader) access at the
71 * outer perimeter.
73 * Do not attempt to modify these flags unless the entire corresponding
74 * driver code is changed to accomodate the newly represented MT-STREAMS
75 * flags. Doing so without making proper modifications to the driver code
76 * will severely impact the intended driver behavior, and thus may affect
77 * the system's stability and performance.
80 static int tun_attach(dev_info_t *, ddi_attach_cmd_t);
81 static int tun_detach(dev_info_t *, ddi_detach_cmd_t);
82 static int tun_info(dev_info_t *, ddi_info_cmd_t, void *, void **);
84 static dev_info_t *tun_dev_info;
86 DDI_DEFINE_STREAM_OPS(sppptun_ops, \
87 nulldev, nulldev, \
88 tun_attach, tun_detach, nodev, tun_info, \
89 D_NEW | D_MP | D_MTQPAIR | D_MTOUTPERIM | D_MTOCEXCL | D_MTPUTSHARED, \
90 &sppptun_tab, ddi_quiesce_not_supported);
93 * This is the loadable module wrapper.
95 #include <sys/modctl.h>
98 * Module linkage information for the kernel.
100 static struct fmodsw sppptun_fmodsw = {
101 PPP_TUN_NAME,
102 &sppptun_tab,
103 D_NEW | D_MP | D_MTQPAIR | D_MTOUTPERIM | D_MTOCEXCL | D_MTPUTSHARED
106 static struct modldrv modldrv = {
107 &mod_driverops,
108 (char *)sppptun_driver_description,
109 &sppptun_ops
112 static struct modlstrmod modlstrmod = {
113 &mod_strmodops,
114 (char *)sppptun_module_description,
115 &sppptun_fmodsw
118 static struct modlinkage modlinkage = {
119 MODREV_1,
120 (void *)&modlstrmod,
121 (void *)&modldrv,
122 NULL
126 _init(void)
128 int retv;
130 sppptun_init();
131 if ((retv = mod_install(&modlinkage)) == 0)
132 sppptun_tcl_init();
133 return (retv);
137 _fini(void)
139 int retv;
141 if ((retv = sppptun_tcl_fintest()) != 0)
142 return (retv);
143 retv = mod_remove(&modlinkage);
144 if (retv != 0)
145 return (retv);
146 sppptun_tcl_fini();
147 return (0);
151 _info(struct modinfo *modinfop)
153 return (mod_info(&modlinkage, modinfop));
157 * tun_attach()
159 * Description:
160 * Attach a PPP tunnel driver to the system.
162 static int
163 tun_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
165 if (cmd != DDI_ATTACH)
166 return (DDI_FAILURE);
167 if (ddi_create_minor_node(dip, PPP_TUN_NAME, S_IFCHR, 0, DDI_PSEUDO,
168 CLONE_DEV) == DDI_FAILURE) {
169 ddi_remove_minor_node(dip, NULL);
170 return (DDI_FAILURE);
172 tun_dev_info = dip;
173 return (DDI_SUCCESS);
177 * tun_detach()
179 * Description:
180 * Detach an interface to the system.
182 static int
183 tun_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
185 if (cmd != DDI_DETACH)
186 return (DDI_FAILURE);
187 tun_dev_info = NULL;
188 ddi_remove_minor_node(dip, NULL);
189 return (DDI_SUCCESS);
193 * tun_info()
195 * Description:
196 * Translate "dev_t" to a pointer to the associated "dev_info_t".
198 /* ARGSUSED */
199 static int
200 tun_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
201 void **result)
203 int rc;
205 switch (infocmd) {
206 case DDI_INFO_DEVT2DEVINFO:
207 if (tun_dev_info == NULL) {
208 rc = DDI_FAILURE;
209 } else {
210 *result = (void *)tun_dev_info;
211 rc = DDI_SUCCESS;
213 break;
214 case DDI_INFO_DEVT2INSTANCE:
215 *result = NULL;
216 rc = DDI_SUCCESS;
217 break;
218 default:
219 rc = DDI_FAILURE;
220 break;
222 return (rc);