269473047d747f7815af570197e4ef7322d3632cEvan Yan * CDDL HEADER START
269473047d747f7815af570197e4ef7322d3632cEvan Yan * The contents of this file are subject to the terms of the
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Common Development and Distribution License (the "License").
269473047d747f7815af570197e4ef7322d3632cEvan Yan * You may not use this file except in compliance with the License.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
269473047d747f7815af570197e4ef7322d3632cEvan Yan * See the License for the specific language governing permissions
269473047d747f7815af570197e4ef7322d3632cEvan Yan * and limitations under the License.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * When distributing Covered Code, include this CDDL HEADER in each
269473047d747f7815af570197e4ef7322d3632cEvan Yan * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * If applicable, add the following below this CDDL HEADER, with the
269473047d747f7815af570197e4ef7322d3632cEvan Yan * fields enclosed by brackets "[]" replaced with your own identifying
269473047d747f7815af570197e4ef7322d3632cEvan Yan * information: Portions Copyright [yyyy] [name of copyright owner]
269473047d747f7815af570197e4ef7322d3632cEvan Yan * CDDL HEADER END
bc6a100fe6399f4a72c84c38df0fc9a960ded814Scott M. Carter * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Plugin library for PCI Express and PCI (SHPC) hotplug controller
269473047d747f7815af570197e4ef7322d3632cEvan Yan#include "../../../../uts/common/sys/hotplug/pci/pcie_hp.h"
269473047d747f7815af570197e4ef7322d3632cEvan Yan#include "../../../../common/pci/pci_strings.h"
269473047d747f7815af570197e4ef7322d3632cEvan Yanextern const struct pci_class_strings_s class_pci[];
269473047d747f7815af570197e4ef7322d3632cEvan Yan "Error: hotplug service is probably not running, " \
269473047d747f7815af570197e4ef7322d3632cEvan Yan "please use 'svcadm enable hotplug' to enable the service. " \
269473047d747f7815af570197e4ef7322d3632cEvan Yan "See cfgadm_shp(1M) for more details."
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Set the version number
269473047d747f7815af570197e4ef7322d3632cEvan Yan * DEBUGING LEVEL
269473047d747f7815af570197e4ef7322d3632cEvan Yan * External routines: 1 - 2
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Internal routines: 3 - 4
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic char *
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic cfga_err_t fix_ap_name(char *ap_log_id, const char *ap_id,
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic cfga_err_t check_options(const char *options);
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic void cfga_msg(struct cfga_msg *msgp, const char *str);
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic char *
269473047d747f7815af570197e4ef7322d3632cEvan Yan"\nPCI hotplug specific commands:",
269473047d747f7815af570197e4ef7322d3632cEvan Yan"\t-c [connect|disconnect|configure|unconfigure|insert|remove] "
269473047d747f7815af570197e4ef7322d3632cEvan Yan"ap_id [ap_id...]",
269473047d747f7815af570197e4ef7322d3632cEvan Yan"\t-x enable_slot ap_id [ap_id...]",
269473047d747f7815af570197e4ef7322d3632cEvan Yan"\t-x disable_slot ap_id [ap_id...]",
269473047d747f7815af570197e4ef7322d3632cEvan Yan"\t-x enable_autoconfig ap_id [ap_id...]",
269473047d747f7815af570197e4ef7322d3632cEvan Yan"\t-x disable_autoconfig ap_id [ap_id...]",
269473047d747f7815af570197e4ef7322d3632cEvan Yan"\t-x led[=[fault|power|active|attn],mode=[on|off|blink]] ap_id [ap_id...]",
269473047d747f7815af570197e4ef7322d3632cEvan Yan"\tunknown command or option: ",
269473047d747f7815af570197e4ef7322d3632cEvan Yantypedef enum { PCIEHPC_FAULT_LED, PCIEHPC_POWER_LED, PCIEHPC_ATTN_LED,
269473047d747f7815af570197e4ef7322d3632cEvan Yantypedef enum { PCIEHPC_BOARD_UNKNOWN, PCIEHPC_BOARD_PCI_HOTPLUG }
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Board Type
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic char *
269473047d747f7815af570197e4ef7322d3632cEvan Yan * HW functions
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic char *
269473047d747f7815af570197e4ef7322d3632cEvan Yan * LED strings
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic char *
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic char *
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* n */ PCIEHPC_PROP_LED_FAULT, /* PCIEHPC_FAULT_LED */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* n */ PCIEHPC_PROP_LED_POWER, /* PCIEHPC_POWER_LED */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* n */ PCIEHPC_PROP_LED_ATTN, /* PCIEHPC_ATTN_LED */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* n */ PCIEHPC_PROP_LED_ACTIVE, /* PCIEHPC_ACTIVE_LED */
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic char *
269473047d747f7815af570197e4ef7322d3632cEvan Yantypedef enum {
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Return the corresponding hp node for a given ap_id, it is the caller's
269473047d747f7815af570197e4ef7322d3632cEvan Yan * responsibility to call hp_fini() to free the snapshot.
269473047d747f7815af570197e4ef7322d3632cEvan Yanphyspath2node(const char *physpath, char **errstring, hp_node_t *nodep)
269473047d747f7815af570197e4ef7322d3632cEvan Yan if ((rpath = malloc(strlen(physpath) + 1)) == NULL)
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Remove devices prefix (if any) */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (strncmp(rpath, DEVICES_DIR SLASH, len + strlen(SLASH)) == 0) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Remove dynamic component if any */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Remove minor name (if any) */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* No reponse to operations on the door file. */
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Callback function for hp_traverse(), to sum up the
269473047d747f7815af570197e4ef7322d3632cEvan Yan * maximum length for error message display.
269473047d747f7815af570197e4ef7322d3632cEvan Yan error_size_cb_arg_t *sizearg = (error_size_cb_arg_t *)arg;
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Only process USAGE nodes */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* size up resource name */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* size up usage description */
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Callback function for hp_traverse(), to add the error
269473047d747f7815af570197e4ef7322d3632cEvan Yan * message to he table.
269473047d747f7815af570197e4ef7322d3632cEvan Yan error_sum_cb_arg_t *sumarg = (error_sum_cb_arg_t *)arg;
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Only process USAGE nodes */
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Takes an opaque rcm_info_t pointer and a character pointer, and appends
269473047d747f7815af570197e4ef7322d3632cEvan Yan * the rcm_info_t data in the form of a table to the given character pointer.
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Protect against invalid arguments */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Set localized table header strings */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* A first pass, to size up the RCM information */
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) hp_traverse(node, &sizearg, error_sizeup_cb);
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* If nothing was sized up above, stop early */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Adjust column widths for column headings */
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Compute the total line width of each line,
269473047d747f7815af570197e4ef7322d3632cEvan Yan * accounting for intercolumn spacing.
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Allocate space for the table */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* zero fill for the strcat() call below */
269473047d747f7815af570197e4ef7322d3632cEvan Yan newtable = realloc(*table, strlen(*table) + table_size);
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Place a table header into the string */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* The resource header */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* The information header */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Underline the headers */
269473047d747f7815af570197e4ef7322d3632cEvan Yan for (i = 0; i < w_rsrc; i++)
269473047d747f7815af570197e4ef7322d3632cEvan Yan for (i = 0; i < w_info; i++)
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Construct the format string */
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) snprintf(format, MAX_FORMAT, "%%-%ds %%-%ds",
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Add the tuples to the table string */
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Figure out the target kernel state for a given cfgadm
269473047d747f7815af570197e4ef7322d3632cEvan Yan * change-state operation.
269473047d747f7815af570197e4ef7322d3632cEvan Yancfga_target_state(cfga_cmd_t state_change_cmd, int *state)
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Translate kernel state to cfgadm receptacle state and occupant state.
269473047d747f7815af570197e4ef7322d3632cEvan Yancfga_get_state(hp_node_t connector, ap_rstate_t *rs, ap_ostate_t *os)
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Receptacle state */
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Connector state can only be one of
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Empty, Present, Powered, Enabled.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Occupant state
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Mark occupant state as "configured" if at least one of the
269473047d747f7815af570197e4ef7322d3632cEvan Yan * associated ports is at state "offline" or above. Driver
269473047d747f7815af570197e4ef7322d3632cEvan Yan * attach ("online" state) is not necessary here.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Transitional Diagram:
269473047d747f7815af570197e4ef7322d3632cEvan Yan * empty unconfigure
269473047d747f7815af570197e4ef7322d3632cEvan Yan * (remove) ^| (physically insert card)
269473047d747f7815af570197e4ef7322d3632cEvan Yan * disconnect configure
269473047d747f7815af570197e4ef7322d3632cEvan Yan * "-c DISCONNECT" ^| "-c CONNECT"
269473047d747f7815af570197e4ef7322d3632cEvan Yan * |V "-c CONFIGURE"
269473047d747f7815af570197e4ef7322d3632cEvan Yan * connect unconfigure -> connect configure
269473047d747f7815af570197e4ef7322d3632cEvan Yan * "-c UNCONFIGURE"
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*ARGSUSED*/
269473047d747f7815af570197e4ef7322d3632cEvan Yancfga_change_state(cfga_cmd_t state_change_cmd, const char *ap_id,
269473047d747f7815af570197e4ef7322d3632cEvan Yan struct cfga_msg *msgp, char **errstring, cfga_flags_t flags)
29d8c27b2f0a34e2c4bc34878465f0e7f7d2b96dScott M. Carter * Check for the FORCE flag. It is only used
29d8c27b2f0a34e2c4bc34878465f0e7f7d2b96dScott M. Carter * for DISCONNECT or UNCONFIGURE state changes.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Which state should we drive to ?
269473047d747f7815af570197e4ef7322d3632cEvan Yan DBG(1, ("cfga_change_state: state is %d\n", state));
bc6a100fe6399f4a72c84c38df0fc9a960ded814Scott M. Carter } else if (state == DDI_HP_CN_STATE_PRESENT) {
bc6a100fe6399f4a72c84c38df0fc9a960ded814Scott M. Carter /* Connect the slot */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (hp_set_state(node, 0, new_state, &results) != 0) {
bc6a100fe6399f4a72c84c38df0fc9a960ded814Scott M. Carter } else if (state > DDI_HP_CN_STATE_PRESENT) {
bc6a100fe6399f4a72c84c38df0fc9a960ded814Scott M. Carter /* Disconnect the slot */
29d8c27b2f0a34e2c4bc34878465f0e7f7d2b96dScott M. Carter rv = hp_set_state(node, hpflags, new_state, &results);
269473047d747f7815af570197e4ef7322d3632cEvan Yan * for multi-func device we allow multiple
269473047d747f7815af570197e4ef7322d3632cEvan Yan * configure on the same slot because one
269473047d747f7815af570197e4ef7322d3632cEvan Yan * func can be configured and other one won't
bc6a100fe6399f4a72c84c38df0fc9a960ded814Scott M. Carter } else if (hp_set_state(node, 0, new_state, &results) != 0) {
bc6a100fe6399f4a72c84c38df0fc9a960ded814Scott M. Carter } else if (state >= DDI_HP_CN_STATE_ENABLED) {
29d8c27b2f0a34e2c4bc34878465f0e7f7d2b96dScott M. Carter rv = hp_set_state(node, hpflags, new_state, &results);
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* do nothing, just produce error msg as is */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* do nothing, just produce error msg as is */
269473047d747f7815af570197e4ef7322d3632cEvan Yanprt_led_mode(const char *ap_id, int repeat, char **errstring,
269473047d747f7815af570197e4ef7322d3632cEvan Yan for (i = 0; i < n; i++) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (hp_get_private(node, led_strs2[led], &result) != 0) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan DBG(1, ("%s:%s\n", led_strs[led], cfga_strs[UNKNOWN]));
269473047d747f7815af570197e4ef7322d3632cEvan Yan * hp_get_private() will return back things like
269473047d747f7815af570197e4ef7322d3632cEvan Yan * "led_fault=off", transform it to cfgadm desired
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*ARGSUSED*/
269473047d747f7815af570197e4ef7322d3632cEvan Yancfga_private_func(const char *function, const char *ap_id,
269473047d747f7815af570197e4ef7322d3632cEvan Yan struct cfga_msg *msgp, char **errstring, cfga_flags_t flags)
269473047d747f7815af570197e4ef7322d3632cEvan Yan DBG(1, ("cfgadm_private_func: ap_id:%s\n", ap_id));
269473047d747f7815af570197e4ef7322d3632cEvan Yan DBG(2, (" options: %s\n", (options == NULL)?"null":options));
269473047d747f7815af570197e4ef7322d3632cEvan Yan switch (i) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* pass through */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* no action needed */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* set mode */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* ACTIVE=3,ATTN=2,POWER=1,FAULT=0 */
269473047d747f7815af570197e4ef7322d3632cEvan Yan else return (CFGA_INVAL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* ON = 1, OFF = 0 */
269473047d747f7815af570197e4ef7322d3632cEvan Yan else return (CFGA_INVAL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* sendin */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* print mode */
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*ARGSUSED*/
269473047d747f7815af570197e4ef7322d3632cEvan Yancfga_err_t cfga_test(const char *ap_id, const char *options,
269473047d747f7815af570197e4ef7322d3632cEvan Yan struct cfga_msg *msgp, char **errstring, cfga_flags_t flags)
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* will need to implement pci CTRL command */
269473047d747f7815af570197e4ef7322d3632cEvan Yan * The slot-names property describes the external labeling of add-in slots.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * This property is an encoded array, an integer followed by a list of
269473047d747f7815af570197e4ef7322d3632cEvan Yan * strings. The return value from di_prop_lookup_ints for slot-names is -1.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * The expected return value should be the number of elements.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Di_prop_decode_common does not decode encoded data from software,
269473047d747f7815af570197e4ef7322d3632cEvan Yan * such as the solaris device tree, unlike from the prom.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Di_prop_decode_common takes the size of the encoded data and mods
269473047d747f7815af570197e4ef7322d3632cEvan Yan * it with the size of int. The size of the encoded data for slot-names is 9
269473047d747f7815af570197e4ef7322d3632cEvan Yan * and the size of int is 4, yielding a non zero result. A value of -1 is used
269473047d747f7815af570197e4ef7322d3632cEvan Yan * to indicate that the number of elements can not be determined.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Di_prop_decode_common can be modified to decode encoded data from the solaris
269473047d747f7815af570197e4ef7322d3632cEvan Yan * device tree.
269473047d747f7815af570197e4ef7322d3632cEvan Yanfixup_slotname(int rval, int *intp, struct searcharg *slotarg)
269473047d747f7815af570197e4ef7322d3632cEvan Yan if ((slotarg->slt_name_src == PROM_SLT_NAME) && (rval == -1)) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* assign tmptr */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* wind tmptr to next \0 */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* point at unknown string */
269473047d747f7815af570197e4ef7322d3632cEvan Yan "unknown");
269473047d747f7815af570197e4ef7322d3632cEvan Yanfind_slotname(di_node_t din, di_minor_t dim, void *arg)
269473047d747f7815af570197e4ef7322d3632cEvan Yan struct searcharg *slotarg = (struct searcharg *)arg;
269473047d747f7815af570197e4ef7322d3632cEvan Yan di_prom_handle_t ph = (di_prom_handle_t)slotarg->promp;
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Check the Solaris device tree first
269473047d747f7815af570197e4ef7322d3632cEvan Yan * in the case of a DR operation
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (strcmp("slot-names", di_prop_name(solaris_prop))
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Check the prom device tree which is populated at boot.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * If this fails, give up and set the slot name to null.
269473047d747f7815af570197e4ef7322d3632cEvan Yan prom_prop = di_prom_prop_next(ph, din, DI_PROM_PROP_NIL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (strcmp("slot-names", di_prom_prop_name(prom_prop))
269473047d747f7815af570197e4ef7322d3632cEvan Yanfind_physical_slot_names(const char *devcomp, struct searcharg *slotarg)
269473047d747f7815af570197e4ef7322d3632cEvan Yan if ((root_node = di_init("/", DINFOCPYALL|DINFOPATH))
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (-1);
269473047d747f7815af570197e4ef7322d3632cEvan Yan if ((slotarg->promp = di_prom_init()) == DI_PROM_HANDLE_NIL) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (-1);
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) di_walk_minor(root_node, "ddi_ctl:attachment_point:pci",
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (0);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (-1);
269473047d747f7815af570197e4ef7322d3632cEvan Yanget_type(const char *boardtype, const char *cardtype, char *buf)
269473047d747f7815af570197e4ef7322d3632cEvan Yan/* for type string assembly in get_type() */
269473047d747f7815af570197e4ef7322d3632cEvan Yan#define TPCT(s) (void) strlcat(buf, (s), CFGA_TYPE_LEN)
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (strcmp(boardtype, PCIEHPC_PROP_VALUE_PCIHOTPLUG) == 0)
269473047d747f7815af570197e4ef7322d3632cEvan Yan * call-back function for di_devlink_walk
269473047d747f7815af570197e4ef7322d3632cEvan Yan * if the link lives in /dev/cfg copy its name
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (strncmp("/dev/cfg/", di_devlink_path(link), 9) == 0) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* copy everything but /dev/cfg/ */
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) strcpy((char *)ap_log_id, di_devlink_path(link) + 9);
269473047d747f7815af570197e4ef7322d3632cEvan Yan DBG(1, ("found_devlink: %s\n", (char *)ap_log_id));
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Walk throught the cached /dev link tree looking for links to the ap
269473047d747f7815af570197e4ef7322d3632cEvan Yan * if none are found return an error
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* ap_id is a valid minor_path with /devices prepended */
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) di_devlink_walk(hdl, NULL, ap_id + 8, DI_PRIMARY_LINK,
269473047d747f7815af570197e4ef7322d3632cEvan Yan DBG(1, ("check_devlinks: invalid ap_id: %s\n", ap_id));
269473047d747f7815af570197e4ef7322d3632cEvan Yan * most of this is needed to compensate for
269473047d747f7815af570197e4ef7322d3632cEvan Yan * differences between various platforms
269473047d747f7815af570197e4ef7322d3632cEvan Yanfix_ap_name(char *ap_log_id, const char *ap_id, char *slot_name,
269473047d747f7815af570197e4ef7322d3632cEvan Yan DBG(1, ("fix_ap_name: failed to snapshot node\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) snprintf(ap_log_id, strlen(ap_id) + 1, "%s%i:%s",
269473047d747f7815af570197e4ef7322d3632cEvan Yan di_driver_name(ap_node), di_instance(ap_node), slot_name);
269473047d747f7815af570197e4ef7322d3632cEvan Yan (*(char **)arg) = strdup(di_devlink_path(devlink));
269473047d747f7815af570197e4ef7322d3632cEvan Yan * returns an allocated string containing the full path to the devlink for
269473047d747f7815af570197e4ef7322d3632cEvan Yan * <ap_phys_id> in the devlink database; we expect only one devlink per
269473047d747f7815af570197e4ef7322d3632cEvan Yan * <ap_phys_id> so we return the first encountered
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic char *
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) di_devlink_walk(hdl, "^cfg/.+$", ap_phys_id, DI_PRIMARY_LINK,
269473047d747f7815af570197e4ef7322d3632cEvan Yan * returns CFGA_OK if it can succesfully retrieve the devlink info associated
269473047d747f7815af570197e4ef7322d3632cEvan Yan * with devlink for <ap_phys_id> which will be returned through <ap_info>
269473047d747f7815af570197e4ef7322d3632cEvan Yanget_dli(char *dlpath, char *ap_info, int ap_info_sz)
269473047d747f7815af570197e4ef7322d3632cEvan Yancfga_get_condition(hp_node_t node, ap_condition_t *cond)
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* "condition" bus specific commands */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (hp_get_private(node, PCIEHPC_PROP_SLOT_CONDITION,
269473047d747f7815af570197e4ef7322d3632cEvan Yan else if (strcmp(condition, PCIEHPC_PROP_COND_FAILING) == 0)
269473047d747f7815af570197e4ef7322d3632cEvan Yan else if (strcmp(condition, PCIEHPC_PROP_COND_FAILED) == 0)
269473047d747f7815af570197e4ef7322d3632cEvan Yan else if (strcmp(condition, PCIEHPC_PROP_COND_UNUSABLE) == 0)
269473047d747f7815af570197e4ef7322d3632cEvan Yan else if (strcmp(condition, PCIEHPC_PROP_COND_UNKNOWN) == 0)
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*ARGSUSED*/
269473047d747f7815af570197e4ef7322d3632cEvan Yancfga_list_ext(const char *ap_id, cfga_list_data_t **cs,
269473047d747f7815af570197e4ef7322d3632cEvan Yan int *nlist, const char *options, const char *listopts, char **errstring,
269473047d747f7815af570197e4ef7322d3632cEvan Yan if ((*cs = malloc(sizeof (cfga_list_data_t))) == NULL) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan * We're not busy since the entrance into the kernel has been
269473047d747f7815af570197e4ef7322d3632cEvan Yan * sync'ed via libhotplug.
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* last change */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* board type */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (hp_get_private(node, PCIEHPC_PROP_BOARD_TYPE, &boardtype) != 0)
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* card type */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (hp_get_private(node, PCIEHPC_PROP_CARD_TYPE, &cardtype) != 0)
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* logical ap_id */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* physical ap_id */
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) strcpy((*cs)->ap_phys_id, ap_id); /* physical path of AP */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* information */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* slot_names of bus node */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (find_physical_slot_names(ap_id, &slotname_arg) != -1)
269473047d747f7815af570197e4ef7322d3632cEvan Yan * This routine prints a single line of help message
269473047d747f7815af570197e4ef7322d3632cEvan Yan cfga_msg(msgp, dgettext(TEXT_DOMAIN, cfga_strs[HELP_UNKNOWN]));
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*ARGSUSED*/
269473047d747f7815af570197e4ef7322d3632cEvan Yancfga_help(struct cfga_msg *msgp, const char *options, cfga_flags_t flags)
269473047d747f7815af570197e4ef7322d3632cEvan Yan cfga_msg(msgp, dgettext(TEXT_DOMAIN, cfga_strs[HELP_UNKNOWN]));
269473047d747f7815af570197e4ef7322d3632cEvan Yan cfga_msg(msgp, dgettext(TEXT_DOMAIN, cfga_strs[HELP_HEADER]));
269473047d747f7815af570197e4ef7322d3632cEvan Yan * cfga_err() accepts a variable number of message IDs and constructs
269473047d747f7815af570197e4ef7322d3632cEvan Yan * a corresponding error string which is returned via the errstring argument.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * cfga_err() calls gettext() to internationalize proper messages.
269473047d747f7815af570197e4ef7322d3632cEvan Yan char *s[32];
269473047d747f7815af570197e4ef7322d3632cEvan Yan * If errstring is null it means user is not interested in getting
269473047d747f7815af570197e4ef7322d3632cEvan Yan * error status. So we don't do all the work
269473047d747f7815af570197e4ef7322d3632cEvan Yan for (n = len = 0; (a = va_arg(ap, int)) != 0; n++) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan switch (a) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan switch (a) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan s[++n] = q;
269473047d747f7815af570197e4ef7322d3632cEvan Yan for (i = 0; i < n; i++) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan * cfga_ap_id_cmp -- use default_ap_id_cmp() in libcfgadm