FCHBAPort.cc revision c465437abaf8cc10b6cafec2fc1576bc770537ba
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * CDDL HEADER START
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * The contents of this file are subject to the terms of the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Common Development and Distribution License (the "License").
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * You may not use this file except in compliance with the License.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * or http://www.opensolaris.org/os/licensing.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * See the License for the specific language governing permissions
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * and limitations under the License.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * When distributing Covered Code, include this CDDL HEADER in each
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * If applicable, add the following below this CDDL HEADER, with the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * fields enclosed by brackets "[]" replaced with your own identifying
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * information: Portions Copyright [yyyy] [name of copyright owner]
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * CDDL HEADER END
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Use is subject to license terms.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <FCHBAPort.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <Exceptions.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <Trace.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sun_fc.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <iostream>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <iomanip>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/types.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/mkdev.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/stat.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <fcntl.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <unistd.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <stropts.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <dirent.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/fibre-channel/fc.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/fibre-channel/fcio.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/fibre-channel/ulp/fcp_util.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/fibre-channel/ulp/fcsm.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/fibre-channel/impl/fc_error.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/fibre-channel/fc_appif.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/scsi/generic/commands.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/scsi/impl/commands.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/scsi/impl/sense.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/scsi/generic/inquiry.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/scsi/generic/status.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <errno.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <FCHBANPIVPort.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelusing namespace std;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelconst int FCHBAPort::MAX_FCIO_MSG_LEN = 256;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelconst string FCHBAPort::FCSM_DRIVER_PATH = "/devices/pseudo/fcsm@0:fcsm";
3db86aab554edbb4244c8d1a1c90f152eee768afstevelconst string FCHBAPort::FCP_DRIVER_PATH = "/devices/pseudo/fcp@0:fcp";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Interpret the error code in the fcio_t structure
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * message must be at least MAX_FCIO_MSG_LEN in length.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelvoid
3db86aab554edbb4244c8d1a1c90f152eee768afstevelFCHBAPort::transportError(uint32_t fcio_errno, char *message) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel Trace log("transportError");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel string fcioErrorString;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (message == NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.internalError("NULL routine argument");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (fcio_errno) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case (uint32_t)FC_FAILURE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "general failure";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case (uint32_t)FC_FAILURE_SILENT:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "general failure but fail silently";
0d282d1376eb7ba06504448622a6d65726e4bd3erw break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_SUCCESS:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "successful completion";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_CAP_ERROR:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "FCA capability error";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_CAP_FOUND:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "FCA capability unsettable";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_CAP_SETTABLE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "FCA capability settable";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_UNBOUND:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "unbound stuff";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_NOMEM:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "allocation error";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_BADPACKET:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "invalid packet specified/supplied";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_OFFLINE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "I/O resource unavailable";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_OLDPORT:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "operation on non-loop port";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_NO_MAP:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "requested map unavailable";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_TRANSPORT_ERROR:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "unable to transport I/O";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_ELS_FREJECT:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "ELS rejected by a Fabric";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_ELS_PREJECT:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "ELS rejected by an N_port";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_ELS_BAD:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "ELS rejected by FCA/fctl";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_ELS_MALFORMED:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "poorly formed ELS request";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_TOOMANY:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "resource request too large";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_UB_BADTOKEN:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "invalid unsolicited buffer token";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_UB_ERROR:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "invalid unsol buf request";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_UB_BUSY:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "buffer already in use";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_BADULP:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "Unknown ulp";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_BADTYPE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "ULP not registered to handle this FC4 type";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_UNCLAIMED:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "request or data not claimed";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_ULP_SAMEMODULE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "module already in use";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_ULP_SAMETYPE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "FC4 module already in use";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_ABORTED:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "request aborted";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_ABORT_FAILED:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "abort request failed";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_BADEXCHANGE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "exchange doesn�t exist";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_BADWWN:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "WWN not recognized";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_BADDEV:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "device unrecognized";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_BADCMD:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "invalid command issued";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_BADOBJECT:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "invalid object requested";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_BADPORT:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "invalid port specified";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_NOTTHISPORT:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "resource not at this port";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_PREJECT:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "reject at remote N_Port";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_FREJECT:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "reject at remote Fabric";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_PBUSY:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "remote N_Port busy";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_FBUSY:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "remote Fabric busy";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_ALREADY:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "already logged in";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_LOGINREQ:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "login required";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_RESETFAIL:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "reset failed";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_INVALID_REQUEST:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "request is invalid";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_OUTOFBOUNDS:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "port number is out of bounds";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_TRAN_BUSY:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "command transport busy";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_STATEC_BUSY:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "port driver currently busy";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_DEVICE_BUSY:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "transport working on this device";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_DEVICE_NOT_TGT:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "device is not a SCSI target";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel snprintf(message, MAX_FCIO_MSG_LEN, "Unknown error code 0x%x",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio_errno);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel snprintf(message, MAX_FCIO_MSG_LEN, "%s", fcioErrorString.c_str());
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelreportSense(struct scsi_extended_sense *sense, const char *routine) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel Trace log("reportSense");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel string msg;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!sense) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.internalError("NULL sense argument passed.");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!routine) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.internalError("NULL routine argument passed.");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.genericIOError("SCSI FAILURE");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (sense->es_key) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case KEY_NO_SENSE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel msg = "No sense";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case KEY_RECOVERABLE_ERROR:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel msg = "Recoverable error";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case KEY_NOT_READY:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel msg = "Not ready";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case KEY_MEDIUM_ERROR:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel msg = "Medium error";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case KEY_HARDWARE_ERROR:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel msg = "Hardware error";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case KEY_ILLEGAL_REQUEST:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel msg = "Illegal request";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case KEY_UNIT_ATTENTION:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel msg = "Unit attention";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case KEY_DATA_PROTECT:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel msg = "Data protect";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case KEY_BLANK_CHECK:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel msg = "Blank check";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case KEY_VENDOR_UNIQUE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel msg = "Vendor Unique";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case KEY_COPY_ABORTED:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel msg = "Copy aborted";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case KEY_ABORTED_COMMAND:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel msg = "Aborted command";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case KEY_EQUAL:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel msg = "Equal";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case KEY_VOLUME_OVERFLOW:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel msg = "Volume overflow";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case KEY_MISCOMPARE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel msg = "Miscompare";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case KEY_RESERVED:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel msg = "Reserved";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel msg = "unknown sense key";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.genericIOError("\tSense key: %s", msg.c_str());
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.genericIOError("\tASC = 0x%x", sense->es_add_code);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.genericIOError("\tASCQ = 0x%x", sense->es_qual_code);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Issue a SCSI pass thru command.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Returns a scsi status value.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelvoid FCHBAPort::sendSCSIPassThru(struct fcp_scsi_cmd *fscsi,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HBA_UINT32 *responseSize, HBA_UINT32 *senseSize,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HBA_UINT8 *scsiStatus) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel Trace log("FCHBAPort::sendSCSIPassThru");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int fd;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HBA_STATUS ret;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int count;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char fcioErrorString[MAX_FCIO_MSG_LEN] = "";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hrtime_t start;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hrtime_t end;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int ioctl_errno;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel double duration;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel la_wwn_t wwn;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (fscsi == NULL ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel responseSize == NULL ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel senseSize == NULL ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel scsiStatus == NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw BadArgumentException();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&wwn, fscsi->scsi_fc_pwwn.raw_wwn, sizeof (la_wwn_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel start = gethrtime();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fscsi->scsi_fc_port_num = instanceNumber;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fd = HBA::_open(FCP_DRIVER_PATH, O_RDONLY | O_NDELAY);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel count = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ioctl_errno = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ioctl(fd, FCP_TGT_SEND_SCSI, fscsi) != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* save off errno */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ioctl_errno = errno;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel close(fd);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * collect SCSI status first regrardless of the value.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * 0 is a good status so this should be okay
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *scsiStatus = fscsi->scsi_bufstatus & STATUS_MASK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel transportError(fscsi->scsi_fc_status, fcioErrorString);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Did we get a check condition? */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((fscsi->scsi_bufstatus & STATUS_MASK) == STATUS_CHECK) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *senseSize = fscsi->scsi_rqlen;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw CheckConditionException();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else if (fscsi->scsi_fc_status == FC_DEVICE_NOT_TGT) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * fcp driver returns FC_DEVICE_NOT_TGT when the node is not
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * scsi-capable like remote hba nodes.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw NotATargetException();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else if (fscsi->scsi_fc_status == FC_INVALID_LUN) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw InvalidLUNException();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else if (ioctl_errno == EBUSY) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw BusyException();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else if (ioctl_errno == EAGAIN) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw TryAgainException();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else if (ioctl_errno == ENOTSUP) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw NotSupportedException();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else if (ioctl_errno == ENOENT) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw UnavailableException();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw IOError(this, wwnConversion(wwn.raw_wwn),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fscsi->scsi_lun);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel close(fd);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Just in case, check for a check-condition state */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((fscsi->scsi_bufstatus & STATUS_MASK) == STATUS_CHECK) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *scsiStatus = fscsi->scsi_bufstatus & STATUS_MASK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *senseSize = fscsi->scsi_rqlen;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw CheckConditionException();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Record the response data */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *scsiStatus = fscsi->scsi_bufstatus & STATUS_MASK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *responseSize = fscsi->scsi_buflen;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *senseSize = fscsi->scsi_rqlen;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Do some quick duration calcuations */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel end = gethrtime();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel duration = end - start;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel duration /= HR_SECOND;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.debug("Total SCSI IO time for HBA %s "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "target %016llx was %.4f seconds", getPath().c_str(),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel wwnConversion(wwn.raw_wwn), duration);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef DEBUG
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Did we have any failure */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ret != HBA_STATUS_OK) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.genericIOError(
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "Ioctl failed for device \"%s\" target %016llx."
3db86aab554edbb4244c8d1a1c90f152eee768afstevel " Errno: \"%s\"(%d), "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "Transport: \"%s\", SCSI Status: 0x%x"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "responseSize = %d, senseSize = %d",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel getPath().c_str(), wwnConversion(fscsi->scsi_fc_pwwn.raw_wwn),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel strerror(ioctl_errno), ioctl_errno, fcioErrorString,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *scsiStatus, *responseSize, *senseSize);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* We may or may not have sense data */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel reportSense((struct scsi_extended_sense *)fscsi->scsi_rqbufaddr,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ROUTINE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * constructs the fcp_scsi_cmd struct for SCSI_Inquiry, SendReadCapacity, or
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * SendReportLUNs
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*#include <fcio.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <fcp_util.h>*/
3db86aab554edbb4244c8d1a1c90f152eee768afstevelinline void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelscsi_cmd_init(struct fcp_scsi_cmd *fscsi, const char *portname, void *reqbuf,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel size_t req_len, void *responseBuffer, size_t resp_len,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel void *senseBuffer, size_t sense_len) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel Trace log("scsi_cmd_init");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fscsi->scsi_fc_rspcode = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fscsi->scsi_flags = FCP_SCSI_READ;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fscsi->scsi_timeout = 10 /* sec */;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fscsi->scsi_cdbbufaddr = (char *)reqbuf;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fscsi->scsi_cdblen = (uint32_t) req_len;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fscsi->scsi_bufaddr = (char *)responseBuffer;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fscsi->scsi_buflen = (uint32_t) resp_len;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fscsi->scsi_bufresid = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fscsi->scsi_bufstatus = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fscsi->scsi_rqbufaddr = (char *)senseBuffer;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fscsi->scsi_rqlen = (uint32_t) sense_len;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fscsi->scsi_rqresid = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelFCHBAPort::FCHBAPort(string thePath) : HBAPort() {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel Trace log("FCHBAPort::FCHBAPort");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.debug("Initializing HBA port %s", thePath.c_str());
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio_t fcio;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int size = 200;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fc_hba_npiv_port_list_t *pathList;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bool retry = false;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int bufSize;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel try {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel path = lookupControllerPath(thePath);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sscanf(path.c_str(), "/dev/cfg/c%d", &controllerNumber);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } catch (...) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.debug("Unable to lookup controller path and number for %s",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel thePath.c_str());
3db86aab554edbb4244c8d1a1c90f152eee768afstevel path = "/devices";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel path += thePath;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel path += ":fc";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel controllerNumber = -1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // Fetch the minor number for later use
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct stat sbuf;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (stat(path.c_str(), &sbuf) == -1) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw IOError("Unable to stat device path: " + path);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel instanceNumber = minor(sbuf.st_rdev);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // This routine is not index based, so we can discard stateChange
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint64_t tmp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HBA_PORTATTRIBUTES attrs = getPortAttributes(tmp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&tmp, &attrs.PortWWN, 8);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel portWWN = ntohll(tmp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&tmp, &attrs.NodeWWN, 8);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nodeWWN = ntohll(tmp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // For reference, here's how to dump WWN's through C++ streams.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // cout << "\tPort WWN: " << hex << setfill('0') << setw(16) << portWWN
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // << endl;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // cout << "\tNode WWN: " << hex << setfill('0') << setw(16) << nodeWWN
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // << endl;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // we should add code here to build NPIVPORT instance
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // Get Port's NPIV port list ( include nwwn and pwwn and path)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memset((caddr_t)&fcio, 0, sizeof (fcio));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_cmd = FCIO_GET_NPIV_PORT_LIST;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_xfer = FCIO_XFER_READ;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel do {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel retry = false;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bufSize = MAXPATHLEN * (size - 1) + (int) sizeof (fc_hba_npiv_port_list_t);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pathList = (fc_hba_npiv_port_list_t *) new uchar_t[bufSize];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pathList->numAdapters = size;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_olen = bufSize;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_obuf = (char *)pathList;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fp_ioctl(getPath(), FCIO_CMD, &fcio);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pathList->numAdapters > size) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.debug("Buffer too small for number of NPIV Port.Retry.");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel size = pathList->numAdapters;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel retry = true;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel delete (pathList);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } while (retry);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.debug("Get %d npiv ports", pathList->numAdapters);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // Make instance for each NPIV Port
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for ( int i = 0; i < pathList->numAdapters; i++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel try {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel addPort(new FCHBANPIVPort(pathList->hbaPaths[i]));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } catch (...) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.debug("Ignoring partial failure");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel delete (pathList);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afsteveluint32_t FCHBAPort::deleteNPIVPort(uint64_t vportwwn) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel Trace log("FCHBAPort::deleteNPIVPort");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio_t fcio;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel la_wwn_t lawwn[1];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int ret = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memset(&fcio, 0, sizeof(fcio));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint64_t en_wwn = htonll(vportwwn);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&lawwn[0], &en_wwn, sizeof (en_wwn));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_cmd = FCIO_DELETE_NPIV_PORT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_xfer = FCIO_XFER_WRITE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_ilen = sizeof (la_wwn_t) * 2;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_ibuf = (caddr_t)&lawwn;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fp_ioctl(getPath(), FCIO_CMD, &fcio);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (ret);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afsteveluint32_t FCHBAPort::createNPIVPort(uint64_t vnodewwn, uint64_t vportwwn, uint32_t vindex) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel Trace log("FCHBAPort::createNPIVPort");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio_t fcio;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel la_wwn_t lawwn[2];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint32_t vportindex = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HBA_NPIVCREATEENTRY entrybuf;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memset(&fcio, 0, sizeof(fcio));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint64_t en_wwn = htonll(vnodewwn);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&entrybuf.VNodeWWN, &en_wwn, sizeof (en_wwn));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel en_wwn = htonll(vportwwn);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&entrybuf.VPortWWN, &en_wwn, sizeof (en_wwn));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel entrybuf.vindex = vindex;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_cmd = FCIO_CREATE_NPIV_PORT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_xfer = FCIO_XFER_READ;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_olen = sizeof (uint32_t);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_obuf = (caddr_t)&vportindex;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_ilen = sizeof (HBA_NPIVCREATEENTRY);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_ibuf = (caddr_t)&entrybuf;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fp_ioctl(getPath(), FCIO_CMD, &fcio);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (vportindex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelHBA_PORTNPIVATTRIBUTES FCHBAPort::getPortNPIVAttributes(uint64_t &stateChange) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel Trace log("FCHBAPort::getPortNPIVAttributes");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HBA_PORTNPIVATTRIBUTES attributes;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fc_hba_port_npiv_attributes_t attrs;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio_t fcio;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memset(&fcio, 0, sizeof(fcio));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memset(&attributes, 0, sizeof(attributes));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_cmd = FCIO_GET_ADAPTER_PORT_NPIV_ATTRIBUTES;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_olen = sizeof(attrs);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_xfer = FCIO_XFER_READ;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_obuf = (caddr_t)&attrs;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fp_ioctl(getPath(), FCIO_CMD, &fcio);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel stateChange = attrs.lastChange;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.npivflag = attrs.npivflag;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&attributes.PortWWN, &attrs.PortWWN, 8);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.MaxNumberOfNPIVPorts = attrs.MaxNumberOfNPIVPorts;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.NumberOfNPIVPorts = attrs.NumberOfNPIVPorts;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (attributes);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelHBA_PORTATTRIBUTES FCHBAPort::getPortAttributes(uint64_t &stateChange) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel Trace log("FCHBAPort::getPortAttributes");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HBA_PORTATTRIBUTES attributes;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio_t fcio;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fc_hba_port_attributes_t attrs;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memset(&fcio, 0, sizeof (fcio));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memset(&attributes, 0, sizeof (attributes));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_cmd = FCIO_GET_ADAPTER_PORT_ATTRIBUTES;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_olen = sizeof (attrs);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_xfer = FCIO_XFER_READ;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_obuf = (caddr_t)&attrs;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fp_ioctl(getPath(), FCIO_CMD, &fcio);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel stateChange = attrs.lastChange;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.PortFcId = attrs.PortFcId;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.PortType = attrs.PortType;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.PortState = attrs.PortState;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.PortSupportedClassofService = attrs.PortSupportedClassofService;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.PortSupportedSpeed = attrs.PortSupportedSpeed;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.PortSpeed = attrs.PortSpeed;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.PortMaxFrameSize = attrs.PortMaxFrameSize;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.NumberofDiscoveredPorts = attrs.NumberofDiscoveredPorts;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&attributes.PortWWN, &attrs.PortWWN, 8);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&attributes.FabricName, &attrs.FabricName, 8);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&attributes.PortSupportedFc4Types, &attrs.PortSupportedFc4Types, 32);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&attributes.PortActiveFc4Types, &attrs.PortActiveFc4Types, 32);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&attributes.PortSymbolicName, &attrs.PortSymbolicName, 256);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel strncpy((char *)attributes.OSDeviceName, getPath().c_str(), 256);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (attributes);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelHBA_PORTATTRIBUTES FCHBAPort::getDiscoveredAttributes(
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HBA_UINT32 discoveredport, uint64_t &stateChange) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel Trace log("FCHBAPort::getDiscoverdAttributes(i)");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HBA_PORTATTRIBUTES attributes;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio_t fcio;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fc_hba_port_attributes_t attrs;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memset(&fcio, 0, sizeof (fcio));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memset(&attributes, 0, sizeof (attributes));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_cmd = FCIO_GET_DISCOVERED_PORT_ATTRIBUTES;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_olen = sizeof (attrs);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_xfer = FCIO_XFER_READ;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_obuf = (caddr_t)&attrs;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_ilen = sizeof (discoveredport);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_ibuf = (caddr_t)&discoveredport;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fp_ioctl(getPath(), FCIO_CMD, &fcio);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel stateChange = attrs.lastChange;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.PortFcId = attrs.PortFcId;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.PortType = attrs.PortType;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.PortState = attrs.PortState;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.PortSupportedClassofService = attrs.PortSupportedClassofService;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.PortSupportedSpeed = attrs.PortSupportedSpeed;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.PortSpeed = attrs.PortSpeed;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.PortMaxFrameSize = attrs.PortMaxFrameSize;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.NumberofDiscoveredPorts = attrs.NumberofDiscoveredPorts;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&attributes.PortWWN, &attrs.PortWWN, 8);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&attributes.FabricName, &attrs.FabricName, 8);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&attributes.PortSupportedFc4Types, &attrs.PortSupportedFc4Types, 32);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&attributes.PortActiveFc4Types, &attrs.PortActiveFc4Types, 32);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&attributes.PortSymbolicName, &attrs.PortSymbolicName, 256);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (attributes);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelHBA_PORTATTRIBUTES FCHBAPort::getDiscoveredAttributes(
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint64_t wwn, uint64_t &stateChange) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel Trace log("FCHBAPort::getDiscoverdAttributes(p)");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HBA_PORTATTRIBUTES attributes;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio_t fcio;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fc_hba_port_attributes_t attrs;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel la_wwn_t lawwn;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memset(&fcio, 0, sizeof (fcio));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memset(&attributes, 0, sizeof (attributes));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint64_t en_wwn = htonll(wwn);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&lawwn, &en_wwn, sizeof (en_wwn));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_cmd = FCIO_GET_PORT_ATTRIBUTES;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_olen = sizeof (attrs);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_xfer = FCIO_XFER_READ;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_obuf = (caddr_t)&attrs;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_ilen = sizeof (wwn);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_ibuf = (caddr_t)&lawwn;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fp_ioctl(getPath(), FCIO_CMD, &fcio);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel stateChange = attrs.lastChange;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.PortFcId = attrs.PortFcId;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.PortType = attrs.PortType;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.PortState = attrs.PortState;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.PortSupportedClassofService = attrs.PortSupportedClassofService;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.PortSupportedSpeed = attrs.PortSupportedSpeed;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.PortSpeed = attrs.PortSpeed;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.PortMaxFrameSize = attrs.PortMaxFrameSize;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.NumberofDiscoveredPorts = attrs.NumberofDiscoveredPorts;
0d282d1376eb7ba06504448622a6d65726e4bd3erw memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8);
0d282d1376eb7ba06504448622a6d65726e4bd3erw memcpy(&attributes.PortWWN, &attrs.PortWWN, 8);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&attributes.FabricName, &attrs.FabricName, 8);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&attributes.PortSupportedFc4Types, &attrs.PortSupportedFc4Types, 32);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&attributes.PortActiveFc4Types, &attrs.PortActiveFc4Types, 32);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&attributes.PortSymbolicName, &attrs.PortSymbolicName, 256);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (attributes);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelvoid FCHBAPort::getTargetMappings(PHBA_FCPTARGETMAPPINGV2 userMappings) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel Trace log("FCHBAPort::getTargetMappings");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int i, index;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint_t total_entries = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct fcp_ioctl fioctl;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fc_hba_target_mappings_t *mappings;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int fd;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bool zeroLength = false;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (userMappings == NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.userError("Null mapping argument ");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw BadArgumentException();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* It's possible they didn't give any space */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (userMappings->NumberOfEntries == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel zeroLength = true;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel userMappings->NumberOfEntries = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* We have to give the driver at least one space */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mappings = (fc_hba_target_mappings_t *)new uchar_t[
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (sizeof (fc_hba_mapping_entry_t)) *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (userMappings->NumberOfEntries - 1) +
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (fc_hba_target_mappings_t)];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (mappings == NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.noMemory();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw InternalError();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fioctl.fp_minor = instanceNumber;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fioctl.listlen = ((uint32_t) (sizeof (fc_hba_mapping_entry_t))) *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (userMappings->NumberOfEntries - 1) +
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (uint32_t) sizeof (fc_hba_target_mappings_t);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fioctl.list = (caddr_t)mappings;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fd = HBA::_open(FCP_DRIVER_PATH, O_RDONLY | O_NDELAY);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.debug("Performing IOCTL to fetch mappings");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ioctl(fd, FCP_GET_TARGET_MAPPINGS, &fioctl) != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel delete (mappings);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel close(fd);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (errno == EBUSY) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw BusyException();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else if (errno == EAGAIN) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw TryAgainException();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else if (errno == ENOTSUP) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw NotSupportedException();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else if (errno == ENOENT) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw UnavailableException();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw IOError("Unable to fetch target mappings");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel close(fd);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // Quickly iterate through and copy the data over to the client
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (i = 0; i < userMappings->NumberOfEntries && !zeroLength &&
3db86aab554edbb4244c8d1a1c90f152eee768afstevel i < mappings->numLuns; i++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel string raw = mappings->entries[i].targetDriver;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (raw.length() <= 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.internalError("Bad target mapping without path, truncating.");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Ideally, we'd like to ask some standard Solaris interface
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * "What is the prefered minor node for this target?"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * but no such interface exists today. So, for now,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * we just hard-code ":n" for tapes, ":c,raw" for disks,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * and ":0" for enclosures.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Devices with other generic names will be presented through
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * first matching /dev path.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((raw.find("/st@") != raw.npos) ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (raw.find("/tape@") != raw.npos)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel raw += ":n";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else if ((raw.find("/ssd@") != raw.npos) ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (raw.find("/sd@") != raw.npos) ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (raw.find("/disk@") != raw.npos)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel raw += ":c,raw";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else if ((raw.find("/ses@") != raw.npos) ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (raw.find("/enclosure@") != raw.npos)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel raw += ":0";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.debug(
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "Unrecognized target driver (%s), using first matching /dev path",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel raw.c_str());
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel snprintf(userMappings->entry[i].ScsiId.OSDeviceName,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (userMappings->entry[i].ScsiId.OSDeviceName),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "/devices%s", raw.c_str());
3db86aab554edbb4244c8d1a1c90f152eee768afstevel userMappings->entry[i].ScsiId.ScsiBusNumber =
3db86aab554edbb4244c8d1a1c90f152eee768afstevel controllerNumber;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel userMappings->entry[i].ScsiId.ScsiTargetNumber =
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mappings->entries[i].targetNumber;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel userMappings->entry[i].ScsiId.ScsiOSLun =
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mappings->entries[i].osLUN;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel userMappings->entry[i].FcpId.FcId =
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mappings->entries[i].d_id;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(userMappings->entry[i].FcpId.NodeWWN.wwn,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mappings->entries[i].NodeWWN.raw_wwn,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (la_wwn_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(userMappings->entry[i].FcpId.PortWWN.wwn,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mappings->entries[i].PortWWN.raw_wwn,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (la_wwn_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel userMappings->entry[i].FcpId.FcpLun =
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mappings->entries[i].samLUN;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(userMappings->entry[i].LUID.buffer,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mappings->entries[i].guid,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (userMappings->entry[i].LUID.buffer));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.debug("Total mappings: %d %08x %08x",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mappings->numLuns, mappings->entries[i].osLUN, mappings->entries[i].samLUN);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // If everything is good, convert paths to sym-links
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (mappings->numLuns > 0 && !zeroLength) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (userMappings->NumberOfEntries >= mappings->numLuns) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // User buffer is larger than needed. (All is good)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel userMappings->NumberOfEntries = mappings->numLuns;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel convertToShortNames(userMappings);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // User buffer is non zero, but too small. Don't bother with links
3db86aab554edbb4244c8d1a1c90f152eee768afstevel userMappings->NumberOfEntries = mappings->numLuns;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel delete (mappings);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw MoreDataException();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else if (mappings->numLuns > 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // Zero length buffer, but we've got mappings
3db86aab554edbb4244c8d1a1c90f152eee768afstevel userMappings->NumberOfEntries = mappings->numLuns;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel delete (mappings);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw MoreDataException();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // No mappings, no worries
3db86aab554edbb4244c8d1a1c90f152eee768afstevel userMappings->NumberOfEntries = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel delete (mappings);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel delete (mappings);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelvoid FCHBAPort::getRNIDMgmtInfo(PHBA_MGMTINFO info) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel Trace log("FCHBAPort::getRNIDMgmtInfo");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HBA_STATUS status = HBA_STATUS_OK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fc_rnid_t rnid;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio_t fcio;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (info == NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.userError("NULL port management info");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw BadArgumentException();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // Get the RNID information from the first port
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memset(&rnid, 0, sizeof (fc_rnid_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memset((caddr_t)&fcio, 0, sizeof (fcio));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_cmd = FCIO_GET_NODE_ID;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_olen = sizeof (fc_rnid_t);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_xfer = FCIO_XFER_READ;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_obuf = (caddr_t)&rnid;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fp_ioctl(getPath(), FCIO_CMD, &fcio);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // Copy out the struct members of rnid into PHBA_MGMTINFO struct
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&info->wwn, &(rnid.global_id), sizeof (info->wwn));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&info->unittype, &(rnid.unit_type), sizeof (info->unittype));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&info->PortId, &(rnid.port_id), sizeof (info->PortId));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&info->NumberOfAttachedNodes, &(rnid.num_attached),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (info->NumberOfAttachedNodes));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&info->IPVersion, &(rnid.ip_version), sizeof (info->IPVersion));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&info->UDPPort, &(rnid.udp_port), sizeof (info->UDPPort));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&info->IPAddress, &(rnid.ip_addr), sizeof (info->IPAddress));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&info->TopologyDiscoveryFlags, &(rnid.topo_flags),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (info->TopologyDiscoveryFlags));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelvoid FCHBAPort::sendCTPassThru(void *requestBuffer, HBA_UINT32 requestSize,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel void *responseBuffer, HBA_UINT32 *responseSize) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel Trace log("FCHBAPort::sendCTPassThru");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio_t fcio;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct stat sbuf;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel minor_t minor_node;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hrtime_t start, end;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel double duration;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // Validate the arguments
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (requestBuffer == NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.userError("NULL request buffer");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw BadArgumentException();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (responseBuffer == NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.userError("NULL response buffer");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw BadArgumentException();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel minor_node = instanceNumber;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // construct fcio struct
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memset(&fcio, 0, sizeof (fcio_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_cmd = FCSMIO_CT_CMD;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_xfer = FCIO_XFER_RW;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_ilen = requestSize;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_ibuf = (char *)requestBuffer;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_olen = *responseSize;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_obuf = (char *)responseBuffer;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_alen = sizeof (minor_t);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_abuf = (char *)&minor_node;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel start = gethrtime();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcsm_ioctl(FCSMIO_CMD, &fcio);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // Do some calculations on the duration of the ioctl.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel end = gethrtime();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel duration = end - start;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel duration /= HR_SECOND;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.debug(
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "Total CTPASS ioctl call for HBA %s was %.4f seconds",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel getPath().c_str(), duration);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelvoid FCHBAPort::sendRLS(uint64_t destWWN,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel void *pRspBuffer,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HBA_UINT32 *pRspBufferSize) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel Trace log("FCHBAPort::sendRLS");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio_t fcio;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fc_portid_t rls_req;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // Validate the arguments
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pRspBuffer == NULL ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pRspBufferSize == NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.userError("NULL hba");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw BadArgumentException();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // check to see if we are sending RLS to the HBA
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HBA_PORTATTRIBUTES attrs;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint64_t tmp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (getPortWWN() == destWWN) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attrs = getPortAttributes(tmp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attrs = getDiscoveredAttributes(destWWN, tmp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&rls_req, &attrs.PortFcId,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (attrs.PortFcId));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memset((caddr_t)&fcio, 0, sizeof (fcio));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_cmd = FCIO_LINK_STATUS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_ibuf = (caddr_t)&rls_req;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_ilen = sizeof (rls_req);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_xfer = FCIO_XFER_RW;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_flags = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_cmd_flags = FCIO_CFLAGS_RLS_DEST_NPORT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_obuf = (char *)new uchar_t[*pRspBufferSize];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_olen = *pRspBufferSize;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (fcio.fcio_obuf == NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.noMemory();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw InternalError();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fp_ioctl(getPath(), FCIO_CMD, &fcio);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(pRspBuffer, fcio.fcio_obuf, *pRspBufferSize);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (fcio.fcio_obuf != NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel delete(fcio.fcio_obuf);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelvoid FCHBAPort::sendReportLUNs(uint64_t wwn,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel void *responseBuffer, HBA_UINT32 *responseSize,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HBA_UINT8 *scsiStatus,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel void *senseBuffer, HBA_UINT32 *senseSize) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel Trace log("FCHBAPort::sendReportLUNs");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct fcp_scsi_cmd fscsi;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel union scsi_cdb scsi_rl_req;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint64_t targetWwn = htonll(wwn);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // Validate the arguments
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (responseBuffer == NULL ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel senseBuffer == NULL ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel responseSize == NULL ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel senseSize == NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw BadArgumentException();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memset(&fscsi, 0, sizeof (fscsi));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memset(&scsi_rl_req, 0, sizeof (scsi_rl_req));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(fscsi.scsi_fc_pwwn.raw_wwn, &targetWwn, sizeof (la_wwn_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel scsi_cmd_init(&fscsi, getPath().c_str(), &scsi_rl_req,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (scsi_rl_req), responseBuffer, *responseSize,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel senseBuffer, *senseSize);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fscsi.scsi_lun = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel scsi_rl_req.scc_cmd = SCMD_REPORT_LUNS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel FORMG5COUNT(&scsi_rl_req, *responseSize);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sendSCSIPassThru(&fscsi, responseSize, senseSize, scsiStatus);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * arguments:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * wwn - remote target WWN where the SCSI Inquiry shall be sent
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * fcLun - the SCSI LUN to which the SCSI Inquiry shall be sent
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * cdb1 - the second byte of the CDB for the SCSI Inquiry
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * cdb2 - the third byte of teh CDB for the SCSI Inquiry
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * responseBuffer - shall be a pointer to a buffer to receive the SCSI
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Inquiry command response
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * responseSize - a pointer to the size of the buffer to receive
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * the SCSI Inquiry.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * scsiStatus - a pointer to a buffer to receive SCSI status
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * senseBuffer - pointer to a buffer to receive SCSI sense data
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * seneseSize - pointer to the size of the buffer to receive SCSI sense
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * data
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelvoid FCHBAPort::sendScsiInquiry(uint64_t wwn, HBA_UINT64 fcLun,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HBA_UINT8 cdb1, HBA_UINT8 cdb2, void *responseBuffer,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HBA_UINT32 *responseSize, HBA_UINT8 *scsiStatus, void *senseBuffer,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HBA_UINT32 *senseSize) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel Trace log("FCHBAPort::sendScsiInquiry");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct fcp_scsi_cmd fscsi;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel union scsi_cdb scsi_inq_req;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint64_t targetWwn = htonll(wwn);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // Validate the arguments
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (responseBuffer == NULL ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel senseBuffer == NULL ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel responseSize == NULL ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel senseSize == NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw BadArgumentException();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memset(&fscsi, 0, sizeof (fscsi));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memset(&scsi_inq_req, 0, sizeof (scsi_inq_req));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(fscsi.scsi_fc_pwwn.raw_wwn, &targetWwn, sizeof (la_wwn_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel scsi_cmd_init(&fscsi, getPath().c_str(), &scsi_inq_req,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (scsi_inq_req), responseBuffer, *responseSize,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel senseBuffer, *senseSize);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fscsi.scsi_lun = fcLun;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel scsi_inq_req.scc_cmd = SCMD_INQUIRY;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel scsi_inq_req.g0_addr1 = cdb2;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel scsi_inq_req.g0_addr2 = cdb1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel scsi_inq_req.g0_count0 = *responseSize;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sendSCSIPassThru(&fscsi, responseSize, senseSize, scsiStatus);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelvoid FCHBAPort::sendReadCapacity(uint64_t pwwn,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HBA_UINT64 fcLun, void *responseBuffer,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HBA_UINT32 *responseSize, HBA_UINT8 *scsiStatus,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel void *senseBuffer, HBA_UINT32 *senseSize) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel Trace log("FCHBAPort::sendReadCapacity");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct fcp_scsi_cmd fscsi;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel union scsi_cdb scsi_rc_req;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint64_t targetWwn = htonll(pwwn);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // Validate the arguments
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (responseBuffer == NULL ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel senseBuffer == NULL ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel responseSize == NULL ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel senseSize == NULL ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel scsiStatus == NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw BadArgumentException();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memset(&fscsi, 0, sizeof (fscsi));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memset(&scsi_rc_req, 0, sizeof (scsi_rc_req));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel scsi_cmd_init(&fscsi, getPath().c_str(), &scsi_rc_req,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (scsi_rc_req), responseBuffer, *responseSize,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel senseBuffer, *senseSize);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(fscsi.scsi_fc_pwwn.raw_wwn, &targetWwn, sizeof (la_wwn_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fscsi.scsi_lun = fcLun;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel scsi_rc_req.scc_cmd = SCMD_READ_CAPACITY;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel scsi_rc_req.g1_reladdr = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel scsi_rc_req.g1_addr3 = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel scsi_rc_req.g1_count0 = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sendSCSIPassThru(&fscsi, responseSize, senseSize, scsiStatus);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelvoid FCHBAPort::sendRNID(uint64_t destwwn, HBA_UINT32 destfcid,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HBA_UINT32 nodeIdDataFormat, void *pRspBuffer,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HBA_UINT32 *RspBufferSize) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel Trace log("FCHBAPort::sendRNID");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int localportfound, remoteportfound, send;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio_t fcio;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // Validate the arguments
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pRspBuffer == NULL ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel RspBufferSize == NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw BadArgumentException();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // NodeIdDataFormat must be within the range of 0x00 and 0xff
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (nodeIdDataFormat > 0xff) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.userError(
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "NodeIdDataFormat must be within the range of 0x00 "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "and 0xFF");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw BadArgumentException();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel remoteportfound = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (destfcid != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel try {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint64_t tmp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HBA_PORTATTRIBUTES attrs = getDiscoveredAttributes(destwwn,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel tmp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (attrs.PortFcId == destfcid) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel send = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel remoteportfound = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel send = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel remoteportfound = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } catch (HBAException &e) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Send RNID if destination port not
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * present in the discovered ports table
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (remoteportfound == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel send = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel send = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!send) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // Can we log something so we can figure out why?
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw BadArgumentException();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memset((caddr_t)&fcio, 0, sizeof (fcio));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint64_t netdestwwn = htonll(destwwn);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_cmd = FCIO_SEND_NODE_ID;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_xfer = FCIO_XFER_READ;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_cmd_flags = nodeIdDataFormat;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_ilen = sizeof (la_wwn_t);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_ibuf = (caddr_t)&netdestwwn;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_olen = *RspBufferSize;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_obuf = (char *)new uchar_t[*RspBufferSize];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (fcio.fcio_obuf == NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.noMemory();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw InternalError();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fp_ioctl(getPath(), FCIO_CMD, &fcio);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(pRspBuffer, fcio.fcio_obuf, *RspBufferSize);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (fcio.fcio_obuf != NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel delete(fcio.fcio_obuf);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelvoid FCHBAPort::setRNID(HBA_MGMTINFO info) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel Trace log("FCHBAPort::setRNID");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fc_rnid_t rnid;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio_t fcio;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memset(&rnid, 0, sizeof (fc_rnid_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memset((caddr_t)&fcio, 0, sizeof (fcio));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_cmd = FCIO_SET_NODE_ID;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_ilen = sizeof (fc_rnid_t);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_xfer = FCIO_XFER_WRITE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_ibuf = (caddr_t)&rnid;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // Copy the HBA_MGMTINFO into fc_rnid_t struct
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&(rnid.unit_type), &(info.unittype), sizeof (rnid.unit_type));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&(rnid.port_id), &(info.PortId), sizeof (rnid.port_id));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&(rnid.global_id), &(info.wwn), sizeof (info.wwn));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&(rnid.num_attached), &(info.NumberOfAttachedNodes),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (rnid.num_attached));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&(rnid.ip_version), &(info.IPVersion), sizeof (rnid.ip_version));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&(rnid.udp_port), &(info.UDPPort), sizeof (rnid.udp_port));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&(rnid.ip_addr), &info.IPAddress, sizeof (rnid.ip_addr));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&(rnid.topo_flags), &(info.TopologyDiscoveryFlags),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (rnid.topo_flags));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fp_ioctl(getPath(), FCIO_CMD, &fcio, O_NDELAY | O_RDONLY | O_EXCL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelvoid FCHBAPort::fp_ioctl(string path, int cmd, fcio_t *fcio, int openflag) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel Trace log("FCHBAPort::fp_ioctl with openflag");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char fcioErrorString[MAX_FCIO_MSG_LEN] = "";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int fd = HBA::_open(path, openflag);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel try {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int times = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HBA::_ioctl(fd, cmd, (uchar_t *)fcio);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel while (fcio->fcio_errno == FC_STATEC_BUSY) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sleep(1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HBA::_ioctl(fd, cmd, (uchar_t *)fcio);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (times++ > 10) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel close(fd);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (fcio->fcio_errno) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw IOError("IOCTL transport failure");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } catch (...) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel close(fd);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel transportError(fcio->fcio_errno, fcioErrorString);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.genericIOError("ioctl (0x%x) failed. Transport: \"%s\"", cmd,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (fcio->fcio_errno) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_BADWWN:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw IllegalWWNException();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_BADPORT:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw IllegalWWNException();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_OUTOFBOUNDS:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw IllegalIndexException();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_PBUSY:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_FBUSY:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_TRAN_BUSY:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_STATEC_BUSY:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_DEVICE_BUSY:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw BusyException();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FC_SUCCESS:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelvoid FCHBAPort::fp_ioctl(string path, int cmd, fcio_t *fcio) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel Trace log("FCHBAPort::fp_ioctl");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fp_ioctl(path, cmd, fcio, O_NDELAY | O_RDONLY);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelvoid FCHBAPort::fcsm_ioctl(int cmd, fcio_t *fcio) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // We use the same error handling as fp, so just re-use
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fp_ioctl(FCSM_DRIVER_PATH, cmd, fcio);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel