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
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Use is subject to license terms.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* Structure for walking the tree */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortetypedef struct {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortetypedef struct {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* The TYPE field is parseable and should not contain spaces */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* Indicates no plag passing */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* defines for retry algorithm */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define OPEN_RETRY_INTERVAL 10000 /* 1/100 of a sec. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* define for fcp scsi passthru wait */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* define for fcp pseudo node */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* Function prototypes */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fpcfga_ret_t postprocess_list_data(const ldata_list_t *listp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fpcfga_cmd_t cmd, cfga_stat_t chld_config, int *np, uint_t flags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int stat_fc_dev(di_node_t node, void *arg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int stat_FCP_dev(di_node_t node, void *arg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fpcfga_ret_t do_stat_fca_xport(fpcfga_list_t *lap, int limited_stat,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int get_xport_state(di_node_t node, void *arg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fpcfga_ret_t do_stat_fc_dev(const di_node_t node, const char *nodepath,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fpcfga_ret_t do_stat_FCP_dev(const di_node_t node, const char *nodepath,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic cfga_stat_t xport_devinfo_to_recep_state(uint_t xport_di_state);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic cfga_stat_t dev_devinfo_to_occupant_state(uint_t dev_di_state);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void get_hw_info(di_node_t node, cfga_list_data_t *clp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fpcfga_ret_t init_ldata_for_accessible_dev(const char *dyncomp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fpcfga_ret_t init_ldata_for_accessible_FCP_dev(const char *port_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fpcfga_ret_t is_dyn_ap_on_ldata_list(const char *port_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte const ldata_list_t *listp, ldata_list_t **matchldpp, int *l_errno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fpcfga_ret_t is_FCP_dev_ap_on_ldata_list(const char *port_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte const int lun_num, ldata_list_t *ldatap, ldata_list_t **matchldpp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fpcfga_ret_t init_ldata_for_mpath_dev(di_path_t path, char *port_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fpcfga_ret_t insert_ldata_to_ldatalist(const char *port_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int *lun_nump, ldata_list_t *listp, ldata_list_t **ldatapp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fpcfga_ret_t insert_fc_dev_ldata(const char *port_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fpcfga_ret_t insert_FCP_dev_ldata(const char *port_wwn, int lun_num,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int stat_path_info_fc_dev(di_node_t root, fpcfga_list_t *lap,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int stat_path_info_FCP_dev(di_node_t root, fpcfga_list_t *lap,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fpcfga_ret_t get_accessible_FCP_dev_ldata(const char *dyncomp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fpcfga_ret_t get_standard_inq_data(const char *xport_phys,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte const char *dyncomp, uchar_t *lun_num, struct scsi_inquiry **inq_buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void init_fcp_scsi_cmd(struct fcp_scsi_cmd *fscsi, uchar_t *lun_num,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t *pwwn, void *scmdbuf, size_t scmdbuf_len, void *respbuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte size_t respbuf_len, void *sensebuf, size_t sensebuf_len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fpcfga_ret_t issue_fcp_scsi_cmd(const char *xport_phys,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic uchar_t get_inq_dtype(char *xport_phys, char *dyncomp, HBA_HANDLE handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte HBA_PORTATTRIBUTES *portAttrs, HBA_PORTATTRIBUTES *discPortAttrs);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This has to be the LAST entry for DTYPE_UNKNOWN_INDEX.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Add entries before this.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define N_DEVICE_TYPES (sizeof (device_list) / sizeof (device_list[0]))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Main routine for list operation.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * It calls various routines to consturct ldata list and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * postprocess the list data.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Overall algorithm:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Get the device list on input hba port and construct ldata list for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * accesible devices.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Stat hba port and devices through walking the device tree.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Verify the validity of the list data.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Create the hba logid (also base component of logical ap_id) */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = make_xport_logid(apidp->xport_phys, &larg.xport_logp, &l_errno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret = findMatchingAdapterPort(larg.apidp->xport_phys, &handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &portIndex, &portAttrs, errstring)) != FPCFGA_OK) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If stating a specific device, we will do limited stat on fca port.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * otherwise full stat on fca part is required.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If stating a specific device we don't know if it exists or is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * configured yet. larg.ret is set to apid noexist for do_stat_dev.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * otherwise larg.ret is set to ok initially.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte larg.ret = FPCFGA_APID_NOEXIST; /* for stat_fc_dev */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* For all list commands, the fca port needs to be stat'ed */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret = do_stat_fca_xport(&larg, limited_stat,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If stat'ing a FCA port or ALL, we have the bus stat data at
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this point.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Assume that the bus has no configured children.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* la_wwn_t has uchar_t raw_wwn[8] thus no need to free. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cvt_dyncomp_to_lawwn(apidp->dyncomp, &pwwn) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if the dyncomp exists on disco ports construct list_data
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * otherwise return FPCFGA_APID_NOEXIST.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* get Port Attributes again after refresh. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break; /* either okay or some other error */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if dyncomp found in disco ports
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * construct ldata_list and return.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * otherwise continue to stat on dev tree with
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * larg.ret set to access_ok which informs stat_fc_dev
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the existence of device on disco ports.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if path is null that guatantees the node is not
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * configured. if node is detached the path
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is incomplete and not usable for further
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * operations like uscsi_inq so take care of it here.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte apidp->dyncomp, handle, &portAttrs, &discPortAttrs);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (init_ldata_for_accessible_dev(apidp->dyncomp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (status == HBA_STATUS_ERROR_ILLEGAL_WWN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * path indicates if the node exists in dev tree.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if not found in dev tree return apid no exist.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * otherwise continue to stat with larg.ret set to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * apid_noexist.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else { /* any error */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * path indicates if the node exists in dev tree.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if not found in dev tree return lib error.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * otherwise continue to stat with larg.ret set to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * apid_noexist.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for each dev in disco ports, create a ldata_list element.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if if no disco ports found, continue to stat on devinfo tree
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to see if any node exist on the fca port.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Move on to the next target */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte memcpy(&pwwn, &discPortAttrs.PortWWN, sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte inq_dtype = get_inq_dtype(apidp->xport_phys, dyncomp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* we need to stat at least 1 device for all commands */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte walkarg.walkmode.node_args.flags = DI_WALK_CLDFIRST;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Subtree is ALWAYS rooted at the HBA (not at the device) as
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * otherwise deadlock may occur if bus is disconnected.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * DINFOPROP was sufficient on apidp->xport_phys prior to the support
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * on scsi_vhci child node. In order to get the link between
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * scsi_vhci node and path info node the snap shot of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the whole device tree is required with DINFOCPYALL | DINFOPATH flag.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = walk_tree(apidp->xport_phys, &larg, DINFOCPYALL | DINFOPATH,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ret from walk_tree is either FPCFGA_OK or FPCFGA_ERR.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * larg.ret is used to detect other errors. Make sure larg.ret
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is set to a correct error.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret != FPCFGA_OK || (ret = larg.ret) != FPCFGA_OK) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* if larg.ret = FPCFGA_APID_NOEXIST; */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = postprocess_list_data(larg.listp, cmd, larg.chld_config, &n,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Main routine for list operation when show_FCP_dev option is given.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * It calls various routines to consturct ldata list and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * postprocess the list data.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The difference between do_list() and do_list_FCP_dev() is to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * process FCP SCSI LUN data list via uscsi report lun operation and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * stat lun level instead of port WWN based target level.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The rest of logic is same.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Overall algorithm:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Get the device list on input hba port and construct ldata list for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * accesible devices.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For each configured device, USCSI report lun is issued and ldata list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * with FCP device level(LUN) information is created.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Stat hba port and LUN devices through walking the device tree.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Verify the validity of the list data.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte const char *ap_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *xport_phys = NULL, *dyn = NULL, *dyncomp = NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((xport_phys = pathdup(ap_id, &l_errno)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Extract the base(hba) and dynamic(device) component if any */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Remove the dynamic component from the base. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* if lun dyncomp exists delete it */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Create the hba logid (also base component of logical ap_id) */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = make_xport_logid(larg.apidp->xport_phys, &larg.xport_logp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret = findMatchingAdapterPort(larg.apidp->xport_phys, &handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &portIndex, &portAttrs, errstring)) != FPCFGA_OK) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If stating a specific device, we will do limited stat on fca port.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * otherwise full stat on fca part is required.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If stating a specific device we don't know if it exists or is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * configured yet. larg.ret is set to apid noexist for do_stat_dev.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * otherwise larg.ret is set to ok initially.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte larg.ret = FPCFGA_APID_NOEXIST; /* for stat_fc_dev */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* For all list commands, the fca port needs to be stat'ed */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret = do_stat_fca_xport(&larg, limited_stat,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If stat'ing a FCA port or ALL, we have the bus stat data at
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this point.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Assume that the bus has no configured children.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* la_wwn_t has uchar_t raw_wwn[8] thus no need to free. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cvt_dyncomp_to_lawwn(larg.apidp->dyncomp, &pwwn) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if the dyncomp exists on disco ports construct list_data
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * otherwise return FPCFGA_APID_NOEXIST.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* get Port Attributes again after refresh. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break; /* either okay or some other error */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if dyncomp exists only in dev list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * construct ldata_list and return.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * otherwise continue to stat on dev tree with
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * larg.ret set to access_ok which informs stat_fc_dev
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the existence of device on dev_list.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if path is null that guatantees the node is not
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * configured. if node is detached the path
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is incomplete and not usable for further
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * operations like uscsi_inq so take care of it here.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte status = HBA_ScsiInquiryV2(handle, portAttrs.PortWWN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (status == HBA_STATUS_ERROR_NOT_A_TARGET) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (init_ldata_for_accessible_dev(larg.apidp->dyncomp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* continue to stat dev with access okay. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (status == HBA_STATUS_ERROR_ILLEGAL_WWN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * path indicates if the node exists in dev tree.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if not found in dev tree return apid no exist.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * otherwise continue to stat with larg.ret set to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * apid_noexist.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else { /* not found or any error */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * continue to stat dev with larg.ret set to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * apid_noexist.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for each dev in disco ports, create a ldata_list element.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if if no disco ports found, continue to stat on devinfo tree
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to see if any node exist on the fca port.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Move on to the next target */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte memcpy(&pwwn, &discPortAttrs.PortWWN, sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte status = HBA_ScsiInquiryV2(handle, portAttrs.PortWWN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (status == HBA_STATUS_ERROR_NOT_A_TARGET) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* default: continue */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* we need to stat at least 1 device for all commands */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((larg.apidp->flags & FLAG_DEVINFO_FORCE) == FLAG_DEVINFO_FORCE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte walkarg.walkmode.node_args.flags = DI_WALK_CLDFIRST;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Subtree is ALWAYS rooted at the HBA (not at the device) as
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * otherwise deadlock may occur if bus is disconnected.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * DINFOPROP was sufficient on apidp->xport_phys prior to the support
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * on scsi_vhci child node. In order to get the link between
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * scsi_vhci node and path info node the snap shot of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the whole device tree is required with DINFOCPYALL | DINFOPATH flag.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = walk_tree(larg.apidp->xport_phys, &larg, DINFOCPYALL | DINFOPATH,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ret from walk_tree is either FPCFGA_OK or FPCFGA_ERR.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * larg.ret is used to detect other errors. Make sure larg.ret
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is set to a correct error.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret != FPCFGA_OK || (ret = larg.ret) != FPCFGA_OK) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* if larg.ret = FPCFGA_APID_NOEXIST return. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = postprocess_list_data(larg.listp, cmd, larg.chld_config, &n,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This routine returns initialize struct fcp_ioctl.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte memcpy(fscsi->scsi_fc_pwwn.raw_wwn, pwwn, sizeof (u_longlong_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fscsi->scsi_timeout = FCP_SCSI_CMD_TIMEOUT; /* second */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte memcpy(&fscsi->scsi_lun, lun_num, sizeof (fscsi->scsi_lun));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This routine returns issues FCP_TGT_SEND_SCSI
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fscsi->scsi_fc_port_num = (uint32_t)minor(stbuf.st_rdev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (fcp_fd < 0 && retry++ < OPEN_RETRY_COUNT && (
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((rv != 0 && retry++ < IOCTL_RETRY_COUNT &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fscsi->scsi_fc_status == FC_DEVICE_NOT_TGT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (rv != 0 || fscsi->scsi_bufstatus != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This routine returns standard inq data for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a target represented by dyncomp.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calls FCP passthru ioctl FCP_TGT_SEND_SCSI to get inquiry data.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Caller should free the *inq_buf.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((*inq_buf = (struct scsi_inquiry *)calloc(1, alloc_len)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte init_fcp_scsi_cmd(&fscsi, lun_num, &pwwn, &scsi_inq_req,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (scsi_inq_req), *inq_buf, alloc_len, &sensebuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (struct scsi_extended_sense));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inq_req.g0_count0 = sizeof (struct scsi_inquiry);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret = issue_fcp_scsi_cmd(xport_phys, &fscsi, l_errnop))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This routine returns report lun data and number of luns found
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * on a target represented by dyncomp.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calls FCP passthru ioctl FCP_TGT_SEND_SCSI to get report lun data.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Caller should free the *resp_buf when FPCFGA_OK is returned.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((*resp_buf = (report_lun_resp_t *)calloc(1, alloc_len)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* sending to LUN 0 so initializing lun_data buffer to be 0 */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte init_fcp_scsi_cmd(&fscsi, lun_data, &pwwn, &scsi_rl_req,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (scsi_rl_req), *resp_buf, alloc_len, sensebuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (struct scsi_extended_sense));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret = issue_fcp_scsi_cmd(xport_phys, &fscsi, l_errnop))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (sizeof (struct report_lun_resp) - REPORT_LUN_HDR_SIZE)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte alloc_len = (*resp_buf)->num_lun + REPORT_LUN_HDR_SIZE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((*resp_buf = (report_lun_resp_t *)calloc(1, alloc_len))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret = issue_fcp_scsi_cmd(xport_phys, &fscsi, l_errnop))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* num_lun represent number of luns * 8. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Routine for consturct ldata list for each FCP SCSI LUN device
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for a discovered target device.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * It calls get_report_lun_data to get report lun data and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * construct ldata list per each lun.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * It is called only when show_FCP_dev option is given.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Overall algorithm:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Get the report lun data thru FCP passthru ioctl.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Call init_ldata_for_accessible_FCP_dev to process the report LUN data.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For each LUN found standard inquiry is issued to get device type.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret = get_report_lun_data(lap->apidp->xport_phys, dyncomp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &num_luns, &resp_buf, &sense, l_errnop)) != FPCFGA_OK) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * when report lun data fails then return FPCFGA_OK thus
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * keep the ldata for the target which is acquired previously.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For remote hba node this will be normal.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For a target error may already be detected through
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FCP_TGT_INQ.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * proceed with to stat if no lun found.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This will make the target apid will be kept.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Routine for checking validity of ldata list based on input argumemnt.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Set the occupant state of hba port if the list is valid.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; tmplp != NULL; tmplp = tmplp->next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* A bus stat data */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Fill in the occupant (child) state. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Routine for checking each target device found in device tree.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When the matching port WWN dev is found from the accessble ldata list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the target device is updated with configured ostate.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Overall algorithm:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Parse the device tree to find configured devices which matches with
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * list argument. If cmd is stat on a specific target device it
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * matches port WWN and continues to further processing. If cmd is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * stat on hba port all the device target under the hba are processed.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Skip partial nodes
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This checking is from the scsi plug-in and will be deleted for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fp plug-in. The node will be processed for fp even if it is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in driver detached state. From fp perspective the node is configured
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * as long as the node is not in offline or down state.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * scsi plug-in considers the known state when it is offlined
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * regradless of driver detached state or when it is not in driver
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * detached state like normal state.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the node is only in driver detached state it is considered as
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * unknown state.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if (!known_state(node) && (lap->cmd != FPCFGA_STAT_FC_DEV)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * return (DI_WALK_CONTINUE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) snprintf(nodepath, len, "%s%s", DEVICES_DIR, devfsp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Skip node if it is HBA */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!dev_cmp(lap->apidp->xport_phys, nodepath, match_minor)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* If stat'ing a specific device, is this node that device */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* checks port wwn property to find a match */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * port wwn doesn't match contine to walk
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if match call do_stat_fc_dev.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If stat'ing a xport only, we look at device nodes only to get
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * xport configuration status. So a limited stat will suffice.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Ignore errors if stat'ing a bus or listing all
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = do_stat_fc_dev(node, nodepath, lap, limited_stat);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Are we done ? */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If stat'ing a specific device, we are done at this point.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*FALLTHRU*/
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Routine for checking each FCP SCSI LUN device found in device tree.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When the matching port WWN and LUN are found from the accessble ldata list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the FCP SCSI LUN is updated with configured ostate.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Overall algorithm:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Parse the device tree to find configured devices which matches with
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * list argument. If cmd is stat on a specific target device it
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * matches port WWN and continues to further processing. If cmd is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * stat on hba port all the FCP SCSI LUN under the hba are processed.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) snprintf(nodepath, len, "%s%s", DEVICES_DIR, devfsp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Skip node if it is HBA */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!dev_cmp(lap->apidp->xport_phys, nodepath, match_minor)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* If stat'ing a specific device, is this node that device */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* checks port wwn property to find a match */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte di_ret = di_prop_lookup_bytes(DDI_DEV_T_ANY, node,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * port wwn doesn't match contine to walk
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if match call do_stat_FCP_dev.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If stat'ing a xport only, we look at device nodes only to get
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * xport configuration status. So a limited stat will suffice.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Ignore errors if stat'ing a bus or listing all
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = do_stat_FCP_dev(node, nodepath, lap, limited_stat);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Are we done ? */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*FALLTHRU*/
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedo_stat_fca_xport(fpcfga_list_t *lap, int limited_stat,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Get xport state */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte walkarg.walkmode.node_args.fcn = get_xport_state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = walk_tree(lap->apidp->xport_phys, &devinfo_state,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DINFOCPYALL | DINFOPATH, &walkarg, FPCFGA_WALK_NODE, &l_errno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lap->xport_rstate = xport_devinfo_to_recep_state(devinfo_state);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Get topology works okay even if the fp port is connected
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to a switch and no devices connected to the switch.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * In this case the list will only shows fp port info without
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * any device listed.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * HBA_PORTTYPE_UNKNOWN means nothing is connected
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* NOT_PRESENT, OTHER, FPORT, FLPORT */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* We only want to know bus(receptacle) connect status */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) snprintf(clp->ap_log_id, sizeof (clp->ap_log_id), "%s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) snprintf(clp->ap_phys_id, sizeof (clp->ap_phys_id), "%s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clp->ap_class[0] = '\0'; /* Filled by libcfgadm */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strncpy(clp->ap_type, lap->xport_type, sizeof (clp->ap_type));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Link it in. lap->listp is NULL originally. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* lap->listp now gets cfga_list_data for the fca port. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Routine for updating ldata list based on the state of device node.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When no matching accessible ldata is found a new ldata is created
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * with proper state information.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Overall algorithm:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the device node is online and the matching ldata is found
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the target device is updated with configued and unknown condition.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the device node is offline or down and the matching ldata is found
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the target device is updated with configued and unusable condition.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the device node is online but the matching ldata is not found
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the target device is created with configued and failing condition.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the device node is offline or down and the matching ldata is not found
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the target device is created with configued and unusable condition.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ostate = dev_devinfo_to_occupant_state(devinfo_state);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * NOTE: The framework cannot currently detect layered driver
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * opens, so the busy indicator is not very reliable. Also,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * non-root users will not be able to determine busy
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * status (libdevice needs root permissions).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This should probably be fixed by adding a DI_BUSY to the di_state()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * routine in libdevinfo.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (devctl_cmd(nodepath, FPCFGA_DEV_GETSTATE, &dctl_state,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte busy = ((dctl_state & DEVICE_BUSY) == DEVICE_BUSY) ? 1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* We only want to know device config state */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (((strcmp(lap->xport_type, FP_FC_FABRIC_PORT_TYPE) == 0) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strcmp(lap->xport_type, FP_FC_PUBLIC_PORT_TYPE) == 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If child device is configured, see if it is accessible also
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for FPCFGA_STAT_FC_DEV cmd.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if configured and not accessble, the device is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * till be displayed with failing condition.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * return code should be FPCFGA_OK to display it.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If not unconfigured and not attached
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the state is set to CFGA_STAT_NONE currently.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is okay for the detached node due to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the driver being unloaded.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * May need to define another state to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * isolate the detached only state.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * handle the same way as configured.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if unconfigured - offline or down,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * set to cond to unusable regardless of accessibility.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This behavior needs to be examined further.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When the device is not accessible the node
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * may get offline or down. In that case failing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * cond may make more sense.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * In anycase the ostate will be set to configured
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * configured.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For fabric port the fca port is considered as
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * configured since user configured previously
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for any existing node. Otherwise when the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * device was accessible, the hba is considered as
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * configured.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* if device found in disco ports, ldata already created. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if cond is not changed then don't update
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * condition to keep the previous condition.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lap->listp->ldata.ap_o_state = CFGA_STAT_CONFIGURED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if cmd is stat all check ldata list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to see if the node exist on the dev list. Otherwise create
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the list element.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = is_dyn_ap_on_ldata_list(dyncomp, lap->listp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* node exists so set ostate to configured. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If not unconfigured and not attached
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the state is set to CFGA_STAT_NONE currently.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is okay for the detached node due to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the driver being unloaded.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * May need to define another state to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * isolate the detached only state.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* update ap_type and ap_info */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * node is offline or down.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * set cond to unusable.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if cond is not unknown
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we already set the cond from
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a different node with the same
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * port WWN or initial probing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * was failed so don't update again.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* node found in ldata list so just return. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* node is attached but not in dev list */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * node is offline or down.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * set cond to unusable.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For fabric port the fca port is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * considered as configured since user
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * configured previously for any
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * existing node.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * continue to create ldata_list struct for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dev_list is null so there is no accessible dev.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * set the cond and continue to create ldata.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * node is offline or down.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * set cond to unusable.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For fabric port the fca port is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * considered as configured since user
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * configured previously for any
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * existing node.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Create the dynamic component. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = make_dyncomp_from_dinode(node, &dyncomp, &l_errno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Create logical and physical ap_id */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) snprintf(clp->ap_log_id, sizeof (clp->ap_log_id), "%s%s%s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) snprintf(clp->ap_phys_id, sizeof (clp->ap_phys_id), "%s%s%s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clp->ap_class[0] = '\0'; /* Filled in by libcfgadm */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* set to ostate to configured and set cond with info. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* get ap_type and ap_info. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Link it in */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Wrapper routine for handling path info.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When show_FCP_dev option is given stat_path_info_FCP_dev() is called.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Otherwise stat_path_info_fc_dev() is called.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((lap->apidp->flags & (FLAG_FCP_DEV)) == FLAG_FCP_DEV) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (stat_path_info_FCP_dev(root, lap, l_errnop));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (stat_path_info_fc_dev(root, lap, l_errnop));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Routine for updating ldata list based on the state of path info node.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When no matching accessible ldata is found a new ldata is created
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * with proper state information.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Overall algorithm:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the path info node is not offline and the matching ldata is found
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the target device is updated with configued and unknown condition.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the path info node is offline or failed and the matching ldata is found
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the target device is updated with configued and unusable condition.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the path info node is online but the matching ldata is not found
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the target device is created with configued and failing condition.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the path info is offline or failed and the matching ldata is not found
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the target device is created with configued and unusable condition.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if stat on a specific dev and walk_node found it okay
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * then just return ok.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((lap->cmd == FPCFGA_STAT_FC_DEV) && (lap->ret == FPCFGA_OK)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if stat on a fca xport and chld_config is set
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * then just return ok.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * when there is no path_info node return FPCFGA_OK.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * That way the result from walk_node shall be maintained.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((path = di_path_next_client(root, path)) == DI_PATH_NIL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if the dev was in dev list but not found
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * return OK to indicate is not configured.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* if stat on fca port return. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (((strcmp(lap->xport_type, FP_FC_FABRIC_PORT_TYPE) == 0) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strcmp(lap->xport_type, FP_FC_PUBLIC_PORT_TYPE) == 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * now parse the path info node.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte count = di_path_prop_lookup_bytes(path, PORT_WWN_PROP,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* if no match contine to the next path info node. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* if device in dev_list, ldata already created. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* check if there is list data. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Update the condition as unusable
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if the pathinfo state is failed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or offline.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * now create ldata for this particular path info node.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if port top is private loop and pathinfo is in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in offline state don't include to ldata list.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (di_path_state(path) != DI_PATH_STATE_OFFLINE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Routine for updating ldata list based on the state of path info node.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When no matching accessible ldata is found a new ldata is created
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * with proper state information.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The difference from stat_path_info_fc_dev() is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to handle FCP SCSI LUN information. Otherwise overall algorithm is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Overall algorithm:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the path info node is not offline and the matching ldata is found
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the target device is updated with configued and unknown condition.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the path info node is offline or failed and the matching ldata is found
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the target device is updated with configued and unusable condition.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the path info node is online but the matching ldata is not found
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the target device is created with configued and failing condition.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the path info is offline or failed and the matching ldata is not found
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the target device is created with configued and unusable condition.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if stat on a fca xport and chld_config is set
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * then just return ok.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * when there is no path_info node return FPCFGA_OK.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * That way the result from walk_node shall be maintained.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((path = di_path_next_client(root, path)) == DI_PATH_NIL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if the dev was in dev list but not found
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * return ok.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If stat on fca port and port topology is fabric return here.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If not fabric return only when path state is not offfline.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The other cases are handbled below.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (((strcmp(lap->xport_type, FP_FC_FABRIC_PORT_TYPE) == 0) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strcmp(lap->xport_type, FP_FC_PUBLIC_PORT_TYPE) == 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * now parse the path info node.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((make_portwwn_luncomp_from_pinode(path, &port_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ldata_ret = is_FCP_dev_ap_on_ldata_list(port_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Update the condition as unusable
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if the pathinfo state is failed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or offline.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (strncmp(port_wwn, lap->apidp->dyncomp, WWN_SIZE*2)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * now create ldata for this particular path info node.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if port top is private loop and pathinfo is in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in offline state don't include to ldata list.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* create ldata for this pi node. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Create logical and physical ap_id */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We reached here since FCP dev is not found
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in ldata list but path info node exists.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Update the condition as failing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if the pathinfo state was normal.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Update the condition as unusable
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if the pathinfo state is failed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or offline.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clp->ap_class[0] = '\0'; /* Filled by libcfgadm */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* update ap_type and ap_info */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((make_portwwn_luncomp_from_pinode(path, &port_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ldata_ret = is_FCP_dev_ap_on_ldata_list(port_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Update the condition as unusable
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if the pathinfo state is failed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or offline.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * now create ldata for this particular path info node.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if port top is private loop and pathinfo is in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in offline state don't include to ldata list.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* create ldata for this pi node. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Create logical and physical ap_id */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We reached here since FCP dev is not found
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in ldata list but path info node exists.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Update the condition as failing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if the pathinfo state was normal.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Update the condition as unusable
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if the pathinfo state is failed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or offline.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clp->ap_class[0] = '\0'; /* Filled by libcfgadm */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* update ap_type and ap_info */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (di_path_state(path) != DI_PATH_STATE_OFFLINE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Routine for updating ldata list based on the state of device node.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When no matching accessible ldata is found a new ldata is created
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * with proper state information.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The difference from do_stat_fc_dev() is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to handle FCP SCSI LUN information. Otherwise overall algorithm is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Overall algorithm:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the device node is online and the matching ldata is found
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the target device is updated with configued and unknown condition.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the device node is offline or down and the matching ldata is found
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the target device is updated with configued and unusable condition.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the device node is online but the matching ldata is not found
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the target device is created with configued and failing condition.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the device node is offline or down and the matching ldata is not found
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the target device is created with configued and unusable condition.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ostate = dev_devinfo_to_occupant_state(devinfo_state);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * NOTE: The devctl framework cannot currently detect layered driver
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * opens, so the busy indicator is not very reliable. Also,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * non-root users will not be able to determine busy
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * status (libdevice needs root permissions).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This should probably be fixed by adding a DI_BUSY to the di_state()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * routine in libdevinfo.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (devctl_cmd(nodepath, FPCFGA_DEV_GETSTATE, &dctl_state,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte busy = ((dctl_state & DEVICE_BUSY) == DEVICE_BUSY) ? 1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* We only want to know device config state */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (((strcmp(lap->xport_type, FP_FC_FABRIC_PORT_TYPE) == 0) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strcmp(lap->xport_type, FP_FC_PUBLIC_PORT_TYPE) == 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If child device is configured, see if it is accessible also
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for FPCFGA_STAT_FC_DEV cmd.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((make_portwwn_luncomp_from_dinode(node, &port_wwn, &lun_nump,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ldata_ret = is_FCP_dev_ap_on_ldata_list(port_wwn, *lun_nump,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if configured and not accessble, the device is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * till be displayed with failing condition.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * return code should be FPCFGA_OK to display it.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If not unconfigured and not attached
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the state is set to CFGA_STAT_NONE currently.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is okay for the detached node due to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the driver being unloaded.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * May need to define another state to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * isolate the detached only state.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * handle the same way as configured.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if unconfigured - offline or down,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * set to cond to unusable regardless of accessibility.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This behavior needs to be examined further.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When the device is not accessible the node
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * may get offline or down. In that case failing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * cond may make more sense.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * In anycase the ostate will be set to configured
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * configured.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For fabric port the fca port is considered as
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * configured since user configured previously
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for any existing node. Otherwise when the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * device was accessible, the hba is considered as
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * configured.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if lap->ret is okay there is at least
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * one matching ldata exist. Need to keep
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * okay ret to display the matching ones.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* if device found in dev_list, ldata already created. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if cond is not changed then don't update
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * condition to keep any condtion
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * from initial discovery. If the initial
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * cond was failed the same condition will be kept.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte matchldp->ldata.ap_o_state = CFGA_STAT_CONFIGURED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* update ap_info via inquiry */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* update ap_type and ap_info */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if cmd is stat all check ldata list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to see if the node exist on the dev list. Otherwise create
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the list element.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* node exists so set ostate to configured. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If not unconfigured and not attached
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the state is set to CFGA_STAT_NONE currently.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is okay for the detached node due to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the driver being unloaded.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * May need to define another state to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * isolate the detached only state.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* update ap_type and ap_info */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * node is offline or down.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * set cond to unusable.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if cond is not unknown
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * initial probing was failed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * so don't update again.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* node found in ldata list so just return. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* node is attached but not in dev list */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * node is offline or down.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * set cond to unusable.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For fabric port the fca port is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * considered as configured since user
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * configured previously for any
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * existing node.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * continue to create ldata_list struct for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Create logical and physical ap_id */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) snprintf(clp->ap_log_id, sizeof (clp->ap_log_id),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "%s%s%s%s%d", lap->xport_logp, DYN_SEP, port_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) snprintf(clp->ap_phys_id, sizeof (clp->ap_phys_id),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "%s%s%s%s%d", lap->apidp->xport_phys, DYN_SEP, port_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clp->ap_class[0] = '\0'; /* Filled in by libcfgadm */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) insert_ldata_to_ldatalist(port_wwn, lun_nump, listp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Searches the ldata_list to find if the the input port_wwn exist.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input: port_wwn, ldata_list.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Return value: FPCFGA_APID_NOACCESS if not found on ldata_list.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FPCFGA_ACCESS_OK if found on ldata_list.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteis_dyn_ap_on_ldata_list(const char *port_wwn, const ldata_list_t *listp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((dyn = GET_DYN(tmplp->ldata.ap_phys_id)) != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Searches the ldata_list to find if the the input port_wwn and lun exist.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input: port_wwn, ldata_list.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Return value: FPCFGA_APID_NOACCESS if not found on ldata_list.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FPCFGA_ACCESS_OK if found on ldata_list.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteis_FCP_dev_ap_on_ldata_list(const char *port_wwn, const int lun_num,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if there is no list data just return the FCP dev list.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Normally this should not occur since list data should
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * be created through discoveredPort list.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* else continue */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* we have match without lun comp. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* else continue */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* we have match without lun comp. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This routine is called when a pathinfo without matching pwwn in dev_list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteinit_ldata_for_mpath_dev(di_path_t path, char *pwwn, int *l_errnop,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* get the client node path */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((client_path = di_devfs_path(client_node)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte devlen = strlen(DEVICES_DIR) + strlen(client_path) + 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) snprintf(devpath, devlen, "%s%s", DEVICES_DIR, client_path);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* now need to create ldata for this dev */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Create logical and physical ap_id */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) snprintf(clp->ap_log_id, sizeof (clp->ap_log_id), "%s%s%s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) snprintf(clp->ap_phys_id, sizeof (clp->ap_phys_id), "%s%s%s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Filled in by libcfgadm */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clp->ap_class[0] = '\0'; /* Filled by libcfgadm */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* set to ostate to configured. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This routine is called when a port WWN is not found in dev list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * but path info node exists.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Update the condition as failing if the pathinfo state was normal.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Update the condition as unusable if the pathinfo state is failed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or offline.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (((pstate = di_path_state(path)) == DI_PATH_STATE_OFFLINE) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* update ap_type and ap_info */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte busy = ((dctl_state & DEVICE_BUSY) == DEVICE_BUSY) ? 1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Link it in */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* now return with ok status with ldata. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Initialize the cfga_list_data struct for an accessible device
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * from g_get_dev_list().
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input: fca port ldata.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Output: device cfga_list_data.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteinit_ldata_for_accessible_dev(const char *dyncomp, uchar_t inq_type,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Create logical and physical ap_id */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) snprintf(clp->ap_log_id, sizeof (clp->ap_log_id), "%s%s%s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) snprintf(clp->ap_phys_id, sizeof (clp->ap_phys_id), "%s%s%s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clp->ap_class[0] = '\0'; /* Filled in by libcfgadm */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < N_DEVICE_TYPES; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) snprintf(clp->ap_type, sizeof (clp->ap_type),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte snprintf(clp->ap_type, sizeof (clp->ap_type), "%s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) snprintf(clp->ap_type, sizeof (clp->ap_type),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Link it in */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) insert_ldata_to_ldatalist(dyncomp, NULL, listp, &(lap->listp));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Initialize the cfga_list_data struct for an accessible FCP SCSI LUN device
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * from the report lun data.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input: fca port ldata. report lun info
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Output: device cfga_list_data.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ldata_list_t *listp = NULL, *listp_start = NULL, *listp_end = NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *prevlp = NULL, *curlp = NULL, *matchp_start = NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* when number of lun is 0 it is not an error. so just return ok. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < num_luns; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lun_string = (uchar_t *)&(resp_buf->lun_string[i]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte memcpy(lun_num_raw, lun_string, sizeof (lun_num_raw));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret = get_standard_inq_data(lap->apidp->xport_phys, port_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (char *)GET_MSG_STR(ERR_UNAVAILABLE), CFGA_TYPE_LEN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte peri_qual = inq_buf->inq_dtype & FP_PERI_QUAL_MASK;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * peripheral qualifier is not 0 so the device node should not
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * included in the ldata list. There should not be a device
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * node for the lun either.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (j = 0; j < N_DEVICE_TYPES; j++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strlcpy(dtype, (char *)device_list[j].name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Followed FCP driver for getting lun number from report
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * According to SAM-2 there are multiple address method for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FCP SCIS LUN. Logincal unit addressing, peripheral device
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * addressing, flat space addressing, and extended logical
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * unit addressing.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * as of 11/2001 FCP supports logical unit addressing and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * peripheral device addressing even thoough 3 defined.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * SSFCP_LUN_ADDRESSING 0x80
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * SSFCP_PD_ADDRESSING 0x00
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * SSFCP_VOLUME_ADDRESSING 0x40
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the menthod below is used by FCP when (lun_string[0] & 0xC0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is either SSFCP_LUN_ADDRESSING or SSFCP_PD_ADDRESSING mode.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lun_num = ((lun_string[0] & 0x3F) << 8) | lun_string[1];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Create logical and physical ap_id */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) snprintf(clp->ap_log_id, sizeof (clp->ap_log_id),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "%s%s%s%s%d", lap->xport_logp, DYN_SEP, port_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) snprintf(clp->ap_phys_id, sizeof (clp->ap_phys_id),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "%s%s%s%s%d", lap->apidp->xport_phys, DYN_SEP, port_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strncpy(clp->ap_type, dtype, strlen(dtype));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clp->ap_class[0] = '\0'; /* Filled in by libcfgadm */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * list data can be null when device peripheral qualifier is not 0
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for any luns. Return ok to continue.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * get the end of list for later uses.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if there is no list data just return the FCP dev list.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Normally this should not occur since list data should
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * be created through g_get_dev_list().
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (listp = listp_start; listp != NULL; listp = listp->next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((dyn != NULL) && ((dyncomp = DYN_TO_DYNCOMP(dyn)) != NULL)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((str_ret = strncmp(dyncomp, port_wwn, WWN_SIZE*2)) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* fillup inqdtype */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* link the new elem of lap->listp. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* free the one matching wwn. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* link lap->listp to listp_start. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (str_ret > 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* link the next elem to listp_end. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* link prevlp to listp_start to drop curlp. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* free matching pwwn elem. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (str_ret > 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Dev not found from accessible
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc dev list but the node should
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * exist. Set to failing cond now
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and check the node state later.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* keep the cur elem by linking to list_end. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (listp = listp_start; listp != NULL; listp = listp->next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* fill in device type, vid, pid from properties */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteget_hw_info(di_node_t node, cfga_list_data_t *clp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if the type is not previously assigned with valid SCSI device type
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * check devinfo to find the type.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * once device is configured it should have a valid device type.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * device node is configured but no valid device type is found
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the type will be set to unavailable.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if the type is not one of defined SCSI device type
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * check devinfo to find the type.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Note: unknown type is not a valid device type.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * It is added in to the device list table to provide
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * constant string of "unknown".
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (strncmp((char *)clp->ap_type, (char *)device_list[i].name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) snprintf(clp->ap_type, sizeof (clp->ap_type), "%s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) snprintf(clp->ap_type, sizeof (clp->ap_type), "%s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Fill in vendor and product ID.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) snprintf(clp->ap_info, sizeof (clp->ap_info),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Get dtype from "inquiry-device-type" property. If not present,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * derive it from minor node type
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic const char *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* first, derive type based on inquiry property */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "inquiry-device-type",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < N_DEVICE_TYPES; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * when found to be unknown type, set name to null to check
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * device minor node type.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* if property fails, use minor nodetype */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte di_minor_t minor = di_minor_next(node, DI_MINOR_NIL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((nodetype = di_minor_nodetype(minor)) != NULL)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < N_DEVICE_TYPES; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* Transform list data to stat data */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ldatap = calloc(nelem, sizeof (cfga_list_data_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Extract the list_data structures from the linked list */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Convert bus state to receptacle state
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortexport_devinfo_to_recep_state(uint_t xport_di_state)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * NOTE: An explicit flag for active should probably be added to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * libdevinfo.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Convert device state to occupant state
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if driver is attached the node is configured.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if offline or down the node is unconfigured.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if only driver detached it is none state which is treated the same
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * way as configured state.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedev_devinfo_to_occupant_state(uint_t dev_di_state)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Driver attached ? */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((dev_di_state & DI_DRIVER_DETACHED) != DI_DRIVER_DETACHED) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((dev_di_state & DI_DEVICE_OFFLINE) == DI_DEVICE_OFFLINE ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (dev_di_state & DI_DEVICE_DOWN) == DI_DEVICE_DOWN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Wrapper routine for inserting ldata to make an sorted ldata list.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When show_FCP_dev option is given insert_FCP_dev_ldata() is called.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Otherwise insert_fc_dev_ldata() is called.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (insert_fc_dev_ldata(port_wwn, listp, ldatapp));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (insert_FCP_dev_ldata(port_wwn, *lun_nump, listp, ldatapp));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Insert an input ldata to ldata list to make sorted ldata list.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* else continue */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* add the ldata to the end of the list. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Insert an input ldata to ldata list to make sorted ldata list.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* else continue */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* else continue */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* add the ldata to the end of the list. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function will return the dtype for the given device
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * It will first issue a report lun to lun 0 and then it will issue a SCSI
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Inquiry to the first lun returned by report luns.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If everything is successful, the dtype will be returned with the peri
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * qualifier masked out.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If either the report lun or the scsi inquiry fails, we will first check
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the return status. If the return status is SCSI_DEVICE_NOT_TGT, then
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we will assume this is a remote HBA and return an UNKNOWN DTYPE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for all other failures, we will return a dtype of ERR_INQ_DTYPE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteget_inq_dtype(char *xport_phys, char *dyncomp, HBA_HANDLE handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte HBA_PORTATTRIBUTES *portAttrs, HBA_PORTATTRIBUTES *discPortAttrs) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret = get_report_lun_data(xport_phys, dyncomp,
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 /* send the inquiry to the first lun */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lun_string = (uchar_t *)&(resp_buf->lun_string[0]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte portAttrs->PortWWN, discPortAttrs->PortWWN, lun, 0, 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &inq, &inquirySize, &scsiStatus, &sense, &senseSize);