1*84ab085aSmws /* 2*84ab085aSmws * CDDL HEADER START 3*84ab085aSmws * 4*84ab085aSmws * The contents of this file are subject to the terms of the 5*84ab085aSmws * Common Development and Distribution License, Version 1.0 only 6*84ab085aSmws * (the "License"). You may not use this file except in compliance 7*84ab085aSmws * with the License. 8*84ab085aSmws * 9*84ab085aSmws * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*84ab085aSmws * or http://www.opensolaris.org/os/licensing. 11*84ab085aSmws * See the License for the specific language governing permissions 12*84ab085aSmws * and limitations under the License. 13*84ab085aSmws * 14*84ab085aSmws * When distributing Covered Code, include this CDDL HEADER in each 15*84ab085aSmws * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*84ab085aSmws * If applicable, add the following below this CDDL HEADER, with the 17*84ab085aSmws * fields enclosed by brackets "[]" replaced with your own identifying 18*84ab085aSmws * information: Portions Copyright [yyyy] [name of copyright owner] 19*84ab085aSmws * 20*84ab085aSmws * CDDL HEADER END 21*84ab085aSmws */ 22*84ab085aSmws 23*84ab085aSmws /* 24*84ab085aSmws * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 25*84ab085aSmws * Use is subject to license terms. 26*84ab085aSmws */ 27*84ab085aSmws 28*84ab085aSmws #pragma ident "%Z%%M% %I% %E% SMI" 29*84ab085aSmws 30*84ab085aSmws /* 31*84ab085aSmws * SMBIOS Information Routines 32*84ab085aSmws * 33*84ab085aSmws * The routines in this file are used to convert from the SMBIOS data format to 34*84ab085aSmws * a more reasonable and stable set of structures offered as part of our ABI. 35*84ab085aSmws * These functions take the general form: 36*84ab085aSmws * 37*84ab085aSmws * stp = smb_lookup_type(shp, foo); 38*84ab085aSmws * smb_foo_t foo; 39*84ab085aSmws * 40*84ab085aSmws * smb_info_bcopy(stp->smbst_hdr, &foo, sizeof (foo)); 41*84ab085aSmws * bzero(caller's struct); 42*84ab085aSmws * 43*84ab085aSmws * copy/convert foo members into caller's struct 44*84ab085aSmws * 45*84ab085aSmws * We copy the internal structure on to an automatic variable so as to avoid 46*84ab085aSmws * checks everywhere for structures that the BIOS has improperly truncated, and 47*84ab085aSmws * also to automatically handle the case of a structure that has been extended. 48*84ab085aSmws * When necessary, this code can use smb_gteq() to determine whether the SMBIOS 49*84ab085aSmws * data is of a particular revision that is supposed to contain a new field. 50*84ab085aSmws */ 51*84ab085aSmws 52*84ab085aSmws #include <sys/smbios_impl.h> 53*84ab085aSmws 54*84ab085aSmws /* 55*84ab085aSmws * A large number of SMBIOS structures contain a set of common strings used to 56*84ab085aSmws * describe a h/w component's serial number, manufacturer, etc. These fields 57*84ab085aSmws * helpfully have different names and offsets and sometimes aren't consistent. 58*84ab085aSmws * To simplify life for our clients, we factor these common things out into 59*84ab085aSmws * smbios_info_t, which can be retrieved for any structure. The following 60*84ab085aSmws * table describes the mapping from a given structure to the smbios_info_t. 61*84ab085aSmws */ 62*84ab085aSmws static const struct smb_infospec { 63*84ab085aSmws uint8_t is_type; /* structure type */ 64*84ab085aSmws uint8_t is_manu; /* manufacturer offset */ 65*84ab085aSmws uint8_t is_product; /* product name offset */ 66*84ab085aSmws uint8_t is_version; /* version offset */ 67*84ab085aSmws uint8_t is_serial; /* serial number offset */ 68*84ab085aSmws uint8_t is_asset; /* asset tag offset */ 69*84ab085aSmws uint8_t is_location; /* location string offset */ 70*84ab085aSmws uint8_t is_part; /* part number offset */ 71*84ab085aSmws } _smb_infospecs[] = { 72*84ab085aSmws { SMB_TYPE_SYSTEM, 73*84ab085aSmws offsetof(smb_system_t, smbsi_manufacturer), 74*84ab085aSmws offsetof(smb_system_t, smbsi_product), 75*84ab085aSmws offsetof(smb_system_t, smbsi_version), 76*84ab085aSmws offsetof(smb_system_t, smbsi_serial), 77*84ab085aSmws 0, 78*84ab085aSmws 0, 79*84ab085aSmws 0 }, 80*84ab085aSmws { SMB_TYPE_BASEBOARD, 81*84ab085aSmws offsetof(smb_bboard_t, smbbb_manufacturer), 82*84ab085aSmws offsetof(smb_bboard_t, smbbb_product), 83*84ab085aSmws offsetof(smb_bboard_t, smbbb_version), 84*84ab085aSmws offsetof(smb_bboard_t, smbbb_serial), 85*84ab085aSmws offsetof(smb_bboard_t, smbbb_asset), 86*84ab085aSmws offsetof(smb_bboard_t, smbbb_location), 87*84ab085aSmws 0 }, 88*84ab085aSmws { SMB_TYPE_CHASSIS, 89*84ab085aSmws offsetof(smb_chassis_t, smbch_manufacturer), 90*84ab085aSmws 0, 91*84ab085aSmws offsetof(smb_chassis_t, smbch_version), 92*84ab085aSmws offsetof(smb_chassis_t, smbch_serial), 93*84ab085aSmws offsetof(smb_chassis_t, smbch_asset), 94*84ab085aSmws 0, 95*84ab085aSmws 0 }, 96*84ab085aSmws { SMB_TYPE_PROCESSOR, 97*84ab085aSmws offsetof(smb_processor_t, smbpr_manufacturer), 98*84ab085aSmws 0, 99*84ab085aSmws offsetof(smb_processor_t, smbpr_version), 100*84ab085aSmws offsetof(smb_processor_t, smbpr_serial), 101*84ab085aSmws offsetof(smb_processor_t, smbpr_asset), 102*84ab085aSmws offsetof(smb_processor_t, smbpr_socket), 103*84ab085aSmws offsetof(smb_processor_t, smbpr_part) }, 104*84ab085aSmws { SMB_TYPE_CACHE, 105*84ab085aSmws 0, 106*84ab085aSmws 0, 107*84ab085aSmws 0, 108*84ab085aSmws 0, 109*84ab085aSmws 0, 110*84ab085aSmws offsetof(smb_cache_t, smbca_socket), 111*84ab085aSmws 0 }, 112*84ab085aSmws { SMB_TYPE_PORT, 113*84ab085aSmws 0, 114*84ab085aSmws 0, 115*84ab085aSmws 0, 116*84ab085aSmws 0, 117*84ab085aSmws 0, 118*84ab085aSmws offsetof(smb_port_t, smbpo_iref), 119*84ab085aSmws 0 }, 120*84ab085aSmws { SMB_TYPE_SLOT, 121*84ab085aSmws 0, 122*84ab085aSmws 0, 123*84ab085aSmws 0, 124*84ab085aSmws 0, 125*84ab085aSmws 0, 126*84ab085aSmws offsetof(smb_slot_t, smbsl_name), 127*84ab085aSmws 0 }, 128*84ab085aSmws { SMB_TYPE_MEMDEVICE, 129*84ab085aSmws offsetof(smb_memdevice_t, smbmdev_manufacturer), 130*84ab085aSmws 0, 131*84ab085aSmws 0, 132*84ab085aSmws offsetof(smb_memdevice_t, smbmdev_serial), 133*84ab085aSmws offsetof(smb_memdevice_t, smbmdev_asset), 134*84ab085aSmws offsetof(smb_memdevice_t, smbmdev_dloc), 135*84ab085aSmws offsetof(smb_memdevice_t, smbmdev_part) }, 136*84ab085aSmws { SMB_TYPE_POWERSUP, 137*84ab085aSmws offsetof(smb_powersup_t, smbpsup_manufacturer), 138*84ab085aSmws offsetof(smb_powersup_t, smbpsup_devname), 139*84ab085aSmws offsetof(smb_powersup_t, smbpsup_rev), 140*84ab085aSmws offsetof(smb_powersup_t, smbpsup_serial), 141*84ab085aSmws offsetof(smb_powersup_t, smbpsup_asset), 142*84ab085aSmws offsetof(smb_powersup_t, smbpsup_loc), 143*84ab085aSmws offsetof(smb_powersup_t, smbpsup_part) }, 144*84ab085aSmws { SMB_TYPE_EOT } 145*84ab085aSmws }; 146*84ab085aSmws 147*84ab085aSmws static const char * 148*84ab085aSmws smb_info_strptr(const smb_struct_t *stp, uint8_t off, int *n) 149*84ab085aSmws { 150*84ab085aSmws const uint8_t *sp = (const uint8_t *)(uintptr_t)stp->smbst_hdr; 151*84ab085aSmws 152*84ab085aSmws if (off != 0 && sp + off < stp->smbst_end) { 153*84ab085aSmws (*n)++; /* indicate success for caller */ 154*84ab085aSmws return (smb_strptr(stp, sp[off])); 155*84ab085aSmws } 156*84ab085aSmws 157*84ab085aSmws return (smb_strptr(stp, 0)); 158*84ab085aSmws } 159*84ab085aSmws 160*84ab085aSmws static void 161*84ab085aSmws smb_info_bcopy(const smb_header_t *hp, void *dst, size_t dstlen) 162*84ab085aSmws { 163*84ab085aSmws if (dstlen > hp->smbh_len) { 164*84ab085aSmws bcopy(hp, dst, hp->smbh_len); 165*84ab085aSmws bzero((char *)dst + hp->smbh_len, dstlen - hp->smbh_len); 166*84ab085aSmws } else 167*84ab085aSmws bcopy(hp, dst, dstlen); 168*84ab085aSmws } 169*84ab085aSmws 170*84ab085aSmws void 171*84ab085aSmws smbios_info_smbios(smbios_hdl_t *shp, smbios_entry_t *ep) 172*84ab085aSmws { 173*84ab085aSmws bcopy(&shp->sh_ent, ep, sizeof (smbios_entry_t)); 174*84ab085aSmws } 175*84ab085aSmws 176*84ab085aSmws int 177*84ab085aSmws smbios_info_common(smbios_hdl_t *shp, id_t id, smbios_info_t *ip) 178*84ab085aSmws { 179*84ab085aSmws const smb_struct_t *stp = smb_lookup_id(shp, id); 180*84ab085aSmws const struct smb_infospec *isp; 181*84ab085aSmws int n = 0; 182*84ab085aSmws 183*84ab085aSmws if (stp == NULL) 184*84ab085aSmws return (-1); /* errno is set for us */ 185*84ab085aSmws 186*84ab085aSmws for (isp = _smb_infospecs; isp->is_type != SMB_TYPE_EOT; isp++) { 187*84ab085aSmws if (isp->is_type == stp->smbst_hdr->smbh_type) 188*84ab085aSmws break; 189*84ab085aSmws } 190*84ab085aSmws 191*84ab085aSmws ip->smbi_manufacturer = smb_info_strptr(stp, isp->is_manu, &n); 192*84ab085aSmws ip->smbi_product = smb_info_strptr(stp, isp->is_product, &n); 193*84ab085aSmws ip->smbi_version = smb_info_strptr(stp, isp->is_version, &n); 194*84ab085aSmws ip->smbi_serial = smb_info_strptr(stp, isp->is_serial, &n); 195*84ab085aSmws ip->smbi_asset = smb_info_strptr(stp, isp->is_asset, &n); 196*84ab085aSmws ip->smbi_location = smb_info_strptr(stp, isp->is_location, &n); 197*84ab085aSmws ip->smbi_part = smb_info_strptr(stp, isp->is_part, &n); 198*84ab085aSmws 199*84ab085aSmws /* 200*84ab085aSmws * If we have a port with an empty internal reference designator string 201*84ab085aSmws * try using the external reference designator string instead. 202*84ab085aSmws */ 203*84ab085aSmws if (isp->is_type == SMB_TYPE_PORT && ip->smbi_location[0] == '\0') { 204*84ab085aSmws ip->smbi_location = smb_info_strptr(stp, 205*84ab085aSmws offsetof(smb_port_t, smbpo_eref), &n); 206*84ab085aSmws } 207*84ab085aSmws 208*84ab085aSmws return (n ? 0 : smb_set_errno(shp, ESMB_NOINFO)); 209*84ab085aSmws } 210*84ab085aSmws 211*84ab085aSmws id_t 212*84ab085aSmws smbios_info_bios(smbios_hdl_t *shp, smbios_bios_t *bp) 213*84ab085aSmws { 214*84ab085aSmws const smb_struct_t *stp = smb_lookup_type(shp, SMB_TYPE_BIOS); 215*84ab085aSmws const smb_bios_t *bip; 216*84ab085aSmws 217*84ab085aSmws if (stp == NULL) 218*84ab085aSmws return (-1); /* errno is set for us */ 219*84ab085aSmws 220*84ab085aSmws if (stp->smbst_hdr->smbh_len < sizeof (smb_bios_t) - sizeof (uint8_t)) 221*84ab085aSmws return (smb_set_errno(shp, ESMB_CORRUPT)); 222*84ab085aSmws 223*84ab085aSmws bip = (smb_bios_t *)(uintptr_t)stp->smbst_hdr; 224*84ab085aSmws bzero(bp, sizeof (smbios_bios_t)); 225*84ab085aSmws 226*84ab085aSmws bp->smbb_vendor = smb_strptr(stp, bip->smbbi_vendor); 227*84ab085aSmws bp->smbb_version = smb_strptr(stp, bip->smbbi_version); 228*84ab085aSmws bp->smbb_segment = bip->smbbi_segment; 229*84ab085aSmws bp->smbb_reldate = smb_strptr(stp, bip->smbbi_reldate); 230*84ab085aSmws bp->smbb_romsize = 64 * 1024 * ((uint32_t)bip->smbbi_romsize + 1); 231*84ab085aSmws bp->smbb_runsize = 16 * (0x10000 - (uint32_t)bip->smbbi_segment); 232*84ab085aSmws bp->smbb_cflags = bip->smbbi_cflags; 233*84ab085aSmws 234*84ab085aSmws /* 235*84ab085aSmws * If one or more extension bytes are present, reset smbb_xcflags to 236*84ab085aSmws * point to them. Otherwise leave this member set to NULL. 237*84ab085aSmws */ 238*84ab085aSmws if (stp->smbst_hdr->smbh_len >= sizeof (smb_bios_t)) { 239*84ab085aSmws bp->smbb_xcflags = bip->smbbi_xcflags; 240*84ab085aSmws bp->smbb_nxcflags = stp->smbst_hdr->smbh_len - 241*84ab085aSmws sizeof (smb_bios_t) + 1; 242*84ab085aSmws 243*84ab085aSmws if (bp->smbb_nxcflags > SMB_BIOSXB_ECFW_MIN && 244*84ab085aSmws smb_gteq(shp, SMB_VERSION_24)) { 245*84ab085aSmws bp->smbb_biosv.smbv_major = 246*84ab085aSmws bip->smbbi_xcflags[SMB_BIOSXB_BIOS_MAJ]; 247*84ab085aSmws bp->smbb_biosv.smbv_minor = 248*84ab085aSmws bip->smbbi_xcflags[SMB_BIOSXB_BIOS_MIN]; 249*84ab085aSmws bp->smbb_ecfwv.smbv_major = 250*84ab085aSmws bip->smbbi_xcflags[SMB_BIOSXB_ECFW_MAJ]; 251*84ab085aSmws bp->smbb_ecfwv.smbv_minor = 252*84ab085aSmws bip->smbbi_xcflags[SMB_BIOSXB_ECFW_MIN]; 253*84ab085aSmws } 254*84ab085aSmws } 255*84ab085aSmws 256*84ab085aSmws return (stp->smbst_hdr->smbh_hdl); 257*84ab085aSmws } 258*84ab085aSmws 259*84ab085aSmws id_t 260*84ab085aSmws smbios_info_system(smbios_hdl_t *shp, smbios_system_t *sip) 261*84ab085aSmws { 262*84ab085aSmws const smb_struct_t *stp = smb_lookup_type(shp, SMB_TYPE_SYSTEM); 263*84ab085aSmws smb_system_t si; 264*84ab085aSmws 265*84ab085aSmws if (stp == NULL) 266*84ab085aSmws return (-1); /* errno is set for us */ 267*84ab085aSmws 268*84ab085aSmws smb_info_bcopy(stp->smbst_hdr, &si, sizeof (si)); 269*84ab085aSmws bzero(sip, sizeof (smbios_system_t)); 270*84ab085aSmws 271*84ab085aSmws sip->smbs_uuid = ((smb_system_t *)stp->smbst_hdr)->smbsi_uuid; 272*84ab085aSmws sip->smbs_uuidlen = sizeof (si.smbsi_uuid); 273*84ab085aSmws sip->smbs_wakeup = si.smbsi_wakeup; 274*84ab085aSmws sip->smbs_sku = smb_strptr(stp, si.smbsi_sku); 275*84ab085aSmws sip->smbs_family = smb_strptr(stp, si.smbsi_family); 276*84ab085aSmws 277*84ab085aSmws return (stp->smbst_hdr->smbh_hdl); 278*84ab085aSmws } 279*84ab085aSmws 280*84ab085aSmws int 281*84ab085aSmws smbios_info_bboard(smbios_hdl_t *shp, id_t id, smbios_bboard_t *bbp) 282*84ab085aSmws { 283*84ab085aSmws const smb_struct_t *stp = smb_lookup_id(shp, id); 284*84ab085aSmws smb_bboard_t bb; 285*84ab085aSmws 286*84ab085aSmws if (stp == NULL) 287*84ab085aSmws return (-1); /* errno is set for us */ 288*84ab085aSmws 289*84ab085aSmws if (stp->smbst_hdr->smbh_type != SMB_TYPE_BASEBOARD) 290*84ab085aSmws return (smb_set_errno(shp, ESMB_TYPE)); 291*84ab085aSmws 292*84ab085aSmws smb_info_bcopy(stp->smbst_hdr, &bb, sizeof (bb)); 293*84ab085aSmws bzero(bbp, sizeof (smbios_bboard_t)); 294*84ab085aSmws 295*84ab085aSmws /* 296*84ab085aSmws * At present, we do not provide support for the contained object 297*84ab085aSmws * handles portion of the Base Board structure, as none of the 2.3+ 298*84ab085aSmws * BIOSes commonly in use appear to implement it at present. 299*84ab085aSmws */ 300*84ab085aSmws bbp->smbb_chassis = bb.smbbb_chassis; 301*84ab085aSmws bbp->smbb_flags = bb.smbbb_flags; 302*84ab085aSmws bbp->smbb_type = bb.smbbb_type; 303*84ab085aSmws 304*84ab085aSmws return (0); 305*84ab085aSmws } 306*84ab085aSmws 307*84ab085aSmws int 308*84ab085aSmws smbios_info_chassis(smbios_hdl_t *shp, id_t id, smbios_chassis_t *chp) 309*84ab085aSmws { 310*84ab085aSmws const smb_struct_t *stp = smb_lookup_id(shp, id); 311*84ab085aSmws smb_chassis_t ch; 312*84ab085aSmws 313*84ab085aSmws if (stp == NULL) 314*84ab085aSmws return (-1); /* errno is set for us */ 315*84ab085aSmws 316*84ab085aSmws if (stp->smbst_hdr->smbh_type != SMB_TYPE_CHASSIS) 317*84ab085aSmws return (smb_set_errno(shp, ESMB_TYPE)); 318*84ab085aSmws 319*84ab085aSmws smb_info_bcopy(stp->smbst_hdr, &ch, sizeof (ch)); 320*84ab085aSmws bzero(chp, sizeof (smbios_chassis_t)); 321*84ab085aSmws 322*84ab085aSmws /* 323*84ab085aSmws * At present, we do not provide support for the contained object 324*84ab085aSmws * handles portion of the Chassis structure, as none of the 2.3+ 325*84ab085aSmws * BIOSes commonly in use appear to implement it at present. 326*84ab085aSmws */ 327*84ab085aSmws chp->smbc_oemdata = ch.smbch_oemdata; 328*84ab085aSmws chp->smbc_lock = (ch.smbch_type & SMB_CHT_LOCK) != 0; 329*84ab085aSmws chp->smbc_type = ch.smbch_type & ~SMB_CHT_LOCK; 330*84ab085aSmws chp->smbc_bustate = ch.smbch_bustate; 331*84ab085aSmws chp->smbc_psstate = ch.smbch_psstate; 332*84ab085aSmws chp->smbc_thstate = ch.smbch_thstate; 333*84ab085aSmws chp->smbc_security = ch.smbch_security; 334*84ab085aSmws chp->smbc_uheight = ch.smbch_uheight; 335*84ab085aSmws chp->smbc_cords = ch.smbch_cords; 336*84ab085aSmws chp->smbc_elems = ch.smbch_cn; 337*84ab085aSmws 338*84ab085aSmws return (0); 339*84ab085aSmws } 340*84ab085aSmws 341*84ab085aSmws int 342*84ab085aSmws smbios_info_processor(smbios_hdl_t *shp, id_t id, smbios_processor_t *pp) 343*84ab085aSmws { 344*84ab085aSmws const smb_struct_t *stp = smb_lookup_id(shp, id); 345*84ab085aSmws smb_processor_t p; 346*84ab085aSmws 347*84ab085aSmws if (stp == NULL) 348*84ab085aSmws return (-1); /* errno is set for us */ 349*84ab085aSmws 350*84ab085aSmws if (stp->smbst_hdr->smbh_type != SMB_TYPE_PROCESSOR) 351*84ab085aSmws return (smb_set_errno(shp, ESMB_TYPE)); 352*84ab085aSmws 353*84ab085aSmws smb_info_bcopy(stp->smbst_hdr, &p, sizeof (p)); 354*84ab085aSmws bzero(pp, sizeof (smbios_processor_t)); 355*84ab085aSmws 356*84ab085aSmws pp->smbp_cpuid = p.smbpr_cpuid; 357*84ab085aSmws pp->smbp_type = p.smbpr_type; 358*84ab085aSmws pp->smbp_family = p.smbpr_family; 359*84ab085aSmws pp->smbp_voltage = p.smbpr_voltage; 360*84ab085aSmws pp->smbp_maxspeed = p.smbpr_maxspeed; 361*84ab085aSmws pp->smbp_curspeed = p.smbpr_curspeed; 362*84ab085aSmws pp->smbp_status = p.smbpr_status; 363*84ab085aSmws pp->smbp_upgrade = p.smbpr_upgrade; 364*84ab085aSmws pp->smbp_l1cache = p.smbpr_l1cache; 365*84ab085aSmws pp->smbp_l2cache = p.smbpr_l2cache; 366*84ab085aSmws pp->smbp_l3cache = p.smbpr_l3cache; 367*84ab085aSmws 368*84ab085aSmws return (0); 369*84ab085aSmws } 370*84ab085aSmws 371*84ab085aSmws int 372*84ab085aSmws smbios_info_cache(smbios_hdl_t *shp, id_t id, smbios_cache_t *cap) 373*84ab085aSmws { 374*84ab085aSmws const smb_struct_t *stp = smb_lookup_id(shp, id); 375*84ab085aSmws smb_cache_t c; 376*84ab085aSmws 377*84ab085aSmws if (stp == NULL) 378*84ab085aSmws return (-1); /* errno is set for us */ 379*84ab085aSmws 380*84ab085aSmws if (stp->smbst_hdr->smbh_type != SMB_TYPE_CACHE) 381*84ab085aSmws return (smb_set_errno(shp, ESMB_TYPE)); 382*84ab085aSmws 383*84ab085aSmws smb_info_bcopy(stp->smbst_hdr, &c, sizeof (c)); 384*84ab085aSmws bzero(cap, sizeof (smbios_cache_t)); 385*84ab085aSmws 386*84ab085aSmws cap->smba_maxsize = SMB_CACHE_SIZE(c.smbca_maxsize); 387*84ab085aSmws cap->smba_size = SMB_CACHE_SIZE(c.smbca_size); 388*84ab085aSmws cap->smba_stype = c.smbca_stype; 389*84ab085aSmws cap->smba_ctype = c.smbca_ctype; 390*84ab085aSmws cap->smba_speed = c.smbca_speed; 391*84ab085aSmws cap->smba_etype = c.smbca_etype; 392*84ab085aSmws cap->smba_ltype = c.smbca_ltype; 393*84ab085aSmws cap->smba_assoc = c.smbca_assoc; 394*84ab085aSmws cap->smba_level = SMB_CACHE_CFG_LEVEL(c.smbca_config); 395*84ab085aSmws cap->smba_mode = SMB_CACHE_CFG_MODE(c.smbca_config); 396*84ab085aSmws cap->smba_location = SMB_CACHE_CFG_LOCATION(c.smbca_config); 397*84ab085aSmws 398*84ab085aSmws if (SMB_CACHE_CFG_ENABLED(c.smbca_config)) 399*84ab085aSmws cap->smba_flags |= SMB_CAF_ENABLED; 400*84ab085aSmws 401*84ab085aSmws if (SMB_CACHE_CFG_SOCKETED(c.smbca_config)) 402*84ab085aSmws cap->smba_flags |= SMB_CAF_SOCKETED; 403*84ab085aSmws 404*84ab085aSmws return (0); 405*84ab085aSmws } 406*84ab085aSmws 407*84ab085aSmws int 408*84ab085aSmws smbios_info_port(smbios_hdl_t *shp, id_t id, smbios_port_t *pop) 409*84ab085aSmws { 410*84ab085aSmws const smb_struct_t *stp = smb_lookup_id(shp, id); 411*84ab085aSmws smb_port_t p; 412*84ab085aSmws 413*84ab085aSmws if (stp == NULL) 414*84ab085aSmws return (-1); /* errno is set for us */ 415*84ab085aSmws 416*84ab085aSmws if (stp->smbst_hdr->smbh_type != SMB_TYPE_PORT) 417*84ab085aSmws return (smb_set_errno(shp, ESMB_TYPE)); 418*84ab085aSmws 419*84ab085aSmws smb_info_bcopy(stp->smbst_hdr, &p, sizeof (p)); 420*84ab085aSmws bzero(pop, sizeof (smbios_port_t)); 421*84ab085aSmws 422*84ab085aSmws pop->smbo_iref = smb_strptr(stp, p.smbpo_iref); 423*84ab085aSmws pop->smbo_eref = smb_strptr(stp, p.smbpo_eref); 424*84ab085aSmws 425*84ab085aSmws pop->smbo_itype = p.smbpo_itype; 426*84ab085aSmws pop->smbo_etype = p.smbpo_etype; 427*84ab085aSmws pop->smbo_ptype = p.smbpo_ptype; 428*84ab085aSmws 429*84ab085aSmws return (0); 430*84ab085aSmws } 431*84ab085aSmws 432*84ab085aSmws int 433*84ab085aSmws smbios_info_slot(smbios_hdl_t *shp, id_t id, smbios_slot_t *sp) 434*84ab085aSmws { 435*84ab085aSmws const smb_struct_t *stp = smb_lookup_id(shp, id); 436*84ab085aSmws smb_slot_t s; 437*84ab085aSmws 438*84ab085aSmws if (stp == NULL) 439*84ab085aSmws return (-1); /* errno is set for us */ 440*84ab085aSmws 441*84ab085aSmws if (stp->smbst_hdr->smbh_type != SMB_TYPE_SLOT) 442*84ab085aSmws return (smb_set_errno(shp, ESMB_TYPE)); 443*84ab085aSmws 444*84ab085aSmws smb_info_bcopy(stp->smbst_hdr, &s, sizeof (s)); 445*84ab085aSmws bzero(sp, sizeof (smbios_slot_t)); 446*84ab085aSmws 447*84ab085aSmws sp->smbl_name = smb_strptr(stp, s.smbsl_name); 448*84ab085aSmws sp->smbl_type = s.smbsl_type; 449*84ab085aSmws sp->smbl_width = s.smbsl_width; 450*84ab085aSmws sp->smbl_usage = s.smbsl_usage; 451*84ab085aSmws sp->smbl_length = s.smbsl_length; 452*84ab085aSmws sp->smbl_id = s.smbsl_id; 453*84ab085aSmws sp->smbl_ch1 = s.smbsl_ch1; 454*84ab085aSmws sp->smbl_ch2 = s.smbsl_ch2; 455*84ab085aSmws 456*84ab085aSmws return (0); 457*84ab085aSmws } 458*84ab085aSmws 459*84ab085aSmws int 460*84ab085aSmws smbios_info_obdevs(smbios_hdl_t *shp, id_t id, int obc, smbios_obdev_t *obp) 461*84ab085aSmws { 462*84ab085aSmws const smb_struct_t *stp = smb_lookup_id(shp, id); 463*84ab085aSmws const smb_obdev_t *op; 464*84ab085aSmws int i, m, n; 465*84ab085aSmws 466*84ab085aSmws if (stp == NULL) 467*84ab085aSmws return (-1); /* errno is set for us */ 468*84ab085aSmws 469*84ab085aSmws if (stp->smbst_hdr->smbh_type != SMB_TYPE_OBDEVS) 470*84ab085aSmws return (smb_set_errno(shp, ESMB_TYPE)); 471*84ab085aSmws 472*84ab085aSmws op = (smb_obdev_t *)((uintptr_t)stp->smbst_hdr + sizeof (smb_header_t)); 473*84ab085aSmws m = (stp->smbst_hdr->smbh_len - sizeof (smb_header_t)) / sizeof (*op); 474*84ab085aSmws n = MIN(m, obc); 475*84ab085aSmws 476*84ab085aSmws for (i = 0; i < n; i++, op++, obp++) { 477*84ab085aSmws obp->smbd_name = smb_strptr(stp, op->smbob_name); 478*84ab085aSmws obp->smbd_type = op->smbob_type & ~SMB_OBT_ENABLED; 479*84ab085aSmws obp->smbd_enabled = (op->smbob_type & SMB_OBT_ENABLED) != 0; 480*84ab085aSmws } 481*84ab085aSmws 482*84ab085aSmws return (m); 483*84ab085aSmws } 484*84ab085aSmws 485*84ab085aSmws /* 486*84ab085aSmws * The implementation structures for OEMSTR, SYSCONFSTR, and LANG all use the 487*84ab085aSmws * first byte to indicate the size of a string table at the end of the record. 488*84ab085aSmws * Therefore, smbios_info_strtab() can be used to retrieve the table size and 489*84ab085aSmws * strings for any of these underlying record types. 490*84ab085aSmws */ 491*84ab085aSmws int 492*84ab085aSmws smbios_info_strtab(smbios_hdl_t *shp, id_t id, int argc, const char *argv[]) 493*84ab085aSmws { 494*84ab085aSmws const smb_struct_t *stp = smb_lookup_id(shp, id); 495*84ab085aSmws smb_strtab_t s; 496*84ab085aSmws int i, n; 497*84ab085aSmws 498*84ab085aSmws if (stp == NULL) 499*84ab085aSmws return (-1); /* errno is set for us */ 500*84ab085aSmws 501*84ab085aSmws if (stp->smbst_hdr->smbh_type != SMB_TYPE_OEMSTR && 502*84ab085aSmws stp->smbst_hdr->smbh_type != SMB_TYPE_SYSCONFSTR && 503*84ab085aSmws stp->smbst_hdr->smbh_type != SMB_TYPE_LANG) 504*84ab085aSmws return (smb_set_errno(shp, ESMB_TYPE)); 505*84ab085aSmws 506*84ab085aSmws smb_info_bcopy(stp->smbst_hdr, &s, sizeof (s)); 507*84ab085aSmws n = MIN(s.smbtb_count, argc); 508*84ab085aSmws 509*84ab085aSmws for (i = 0; i < n; i++) 510*84ab085aSmws argv[i] = smb_strptr(stp, i + 1); 511*84ab085aSmws 512*84ab085aSmws return (s.smbtb_count); 513*84ab085aSmws } 514*84ab085aSmws 515*84ab085aSmws id_t 516*84ab085aSmws smbios_info_lang(smbios_hdl_t *shp, smbios_lang_t *lp) 517*84ab085aSmws { 518*84ab085aSmws const smb_struct_t *stp = smb_lookup_type(shp, SMB_TYPE_LANG); 519*84ab085aSmws smb_lang_t l; 520*84ab085aSmws 521*84ab085aSmws if (stp == NULL) 522*84ab085aSmws return (-1); /* errno is set for us */ 523*84ab085aSmws 524*84ab085aSmws smb_info_bcopy(stp->smbst_hdr, &l, sizeof (l)); 525*84ab085aSmws bzero(lp, sizeof (smbios_lang_t)); 526*84ab085aSmws 527*84ab085aSmws lp->smbla_cur = smb_strptr(stp, l.smblang_cur); 528*84ab085aSmws lp->smbla_fmt = l.smblang_flags & 1; 529*84ab085aSmws lp->smbla_num = l.smblang_num; 530*84ab085aSmws 531*84ab085aSmws return (stp->smbst_hdr->smbh_hdl); 532*84ab085aSmws } 533*84ab085aSmws 534*84ab085aSmws id_t 535*84ab085aSmws smbios_info_eventlog(smbios_hdl_t *shp, smbios_evlog_t *evp) 536*84ab085aSmws { 537*84ab085aSmws const smb_struct_t *stp = smb_lookup_type(shp, SMB_TYPE_EVENTLOG); 538*84ab085aSmws const smb_sel_t *sel; 539*84ab085aSmws size_t len; 540*84ab085aSmws 541*84ab085aSmws if (stp == NULL) 542*84ab085aSmws return (-1); /* errno is set for us */ 543*84ab085aSmws 544*84ab085aSmws if (stp->smbst_hdr->smbh_len < sizeof (smb_sel_t) - sizeof (uint8_t)) 545*84ab085aSmws return (smb_set_errno(shp, ESMB_CORRUPT)); 546*84ab085aSmws 547*84ab085aSmws sel = (smb_sel_t *)(uintptr_t)stp->smbst_hdr; 548*84ab085aSmws len = stp->smbst_hdr->smbh_len - sizeof (smb_sel_t) + sizeof (uint8_t); 549*84ab085aSmws bzero(evp, sizeof (smbios_evlog_t)); 550*84ab085aSmws 551*84ab085aSmws if (len < sel->smbsel_typec * sel->smbsel_typesz) 552*84ab085aSmws return (smb_set_errno(shp, ESMB_CORRUPT)); 553*84ab085aSmws 554*84ab085aSmws evp->smbev_size = sel->smbsel_len; 555*84ab085aSmws evp->smbev_hdr = sel->smbsel_hdroff; 556*84ab085aSmws evp->smbev_data = sel->smbsel_dataoff; 557*84ab085aSmws evp->smbev_method = sel->smbsel_method; 558*84ab085aSmws evp->smbev_flags = sel->smbsel_status; 559*84ab085aSmws evp->smbev_format = sel->smbsel_format; 560*84ab085aSmws evp->smbev_token = sel->smbsel_token; 561*84ab085aSmws evp->smbev_addr.eva_addr = sel->smbsel_addr; 562*84ab085aSmws 563*84ab085aSmws if (sel->smbsel_typesz == sizeof (smbios_evtype_t)) { 564*84ab085aSmws evp->smbev_typec = sel->smbsel_typec; 565*84ab085aSmws evp->smbev_typev = (void *)(uintptr_t)sel->smbsel_typev; 566*84ab085aSmws } 567*84ab085aSmws 568*84ab085aSmws return (stp->smbst_hdr->smbh_hdl); 569*84ab085aSmws } 570*84ab085aSmws 571*84ab085aSmws int 572*84ab085aSmws smbios_info_memarray(smbios_hdl_t *shp, id_t id, smbios_memarray_t *map) 573*84ab085aSmws { 574*84ab085aSmws const smb_struct_t *stp = smb_lookup_id(shp, id); 575*84ab085aSmws smb_memarray_t m; 576*84ab085aSmws 577*84ab085aSmws if (stp == NULL) 578*84ab085aSmws return (-1); /* errno is set for us */ 579*84ab085aSmws 580*84ab085aSmws if (stp->smbst_hdr->smbh_type != SMB_TYPE_MEMARRAY) 581*84ab085aSmws return (smb_set_errno(shp, ESMB_TYPE)); 582*84ab085aSmws 583*84ab085aSmws smb_info_bcopy(stp->smbst_hdr, &m, sizeof (m)); 584*84ab085aSmws bzero(map, sizeof (smbios_memarray_t)); 585*84ab085aSmws 586*84ab085aSmws map->smbma_location = m.smbmarr_loc; 587*84ab085aSmws map->smbma_use = m.smbmarr_use; 588*84ab085aSmws map->smbma_ecc = m.smbmarr_ecc; 589*84ab085aSmws map->smbma_ndevs = m.smbmarr_ndevs; 590*84ab085aSmws map->smbma_err = m.smbmarr_err; 591*84ab085aSmws 592*84ab085aSmws if (m.smbmarr_cap != 0x80000000) 593*84ab085aSmws map->smbma_size = (uint64_t)m.smbmarr_cap * 1024; 594*84ab085aSmws else 595*84ab085aSmws map->smbma_size = 0; /* unknown */ 596*84ab085aSmws 597*84ab085aSmws return (0); 598*84ab085aSmws } 599*84ab085aSmws 600*84ab085aSmws int 601*84ab085aSmws smbios_info_memarrmap(smbios_hdl_t *shp, id_t id, smbios_memarrmap_t *map) 602*84ab085aSmws { 603*84ab085aSmws const smb_struct_t *stp = smb_lookup_id(shp, id); 604*84ab085aSmws smb_memarrmap_t m; 605*84ab085aSmws 606*84ab085aSmws if (stp == NULL) 607*84ab085aSmws return (-1); /* errno is set for us */ 608*84ab085aSmws 609*84ab085aSmws if (stp->smbst_hdr->smbh_type != SMB_TYPE_MEMARRAYMAP) 610*84ab085aSmws return (smb_set_errno(shp, ESMB_TYPE)); 611*84ab085aSmws 612*84ab085aSmws smb_info_bcopy(stp->smbst_hdr, &m, sizeof (m)); 613*84ab085aSmws bzero(map, sizeof (smbios_memarrmap_t)); 614*84ab085aSmws 615*84ab085aSmws map->smbmam_array = m.smbamap_array; 616*84ab085aSmws map->smbmam_width = m.smbamap_width; 617*84ab085aSmws map->smbmam_addr = (uint64_t)m.smbamap_start * 1024; 618*84ab085aSmws map->smbmam_size = (uint64_t) 619*84ab085aSmws (m.smbamap_end - m.smbamap_start + 1) * 1024; 620*84ab085aSmws 621*84ab085aSmws return (0); 622*84ab085aSmws } 623*84ab085aSmws 624*84ab085aSmws int 625*84ab085aSmws smbios_info_memdevice(smbios_hdl_t *shp, id_t id, smbios_memdevice_t *mdp) 626*84ab085aSmws { 627*84ab085aSmws const smb_struct_t *stp = smb_lookup_id(shp, id); 628*84ab085aSmws smb_memdevice_t m; 629*84ab085aSmws 630*84ab085aSmws if (stp == NULL) 631*84ab085aSmws return (-1); /* errno is set for us */ 632*84ab085aSmws 633*84ab085aSmws if (stp->smbst_hdr->smbh_type != SMB_TYPE_MEMDEVICE) 634*84ab085aSmws return (smb_set_errno(shp, ESMB_TYPE)); 635*84ab085aSmws 636*84ab085aSmws smb_info_bcopy(stp->smbst_hdr, &m, sizeof (m)); 637*84ab085aSmws bzero(mdp, sizeof (smbios_memdevice_t)); 638*84ab085aSmws 639*84ab085aSmws mdp->smbmd_array = m.smbmdev_array; 640*84ab085aSmws mdp->smbmd_error = m.smbmdev_error; 641*84ab085aSmws mdp->smbmd_twidth = m.smbmdev_twidth == 0xFFFF ? -1U : m.smbmdev_twidth; 642*84ab085aSmws mdp->smbmd_dwidth = m.smbmdev_dwidth == 0xFFFF ? -1U : m.smbmdev_dwidth; 643*84ab085aSmws 644*84ab085aSmws if (mdp->smbmd_size != 0xFFFF) { 645*84ab085aSmws mdp->smbmd_size = (uint64_t)(m.smbmdev_size & ~SMB_MDS_KBYTES); 646*84ab085aSmws if (m.smbmdev_size & SMB_MDS_KBYTES) 647*84ab085aSmws mdp->smbmd_size *= 1024; 648*84ab085aSmws else 649*84ab085aSmws mdp->smbmd_size *= 1024 * 1024; 650*84ab085aSmws } else 651*84ab085aSmws mdp->smbmd_size = -1ULL; /* size unknown */ 652*84ab085aSmws 653*84ab085aSmws mdp->smbmd_form = m.smbmdev_form; 654*84ab085aSmws mdp->smbmd_set = m.smbmdev_set; 655*84ab085aSmws mdp->smbmd_type = m.smbmdev_type; 656*84ab085aSmws mdp->smbmd_flags = m.smbmdev_flags; 657*84ab085aSmws mdp->smbmd_dloc = smb_strptr(stp, m.smbmdev_dloc); 658*84ab085aSmws mdp->smbmd_bloc = smb_strptr(stp, m.smbmdev_bloc); 659*84ab085aSmws 660*84ab085aSmws if (m.smbmdev_speed != 0) 661*84ab085aSmws mdp->smbmd_speed = 1000 / m.smbmdev_speed; /* MHz -> nsec */ 662*84ab085aSmws 663*84ab085aSmws return (0); 664*84ab085aSmws } 665*84ab085aSmws 666*84ab085aSmws int 667*84ab085aSmws smbios_info_memdevmap(smbios_hdl_t *shp, id_t id, smbios_memdevmap_t *mdp) 668*84ab085aSmws { 669*84ab085aSmws const smb_struct_t *stp = smb_lookup_id(shp, id); 670*84ab085aSmws smb_memdevmap_t m; 671*84ab085aSmws 672*84ab085aSmws if (stp == NULL) 673*84ab085aSmws return (-1); /* errno is set for us */ 674*84ab085aSmws 675*84ab085aSmws if (stp->smbst_hdr->smbh_type != SMB_TYPE_MEMDEVICEMAP) 676*84ab085aSmws return (smb_set_errno(shp, ESMB_TYPE)); 677*84ab085aSmws 678*84ab085aSmws smb_info_bcopy(stp->smbst_hdr, &m, sizeof (m)); 679*84ab085aSmws bzero(mdp, sizeof (smbios_memdevmap_t)); 680*84ab085aSmws 681*84ab085aSmws mdp->smbmdm_device = m.smbdmap_device; 682*84ab085aSmws mdp->smbmdm_arrmap = m.smbdmap_array; 683*84ab085aSmws mdp->smbmdm_addr = (uint64_t)m.smbdmap_start * 1024; 684*84ab085aSmws mdp->smbmdm_size = (uint64_t) 685*84ab085aSmws (m.smbdmap_end - m.smbdmap_start + 1) * 1024; 686*84ab085aSmws mdp->smbmdm_rpos = m.smbdmap_rpos; 687*84ab085aSmws mdp->smbmdm_ipos = m.smbdmap_ipos; 688*84ab085aSmws mdp->smbmdm_idepth = m.smbdmap_idepth; 689*84ab085aSmws 690*84ab085aSmws return (0); 691*84ab085aSmws } 692*84ab085aSmws 693*84ab085aSmws id_t 694*84ab085aSmws smbios_info_hwsec(smbios_hdl_t *shp, smbios_hwsec_t *hsp) 695*84ab085aSmws { 696*84ab085aSmws const smb_struct_t *stp = smb_lookup_type(shp, SMB_TYPE_SECURITY); 697*84ab085aSmws smb_hwsec_t hs; 698*84ab085aSmws 699*84ab085aSmws if (stp == NULL) 700*84ab085aSmws return (-1); /* errno is set for us */ 701*84ab085aSmws 702*84ab085aSmws smb_info_bcopy(stp->smbst_hdr, &hs, sizeof (hs)); 703*84ab085aSmws bzero(hsp, sizeof (smbios_hwsec_t)); 704*84ab085aSmws 705*84ab085aSmws hsp->smbh_pwr_ps = SMB_HWS_PWR_PS(hs.smbhs_settings); 706*84ab085aSmws hsp->smbh_kbd_ps = SMB_HWS_KBD_PS(hs.smbhs_settings); 707*84ab085aSmws hsp->smbh_adm_ps = SMB_HWS_ADM_PS(hs.smbhs_settings); 708*84ab085aSmws hsp->smbh_pan_ps = SMB_HWS_PAN_PS(hs.smbhs_settings); 709*84ab085aSmws 710*84ab085aSmws return (stp->smbst_hdr->smbh_hdl); 711*84ab085aSmws } 712*84ab085aSmws 713*84ab085aSmws id_t 714*84ab085aSmws smbios_info_boot(smbios_hdl_t *shp, smbios_boot_t *bp) 715*84ab085aSmws { 716*84ab085aSmws const smb_struct_t *stp = smb_lookup_type(shp, SMB_TYPE_BOOT); 717*84ab085aSmws const smb_boot_t *b = (smb_boot_t *)(uintptr_t)stp->smbst_hdr; 718*84ab085aSmws 719*84ab085aSmws if (stp == NULL) 720*84ab085aSmws return (-1); /* errno is set for us */ 721*84ab085aSmws 722*84ab085aSmws bzero(bp, sizeof (smbios_boot_t)); 723*84ab085aSmws 724*84ab085aSmws bp->smbt_status = b->smbbo_status[0]; 725*84ab085aSmws bp->smbt_size = stp->smbst_hdr->smbh_len - sizeof (smb_boot_t); 726*84ab085aSmws bp->smbt_data = bp->smbt_size ? &b->smbbo_status[1] : NULL; 727*84ab085aSmws 728*84ab085aSmws return (stp->smbst_hdr->smbh_hdl); 729*84ab085aSmws } 730*84ab085aSmws 731*84ab085aSmws id_t 732*84ab085aSmws smbios_info_ipmi(smbios_hdl_t *shp, smbios_ipmi_t *ip) 733*84ab085aSmws { 734*84ab085aSmws const smb_struct_t *stp = smb_lookup_type(shp, SMB_TYPE_IPMIDEV); 735*84ab085aSmws smb_ipmi_t i; 736*84ab085aSmws 737*84ab085aSmws if (stp == NULL) 738*84ab085aSmws return (-1); /* errno is set for us */ 739*84ab085aSmws 740*84ab085aSmws smb_info_bcopy(stp->smbst_hdr, &i, sizeof (i)); 741*84ab085aSmws bzero(ip, sizeof (smbios_ipmi_t)); 742*84ab085aSmws 743*84ab085aSmws ip->smbip_type = i.smbipm_type; 744*84ab085aSmws ip->smbip_vers.smbv_major = SMB_IPM_SPEC_MAJOR(i.smbipm_spec); 745*84ab085aSmws ip->smbip_vers.smbv_minor = SMB_IPM_SPEC_MINOR(i.smbipm_spec); 746*84ab085aSmws ip->smbip_i2c = i.smbipm_i2c; 747*84ab085aSmws ip->smbip_addr = i.smbipm_addr & ~SMB_IPM_ADDR_IO; 748*84ab085aSmws ip->smbip_intr = i.smbipm_intr; 749*84ab085aSmws 750*84ab085aSmws if (i.smbipm_bus != (uint8_t)-1) 751*84ab085aSmws ip->smbip_bus = i.smbipm_bus; 752*84ab085aSmws else 753*84ab085aSmws ip->smbip_bus = -1u; 754*84ab085aSmws 755*84ab085aSmws if (SMB_IPM_INFO_LSB(i.smbipm_info)) 756*84ab085aSmws ip->smbip_addr |= 1; /* turn on least-significant bit of addr */ 757*84ab085aSmws 758*84ab085aSmws if (i.smbipm_addr & SMB_IPM_ADDR_IO) { 759*84ab085aSmws switch (SMB_IPM_INFO_REGS(i.smbipm_info)) { 760*84ab085aSmws case SMB_IPM_REGS_1B: 761*84ab085aSmws ip->smbip_regspacing = 1; 762*84ab085aSmws break; 763*84ab085aSmws case SMB_IPM_REGS_4B: 764*84ab085aSmws ip->smbip_regspacing = 4; 765*84ab085aSmws break; 766*84ab085aSmws case SMB_IPM_REGS_16B: 767*84ab085aSmws ip->smbip_regspacing = 16; 768*84ab085aSmws break; 769*84ab085aSmws default: 770*84ab085aSmws ip->smbip_regspacing = 1; 771*84ab085aSmws } 772*84ab085aSmws ip->smbip_flags |= SMB_IPMI_F_IOADDR; 773*84ab085aSmws } 774*84ab085aSmws 775*84ab085aSmws if (SMB_IPM_INFO_ISPEC(i.smbipm_info)) 776*84ab085aSmws ip->smbip_flags |= SMB_IPMI_F_INTRSPEC; 777*84ab085aSmws 778*84ab085aSmws if (SMB_IPM_INFO_IPOL(i.smbipm_info) == SMB_IPM_IPOL_HI) 779*84ab085aSmws ip->smbip_flags |= SMB_IPMI_F_INTRHIGH; 780*84ab085aSmws 781*84ab085aSmws if (SMB_IPM_INFO_IMODE(i.smbipm_info) == SMB_IPM_IMODE_EDGE) 782*84ab085aSmws ip->smbip_flags |= SMB_IPMI_F_INTREDGE; 783*84ab085aSmws 784*84ab085aSmws return (stp->smbst_hdr->smbh_hdl); 785*84ab085aSmws } 786