xref: /illumos-gate/usr/src/lib/libdiskmgt/common/bus.c (revision 7c478bd9)
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