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 * Free the specified kernel tli data structure.
44 *
45 * Returns:
46 * 0 on success or
47 * positive error code.
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/t_kuser.h>
62 #include <sys/kmem.h>
63
64
65 /*ARGSUSED*/
66 int
t_kfree(TIUSER * tiptr,char * ptr,int struct_type)67 t_kfree(TIUSER *tiptr, char *ptr, int struct_type)
68 {
69 union structptrs {
70 struct t_bind *bind;
71 struct t_call *call;
72 struct t_discon *dis;
73 struct t_optmgmt *opt;
74 struct t_kunitdata *udata;
75 struct t_uderr *uderr;
76 } p;
77 int error = 0;
78
79 /*
80 * Free all the buffers associated with the appropriate
81 * fields of each structure.
82 */
83
84 switch (struct_type) {
85 case T_BIND:
86 /* LINTED pointer alignment */
87 p.bind = (struct t_bind *)ptr;
88 if (p.bind->addr.buf != NULL)
89 kmem_free(p.bind->addr.buf, p.bind->addr.maxlen);
90 kmem_free(ptr, sizeof (struct t_bind));
91 break;
92
93 case T_CALL:
94 /* LINTED pointer alignment */
95 p.call = (struct t_call *)ptr;
96 if (p.call->addr.buf != NULL)
97 kmem_free(p.call->addr.buf, p.call->addr.maxlen);
98 if (p.call->opt.buf != NULL)
99 kmem_free(p.call->opt.buf, p.call->opt.maxlen);
100 if (p.call->udata.buf != NULL)
101 kmem_free(p.call->udata.buf, p.call->udata.maxlen);
102 kmem_free(ptr, sizeof (struct t_call));
103 break;
104
105 case T_OPTMGMT:
106 /* LINTED pointer alignment */
107 p.opt = (struct t_optmgmt *)ptr;
108 if (p.opt->opt.buf != NULL)
109 kmem_free(p.opt->opt.buf, p.opt->opt.maxlen);
110 kmem_free(ptr, sizeof (struct t_optmgmt));
111 break;
112
113 case T_DIS:
114 /* LINTED pointer alignment */
115 p.dis = (struct t_discon *)ptr;
116 if (p.dis->udata.buf != NULL)
117 kmem_free(p.dis->udata.buf, p.dis->udata.maxlen);
118 kmem_free(ptr, sizeof (struct t_discon));
119 break;
120
121 case T_UNITDATA:
122 /* LINTED pointer alignment */
123 p.udata = (struct t_kunitdata *)ptr;
124
125 if (p.udata->udata.udata_mp) {
126 KTLILOG(2, "t_kfree: freeing mblk_t %x, ",
127 p.udata->udata.udata_mp);
128 KTLILOG(2, "ref %d\n",
129 p.udata->udata.udata_mp->b_datap->db_ref);
130 freemsg(p.udata->udata.udata_mp);
131 }
132 if (p.udata->opt.buf != NULL)
133 kmem_free(p.udata->opt.buf, p.udata->opt.maxlen);
134 if (p.udata->addr.buf != NULL) {
135 KTLILOG(2, "t_kfree: freeing address %x, ",
136 p.udata->addr.buf);
137 KTLILOG(2, "len %d\n", p.udata->addr.maxlen);
138 kmem_free(p.udata->addr.buf, p.udata->addr.maxlen);
139 }
140 KTLILOG(2, "t_kfree: freeing t_kunitdata\n", 0);
141 kmem_free(ptr, sizeof (struct t_kunitdata));
142 break;
143
144 case T_UDERROR:
145 /* LINTED pointer alignment */
146 p.uderr = (struct t_uderr *)ptr;
147 if (p.uderr->addr.buf != NULL)
148 kmem_free(p.uderr->addr.buf, p.uderr->addr.maxlen);
149 if (p.uderr->opt.buf != NULL)
150 kmem_free(p.uderr->opt.buf, p.uderr->opt.maxlen);
151 kmem_free(ptr, sizeof (struct t_uderr));
152 break;
153
154 case T_INFO:
155 break;
156
157 default:
158 error = EINVAL;
159 break;
160 }
161
162 return (error);
163 }
164