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]
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>
34 #include <sys/systm.h>
35 #include <sys/socket.h>
36 #include <sys/stream.h>
37 #include <sys/stropts.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:
51 * An inner perimeter that spans the queue pair.
53 * An outer perimeter that spans over all queues in the module.
55 * Open & close procedures are entered exclusively at outer perimeter.
57 * Entry to put procedures are done with SHARED (reader) acess
58 * and not EXCLUSIVE (writer) access.
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
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
, \
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
= {
103 D_NEW
| D_MP
| D_MTQPAIR
| D_MTOUTPERIM
| D_MTOCEXCL
| D_MTPUTSHARED
106 static struct modldrv modldrv
= {
108 (char *)sppptun_driver_description
,
112 static struct modlstrmod modlstrmod
= {
114 (char *)sppptun_module_description
,
118 static struct modlinkage modlinkage
= {
131 if ((retv
= mod_install(&modlinkage
)) == 0)
141 if ((retv
= sppptun_tcl_fintest()) != 0)
143 retv
= mod_remove(&modlinkage
);
151 _info(struct modinfo
*modinfop
)
153 return (mod_info(&modlinkage
, modinfop
));
160 * Attach a PPP tunnel driver to the system.
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
);
173 return (DDI_SUCCESS
);
180 * Detach an interface to the system.
183 tun_detach(dev_info_t
*dip
, ddi_detach_cmd_t cmd
)
185 if (cmd
!= DDI_DETACH
)
186 return (DDI_FAILURE
);
188 ddi_remove_minor_node(dip
, NULL
);
189 return (DDI_SUCCESS
);
196 * Translate "dev_t" to a pointer to the associated "dev_info_t".
200 tun_info(dev_info_t
*dip
, ddi_info_cmd_t infocmd
, void *arg
,
206 case DDI_INFO_DEVT2DEVINFO
:
207 if (tun_dev_info
== NULL
) {
210 *result
= (void *)tun_dev_info
;
214 case DDI_INFO_DEVT2INSTANCE
: