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 /* 41 * Kernel TLI-like function to allocate memory for the various TLI 42 * primitives. 43 * 44 * Returns 0 on success or a positive error value. On success, ptr is 45 * set the structure required. 46 */ 47 48 #include <sys/param.h> 49 #include <sys/types.h> 50 #include <sys/user.h> 51 #include <sys/stream.h> 52 #include <sys/ioctl.h> 53 #include <sys/file.h> 54 #include <sys/stropts.h> 55 #include <sys/tihdr.h> 56 #include <sys/timod.h> 57 #include <sys/tiuser.h> 58 #include <sys/errno.h> 59 #include <sys/signal.h> 60 #include <sys/t_kuser.h> 61 #include <sys/kmem.h> 62 #include <sys/sysmacros.h> 63 64 static void _alloc_buf(struct netbuf *, t_scalar_t); 65 66 int 67 t_kalloc(TIUSER *tiptr, int struct_type, int fields, char **ptr) 68 { 69 union structptrs { 70 char *caddr; 71 struct t_bind *bind; 72 struct t_call *call; 73 struct t_discon *dis; 74 struct t_optmgmt *opt; 75 struct t_kunitdata *udata; 76 struct t_uderr *uderr; 77 struct t_info *info; 78 } p; 79 t_scalar_t dsize; 80 81 if (ptr == NULL) 82 return (EINVAL); 83 84 /* 85 * allocate appropriate structure and the specified 86 * fields within each structure. Initialize the 87 * 'buf' and 'maxlen' fields of each. 88 */ 89 switch (struct_type) { 90 case T_BIND: 91 p.bind = kmem_zalloc(sizeof (struct t_bind), KM_SLEEP); 92 if (fields & T_ADDR) 93 _alloc_buf(&p.bind->addr, tiptr->tp_info.addr); 94 *ptr = ((char *)p.bind); 95 return (0); 96 97 case T_CALL: 98 p.call = kmem_zalloc(sizeof (struct t_call), KM_SLEEP); 99 if (fields & T_ADDR) 100 _alloc_buf(&p.call->addr, tiptr->tp_info.addr); 101 if (fields & T_OPT) 102 _alloc_buf(&p.call->opt, tiptr->tp_info.options); 103 if (fields & T_UDATA) { 104 dsize = MAX(tiptr->tp_info.connect, 105 tiptr->tp_info.discon); 106 _alloc_buf(&p.call->opt, dsize); 107 } 108 *ptr = ((char *)p.call); 109 return (0); 110 111 case T_OPTMGMT: 112 p.opt = kmem_zalloc(sizeof (struct t_optmgmt), KM_SLEEP); 113 if (fields & T_OPT) 114 _alloc_buf(&p.opt->opt, tiptr->tp_info.options); 115 *ptr = ((char *)p.opt); 116 return (0); 117 118 case T_DIS: 119 p.dis = kmem_zalloc(sizeof (struct t_discon), KM_SLEEP); 120 if (fields & T_UDATA) 121 _alloc_buf(&p.dis->udata, tiptr->tp_info.discon); 122 *ptr = ((char *)p.dis); 123 return (0); 124 125 case T_UNITDATA: 126 p.udata = kmem_zalloc(sizeof (struct t_kunitdata), KM_SLEEP); 127 if (fields & T_ADDR) 128 _alloc_buf(&p.udata->addr, tiptr->tp_info.addr); 129 else 130 p.udata->addr.maxlen = p.udata->addr.len = 0; 131 132 if (fields & T_OPT) 133 _alloc_buf(&p.udata->opt, tiptr->tp_info.options); 134 else 135 p.udata->opt.maxlen = p.udata->opt.len = 0; 136 137 if (fields & T_UDATA) { 138 p.udata->udata.udata_mp = NULL; 139 p.udata->udata.buf = NULL; 140 p.udata->udata.maxlen = tiptr->tp_info.tsdu; 141 p.udata->udata.len = 0; 142 } else { 143 p.udata->udata.maxlen = p.udata->udata.len = 0; 144 } 145 *ptr = (char *)p.udata; 146 return (0); 147 148 case T_UDERROR: 149 p.uderr = kmem_zalloc(sizeof (struct t_uderr), KM_SLEEP); 150 if (fields & T_ADDR) 151 _alloc_buf(&p.uderr->addr, tiptr->tp_info.addr); 152 if (fields & T_OPT) 153 _alloc_buf(&p.uderr->opt, tiptr->tp_info.options); 154 *ptr = (char *)p.uderr; 155 return (0); 156 157 case T_INFO: 158 p.info = kmem_zalloc(sizeof (struct t_info), KM_SLEEP); 159 *ptr = (char *)p.info; 160 return (0); 161 162 default: 163 return (EINVAL); 164 } 165 } 166 167 168 static void 169 _alloc_buf(struct netbuf *buf, t_scalar_t n) 170 { 171 switch (n) { 172 case -1: 173 buf->buf = kmem_zalloc(1024, KM_SLEEP); 174 buf->maxlen = 1024; 175 buf->len = 0; 176 break; 177 178 case 0: 179 case -2: 180 buf->buf = NULL; 181 buf->maxlen = 0; 182 buf->len = 0; 183 break; 184 185 default: 186 buf->buf = kmem_zalloc(n, KM_SLEEP); 187 buf->maxlen = n; 188 buf->len = 0; 189 break; 190 } 191 } 192