Merge remote-tracking branch 'origin/master'
[unleashed/lotheac.git] / usr / src / uts / common / io / ppp / sppp / sppp_mod.c
blob168cf17f49b765d6063b97e3828bbb7416aa85d9
1 /*
2 * sppp_mod.c - modload support for PPP pseudo-device driver.
4 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
5 * Use is subject to license terms.
7 * Permission to use, copy, modify, and distribute this software and its
8 * documentation is hereby granted, provided that the above copyright
9 * notice appears in all copies.
11 * SUN MAKES NO REPRESENTATION OR WARRANTIES ABOUT THE SUITABILITY OF
12 * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
13 * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
14 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
15 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
16 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES
18 * Copyright (c) 1994 The Australian National University.
19 * All rights reserved.
21 * Permission to use, copy, modify, and distribute this software and its
22 * documentation is hereby granted, provided that the above copyright
23 * notice appears in all copies. This software is provided without any
24 * warranty, express or implied. The Australian National University
25 * makes no representations about the suitability of this software for
26 * any purpose.
28 * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
29 * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
30 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
31 * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY
32 * OF SUCH DAMAGE.
34 * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
35 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
36 * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
37 * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
38 * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
39 * OR MODIFICATIONS.
41 * This driver is derived from the original SVR4 STREAMS PPP driver
42 * originally written by Paul Mackerras <paul.mackerras@cs.anu.edu.au>.
44 * Adi Masputra <adi.masputra@sun.com> rewrote and restructured the code
45 * for improved performance and scalability.
48 #define RCSID " $Id: sppp_mod.c,v 1.0 2000/05/08 10:53:28 masputra Exp $"
50 #include <sys/types.h>
51 #include <sys/systm.h>
52 #include <sys/ddi.h>
53 #include <sys/conf.h>
54 #include <sys/sunddi.h>
55 #include <sys/stat.h>
56 #include <sys/kstat.h>
57 #include <net/pppio.h>
58 #include <sys/modctl.h>
60 #include "s_common.h"
61 #include "sppp.h"
63 static int _mi_driver_attach(dev_info_t *, ddi_attach_cmd_t);
64 static int _mi_driver_detach(dev_info_t *, ddi_detach_cmd_t);
65 static int _mi_driver_info(dev_info_t *, ddi_info_cmd_t, void *, void **);
68 * Globals for PPP multiplexer module wrapper
70 extern const char sppp_module_description[];
71 static dev_info_t *_mi_dip;
73 #define PPP_MI_HIWAT (PPP_MTU * 16) /* XXX find more meaningful value */
74 #define PPP_MI_LOWAT (PPP_MTU * 14) /* XXX find more meaningful value */
76 static struct module_info sppp_modinfo = {
77 PPP_MOD_ID, /* mi_idnum */
78 PPP_DRV_NAME, /* mi_idname */
79 0, /* mi_minpsz */
80 PPP_MAXMTU, /* mi_maxpsz */
81 PPP_MI_HIWAT, /* mi_hiwat */
82 PPP_MI_LOWAT /* mi_lowat */
85 static struct qinit sppp_urinit = {
86 NULL, /* qi_putp */
87 NULL, /* qi_srvp */
88 sppp_open, /* qi_qopen */
89 sppp_close, /* qi_qclose */
90 NULL, /* qi_qadmin */
91 &sppp_modinfo, /* qi_minfo */
92 NULL /* qi_mstat */
95 static struct qinit sppp_uwinit = {
96 (int (*)())sppp_uwput, /* qi_putp */
97 (int (*)())sppp_uwsrv, /* qi_srvp */
98 NULL, /* qi_qopen */
99 NULL, /* qi_qclose */
100 NULL, /* qi_qadmin */
101 &sppp_modinfo, /* qi_minfo */
102 NULL /* qi_mstat */
105 static struct qinit sppp_lrinit = {
106 (int (*)())sppp_lrput, /* qi_putp */
107 (int (*)())sppp_lrsrv, /* qi_srvp */
108 NULL, /* qi_qopen */
109 NULL, /* qi_qclose */
110 NULL, /* qi_qadmin */
111 &sppp_modinfo, /* qi_minfo */
112 NULL /* qi_mstat */
115 static struct qinit sppp_lwinit = {
116 NULL, /* qi_putp */
117 (int (*)())sppp_lwsrv, /* qi_srvp */
118 NULL, /* qi_qopen */
119 NULL, /* qi_qclose */
120 NULL, /* qi_qadmin */
121 &sppp_modinfo, /* qi_minfo */
122 NULL /* qi_mstat */
125 static struct streamtab sppp_tab = {
126 &sppp_urinit, /* st_rdinit */
127 &sppp_uwinit, /* st_wrinit */
128 &sppp_lrinit, /* st_muxrinit */
129 &sppp_lwinit /* st_muxwrinit */
133 * Descriptions for flags values in cb_flags field:
135 * D_MTQPAIR:
136 * An inner perimeter that spans the queue pair.
137 * D_MTOUTPERIM:
138 * An outer perimeter that spans over all queues in the module.
139 * D_MTOCEXCL:
140 * Open & close procedures are entered exclusively at outer perimeter.
141 * D_MTPUTSHARED:
142 * Entry to put procedures are done with SHARED (reader) acess
143 * and not EXCLUSIVE (writer) access.
145 * Therefore:
147 * 1. Open and close procedures are entered with EXCLUSIVE (writer)
148 * access at the inner perimeter, and with EXCLUSIVE (writer) access at
149 * the outer perimeter.
151 * 2. Put procedures are entered with SHARED (reader) access at the inner
152 * perimeter, and with SHARED (reader) access at the outer perimeter.
154 * 3. Service procedures are entered with EXCLUSIVE (writer) access at
155 * the inner perimeter, and with SHARED (reader) access at the
156 * outer perimeter.
158 * Do not attempt to modify these flags unless the entire corresponding
159 * driver code is changed to accomodate the newly represented MT-STREAMS
160 * flags. Doing so without making proper modifications to the driver code
161 * will severely impact the intended driver behavior, and thus may affect
162 * the system's stability and performance.
164 DDI_DEFINE_STREAM_OPS(sppp_ops, \
165 nulldev, nulldev, \
166 _mi_driver_attach, _mi_driver_detach, nodev, _mi_driver_info, \
167 D_NEW | D_MP | D_MTQPAIR | D_MTOUTPERIM | D_MTOCEXCL | D_MTPUTSHARED, \
168 &sppp_tab, ddi_quiesce_not_supported);
170 static struct modldrv modldrv = {
171 &mod_driverops, /* drv_modops */
172 (char *)sppp_module_description, /* drv_linkinfo */
173 &sppp_ops /* drv_dev_ops */
176 static struct modlinkage modlinkage = {
177 MODREV_1, /* ml_rev, has to be MODREV_1 */
178 &modldrv, /* ml_linkage, NULL-terminated list */
179 NULL /* of linkage structures */
183 _init(void)
185 return (mod_install(&modlinkage));
189 _fini(void)
191 return (mod_remove(&modlinkage));
195 _info(struct modinfo *modinfop)
197 return (mod_info(&modlinkage, modinfop));
201 * _mi_driver_attach()
203 * Description:
204 * Attach a point-to-point interface to the system.
206 static int
207 _mi_driver_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
209 if (cmd != DDI_ATTACH) {
210 return (DDI_FAILURE);
212 _mi_dip = dip;
213 if (ddi_create_minor_node(dip, PPP_DRV_NAME, S_IFCHR,
214 0, DDI_PSEUDO, CLONE_DEV) == DDI_FAILURE) {
215 ddi_remove_minor_node(dip, NULL);
216 return (DDI_FAILURE);
218 sppp_dlpi_pinfoinit();
219 return (DDI_SUCCESS);
223 * _mi_driver_detach()
225 * Description:
226 * Detach an interface to the system.
228 static int
229 _mi_driver_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
231 if (cmd != DDI_DETACH) {
232 return (DDI_FAILURE);
234 ddi_remove_minor_node(dip, NULL);
235 _mi_dip = NULL;
236 return (DDI_SUCCESS);
240 * _mi_driver_info()
242 * Description:
243 * Translate "dev_t" to a pointer to the associated "dev_info_t".
245 /* ARGSUSED */
246 static int
247 _mi_driver_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
248 void **result)
250 int rc;
252 switch (infocmd) {
253 case DDI_INFO_DEVT2DEVINFO:
254 if (_mi_dip == NULL) {
255 rc = DDI_FAILURE;
256 } else {
257 *result = (void *)_mi_dip;
258 rc = DDI_SUCCESS;
260 break;
261 case DDI_INFO_DEVT2INSTANCE:
262 *result = NULL;
263 rc = DDI_SUCCESS;
264 break;
265 default:
266 rc = DDI_FAILURE;
267 break;
269 return (rc);