/*
* 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"
char **rsrc_fixed);
static int fp_rcm_process_node(di_node_t, void *);
static char *chop_minor(char *);
typedef struct {
char *bus_path;
char *filter;
char **errstring;
} walkargs_t;
static int fp_rcm_process_node(di_node_t, void *);
char **);
static char *chop_minor(char *);
/*
* fp_rcm_offline()
*
* Offline FP resource consumers.
*/
{
int rret;
char *rsrc_fixed;
!= FPCFGA_OK)
return (ret);
!= RCM_SUCCESS) {
if (rinfo) {
}
if (rret == RCM_FAILURE)
ret = FPCFGA_BUSY;
}
return (ret);
}
/*
* fp_rcm_online()
*
* Online FP resource consumers that were previously offlined.
*/
{
char *rsrc_fixed;
!= FPCFGA_OK)
return (ret);
ret = FPCFGA_ERR;
}
return (ret);
}
/*
* fp_rcm_remove()
*
* Remove FP resource consumers after their kernel removal.
*/
{
char *rsrc_fixed;
!= FPCFGA_OK)
return (ret);
!= RCM_SUCCESS) {
if (rinfo) {
}
ret = FPCFGA_ERR;
}
return (ret);
}
/*
* fp_rcm_suspend()
*
* Suspend FP resource consumers before a bus quiesce.
*/
{
int rret;
char *rsrc_fixed;
char *filter_fixed;
char *rsrc_devpath;
!= FPCFGA_OK)
return (ret);
/* If a filter is provided, ensure that it makes sense */
return (FPCFGA_ERR);
}
/*
* If no filter is specified: attempt a suspension on the resource,
* directly.
*/
0);
if (rinfo) {
}
if (rret == RCM_FAILURE)
(flags & (~CFGA_FLAG_FORCE)));
ret = FPCFGA_BUSY;
}
return (ret);
}
/*
* If a filter is specified: open the resource with libdevinfo, walk
* through its nodes, and attempt a suspension of each node that
* mismatches the filter.
*/
/* Chop off the filter's minor name */
return (FPCFGA_ERR);
/* get a libdevinfo snapshot of the resource's subtree */
if (node == DI_NODE_NIL) {
ret = FPCFGA_ERR;
}
/* apply the filter, and suspend all resources not filtered out */
}
if (node != DI_NODE_NIL)
(flags & (~CFGA_FLAG_FORCE)));
return (ret);
}
/*
* fp_rcm_resume()
*
* Resume FP resource consumers after a bus has been unquiesced.
*/
{
char *rsrc_fixed;
char *filter_fixed;
char *rsrc_devpath;
!= FPCFGA_OK)
return (ret);
/* If a filter is provided, ensure that it makes sense */
return (FPCFGA_ERR);
}
/*
* If no filter is specified: resume the resource directly.
*/
0);
ret = FPCFGA_BUSY;
}
return (ret);
}
/*
* If a filter is specified: open the resource with libdevinfo, walk
* through its nodes, and resume each of its nodes that mismatches
* the filter.
*/
/* Chop off the filter's minor name */
return (FPCFGA_ERR);
/* get a libdevinfo snapshot of the resource's subtree */
if (node == DI_NODE_NIL) {
ret = FPCFGA_ERR;
}
/* apply the filter, and resume all resources not filtered out */
}
if (node != DI_NODE_NIL)
return (ret);
}
/*
* fp_rcm_info
*
* Queries RCM information for resources, and formats it into a table.
* The table is appended to the info argument. If the info argument is a
* null pointer, then a new string is malloc'ed. If the info argument is
* not a null pointer, then it is realloc'ed to the required size.
*/
{
char *rsrc_fixed;
!= FPCFGA_OK)
return (ret);
return (FPCFGA_ERR);
}
!= RCM_SUCCESS) {
ret = FPCFGA_ERR;
if (rinfo) {
}
return (ret);
}
/*
* fp_rcm_init()
*
* Contains common initialization code for entering a fp_rcm_xx()
* routine.
*/
static fpcfga_ret_t
char **rsrc_fixed)
{
/* Validate the rsrc argument */
return (FPCFGA_ERR);
}
/* Translate the cfgadm flags to RCM flags */
/* Get a handle for the RCM operations */
(void) mutex_lock(&rcm_handle_lock);
if (rcm_handle == NULL) {
RCM_SUCCESS) {
(void) mutex_unlock(&rcm_handle_lock);
return (FPCFGA_LIB_ERR);
}
}
(void) mutex_unlock(&rcm_handle_lock);
/* Chop off the rsrc's minor, if it has one */
return (FPCFGA_ERR);
return (FPCFGA_OK);
}
/*
* fp_rcm_process_node
*
* Helper routine for fp_rcm_{suspend,resume}. This is a di_walk_node()
* callback that will apply a filter to every node it sees, and either suspend
* or resume it if it doesn't match the filter.
*/
static int
{
char *devfs_path;
/* Guard against bad arguments */
return (DI_WALK_TERMINATE);
return (DI_WALK_TERMINATE);
}
/* If the node has no minors, then skip it */
return (DI_WALK_CONTINUE);
/* Construct the devices path */
return (DI_WALK_CONTINUE);
/*
* If the node does not correspond to the targeted FP bus or the
* function.
*/
/* Stop the walk early if the above operation failed */
return (DI_WALK_TERMINATE);
}
return (DI_WALK_CONTINUE);
}
/*
* fp_rcm_info_table
*
* Takes an opaque rcm_info_t pointer and a character pointer, and appends
* the rcm_info_t data in the form of a table to the given character pointer.
*/
static fpcfga_ret_t
{
int i;
size_t w;
char *rsrc;
char *info;
char *newtable;
/* Protect against invalid arguments */
return (FPCFGA_ERR);
/* Set localized table header strings */
/* A first pass, to size up the RCM information */
tuples++;
w_rsrc = w;
w_info = w;
}
}
/* If nothing was sized up above, stop early */
if (tuples == 0)
return (FPCFGA_OK);
/* Adjust column widths for column headings */
w_rsrc = w;
else if ((w_rsrc - w) % 2)
w_rsrc++;
w_info = w;
else if ((w_info - w) % 2)
w_info++;
/*
* Compute the total line width of each line,
* accounting for intercolumn spacing.
*/
/* Allocate space for the table */
else {
}
return (FPCFGA_ERR);
/* Place a table header into the string */
/* The resource header */
for (i = 0; i < ((w_rsrc - w) / 2); i++)
for (i = 0; i < ((w_rsrc - w) / 2); i++)
/* The information header */
for (i = 0; i < ((w_info - w) / 2); i++)
for (i = 0; i < ((w_info - w) / 2); i++)
/* Underline the headers */
for (i = 0; i < w_rsrc; i++)
for (i = 0; i < w_info; i++)
/* Construct the format string */
/* Add the tuples to the table string */
}
}
return (FPCFGA_OK);
}
/*
* chop_minor()
*
* Chops off the minor name portion of a resource. Allocates storage for
* the returned string. Caller must free the storage if return is non-NULL.
*/
static char *
{
char *rsrc_fixed;
char *cp;
return (NULL);
*cp = '\0';
return (rsrc_fixed);
}