fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER START
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The contents of this file are subject to the terms of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Common Development and Distribution License (the "License").
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You may not use this file except in compliance with the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the License for the specific language governing permissions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and limitations under the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If applicable, add the following below this CDDL HEADER, with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER END
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Use is subject to license terms.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* Some forward declarations */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fpcfga_ret_t do_devctl_dev_create(apid_t *, char *, int,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fpcfga_ret_t dev_rcm_online(apid_t *, int, cfga_flags_t, char **);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void dev_rcm_online_nonoperationalpath(apid_t *, cfga_flags_t, char **);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fpcfga_ret_t dev_rcm_offline(apid_t *, cfga_flags_t, char **);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fpcfga_ret_t dev_rcm_remove(apid_t *, cfga_flags_t, char **);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fpcfga_ret_t lun_unconf(char *, int, char *, char *, char **);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fpcfga_ret_t dev_unconf(apid_t *, char **, uchar_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fpcfga_ret_t is_xport_phys_in_pathlist(apid_t *, char **);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void copy_pwwn_data_to_str(char *, const uchar_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fpcfga_ret_t unconf_vhci_nodes(di_path_t, di_node_t, char *,
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada char *, int, int *, int *, char **, cfga_flags_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fpcfga_ret_t unconf_non_vhci_nodes(di_node_t, char *, char *,
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada int, int *, int *, char **, cfga_flags_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fpcfga_ret_t unconf_any_devinfo_nodes(apid_t *, cfga_flags_t, char **,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int *, int *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fpcfga_ret_t handle_devs(cfga_cmd_t, apid_t *, cfga_flags_t,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function initiates the creation of the new device node for a given
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * So, apidt->dyncomp CANNOT be NULL
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedo_devctl_dev_create(apid_t *apidt, char *dev_path, int pathlen,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ddef_hdl = devctl_ddef_alloc(drvr_name, 0)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cfga_err(errstring, errno, ERRARG_DC_DDEF_ALLOC, drvr_name, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cvt_dyncomp_to_lawwn(apidt->dyncomp, &pwwn)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (devctl_ddef_byte_array(ddef_hdl, PORT_WWN_PROP, FC_WWN_SIZE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((bus_hdl = devctl_bus_acquire(apidt->xport_phys, 0)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cfga_err(errstring, errno, ERRARG_DC_BUS_ACQUIRE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Let driver handle creation of the new path */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (devctl_bus_dev_create(bus_hdl, ddef_hdl, 0, &dev_hdl)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Unknown DTYPES are devices such as another system's
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FC HBA port. We have tried to configure it but
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * have failed. Since devices with no device type
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or an unknown dtype cannot be configured, we will
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * return an appropriate error message.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ERRARG_BUS_DEV_CREATE_UNKNOWN, apidt->dyncomp, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cfga_err(errstring, errno, ERRARG_BUS_DEV_CREATE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Online, in RCM, all the LUNs for a particular device.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Caller can specify the # of luns in the lunlist that have to be onlined
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * by passing a count that is not -ve.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * apidt - this is expected to have the list of luns for the device and so
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is assumed to be filled in prior to this call
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * count - # of LUNs in the list that have to be onlined.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * errstring - If non-NULL, it will hold any error messages
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 0 on success
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * non-zero otherwise
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedev_rcm_online(apid_t *apidt, int count, cfga_flags_t flags, char **errstring)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* This check may be redundant, but safer this way */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* User has requested not to notify RCM framework */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (lunlistp = apidt->lunlist; lunlistp != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_rcm_online(lunlistp->path, errstring, flags) !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Online in RCM for devices which only have paths
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * not in ONLINE/STANDBY state
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedev_rcm_online_nonoperationalpath(apid_t *apidt, cfga_flags_t flags,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (lunlistp = apidt->lunlist; lunlistp != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((lunlistp->lun_flag & FLAG_SKIP_ONLINEOTHERS) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_rcm_online(lunlistp->path, errstring, flags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Offline, in RCM, all the LUNs for a particular device.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function should not be called for the MPXIO case.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * apidt - this is expected to have the list of luns for the device and so
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is assumed to be filled in prior to this call
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * errstring - If non-NULL, it will hold any error messages
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FPCFGA_OK on success
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * error code otherwise
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedev_rcm_offline(apid_t *apidt, cfga_flags_t flags, char **errstring)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* User has requested not to notify RCM framework */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (lunlistp = apidt->lunlist; lunlistp != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((lunlistp->lun_flag & FLAG_SKIP_RCMOFFLINE) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((apidt->flags & FLAG_REMOVE_UNUSABLE_FCP_DEV) ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ret = strncmp(lunlistp->path, SCSI_VHCI_ROOT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (((ret == 0) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (lunlistp->node_state == DI_PATH_STATE_OFFLINE)) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Offline the device through RCM */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Bring everything back online in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rcm and return
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Offline the device through RCM */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Bring everything back online in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rcm and return
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Remove, in RCM, all the LUNs for a particular device.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function should not be called for the MPXIO case.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * apidt - this is expected to have the list of luns for the device and so
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is assumed to be filled in prior to this call
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * errstring - If non-NULL, it will hold any error messages
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FPCFGA_OK on success
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * error code otherwise
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedev_rcm_remove(apid_t *apidt, cfga_flags_t flags, char **errstring)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* User has requested not to notify RCM framework */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (lunlistp = apidt->lunlist; lunlistp != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((lunlistp->lun_flag & FLAG_SKIP_RCMREMOVE) != 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((apidt->flags & FLAG_REMOVE_UNUSABLE_FCP_DEV) ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ret = strncmp(lunlistp->path, SCSI_VHCI_ROOT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (((ret == 0) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (lunlistp->node_state == DI_PATH_STATE_OFFLINE)) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* remove the device through RCM */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Bring everything back online in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rcm and return
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* remove the device through RCM */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Bring everything back online in rcm and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortelun_unconf(char *path, int lunnum, char *xport_phys, char *dyncomp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (strncmp(path, SCSI_VHCI_ROOT, strlen(SCSI_VHCI_ROOT)) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We have an MPXIO managed device here.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * So, we have to concoct a path for the device.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * xport_phys looks like :
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * /devices/pci@b,2000/pci@1/SUNW,qlc@5/fp@0,0:fc
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strlcpy(pathname, xport_phys, MAXPATHLEN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Get pointer to driver name from VHCI path
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * So, if lunlistp->path is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * /devices/scsi_vhci/ssd@g220000203707a417,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we need a pointer to the last '/'
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Assumption:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * With MPXIO there will be only one entry per lun
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * So, there will only be one entry in the linked list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * apidt->lunlist
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* This shouldn't happen, but anyways ... */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cfga_err(errstring, 0, ERRARG_INVALID_PATH, path, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Make pathname to look something like :
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * /devices/pci@x,xxxx/pci@x/SUNW,qlc@x/fp@x,x/ssd@w...
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * apidt_create() will make sure that lunlist->path
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * has a "@<something>" at the end even if the driver
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * state is "detached"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* This shouldn't happen, but anyways ... */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Now, concoct the path */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * non-MPXIO path, use the path that is passed in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((hdl = devctl_device_acquire(ptr, 0)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cfga_err(errstring, errno, ERRARG_DEV_ACQUIRE, ptr, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cfga_err(errstring, errno, ERRARG_DEV_REMOVE, ptr, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedev_unconf(apid_t *apidt, char **errstring, uchar_t *flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (lunlistp = apidt->lunlist; lunlistp != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Unconfigure each LUN.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Note that for MPXIO devices, lunlistp->path will be a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((apidt->flags & FLAG_REMOVE_UNUSABLE_FCP_DEV) ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((lunlistp->node_state & DI_DEVICE_OFFLINE) ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Unconfigure each LUN.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Note that for MPXIO devices, lunlistp->path will be a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret = lun_unconf(lunlistp->path, lunlistp->lunnum,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((apidt->flags & FLAG_REMOVE_UNUSABLE_FCP_DEV) ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * when all luns are unconfigured
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * indicate to remove repository entry.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check if the given physical path (the xport_phys) is part of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * pHCI list and if the RCM should be done for a particular pHCI.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Skip non-MPxIO dev node if any.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteis_xport_phys_in_pathlist(apid_t *apidt, char **errstring)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *vhci_path_ptr, *pathname_ptr, pathname[MAXPATHLEN];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* a safety check */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((apidt->dyncomp == NULL) || (*apidt->dyncomp == '\0')) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (lunlistp = apidt->lunlist; lunlistp != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte num_active_paths = 0; /* # of paths in ONLINE/STANDBY */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cfga_err(errstring, 0, ERRARG_XPORT_NOT_IN_PHCI_LIST,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strlcpy(pathname, xport_phys, MAXPATHLEN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((pathname_ptr = strrchr(pathname, ':')) != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* strip off the /devices/from the path */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((vhci = di_drv_first_node(SCSI_VHCI_DRVR, root)) ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (node = di_child_node(vhci); node != DI_NODE_NIL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cfga_err(errstring, 0, ERRARG_XPORT_NOT_IN_PHCI_LIST,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* found vhci_path we are looking for */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (path = di_path_next_phci(node, DI_PATH_NIL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((phci = di_path_phci_node(path)) == DI_NODE_NIL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((phci_addr == NULL) || (*phci_addr == '\0')) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check if the phci path has the same
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * xport addr and the target addr with current lun
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* SUCCESS Found xport_phys */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (di_path_state(path) == DI_PATH_STATE_STANDBY)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We have another path not in ONLINE/STANDBY
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * state now, so should do a RCM online after
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the unconfiguration of current path.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * There are other ONLINE/STANDBY paths,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * so no need to do the RCM
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Fail all operations here
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cfga_err(errstring, 0, ERRARG_XPORT_NOT_IN_PHCI_LIST,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Mark duplicated paths for same vhci in the list */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (lunlistp = apidt->lunlist; lunlistp != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * don't do RCM for dup
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * apidt->dyncomp has to be non-NULL by the time this routine is called
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedev_change_state(cfga_cmd_t state_change_cmd, apid_t *apidt, la_wwn_t *pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cfga_flags_t flags, char **errstring, HBA_HANDLE handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((apidt->dyncomp == NULL) || (*apidt->dyncomp == '\0')) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * No dynamic component specified. Just return success.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Should not see this case. Just a safety check.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Now construct the string we are going to put in the repository */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((update_str = calloc(1, (strlen(apidt->xport_phys) +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strlen(DYN_SEP) + strlen(apidt->dyncomp) + 1))) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* If force update of repository is sought, do it first */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Ignore any failure in rep update */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret = get_report_lun_data(apidt->xport_phys, apidt->dyncomp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &num_luns, &resp_buf, &sense, &l_errno)) != FPCFGA_OK) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Checking the sense key data as well as the additional
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * sense key. The SES Node is not required to repond
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to Report LUN. In the case of Minnow, the SES node
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returns with KEY_ILLEGAL_REQUEST and the additional
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * sense key of 0x20. In this case we will blindly
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * send the SCSI Inquiry call to lun 0
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if we get any other error we will set the inq_type
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * appropriately
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Failed to get the LUN data for the device
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If we find that there is a lunlist for this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * device it could mean that there are dangling
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * devinfo nodes. So, we will go ahead and try
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to unconfigure them.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* unconfig with lunlist not empty */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < num_luns; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * issue the inquiry to the first valid lun found
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in the lun_string
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lun_string = (uchar_t *)&(resp_buf->lun_string[i]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte status = HBA_ScsiInquiryV2(handle, portAttrs.PortWWN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *(HBA_WWN *)(pwwn), lun, 0, 0, &inq, &inquirySize,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if Inquiry is returned correctly, check the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * peripheral qualifier for the lun. if it is non-zero
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * then try the SCSI Inquiry on the next lun
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If there are no luns on this target, we will attempt to send
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the SCSI Inquiry to lun 0
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte status = HBA_ScsiInquiryV2(handle, portAttrs.PortWWN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *(HBA_WWN *)(pwwn), lun, 0, 0, &inq, &inquirySize,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (status == HBA_STATUS_ERROR_ILLEGAL_WWN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Failed to get the inq_dtype of device
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If we find that there is a lunlist for this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * device it could mean that there dangling
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * devinfo nodes. So, we will go ahead and try
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to unconfigure them. We'll just set the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * inq_dtype to some invalid value (0xFF)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* unconfig with lunlist not empty */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (((inq.inq_dtype & DTYPE_MASK) == DTYPE_UNKNOWN) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We assume all DTYPE_UNKNOWNs are HBAs and we wont
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * waste time trying to config them. If they are not
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * HBAs, then there is something wrong since they should
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * have had a valid dtype.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * However, if the force flag is set (cfgadm -f), we
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * go ahead and try to configure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * In this path, however, the force flag is not set.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We'll issue the devctl_bus_dev_create() call even if the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * path exists in the devinfo tree. This is to take care of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the situation where the device may be in a state other
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * than the online and attached state.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret = do_devctl_dev_create(apidt, dev_path, MAXPATHLEN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Could not configure device. To provide a more
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * meaningful error message, first see if the supplied port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * WWN is there on the fabric. Otherwise print the error
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * message using the information received from the driver
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte status = getPortAttrsByWWN(handle, *((HBA_WWN *)(pwwn)),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (((optflag & (FLAG_FORCE_UPDATE_REP|FLAG_NO_UPDATE_REP)) == 0) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte update_fabric_wwn_list(ADD_ENTRY, update_str, errstring)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * There may be multiple LUNs associated with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * WWN we created nodes for. So, we'll call
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * apidt_create() again and let it build a list of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * all the LUNs for this WWN using the devinfo tree.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We will then online all those devices in RCM
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((t_apid = calloc(1, strlen(apidt->xport_phys) +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sprintf(t_apid, "%s%s%s", apidt->xport_phys, DYN_SEP,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte status = getPortAttrsByWWN(handle, *((HBA_WWN *)(pwwn)),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * But first, remove entry from the repository if it is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * there ... provided the force update flag is not set
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (in which case the update is already done) or if
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the no-update flag is not set.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (FLAG_FORCE_UPDATE_REP|FLAG_NO_UPDATE_REP)) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If there are multiple paths to the mpxio
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * device, we will not check in RCM ONLY when there
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is atleast one other ONLINE/STANDBY path
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (is_xport_phys_in_pathlist(apidt, errstring) !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dev_rcm_offline() updates errstring
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret = dev_rcm_offline(apidt, flags, errstring)) !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret = dev_unconf(apidt, errstring, &unconf_flag)) !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* when inq failed don't attempt to reconfigure */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) do_devctl_dev_create(apidt, dev_path, MAXPATHLEN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret = dev_rcm_remove(apidt, flags, errstring)) !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) do_devctl_dev_create(apidt, dev_path, MAXPATHLEN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If we offlined a lun in RCM when there are multiple paths but
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * none of them are ONLINE/STANDBY, we have to online it back
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in RCM now. This is a try best, will not fail for it.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev_rcm_online_nonoperationalpath(apidt, flags, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Update the repository if we havent already done it */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (FLAG_FORCE_UPDATE_REP|FLAG_NO_UPDATE_REP)) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function copies a port_wwn got by reading the property on a device
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * node (from_ptr in the function below) on to an array (to_ptr) so that it is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Caller responsible to allocate enough memory in "to_ptr"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortecopy_pwwn_data_to_str(char *to_ptr, const uchar_t *from_ptr)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(to_ptr, "%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte from_ptr[0], from_ptr[1], from_ptr[2], from_ptr[3],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte from_ptr[4], from_ptr[5], from_ptr[6], from_ptr[7]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteunconf_vhci_nodes(di_path_t pnode, di_node_t fp_node, char *xport_phys,
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada int *num_devs, int *failure_count, char **errstring,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char port_wwn[WWN_SIZE*2+1], pathname[MAXPATHLEN];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((node_path = di_devfs_path(fp_node)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iret1 = di_path_prop_lookup_bytes(pnode, PORT_WWN_PROP,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iret2 = di_path_prop_lookup_ints(pnode, LUN_PROP, &lunnump);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((client_node = di_path_client_node(pnode)) ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((vhci_path = di_devfs_path(client_node)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sprintf(pathname, "%s%s/%s@w%s,%x", DEVICES_DIR, node_path,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Try to offline in RCM first and if that is successful,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * unconfigure the LUN. If offlining in RCM fails, then
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * update the failure_count which gets passed back to caller
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada * Here we got to check if unusable_flag is set or not.
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada * If set, then unconfigure only those luns which are in
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada * node_state DI_PATH_STATE_OFFLINE. If not set, unconfigure
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada if ((unusable_flag & FLAG_REMOVE_UNUSABLE_FCP_DEV) ==
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada if (pnode->path_state == DI_PATH_STATE_OFFLINE) {
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada } else if (fp_rcm_remove(pathname, errstring,
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada * Bring everything back online
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada * in rcm and continue
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada if (fp_rcm_offline(pathname, errstring, flags) != 0) {
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada pnode = di_path_next_client(fp_node, pnode);
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada } else if (lun_unconf(pathname, *lunnump, xport_phys,
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada (void) fp_rcm_online(pathname, NULL, flags);
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada pnode = di_path_next_client(fp_node, pnode);
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada } else if (fp_rcm_remove(pathname, errstring,
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada * Bring everything back online
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada * in rcm and continue
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada (void) fp_rcm_online(pathname, NULL, flags);
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada pnode = di_path_next_client(fp_node, pnode);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Update the repository only on a successful unconfigure */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cfga_err(errstring, errno, ERR_UNCONF_OK_UPD_REP, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Init the string to be removed from repository */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sprintf(update_str, "%s%s%s", xport_phys, DYN_SEP, port_wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (update_fabric_wwn_list(REMOVE_ENTRY, update_str,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Cleanup and continue from here just for clarity */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteunconf_non_vhci_nodes(di_node_t dnode, char *xport_phys, char *dyncomp,
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada int unusable_flag, int *num_devs, int *failure_count,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Get the physical path for this node */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((node_path = di_devfs_path(dnode)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We don't try to offline in RCM here because we
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * don't know the path to offline. Just continue to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the next node.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cfga_err(errstring, 0, ERRARG_DEVINFO, xport_phys, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Now get the LUN # of this device thru the property */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Next get the port WWN of the device */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret2 = di_prop_lookup_bytes(DDI_DEV_T_ANY, dnode,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* A failure in any of the above is not good */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We don't try to offline in RCM here because we
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * don't know the path to offline. Just continue to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the next node.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Prepend the "/devices" prefix to the path and copy it */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sprintf(pathname, "%s%s", DEVICES_DIR, node_path);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the driver is detached, some part of the path
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * may be missing and so we'll manually construct it
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Try to offline in RCM first and if that is successful,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * unconfigure the LUN. If offlining in RCM fails, then
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * update the failure count
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada * Here we got to check if unusable_flag is set or not.
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada * If set, then unconfigure only those luns which are in
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada * node_state DI_DEVICE_OFFLINE or DI_DEVICE_DOWN.
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada * If not set, unconfigure all luns.
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada if ((unusable_flag & FLAG_REMOVE_UNUSABLE_FCP_DEV) ==
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada if ((dnode->node_state == DI_DEVICE_OFFLINE) ||
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada } else if (fp_rcm_remove(pathname, errstring,
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada * Bring everything back online
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada * in rcm and continue
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada if (fp_rcm_offline(pathname, errstring, flags) != 0) {
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada } else if (lun_unconf(pathname, *lunnump, xport_phys,
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada (void) fp_rcm_online(pathname, NULL, flags);
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada } else if (fp_rcm_remove(pathname, errstring,
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada * Bring everything back online
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada * in rcm and continue
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada (void) fp_rcm_online(pathname, NULL, flags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Update the repository only on a successful unconfigure */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cfga_err(errstring, errno, ERR_UNCONF_OK_UPD_REP, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Init the string to be removed from repository */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sprintf(update_str, "%s%s%s", xport_phys, DYN_SEP, port_wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (update_fabric_wwn_list(REMOVE_ENTRY, update_str,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cfga_err(errstring, errno, ERR_UNCONF_OK_UPD_REP, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * apidt - Pointer to apid_t structure with data filled in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * flags - Flags for special handling
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * errstring - Applicable only on a failure from plugin
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * num_devs - Incremented per lun
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * failure_count - Incremented on any failed operation on lun
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * non-FPCFGA_OK on any validation check error. If this value is returned, no
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * devices were handled. Consequently num_devs and failure_count
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * will not be incremented.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FPCFGA_OK This return value doesn't mean that all devices were successfully
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * unconfigured, you have to check failure_count.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteunconf_any_devinfo_nodes(apid_t *apidt, cfga_flags_t flags, char **errstring,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char pathname[MAXPATHLEN], *ptr; /* scratch pad */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * apidt->xport_phys is something like :
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * /devices/pci@.../SUNW,qlc@../fp@0,0:fc
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Make sure we copy both the devinfo and pathinfo nodes
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strlcpy(pathname, apidt->xport_phys, MAXPATHLEN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Now get rid of the ':' at the end */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (strncmp(pathname, DEVICES_DIR, strlen(DEVICES_DIR))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cfga_err(errstring, 0, ERRARG_INVALID_PATH, pathname, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((root_node = di_init("/", DINFOCPYALL | DINFOPATH)) ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((fp_node = di_drv_first_node("fp", root_node)) == DI_NODE_NIL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Search all the fp nodes to see if any match the one we are trying
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to unconfigure
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Skip the "/devices" prefix */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Found the fp node. 'pathname' has the full path */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte path_node = di_path_next_client(fp_node, path_node);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((direct_node == DI_NODE_NIL) && (path_node == DI_PATH_NIL)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* No devinfo or pathinfo nodes. Great ! Just return success */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* First unconfigure any non-MPXIO nodes */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte unconf_non_vhci_nodes(direct_node, apidt->xport_phys, apidt->dyncomp,
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada apidt->flags, num_devs, failure_count, errstring, flags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Now we will traverse any path info nodes that are there
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Only MPXIO devices have pathinfo nodes
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte unconf_vhci_nodes(path_node, fp_node, apidt->xport_phys, apidt->dyncomp,
3c709d8a1cbd663cabf900d1c42dc55f422f781cRaghuram Prahlada apidt->flags, num_devs, failure_count, errstring, flags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We don't want to check the return value of unconf_non_vhci_nodes()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and unconf_vhci_nodes(). But instead, we are interested only in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * consistently incrementing num_devs and failure_count so that we can
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * compare them.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function handles configuring/unconfiguring all the devices w.r.t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the FCA port specified by apidt.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * In the unconfigure case, it first unconfigures all the devices that are
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * seen through the given port at that moment and then unconfigures all the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * devices that still (somehow) have devinfo nodes on the system for that FCA
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * cmd - CFGA_CMD_CONFIGURE or CFGA_CMD_UNCONFIGURE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * apidt - Pointer to apid_t structure with data filled in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * flags - Flags for special handling
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * errstring - Applicable only on a failure from plugin
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FPCFGA_OK on success
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * non-FPCFGA_OK otherwise
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortehandle_devs(cfga_cmd_t cmd, apid_t *apidt, cfga_flags_t flags,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char **errstring, HBA_HANDLE handle, int portIndex,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (discIndex = 0; discIndex < portAttrs.NumberofDiscoveredPorts;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Move on to the next target */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Construct a fake apid string similar to the one the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * plugin gets from the framework and have apidt_create()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fill in the apid_t structure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (apidt_create(my_apid, &my_apidt, errstring) != FPCFGA_OK) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte memcpy(&pwwn, &(discPortAttrs.PortWWN), sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte flags, errstring, handle, portAttrs) != FPCFGA_OK) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We have now handled all the devices that are currently visible
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * through the given FCA port. But, it is possible that there are
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * some devinfo nodes hanging around. For the unconfigure operation,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this has to be looked into too.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* dev_cs_failed will be updated to indicate any failures */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = unconf_any_devinfo_nodes(apidt, flags, errstring,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For the discovered ports, num_devs is counted on target
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * basis, but for invisible targets, num_devs is counted on
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * lun basis.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * But if dev_cs_failed and num_devs are incremented
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * consistently, comparation of these two counters is still
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * meaningful.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Failed on all devices seen through this FCA port */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Failed only on some of the devices */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Failed on all devices seen through this FCA port */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Failed only on some of the devices */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Should never get here
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefca_change_state(cfga_cmd_t state_change_cmd, apid_t *apidt,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret = findMatchingAdapterPort(apidt->xport_phys, &handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &portIndex, &portAttrs, errstring)) != FPCFGA_OK) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Bail out if not fabric/public loop