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 ** 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 * 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 * 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 ** 126 bus_get_descriptors(int filter[], int *errp) 127 { 128 return (cache_get_descriptors(DM_BUS, errp)); 129 } 130 131 char * 132 bus_get_name(descriptor_t *desc) 133 { 134 return (desc->p.bus->name); 135 } 136 137 /* ARGSUSED */ 138 nvlist_t * 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 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 ** 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 ** 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