17836SJohn.Forte@Sun.COM /*
27836SJohn.Forte@Sun.COM * CDDL HEADER START
37836SJohn.Forte@Sun.COM *
47836SJohn.Forte@Sun.COM * The contents of this file are subject to the terms of the
57836SJohn.Forte@Sun.COM * Common Development and Distribution License (the "License").
67836SJohn.Forte@Sun.COM * You may not use this file except in compliance with the License.
77836SJohn.Forte@Sun.COM *
87836SJohn.Forte@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97836SJohn.Forte@Sun.COM * or http://www.opensolaris.org/os/licensing.
107836SJohn.Forte@Sun.COM * See the License for the specific language governing permissions
117836SJohn.Forte@Sun.COM * and limitations under the License.
127836SJohn.Forte@Sun.COM *
137836SJohn.Forte@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
147836SJohn.Forte@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157836SJohn.Forte@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
167836SJohn.Forte@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
177836SJohn.Forte@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
187836SJohn.Forte@Sun.COM *
197836SJohn.Forte@Sun.COM * CDDL HEADER END
207836SJohn.Forte@Sun.COM */
217836SJohn.Forte@Sun.COM /*
22*10088SAllan.Ou@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
237836SJohn.Forte@Sun.COM * Use is subject to license terms.
247836SJohn.Forte@Sun.COM */
257836SJohn.Forte@Sun.COM
267836SJohn.Forte@Sun.COM
277836SJohn.Forte@Sun.COM
287836SJohn.Forte@Sun.COM #include <TgtFCHBAPort.h>
297836SJohn.Forte@Sun.COM #include <Exceptions.h>
307836SJohn.Forte@Sun.COM #include <Trace.h>
317836SJohn.Forte@Sun.COM #include <sun_fc.h>
327836SJohn.Forte@Sun.COM #include <iostream>
337836SJohn.Forte@Sun.COM #include <iomanip>
347836SJohn.Forte@Sun.COM #include <sys/types.h>
357836SJohn.Forte@Sun.COM #include <sys/mkdev.h>
367836SJohn.Forte@Sun.COM #include <sys/stat.h>
377836SJohn.Forte@Sun.COM #include <fcntl.h>
387836SJohn.Forte@Sun.COM #include <unistd.h>
397836SJohn.Forte@Sun.COM #include <stropts.h>
407836SJohn.Forte@Sun.COM #include <dirent.h>
417836SJohn.Forte@Sun.COM #include <sys/fibre-channel/fc.h>
427836SJohn.Forte@Sun.COM #include <sys/fctio.h>
437836SJohn.Forte@Sun.COM #include <sys/fibre-channel/impl/fc_error.h>
447836SJohn.Forte@Sun.COM #include <sys/fibre-channel/fc_appif.h>
457836SJohn.Forte@Sun.COM #include <sys/scsi/generic/commands.h>
467836SJohn.Forte@Sun.COM #include <sys/scsi/impl/commands.h>
477836SJohn.Forte@Sun.COM #include <sys/scsi/impl/sense.h>
487836SJohn.Forte@Sun.COM #include <sys/scsi/generic/inquiry.h>
497836SJohn.Forte@Sun.COM #include <sys/scsi/generic/status.h>
507836SJohn.Forte@Sun.COM #include <errno.h>
517836SJohn.Forte@Sun.COM
527836SJohn.Forte@Sun.COM
537836SJohn.Forte@Sun.COM using namespace std;
547836SJohn.Forte@Sun.COM
557836SJohn.Forte@Sun.COM const int TgtFCHBAPort::MAX_FCTIO_MSG_LEN = 256;
567836SJohn.Forte@Sun.COM const string TgtFCHBAPort::FCT_DRIVER_PATH = "/devices/pseudo/fct@0:admin";
577836SJohn.Forte@Sun.COM
587836SJohn.Forte@Sun.COM /*
597836SJohn.Forte@Sun.COM * Interpret the error code in the fctio_t structure
607836SJohn.Forte@Sun.COM *
617836SJohn.Forte@Sun.COM * message must be at least MAX_FCTIO_MSG_LEN in length.
627836SJohn.Forte@Sun.COM */
637836SJohn.Forte@Sun.COM void
transportError(uint32_t fctio_errno,char * message)647836SJohn.Forte@Sun.COM TgtFCHBAPort::transportError(uint32_t fctio_errno, char *message) {
657836SJohn.Forte@Sun.COM Trace log("transportError");
667836SJohn.Forte@Sun.COM string fcioErrorString;
677836SJohn.Forte@Sun.COM if (message == NULL) {
687836SJohn.Forte@Sun.COM log.internalError("NULL routine argument");
697836SJohn.Forte@Sun.COM return;
707836SJohn.Forte@Sun.COM }
717836SJohn.Forte@Sun.COM switch (fctio_errno) {
727836SJohn.Forte@Sun.COM case (uint32_t)FC_FAILURE:
737836SJohn.Forte@Sun.COM fcioErrorString = "general failure";
747836SJohn.Forte@Sun.COM break;
757836SJohn.Forte@Sun.COM case (uint32_t)FC_FAILURE_SILENT:
767836SJohn.Forte@Sun.COM fcioErrorString = "general failure but fail silently";
777836SJohn.Forte@Sun.COM break;
787836SJohn.Forte@Sun.COM case FC_SUCCESS:
797836SJohn.Forte@Sun.COM fcioErrorString = "successful completion";
807836SJohn.Forte@Sun.COM break;
817836SJohn.Forte@Sun.COM case FC_CAP_ERROR:
827836SJohn.Forte@Sun.COM fcioErrorString = "FCA capability error";
837836SJohn.Forte@Sun.COM break;
847836SJohn.Forte@Sun.COM case FC_CAP_FOUND:
857836SJohn.Forte@Sun.COM fcioErrorString = "FCA capability unsettable";
867836SJohn.Forte@Sun.COM break;
877836SJohn.Forte@Sun.COM case FC_CAP_SETTABLE:
887836SJohn.Forte@Sun.COM fcioErrorString = "FCA capability settable";
897836SJohn.Forte@Sun.COM break;
907836SJohn.Forte@Sun.COM case FC_UNBOUND:
917836SJohn.Forte@Sun.COM fcioErrorString = "unbound stuff";
927836SJohn.Forte@Sun.COM break;
937836SJohn.Forte@Sun.COM case FC_NOMEM:
947836SJohn.Forte@Sun.COM fcioErrorString = "allocation error";
957836SJohn.Forte@Sun.COM break;
967836SJohn.Forte@Sun.COM case FC_BADPACKET:
977836SJohn.Forte@Sun.COM fcioErrorString = "invalid packet specified/supplied";
987836SJohn.Forte@Sun.COM break;
997836SJohn.Forte@Sun.COM case FC_OFFLINE:
1007836SJohn.Forte@Sun.COM fcioErrorString = "I/O resource unavailable";
1017836SJohn.Forte@Sun.COM break;
1027836SJohn.Forte@Sun.COM case FC_OLDPORT:
1037836SJohn.Forte@Sun.COM fcioErrorString = "operation on non-loop port";
1047836SJohn.Forte@Sun.COM break;
1057836SJohn.Forte@Sun.COM case FC_NO_MAP:
1067836SJohn.Forte@Sun.COM fcioErrorString = "requested map unavailable";
1077836SJohn.Forte@Sun.COM break;
1087836SJohn.Forte@Sun.COM case FC_TRANSPORT_ERROR:
1097836SJohn.Forte@Sun.COM fcioErrorString = "unable to transport I/O";
1107836SJohn.Forte@Sun.COM break;
1117836SJohn.Forte@Sun.COM case FC_ELS_FREJECT:
1127836SJohn.Forte@Sun.COM fcioErrorString = "ELS rejected by a Fabric";
1137836SJohn.Forte@Sun.COM break;
1147836SJohn.Forte@Sun.COM case FC_ELS_PREJECT:
1157836SJohn.Forte@Sun.COM fcioErrorString = "ELS rejected by an N_port";
1167836SJohn.Forte@Sun.COM break;
1177836SJohn.Forte@Sun.COM case FC_ELS_BAD:
1187836SJohn.Forte@Sun.COM fcioErrorString = "ELS rejected by FCA/fctl";
1197836SJohn.Forte@Sun.COM break;
1207836SJohn.Forte@Sun.COM case FC_ELS_MALFORMED:
1217836SJohn.Forte@Sun.COM fcioErrorString = "poorly formed ELS request";
1227836SJohn.Forte@Sun.COM break;
1237836SJohn.Forte@Sun.COM case FC_TOOMANY:
1247836SJohn.Forte@Sun.COM fcioErrorString = "resource request too large";
1257836SJohn.Forte@Sun.COM break;
1267836SJohn.Forte@Sun.COM case FC_UB_BADTOKEN:
1277836SJohn.Forte@Sun.COM fcioErrorString = "invalid unsolicited buffer token";
1287836SJohn.Forte@Sun.COM break;
1297836SJohn.Forte@Sun.COM case FC_UB_ERROR:
1307836SJohn.Forte@Sun.COM fcioErrorString = "invalid unsol buf request";
1317836SJohn.Forte@Sun.COM break;
1327836SJohn.Forte@Sun.COM case FC_UB_BUSY:
1337836SJohn.Forte@Sun.COM fcioErrorString = "buffer already in use";
1347836SJohn.Forte@Sun.COM break;
1357836SJohn.Forte@Sun.COM case FC_BADULP:
1367836SJohn.Forte@Sun.COM fcioErrorString = "Unknown ulp";
1377836SJohn.Forte@Sun.COM break;
1387836SJohn.Forte@Sun.COM case FC_BADTYPE:
1397836SJohn.Forte@Sun.COM fcioErrorString = "ULP not registered to handle this FC4 type";
1407836SJohn.Forte@Sun.COM break;
1417836SJohn.Forte@Sun.COM case FC_UNCLAIMED:
1427836SJohn.Forte@Sun.COM fcioErrorString = "request or data not claimed";
1437836SJohn.Forte@Sun.COM break;
1447836SJohn.Forte@Sun.COM case FC_ULP_SAMEMODULE:
1457836SJohn.Forte@Sun.COM fcioErrorString = "module already in use";
1467836SJohn.Forte@Sun.COM break;
1477836SJohn.Forte@Sun.COM case FC_ULP_SAMETYPE:
1487836SJohn.Forte@Sun.COM fcioErrorString = "FC4 module already in use";
1497836SJohn.Forte@Sun.COM break;
1507836SJohn.Forte@Sun.COM case FC_ABORTED:
1517836SJohn.Forte@Sun.COM fcioErrorString = "request aborted";
1527836SJohn.Forte@Sun.COM break;
1537836SJohn.Forte@Sun.COM case FC_ABORT_FAILED:
1547836SJohn.Forte@Sun.COM fcioErrorString = "abort request failed";
1557836SJohn.Forte@Sun.COM break;
1567836SJohn.Forte@Sun.COM case FC_BADEXCHANGE:
1577836SJohn.Forte@Sun.COM fcioErrorString = "exchange doesn�t exist";
1587836SJohn.Forte@Sun.COM break;
1597836SJohn.Forte@Sun.COM case FC_BADWWN:
1607836SJohn.Forte@Sun.COM fcioErrorString = "WWN not recognized";
1617836SJohn.Forte@Sun.COM break;
1627836SJohn.Forte@Sun.COM case FC_BADDEV:
1637836SJohn.Forte@Sun.COM fcioErrorString = "device unrecognized";
1647836SJohn.Forte@Sun.COM break;
1657836SJohn.Forte@Sun.COM case FC_BADCMD:
1667836SJohn.Forte@Sun.COM fcioErrorString = "invalid command issued";
1677836SJohn.Forte@Sun.COM break;
1687836SJohn.Forte@Sun.COM case FC_BADOBJECT:
1697836SJohn.Forte@Sun.COM fcioErrorString = "invalid object requested";
1707836SJohn.Forte@Sun.COM break;
1717836SJohn.Forte@Sun.COM case FC_BADPORT:
1727836SJohn.Forte@Sun.COM fcioErrorString = "invalid port specified";
1737836SJohn.Forte@Sun.COM break;
1747836SJohn.Forte@Sun.COM case FC_NOTTHISPORT:
1757836SJohn.Forte@Sun.COM fcioErrorString = "resource not at this port";
1767836SJohn.Forte@Sun.COM break;
1777836SJohn.Forte@Sun.COM case FC_PREJECT:
1787836SJohn.Forte@Sun.COM fcioErrorString = "reject at remote N_Port";
1797836SJohn.Forte@Sun.COM break;
1807836SJohn.Forte@Sun.COM case FC_FREJECT:
1817836SJohn.Forte@Sun.COM fcioErrorString = "reject at remote Fabric";
1827836SJohn.Forte@Sun.COM break;
1837836SJohn.Forte@Sun.COM case FC_PBUSY:
1847836SJohn.Forte@Sun.COM fcioErrorString = "remote N_Port busy";
1857836SJohn.Forte@Sun.COM break;
1867836SJohn.Forte@Sun.COM case FC_FBUSY:
1877836SJohn.Forte@Sun.COM fcioErrorString = "remote Fabric busy";
1887836SJohn.Forte@Sun.COM break;
1897836SJohn.Forte@Sun.COM case FC_ALREADY:
1907836SJohn.Forte@Sun.COM fcioErrorString = "already logged in";
1917836SJohn.Forte@Sun.COM break;
1927836SJohn.Forte@Sun.COM case FC_LOGINREQ:
1937836SJohn.Forte@Sun.COM fcioErrorString = "login required";
1947836SJohn.Forte@Sun.COM break;
1957836SJohn.Forte@Sun.COM case FC_RESETFAIL:
1967836SJohn.Forte@Sun.COM fcioErrorString = "reset failed";
1977836SJohn.Forte@Sun.COM break;
1987836SJohn.Forte@Sun.COM case FC_INVALID_REQUEST:
1997836SJohn.Forte@Sun.COM fcioErrorString = "request is invalid";
2007836SJohn.Forte@Sun.COM break;
2017836SJohn.Forte@Sun.COM case FC_OUTOFBOUNDS:
2027836SJohn.Forte@Sun.COM fcioErrorString = "port number is out of bounds";
2037836SJohn.Forte@Sun.COM break;
2047836SJohn.Forte@Sun.COM case FC_TRAN_BUSY:
2057836SJohn.Forte@Sun.COM fcioErrorString = "command transport busy";
2067836SJohn.Forte@Sun.COM break;
2077836SJohn.Forte@Sun.COM case FC_STATEC_BUSY:
2087836SJohn.Forte@Sun.COM fcioErrorString = "port driver currently busy";
2097836SJohn.Forte@Sun.COM break;
2107836SJohn.Forte@Sun.COM case FC_DEVICE_BUSY:
2117836SJohn.Forte@Sun.COM fcioErrorString = "transport working on this device";
2127836SJohn.Forte@Sun.COM break;
2137836SJohn.Forte@Sun.COM case FC_DEVICE_NOT_TGT:
2147836SJohn.Forte@Sun.COM fcioErrorString = "device is not a SCSI target";
2157836SJohn.Forte@Sun.COM break;
2167836SJohn.Forte@Sun.COM default:
2177836SJohn.Forte@Sun.COM snprintf(message, MAX_FCTIO_MSG_LEN, "Unknown error code 0x%x",
2187836SJohn.Forte@Sun.COM fctio_errno);
2197836SJohn.Forte@Sun.COM return;
2207836SJohn.Forte@Sun.COM }
2217836SJohn.Forte@Sun.COM snprintf(message, MAX_FCTIO_MSG_LEN, "%s", fcioErrorString.c_str());
2227836SJohn.Forte@Sun.COM }
2237836SJohn.Forte@Sun.COM
TgtFCHBAPort(string thePath)2247836SJohn.Forte@Sun.COM TgtFCHBAPort::TgtFCHBAPort(string thePath) : HBAPort() {
2257836SJohn.Forte@Sun.COM Trace log("TgtFCHBAPort::TgtFCHBAPort");
2267836SJohn.Forte@Sun.COM log.debug("Initializing HBA port %s", path.c_str());
2277836SJohn.Forte@Sun.COM path = thePath;
2287836SJohn.Forte@Sun.COM
2297836SJohn.Forte@Sun.COM // This routine is not index based, so we can discard stateChange
2307836SJohn.Forte@Sun.COM uint64_t tmp;
2317836SJohn.Forte@Sun.COM HBA_PORTATTRIBUTES attrs = getPortAttributes(tmp);
2327836SJohn.Forte@Sun.COM memcpy(&tmp, &attrs.PortWWN, 8);
2337836SJohn.Forte@Sun.COM portWWN = ntohll(tmp);
2347836SJohn.Forte@Sun.COM memcpy(&tmp, &attrs.NodeWWN, 8);
2357836SJohn.Forte@Sun.COM nodeWWN = ntohll(tmp);
2367836SJohn.Forte@Sun.COM
2377836SJohn.Forte@Sun.COM // For reference, here's how to dump WWN's through C++ streams.
2387836SJohn.Forte@Sun.COM // cout << "\tPort WWN: " << hex << setfill('0') << setw(16) << portWWN
2397836SJohn.Forte@Sun.COM // << endl;
2407836SJohn.Forte@Sun.COM // cout << "\tNode WWN: " << hex << setfill('0') << setw(16) << nodeWWN
2417836SJohn.Forte@Sun.COM // << endl;
2427836SJohn.Forte@Sun.COM }
2437836SJohn.Forte@Sun.COM
getPortAttributes(uint64_t & stateChange)2447836SJohn.Forte@Sun.COM HBA_PORTATTRIBUTES TgtFCHBAPort::getPortAttributes(uint64_t &stateChange) {
2457836SJohn.Forte@Sun.COM Trace log("TgtFCHBAPort::getPortAttributes");
2467836SJohn.Forte@Sun.COM
2477836SJohn.Forte@Sun.COM HBA_PORTATTRIBUTES attributes;
2487836SJohn.Forte@Sun.COM fctio_t fctio;
2497836SJohn.Forte@Sun.COM fc_tgt_hba_port_attributes_t attrs;
2507836SJohn.Forte@Sun.COM
2517836SJohn.Forte@Sun.COM memset(&fctio, 0, sizeof (fctio));
2527836SJohn.Forte@Sun.COM memset(&attributes, 0, sizeof (attributes));
2537836SJohn.Forte@Sun.COM
2547836SJohn.Forte@Sun.COM uint64_t portwwn = 0;
2557836SJohn.Forte@Sun.COM try {
2567836SJohn.Forte@Sun.COM string::size_type offset = path.find_last_of(".");
2577836SJohn.Forte@Sun.COM if (offset >= 0) {
2587836SJohn.Forte@Sun.COM string portwwnString = path.substr(offset+1);
2597836SJohn.Forte@Sun.COM portwwn = strtoull(portwwnString.c_str(), NULL, 16);
2607836SJohn.Forte@Sun.COM }
2617836SJohn.Forte@Sun.COM } catch (...) {
2627836SJohn.Forte@Sun.COM throw BadArgumentException();
2637836SJohn.Forte@Sun.COM }
2647836SJohn.Forte@Sun.COM
2657836SJohn.Forte@Sun.COM uint64_t en_wwn = htonll(portwwn);
2667836SJohn.Forte@Sun.COM
2677836SJohn.Forte@Sun.COM fctio.fctio_cmd = FCTIO_GET_ADAPTER_PORT_ATTRIBUTES;
2687836SJohn.Forte@Sun.COM fctio.fctio_ilen = 8;
2697836SJohn.Forte@Sun.COM fctio.fctio_ibuf = (uint64_t)(uintptr_t)&en_wwn;
2707836SJohn.Forte@Sun.COM fctio.fctio_xfer = FCTIO_XFER_READ;
2717836SJohn.Forte@Sun.COM fctio.fctio_olen = (uint32_t)(sizeof (attrs));
2727836SJohn.Forte@Sun.COM fctio.fctio_obuf = (uint64_t)(uintptr_t)&attrs;
2737836SJohn.Forte@Sun.COM
2747836SJohn.Forte@Sun.COM fct_ioctl(FCTIO_CMD, &fctio);
2757836SJohn.Forte@Sun.COM
2767836SJohn.Forte@Sun.COM stateChange = attrs.lastChange;
2777836SJohn.Forte@Sun.COM
2787836SJohn.Forte@Sun.COM attributes.PortFcId = attrs.PortFcId;
2797836SJohn.Forte@Sun.COM attributes.PortType = attrs.PortType;
2807836SJohn.Forte@Sun.COM attributes.PortState = attrs.PortState;
2817836SJohn.Forte@Sun.COM attributes.PortSupportedClassofService = attrs.PortSupportedClassofService;
2827836SJohn.Forte@Sun.COM attributes.PortSupportedSpeed = attrs.PortSupportedSpeed;
2837836SJohn.Forte@Sun.COM attributes.PortSpeed = attrs.PortSpeed;
2847836SJohn.Forte@Sun.COM attributes.PortMaxFrameSize = attrs.PortMaxFrameSize;
2857836SJohn.Forte@Sun.COM attributes.NumberofDiscoveredPorts = attrs.NumberofDiscoveredPorts;
2867836SJohn.Forte@Sun.COM memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8);
2877836SJohn.Forte@Sun.COM memcpy(&attributes.PortWWN, &attrs.PortWWN, 8);
2887836SJohn.Forte@Sun.COM memcpy(&attributes.FabricName, &attrs.FabricName, 8);
2897836SJohn.Forte@Sun.COM memcpy(&attributes.PortSupportedFc4Types, &attrs.PortSupportedFc4Types, 32);
2907836SJohn.Forte@Sun.COM memcpy(&attributes.PortActiveFc4Types, &attrs.PortActiveFc4Types, 32);
2917836SJohn.Forte@Sun.COM memcpy(&attributes.PortSymbolicName, &attrs.PortSymbolicName, 256);
2927836SJohn.Forte@Sun.COM
2937836SJohn.Forte@Sun.COM strncpy((char *)attributes.OSDeviceName, "Not Applicable", 15);
2947836SJohn.Forte@Sun.COM return (attributes);
2957836SJohn.Forte@Sun.COM }
2967836SJohn.Forte@Sun.COM
getDiscoveredAttributes(HBA_UINT32 discoveredport,uint64_t & stateChange)2977836SJohn.Forte@Sun.COM HBA_PORTATTRIBUTES TgtFCHBAPort::getDiscoveredAttributes(
2987836SJohn.Forte@Sun.COM HBA_UINT32 discoveredport, uint64_t &stateChange) {
2997836SJohn.Forte@Sun.COM Trace log("TgtFCHBAPort::getDiscoverdAttributes(i)");
3007836SJohn.Forte@Sun.COM
3017836SJohn.Forte@Sun.COM HBA_PORTATTRIBUTES attributes;
3027836SJohn.Forte@Sun.COM fctio_t fctio;
3037836SJohn.Forte@Sun.COM fc_tgt_hba_port_attributes_t attrs;
3047836SJohn.Forte@Sun.COM
3057836SJohn.Forte@Sun.COM memset(&fctio, 0, sizeof (fctio));
3067836SJohn.Forte@Sun.COM memset(&attributes, 0, sizeof (attributes));
3077836SJohn.Forte@Sun.COM
3087836SJohn.Forte@Sun.COM uint64_t portwwn = 0;
3097836SJohn.Forte@Sun.COM try {
3107836SJohn.Forte@Sun.COM string::size_type offset = path.find_last_of(".");
3117836SJohn.Forte@Sun.COM if (offset >= 0) {
3127836SJohn.Forte@Sun.COM string portwwnString = path.substr(offset+1);
3137836SJohn.Forte@Sun.COM portwwn = strtoull(portwwnString.c_str(), NULL, 16);
3147836SJohn.Forte@Sun.COM }
3157836SJohn.Forte@Sun.COM } catch (...) {
3167836SJohn.Forte@Sun.COM throw BadArgumentException();
3177836SJohn.Forte@Sun.COM }
3187836SJohn.Forte@Sun.COM
3197836SJohn.Forte@Sun.COM uint64_t en_wwn = htonll(portwwn);
3207836SJohn.Forte@Sun.COM
3217836SJohn.Forte@Sun.COM fctio.fctio_cmd = FCTIO_GET_DISCOVERED_PORT_ATTRIBUTES;
3227836SJohn.Forte@Sun.COM fctio.fctio_ilen = 8;
3237836SJohn.Forte@Sun.COM fctio.fctio_ibuf = (uint64_t)(uintptr_t)&en_wwn;
3247836SJohn.Forte@Sun.COM fctio.fctio_xfer = FCTIO_XFER_READ;
3257836SJohn.Forte@Sun.COM fctio.fctio_olen = (uint32_t)(sizeof (attrs));
3267836SJohn.Forte@Sun.COM fctio.fctio_obuf = (uint64_t)(uintptr_t)&attrs;
3277836SJohn.Forte@Sun.COM fctio.fctio_alen = (uint32_t)(sizeof (discoveredport));
3287836SJohn.Forte@Sun.COM fctio.fctio_abuf = (uint64_t)(uintptr_t)&discoveredport;
3297836SJohn.Forte@Sun.COM
3307836SJohn.Forte@Sun.COM fct_ioctl(FCTIO_CMD, &fctio);
3317836SJohn.Forte@Sun.COM
3327836SJohn.Forte@Sun.COM stateChange = attrs.lastChange;
3337836SJohn.Forte@Sun.COM
3347836SJohn.Forte@Sun.COM attributes.PortFcId = attrs.PortFcId;
3357836SJohn.Forte@Sun.COM attributes.PortType = attrs.PortType;
3367836SJohn.Forte@Sun.COM attributes.PortState = attrs.PortState;
3377836SJohn.Forte@Sun.COM attributes.PortSupportedClassofService = attrs.PortSupportedClassofService;
3387836SJohn.Forte@Sun.COM attributes.PortSupportedSpeed = attrs.PortSupportedSpeed;
3397836SJohn.Forte@Sun.COM attributes.PortSpeed = attrs.PortSpeed;
3407836SJohn.Forte@Sun.COM attributes.PortMaxFrameSize = attrs.PortMaxFrameSize;
3417836SJohn.Forte@Sun.COM attributes.NumberofDiscoveredPorts = attrs.NumberofDiscoveredPorts;
3427836SJohn.Forte@Sun.COM memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8);
3437836SJohn.Forte@Sun.COM memcpy(&attributes.PortWWN, &attrs.PortWWN, 8);
3447836SJohn.Forte@Sun.COM memcpy(&attributes.FabricName, &attrs.FabricName, 8);
3457836SJohn.Forte@Sun.COM memcpy(&attributes.PortSupportedFc4Types, &attrs.PortSupportedFc4Types, 32);
3467836SJohn.Forte@Sun.COM memcpy(&attributes.PortActiveFc4Types, &attrs.PortActiveFc4Types, 32);
3477836SJohn.Forte@Sun.COM memcpy(&attributes.PortSymbolicName, &attrs.PortSymbolicName, 256);
3487836SJohn.Forte@Sun.COM
3497836SJohn.Forte@Sun.COM
3507836SJohn.Forte@Sun.COM return (attributes);
3517836SJohn.Forte@Sun.COM }
3527836SJohn.Forte@Sun.COM
getDiscoveredAttributes(uint64_t wwn,uint64_t & stateChange)3537836SJohn.Forte@Sun.COM HBA_PORTATTRIBUTES TgtFCHBAPort::getDiscoveredAttributes(
3547836SJohn.Forte@Sun.COM uint64_t wwn, uint64_t &stateChange) {
3557836SJohn.Forte@Sun.COM Trace log("TgtFCHBAPort::getDiscoverdAttributes(p)");
3567836SJohn.Forte@Sun.COM
3577836SJohn.Forte@Sun.COM HBA_PORTATTRIBUTES attributes;
3587836SJohn.Forte@Sun.COM fctio_t fctio;
3597836SJohn.Forte@Sun.COM fc_tgt_hba_port_attributes_t attrs;
3607836SJohn.Forte@Sun.COM
3617836SJohn.Forte@Sun.COM memset(&fctio, 0, sizeof (fctio));
3627836SJohn.Forte@Sun.COM memset(&attributes, 0, sizeof (attributes));
3637836SJohn.Forte@Sun.COM
3647836SJohn.Forte@Sun.COM uint64_t en_wwn = htonll(wwn);
3657836SJohn.Forte@Sun.COM
3667836SJohn.Forte@Sun.COM fctio.fctio_cmd = FCTIO_GET_PORT_ATTRIBUTES;
3677836SJohn.Forte@Sun.COM fctio.fctio_olen = (uint32_t)(sizeof (attrs));
3687836SJohn.Forte@Sun.COM fctio.fctio_xfer = FCTIO_XFER_READ;
3697836SJohn.Forte@Sun.COM fctio.fctio_obuf = (uint64_t)(uintptr_t)&attrs;
3707836SJohn.Forte@Sun.COM fctio.fctio_ilen = (uint32_t)(sizeof (wwn));
3717836SJohn.Forte@Sun.COM fctio.fctio_ibuf = (uint64_t)(uintptr_t)&en_wwn;
3727836SJohn.Forte@Sun.COM
3737836SJohn.Forte@Sun.COM fct_ioctl(FCTIO_CMD, &fctio);
3747836SJohn.Forte@Sun.COM
3757836SJohn.Forte@Sun.COM stateChange = attrs.lastChange;
3767836SJohn.Forte@Sun.COM
3777836SJohn.Forte@Sun.COM attributes.PortFcId = attrs.PortFcId;
3787836SJohn.Forte@Sun.COM attributes.PortType = attrs.PortType;
3797836SJohn.Forte@Sun.COM attributes.PortState = attrs.PortState;
3807836SJohn.Forte@Sun.COM attributes.PortSupportedClassofService = attrs.PortSupportedClassofService;
3817836SJohn.Forte@Sun.COM attributes.PortSupportedSpeed = attrs.PortSupportedSpeed;
3827836SJohn.Forte@Sun.COM attributes.PortSpeed = attrs.PortSpeed;
3837836SJohn.Forte@Sun.COM attributes.PortMaxFrameSize = attrs.PortMaxFrameSize;
3847836SJohn.Forte@Sun.COM attributes.NumberofDiscoveredPorts = attrs.NumberofDiscoveredPorts;
3857836SJohn.Forte@Sun.COM memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8);
3867836SJohn.Forte@Sun.COM memcpy(&attributes.PortWWN, &attrs.PortWWN, 8);
3877836SJohn.Forte@Sun.COM memcpy(&attributes.FabricName, &attrs.FabricName, 8);
3887836SJohn.Forte@Sun.COM memcpy(&attributes.PortSupportedFc4Types, &attrs.PortSupportedFc4Types, 32);
3897836SJohn.Forte@Sun.COM memcpy(&attributes.PortActiveFc4Types, &attrs.PortActiveFc4Types, 32);
3907836SJohn.Forte@Sun.COM memcpy(&attributes.PortSymbolicName, &attrs.PortSymbolicName, 256);
3917836SJohn.Forte@Sun.COM
3927836SJohn.Forte@Sun.COM
3937836SJohn.Forte@Sun.COM return (attributes);
3947836SJohn.Forte@Sun.COM }
3957836SJohn.Forte@Sun.COM
sendRLS(uint64_t destWWN,void * pRspBuffer,HBA_UINT32 * pRspBufferSize)3967836SJohn.Forte@Sun.COM void TgtFCHBAPort::sendRLS(uint64_t destWWN,
3977836SJohn.Forte@Sun.COM void *pRspBuffer,
3987836SJohn.Forte@Sun.COM HBA_UINT32 *pRspBufferSize) {
3997836SJohn.Forte@Sun.COM Trace log("FCHBAPort::sendRLS");
4007836SJohn.Forte@Sun.COM
4017836SJohn.Forte@Sun.COM fctio_t fctio;
4027836SJohn.Forte@Sun.COM // fc_hba_adapter_port_stats_t fc_port_stat;
4037836SJohn.Forte@Sun.COM uint64_t en_portWWN;
404*10088SAllan.Ou@Sun.COM uint64_t DestPortID;
4057836SJohn.Forte@Sun.COM
4067836SJohn.Forte@Sun.COM // Validate the arguments
4077836SJohn.Forte@Sun.COM if (pRspBuffer == NULL ||
4087836SJohn.Forte@Sun.COM pRspBufferSize == NULL) {
4097836SJohn.Forte@Sun.COM log.userError("NULL hba");
4107836SJohn.Forte@Sun.COM throw BadArgumentException();
4117836SJohn.Forte@Sun.COM }
4127836SJohn.Forte@Sun.COM
4137836SJohn.Forte@Sun.COM // check to see if we are sending RLS to the HBA
4147836SJohn.Forte@Sun.COM HBA_PORTATTRIBUTES attrs;
4157836SJohn.Forte@Sun.COM uint64_t tmp;
4167836SJohn.Forte@Sun.COM portWWN = getPortWWN();
4177836SJohn.Forte@Sun.COM en_portWWN = htonll(portWWN);
4187836SJohn.Forte@Sun.COM
4197836SJohn.Forte@Sun.COM /* The destWWN is either the adapter port or a discovered port. */
4207836SJohn.Forte@Sun.COM memset(&fctio, 0, sizeof (fctio));
421*10088SAllan.Ou@Sun.COM fctio.fctio_cmd = FCTIO_GET_LINK_STATUS;
4227836SJohn.Forte@Sun.COM fctio.fctio_ibuf = (uint64_t)(uintptr_t)&en_portWWN;
4237836SJohn.Forte@Sun.COM fctio.fctio_ilen = (uint32_t)(sizeof (en_portWWN));
4247836SJohn.Forte@Sun.COM if (portWWN != destWWN) {
4257836SJohn.Forte@Sun.COM attrs = getDiscoveredAttributes(destWWN, tmp);
426*10088SAllan.Ou@Sun.COM DestPortID = (uint64_t)attrs.PortFcId;
427*10088SAllan.Ou@Sun.COM fctio.fctio_abuf = (uint64_t)(uintptr_t)&DestPortID;
428*10088SAllan.Ou@Sun.COM fctio.fctio_alen = (uint32_t)(sizeof (DestPortID));
4297836SJohn.Forte@Sun.COM }
4307836SJohn.Forte@Sun.COM fctio.fctio_xfer = FCTIO_XFER_READ;
4317836SJohn.Forte@Sun.COM fctio.fctio_flags = 0;
4327836SJohn.Forte@Sun.COM fctio.fctio_obuf = (uint64_t)(uintptr_t)new uchar_t[*pRspBufferSize];
4337836SJohn.Forte@Sun.COM fctio.fctio_olen = *pRspBufferSize;
4347836SJohn.Forte@Sun.COM
4357836SJohn.Forte@Sun.COM if (fctio.fctio_obuf == NULL) {
4367836SJohn.Forte@Sun.COM log.noMemory();
4377836SJohn.Forte@Sun.COM throw InternalError();
4387836SJohn.Forte@Sun.COM }
4397836SJohn.Forte@Sun.COM
4407836SJohn.Forte@Sun.COM fct_ioctl(FCTIO_CMD, &fctio);
4417836SJohn.Forte@Sun.COM memcpy(pRspBuffer, (uchar_t *)(uintptr_t)fctio.fctio_obuf,
4427836SJohn.Forte@Sun.COM *pRspBufferSize);
4437836SJohn.Forte@Sun.COM if (fctio.fctio_obuf != NULL) {
4447836SJohn.Forte@Sun.COM delete((uchar_t *)(uintptr_t)fctio.fctio_obuf);
4457836SJohn.Forte@Sun.COM }
4467836SJohn.Forte@Sun.COM }
4477836SJohn.Forte@Sun.COM
4487836SJohn.Forte@Sun.COM /**
4497836SJohn.Forte@Sun.COM * @memo Validate that the port is still present in the system
4507836SJohn.Forte@Sun.COM * @exception UnavailableException if the port is not present
4517836SJohn.Forte@Sun.COM * @version 1.7
4527836SJohn.Forte@Sun.COM *
4537836SJohn.Forte@Sun.COM * @doc If the port is still present on the system, the routine
4547836SJohn.Forte@Sun.COM * will return normally. If the port is not present
4557836SJohn.Forte@Sun.COM * an exception will be thrown.
4567836SJohn.Forte@Sun.COM */
validatePresent()4577836SJohn.Forte@Sun.COM void TgtFCHBAPort::validatePresent() {
4587836SJohn.Forte@Sun.COM Trace log("TgtFCHBAPort::validatePresent");
4597836SJohn.Forte@Sun.COM // We already got the adapter list through the ioctl
4607836SJohn.Forte@Sun.COM // so calling it again to validate it is too expensive.
4617836SJohn.Forte@Sun.COM }
4627836SJohn.Forte@Sun.COM
fct_ioctl(int cmd,fctio_t * fctio)4637836SJohn.Forte@Sun.COM void TgtFCHBAPort::fct_ioctl(int cmd, fctio_t *fctio) {
4647836SJohn.Forte@Sun.COM Trace log("TgtFCHBAPort::fct_ioctl");
4657836SJohn.Forte@Sun.COM char fcioErrorString[MAX_FCTIO_MSG_LEN] = "";
4667836SJohn.Forte@Sun.COM int fd = HBA::_open(FCT_DRIVER_PATH, O_NDELAY | O_RDONLY);
4677836SJohn.Forte@Sun.COM try {
4687836SJohn.Forte@Sun.COM HBA::_ioctl(fd, cmd, (uchar_t *)fctio);
4697836SJohn.Forte@Sun.COM close(fd);
4707836SJohn.Forte@Sun.COM if (fctio->fctio_errno) {
4717836SJohn.Forte@Sun.COM throw IOError("IOCTL transport failure");
4727836SJohn.Forte@Sun.COM }
4737836SJohn.Forte@Sun.COM } catch (...) {
4747836SJohn.Forte@Sun.COM close(fd);
4757836SJohn.Forte@Sun.COM transportError(fctio->fctio_errno, fcioErrorString);
4767836SJohn.Forte@Sun.COM log.genericIOError("ioctl (0x%x) failed. Transport: \"%s\"", cmd,
4777836SJohn.Forte@Sun.COM fcioErrorString);
4787836SJohn.Forte@Sun.COM switch (fctio->fctio_errno) {
4797836SJohn.Forte@Sun.COM case FC_BADWWN:
4807836SJohn.Forte@Sun.COM throw IllegalWWNException();
4817836SJohn.Forte@Sun.COM case FC_BADPORT:
4827836SJohn.Forte@Sun.COM throw IllegalWWNException();
4837836SJohn.Forte@Sun.COM case FC_OUTOFBOUNDS:
4847836SJohn.Forte@Sun.COM throw IllegalIndexException();
4857836SJohn.Forte@Sun.COM case FC_PBUSY:
4867836SJohn.Forte@Sun.COM case FC_FBUSY:
4877836SJohn.Forte@Sun.COM case FC_TRAN_BUSY:
4887836SJohn.Forte@Sun.COM case FC_STATEC_BUSY:
4897836SJohn.Forte@Sun.COM case FC_DEVICE_BUSY:
4907836SJohn.Forte@Sun.COM throw BusyException();
4917836SJohn.Forte@Sun.COM case FC_SUCCESS:
4927836SJohn.Forte@Sun.COM default:
4937836SJohn.Forte@Sun.COM throw;
4947836SJohn.Forte@Sun.COM }
4957836SJohn.Forte@Sun.COM }
4967836SJohn.Forte@Sun.COM }
497