/*
* 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 <sys/pathname.h>
#include <sys/mdi_impldefs.h>
struct parinfo {
};
/*
* internal functions
*/
static int resolve_devfs_name(char *, char *);
/* internal global data */
&mod_miscops, "bootdev misc module 1.22"
};
};
int
_init()
{
return (mod_install(&modlinkage));
}
int
_fini()
{
return (mod_remove(&modlinkage));
}
int
{
}
/*
* convert a prom device path to an equivalent path in /devices
* Does not deal with aliases. Does deal with pathnames which
* are not fully qualified. This routine is generalized
* to work across several flavors of OBP
*/
int
{
return (EINVAL);
}
return (EINVAL);
return (0);
}
/*
* The function is to get prom name according non-client dip node.
* And the function will set the alternate node of dip to alt_dip
* if it is exist which must be PROM node.
*/
static int
{
int ret = 0;
if (MDI_CLIENT(dip))
return (EINVAL);
return (0);
}
/*
* ddi_pathname_obp return NULL, but the obp path still could
* be different with the devfs path name, so need use a parents
* stack to compose the path name string layer by layer.
*/
/* find the closest ancestor which is a prom node */
KM_SLEEP);
if (depth == OBP_STACKDEPTH) {
/* must not have been an obp node */
goto out;
}
}
if (pdip)
if (pdip) {
if (cdip) {
}
}
/*
* node name + unitaddr to the prom_path
*/
if (unit_address && (*unit_address)) {
}
}
if (pdip) {
}
/*
* Now pdip is the alternate node which is same hierarchy as dip
* if it exists.
*/
out:
if (parinfo) {
/* release holds from get_parent() */
}
}
return (ret);
}
/*
* translate a devfs pathname to one that will be acceptable
* by the prom. In most cases, there is no translation needed.
* For systems supporting generically named devices, the prom
* may support nodes such as 'disk' that do not have any unit
* address information (i.e. target,lun info). If this is the
* case, the ddi framework will reject the node as invalid and
* populate the devinfo tree with nodes froms the .conf file
* (e.g. sd). In this case, the names that show up in /devices
* are sd - since the prom only knows about 'disk' nodes, this
* routine detects this situation and does the conversion
* There are also cases such as pluto where the disk node in the
* prom is named "SUNW,ssd" but in /devices the name is "ssd".
*
* If MPxIO is enabled, the translation involves following
* pathinfo nodes to the "best" parent.
*
* return a 0 on success with the new device string in ret_buf.
* Otherwise return the appropriate error code as we may be called
* from the openprom driver.
*/
int
{
int circ;
int ret = 0;
/* do some sanity checks */
return (EINVAL);
}
/*
* Convert to a /devices name. Fail the translation if
* the name doesn't exist.
*/
return (EINVAL);
}
/* we are done */
return (0);
}
/*
* if we get here, then some portion of the device path is
* not understood by the prom. We need to look for alternate
* names (e.g. replace ssd by disk) and mpxio enabled devices.
*/
return (EINVAL);
}
if (!MDI_CLIENT(dip)) {
if (ret == 0) {
}
}
} else {
/*
* if get to here, means dip is a vhci client
*/
/*
* The following code assumes that the phci client is at leaf
* level.
*/
/*
* walk all paths associated to the client node
*/
/*
* replace with mdi_hold_path() when mpxio goes into
* genunix
*/
/*
* The path has different obp path
*/
goto minor_pathinfo;
}
/*
* Get obp path name of the phci node firstly.
* NOTE: if the alternate node of pdip exists,
* the third argument of the i_devi_to_promname()
* would be set to the alternate node.
*/
}
if (cdip) {
}
/*
* node name + unitaddr to the prom_path
*/
if (unit_address && (*unit_address)) {
}
if (cdip) {
/* hold from find_alternate_node */
}
}
if (MDI_PI_IS_ONLINE(pip)) {
if (rlen <= 0) /* drop paths we can't store */
break;
} else { /* path is offline */
if (olen > 0) /* drop paths we can't store */
}
}
ret = 0;
if (rlen > 0) {
/* now add as much of offline to ret_buf as possible */
}
}
/* release hold from e_ddi_hold_devi_by_path() */
return (ret);
}
/*
* check for a possible substitute node. This routine searches the
* children of parent_dip, looking for a node that:
* 1. is a prom node
* 2. binds to the same major number
* 3. there is no need to verify that the unit-address information
* match since it is likely that the substitute node
* will have none (e.g. disk) - this would be the reason the
* framework rejected it in the first place.
*
* assumes parent_dip is held
*/
static dev_info_t *
{
int circ;
/* lock down parent to keep children from being removed */
/* look for obp node with matching major */
if ((ndi_dev_is_prom_node(child_dip) != 0) &&
break;
}
}
return (child_dip);
}
/*
* given an absolute pathname, convert it, if possible, to a devfs
* name. Examples:
* /pci@1f,4000/glm@3/sd@0,0:a unchanged
*
* This routine deals with symbolic links, physical pathname with and
* without /devices stripped. Returns 0 on success or -1 on failure.
*/
static int
{
int error;
/* if not a /dev or /device name, prepend /devices */
}
if (fullname)
return (-1);
}
if (error == 0)
if (fullname)
return (error);
}
/*
* If bootstring contains a device path, we need to convert to a format
* the prom will understand. To do so, we convert the existing path to
* a prom-compatible path and return the value of new_path. If the
* caller specifies new_path as NULL, we allocate an appropriately
* sized new_path on behalf of the caller. If the caller invokes this
* function with new_path = NULL, they must do so from a context in
* which it is safe to perform a sleeping memory allocation.
*/
char *
{
char *ptr;
int rval;
}
*ptr = '\0';
*ptr = ' ';
if (rval == 0) {
}
} else { /* the conversion failed */
}
return (new_path);
}
/*
* Get the parent dip.
*/
static dev_info_t *
{
return (pdip);
}