1/* 2 * ppp_mod.c - modload support for PPP pseudo-device driver. 3 * 4 * Copyright (c) 1994 The Australian National University. 5 * All rights reserved. 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. This software is provided without any 10 * warranty, express or implied. The Australian National University 11 * makes no representations about the suitability of this software for 12 * any purpose. 13 * 14 * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY 15 * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 16 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 17 * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY 18 * OF SUCH DAMAGE. 19 * 20 * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, 21 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 22 * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 23 * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO 24 * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, 25 * OR MODIFICATIONS. 26 * 27 * $Id: ppp_mod.c,v 1.1.1.1 2008/10/15 03:30:13 james26_jang Exp $ 28 */ 29 30/* 31 * This file is used under Solaris 2. 32 */ 33 34#include <sys/types.h> 35#include <sys/param.h> 36#include <sys/stat.h> 37#include <sys/conf.h> 38#include <sys/modctl.h> 39#include <sys/sunddi.h> 40#include <sys/ksynch.h> 41 42#ifdef __STDC__ 43#define __P(x) x 44#else 45#define __P(x) () 46#endif 47 48static int ppp_identify __P((dev_info_t *)); 49static int ppp_attach __P((dev_info_t *, ddi_attach_cmd_t)); 50static int ppp_detach __P((dev_info_t *, ddi_detach_cmd_t)); 51static int ppp_devinfo __P((dev_info_t *, ddi_info_cmd_t, void *, void **)); 52 53extern struct streamtab pppinfo; 54extern krwlock_t ppp_lower_lock; 55 56static dev_info_t *ppp_dip; 57 58static struct cb_ops cb_ppp_ops = { 59 nulldev, nulldev, nodev, nodev, /* cb_open, ... */ 60 nodev, nodev, nodev, nodev, /* cb_dump, ... */ 61 nodev, nodev, nodev, nochpoll, /* cb_devmap, ... */ 62 ddi_prop_op, /* cb_prop_op */ 63 &pppinfo, /* cb_stream */ 64 D_NEW|D_MP|D_MTQPAIR|D_MTOUTPERIM|D_MTOCEXCL /* cb_flag */ 65}; 66 67static struct dev_ops ppp_ops = { 68 DEVO_REV, /* devo_rev */ 69 0, /* devo_refcnt */ 70 ppp_devinfo, /* devo_getinfo */ 71 ppp_identify, /* devo_identify */ 72 nulldev, /* devo_probe */ 73 ppp_attach, /* devo_attach */ 74 ppp_detach, /* devo_detach */ 75 nodev, /* devo_reset */ 76 &cb_ppp_ops, /* devo_cb_ops */ 77 NULL /* devo_bus_ops */ 78}; 79 80/* 81 * Module linkage information 82 */ 83 84static struct modldrv modldrv = { 85 &mod_driverops, /* says this is a pseudo driver */ 86 "PPP-2.3 multiplexing driver", 87 &ppp_ops /* driver ops */ 88}; 89 90static struct modlinkage modlinkage = { 91 MODREV_1, 92 (void *) &modldrv, 93 NULL 94}; 95 96int 97_init(void) 98{ 99 return mod_install(&modlinkage); 100} 101 102int 103_fini(void) 104{ 105 return mod_remove(&modlinkage); 106} 107 108int 109_info(mip) 110 struct modinfo *mip; 111{ 112 return mod_info(&modlinkage, mip); 113} 114 115static int 116ppp_identify(dip) 117 dev_info_t *dip; 118{ 119 return strcmp(ddi_get_name(dip), "ppp") == 0? DDI_IDENTIFIED: 120 DDI_NOT_IDENTIFIED; 121} 122 123static int 124ppp_attach(dip, cmd) 125 dev_info_t *dip; 126 ddi_attach_cmd_t cmd; 127{ 128 129 if (cmd != DDI_ATTACH) 130 return DDI_FAILURE; 131 if (ddi_create_minor_node(dip, "ppp", S_IFCHR, 0, DDI_PSEUDO, CLONE_DEV) 132 == DDI_FAILURE) { 133 ddi_remove_minor_node(dip, NULL); 134 return DDI_FAILURE; 135 } 136 rw_init(&ppp_lower_lock, NULL, RW_DRIVER, NULL); 137 return DDI_SUCCESS; 138} 139 140static int 141ppp_detach(dip, cmd) 142 dev_info_t *dip; 143 ddi_detach_cmd_t cmd; 144{ 145 rw_destroy(&ppp_lower_lock); 146 ddi_remove_minor_node(dip, NULL); 147 return DDI_SUCCESS; 148} 149 150static int 151ppp_devinfo(dip, cmd, arg, result) 152 dev_info_t *dip; 153 ddi_info_cmd_t cmd; 154 void *arg; 155 void **result; 156{ 157 int error; 158 159 error = DDI_SUCCESS; 160 switch (cmd) { 161 case DDI_INFO_DEVT2DEVINFO: 162 if (ppp_dip == NULL) 163 error = DDI_FAILURE; 164 else 165 *result = (void *) ppp_dip; 166 break; 167 case DDI_INFO_DEVT2INSTANCE: 168 *result = NULL; 169 break; 170 default: 171 error = DDI_FAILURE; 172 } 173 return error; 174} 175