/*
* 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 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* cpr functions for supported sparc platforms
*/
/*
* new_def_info is used as tmp space to store new values and write them
* to nvram. orig_def_info gets filled with the original nvram values,
* gets written to disk, and later used by cprboot to restore the
* original nvram values.
*/
0, 0,
0, "boot-file", "", /* props[0] */
0, "boot-device", "", /* props[1] */
0, "auto-boot?", "", /* props[2] */
0, "diag-file", "", /* props[3] */
0, "diag-device", "", /* props[4] */
};
/*
* since the above array is the only place where cprop_t content
*/
static char *cpr_next_component(char **);
static char *cpr_get_prefix(char *);
static char *cpr_build_nodename(pnode_t);
static void cpr_abbreviate_devpath(char *, char *);
static int cpr_show_props = 0;
static int
{
*nodep = prom_optionsnode();
return (ENOENT);
}
return (0);
}
/*
* returns non-zero on error, otherwise returns 0 and
* sets the result code based on (prop value == "true")
*/
static int
{
return (err);
return (ENXIO);
return (ENOENT);
return (0);
}
/*
* write new or original values to nvram
*/
int
{
return (rc);
if (cpr_show_props)
prom_printf("\ncpr_show_props:\n");
if (cpr_show_props) {
prom_printf("mod=%c, name \"%s\",\tvalue \"%s\"\n",
}
continue;
/*
* Note: When doing a prom_setprop you must include the
* trailing NULL in the length argument, but when calling
* prom_getproplen() the NULL is excluded from the count!
*/
return (ENXIO);
}
}
return (0);
}
/*
* update nvram with the new or original nvram values;
* this routine provides local access to both sets
*/
int
{
return (cpr_update_nvram(props));
}
/*
* update the .mod field in both new_def_info and orig_def_info;
* then copy the arg str into a new property value at index
*/
static void
{
}
/*
* setup new property values within new_def_info;
* these are used later to udpate nvram
*/
static int
cpr_prop_setup(void)
{
/*
* create a new boot-device value. for some older prom revs,
* a fully qualified device path can be truncated when stored
* to nvram. this call generates the shortest equivalent.
* using devaliases could be simpler in most cases.
*/
/*
* create a new boot-file value; flags get appended when
* not reusable and when the statefile is a block device
*/
if (!cpr_reusable_mode && cpr_statefile_is_spec())
sp = " -S ";
else
if (sp) {
}
/*
* record property info for booting with cprboot based on
* the value of diag-switch?. when "false", set boot-device
* and boot-file; when "true", set diag-device and diag-file
*/
return (err);
else if (ds_ival == 0) {
} else {
}
if (!cpr_reusable_mode)
/*
*/
cp = "true";
return (0);
}
/*
*/
int
{
char *fmt;
if (alloc == 0) {
new_def_info = NULL;
return (0);
}
return (err);
/*
* allocate space for new properties, get the original nvram
* property values, mark both property sets with PROP_NOMOD,
* and copy the original prop names to the new set.
*/
fmt = "invalid property or length for \"%s\"";
break;
}
fmt = "cannot get \"%s\" value";
break;
}
}
if (err) {
new_def_info = NULL;
} else
err = cpr_prop_setup();
return (err);
}
int
{
return (cpr_write_deffile(&orig_def_info));
}
void
cpr_send_notice(void)
{
prom_printf("Saving System State. Please Wait... ");
}
void
cpr_spinning_bar(void)
{
static int idx;
if (++idx == 4)
idx = 0;
}
void
cpr_resume_notice(void)
{
prom_printf("Restoring System State. Please Wait... ");
}
/*
* Convert a full device path to its shortest unambiguous equivalent.
* problems at any point, just output the unabbreviated path.
*/
static void
{
char *cmpt;
cur_node = prom_nextnode(0);
*out_path = '\0';
int short_hits = 0;
char *name;
/* Go to next tree level by getting first child. */
return;
}
/*
* Traverse the current level and remember the node (if any)
* where we match on the fully qualified component name.
* Also remember the node of the most recent prefix match
* and the number of such matches.
*/
do {
short_hits++;
}
/*
* We don't want to be too dependent on what we know
* about how the names are stored. We just assume that
* if there is only one match on the prefix, we can
* use it, otherwise we need to use a fully qualified
* name. In the "impossible" cases we just give up
* and use the complete input devpath.
*/
if (short_hits == 1) {
}
else
if (long_match) {
} else {
return;
}
}
/* We need to copy the target and slice info manually. */
}
/*
* Return a pointer to the next component of a device path or NULL if
* the entire path has been consumed. Note that we update the caller's
* pointer to the current position in the full pathname buffer.
*/
static char *
{
char *slash;
if (len == 0)
return (NULL);
} else {
}
return (obuf);
}
/*
* Return a pointer to the prefix (i.e., the basic unqualified node name)
* Basically, this is the part of the fully qualified name before the @.
*/
static char *
{
return (prefix);
}
/*
* Build the unambiguous name for the current node, like iommu@f,e10000000.
* The prefix is just the "name" property, and the qualifier is constructed
* from the first two (binary) words of the "reg" property.
*/
static char *
{
return ("");
return (name);
return (name);
return (name);
}
/*
* Makes a printable list of prom_prop names for error messages
* Caller must free space.
*/
char *
{
char *buf;
*buf = '\0';
}
return (buf);
}