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