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 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 #include <fcntl.h>
30 #include <libdevinfo.h>
31 #include <stdlib.h>
32 #include <sys/sunddi.h>
33 #include <sys/types.h>
34 #include <sys/scsi/conf/autoconf.h>
35
36 #include "libdiskmgt.h"
37 #include "disks_private.h"
38
39 static descriptor_t **get_assoc_buses(descriptor_t *desc, int *errp);
40 static descriptor_t **get_assoc_controllers(descriptor_t *desc, int *errp);
41
42 descriptor_t **
bus_get_assoc_descriptors(descriptor_t * desc,dm_desc_type_t type,int * errp)43 bus_get_assoc_descriptors(descriptor_t *desc, dm_desc_type_t type, int *errp)
44 {
45 switch (type) {
46 case DM_BUS:
47 return (get_assoc_buses(desc, errp));
48 case DM_CONTROLLER:
49 return (get_assoc_controllers(desc, errp));
50 }
51
52 *errp = EINVAL;
53 return (NULL);
54 }
55
56 nvlist_t *
bus_get_attributes(descriptor_t * dp,int * errp)57 bus_get_attributes(descriptor_t *dp, int *errp)
58 {
59 bus_t *bp;
60 nvlist_t *attrs;
61
62 if (nvlist_alloc(&attrs, NVATTRS, 0) != 0) {
63 *errp = ENOMEM;
64 return (NULL);
65 }
66
67 bp = dp->p.bus;
68
69 if (nvlist_add_string(attrs, DM_BTYPE, bp->btype) != 0) {
70 nvlist_free(attrs);
71 *errp = ENOMEM;
72 return (NULL);
73 }
74
75 if (bp->freq != 0) {
76 if (nvlist_add_uint32(attrs, DM_CLOCK, bp->freq) != 0) {
77 nvlist_free(attrs);
78 *errp = ENOMEM;
79 return (NULL);
80 }
81 }
82
83 if (bp->pname != NULL) {
84 if (nvlist_add_string(attrs, DM_PNAME, bp->pname) != 0) {
85 nvlist_free(attrs);
86 *errp = ENOMEM;
87 return (NULL);
88 }
89 }
90
91 *errp = 0;
92 return (attrs);
93 }
94
95 descriptor_t *
bus_get_descriptor_by_name(char * name,int * errp)96 bus_get_descriptor_by_name(char *name, int *errp)
97 {
98 descriptor_t **buses;
99 int i;
100 descriptor_t *bus = NULL;
101
102 buses = cache_get_descriptors(DM_BUS, errp);
103 if (*errp != 0) {
104 return (NULL);
105 }
106
107 for (i = 0; buses[i]; i++) {
108 if (libdiskmgt_str_eq(name, buses[i]->p.bus->name)) {
109 bus = buses[i];
110 } else {
111 /* clean up the unused descriptors */
112 cache_free_descriptor(buses[i]);
113 }
114 }
115 free(buses);
116
117 if (bus == NULL) {
118 *errp = ENODEV;
119 }
120
121 return (bus);
122 }
123
124 /* ARGSUSED */
125 descriptor_t **
bus_get_descriptors(int filter[],int * errp)126 bus_get_descriptors(int filter[], int *errp)
127 {
128 return (cache_get_descriptors(DM_BUS, errp));
129 }
130
131 char *
bus_get_name(descriptor_t * desc)132 bus_get_name(descriptor_t *desc)
133 {
134 return (desc->p.bus->name);
135 }
136
137 /* ARGSUSED */
138 nvlist_t *
bus_get_stats(descriptor_t * dp,int stat_type,int * errp)139 bus_get_stats(descriptor_t *dp, int stat_type, int *errp)
140 {
141 /* There are no stat types defined for controllers */
142 *errp = EINVAL;
143 return (NULL);
144 }
145
146 int
bus_make_descriptors()147 bus_make_descriptors()
148 {
149 int error;
150 bus_t *bp;
151
152 bp = cache_get_buslist();
153 while (bp != NULL) {
154 cache_load_desc(DM_BUS, bp, NULL, NULL, &error);
155 if (error != 0) {
156 return (error);
157 }
158 bp = bp->next;
159 }
160
161 return (0);
162 }
163
164 static descriptor_t **
get_assoc_buses(descriptor_t * desc,int * errp)165 get_assoc_buses(descriptor_t *desc, int *errp)
166 {
167 bus_t *bp;
168 char *name;
169 descriptor_t **allbuses;
170 descriptor_t **buses;
171 int cnt;
172 int i;
173 int pos;
174
175 bp = desc->p.bus;
176 name = bp->name;
177
178 allbuses = cache_get_descriptors(DM_BUS, errp);
179 if (*errp != 0) {
180 return (NULL);
181 }
182
183 /* Count how many we have (we overcount, but thats ok). */
184 for (cnt = 0; allbuses[cnt]; cnt++);
185
186 /* make the snapshot */
187 buses = (descriptor_t **)calloc(cnt + 1, sizeof (descriptor_t *));
188 if (buses == NULL) {
189 *errp = ENOMEM;
190 cache_free_descriptors(allbuses);
191 return (NULL);
192 }
193
194 /*
195 * Get this buses parent bus and get the buses that I am the parent of.
196 */
197 pos = 0;
198 for (i = 0; allbuses[i]; i++) {
199 if (libdiskmgt_str_eq(name, allbuses[i]->p.bus->pname)) {
200 buses[pos++] = allbuses[i];
201 } else if (bp->pname != NULL &&
202 libdiskmgt_str_eq(bp->pname, allbuses[i]->p.bus->name)) {
203
204 buses[pos++] = allbuses[i];
205 } else {
206 /* clean up the unused descriptor */
207 cache_free_descriptor(allbuses[i]);
208 }
209 }
210 buses[pos] = NULL;
211
212 free(allbuses);
213
214 *errp = 0;
215 return (buses);
216 }
217
218 static descriptor_t **
get_assoc_controllers(descriptor_t * desc,int * errp)219 get_assoc_controllers(descriptor_t *desc, int *errp)
220 {
221 bus_t *bp;
222 descriptor_t **controllers;
223 int cnt;
224 int i;
225
226 bp = desc->p.bus;
227
228 /* Count how many we have. */
229 for (cnt = 0; bp->controllers[cnt]; cnt++);
230
231 /* make the snapshot */
232 controllers = (descriptor_t **)calloc(cnt + 1, sizeof (descriptor_t *));
233 if (controllers == NULL) {
234 *errp = ENOMEM;
235 return (NULL);
236 }
237
238 for (i = 0; bp->controllers[i]; i++) {
239 controllers[i] = cache_get_desc(DM_CONTROLLER, bp->controllers[i],
240 NULL, NULL, errp);
241 if (*errp != 0) {
242 cache_free_descriptors(controllers);
243 return (NULL);
244 }
245 }
246 controllers[i] = NULL;
247
248 *errp = 0;
249 return (controllers);
250 }
251