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