/*
* 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
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include "cfga_fp.h"
/* Function prototypes */
static char ctoi(char c);
/* Globals */
/* Various conversions routines */
void
{
}
}
int
{
int i;
char c, c1;
return (-1);
}
return (0);
}
static char
ctoi(char c)
{
if ((c >= '0') && (c <= '9'))
c -= '0';
else if ((c >= 'A') && (c <= 'F'))
c = c - 'A' + 10;
else if ((c >= 'a') && (c <= 'f'))
c = c - 'a' + 10;
else
c = -1;
return (c);
}
/*
* Generates the HBA logical ap_id from physical ap_id.
*/
{
if (*xport_logpp != NULL) {
return (FPCFGA_ERR);
}
/*
* driver name and instance number based based link needs to be
* constructed for the minor node type of DDI_NT_FC_ATTACHMENT_POINT.
* sunddi.h defines DDI_NT_FC_ATTACHMENT_POINT for
* ddi_ctl:attachment_point:fc
*/
return (FPCFGA_OK);
} else {
return (FPCFGA_ERR);
}
}
static fpcfga_ret_t
{
int match_minor;
match_minor = 1;
return (ret);
}
return (FPCFGA_OK);
}
/*
* Given a xport path and dynamic ap_id, returns the physical
* path in pathpp. If the dynamic ap is not configured pathpp set to NULL
* and returns FPCFGA_APID_NOCONFIGURE.
*/
const char *xport_phys,
const char *dyncomp,
struct luninfo_list **lunlistpp,
int *l_errnop)
{
/* A device MUST have a dynamic component */
return (FPCFGA_LIB_ERR);
}
return (ret);
}
/*
* When both the transport and dynamic comp are given this function
* checks to see if the dynamic ap is configured on the dev tree.
* If it is configured the devfs path will be stored in pathpp.
* When the dynamic comp is null this function check to see if the transport
* node has any child.
*
* Retrun value: FPCFGA_OK if the apid is configured.
* FPCFGA_APID_NOCONFIGURE if the apid is not configured.
* FPCFGA_LIB_ERR for other errors.
*/
static fpcfga_ret_t
const char *xport_phys,
const char *dyncomp,
struct luninfo_list **lunlistpp,
int *l_errnop)
{
found_fp = 0;
return (FPCFGA_LIB_ERR);
}
return (FPCFGA_LIB_ERR);
}
}
}
== DI_NODE_NIL) {
return (FPCFGA_LIB_ERR);
}
while (fpnode) {
found_fp = 1;
break;
}
}
if (!(found_fp)) {
goto out;
} else {
}
/*
* when there is no child and path info node the
* FPCFGA_APID_NOCONFIGURE is returned
* regardless of the dynamic comp.
*/
goto out;
}
/*
* when dyn comp is null the function just checks if there is any
* child under fp transport attachment point.
*/
goto out;
}
/*
* now checks the children node to find
* if dynamic ap is configured. if there are multiple luns
* store into lunlist.
*/
if (dev_node != DI_NODE_NIL) {
do {
DI_PROP_NIL) {
/* is property name port-wwn */
if ((!(strcmp(PORT_WWN_PROP,
di_prop_name(prop)))) &&
(di_prop_type(prop) ==
break;
}
}
if (prop != DI_PROP_NIL) {
goto out;
} else {
"%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x",
WWN_SIZE*2))) {
goto out;
}
}
}
}
prop = DI_PROP_NIL;
} while (dev_node != DI_NODE_NIL);
}
/*
* now checks the path info node to find
* if dynamic ap is configured. if there are multiple luns
* store into lunlist.
*/
if (path != DI_PATH_NIL) {
/*
* now parse the path info node.
*/
do {
goto out;
}
"%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x",
/* if matches get the path of scsi_vhci child node. */
if (client_node == DI_NODE_NIL) {
goto out;
}
/*
* If the node is
* state then check the devfs_path to
* see if it has a complete path.
* For non scsi_vhci node the path
* doesn't contain @w(portwwn) part
* consistently. For scsi_vhci
* this behavior may not be there.
* To be safe @g(guid) is attempted
* to be added here.
*/
if ((state & DI_DRIVER_DETACHED) &&
prop = DI_PROP_NIL;
prop)) != DI_PROP_NIL) {
/* is property name lun-wwn */
if ((!(strcmp(LUN_GUID_PROP,
di_prop_name(prop)))) &&
(di_prop_type(prop) ==
break;
}
}
if (prop != DI_PROP_NIL) {
"@g%s", lun_guid);
} else {
goto out;
}
}
== NULL) {
return (FPCFGA_LIB_ERR);
} else {
}
FPCFGA_OK) {
goto out;
}
}
} while (path != DI_PATH_NIL);
}
out:
return (ret);
}
static fpcfga_ret_t
struct luninfo_list **lunlistpp,
const char *dyncomp,
int *l_errnop)
{
int *lunp;
if (count <= 0) {
return (FPCFGA_LIB_ERR);
}
break;
}
}
if (prop_lun == DI_PROP_NIL) {
return (FPCFGA_LIB_ERR);
}
/*
* stores state info in state.
* This information is used to get the
* validity of path.
* if driver_detached don't try to get
* the devfs_path since it is not
* complete. ex, /pci@1f,2000/pci@1/
* SUNW,qlc@5/fp@0,0/ssd
* which doesn't contain the port wwn
* part. The attached node looks like
* /pci@1f,2000/pci@1/SUNW,qlc@5/fp@0,0/
* ssd@w2100002037006b14,0
*/
return (FPCFGA_LIB_ERR);
}
if ((state & DI_DRIVER_DETACHED) &&
*lunp);
}
== NULL) {
return (FPCFGA_LIB_ERR);
} else {
}
}
static fpcfga_ret_t
struct luninfo_list **lunlistpp,
int lun,
char *pathp,
int *l_errnop)
{
return (FPCFGA_LIB_ERR);
}
/* if lunlist is empty add the new lun info and return. */
return (FPCFGA_OK);
}
/* if the first lun in the list is the same as the new lun return. */
return (FPCFGA_OK);
}
/*
* if the first lun in the list is less than the new lun add the
* new lun as the first lun and return.
*/
return (FPCFGA_OK);
}
/*
* if the first lun in the list is greater than the new lun and
* there is a single lun add new lun after the first lun and return.
*/
return (FPCFGA_OK);
}
/*
* now there is more than two luns in the list and the first lun
* is greter than the input lun.
*/
return (FPCFGA_OK);
return (FPCFGA_OK);
} else {
}
}
/* add the new lun at the end of list. */
return (FPCFGA_OK);
}
char **dyncompp,
int *l_errnop)
{
int count;
*l_errnop = 0;
return (FPCFGA_LIB_ERR);
}
/* now get port-wwn for the input node. */
break;
}
}
if (prop != DI_PROP_NIL) {
return (FPCFGA_LIB_ERR);
}
} else {
return (FPCFGA_LIB_ERR);
}
return (FPCFGA_OK);
}
char **dyncompp,
int **luncompp,
int *l_errnop)
{
*l_errnop = 0;
}
}
/*
* di_prop* returns the number of entries found or 0 if not found
* or -1 for othere failure.
*/
return (FPCFGA_LIB_ERR);
}
return (FPCFGA_LIB_ERR);
}
return (FPCFGA_OK);
}
char **dyncompp,
int **luncompp,
int *l_errnop)
{
*l_errnop = 0;
PORT_WWN_PROP, &port_wwn_data)) <= 0)) {
}
}
/*
* di_prop* returns the number of entries found or 0 if not found
* or -1 for othere failure.
*/
return (FPCFGA_LIB_ERR);
}
return (FPCFGA_LIB_ERR);
}
return (FPCFGA_OK);
}
char **node_pathp,
int *l_errnop)
{
/*
* If the node is
* state then check the devfs_path to
* see if it has a complete path.
* For non scsi_vhci node the path
* doesn't contain @w(portwwn) part
* consistently. For scsi_vhci
* this behavior may not be there.
* To be safe @g(guid) is attempted
* to be added here.
*/
if (state & DI_DRIVER_DETACHED) {
if (is_scsi_vhci_dev &&
if (di_ret == -1) {
return (FPCFGA_LIB_ERR);
} else {
"@g%s", lun_guid);
}
} else if (!is_scsi_vhci_dev &&
if (di_ret == -1) {
return (FPCFGA_LIB_ERR);
} else {
== NULL) {
return (FPCFGA_LIB_ERR);
}
"@w%s", port_wwn);
}
}
}
return (FPCFGA_LIB_ERR);
} else {
}
return (FPCFGA_OK);
}
{
}