/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
/*
* Create bay topology node from SMBIOS Type 136 structure, call the disk
* enumerator to enumerate a SATA direct attached disk.
*/
#include <strings.h>
#include <fm/topo_mod.h>
#include <sys/systeminfo.h>
#include <sys/smbios_impl.h>
#include <x86pi_impl.h>
1
};
1
};
/*
*/
int
{
int devt;
char *f = "bay_bdf";
return (-1);
}
/*
* Depending on device type, BDF comes from either slot (type-9) or
* on-board (type-41) SMBIOS structure.
*/
if (devt == SMB_TYPE_SLOT) {
} else if (devt == SMB_TYPE_OBDEVEXT) {
} else {
f, devt);
return (-1);
}
return (0);
}
/*
* Decorate topo node with pgroups.
*/
int
char *minor_name)
{
char *f = "bay_pgoups";
/*
* Create "io" pgroup and attachment point path.
*/
if (rv != 0) {
"%s: failed to create \"io\" pgroup: %s\n",
f, topo_strerror(err));
return (err);
}
}
/* add ap-path */
if (rv != 0) {
f, topo_strerror(err));
return (err);
}
/*
* Create "binding" pgroup and occupant path.
*/
if (rv != 0) {
"%s: failed to create \"io\" pgroup: %s\n",
f, topo_strerror(err));
return (err);
}
return (-1);
}
/* add ocupant-path */
&err);
if (rv != 0) {
f, topo_strerror(err));
return (err);
}
/*
* Now that we have an occupant path, go see if there is an alias set
* for it. If there is, set FM_FMRI_AUTH_V1_CHASSIS_ALIAS in the bay
* node and in it's (chassis) parent (direct attached storage is always
* a child of a chassis).
*/
return (0);
}
int
{
int rv;
int minor_cnt = 0;
char *f = "bay_update_tnode";
/*
* Find HBA device node from BDF.
*/
if (devtree == DI_NODE_NIL) {
return (-1);
}
dnode != DI_NODE_NIL;
/*
* Match child node from PHY.
*/
while (sib != DI_NODE_NIL) {
break;
}
break;
}
}
if (dnode == DI_NODE_NIL) {
}
/*
* HBA attachment point minor node name.
*/
strlen(DDI_NT_SATA_ATTACHMENT_POINT)) == 0) {
"%s: phy(%d) minor name(%s)\n",
f, phy, minor_name);
break;
}
}
}
if (rv != 0) {
return (-1);
}
return (0);
}
/*
* x86pi_gen_bay:
* enumerate all bays associated with this system:
* x86pi_gen_sas_bay(): enumerate SAS direct attached bays
* x86pi_gen_sata_bay(): enumerate SATA direct attached bays
* x86pi_gen_expander_bay(): enumerate bays behind an internal ses
*/
void
{
int i, rv;
int max_inst_exp_bay = 0;
int disk_inst = 0;
char *f = "x86pi_gen_bay";
/*
* Calls a routine that initiates enumeration of expander
* attached internal drives.
* The max_inst_exp_bay value indicates that the max instance
* number used in the ses enumerator if any expander attached
* internal drives are processed.
*/
if (rv != 0) {
"%s: Failed to enumerate expander attached "
"internal bays. Continue on.", f);
} else {
/*
* some expadner attached bay is enumerated.
*/
if (max_inst_exp_bay != 0) {
}
}
/* count SMBIOS extended port connector structures */
/*
* enumerate direct attached SATA disks if we found a
* SUN_OEM_EXT_PORT record.
*/
/* get smbios handle */
return;
}
if (rv == 0) {
&export);
if (rv == 0) {
/* belong to this chassis? */
if (export.smbporte_chassis ==
ch_smbid) {
/*
* x86pi_gen_sata_bay:
* create "bay" node
* call "disk" enum passing
* in "bay" node
*/
if (rv != 0) {
"%s: Failed to "
"create disk %d\n",
f, i);
}
disk_inst++;
}
} else {
"%s: smbios_info_export failed: id "
}
}
} else {
"%s: Failed to create %s range: %s\n",
}
}
/*
* Call the bay enumerator to enumerate any SAS direct
* attached disks.
*/
if (rv != 0) {
"%s: Failed to enumerate sas direct attached "
"bays.", f);
}
}
/*
* x86pi_gen_expander_bay:
* call "ses" enum with a flag indicating that the request is related
* to internal enclosure.
*/
int
{
int rv;
char *f = "x86pi_gen_expander_bay";
return (topo_mod_errno(mod));
}
/*
* Call the ses enumerator to process expander attached bays.
* By passing SES_ENCLOSURE node name here the ses enumerator will
* process an internal enclousure and find expander attached internal
* drives through SES ARRAY device elements.
*
* Currently other places that ses enumerator is called are
* some platform specific mapfiles. Those calls are intended
* to enumerate an external enclosure or disk nodes through
* legacy enumeration. They end up in topo_xml.c which sets
* the arg for the flag to NULL.
*
* If there is any expander attached internal bays the highest
* instance nubmer is returned to the max inst var.
*/
if (rv != 0) {
"enumeration failed: %s\n", f,
return (topo_mod_errno(mod));
}
"%s: done. Max instance for expander attached bays: %d.\n", f,
*max_inst);
return (0);
}
/*
* x86pi_gen_sas_bay:
* Call "bay" enum to enumerate SAS direct attached disks passing in the
* 'chassis' topo parent node and the current 'bay' instance.
*/
int
{
int rv;
char *f = "x86pi_gen_sas_bay";
return (topo_mod_errno(mod));
}
if (rv != 0) {
return (topo_mod_errno(mod));
}
return (0);
}
/*
* x86pi_gen_bay:
* create "bay" node
* call "disk" enum passing in "bay" node
*/
int
int instance)
{
int rv;
char *f = "x86pi_gen_sata_bay";
}
/*
* Label comes from the port (type-8) SMBIOS structure.
*/
if (rv != 0) {
"%s: failed to get port %d SMBIOS struct\n",
f, port_id);
}
/*
* Fill in hcfmri info.
*/
LABEL);
/*
* Create "bay" node.
*/
if (rv != 0) {
"%s: failed to create %s topo node: %d\n",
}
/* free up location string */
}
/*
* Determine the bay BDF.
*/
if (rv != 0) {
}
/*
* Decorate bay topo node.
*/
if (rv != 0) {
/*
* Message the failure but we still want to call the disk
* enum to notify CRO of empty bays.
*/
}
/*
* Call disk enum passing in decorated bay topo node.
*/
return (topo_mod_errno(mod));
}
if (rv != 0) {
return (topo_mod_errno(mod));
}
if (rv != 0) {
return (topo_mod_errno(mod));
}
return (0);
}