3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews * CDDL HEADER START
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews * The contents of this file are subject to the terms of the
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews * Common Development and Distribution License (the "License").
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews * You may not use this file except in compliance with the License.
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews * See the License for the specific language governing permissions
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews * and limitations under the License.
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews * When distributing Covered Code, include this CDDL HEADER in each
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews * If applicable, add the following below this CDDL HEADER, with the
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews * fields enclosed by brackets "[]" replaced with your own identifying
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews * information: Portions Copyright [yyyy] [name of copyright owner]
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews * CDDL HEADER END
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews * Use is subject to license terms.
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews#define DEFAULT_LUN_LENGTH DEFAULT_LUN_COUNT * \
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews/* Some forward declarations */
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrewsstatic fpcfga_ret_t do_devctl_dev_create(apid_t *, char *, int,
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrewsstatic fpcfga_ret_t dev_rcm_online(apid_t *, int, cfga_flags_t, char **);
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrewsstatic void dev_rcm_online_nonoperationalpath(apid_t *, cfga_flags_t, char **);
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrewsstatic fpcfga_ret_t dev_rcm_offline(apid_t *, cfga_flags_t, char **);
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrewsstatic fpcfga_ret_t dev_rcm_remove(apid_t *, cfga_flags_t, char **);
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrewsstatic fpcfga_ret_t lun_unconf(char *, int, char *, char *, char **);
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrewsstatic fpcfga_ret_t dev_unconf(apid_t *, char **, uchar_t *);
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrewsstatic fpcfga_ret_t is_xport_phys_in_pathlist(apid_t *, char **);
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrewsstatic void copy_pwwn_data_to_str(char *, const uchar_t *);
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrewsstatic fpcfga_ret_t unconf_vhci_nodes(di_path_t, di_node_t, char *,
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews char *, int, int *, int *, char **, cfga_flags_t);
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrewsstatic fpcfga_ret_t unconf_non_vhci_nodes(di_node_t, char *, char *,
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews int, int *, int *, char **, cfga_flags_t);
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrewsstatic fpcfga_ret_t unconf_any_devinfo_nodes(apid_t *, cfga_flags_t, char **,
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews int *, int *);
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrewsstatic fpcfga_ret_t handle_devs(cfga_cmd_t, apid_t *, cfga_flags_t,
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews * This function initiates the creation of the new device node for a given
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews * So, apidt->dyncomp CANNOT be NULL
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrewsdo_devctl_dev_create(apid_t *apidt, char *dev_path, int pathlen,
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews if ((ddef_hdl = devctl_ddef_alloc(drvr_name, 0)) == NULL) {
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews cfga_err(errstring, errno, ERRARG_DC_DDEF_ALLOC, drvr_name, 0);
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews if (cvt_dyncomp_to_lawwn(apidt->dyncomp, &pwwn)) {
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews if (devctl_ddef_byte_array(ddef_hdl, PORT_WWN_PROP, FC_WWN_SIZE,
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews cfga_err(errstring, errno, ERRARG_DC_BYTE_ARRAY,
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews if ((bus_hdl = devctl_bus_acquire(apidt->xport_phys, 0)) == NULL) {
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews cfga_err(errstring, errno, ERRARG_DC_BUS_ACQUIRE,
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews /* Let driver handle creation of the new path */
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews if (devctl_bus_dev_create(bus_hdl, ddef_hdl, 0, &dev_hdl)) {
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews * Unknown DTYPES are devices such as another system's
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews * FC HBA port. We have tried to configure it but
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews * have failed. Since devices with no device type
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews * or an unknown dtype cannot be configured, we will
3b83676e079a799f97ad8b76c057e6ecb0426b1dMark Andrews * return an appropriate error message.
return (FPCFGA_LIB_ERR);
return (FPCFGA_OK);
static fpcfga_ret_t
return (FPCFGA_OK);
FPCFGA_OK) {
ret++;
if (ret > 0)
return (retval);
char **errstring)
static fpcfga_ret_t
return (FPCFGA_OK);
if (((ret == 0) &&
((ret != 0) &&
DI_DEVICE_OFFLINE))) {
flags) != 0) {
return (FPCFGA_LIB_ERR);
count++;
flags) != 0) {
NULL);
return (FPCFGA_LIB_ERR);
count++;
return (FPCFGA_OK);
static fpcfga_ret_t
return (FPCFGA_OK);
if (((ret == 0) &&
((ret != 0) &&
DI_DEVICE_OFFLINE))) {
flags) != 0) {
return (FPCFGA_LIB_ERR);
count++;
flags) != 0) {
NULL);
return (FPCFGA_LIB_ERR);
count++;
return (FPCFGA_OK);
static fpcfga_ret_t
char **errstring)
return (FPCFGA_OK);
return (FPCFGA_LIB_ERR);
pathname, 0);
return (FPCFGA_LIB_ERR);
return (FPCFGA_LIB_ERR);
return (FPCFGA_LIB_ERR);
return (FPCFGA_OK);
static fpcfga_ret_t
lun_cnt++;
return (ret);
return (ret);
return (ret);
return (ret);
static fpcfga_ret_t
return (FPCFGA_LIB_ERR);
xport_phys, 0);
return (FPCFGA_LIB_ERR);
return (FPCFGA_LIB_ERR);
DI_NODE_NIL) {
return (FPCFGA_LIB_ERR);
found = 0;
if (found == 0) {
xport_phys, 0);
return (FPCFGA_LIB_ERR);
found = 0;
xport_phys, 0);
return (FPCFGA_LIB_ERR);
xport_phys, 0);
return (FPCFGA_LIB_ERR);
xport_phys, 0);
return (FPCFGA_LIB_ERR);
if (num_active_paths != 0) {
if (non_operational_path_count == 0) {
xport_phys, 0);
return (FPCFGA_APID_NOEXIST);
return (FPCFGA_OK);
return (FPCFGA_OK);
return (FPCFGA_LIB_ERR);
(void) update_fabric_wwn_list(
lun = 0;
if (status ==
return (FPCFGA_APID_NOEXIST);
return (FPCFGA_LIB_ERR);
for (i = 0; i < num_luns; i++) {
if (num_luns == 0) {
lun = 0;
return (FPCFGA_APID_NOEXIST);
return (FPCFGA_LIB_ERR);
switch (state_change_cmd) {
case CFGA_CMD_CONFIGURE:
return (FPCFGA_OK);
return (FPCFGA_OK);
errno = 0;
return (FPCFGA_APID_NOEXIST);
return (FPCFGA_LIB_ERR);
return (FPCFGA_LIB_ERR);
return (ret);
return (ret);
return (FPCFGA_OK);
case CFGA_CMD_UNCONFIGURE:
return (FPCFGA_OPNOTSUPP);
if ((optflag &
return (FPCFGA_APID_NOEXIST);
return (FPCFGA_OK);
FPCFGA_OK) {
return (FPCFGA_XPORT_NOT_IN_PHCI_LIST);
FPCFGA_OK) {
return (ret);
FPCFGA_OK) {
if (!no_config_attempt) {
return (ret);
FPCFGA_OK) {
return (ret);
if ((optflag &
return (FPCFGA_UNCONF_OK_UPD_REP_FAILED);
return (FPCFGA_OK);
return (FPCFGA_OPNOTSUPP);
static fpcfga_ret_t
(*num_devs)++;
xport_phys, 0);
(*failure_count)++;
node_path, 0);
(*failure_count)++;
DI_NODE_NIL) {
(*failure_count)++;
(*failure_count)++;
(*failure_count)++;
flags) != 0) {
(*failure_count)++;
pnode);
!= FPCFGA_OK) {
(*failure_count)++;
pnode);
flags) != 0) {
(*failure_count)++;
pnode);
(*failure_count)++;
(*failure_count)++;
flags) != 0) {
(*failure_count)++;
(*failure_count)++;
errstring)) {
(*failure_count)++;
return (FPCFGA_OK);
static fpcfga_ret_t
(*num_devs)++;
(*failure_count)++;
(*failure_count)++;
flags) != 0) {
(*failure_count)++;
!= FPCFGA_OK) {
(*failure_count)++;
flags) != 0) {
(*failure_count)++;
(*failure_count)++;
(*failure_count)++;
flags) != 0) {
(*failure_count)++;
(*failure_count)++;
errstring)) {
(*failure_count)++;
return (FPCFGA_OK);
static fpcfga_ret_t
return (FPCFGA_INVALID_PATH);
DI_NODE_NIL) {
return (FPCFGA_LIB_ERR);
return (FPCFGA_LIB_ERR);
return (FPCFGA_LIB_ERR);
return (FPCFGA_OK);
return (FPCFGA_OK);
* This function handles configuring/unconfiguring all the devices w.r.t
static fpcfga_ret_t
return (FPCFGA_LIB_ERR);
discIndex++) {
if (dev_cs_failed == 0)
return (FPCFGA_OK);
return (FPCFGA_LIB_ERR);
return (FPCFGA_LIB_ERR);
return (FPCFGA_LIB_ERR);
return (FPCFGA_LIB_ERR);
return (ret);
switch (state_change_cmd) {
case CFGA_CMD_CONFIGURE:
return (FPCFGA_OK);
case CFGA_CMD_UNCONFIGURE:
return (FPCFGA_OPNOTSUPP);
return (FPCFGA_LIB_ERR);
return (ret);