sppp_mod.c revision 7656:2621e50fdf4a
1/* 2 * sppp_mod.c - modload support for PPP pseudo-device driver. 3 * 4 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 5 * Use is subject to license terms. 6 * 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. 10 * 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 17 * 18 * Copyright (c) 1994 The Australian National University. 19 * All rights reserved. 20 * 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. 27 * 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. 33 * 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. 40 * 41 * This driver is derived from the original SVR4 STREAMS PPP driver 42 * originally written by Paul Mackerras <paul.mackerras@cs.anu.edu.au>. 43 * 44 * Adi Masputra <adi.masputra@sun.com> rewrote and restructured the code 45 * for improved performance and scalability. 46 */ 47 48#define RCSID " $Id: sppp_mod.c,v 1.0 2000/05/08 10:53:28 masputra Exp $" 49 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> 59 60#include "s_common.h" 61#include "sppp.h" 62 63static int _mi_driver_attach(dev_info_t *, ddi_attach_cmd_t); 64static int _mi_driver_detach(dev_info_t *, ddi_detach_cmd_t); 65static int _mi_driver_info(dev_info_t *, ddi_info_cmd_t, void *, void **); 66 67/* 68 * Globals for PPP multiplexer module wrapper 69 */ 70extern const char sppp_module_description[]; 71static dev_info_t *_mi_dip; 72 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 */ 75 76static 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 */ 83}; 84 85static 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 */ 93}; 94 95static 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 */ 103}; 104 105static struct qinit sppp_lrinit = { 106 (int (*)())sppp_lrput, /* qi_putp */ 107 NULL, /* qi_srvp */ 108 NULL, /* qi_qopen */ 109 NULL, /* qi_qclose */ 110 NULL, /* qi_qadmin */ 111 &sppp_modinfo, /* qi_minfo */ 112 NULL /* qi_mstat */ 113}; 114 115static 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 */ 123}; 124 125static struct streamtab sppp_tab = { 126 &sppp_urinit, /* st_rdinit */ 127 &sppp_uwinit, /* st_wrinit */ 128 &sppp_lrinit, /* st_muxrinit */ 129 &sppp_lwinit /* st_muxwrinit */ 130}; 131 132/* 133 * Descriptions for flags values in cb_flags field: 134 * 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. 144 * 145 * Therefore: 146 * 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. 150 * 151 * 2. Put procedures are entered with SHARED (reader) access at the inner 152 * perimeter, and with SHARED (reader) access at the outer perimeter. 153 * 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. 157 * 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. 163 */ 164DDI_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); 169 170static struct modldrv modldrv = { 171 &mod_driverops, /* drv_modops */ 172 (char *)sppp_module_description, /* drv_linkinfo */ 173 &sppp_ops /* drv_dev_ops */ 174}; 175 176static 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 */ 180}; 181 182int 183_init(void) 184{ 185 return (mod_install(&modlinkage)); 186} 187 188int 189_fini(void) 190{ 191 return (mod_remove(&modlinkage)); 192} 193 194int 195_info(struct modinfo *modinfop) 196{ 197 return (mod_info(&modlinkage, modinfop)); 198} 199 200/* 201 * _mi_driver_attach() 202 * 203 * Description: 204 * Attach a point-to-point interface to the system. 205 */ 206static int 207_mi_driver_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 208{ 209 if (cmd != DDI_ATTACH) { 210 return (DDI_FAILURE); 211 } 212 if (ddi_create_minor_node(dip, PPP_DRV_NAME, S_IFCHR, 213 0, DDI_PSEUDO, CLONE_DEV) == DDI_FAILURE) { 214 ddi_remove_minor_node(dip, NULL); 215 return (DDI_FAILURE); 216 } 217 sppp_dlpi_pinfoinit(); 218 return (DDI_SUCCESS); 219} 220 221/* 222 * _mi_driver_detach() 223 * 224 * Description: 225 * Detach an interface to the system. 226 */ 227static int 228_mi_driver_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 229{ 230 if (cmd != DDI_DETACH) { 231 return (DDI_FAILURE); 232 } 233 ddi_remove_minor_node(dip, NULL); 234 return (DDI_SUCCESS); 235} 236 237/* 238 * _mi_driver_info() 239 * 240 * Description: 241 * Translate "dev_t" to a pointer to the associated "dev_info_t". 242 */ 243/* ARGSUSED */ 244static int 245_mi_driver_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, 246 void **result) 247{ 248 int rc; 249 250 switch (infocmd) { 251 case DDI_INFO_DEVT2DEVINFO: 252 if (_mi_dip == NULL) { 253 rc = DDI_FAILURE; 254 } else { 255 *result = (void *)_mi_dip; 256 rc = DDI_SUCCESS; 257 } 258 break; 259 case DDI_INFO_DEVT2INSTANCE: 260 *result = NULL; 261 rc = DDI_SUCCESS; 262 break; 263 default: 264 rc = DDI_FAILURE; 265 break; 266 } 267 return (rc); 268} 269