Print this page
11416 smbios_info_slot_peers() gets NULL check wrong
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/common/smbios/smb_info.c
+++ new/usr/src/common/smbios/smb_info.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved.
24 - * Copyright (c) 2018, Joyent, Inc.
24 + * Copyright 2019 Joyent, Inc.
25 25 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
26 26 * Use is subject to license terms.
27 27 */
28 28
29 29 /*
30 30 * SMBIOS Information Routines
31 31 *
32 32 * The routines in this file are used to convert from the SMBIOS data format to
33 33 * a more reasonable and stable set of structures offered as part of our ABI.
34 34 * These functions take the general form:
35 35 *
36 36 * stp = smb_lookup_type(shp, foo);
37 37 * smb_foo_t foo;
38 38 *
39 39 * smb_info_bcopy(stp->smbst_hdr, &foo, sizeof (foo));
40 40 * bzero(caller's struct);
41 41 *
42 42 * copy/convert foo members into caller's struct
43 43 *
44 44 * We copy the internal structure on to an automatic variable so as to avoid
45 45 * checks everywhere for structures that the BIOS has improperly truncated, and
46 46 * also to automatically handle the case of a structure that has been extended.
47 47 * When necessary, this code can use smb_gteq() to determine whether the SMBIOS
48 48 * data is of a particular revision that is supposed to contain a new field.
49 49 *
50 50 * Note, when trying to bzero the caller's struct you have to be careful about
51 51 * versions. One can only bzero the initial version that existed in illumos. In
52 52 * other words, if someone passes an older library handle that doesn't support a
53 53 * version you cannot assume that their structures have those additional members
54 54 * in them. Instead, a 'base' version is introduced for such types that have
55 55 * differences and instead we only bzero out the base version and then handle
56 56 * the additional members. In general, because all additional members will be
57 57 * assigned, there's no reason to zero them out unless they are arrays that
58 58 * won't be entirely filled in.
59 59 *
60 60 * Due to history, anything added after the update from version 2.4, in other
61 61 * words additions from or after '5094 Update libsmbios with recent items'
62 62 * (4e901881) is currently being used for this. While we don't allow software
63 63 * compiling against this to get an older form, this was the first major update
64 64 * and a good starting point for us to enforce this behavior which is useful for
65 65 * moving forward to making this more public.
66 66 */
67 67
68 68 #include <sys/smbios_impl.h>
69 69 #include <sys/byteorder.h>
70 70 #include <sys/debug.h>
71 71
72 72 #ifdef _KERNEL
73 73 #include <sys/sunddi.h>
74 74 #else
75 75 #include <fcntl.h>
76 76 #include <unistd.h>
77 77 #include <string.h>
78 78 #endif
79 79
80 80 /*
81 81 * A large number of SMBIOS structures contain a set of common strings used to
82 82 * describe a h/w component's serial number, manufacturer, etc. These fields
83 83 * helpfully have different names and offsets and sometimes aren't consistent.
84 84 * To simplify life for our clients, we factor these common things out into
85 85 * smbios_info_t, which can be retrieved for any structure. The following
86 86 * table describes the mapping from a given structure to the smbios_info_t.
87 87 * Multiple SMBIOS stuctures' contained objects are also handled here.
88 88 */
89 89 static const struct smb_infospec {
90 90 uint8_t is_type; /* structure type */
91 91 uint8_t is_manu; /* manufacturer offset */
92 92 uint8_t is_product; /* product name offset */
93 93 uint8_t is_version; /* version offset */
94 94 uint8_t is_serial; /* serial number offset */
95 95 uint8_t is_asset; /* asset tag offset */
96 96 uint8_t is_location; /* location string offset */
97 97 uint8_t is_part; /* part number offset */
98 98 uint8_t is_contc; /* contained count */
99 99 uint8_t is_contsz; /* contained size */
100 100 uint8_t is_contv; /* contained objects */
101 101 } _smb_infospecs[] = {
102 102 { SMB_TYPE_SYSTEM,
103 103 offsetof(smb_system_t, smbsi_manufacturer),
104 104 offsetof(smb_system_t, smbsi_product),
105 105 offsetof(smb_system_t, smbsi_version),
106 106 offsetof(smb_system_t, smbsi_serial),
107 107 0,
108 108 0,
109 109 0,
110 110 0,
111 111 0,
112 112 0 },
113 113 { SMB_TYPE_BASEBOARD,
114 114 offsetof(smb_bboard_t, smbbb_manufacturer),
115 115 offsetof(smb_bboard_t, smbbb_product),
116 116 offsetof(smb_bboard_t, smbbb_version),
117 117 offsetof(smb_bboard_t, smbbb_serial),
118 118 offsetof(smb_bboard_t, smbbb_asset),
119 119 offsetof(smb_bboard_t, smbbb_location),
120 120 0,
121 121 offsetof(smb_bboard_t, smbbb_cn),
122 122 SMB_CONT_WORD,
123 123 offsetof(smb_bboard_t, smbbb_cv) },
124 124 { SMB_TYPE_CHASSIS,
125 125 offsetof(smb_chassis_t, smbch_manufacturer),
126 126 0,
127 127 offsetof(smb_chassis_t, smbch_version),
128 128 offsetof(smb_chassis_t, smbch_serial),
129 129 offsetof(smb_chassis_t, smbch_asset),
130 130 0,
131 131 0,
132 132 offsetof(smb_chassis_t, smbch_cn),
133 133 SMB_CONT_BYTE,
134 134 offsetof(smb_chassis_t, smbch_cv) },
135 135 { SMB_TYPE_PROCESSOR,
136 136 offsetof(smb_processor_t, smbpr_manufacturer),
137 137 0,
138 138 offsetof(smb_processor_t, smbpr_version),
139 139 offsetof(smb_processor_t, smbpr_serial),
140 140 offsetof(smb_processor_t, smbpr_asset),
141 141 offsetof(smb_processor_t, smbpr_socket),
142 142 offsetof(smb_processor_t, smbpr_part),
143 143 0,
144 144 0,
145 145 0 },
146 146 { SMB_TYPE_CACHE,
147 147 0,
148 148 0,
149 149 0,
150 150 0,
151 151 0,
152 152 offsetof(smb_cache_t, smbca_socket),
153 153 0,
154 154 0,
155 155 0,
156 156 0 },
157 157 { SMB_TYPE_PORT,
158 158 0,
159 159 0,
160 160 0,
161 161 0,
162 162 0,
163 163 offsetof(smb_port_t, smbpo_iref),
164 164 0,
165 165 0,
166 166 0,
167 167 0 },
168 168 { SMB_TYPE_SLOT,
169 169 0,
170 170 0,
171 171 0,
172 172 0,
173 173 0,
174 174 offsetof(smb_slot_t, smbsl_name),
175 175 0,
176 176 0,
177 177 0,
178 178 0 },
179 179 { SMB_TYPE_MEMDEVICE,
180 180 offsetof(smb_memdevice_t, smbmdev_manufacturer),
181 181 0,
182 182 0,
183 183 offsetof(smb_memdevice_t, smbmdev_serial),
184 184 offsetof(smb_memdevice_t, smbmdev_asset),
185 185 offsetof(smb_memdevice_t, smbmdev_dloc),
186 186 offsetof(smb_memdevice_t, smbmdev_part),
187 187 0,
188 188 0,
189 189 0 },
190 190 { SMB_TYPE_POWERSUP,
191 191 offsetof(smb_powersup_t, smbpsup_manufacturer),
192 192 offsetof(smb_powersup_t, smbpsup_devname),
193 193 offsetof(smb_powersup_t, smbpsup_rev),
194 194 offsetof(smb_powersup_t, smbpsup_serial),
195 195 offsetof(smb_powersup_t, smbpsup_asset),
196 196 offsetof(smb_powersup_t, smbpsup_loc),
197 197 offsetof(smb_powersup_t, smbpsup_part),
198 198 0,
199 199 0,
200 200 0 },
201 201 { SMB_TYPE_EOT }
202 202 };
203 203
204 204 static const char *
205 205 smb_info_strptr(const smb_struct_t *stp, uint8_t off, int *n)
206 206 {
207 207 const uint8_t *sp = (const uint8_t *)(uintptr_t)stp->smbst_hdr;
208 208
209 209 if (off != 0 && sp + off < stp->smbst_end) {
210 210 (*n)++; /* indicate success for caller */
211 211 return (smb_strptr(stp, sp[off]));
212 212 }
213 213
214 214 return (smb_strptr(stp, 0));
215 215 }
216 216
217 217 static void
218 218 smb_info_bcopy(const smb_header_t *hp, void *dst, size_t dstlen)
219 219 {
220 220 if (dstlen > hp->smbh_len) {
221 221 bcopy(hp, dst, hp->smbh_len);
222 222 bzero((char *)dst + hp->smbh_len, dstlen - hp->smbh_len);
223 223 } else
224 224 bcopy(hp, dst, dstlen);
225 225 }
226 226
227 227 smbios_entry_point_t
228 228 smbios_info_smbios(smbios_hdl_t *shp, smbios_entry_t *ep)
229 229 {
230 230 bcopy(&shp->sh_ent, ep, sizeof (smbios_entry_t));
231 231 return (shp->sh_ent_type);
232 232 }
233 233
234 234 void
235 235 smbios_info_smbios_version(smbios_hdl_t *shp, smbios_version_t *v)
236 236 {
237 237 v->smbv_major = SMB_MAJOR(shp->sh_smbvers);
238 238 v->smbv_minor = SMB_MINOR(shp->sh_smbvers);
239 239 }
240 240
241 241 #ifndef _KERNEL
242 242 static char smbios_product_override[256];
243 243 static boolean_t smbios_product_checked;
244 244 #endif
245 245
246 246 int
247 247 smbios_info_common(smbios_hdl_t *shp, id_t id, smbios_info_t *ip)
248 248 {
249 249 const smb_struct_t *stp = smb_lookup_id(shp, id);
250 250 const struct smb_infospec *isp;
251 251 int n = 0;
252 252
253 253 if (stp == NULL)
254 254 return (-1); /* errno is set for us */
255 255
256 256 for (isp = _smb_infospecs; isp->is_type != SMB_TYPE_EOT; isp++) {
257 257 if (isp->is_type == stp->smbst_hdr->smbh_type)
258 258 break;
259 259 }
260 260
261 261 ip->smbi_manufacturer = smb_info_strptr(stp, isp->is_manu, &n);
262 262 ip->smbi_product = smb_info_strptr(stp, isp->is_product, &n);
263 263 ip->smbi_version = smb_info_strptr(stp, isp->is_version, &n);
264 264 ip->smbi_serial = smb_info_strptr(stp, isp->is_serial, &n);
265 265 ip->smbi_asset = smb_info_strptr(stp, isp->is_asset, &n);
266 266 ip->smbi_location = smb_info_strptr(stp, isp->is_location, &n);
267 267 ip->smbi_part = smb_info_strptr(stp, isp->is_part, &n);
268 268
269 269 /*
270 270 * This private file allows developers to experiment with reporting
271 271 * different platform strings from SMBIOS. It is not a supported
272 272 * mechanism in the long term, and does not work in the kernel.
273 273 */
274 274 #ifndef _KERNEL
275 275 if (isp->is_type == SMB_TYPE_SYSTEM) {
276 276 if (!smbios_product_checked) {
277 277 int fd = open("/etc/smbios_product", O_RDONLY);
278 278 if (fd >= 0) {
279 279 (void) read(fd, smbios_product_override,
280 280 sizeof (smbios_product_override) - 1);
281 281 (void) close(fd);
282 282 }
283 283 smbios_product_checked = B_TRUE;
284 284 }
285 285
286 286 if (smbios_product_override[0] != '\0')
287 287 ip->smbi_product = smbios_product_override;
288 288 }
289 289 #endif
290 290
291 291 /*
292 292 * If we have a port with an empty internal reference designator string
293 293 * try using the external reference designator string instead.
294 294 */
295 295 if (isp->is_type == SMB_TYPE_PORT && ip->smbi_location[0] == '\0') {
296 296 ip->smbi_location = smb_info_strptr(stp,
297 297 offsetof(smb_port_t, smbpo_eref), &n);
298 298 }
299 299
300 300 return (n ? 0 : smb_set_errno(shp, ESMB_NOINFO));
301 301 }
302 302
303 303 /*
304 304 * Returns the actual number of contained objects.
305 305 *
306 306 * idc - number of contained objects
307 307 * idv - returned array of contained objects
308 308 */
309 309 int
310 310 smbios_info_contains(smbios_hdl_t *shp, id_t id, uint_t idc, id_t *idv)
311 311 {
312 312 const smb_struct_t *stp = smb_lookup_id(shp, id);
313 313 const struct smb_infospec *isp;
314 314 id_t *cp;
315 315 uint_t size;
316 316 uint8_t cnt;
317 317 int i, n;
318 318
319 319 if (stp == NULL) {
320 320 return (-1); /* errno is set for us */
321 321 }
322 322
323 323 for (isp = _smb_infospecs; isp->is_type != SMB_TYPE_EOT; isp++) {
324 324 if (isp->is_type == stp->smbst_hdr->smbh_type)
325 325 break;
326 326 }
327 327 if (isp->is_type == SMB_TYPE_EOT)
328 328 return (smb_set_errno(shp, ESMB_TYPE));
329 329
330 330 size = isp->is_contsz;
331 331 cnt = *((uint8_t *)(uintptr_t)stp->smbst_hdr + isp->is_contc);
332 332 cp = (id_t *)((uintptr_t)stp->smbst_hdr + isp->is_contv);
333 333
334 334 n = MIN(cnt, idc);
335 335 for (i = 0; i < n; i++) {
336 336 if (size == SMB_CONT_WORD)
337 337 idv[i] = *((uint8_t *)(uintptr_t)cp + (i * 2));
338 338 else if (size == SMB_CONT_BYTE)
339 339 idv[i] = *((uint8_t *)(uintptr_t)cp + (i * 3));
340 340 else
341 341 return (smb_set_errno(shp, ESMB_INVAL));
342 342 }
343 343
344 344 return (cnt);
345 345 }
346 346
347 347 id_t
348 348 smbios_info_bios(smbios_hdl_t *shp, smbios_bios_t *bp)
349 349 {
350 350 const smb_struct_t *stp = smb_lookup_type(shp, SMB_TYPE_BIOS);
351 351 const smb_bios_t *bip;
352 352
353 353 if (stp == NULL)
354 354 return (-1); /* errno is set for us */
355 355
356 356 if (stp->smbst_hdr->smbh_len < sizeof (smb_bios_t) - sizeof (uint8_t))
357 357 return (smb_set_errno(shp, ESMB_CORRUPT));
358 358
359 359 bip = (smb_bios_t *)(uintptr_t)stp->smbst_hdr;
360 360 bzero(bp, sizeof (smb_base_bios_t));
361 361 if (smb_libgteq(shp, SMB_VERSION_31)) {
362 362 bp->smbb_extromsize = 0;
363 363 }
364 364
365 365 bp->smbb_vendor = smb_strptr(stp, bip->smbbi_vendor);
366 366 bp->smbb_version = smb_strptr(stp, bip->smbbi_version);
367 367 bp->smbb_segment = bip->smbbi_segment;
368 368 bp->smbb_reldate = smb_strptr(stp, bip->smbbi_reldate);
369 369 bp->smbb_romsize = 64 * 1024 * ((uint32_t)bip->smbbi_romsize + 1);
370 370 bp->smbb_runsize = 16 * (0x10000 - (uint32_t)bip->smbbi_segment);
371 371 bp->smbb_cflags = bip->smbbi_cflags;
372 372
373 373 /*
374 374 * If one or more extension bytes are present, reset smbb_xcflags to
375 375 * point to them. Otherwise leave this member set to NULL.
376 376 */
377 377 if (stp->smbst_hdr->smbh_len >= sizeof (smb_bios_t)) {
378 378 bp->smbb_xcflags = bip->smbbi_xcflags;
379 379 bp->smbb_nxcflags = stp->smbst_hdr->smbh_len -
380 380 sizeof (smb_bios_t) + 1;
381 381
382 382 if (bp->smbb_nxcflags > SMB_BIOSXB_ECFW_MIN &&
383 383 smb_gteq(shp, SMB_VERSION_24)) {
384 384 bp->smbb_biosv.smbv_major =
385 385 bip->smbbi_xcflags[SMB_BIOSXB_BIOS_MAJ];
386 386 bp->smbb_biosv.smbv_minor =
387 387 bip->smbbi_xcflags[SMB_BIOSXB_BIOS_MIN];
388 388 bp->smbb_ecfwv.smbv_major =
389 389 bip->smbbi_xcflags[SMB_BIOSXB_ECFW_MAJ];
390 390 bp->smbb_ecfwv.smbv_minor =
391 391 bip->smbbi_xcflags[SMB_BIOSXB_ECFW_MIN];
392 392 }
393 393
394 394 if (bp->smbb_nxcflags > SMB_BIOSXB_EXTROM + 1 &&
395 395 smb_gteq(shp, SMB_VERSION_31)) {
396 396 uint16_t val;
397 397 uint64_t rs;
398 398
399 399 /*
400 400 * Because of the fact that the extended size is a
401 401 * uint16_t and we'd need to define an explicit
402 402 * endian-aware way to access it, we don't include it in
403 403 * the number of extended flags below and thus subtract
404 404 * its size.
405 405 */
406 406 bp->smbb_nxcflags -= sizeof (uint16_t);
407 407 bcopy(&bip->smbbi_xcflags[SMB_BIOSXB_EXTROM], &val,
408 408 sizeof (val));
409 409 val = LE_16(val);
410 410
411 411 /*
412 412 * The upper two bits of the extended rom size are used
413 413 * to indicate whether the other 14 bits are in MB or
414 414 * GB.
415 415 */
416 416 rs = SMB_BIOS_EXTROM_VALUE_MASK(val);
417 417 switch (SMB_BIOS_EXTROM_SHIFT_MASK(val)) {
418 418 case 0:
419 419 rs *= 1024ULL * 1024ULL;
420 420 break;
421 421 case 1:
422 422 rs *= 1024ULL * 1024ULL * 1024ULL;
423 423 break;
424 424 default:
425 425 rs = 0;
426 426 break;
427 427 }
428 428
429 429 if (smb_libgteq(shp, SMB_VERSION_31)) {
430 430 bp->smbb_extromsize = rs;
431 431 }
432 432 }
433 433 }
434 434
435 435 if (smb_libgteq(shp, SMB_VERSION_31) && bp->smbb_extromsize == 0) {
436 436 bp->smbb_extromsize = bp->smbb_romsize;
437 437 }
438 438
439 439 return (stp->smbst_hdr->smbh_hdl);
440 440 }
441 441
442 442 id_t
443 443 smbios_info_system(smbios_hdl_t *shp, smbios_system_t *sip)
444 444 {
445 445 const smb_struct_t *stp = smb_lookup_type(shp, SMB_TYPE_SYSTEM);
446 446 smb_system_t si;
447 447
448 448 if (stp == NULL)
449 449 return (-1); /* errno is set for us */
450 450
451 451 smb_info_bcopy(stp->smbst_hdr, &si, sizeof (si));
452 452 bzero(sip, sizeof (smbios_system_t));
453 453
454 454 sip->smbs_uuid = ((smb_system_t *)stp->smbst_hdr)->smbsi_uuid;
455 455 sip->smbs_uuidlen = sizeof (si.smbsi_uuid);
456 456 sip->smbs_wakeup = si.smbsi_wakeup;
457 457 sip->smbs_sku = smb_strptr(stp, si.smbsi_sku);
458 458 sip->smbs_family = smb_strptr(stp, si.smbsi_family);
459 459
460 460 return (stp->smbst_hdr->smbh_hdl);
461 461 }
462 462
463 463 int
464 464 smbios_info_bboard(smbios_hdl_t *shp, id_t id, smbios_bboard_t *bbp)
465 465 {
466 466 const smb_struct_t *stp = smb_lookup_id(shp, id);
467 467 smb_bboard_t bb;
468 468
469 469 if (stp == NULL)
470 470 return (-1); /* errno is set for us */
471 471
472 472 if (stp->smbst_hdr->smbh_type != SMB_TYPE_BASEBOARD)
473 473 return (smb_set_errno(shp, ESMB_TYPE));
474 474
475 475 smb_info_bcopy(stp->smbst_hdr, &bb, sizeof (bb));
476 476 bzero(bbp, sizeof (smbios_bboard_t));
477 477
478 478 bbp->smbb_chassis = bb.smbbb_chassis;
479 479 bbp->smbb_flags = bb.smbbb_flags;
480 480 bbp->smbb_type = bb.smbbb_type;
481 481 bbp->smbb_contn = bb.smbbb_cn;
482 482
483 483 return (0);
484 484 }
485 485
486 486 int
487 487 smbios_info_chassis(smbios_hdl_t *shp, id_t id, smbios_chassis_t *chp)
488 488 {
489 489 const smb_struct_t *stp = smb_lookup_id(shp, id);
490 490 /* Length is measurable by one byte, so it'll be no more than 255. */
491 491 uint8_t buf[256];
492 492 smb_chassis_t *ch = (smb_chassis_t *)&buf[0];
493 493
494 494 if (stp == NULL)
495 495 return (-1); /* errno is set for us */
496 496
497 497 if (stp->smbst_hdr->smbh_type != SMB_TYPE_CHASSIS)
498 498 return (smb_set_errno(shp, ESMB_TYPE));
499 499
500 500 smb_info_bcopy(stp->smbst_hdr, ch, sizeof (buf));
501 501 bzero(chp, sizeof (smb_base_chassis_t));
502 502 if (smb_libgteq(shp, SMB_VERSION_27)) {
503 503 bzero(chp->smbc_sku, sizeof (chp->smbc_sku));
504 504 }
505 505
506 506 chp->smbc_oemdata = ch->smbch_oemdata;
507 507 chp->smbc_lock = (ch->smbch_type & SMB_CHT_LOCK) != 0;
508 508 chp->smbc_type = ch->smbch_type & ~SMB_CHT_LOCK;
509 509 chp->smbc_bustate = ch->smbch_bustate;
510 510 chp->smbc_psstate = ch->smbch_psstate;
511 511 chp->smbc_thstate = ch->smbch_thstate;
512 512 chp->smbc_security = ch->smbch_security;
513 513 chp->smbc_uheight = ch->smbch_uheight;
514 514 chp->smbc_cords = ch->smbch_cords;
515 515 chp->smbc_elems = ch->smbch_cn;
516 516 chp->smbc_elemlen = ch->smbch_cm;
517 517
518 518 if (smb_libgteq(shp, SMB_VERSION_27)) {
519 519 (void) strlcpy(chp->smbc_sku, SMB_CH_SKU(ch),
520 520 sizeof (chp->smbc_sku));
521 521 }
522 522
523 523 return (0);
524 524 }
525 525
526 526 int
527 527 smbios_info_processor(smbios_hdl_t *shp, id_t id, smbios_processor_t *pp)
528 528 {
529 529 const smb_struct_t *stp = smb_lookup_id(shp, id);
530 530 smb_processor_t p;
531 531
532 532 if (stp == NULL)
533 533 return (-1); /* errno is set for us */
534 534
535 535 if (stp->smbst_hdr->smbh_type != SMB_TYPE_PROCESSOR)
536 536 return (smb_set_errno(shp, ESMB_TYPE));
537 537
538 538 smb_info_bcopy(stp->smbst_hdr, &p, sizeof (p));
539 539 bzero(pp, sizeof (smb_base_processor_t));
540 540
541 541 pp->smbp_cpuid = p.smbpr_cpuid;
542 542 pp->smbp_type = p.smbpr_type;
543 543 pp->smbp_family = p.smbpr_family;
544 544 pp->smbp_voltage = p.smbpr_voltage;
545 545 pp->smbp_maxspeed = p.smbpr_maxspeed;
546 546 pp->smbp_curspeed = p.smbpr_curspeed;
547 547 pp->smbp_status = p.smbpr_status;
548 548 pp->smbp_upgrade = p.smbpr_upgrade;
549 549 pp->smbp_l1cache = p.smbpr_l1cache;
550 550 pp->smbp_l2cache = p.smbpr_l2cache;
551 551 pp->smbp_l3cache = p.smbpr_l3cache;
552 552
553 553 if (smb_libgteq(shp, SMB_VERSION_25)) {
554 554 pp->smbp_corecount = p.smbpr_corecount;
555 555 pp->smbp_coresenabled = p.smbpr_coresenabled;
556 556 pp->smbp_threadcount = p.smbpr_threadcount;
557 557 pp->smbp_cflags = p.smbpr_cflags;
558 558 }
559 559
560 560 if (smb_libgteq(shp, SMB_VERSION_26)) {
561 561 pp->smbp_family2 = p.smbpr_family2;
562 562 }
563 563
564 564 if (smb_libgteq(shp, SMB_VERSION_30)) {
565 565 pp->smbp_corecount2 = p.smbpr_corecount2;
566 566 pp->smbp_coresenabled2 = p.smbpr_coresenabled2;
567 567 pp->smbp_threadcount2 = p.smbpr_threadcount2;
568 568 }
569 569
570 570 return (0);
571 571 }
572 572
573 573 int
574 574 smbios_info_cache(smbios_hdl_t *shp, id_t id, smbios_cache_t *cap)
575 575 {
576 576 const smb_struct_t *stp = smb_lookup_id(shp, id);
577 577 smb_cache_t c;
578 578
579 579 if (stp == NULL)
580 580 return (-1); /* errno is set for us */
581 581
582 582 if (stp->smbst_hdr->smbh_type != SMB_TYPE_CACHE)
583 583 return (smb_set_errno(shp, ESMB_TYPE));
584 584
585 585 smb_info_bcopy(stp->smbst_hdr, &c, sizeof (c));
586 586 bzero(cap, sizeof (smb_base_cache_t));
587 587
588 588 cap->smba_maxsize = SMB_CACHE_SIZE(c.smbca_maxsize);
589 589 cap->smba_size = SMB_CACHE_SIZE(c.smbca_size);
590 590 cap->smba_stype = c.smbca_stype;
591 591 cap->smba_ctype = c.smbca_ctype;
592 592 cap->smba_speed = c.smbca_speed;
593 593 cap->smba_etype = c.smbca_etype;
594 594 cap->smba_ltype = c.smbca_ltype;
595 595 cap->smba_assoc = c.smbca_assoc;
596 596 cap->smba_level = SMB_CACHE_CFG_LEVEL(c.smbca_config);
597 597 cap->smba_mode = SMB_CACHE_CFG_MODE(c.smbca_config);
598 598 cap->smba_location = SMB_CACHE_CFG_LOCATION(c.smbca_config);
599 599
600 600 if (SMB_CACHE_CFG_ENABLED(c.smbca_config))
601 601 cap->smba_flags |= SMB_CAF_ENABLED;
602 602
603 603 if (SMB_CACHE_CFG_SOCKETED(c.smbca_config))
604 604 cap->smba_flags |= SMB_CAF_SOCKETED;
605 605
606 606 if (smb_libgteq(shp, SMB_VERSION_31)) {
607 607 cap->smba_maxsize2 = SMB_CACHE_EXT_SIZE(c.smbca_maxsize2);
608 608 cap->smba_size2 = SMB_CACHE_EXT_SIZE(c.smbca_size2);
609 609
610 610 if (cap->smba_maxsize2 == 0) {
611 611 cap->smba_maxsize2 = cap->smba_maxsize;
612 612 }
613 613
614 614 if (cap->smba_size2 == 0) {
615 615 cap->smba_size2 = cap->smba_size;
616 616 }
617 617 }
618 618
619 619 return (0);
620 620 }
621 621
622 622 int
623 623 smbios_info_port(smbios_hdl_t *shp, id_t id, smbios_port_t *pop)
624 624 {
625 625 const smb_struct_t *stp = smb_lookup_id(shp, id);
626 626 smb_port_t p;
627 627
628 628 if (stp == NULL)
629 629 return (-1); /* errno is set for us */
630 630
631 631 if (stp->smbst_hdr->smbh_type != SMB_TYPE_PORT)
632 632 return (smb_set_errno(shp, ESMB_TYPE));
633 633
634 634 smb_info_bcopy(stp->smbst_hdr, &p, sizeof (p));
635 635 bzero(pop, sizeof (smbios_port_t));
636 636
637 637 pop->smbo_iref = smb_strptr(stp, p.smbpo_iref);
638 638 pop->smbo_eref = smb_strptr(stp, p.smbpo_eref);
639 639
640 640 pop->smbo_itype = p.smbpo_itype;
641 641 pop->smbo_etype = p.smbpo_etype;
642 642 pop->smbo_ptype = p.smbpo_ptype;
643 643
644 644 return (0);
645 645 }
646 646
647 647 int
648 648 smbios_info_slot(smbios_hdl_t *shp, id_t id, smbios_slot_t *sp)
649 649 {
650 650 const smb_struct_t *stp = smb_lookup_id(shp, id);
651 651 smb_slot_t s;
652 652
653 653 if (stp == NULL)
654 654 return (-1); /* errno is set for us */
655 655
656 656 if (stp->smbst_hdr->smbh_type != SMB_TYPE_SLOT)
657 657 return (smb_set_errno(shp, ESMB_TYPE));
658 658
659 659 smb_info_bcopy(stp->smbst_hdr, &s, sizeof (s));
660 660 bzero(sp, sizeof (smb_base_slot_t));
661 661
662 662 sp->smbl_name = smb_strptr(stp, s.smbsl_name);
663 663 sp->smbl_type = s.smbsl_type;
664 664 sp->smbl_width = s.smbsl_width;
665 665 sp->smbl_usage = s.smbsl_usage;
666 666 sp->smbl_length = s.smbsl_length;
667 667 sp->smbl_id = s.smbsl_id;
668 668 sp->smbl_ch1 = s.smbsl_ch1;
669 669 sp->smbl_ch2 = s.smbsl_ch2;
670 670 sp->smbl_sg = s.smbsl_sg;
671 671 sp->smbl_bus = s.smbsl_bus;
672 672 sp->smbl_df = s.smbsl_df;
673 673
674 674 if (smb_libgteq(shp, SMB_VERSION_32)) {
675 675 sp->smbl_dbw = s.smbsl_dbw;
676 676 sp->smbl_npeers = s.smbsl_npeers;
677 677 }
678 678
679 679 return (0);
680 680 }
681 681
682 682 void
683 683 smbios_info_slot_peers_free(smbios_hdl_t *shp, uint_t npeers,
684 684 smbios_slot_peer_t *peer)
685 685 {
686 686 size_t sz = npeers * sizeof (smbios_slot_peer_t);
687 687
688 688 if (npeers == 0) {
689 689 ASSERT3P(peer, ==, NULL);
690 690 return;
↓ open down ↓ |
656 lines elided |
↑ open up ↑ |
691 691 }
692 692
693 693 smb_free(peer, sz);
694 694 }
695 695
696 696 int
697 697 smbios_info_slot_peers(smbios_hdl_t *shp, id_t id, uint_t *npeers,
698 698 smbios_slot_peer_t **peerp)
699 699 {
700 700 const smb_struct_t *stp = smb_lookup_id(shp, id);
701 - const smb_slot_t *slotp = (const smb_slot_t *)stp->smbst_hdr;
701 + const smb_slot_t *slotp;
702 702 smbios_slot_peer_t *peer;
703 703 size_t minlen;
704 704 uint_t i;
705 705
706 706 if (stp == NULL)
707 707 return (-1); /* errno is set for us */
708 708
709 + slotp = (const smb_slot_t *)stp->smbst_hdr;
710 +
709 711 if (stp->smbst_hdr->smbh_type != SMB_TYPE_SLOT)
710 712 return (smb_set_errno(shp, ESMB_TYPE));
711 713
712 714 if (stp->smbst_hdr->smbh_len <= offsetof(smb_slot_t, smbsl_npeers) ||
713 715 slotp->smbsl_npeers == 0) {
714 716 *npeers = 0;
715 717 *peerp = NULL;
716 718 return (0);
717 719 }
718 720
719 721 /*
720 722 * Make sure that the size of the structure makes sense for the number
721 723 * of peers reported.
722 724 */
723 725 minlen = slotp->smbsl_npeers * sizeof (smb_slot_peer_t) +
724 726 offsetof(smb_slot_t, smbsl_npeers);
725 727 if (stp->smbst_hdr->smbh_len < minlen) {
726 728 return (smb_set_errno(shp, ESMB_SHORT));
727 729 }
728 730
729 731 if ((peer = smb_alloc(slotp->smbsl_npeers *
730 732 sizeof (smbios_slot_peer_t))) == NULL) {
731 733 return (smb_set_errno(shp, ESMB_NOMEM));
732 734 }
733 735
734 736 for (i = 0; i < slotp->smbsl_npeers; i++) {
735 737 peer[i].smblp_group = slotp->smbsl_peers[i].smbspb_group_no;
736 738 peer[i].smblp_bus = slotp->smbsl_peers[i].smbspb_bus;
737 739 peer[i].smblp_device = slotp->smbsl_peers[i].smbspb_df >> 3;
738 740 peer[i].smblp_function = slotp->smbsl_peers[i].smbspb_df & 0x7;
739 741 peer[i].smblp_data_width = slotp->smbsl_peers[i].smbspb_width;
740 742 }
741 743
742 744 *npeers = slotp->smbsl_npeers;
743 745 *peerp = peer;
744 746
745 747 return (0);
746 748 }
747 749
748 750 int
749 751 smbios_info_obdevs_ext(smbios_hdl_t *shp, id_t id, smbios_obdev_ext_t *oep)
750 752 {
751 753 const smb_struct_t *stp = smb_lookup_id(shp, id);
752 754 smb_obdev_ext_t obe;
753 755
754 756 if (stp == NULL)
755 757 return (-1); /* errno is set for us */
756 758
757 759 if (stp->smbst_hdr->smbh_type != SMB_TYPE_OBDEVEXT)
758 760 return (smb_set_errno(shp, ESMB_TYPE));
759 761
760 762 smb_info_bcopy(stp->smbst_hdr, &obe, sizeof (obe));
761 763 bzero(oep, sizeof (smbios_obdev_ext_t));
762 764
763 765 oep->smboe_name = smb_strptr(stp, obe.smbobe_name);
764 766 oep->smboe_dtype = obe.smbobe_dtype;
765 767 oep->smboe_dti = obe.smbobe_dti;
766 768 oep->smboe_sg = obe.smbobe_sg;
767 769 oep->smboe_bus = obe.smbobe_bus;
768 770 oep->smboe_df = obe.smbobe_df;
769 771
770 772 return (0);
771 773 }
772 774
773 775 int
774 776 smbios_info_obdevs(smbios_hdl_t *shp, id_t id, int obc, smbios_obdev_t *obp)
775 777 {
776 778 const smb_struct_t *stp = smb_lookup_id(shp, id);
777 779 const smb_obdev_t *op;
778 780 int i, m, n;
779 781
780 782 if (stp == NULL)
781 783 return (-1); /* errno is set for us */
782 784
783 785 if (stp->smbst_hdr->smbh_type != SMB_TYPE_OBDEVS)
784 786 return (smb_set_errno(shp, ESMB_TYPE));
785 787
786 788 op = (smb_obdev_t *)((uintptr_t)stp->smbst_hdr + sizeof (smb_header_t));
787 789 m = (stp->smbst_hdr->smbh_len - sizeof (smb_header_t)) / sizeof (*op);
788 790 n = MIN(m, obc);
789 791
790 792 for (i = 0; i < n; i++, op++, obp++) {
791 793 obp->smbd_name = smb_strptr(stp, op->smbob_name);
792 794 obp->smbd_type = op->smbob_type & ~SMB_OBT_ENABLED;
793 795 obp->smbd_enabled = (op->smbob_type & SMB_OBT_ENABLED) != 0;
794 796 }
795 797
796 798 return (m);
797 799 }
798 800
799 801 /*
800 802 * The implementation structures for OEMSTR, SYSCONFSTR, and LANG all use the
801 803 * first byte to indicate the size of a string table at the end of the record.
802 804 * Therefore, smbios_info_strtab() can be used to retrieve the table size and
803 805 * strings for any of these underlying record types.
804 806 */
805 807 int
806 808 smbios_info_strtab(smbios_hdl_t *shp, id_t id, int argc, const char *argv[])
807 809 {
808 810 const smb_struct_t *stp = smb_lookup_id(shp, id);
809 811 smb_strtab_t s;
810 812 int i, n;
811 813
812 814 if (stp == NULL)
813 815 return (-1); /* errno is set for us */
814 816
815 817 if (stp->smbst_hdr->smbh_type != SMB_TYPE_OEMSTR &&
816 818 stp->smbst_hdr->smbh_type != SMB_TYPE_SYSCONFSTR &&
817 819 stp->smbst_hdr->smbh_type != SMB_TYPE_LANG)
818 820 return (smb_set_errno(shp, ESMB_TYPE));
819 821
820 822 smb_info_bcopy(stp->smbst_hdr, &s, sizeof (s));
821 823 n = MIN(s.smbtb_count, argc);
822 824
823 825 for (i = 0; i < n; i++)
824 826 argv[i] = smb_strptr(stp, i + 1);
825 827
826 828 return (s.smbtb_count);
827 829 }
828 830
829 831 id_t
830 832 smbios_info_lang(smbios_hdl_t *shp, smbios_lang_t *lp)
831 833 {
832 834 const smb_struct_t *stp = smb_lookup_type(shp, SMB_TYPE_LANG);
833 835 smb_lang_t l;
834 836
835 837 if (stp == NULL)
836 838 return (-1); /* errno is set for us */
837 839
838 840 smb_info_bcopy(stp->smbst_hdr, &l, sizeof (l));
839 841 bzero(lp, sizeof (smbios_lang_t));
840 842
841 843 lp->smbla_cur = smb_strptr(stp, l.smblang_cur);
842 844 lp->smbla_fmt = l.smblang_flags & 1;
843 845 lp->smbla_num = l.smblang_num;
844 846
845 847 return (stp->smbst_hdr->smbh_hdl);
846 848 }
847 849
848 850 id_t
849 851 smbios_info_eventlog(smbios_hdl_t *shp, smbios_evlog_t *evp)
850 852 {
851 853 const smb_struct_t *stp = smb_lookup_type(shp, SMB_TYPE_EVENTLOG);
852 854 const smb_sel_t *sel;
853 855 size_t len;
854 856
855 857 if (stp == NULL)
856 858 return (-1); /* errno is set for us */
857 859
858 860 if (stp->smbst_hdr->smbh_len < sizeof (smb_sel_t) - sizeof (uint8_t))
859 861 return (smb_set_errno(shp, ESMB_CORRUPT));
860 862
861 863 sel = (smb_sel_t *)(uintptr_t)stp->smbst_hdr;
862 864 len = stp->smbst_hdr->smbh_len - sizeof (smb_sel_t) + sizeof (uint8_t);
863 865 bzero(evp, sizeof (smbios_evlog_t));
864 866
865 867 if (len < sel->smbsel_typec * sel->smbsel_typesz)
866 868 return (smb_set_errno(shp, ESMB_CORRUPT));
867 869
868 870 evp->smbev_size = sel->smbsel_len;
869 871 evp->smbev_hdr = sel->smbsel_hdroff;
870 872 evp->smbev_data = sel->smbsel_dataoff;
871 873 evp->smbev_method = sel->smbsel_method;
872 874 evp->smbev_flags = sel->smbsel_status;
873 875 evp->smbev_format = sel->smbsel_format;
874 876 evp->smbev_token = sel->smbsel_token;
875 877 evp->smbev_addr.eva_addr = sel->smbsel_addr;
876 878
877 879 if (sel->smbsel_typesz == sizeof (smbios_evtype_t)) {
878 880 evp->smbev_typec = sel->smbsel_typec;
879 881 evp->smbev_typev = (void *)(uintptr_t)sel->smbsel_typev;
880 882 }
881 883
882 884 return (stp->smbst_hdr->smbh_hdl);
883 885 }
884 886
885 887 int
886 888 smbios_info_memarray(smbios_hdl_t *shp, id_t id, smbios_memarray_t *map)
887 889 {
888 890 const smb_struct_t *stp = smb_lookup_id(shp, id);
889 891 smb_memarray_t m;
890 892
891 893 if (stp == NULL)
892 894 return (-1); /* errno is set for us */
893 895
894 896 if (stp->smbst_hdr->smbh_type != SMB_TYPE_MEMARRAY)
895 897 return (smb_set_errno(shp, ESMB_TYPE));
896 898
897 899 smb_info_bcopy(stp->smbst_hdr, &m, sizeof (m));
898 900 bzero(map, sizeof (smbios_memarray_t));
899 901
900 902 map->smbma_location = m.smbmarr_loc;
901 903 map->smbma_use = m.smbmarr_use;
902 904 map->smbma_ecc = m.smbmarr_ecc;
903 905 map->smbma_ndevs = m.smbmarr_ndevs;
904 906 map->smbma_err = m.smbmarr_err;
905 907
906 908 if (m.smbmarr_cap != 0x80000000)
907 909 map->smbma_size = (uint64_t)m.smbmarr_cap * 1024;
908 910 else if (m.smbmarr_extcap != 0)
909 911 map->smbma_size = m.smbmarr_extcap;
910 912 else
911 913 map->smbma_size = 0; /* unknown */
912 914
913 915 return (0);
914 916 }
915 917
916 918 int
917 919 smbios_info_memarrmap(smbios_hdl_t *shp, id_t id, smbios_memarrmap_t *map)
918 920 {
919 921 const smb_struct_t *stp = smb_lookup_id(shp, id);
920 922 smb_memarrmap_t m;
921 923
922 924 if (stp == NULL)
923 925 return (-1); /* errno is set for us */
924 926
925 927 if (stp->smbst_hdr->smbh_type != SMB_TYPE_MEMARRAYMAP)
926 928 return (smb_set_errno(shp, ESMB_TYPE));
927 929
928 930 smb_info_bcopy(stp->smbst_hdr, &m, sizeof (m));
929 931 bzero(map, sizeof (smbios_memarrmap_t));
930 932
931 933 map->smbmam_array = m.smbamap_array;
932 934 map->smbmam_width = m.smbamap_width;
933 935
934 936 if (m.smbamap_start != 0xFFFFFFFF && m.smbamap_end != 0xFFFFFFFF) {
935 937 map->smbmam_addr = (uint64_t)m.smbamap_start * 1024;
936 938 map->smbmam_size = (uint64_t)
937 939 (m.smbamap_end - m.smbamap_start + 1) * 1024;
938 940 } else if (m.smbamap_extstart != 0 && m.smbamap_extend != 0) {
939 941 map->smbmam_addr = m.smbamap_extstart;
940 942 map->smbmam_size = m.smbamap_extend - m.smbamap_extstart + 1;
941 943 }
942 944
943 945 return (0);
944 946 }
945 947
946 948 int
947 949 smbios_info_memdevice(smbios_hdl_t *shp, id_t id, smbios_memdevice_t *mdp)
948 950 {
949 951 const smb_struct_t *stp = smb_lookup_id(shp, id);
950 952 smb_memdevice_t m;
951 953
952 954 if (stp == NULL)
953 955 return (-1); /* errno is set for us */
954 956
955 957 if (stp->smbst_hdr->smbh_type != SMB_TYPE_MEMDEVICE)
956 958 return (smb_set_errno(shp, ESMB_TYPE));
957 959
958 960 smb_info_bcopy(stp->smbst_hdr, &m, sizeof (m));
959 961 bzero(mdp, sizeof (smb_base_memdevice_t));
960 962
961 963 mdp->smbmd_array = m.smbmdev_array;
962 964 mdp->smbmd_error = m.smbmdev_error;
963 965 mdp->smbmd_twidth = m.smbmdev_twidth == 0xFFFF ? -1U : m.smbmdev_twidth;
964 966 mdp->smbmd_dwidth = m.smbmdev_dwidth == 0xFFFF ? -1U : m.smbmdev_dwidth;
965 967
966 968 if (m.smbmdev_size == 0x7FFF) {
967 969 mdp->smbmd_size = (uint64_t)m.smbmdev_extsize;
968 970 mdp->smbmd_size *= 1024 * 1024; /* convert MB to bytes */
969 971 } else if (m.smbmdev_size != 0xFFFF) {
970 972 mdp->smbmd_size = (uint64_t)(m.smbmdev_size & ~SMB_MDS_KBYTES);
971 973 if (m.smbmdev_size & SMB_MDS_KBYTES)
972 974 mdp->smbmd_size *= 1024;
973 975 else
974 976 mdp->smbmd_size *= 1024 * 1024;
975 977 } else
976 978 mdp->smbmd_size = -1ULL; /* size unknown */
977 979
978 980 mdp->smbmd_form = m.smbmdev_form;
979 981 mdp->smbmd_set = m.smbmdev_set;
980 982 mdp->smbmd_type = m.smbmdev_type;
981 983 mdp->smbmd_speed = m.smbmdev_speed;
982 984 mdp->smbmd_flags = m.smbmdev_flags;
983 985 mdp->smbmd_dloc = smb_strptr(stp, m.smbmdev_dloc);
984 986 mdp->smbmd_bloc = smb_strptr(stp, m.smbmdev_bloc);
985 987
986 988 if (smb_libgteq(shp, SMB_VERSION_26)) {
987 989 mdp->smbmd_rank = m.smbmdev_attrs & 0x0F;
988 990 }
989 991
990 992 if (smb_libgteq(shp, SMB_VERSION_27)) {
991 993 mdp->smbmd_clkspeed = m.smbmdev_clkspeed;
992 994 }
993 995
994 996 if (smb_libgteq(shp, SMB_VERSION_28)) {
995 997 mdp->smbmd_minvolt = m.smbmdev_minvolt;
996 998 mdp->smbmd_maxvolt = m.smbmdev_maxvolt;
997 999 mdp->smbmd_confvolt = m.smbmdev_confvolt;
998 1000 }
999 1001
1000 1002 if (smb_libgteq(shp, SMB_VERSION_32)) {
1001 1003 mdp->smbmd_memtech = m.smbmdev_memtech;
1002 1004 mdp->smbmd_opcap_flags = m.smbmdev_opmode;
1003 1005 mdp->smbmd_firmware_rev = smb_strptr(stp,
1004 1006 m.smbmdev_fwver);
1005 1007 mdp->smbmd_modmfg_id = m.smbmdev_modulemfgid;
1006 1008 mdp->smbmd_modprod_id = m.smbmdev_moduleprodid;
1007 1009 mdp->smbmd_cntrlmfg_id = m.smbmdev_memsysmfgid;
1008 1010 mdp->smbmd_cntrlprod_id = m.smbmdev_memsysprodid;
1009 1011 mdp->smbmd_nvsize = m.smbmdev_nvsize;
1010 1012 mdp->smbmd_volatile_size = m.smbmdev_volsize;
1011 1013 mdp->smbmd_cache_size = m.smbmdev_cachesize;
1012 1014 mdp->smbmd_logical_size = m.smbmdev_logicalsize;
1013 1015 }
1014 1016
1015 1017 return (0);
1016 1018 }
1017 1019
1018 1020 int
1019 1021 smbios_info_memdevmap(smbios_hdl_t *shp, id_t id, smbios_memdevmap_t *mdp)
1020 1022 {
1021 1023 const smb_struct_t *stp = smb_lookup_id(shp, id);
1022 1024 smb_memdevmap_t m;
1023 1025
1024 1026 if (stp == NULL)
1025 1027 return (-1); /* errno is set for us */
1026 1028
1027 1029 if (stp->smbst_hdr->smbh_type != SMB_TYPE_MEMDEVICEMAP)
1028 1030 return (smb_set_errno(shp, ESMB_TYPE));
1029 1031
1030 1032 smb_info_bcopy(stp->smbst_hdr, &m, sizeof (m));
1031 1033 bzero(mdp, sizeof (smbios_memdevmap_t));
1032 1034
1033 1035 mdp->smbmdm_device = m.smbdmap_device;
1034 1036 mdp->smbmdm_arrmap = m.smbdmap_array;
1035 1037 mdp->smbmdm_rpos = m.smbdmap_rpos;
1036 1038 mdp->smbmdm_ipos = m.smbdmap_ipos;
1037 1039 mdp->smbmdm_idepth = m.smbdmap_idepth;
1038 1040
1039 1041 if (m.smbdmap_start != 0xFFFFFFFF && m.smbdmap_end != 0xFFFFFFFF) {
1040 1042 mdp->smbmdm_addr = (uint64_t)m.smbdmap_start * 1024;
1041 1043 mdp->smbmdm_size = (uint64_t)
1042 1044 (m.smbdmap_end - m.smbdmap_start + 1) * 1024;
1043 1045 } else if (m.smbdmap_extstart != 0 && m.smbdmap_extend != 0) {
1044 1046 mdp->smbmdm_addr = m.smbdmap_extstart;
1045 1047 mdp->smbmdm_size = m.smbdmap_extend - m.smbdmap_extstart + 1;
1046 1048 }
1047 1049
1048 1050 return (0);
1049 1051 }
1050 1052
1051 1053 id_t
1052 1054 smbios_info_hwsec(smbios_hdl_t *shp, smbios_hwsec_t *hsp)
1053 1055 {
1054 1056 const smb_struct_t *stp = smb_lookup_type(shp, SMB_TYPE_SECURITY);
1055 1057 smb_hwsec_t hs;
1056 1058
1057 1059 if (stp == NULL)
1058 1060 return (-1); /* errno is set for us */
1059 1061
1060 1062 smb_info_bcopy(stp->smbst_hdr, &hs, sizeof (hs));
1061 1063 bzero(hsp, sizeof (smbios_hwsec_t));
1062 1064
1063 1065 hsp->smbh_pwr_ps = SMB_HWS_PWR_PS(hs.smbhs_settings);
1064 1066 hsp->smbh_kbd_ps = SMB_HWS_KBD_PS(hs.smbhs_settings);
1065 1067 hsp->smbh_adm_ps = SMB_HWS_ADM_PS(hs.smbhs_settings);
1066 1068 hsp->smbh_pan_ps = SMB_HWS_PAN_PS(hs.smbhs_settings);
1067 1069
1068 1070 return (stp->smbst_hdr->smbh_hdl);
1069 1071 }
1070 1072
1071 1073 id_t
1072 1074 smbios_info_boot(smbios_hdl_t *shp, smbios_boot_t *bp)
1073 1075 {
1074 1076 const smb_struct_t *stp = smb_lookup_type(shp, SMB_TYPE_BOOT);
1075 1077 const smb_boot_t *b;
1076 1078
1077 1079 if (stp == NULL)
1078 1080 return (-1); /* errno is set for us */
1079 1081
1080 1082 bzero(bp, sizeof (smbios_boot_t));
1081 1083
1082 1084 b = (smb_boot_t *)(uintptr_t)stp->smbst_hdr;
1083 1085
1084 1086 bp->smbt_status = b->smbbo_status[0];
1085 1087 bp->smbt_size = stp->smbst_hdr->smbh_len - sizeof (smb_boot_t);
1086 1088 bp->smbt_data = bp->smbt_size ? &b->smbbo_status[1] : NULL;
1087 1089
1088 1090 return (stp->smbst_hdr->smbh_hdl);
1089 1091 }
1090 1092
1091 1093 id_t
1092 1094 smbios_info_ipmi(smbios_hdl_t *shp, smbios_ipmi_t *ip)
1093 1095 {
1094 1096 const smb_struct_t *stp = smb_lookup_type(shp, SMB_TYPE_IPMIDEV);
1095 1097 smb_ipmi_t i;
1096 1098
1097 1099 if (stp == NULL)
1098 1100 return (-1); /* errno is set for us */
1099 1101
1100 1102 smb_info_bcopy(stp->smbst_hdr, &i, sizeof (i));
1101 1103 bzero(ip, sizeof (smbios_ipmi_t));
1102 1104
1103 1105 ip->smbip_type = i.smbipm_type;
1104 1106 ip->smbip_vers.smbv_major = SMB_IPM_SPEC_MAJOR(i.smbipm_spec);
1105 1107 ip->smbip_vers.smbv_minor = SMB_IPM_SPEC_MINOR(i.smbipm_spec);
1106 1108 ip->smbip_i2c = i.smbipm_i2c;
1107 1109 ip->smbip_addr = i.smbipm_addr & ~SMB_IPM_ADDR_IO;
1108 1110 ip->smbip_intr = i.smbipm_intr;
1109 1111
1110 1112 if (i.smbipm_bus != (uint8_t)-1)
1111 1113 ip->smbip_bus = i.smbipm_bus;
1112 1114 else
1113 1115 ip->smbip_bus = -1u;
1114 1116
1115 1117 if (SMB_IPM_INFO_LSB(i.smbipm_info))
1116 1118 ip->smbip_addr |= 1; /* turn on least-significant bit of addr */
1117 1119
1118 1120 if (i.smbipm_addr & SMB_IPM_ADDR_IO) {
1119 1121 switch (SMB_IPM_INFO_REGS(i.smbipm_info)) {
1120 1122 case SMB_IPM_REGS_1B:
1121 1123 ip->smbip_regspacing = 1;
1122 1124 break;
1123 1125 case SMB_IPM_REGS_4B:
1124 1126 ip->smbip_regspacing = 4;
1125 1127 break;
1126 1128 case SMB_IPM_REGS_16B:
1127 1129 ip->smbip_regspacing = 16;
1128 1130 break;
1129 1131 default:
1130 1132 ip->smbip_regspacing = 1;
1131 1133 }
1132 1134 ip->smbip_flags |= SMB_IPMI_F_IOADDR;
1133 1135 }
1134 1136
1135 1137 if (SMB_IPM_INFO_ISPEC(i.smbipm_info))
1136 1138 ip->smbip_flags |= SMB_IPMI_F_INTRSPEC;
1137 1139
1138 1140 if (SMB_IPM_INFO_IPOL(i.smbipm_info) == SMB_IPM_IPOL_HI)
1139 1141 ip->smbip_flags |= SMB_IPMI_F_INTRHIGH;
1140 1142
1141 1143 if (SMB_IPM_INFO_IMODE(i.smbipm_info) == SMB_IPM_IMODE_EDGE)
1142 1144 ip->smbip_flags |= SMB_IPMI_F_INTREDGE;
1143 1145
1144 1146 return (stp->smbst_hdr->smbh_hdl);
1145 1147 }
1146 1148
1147 1149 static boolean_t
1148 1150 smbios_has_oemstr(smbios_hdl_t *shp, const char *oemstr)
1149 1151 {
1150 1152 const smb_struct_t *stp = shp->sh_structs;
1151 1153 smb_strtab_t s;
1152 1154 int i, j;
1153 1155
1154 1156 for (i = 0; i < shp->sh_nstructs; i++, stp++) {
1155 1157 if (stp->smbst_hdr->smbh_type != SMB_TYPE_OEMSTR)
1156 1158 continue;
1157 1159
1158 1160 smb_info_bcopy(stp->smbst_hdr, &s, sizeof (s));
1159 1161 for (j = 0; j < s.smbtb_count; j++)
1160 1162 if (strcmp(smb_strptr(stp, j + 1), oemstr) == 0)
1161 1163 return (B_TRUE);
1162 1164 }
1163 1165
1164 1166 return (B_FALSE);
1165 1167 }
1166 1168
1167 1169 static const char *
1168 1170 smb_serial_valid(const char *serial)
1169 1171 {
1170 1172 char buf[MAXNAMELEN];
1171 1173 int i = 0;
1172 1174
1173 1175 if (serial == NULL)
1174 1176 return (NULL);
1175 1177
1176 1178 (void) strlcpy(buf, serial, sizeof (buf));
1177 1179
1178 1180 while (buf[i] != '\0' && buf[i] == ' ')
1179 1181 i++;
1180 1182
1181 1183 if (buf[i] == '\0' || strstr(buf, SMB_DEFAULT1) != NULL ||
1182 1184 strstr(buf, SMB_DEFAULT2) != NULL)
1183 1185 return (NULL);
1184 1186
1185 1187 return (serial);
1186 1188 }
1187 1189
1188 1190 /*
1189 1191 * Get chassis SN or product SN
1190 1192 */
1191 1193 static int
1192 1194 smb_get_sn(smbios_hdl_t *shp, const char **psnp, const char **csnp)
1193 1195 {
1194 1196 const smb_struct_t *stp;
1195 1197 smbios_info_t s1, s3;
1196 1198
1197 1199 if (psnp == NULL || csnp == NULL)
1198 1200 return (smb_set_errno(shp, ESMB_INVAL));
1199 1201
1200 1202 *psnp = *csnp = NULL;
1201 1203
1202 1204 /*
1203 1205 * If SMBIOS meets Sun's PRMS requirements, retrieve product SN
1204 1206 * from type 1 structure, and chassis SN from type 3 structure.
1205 1207 * Otherwise return SN in type 1 structure as chassis SN.
1206 1208 */
1207 1209
1208 1210 /* Get type 1 SN */
1209 1211 if ((stp = smb_lookup_type(shp, SMB_TYPE_SYSTEM)) == NULL ||
1210 1212 smbios_info_common(shp, stp->smbst_hdr->smbh_hdl, &s1) == SMB_ERR)
1211 1213 s1.smbi_serial = NULL;
1212 1214
1213 1215 /* Get type 3 SN */
1214 1216 if ((stp = smb_lookup_type(shp, SMB_TYPE_CHASSIS)) == NULL ||
1215 1217 smbios_info_common(shp, stp->smbst_hdr->smbh_hdl, &s3) == SMB_ERR)
1216 1218 s3.smbi_serial = NULL;
1217 1219
1218 1220 if (smbios_has_oemstr(shp, SMB_PRMS1)) {
1219 1221 *psnp = smb_serial_valid(s1.smbi_serial);
1220 1222 *csnp = smb_serial_valid(s3.smbi_serial);
1221 1223 } else {
1222 1224 *csnp = smb_serial_valid(s1.smbi_serial);
1223 1225 }
1224 1226
1225 1227 return (0);
1226 1228 }
1227 1229
1228 1230 const char *
1229 1231 smbios_psn(smbios_hdl_t *shp)
1230 1232 {
1231 1233 const char *psn, *csn;
1232 1234
1233 1235 return (smb_get_sn(shp, &psn, &csn) == SMB_ERR ? NULL : psn);
1234 1236 }
1235 1237
1236 1238 const char *
1237 1239 smbios_csn(smbios_hdl_t *shp)
1238 1240 {
1239 1241 const char *psn, *csn;
1240 1242
1241 1243 return (smb_get_sn(shp, &psn, &csn) == SMB_ERR ? NULL : csn);
1242 1244 }
1243 1245
1244 1246 int
1245 1247 smbios_info_extprocessor(smbios_hdl_t *shp, id_t id,
1246 1248 smbios_processor_ext_t *epp)
1247 1249 {
1248 1250 const smb_struct_t *stp = smb_lookup_id(shp, id);
1249 1251 smb_processor_ext_t *exp;
1250 1252
1251 1253 if (stp == NULL)
1252 1254 return (-1); /* errno is set for us */
1253 1255
1254 1256 if (stp->smbst_hdr->smbh_type != SUN_OEM_EXT_PROCESSOR)
1255 1257 return (smb_set_errno(shp, ESMB_TYPE));
1256 1258
1257 1259 exp = (smb_processor_ext_t *)(uintptr_t)stp->smbst_hdr;
1258 1260 bzero(epp, sizeof (smbios_processor_ext_t));
1259 1261
1260 1262 epp->smbpe_processor = exp->smbpre_processor;
1261 1263 epp->smbpe_fru = exp->smbpre_fru;
1262 1264 epp->smbpe_n = exp->smbpre_n;
1263 1265 epp->smbpe_apicid = exp->smbpre_apicid;
1264 1266
1265 1267 return (0);
1266 1268 }
1267 1269
1268 1270 int
1269 1271 smbios_info_extport(smbios_hdl_t *shp, id_t id, smbios_port_ext_t *eportp)
1270 1272 {
1271 1273 const smb_struct_t *stp = smb_lookup_id(shp, id);
1272 1274 smb_port_ext_t *ep;
1273 1275
1274 1276 if (stp == NULL)
1275 1277 return (-1); /* errno is set for us */
1276 1278
1277 1279 if (stp->smbst_hdr->smbh_type != SUN_OEM_EXT_PORT)
1278 1280 return (smb_set_errno(shp, ESMB_TYPE));
1279 1281
1280 1282 ep = (smb_port_ext_t *)(uintptr_t)stp->smbst_hdr;
1281 1283 bzero(eportp, sizeof (smbios_port_ext_t));
1282 1284
1283 1285 eportp->smbporte_chassis = ep->smbpoe_chassis;
1284 1286 eportp->smbporte_port = ep->smbpoe_port;
1285 1287 eportp->smbporte_dtype = ep->smbpoe_dtype;
1286 1288 eportp->smbporte_devhdl = ep->smbpoe_devhdl;
1287 1289 eportp->smbporte_phy = ep->smbpoe_phy;
1288 1290
1289 1291 return (0);
1290 1292 }
1291 1293
1292 1294 int
1293 1295 smbios_info_pciexrc(smbios_hdl_t *shp, id_t id,
1294 1296 smbios_pciexrc_t *rcp)
1295 1297 {
1296 1298 const smb_struct_t *stp = smb_lookup_id(shp, id);
1297 1299 smb_pciexrc_t rc;
1298 1300
1299 1301 if (stp == NULL)
1300 1302 return (-1); /* errno is set for us */
1301 1303
1302 1304 if (stp->smbst_hdr->smbh_type != SUN_OEM_PCIEXRC)
1303 1305 return (smb_set_errno(shp, ESMB_TYPE));
1304 1306
1305 1307 smb_info_bcopy(stp->smbst_hdr, &rc, sizeof (rc));
1306 1308 bzero(rcp, sizeof (smbios_pciexrc_t));
1307 1309
1308 1310 rcp->smbpcie_bb = rc.smbpciexrc_bboard;
1309 1311 rcp->smbpcie_bdf = rc.smbpciexrc_bdf;
1310 1312
1311 1313 return (0);
1312 1314 }
1313 1315
1314 1316 int
1315 1317 smbios_info_extmemarray(smbios_hdl_t *shp, id_t id, smbios_memarray_ext_t *emap)
1316 1318 {
1317 1319 const smb_struct_t *stp = smb_lookup_id(shp, id);
1318 1320 smb_memarray_ext_t exma;
1319 1321
1320 1322 if (stp == NULL)
1321 1323 return (-1); /* errno is set for us */
1322 1324
1323 1325 if (stp->smbst_hdr->smbh_type != SUN_OEM_EXT_MEMARRAY)
1324 1326 return (smb_set_errno(shp, ESMB_TYPE));
1325 1327
1326 1328 smb_info_bcopy(stp->smbst_hdr, &exma, sizeof (exma));
1327 1329 bzero(emap, sizeof (smbios_memarray_ext_t));
1328 1330
1329 1331 emap->smbmae_ma = exma.smbmarre_ma;
1330 1332 emap->smbmae_comp = exma.smbmarre_component;
1331 1333 emap->smbmae_bdf = exma.smbmarre_bdf;
1332 1334
1333 1335 return (0);
1334 1336 }
1335 1337
1336 1338 int
1337 1339 smbios_info_extmemdevice(smbios_hdl_t *shp, id_t id,
1338 1340 smbios_memdevice_ext_t *emdp)
1339 1341 {
1340 1342 const smb_struct_t *stp = smb_lookup_id(shp, id);
1341 1343 smb_memdevice_ext_t exmd;
1342 1344
1343 1345 if (stp == NULL)
1344 1346 return (-1); /* errno is set for us */
1345 1347
1346 1348 if (stp->smbst_hdr->smbh_type != SUN_OEM_EXT_MEMDEVICE)
1347 1349 return (smb_set_errno(shp, ESMB_TYPE));
1348 1350
1349 1351 smb_info_bcopy(stp->smbst_hdr, &exmd, sizeof (exmd));
1350 1352 bzero(emdp, sizeof (smbios_memdevice_ext_t));
1351 1353
1352 1354 emdp->smbmdeve_md = exmd.smbmdeve_mdev;
1353 1355 emdp->smbmdeve_drch = exmd.smbmdeve_dchan;
1354 1356 emdp->smbmdeve_ncs = exmd.smbmdeve_ncs;
1355 1357 emdp->smbmdeve_cs = exmd.smbmdeve_cs;
1356 1358
1357 1359 return (0);
1358 1360 }
1359 1361
1360 1362 int
1361 1363 smbios_info_powersup(smbios_hdl_t *shp, id_t id, smbios_powersup_t *psup)
1362 1364 {
1363 1365 const smb_struct_t *stp = smb_lookup_id(shp, id);
1364 1366 smb_powersup_t psu;
1365 1367
1366 1368 if (stp == NULL)
1367 1369 return (-1); /* errno is set for us */
1368 1370
1369 1371 if (stp->smbst_hdr->smbh_type != SMB_TYPE_POWERSUP)
1370 1372 return (smb_set_errno(shp, ESMB_TYPE));
1371 1373
1372 1374 /* The minimum length required by the spec is 0x10. */
1373 1375 if (stp->smbst_hdr->smbh_len < 0x10)
1374 1376 return (smb_set_errno(shp, ESMB_SHORT));
1375 1377
1376 1378 bzero(psup, sizeof (*psup));
1377 1379 smb_info_bcopy(stp->smbst_hdr, &psu, sizeof (psu));
1378 1380 psup->smbps_group = psu.smbpsup_group;
1379 1381 psup->smbps_maxout = psu.smbpsup_max;
1380 1382
1381 1383 if (SMB_PSU_CHARS_ISHOT(psu.smbpsup_char))
1382 1384 psup->smbps_flags |= SMB_POWERSUP_F_HOT;
1383 1385 if (SMB_PSU_CHARS_ISPRES(psu.smbpsup_char))
1384 1386 psup->smbps_flags |= SMB_POWERSUP_F_PRESENT;
1385 1387 if (SMB_PSU_CHARS_ISUNPLUG(psu.smbpsup_char))
1386 1388 psup->smbps_flags |= SMB_POWERSUP_F_UNPLUG;
1387 1389
1388 1390 psup->smbps_ivrs = SMB_PSU_CHARS_IVRS(psu.smbpsup_char);
1389 1391 psup->smbps_status = SMB_PSU_CHARS_STATUS(psu.smbpsup_char);
1390 1392 psup->smbps_pstype = SMB_PSU_CHARS_TYPE(psu.smbpsup_char);
1391 1393
1392 1394 if (stp->smbst_hdr->smbh_len >= 0x12) {
1393 1395 psup->smbps_vprobe = psu.smbpsup_vprobe;
1394 1396 } else {
1395 1397 psup->smbps_vprobe = 0xffff;
1396 1398 }
1397 1399
1398 1400 if (stp->smbst_hdr->smbh_len >= 0x14) {
1399 1401 psup->smbps_cooldev = psu.smbpsup_cooldev;
1400 1402 } else {
1401 1403 psup->smbps_cooldev = 0xffff;
1402 1404 }
1403 1405
1404 1406 if (stp->smbst_hdr->smbh_len >= 0x16) {
1405 1407 psup->smbps_iprobe = psu.smbpsup_iprobe;
1406 1408 } else {
1407 1409 psup->smbps_iprobe = 0xffff;
1408 1410 }
1409 1411
1410 1412 return (0);
1411 1413 }
1412 1414
1413 1415 int
1414 1416 smbios_info_vprobe(smbios_hdl_t *shp, id_t id, smbios_vprobe_t *vprobe)
1415 1417 {
1416 1418 const smb_struct_t *stp = smb_lookup_id(shp, id);
1417 1419 smb_vprobe_t vp;
1418 1420
1419 1421 if (stp == NULL)
1420 1422 return (-1); /* errno is set for us */
1421 1423
1422 1424 if (stp->smbst_hdr->smbh_type != SMB_TYPE_VPROBE)
1423 1425 return (smb_set_errno(shp, ESMB_TYPE));
1424 1426
1425 1427 if (stp->smbst_hdr->smbh_len < SMB_VPROBE_MINLEN)
1426 1428 return (smb_set_errno(shp, ESMB_SHORT));
1427 1429
1428 1430 bzero(vprobe, sizeof (*vprobe));
1429 1431 smb_info_bcopy(stp->smbst_hdr, &vp, sizeof (vp));
1430 1432 vprobe->smbvp_description = smb_strptr(stp, vp.smbvpr_descr);
1431 1433 vprobe->smbvp_location = SMB_VPROBE_LOCATION(vp.smbvpr_locstat);
1432 1434 vprobe->smbvp_status = SMB_VPROBE_STATUS(vp.smbvpr_locstat);
1433 1435 vprobe->smbvp_maxval = vp.smbvpr_maxval;
1434 1436 vprobe->smbvp_minval = vp.smbvpr_minval;
1435 1437 vprobe->smbvp_resolution = vp.smbvpr_resolution;
1436 1438 vprobe->smbvp_tolerance = vp.smbvpr_tolerance;
1437 1439 vprobe->smbvp_accuracy = vp.smbvpr_accuracy;
1438 1440
1439 1441 if (stp->smbst_hdr->smbh_len >= SMB_VPROBE_NOMINAL_MINLEN) {
1440 1442 vprobe->smbvp_nominal = vp.smbvpr_nominal;
1441 1443 } else {
1442 1444 vprobe->smbvp_nominal = SMB_PROBE_UNKNOWN_VALUE;
1443 1445 }
1444 1446
1445 1447 return (0);
1446 1448 }
1447 1449
1448 1450 int
1449 1451 smbios_info_cooldev(smbios_hdl_t *shp, id_t id, smbios_cooldev_t *cooldev)
1450 1452 {
1451 1453 const smb_struct_t *stp = smb_lookup_id(shp, id);
1452 1454 smb_cooldev_t cd;
1453 1455
1454 1456 if (stp == NULL)
1455 1457 return (-1); /* errno is set for us */
1456 1458
1457 1459 if (stp->smbst_hdr->smbh_type != SMB_TYPE_COOLDEV)
1458 1460 return (smb_set_errno(shp, ESMB_TYPE));
1459 1461
1460 1462 if (stp->smbst_hdr->smbh_len < SMB_COOLDEV_MINLEN)
1461 1463 return (smb_set_errno(shp, ESMB_SHORT));
1462 1464
1463 1465 bzero(cooldev, sizeof (*cooldev));
1464 1466 smb_info_bcopy(stp->smbst_hdr, &cd, sizeof (cd));
1465 1467 cooldev->smbcd_tprobe = cd.smbcdev_tprobe;
1466 1468 cooldev->smbcd_type = SMB_COOLDEV_TYPE(cd.smbcdev_typstat);
1467 1469 cooldev->smbcd_status = SMB_COOLDEV_STATUS(cd.smbcdev_typstat);
1468 1470 cooldev->smbcd_group = cd.smbcdev_group;
1469 1471 cooldev->smbcd_oem = cd.smbcdev_oem;
1470 1472
1471 1473 if (stp->smbst_hdr->smbh_len >= SMB_COOLDEV_NOMINAL_MINLEN) {
1472 1474 cooldev->smbcd_nominal = cd.smbcdev_nominal;
1473 1475 } else {
1474 1476 cooldev->smbcd_nominal = SMB_PROBE_UNKNOWN_VALUE;
1475 1477 }
1476 1478
1477 1479 /*
1478 1480 * The description field was added in SMBIOS version 2.7. The
1479 1481 * SMB_TYPE_COOLDEV support was only added after all of the 2.7+ fields
1480 1482 * were added in the spec. So while a user may request an older version,
1481 1483 * we don't have to worry about old structures and just simply skip it
1482 1484 * if they're not asking for it.
1483 1485 */
1484 1486 if (smb_libgteq(shp, SMB_VERSION_27) &&
1485 1487 smb_gteq(shp, SMB_VERSION_27) &&
1486 1488 stp->smbst_hdr->smbh_len >= SMB_COOLDEV_DESCR_MINLEN) {
1487 1489 cooldev->smbcd_descr = smb_strptr(stp, cd.smbcdev_descr);
1488 1490 } else {
1489 1491 cooldev->smbcd_descr = NULL;
1490 1492 }
1491 1493
1492 1494 return (0);
1493 1495 }
1494 1496
1495 1497 int
1496 1498 smbios_info_tprobe(smbios_hdl_t *shp, id_t id, smbios_tprobe_t *tprobe)
1497 1499 {
1498 1500 const smb_struct_t *stp = smb_lookup_id(shp, id);
1499 1501 smb_tprobe_t tp;
1500 1502
1501 1503 if (stp == NULL)
1502 1504 return (-1); /* errno is set for us */
1503 1505
1504 1506 if (stp->smbst_hdr->smbh_type != SMB_TYPE_TPROBE)
1505 1507 return (smb_set_errno(shp, ESMB_TYPE));
1506 1508
1507 1509 if (stp->smbst_hdr->smbh_len < SMB_TPROBE_MINLEN)
1508 1510 return (smb_set_errno(shp, ESMB_SHORT));
1509 1511
1510 1512 bzero(tprobe, sizeof (*tprobe));
1511 1513 smb_info_bcopy(stp->smbst_hdr, &tp, sizeof (tp));
1512 1514 tprobe->smbtp_description = smb_strptr(stp, tp.smbtpr_descr);
1513 1515 tprobe->smbtp_location = SMB_TPROBE_LOCATION(tp.smbtpr_locstat);
1514 1516 tprobe->smbtp_status = SMB_TPROBE_STATUS(tp.smbtpr_locstat);
1515 1517 tprobe->smbtp_maxval = tp.smbtpr_maxval;
1516 1518 tprobe->smbtp_minval = tp.smbtpr_minval;
1517 1519 tprobe->smbtp_resolution = tp.smbtpr_resolution;
1518 1520 tprobe->smbtp_tolerance = tp.smbtpr_tolerance;
1519 1521 tprobe->smbtp_accuracy = tp.smbtpr_accuracy;
1520 1522
1521 1523 if (stp->smbst_hdr->smbh_len >= SMB_TPROBE_NOMINAL_MINLEN) {
1522 1524 tprobe->smbtp_nominal = tp.smbtpr_nominal;
1523 1525 } else {
1524 1526 tprobe->smbtp_nominal = SMB_PROBE_UNKNOWN_VALUE;
1525 1527 }
1526 1528
1527 1529 return (0);
1528 1530 }
1529 1531
1530 1532 int
1531 1533 smbios_info_iprobe(smbios_hdl_t *shp, id_t id, smbios_iprobe_t *iprobe)
1532 1534 {
1533 1535 const smb_struct_t *sip = smb_lookup_id(shp, id);
1534 1536 smb_iprobe_t ip;
1535 1537
1536 1538 if (sip == NULL)
1537 1539 return (-1); /* errno is set for us */
1538 1540
1539 1541 if (sip->smbst_hdr->smbh_type != SMB_TYPE_IPROBE)
1540 1542 return (smb_set_errno(shp, ESMB_TYPE));
1541 1543
1542 1544 if (sip->smbst_hdr->smbh_len < SMB_IPROBE_MINLEN)
1543 1545 return (smb_set_errno(shp, ESMB_SHORT));
1544 1546
1545 1547 bzero(iprobe, sizeof (*iprobe));
1546 1548 smb_info_bcopy(sip->smbst_hdr, &ip, sizeof (ip));
1547 1549 iprobe->smbip_description = smb_strptr(sip, ip.smbipr_descr);
1548 1550 iprobe->smbip_location = SMB_IPROBE_LOCATION(ip.smbipr_locstat);
1549 1551 iprobe->smbip_status = SMB_IPROBE_STATUS(ip.smbipr_locstat);
1550 1552 iprobe->smbip_maxval = ip.smbipr_maxval;
1551 1553 iprobe->smbip_minval = ip.smbipr_minval;
1552 1554 iprobe->smbip_resolution = ip.smbipr_resolution;
1553 1555 iprobe->smbip_tolerance = ip.smbipr_tolerance;
1554 1556 iprobe->smbip_accuracy = ip.smbipr_accuracy;
1555 1557
1556 1558 if (sip->smbst_hdr->smbh_len >= SMB_IPROBE_NOMINAL_MINLEN) {
1557 1559 iprobe->smbip_nominal = ip.smbipr_nominal;
1558 1560 } else {
1559 1561 iprobe->smbip_nominal = SMB_PROBE_UNKNOWN_VALUE;
1560 1562 }
1561 1563
1562 1564 return (0);
1563 1565 }
↓ open down ↓ |
845 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX