/*
* 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 a topology node for a PRI node of type 'bay'. Call the disk
* enumerator to enumerate any disks that may be attached.
*/
#include <strings.h>
#include <fm/topo_mod.h>
#include <libdevinfo.h>
#include <bay.h>
#include "pi_impl.h"
1
};
1
};
/*
* Return the MPxIO occupant path bay property.
*
* The string must be freed with topo_mod_strfree().
*/
static char *
{
int lun;
/* 'target-port' property */
"'target-port' property\n");
return (NULL);
}
/* 'lun' property */
"property\n");
return (NULL);
}
/* 'target-port' leading 'w' is not consistent */
/*
* Build occupatnt path:
* 'devfs_path' + "/disk@w" + 'target-port' + "," + 'lun'
*/
"pi_bay_ocpath: failed to get devfs path\n");
return (NULL);
}
}
/*
* Create bay "io" pgroup, create and add "ap_path" property.
* Create bay "binding" pgroup, create and add "oc_path" property.
* Set chassis alias.
*/
static int
{
int rv;
int err;
char *ap_path;
/* Create "io" pgroup. */
if (rv != 0) {
goto out;
}
/* Allocate what we need first, then create the properties */
"ap_path\n");
goto out;
}
/* attachment point path: "/devices" + minor node path */
if (minor_path == NULL) {
"pi_bay_pgroups: failed to get minor path\n");
goto out;
}
/* add ap_path prop to io pgroup */
if (rv != 0) {
goto out;
}
/* Create "binding" pgroup. */
if (rv != 0) {
goto out;
}
/*
* Create the oc_path property:
*/
if (MPxIO_ENABLED) {
} else {
}
rv = -1;
goto out;
}
/* add oc_path to binding pgroup */
if (rv != 0) {
goto out;
}
/* set chassis alias */
/* no matching devchassis path; try client */
int lun;
/* 'target-port' prop */
"pi_bay_pgroups: failed to get target-port\n");
goto out;
}
/* 'lun' prop */
"pi_bay_pgroups: invalid lun (%d)\n", lun);
goto out;
}
if (client_oc_path != NULL) {
} else {
"failed to set chassis alias.\n");
}
}
out:
if (MPxIO_ENABLED) {
} else {
}
}
return (rv);
}
/*
* Find the child devinfo node of the HBA that matches the PHY, capture the
* minor attachment point node.
*/
static void
{
/*
* When MPxIO is enabled the child node of the HBA (iport) contains
* the pathinfo property we're looking for; when MPxIO is disabled
* the grand-child of the HBA (disk) contains the devinfo property
* we're looking for.
*/
while (sib != DI_NODE_NIL) {
/* match the PHY */
DI_MINOR_NIL) {
/* scsi attachment point */
goto out;
}
}
} else {
/* look in grandchildren */
while (gsib != DI_NODE_NIL) {
/* match the PHY */
minor)) != DI_MINOR_NIL) {
/* scsi attachment point */
if (strncmp(
minor))) == 0) {
goto out;
}
}
}
}
}
}
out:
if (sib == DI_NODE_NIL) {
*sibp = DI_NODE_NIL;
} else {
}
if (minor == DI_MINOR_NIL) {
*minorp = DI_MINOR_NIL;
} else {
}
}
/*
* Find the HBA devinfo node associated with the path.
*/
static di_node_t
{
/*
* The hba path and bay PHY come from the PRI; find the
* driver node that coresponds to the PHY and it's minor
* node name and create the occupant path/attachmeent_point
* path
*/
if (devtree == DI_NODE_NIL) {
"pi_bay_hba_node: failed to get devtree\n");
goto bad;
}
dnode != DI_NODE_NIL;
/* find the dnode path that matches the pri path */
/* found our dnode */
break;
}
}
if (dnode == DI_NODE_NIL) {
"devinfo path.\n");
goto bad;
}
return (dnode);
bad:
return (DI_NODE_NIL);
}
/*
* Decorate "bay" node with required properties for disk enumerator.
*/
static int
{
int rv;
char *mpxio_prop;
/*
* The "mpxio-disable" variable determines if MPxIO (multipathing)
* is disabled (or enabled).
*/
&mpxio_prop) < 0) {
/* no way to determine if MPxIO is enabled */
"pi_bay_update_node: no \"mpxio-disable\" property\n");
goto bad;
}
/* set MPxIO_ENABLED inverse to "mpxio-disable" */
"FALSE");
/*
* Find the child node matching the PRI phy_number and determine the
* minor attachment point.
*/
"PHY %d.\n", phy);
goto bad;
}
/* add pgroups */
if (rv != 0) {
"pgroups.\n", _ENUM_NAME);
goto bad;
}
return (0);
bad:
return (-1);
}
/* ARGSUSED */
int
{
int i, rv;
int num_arcs;
int nphy;
int nodisk;
char *hba_pri_path;
/* count how many PHYs the bay node has */
if (nphy <= 0) {
rv = -1;
goto out;
}
rv = -1;
goto out;
}
/* get the PHY(s) for this bay node */
rv = -1;
goto out;
}
/* determine how many parent (HBA) nodes */
if (num_arcs == 0) {
rv = -1;
goto out;
}
/* get the "back" nodes */
goto out;
}
/* make sure there are as many HBA nodes as PHYs */
rv = -1;
goto out;
}
/* create topo bay node for each HBA attached to this bay */
for (i = 0; i < num_arcs; i++) {
nodisk = 0;
/* skip if topo-hc-skip = 1 */
continue;
}
/* must be an ses expander if no path property - skip */
strlen(hba_pri_path) == 0) {
continue;
}
/*
* Create a generic "bay" node; decorate below.
*
* If we have more than one HBA the bay inst here will be
* the same for both. This is okay since the paths will
* be different for each HBA.
*/
"%s: node_0x%llx failed to create topo node: %s\n",
rv = -1;
goto out;
}
/* grab the hba dnode */
if (hba_dnode == DI_NODE_NIL) {
"%s: failed to find HBA devinfo node\n");
continue;
}
/*
* Call the bay enum to create bay topo facility nodes.
*/
/* create tnode specific bay_t */
"%s: no memory for bay_t\n", _ENUM_NAME);
goto out;
}
0, 0, NULL);
if (rv != 0) {
"FAILED TO ENUM BAY: %s\n",
/* drive on */
}
} else {
"FAILED TO LOAD BAY MODULE: %s.\n",
/* drive on */
}
/* Decorate the bay tnode */
if (rv != 0) {
/*
* Message the failure but we still want to call the
* disk enum to notify CRO of empty bays.
*/
"node_0x%llx\n",
nodisk = 1;
}
/*
* Call the disk enum passing in decorated bay tnode.
*/
"%s: Failed to load %s module: %s\n",
goto out;
}
if (rv != 0) {
"%s: failed to create range: %s\n", _ENUM_NAME,
goto out;
}
NULL);
if (rv != 0) {
"%s: %s enumeration failed: %s\n", _ENUM_NAME,
goto out;
}
if (nodisk)
continue;
}
rv = 0;
out:
/* cleanup */
}
}
return (rv);
}