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