/*
* 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
*/
/*
*/
#include <devid.h>
#include <strings.h>
#include <fcntl.h>
#include <unistd.h>
#include <stropts.h>
#include <strings.h>
#include <stddef.h>
#include <pthread.h>
#include <inttypes.h>
#include <fm/topo_mod.h>
#include <fm/topo_list.h>
#include <sys/systeminfo.h>
#include <sys/pci_tools.h>
#include <bay_impl.h>
extern int hba_node_cnt;
/*
* Routines used by the bay,so topo enumerator.
*/
/*
* Create "target-port-l0ids" property.
*/
int
{
int err;
int rv;
char *f = "create_l0ids";
if (rv != 0) {
goto out;
}
f);
goto out;
}
if (rv != 0) {
/* look at the child */
if (rv != 0) {
"%s: failed to get \'target-port\'\n", f);
goto out;
}
}
goto out;
}
if (rv != 0) {
goto out;
}
return (0);
out:
}
return (-1);
}
/*
* Return the minor attachment point node.
*/
/* ARGSUSED */
{
return (minor);
}
}
return (DI_MINOR_NIL);
}
/*
* return the child node which matches the phy.
*/
/* ARGSUSED */
int
int phy)
{
while (cnode != DI_NODE_NIL) {
return (0);
}
}
return (0);
}
}
/* no PHY found */
return (-1);
}
/*
* Create the attachment point path.
*/
char *
{
/* ap_path = "/devices" + minor node path */
}
/*
* Return the generated generic slot label.
*
* The caller is responsible to free memory.
*/
char *
{
char *f = "generic_label";
/* grab the topo pci label */
/* get the generic name from the class code */
/* no generic name, use node name */
if (gen_node_name == NULL) {
}
/* create the label */
/* clean up */
}
if (gen_node_name != NULL) {
}
}
/* return label */
}
/*
* Return TRUE if chassis label is an 'internal' chassis.
*/
{
return (B_TRUE);
}
return (B_FALSE);
}
/*
* Generate the occupant path.
*/
char *
{
int rv;
int lun;
char *f = "gen_oc";
/* dev path */
if (pnode != DI_PATH_NIL) {
goto done;
}
if (dnode != DI_NODE_NIL) {
} else {
goto out;
}
/* 'target-port' prop */
if (target_port == NULL) {
goto out;
}
if (rv != 0) {
goto out;
}
/* 'lun' prop */
goto out;
}
/* leading 'w' is not always consistent */
/* oc_path = devfs path + "/disk@w' + 'target-port' + "," + 'lun' */
done:
out:
if (target_port != NULL) {
}
if (devfs_path != NULL) {
}
return (NULL);
}
/*
* Get the devid property from the disk node matching the path passed in.
*/
char *
{
int rv;
char *f = "get_devid";
while (dnode != DI_NODE_NIL) {
NULL) {
if (rv < 0) {
"for path: %s\n", f, path);
goto nopath;
}
goto done;
}
}
}
/* find the child matching the phy and grab the devid prop */
dpath = DI_PATH_NIL;
if (rv == 0) {
if (rv != 0) {
return (NULL);
}
}
done:
}
oc_path);
return (NULL);
}
{
int rv;
char *f = "get_generic";
if (s == NULL) {
return (B_FALSE);
}
/* look for boot flag */
/* not set of not true */
return (B_FALSE);
}
return (B_TRUE);
}
/*
* Get the total number of possible direct attached PHYs (bays). It's either
* the 'num-phys-hba' or 'num-phys' integer property of the HBA di_node.
*/
int
{
int num_phys;
/* first look for 'num-phys' */
if (num_phys == -1) {
/* next look for 'num-phys-hba' */
if (num_phys == -1) {
}
}
return (num_phys);
}
/*
* Get the chassis name (held in FM_FMRI_AUTH_V1_CHASSIS_NM) and chassis S/N
* (FM_FMRI_AUTH_V1_CHASSIS_SN) from the authority fmri.
*/
int
{
int rv;
} else {
/* everyone has either a chassis or a mother(board) */
}
"No chassis or motherboard node.\n");
return (-1);
}
}
/* get auth list from topo node */
/* get chassis name */
} else {
}
/* chassis serial number */
} else {
}
return (0);
}
/*
* Callback for mod walk routine; calls the shared routine to find the
* hba label.
*/
/* ARGSUSED */
static int
{
}
/*
* Get the pci slot label.
*
* The caller is responsible for freeing memory.
*/
char *
{
int rv;
int err;
char *f = "get_pcilabel";
/* init walk */
"%s: topo_walk_init() failed for (%s)\n",
f, cbs.devfs_path);
goto bad;
}
/* walk */
if (rv == TOPO_WALK_ERR) {
"%s: topo_walk_step() failed for (%s)\n",
f, cbs.devfs_path);
goto bad;
}
/* no label */
goto bad;
}
bad:
return (NULL);
}
/*
* Get the slot id by parsing the pci label for the slot, or return 0 if
* it's an on-board device (label == "MB").
*/
int
{
int i, j;
int id;
char n[3];
id = -1;
goto out;
}
/* on-board - slot id is 0 by pcie spec */
id = 0;
goto out;
}
/* extract the slot id from the label */
label[i] != '\0')
continue;
n[j] = label[i];
}
/* convert to an int */
/* 'PCIe 0' is really slot id 1 */
id++;
out:
return (id);
}
/*
* Parse a line of the bay config file to extract data.
*/
static int
{
int i;
int phy;
int drv_inst;
char *token;
/* skip lines starting with '#' */
return (-1);
}
/* parse the line e.g. */
/* Sans Digital TR4X:pmcs:0:JBOD 0:812BDA443-184:5:BAY2 */
NULL) {
!= NULL) {
if ((token =
!= NULL) {
}
}
}
}
}
}
}
/* check strings */
return (-1);
}
/* check the hba driver name and instance */
/* not what we're looking for */
return (-1);
}
/* cut off the last newline */
if (label[i] == '\n') {
label[i] = '\0';
}
}
"chassis label(%s) chassis S/N(%s) phy(%d) bay label(%s)\n",
/* fill in the bay struct */
return (0);
}
/*
* Read the config file and fill in the bays array. Return the number of
* structs (bays) filled in.
*/
int
{
int rv;
int cnt = 0;
char s[MAXNAMELEN];
/* open the config file and read how many bays for this hba */
"read_config: failed to open config file (%s)\n", f);
return (-1);
}
/*
* config file format:
* "product:driver name:instance:product name:product s/n:PHY:label"
* "%s:%s:%d:%s:%d:%s"
*/
if (rv == 0) {
cnt++;
}
}
*n = cnt;
return (0);
}
/*
* Sort the hba_nodes[] array relative to their slot id. If the slot id is
* not obtainable; sort in the order seen.
*
* Return: 0 - successfully sorted
* -1 - failed to sort (usually due to lack of PCIe slotid)
*/
int
{
int i;
int j;
int slot_id;
struct s {
di_node_t d;
int id;
/* fill in the sorting struct */
for (i = 0; i < hba_node_cnt; i++) {
/*
* Get the pci slot id from the HBA pcibus topo label.
* The pcibus enum has already done all the twizzle
*/
if (slot_id == -1) {
return (-1);
}
slot_id);
}
/* get ya sort on */
for (j = 0; j < hba_node_cnt; j++) {
for (i = 0; i < (hba_node_cnt - 1); i++) {
}
}
}
/* refill hba_nodes now in relative order */
for (i = 0; i < hba_node_cnt; i++) {
}
return (0);
}