FCHBAPort.cc revision c465437abaf8cc10b6cafec2fc1576bc770537ba
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * CDDL HEADER START
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 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * See the License for the specific language governing permissions
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * and limitations under the License.
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 * CDDL HEADER END
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Use is subject to license terms.
3db86aab554edbb4244c8d1a1c90f152eee768afstevelusing namespace std;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelconst string FCHBAPort::FCSM_DRIVER_PATH = "/devices/pseudo/fcsm@0:fcsm";
3db86aab554edbb4244c8d1a1c90f152eee768afstevelconst string FCHBAPort::FCP_DRIVER_PATH = "/devices/pseudo/fcp@0:fcp";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Interpret the error code in the fcio_t structure
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * message must be at least MAX_FCIO_MSG_LEN in length.
3db86aab554edbb4244c8d1a1c90f152eee768afstevelFCHBAPort::transportError(uint32_t fcio_errno, char *message) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "general failure but fail silently";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "invalid packet specified/supplied";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "invalid unsolicited buffer token";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "ULP not registered to handle this FC4 type";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcioErrorString = "transport working on this device";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel snprintf(message, MAX_FCIO_MSG_LEN, "Unknown error code 0x%x",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel snprintf(message, MAX_FCIO_MSG_LEN, "%s", fcioErrorString.c_str());
3db86aab554edbb4244c8d1a1c90f152eee768afstevelreportSense(struct scsi_extended_sense *sense, const char *routine) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.genericIOError("\tASC = 0x%x", sense->es_add_code);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.genericIOError("\tASCQ = 0x%x", sense->es_qual_code);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Issue a SCSI pass thru command.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Returns a scsi status value.
3db86aab554edbb4244c8d1a1c90f152eee768afstevelvoid FCHBAPort::sendSCSIPassThru(struct fcp_scsi_cmd *fscsi,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&wwn, fscsi->scsi_fc_pwwn.raw_wwn, sizeof (la_wwn_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fd = HBA::_open(FCP_DRIVER_PATH, O_RDONLY | O_NDELAY);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* save off errno */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * collect SCSI status first regrardless of the value.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * 0 is a good status so this should be okay
3db86aab554edbb4244c8d1a1c90f152eee768afstevel transportError(fscsi->scsi_fc_status, fcioErrorString);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Did we get a check condition? */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((fscsi->scsi_bufstatus & STATUS_MASK) == STATUS_CHECK) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else if (fscsi->scsi_fc_status == FC_DEVICE_NOT_TGT) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * fcp driver returns FC_DEVICE_NOT_TGT when the node is not
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * scsi-capable like remote hba nodes.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else if (fscsi->scsi_fc_status == FC_INVALID_LUN) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Just in case, check for a check-condition state */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((fscsi->scsi_bufstatus & STATUS_MASK) == STATUS_CHECK) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Record the response data */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Do some quick duration calcuations */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "target %016llx was %.4f seconds", getPath().c_str(),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Did we have any failure */
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 /* We may or may not have sense data */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel reportSense((struct scsi_extended_sense *)fscsi->scsi_rqbufaddr,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * constructs the fcp_scsi_cmd struct for SCSI_Inquiry, SendReadCapacity, or
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * SendReportLUNs
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*#include <fcio.h>
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 log.debug("Initializing HBA port %s", thePath.c_str());
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bool retry = false;
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 // Fetch the minor number for later use
3db86aab554edbb4244c8d1a1c90f152eee768afstevel throw IOError("Unable to stat device path: " + path);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // This routine is not index based, so we can discard stateChange
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 // we should add code here to build NPIVPORT instance
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // Get Port's NPIV port list ( include nwwn and pwwn and path)
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 log.debug("Buffer too small for number of NPIV Port.Retry.");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.debug("Get %d npiv ports", pathList->numAdapters);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // Make instance for each NPIV Port
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } catch (...) {
3db86aab554edbb4244c8d1a1c90f152eee768afsteveluint32_t FCHBAPort::deleteNPIVPort(uint64_t vportwwn) {
3db86aab554edbb4244c8d1a1c90f152eee768afsteveluint32_t FCHBAPort::createNPIVPort(uint64_t vnodewwn, uint64_t vportwwn, uint32_t vindex) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&entrybuf.VNodeWWN, &en_wwn, sizeof (en_wwn));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(&entrybuf.VPortWWN, &en_wwn, sizeof (en_wwn));
3db86aab554edbb4244c8d1a1c90f152eee768afstevelHBA_PORTNPIVATTRIBUTES FCHBAPort::getPortNPIVAttributes(uint64_t &stateChange) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_cmd = FCIO_GET_ADAPTER_PORT_NPIV_ATTRIBUTES;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.MaxNumberOfNPIVPorts = attrs.MaxNumberOfNPIVPorts;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.NumberOfNPIVPorts = attrs.NumberOfNPIVPorts;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelHBA_PORTATTRIBUTES FCHBAPort::getPortAttributes(uint64_t &stateChange) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.PortSupportedClassofService = attrs.PortSupportedClassofService;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.PortSupportedSpeed = attrs.PortSupportedSpeed;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.PortMaxFrameSize = attrs.PortMaxFrameSize;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.NumberofDiscoveredPorts = attrs.NumberofDiscoveredPorts;
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 strncpy((char *)attributes.OSDeviceName, getPath().c_str(), 256);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelHBA_PORTATTRIBUTES FCHBAPort::getDiscoveredAttributes(
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.PortSupportedClassofService = attrs.PortSupportedClassofService;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.PortSupportedSpeed = attrs.PortSupportedSpeed;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.PortMaxFrameSize = attrs.PortMaxFrameSize;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.NumberofDiscoveredPorts = attrs.NumberofDiscoveredPorts;
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);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelHBA_PORTATTRIBUTES FCHBAPort::getDiscoveredAttributes(
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.PortSupportedClassofService = attrs.PortSupportedClassofService;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.PortSupportedSpeed = attrs.PortSupportedSpeed;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.PortMaxFrameSize = attrs.PortMaxFrameSize;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attributes.NumberofDiscoveredPorts = attrs.NumberofDiscoveredPorts;
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);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelvoid FCHBAPort::getTargetMappings(PHBA_FCPTARGETMAPPINGV2 userMappings) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bool zeroLength = false;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* It's possible they didn't give any space */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* We have to give the driver at least one space */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fioctl.listlen = ((uint32_t) (sizeof (fc_hba_mapping_entry_t))) *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fd = HBA::_open(FCP_DRIVER_PATH, O_RDONLY | O_NDELAY);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ioctl(fd, FCP_GET_TARGET_MAPPINGS, &fioctl) != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // Quickly iterate through and copy the data over to the client
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (i = 0; i < userMappings->NumberOfEntries && !zeroLength &&
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.internalError("Bad target mapping without path, truncating.");
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 "Unrecognized target driver (%s), using first matching /dev path",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mappings->numLuns, mappings->entries[i].osLUN, mappings->entries[i].samLUN);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // If everything is good, convert paths to sym-links
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (userMappings->NumberOfEntries >= mappings->numLuns) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // User buffer is larger than needed. (All is good)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // User buffer is non zero, but too small. Don't bother with links
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // Zero length buffer, but we've got mappings
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // No mappings, no worries
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // Get the RNID information from the first port
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 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),
3db86aab554edbb4244c8d1a1c90f152eee768afstevelvoid FCHBAPort::sendCTPassThru(void *requestBuffer, HBA_UINT32 requestSize,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // Validate the arguments
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // construct fcio struct
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // Do some calculations on the duration of the ioctl.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "Total CTPASS ioctl call for HBA %s was %.4f seconds",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // Validate the arguments
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // check to see if we are sending RLS to the HBA
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_obuf = (char *)new uchar_t[*pRspBufferSize];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // Validate the arguments
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(fscsi.scsi_fc_pwwn.raw_wwn, &targetWwn, sizeof (la_wwn_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel scsi_cmd_init(&fscsi, getPath().c_str(), &scsi_rl_req,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sendSCSIPassThru(&fscsi, responseSize, senseSize, scsiStatus);
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
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 // Validate the arguments
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(fscsi.scsi_fc_pwwn.raw_wwn, &targetWwn, sizeof (la_wwn_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel scsi_cmd_init(&fscsi, getPath().c_str(), &scsi_inq_req,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (scsi_inq_req), responseBuffer, *responseSize,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sendSCSIPassThru(&fscsi, responseSize, senseSize, scsiStatus);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // Validate the arguments
3db86aab554edbb4244c8d1a1c90f152eee768afstevel scsi_cmd_init(&fscsi, getPath().c_str(), &scsi_rc_req,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memcpy(fscsi.scsi_fc_pwwn.raw_wwn, &targetWwn, sizeof (la_wwn_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sendSCSIPassThru(&fscsi, responseSize, senseSize, scsiStatus);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelvoid FCHBAPort::sendRNID(uint64_t destwwn, HBA_UINT32 destfcid,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // Validate the arguments
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // NodeIdDataFormat must be within the range of 0x00 and 0xff
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "NodeIdDataFormat must be within the range of 0x00 "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "and 0xFF");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HBA_PORTATTRIBUTES attrs = getDiscoveredAttributes(destwwn,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } catch (HBAException &e) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Send RNID if destination port not
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * present in the discovered ports table
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // Can we log something so we can figure out why?
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fcio.fcio_obuf = (char *)new uchar_t[*RspBufferSize];
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 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 fp_ioctl(getPath(), FCIO_CMD, &fcio, O_NDELAY | O_RDONLY | O_EXCL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelvoid FCHBAPort::fp_ioctl(string path, int cmd, fcio_t *fcio, int openflag) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } catch (...) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel log.genericIOError("ioctl (0x%x) failed. Transport: \"%s\"", cmd,
3db86aab554edbb4244c8d1a1c90f152eee768afstevelvoid FCHBAPort::fp_ioctl(string path, int cmd, fcio_t *fcio) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel // We use the same error handling as fp, so just re-use