1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1997 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 /* 31 * University Copyright- Copyright (c) 1982, 1986, 1988 32 * The Regents of the University of California 33 * All Rights Reserved 34 * 35 * University Acknowledgment- Portions of this document are derived from 36 * software developed by the University of California, Berkeley, and its 37 * contributors. 38 */ 39 40 #pragma ident "%Z%%M% %I% %E% SMI" 41 42 /* 43 * Kernel TLI-like function to allocate memory for the various TLI 44 * primitives. 45 * 46 * Returns 0 on success or a positive error value. On success, ptr is 47 * set the structure required. 48 */ 49 50 #include <sys/param.h> 51 #include <sys/types.h> 52 #include <sys/user.h> 53 #include <sys/stream.h> 54 #include <sys/ioctl.h> 55 #include <sys/file.h> 56 #include <sys/stropts.h> 57 #include <sys/tihdr.h> 58 #include <sys/timod.h> 59 #include <sys/tiuser.h> 60 #include <sys/errno.h> 61 #include <sys/signal.h> 62 #include <sys/t_kuser.h> 63 #include <sys/kmem.h> 64 #include <sys/sysmacros.h> 65 66 static void _alloc_buf(struct netbuf *, t_scalar_t); 67 68 int 69 t_kalloc(TIUSER *tiptr, int struct_type, int fields, char **ptr) 70 { 71 union structptrs { 72 char *caddr; 73 struct t_bind *bind; 74 struct t_call *call; 75 struct t_discon *dis; 76 struct t_optmgmt *opt; 77 struct t_kunitdata *udata; 78 struct t_uderr *uderr; 79 struct t_info *info; 80 } p; 81 t_scalar_t dsize; 82 83 if (ptr == NULL) 84 return (EINVAL); 85 86 /* 87 * allocate appropriate structure and the specified 88 * fields within each structure. Initialize the 89 * 'buf' and 'maxlen' fields of each. 90 */ 91 switch (struct_type) { 92 case T_BIND: 93 p.bind = kmem_zalloc(sizeof (struct t_bind), KM_SLEEP); 94 if (fields & T_ADDR) 95 _alloc_buf(&p.bind->addr, tiptr->tp_info.addr); 96 *ptr = ((char *)p.bind); 97 return (0); 98 99 case T_CALL: 100 p.call = kmem_zalloc(sizeof (struct t_call), KM_SLEEP); 101 if (fields & T_ADDR) 102 _alloc_buf(&p.call->addr, tiptr->tp_info.addr); 103 if (fields & T_OPT) 104 _alloc_buf(&p.call->opt, tiptr->tp_info.options); 105 if (fields & T_UDATA) { 106 dsize = MAX(tiptr->tp_info.connect, 107 tiptr->tp_info.discon); 108 _alloc_buf(&p.call->opt, dsize); 109 } 110 *ptr = ((char *)p.call); 111 return (0); 112 113 case T_OPTMGMT: 114 p.opt = kmem_zalloc(sizeof (struct t_optmgmt), KM_SLEEP); 115 if (fields & T_OPT) 116 _alloc_buf(&p.opt->opt, tiptr->tp_info.options); 117 *ptr = ((char *)p.opt); 118 return (0); 119 120 case T_DIS: 121 p.dis = kmem_zalloc(sizeof (struct t_discon), KM_SLEEP); 122 if (fields & T_UDATA) 123 _alloc_buf(&p.dis->udata, tiptr->tp_info.discon); 124 *ptr = ((char *)p.dis); 125 return (0); 126 127 case T_UNITDATA: 128 p.udata = kmem_zalloc(sizeof (struct t_kunitdata), KM_SLEEP); 129 if (fields & T_ADDR) 130 _alloc_buf(&p.udata->addr, tiptr->tp_info.addr); 131 else 132 p.udata->addr.maxlen = p.udata->addr.len = 0; 133 134 if (fields & T_OPT) 135 _alloc_buf(&p.udata->opt, tiptr->tp_info.options); 136 else 137 p.udata->opt.maxlen = p.udata->opt.len = 0; 138 139 if (fields & T_UDATA) { 140 p.udata->udata.udata_mp = NULL; 141 p.udata->udata.buf = NULL; 142 p.udata->udata.maxlen = tiptr->tp_info.tsdu; 143 p.udata->udata.len = 0; 144 } else { 145 p.udata->udata.maxlen = p.udata->udata.len = 0; 146 } 147 *ptr = (char *)p.udata; 148 return (0); 149 150 case T_UDERROR: 151 p.uderr = kmem_zalloc(sizeof (struct t_uderr), KM_SLEEP); 152 if (fields & T_ADDR) 153 _alloc_buf(&p.uderr->addr, tiptr->tp_info.addr); 154 if (fields & T_OPT) 155 _alloc_buf(&p.uderr->opt, tiptr->tp_info.options); 156 *ptr = (char *)p.uderr; 157 return (0); 158 159 case T_INFO: 160 p.info = kmem_zalloc(sizeof (struct t_info), KM_SLEEP); 161 *ptr = (char *)p.info; 162 return (0); 163 164 default: 165 return (EINVAL); 166 } 167 } 168 169 170 static void 171 _alloc_buf(struct netbuf *buf, t_scalar_t n) 172 { 173 switch (n) { 174 case -1: 175 buf->buf = kmem_zalloc(1024, KM_SLEEP); 176 buf->maxlen = 1024; 177 buf->len = 0; 178 break; 179 180 case 0: 181 case -2: 182 buf->buf = NULL; 183 buf->maxlen = 0; 184 buf->len = 0; 185 break; 186 187 default: 188 buf->buf = kmem_zalloc(n, KM_SLEEP); 189 buf->maxlen = n; 190 buf->len = 0; 191 break; 192 } 193 } 194