1fcf3ce44SJohn Forte /* 2fcf3ce44SJohn Forte * CDDL HEADER START 3fcf3ce44SJohn Forte * 4fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the 5fcf3ce44SJohn Forte * Common Development and Distribution License (the "License"). 6fcf3ce44SJohn Forte * You may not use this file except in compliance with the License. 7fcf3ce44SJohn Forte * 8fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing. 10fcf3ce44SJohn Forte * See the License for the specific language governing permissions 11fcf3ce44SJohn Forte * and limitations under the License. 12fcf3ce44SJohn Forte * 13fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 14fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 16fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 17fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 18fcf3ce44SJohn Forte * 19fcf3ce44SJohn Forte * CDDL HEADER END 20fcf3ce44SJohn Forte */ 21fcf3ce44SJohn Forte /* 22c946facaSallan * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23fcf3ce44SJohn Forte * Use is subject to license terms. 24fcf3ce44SJohn Forte */ 25fcf3ce44SJohn Forte 26fcf3ce44SJohn Forte 27fcf3ce44SJohn Forte 28fcf3ce44SJohn Forte #include <TgtFCHBAPort.h> 29fcf3ce44SJohn Forte #include <Exceptions.h> 30fcf3ce44SJohn Forte #include <Trace.h> 31fcf3ce44SJohn Forte #include <sun_fc.h> 32fcf3ce44SJohn Forte #include <iostream> 33fcf3ce44SJohn Forte #include <iomanip> 34fcf3ce44SJohn Forte #include <sys/types.h> 35fcf3ce44SJohn Forte #include <sys/mkdev.h> 36fcf3ce44SJohn Forte #include <sys/stat.h> 37fcf3ce44SJohn Forte #include <fcntl.h> 38fcf3ce44SJohn Forte #include <unistd.h> 39fcf3ce44SJohn Forte #include <stropts.h> 40fcf3ce44SJohn Forte #include <dirent.h> 41fcf3ce44SJohn Forte #include <sys/fibre-channel/fc.h> 42fcf3ce44SJohn Forte #include <sys/fctio.h> 43fcf3ce44SJohn Forte #include <sys/fibre-channel/impl/fc_error.h> 44fcf3ce44SJohn Forte #include <sys/fibre-channel/fc_appif.h> 45fcf3ce44SJohn Forte #include <sys/scsi/generic/commands.h> 46fcf3ce44SJohn Forte #include <sys/scsi/impl/commands.h> 47fcf3ce44SJohn Forte #include <sys/scsi/impl/sense.h> 48fcf3ce44SJohn Forte #include <sys/scsi/generic/inquiry.h> 49fcf3ce44SJohn Forte #include <sys/scsi/generic/status.h> 50fcf3ce44SJohn Forte #include <errno.h> 51*f3aaec0aSRichard Lowe #include <cstdlib> 52fcf3ce44SJohn Forte 53fcf3ce44SJohn Forte 54fcf3ce44SJohn Forte using namespace std; 55fcf3ce44SJohn Forte 56fcf3ce44SJohn Forte const int TgtFCHBAPort::MAX_FCTIO_MSG_LEN = 256; 57fcf3ce44SJohn Forte const string TgtFCHBAPort::FCT_DRIVER_PATH = "/devices/pseudo/fct@0:admin"; 58fcf3ce44SJohn Forte 59fcf3ce44SJohn Forte /* 60fcf3ce44SJohn Forte * Interpret the error code in the fctio_t structure 61fcf3ce44SJohn Forte * 62fcf3ce44SJohn Forte * message must be at least MAX_FCTIO_MSG_LEN in length. 63fcf3ce44SJohn Forte */ 64fcf3ce44SJohn Forte void 65fcf3ce44SJohn Forte TgtFCHBAPort::transportError(uint32_t fctio_errno, char *message) { 66fcf3ce44SJohn Forte Trace log("transportError"); 67fcf3ce44SJohn Forte string fcioErrorString; 68fcf3ce44SJohn Forte if (message == NULL) { 69fcf3ce44SJohn Forte log.internalError("NULL routine argument"); 70fcf3ce44SJohn Forte return; 71fcf3ce44SJohn Forte } 72fcf3ce44SJohn Forte switch (fctio_errno) { 73fcf3ce44SJohn Forte case (uint32_t)FC_FAILURE: 74fcf3ce44SJohn Forte fcioErrorString = "general failure"; 75fcf3ce44SJohn Forte break; 76fcf3ce44SJohn Forte case (uint32_t)FC_FAILURE_SILENT: 77fcf3ce44SJohn Forte fcioErrorString = "general failure but fail silently"; 78fcf3ce44SJohn Forte break; 79fcf3ce44SJohn Forte case FC_SUCCESS: 80fcf3ce44SJohn Forte fcioErrorString = "successful completion"; 81fcf3ce44SJohn Forte break; 82fcf3ce44SJohn Forte case FC_CAP_ERROR: 83fcf3ce44SJohn Forte fcioErrorString = "FCA capability error"; 84fcf3ce44SJohn Forte break; 85fcf3ce44SJohn Forte case FC_CAP_FOUND: 86fcf3ce44SJohn Forte fcioErrorString = "FCA capability unsettable"; 87fcf3ce44SJohn Forte break; 88fcf3ce44SJohn Forte case FC_CAP_SETTABLE: 89fcf3ce44SJohn Forte fcioErrorString = "FCA capability settable"; 90fcf3ce44SJohn Forte break; 91fcf3ce44SJohn Forte case FC_UNBOUND: 92fcf3ce44SJohn Forte fcioErrorString = "unbound stuff"; 93fcf3ce44SJohn Forte break; 94fcf3ce44SJohn Forte case FC_NOMEM: 95fcf3ce44SJohn Forte fcioErrorString = "allocation error"; 96fcf3ce44SJohn Forte break; 97fcf3ce44SJohn Forte case FC_BADPACKET: 98fcf3ce44SJohn Forte fcioErrorString = "invalid packet specified/supplied"; 99fcf3ce44SJohn Forte break; 100fcf3ce44SJohn Forte case FC_OFFLINE: 101fcf3ce44SJohn Forte fcioErrorString = "I/O resource unavailable"; 102fcf3ce44SJohn Forte break; 103fcf3ce44SJohn Forte case FC_OLDPORT: 104fcf3ce44SJohn Forte fcioErrorString = "operation on non-loop port"; 105fcf3ce44SJohn Forte break; 106fcf3ce44SJohn Forte case FC_NO_MAP: 107fcf3ce44SJohn Forte fcioErrorString = "requested map unavailable"; 108fcf3ce44SJohn Forte break; 109fcf3ce44SJohn Forte case FC_TRANSPORT_ERROR: 110fcf3ce44SJohn Forte fcioErrorString = "unable to transport I/O"; 111fcf3ce44SJohn Forte break; 112fcf3ce44SJohn Forte case FC_ELS_FREJECT: 113fcf3ce44SJohn Forte fcioErrorString = "ELS rejected by a Fabric"; 114fcf3ce44SJohn Forte break; 115fcf3ce44SJohn Forte case FC_ELS_PREJECT: 116fcf3ce44SJohn Forte fcioErrorString = "ELS rejected by an N_port"; 117fcf3ce44SJohn Forte break; 118fcf3ce44SJohn Forte case FC_ELS_BAD: 119fcf3ce44SJohn Forte fcioErrorString = "ELS rejected by FCA/fctl"; 120fcf3ce44SJohn Forte break; 121fcf3ce44SJohn Forte case FC_ELS_MALFORMED: 122fcf3ce44SJohn Forte fcioErrorString = "poorly formed ELS request"; 123fcf3ce44SJohn Forte break; 124fcf3ce44SJohn Forte case FC_TOOMANY: 125fcf3ce44SJohn Forte fcioErrorString = "resource request too large"; 126fcf3ce44SJohn Forte break; 127fcf3ce44SJohn Forte case FC_UB_BADTOKEN: 128fcf3ce44SJohn Forte fcioErrorString = "invalid unsolicited buffer token"; 129fcf3ce44SJohn Forte break; 130fcf3ce44SJohn Forte case FC_UB_ERROR: 131fcf3ce44SJohn Forte fcioErrorString = "invalid unsol buf request"; 132fcf3ce44SJohn Forte break; 133fcf3ce44SJohn Forte case FC_UB_BUSY: 134fcf3ce44SJohn Forte fcioErrorString = "buffer already in use"; 135fcf3ce44SJohn Forte break; 136fcf3ce44SJohn Forte case FC_BADULP: 137fcf3ce44SJohn Forte fcioErrorString = "Unknown ulp"; 138fcf3ce44SJohn Forte break; 139fcf3ce44SJohn Forte case FC_BADTYPE: 140fcf3ce44SJohn Forte fcioErrorString = "ULP not registered to handle this FC4 type"; 141fcf3ce44SJohn Forte break; 142fcf3ce44SJohn Forte case FC_UNCLAIMED: 143fcf3ce44SJohn Forte fcioErrorString = "request or data not claimed"; 144fcf3ce44SJohn Forte break; 145fcf3ce44SJohn Forte case FC_ULP_SAMEMODULE: 146fcf3ce44SJohn Forte fcioErrorString = "module already in use"; 147fcf3ce44SJohn Forte break; 148fcf3ce44SJohn Forte case FC_ULP_SAMETYPE: 149fcf3ce44SJohn Forte fcioErrorString = "FC4 module already in use"; 150fcf3ce44SJohn Forte break; 151fcf3ce44SJohn Forte case FC_ABORTED: 152fcf3ce44SJohn Forte fcioErrorString = "request aborted"; 153fcf3ce44SJohn Forte break; 154fcf3ce44SJohn Forte case FC_ABORT_FAILED: 155fcf3ce44SJohn Forte fcioErrorString = "abort request failed"; 156fcf3ce44SJohn Forte break; 157fcf3ce44SJohn Forte case FC_BADEXCHANGE: 158fcf3ce44SJohn Forte fcioErrorString = "exchange doesn�t exist"; 159fcf3ce44SJohn Forte break; 160fcf3ce44SJohn Forte case FC_BADWWN: 161fcf3ce44SJohn Forte fcioErrorString = "WWN not recognized"; 162fcf3ce44SJohn Forte break; 163fcf3ce44SJohn Forte case FC_BADDEV: 164fcf3ce44SJohn Forte fcioErrorString = "device unrecognized"; 165fcf3ce44SJohn Forte break; 166fcf3ce44SJohn Forte case FC_BADCMD: 167fcf3ce44SJohn Forte fcioErrorString = "invalid command issued"; 168fcf3ce44SJohn Forte break; 169fcf3ce44SJohn Forte case FC_BADOBJECT: 170fcf3ce44SJohn Forte fcioErrorString = "invalid object requested"; 171fcf3ce44SJohn Forte break; 172fcf3ce44SJohn Forte case FC_BADPORT: 173fcf3ce44SJohn Forte fcioErrorString = "invalid port specified"; 174fcf3ce44SJohn Forte break; 175fcf3ce44SJohn Forte case FC_NOTTHISPORT: 176fcf3ce44SJohn Forte fcioErrorString = "resource not at this port"; 177fcf3ce44SJohn Forte break; 178fcf3ce44SJohn Forte case FC_PREJECT: 179fcf3ce44SJohn Forte fcioErrorString = "reject at remote N_Port"; 180fcf3ce44SJohn Forte break; 181fcf3ce44SJohn Forte case FC_FREJECT: 182fcf3ce44SJohn Forte fcioErrorString = "reject at remote Fabric"; 183fcf3ce44SJohn Forte break; 184fcf3ce44SJohn Forte case FC_PBUSY: 185fcf3ce44SJohn Forte fcioErrorString = "remote N_Port busy"; 186fcf3ce44SJohn Forte break; 187fcf3ce44SJohn Forte case FC_FBUSY: 188fcf3ce44SJohn Forte fcioErrorString = "remote Fabric busy"; 189fcf3ce44SJohn Forte break; 190fcf3ce44SJohn Forte case FC_ALREADY: 191fcf3ce44SJohn Forte fcioErrorString = "already logged in"; 192fcf3ce44SJohn Forte break; 193fcf3ce44SJohn Forte case FC_LOGINREQ: 194fcf3ce44SJohn Forte fcioErrorString = "login required"; 195fcf3ce44SJohn Forte break; 196fcf3ce44SJohn Forte case FC_RESETFAIL: 197fcf3ce44SJohn Forte fcioErrorString = "reset failed"; 198fcf3ce44SJohn Forte break; 199fcf3ce44SJohn Forte case FC_INVALID_REQUEST: 200fcf3ce44SJohn Forte fcioErrorString = "request is invalid"; 201fcf3ce44SJohn Forte break; 202fcf3ce44SJohn Forte case FC_OUTOFBOUNDS: 203fcf3ce44SJohn Forte fcioErrorString = "port number is out of bounds"; 204fcf3ce44SJohn Forte break; 205fcf3ce44SJohn Forte case FC_TRAN_BUSY: 206fcf3ce44SJohn Forte fcioErrorString = "command transport busy"; 207fcf3ce44SJohn Forte break; 208fcf3ce44SJohn Forte case FC_STATEC_BUSY: 209fcf3ce44SJohn Forte fcioErrorString = "port driver currently busy"; 210fcf3ce44SJohn Forte break; 211fcf3ce44SJohn Forte case FC_DEVICE_BUSY: 212fcf3ce44SJohn Forte fcioErrorString = "transport working on this device"; 213fcf3ce44SJohn Forte break; 214fcf3ce44SJohn Forte case FC_DEVICE_NOT_TGT: 215fcf3ce44SJohn Forte fcioErrorString = "device is not a SCSI target"; 216fcf3ce44SJohn Forte break; 217fcf3ce44SJohn Forte default: 218fcf3ce44SJohn Forte snprintf(message, MAX_FCTIO_MSG_LEN, "Unknown error code 0x%x", 219fcf3ce44SJohn Forte fctio_errno); 220fcf3ce44SJohn Forte return; 221fcf3ce44SJohn Forte } 222fcf3ce44SJohn Forte snprintf(message, MAX_FCTIO_MSG_LEN, "%s", fcioErrorString.c_str()); 223fcf3ce44SJohn Forte } 224fcf3ce44SJohn Forte 225fcf3ce44SJohn Forte TgtFCHBAPort::TgtFCHBAPort(string thePath) : HBAPort() { 226fcf3ce44SJohn Forte Trace log("TgtFCHBAPort::TgtFCHBAPort"); 227fcf3ce44SJohn Forte log.debug("Initializing HBA port %s", path.c_str()); 228fcf3ce44SJohn Forte path = thePath; 229fcf3ce44SJohn Forte 230fcf3ce44SJohn Forte // This routine is not index based, so we can discard stateChange 231fcf3ce44SJohn Forte uint64_t tmp; 232fcf3ce44SJohn Forte HBA_PORTATTRIBUTES attrs = getPortAttributes(tmp); 233fcf3ce44SJohn Forte memcpy(&tmp, &attrs.PortWWN, 8); 234fcf3ce44SJohn Forte portWWN = ntohll(tmp); 235fcf3ce44SJohn Forte memcpy(&tmp, &attrs.NodeWWN, 8); 236fcf3ce44SJohn Forte nodeWWN = ntohll(tmp); 237fcf3ce44SJohn Forte 238fcf3ce44SJohn Forte // For reference, here's how to dump WWN's through C++ streams. 239fcf3ce44SJohn Forte // cout << "\tPort WWN: " << hex << setfill('0') << setw(16) << portWWN 240fcf3ce44SJohn Forte // << endl; 241fcf3ce44SJohn Forte // cout << "\tNode WWN: " << hex << setfill('0') << setw(16) << nodeWWN 242fcf3ce44SJohn Forte // << endl; 243fcf3ce44SJohn Forte } 244fcf3ce44SJohn Forte 245fcf3ce44SJohn Forte HBA_PORTATTRIBUTES TgtFCHBAPort::getPortAttributes(uint64_t &stateChange) { 246fcf3ce44SJohn Forte Trace log("TgtFCHBAPort::getPortAttributes"); 247fcf3ce44SJohn Forte 248fcf3ce44SJohn Forte HBA_PORTATTRIBUTES attributes; 249fcf3ce44SJohn Forte fctio_t fctio; 250fcf3ce44SJohn Forte fc_tgt_hba_port_attributes_t attrs; 251fcf3ce44SJohn Forte 252fcf3ce44SJohn Forte memset(&fctio, 0, sizeof (fctio)); 253fcf3ce44SJohn Forte memset(&attributes, 0, sizeof (attributes)); 254fcf3ce44SJohn Forte 255fcf3ce44SJohn Forte uint64_t portwwn = 0; 256fcf3ce44SJohn Forte try { 257fcf3ce44SJohn Forte string::size_type offset = path.find_last_of("."); 258fcf3ce44SJohn Forte if (offset >= 0) { 259fcf3ce44SJohn Forte string portwwnString = path.substr(offset+1); 260fcf3ce44SJohn Forte portwwn = strtoull(portwwnString.c_str(), NULL, 16); 261fcf3ce44SJohn Forte } 262fcf3ce44SJohn Forte } catch (...) { 263fcf3ce44SJohn Forte throw BadArgumentException(); 264fcf3ce44SJohn Forte } 265fcf3ce44SJohn Forte 266fcf3ce44SJohn Forte uint64_t en_wwn = htonll(portwwn); 267fcf3ce44SJohn Forte 268fcf3ce44SJohn Forte fctio.fctio_cmd = FCTIO_GET_ADAPTER_PORT_ATTRIBUTES; 269fcf3ce44SJohn Forte fctio.fctio_ilen = 8; 270fcf3ce44SJohn Forte fctio.fctio_ibuf = (uint64_t)(uintptr_t)&en_wwn; 271fcf3ce44SJohn Forte fctio.fctio_xfer = FCTIO_XFER_READ; 272fcf3ce44SJohn Forte fctio.fctio_olen = (uint32_t)(sizeof (attrs)); 273fcf3ce44SJohn Forte fctio.fctio_obuf = (uint64_t)(uintptr_t)&attrs; 274fcf3ce44SJohn Forte 275fcf3ce44SJohn Forte fct_ioctl(FCTIO_CMD, &fctio); 276fcf3ce44SJohn Forte 277fcf3ce44SJohn Forte stateChange = attrs.lastChange; 278fcf3ce44SJohn Forte 279fcf3ce44SJohn Forte attributes.PortFcId = attrs.PortFcId; 280fcf3ce44SJohn Forte attributes.PortType = attrs.PortType; 281fcf3ce44SJohn Forte attributes.PortState = attrs.PortState; 282fcf3ce44SJohn Forte attributes.PortSupportedClassofService = attrs.PortSupportedClassofService; 283fcf3ce44SJohn Forte attributes.PortSupportedSpeed = attrs.PortSupportedSpeed; 284fcf3ce44SJohn Forte attributes.PortSpeed = attrs.PortSpeed; 285fcf3ce44SJohn Forte attributes.PortMaxFrameSize = attrs.PortMaxFrameSize; 286fcf3ce44SJohn Forte attributes.NumberofDiscoveredPorts = attrs.NumberofDiscoveredPorts; 287fcf3ce44SJohn Forte memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8); 288fcf3ce44SJohn Forte memcpy(&attributes.PortWWN, &attrs.PortWWN, 8); 289fcf3ce44SJohn Forte memcpy(&attributes.FabricName, &attrs.FabricName, 8); 290fcf3ce44SJohn Forte memcpy(&attributes.PortSupportedFc4Types, &attrs.PortSupportedFc4Types, 32); 291fcf3ce44SJohn Forte memcpy(&attributes.PortActiveFc4Types, &attrs.PortActiveFc4Types, 32); 292fcf3ce44SJohn Forte memcpy(&attributes.PortSymbolicName, &attrs.PortSymbolicName, 256); 293fcf3ce44SJohn Forte 294fcf3ce44SJohn Forte strncpy((char *)attributes.OSDeviceName, "Not Applicable", 15); 295fcf3ce44SJohn Forte return (attributes); 296fcf3ce44SJohn Forte } 297fcf3ce44SJohn Forte 298fcf3ce44SJohn Forte HBA_PORTATTRIBUTES TgtFCHBAPort::getDiscoveredAttributes( 299fcf3ce44SJohn Forte HBA_UINT32 discoveredport, uint64_t &stateChange) { 300fcf3ce44SJohn Forte Trace log("TgtFCHBAPort::getDiscoverdAttributes(i)"); 301fcf3ce44SJohn Forte 302fcf3ce44SJohn Forte HBA_PORTATTRIBUTES attributes; 303fcf3ce44SJohn Forte fctio_t fctio; 304fcf3ce44SJohn Forte fc_tgt_hba_port_attributes_t attrs; 305fcf3ce44SJohn Forte 306fcf3ce44SJohn Forte memset(&fctio, 0, sizeof (fctio)); 307fcf3ce44SJohn Forte memset(&attributes, 0, sizeof (attributes)); 308fcf3ce44SJohn Forte 309fcf3ce44SJohn Forte uint64_t portwwn = 0; 310fcf3ce44SJohn Forte try { 311fcf3ce44SJohn Forte string::size_type offset = path.find_last_of("."); 312fcf3ce44SJohn Forte if (offset >= 0) { 313fcf3ce44SJohn Forte string portwwnString = path.substr(offset+1); 314fcf3ce44SJohn Forte portwwn = strtoull(portwwnString.c_str(), NULL, 16); 315fcf3ce44SJohn Forte } 316fcf3ce44SJohn Forte } catch (...) { 317fcf3ce44SJohn Forte throw BadArgumentException(); 318fcf3ce44SJohn Forte } 319fcf3ce44SJohn Forte 320fcf3ce44SJohn Forte uint64_t en_wwn = htonll(portwwn); 321fcf3ce44SJohn Forte 322fcf3ce44SJohn Forte fctio.fctio_cmd = FCTIO_GET_DISCOVERED_PORT_ATTRIBUTES; 323fcf3ce44SJohn Forte fctio.fctio_ilen = 8; 324fcf3ce44SJohn Forte fctio.fctio_ibuf = (uint64_t)(uintptr_t)&en_wwn; 325fcf3ce44SJohn Forte fctio.fctio_xfer = FCTIO_XFER_READ; 326fcf3ce44SJohn Forte fctio.fctio_olen = (uint32_t)(sizeof (attrs)); 327fcf3ce44SJohn Forte fctio.fctio_obuf = (uint64_t)(uintptr_t)&attrs; 328fcf3ce44SJohn Forte fctio.fctio_alen = (uint32_t)(sizeof (discoveredport)); 329fcf3ce44SJohn Forte fctio.fctio_abuf = (uint64_t)(uintptr_t)&discoveredport; 330fcf3ce44SJohn Forte 331fcf3ce44SJohn Forte fct_ioctl(FCTIO_CMD, &fctio); 332fcf3ce44SJohn Forte 333fcf3ce44SJohn Forte stateChange = attrs.lastChange; 334fcf3ce44SJohn Forte 335fcf3ce44SJohn Forte attributes.PortFcId = attrs.PortFcId; 336fcf3ce44SJohn Forte attributes.PortType = attrs.PortType; 337fcf3ce44SJohn Forte attributes.PortState = attrs.PortState; 338fcf3ce44SJohn Forte attributes.PortSupportedClassofService = attrs.PortSupportedClassofService; 339fcf3ce44SJohn Forte attributes.PortSupportedSpeed = attrs.PortSupportedSpeed; 340fcf3ce44SJohn Forte attributes.PortSpeed = attrs.PortSpeed; 341fcf3ce44SJohn Forte attributes.PortMaxFrameSize = attrs.PortMaxFrameSize; 342fcf3ce44SJohn Forte attributes.NumberofDiscoveredPorts = attrs.NumberofDiscoveredPorts; 343fcf3ce44SJohn Forte memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8); 344fcf3ce44SJohn Forte memcpy(&attributes.PortWWN, &attrs.PortWWN, 8); 345fcf3ce44SJohn Forte memcpy(&attributes.FabricName, &attrs.FabricName, 8); 346fcf3ce44SJohn Forte memcpy(&attributes.PortSupportedFc4Types, &attrs.PortSupportedFc4Types, 32); 347fcf3ce44SJohn Forte memcpy(&attributes.PortActiveFc4Types, &attrs.PortActiveFc4Types, 32); 348fcf3ce44SJohn Forte memcpy(&attributes.PortSymbolicName, &attrs.PortSymbolicName, 256); 349fcf3ce44SJohn Forte 350fcf3ce44SJohn Forte 351fcf3ce44SJohn Forte return (attributes); 352fcf3ce44SJohn Forte } 353fcf3ce44SJohn Forte 354fcf3ce44SJohn Forte HBA_PORTATTRIBUTES TgtFCHBAPort::getDiscoveredAttributes( 355fcf3ce44SJohn Forte uint64_t wwn, uint64_t &stateChange) { 356fcf3ce44SJohn Forte Trace log("TgtFCHBAPort::getDiscoverdAttributes(p)"); 357fcf3ce44SJohn Forte 358fcf3ce44SJohn Forte HBA_PORTATTRIBUTES attributes; 359fcf3ce44SJohn Forte fctio_t fctio; 360fcf3ce44SJohn Forte fc_tgt_hba_port_attributes_t attrs; 361fcf3ce44SJohn Forte 362fcf3ce44SJohn Forte memset(&fctio, 0, sizeof (fctio)); 363fcf3ce44SJohn Forte memset(&attributes, 0, sizeof (attributes)); 364fcf3ce44SJohn Forte 365fcf3ce44SJohn Forte uint64_t en_wwn = htonll(wwn); 366fcf3ce44SJohn Forte 367fcf3ce44SJohn Forte fctio.fctio_cmd = FCTIO_GET_PORT_ATTRIBUTES; 368fcf3ce44SJohn Forte fctio.fctio_olen = (uint32_t)(sizeof (attrs)); 369fcf3ce44SJohn Forte fctio.fctio_xfer = FCTIO_XFER_READ; 370fcf3ce44SJohn Forte fctio.fctio_obuf = (uint64_t)(uintptr_t)&attrs; 371fcf3ce44SJohn Forte fctio.fctio_ilen = (uint32_t)(sizeof (wwn)); 372fcf3ce44SJohn Forte fctio.fctio_ibuf = (uint64_t)(uintptr_t)&en_wwn; 373fcf3ce44SJohn Forte 374fcf3ce44SJohn Forte fct_ioctl(FCTIO_CMD, &fctio); 375fcf3ce44SJohn Forte 376fcf3ce44SJohn Forte stateChange = attrs.lastChange; 377fcf3ce44SJohn Forte 378fcf3ce44SJohn Forte attributes.PortFcId = attrs.PortFcId; 379fcf3ce44SJohn Forte attributes.PortType = attrs.PortType; 380fcf3ce44SJohn Forte attributes.PortState = attrs.PortState; 381fcf3ce44SJohn Forte attributes.PortSupportedClassofService = attrs.PortSupportedClassofService; 382fcf3ce44SJohn Forte attributes.PortSupportedSpeed = attrs.PortSupportedSpeed; 383fcf3ce44SJohn Forte attributes.PortSpeed = attrs.PortSpeed; 384fcf3ce44SJohn Forte attributes.PortMaxFrameSize = attrs.PortMaxFrameSize; 385fcf3ce44SJohn Forte attributes.NumberofDiscoveredPorts = attrs.NumberofDiscoveredPorts; 386fcf3ce44SJohn Forte memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8); 387fcf3ce44SJohn Forte memcpy(&attributes.PortWWN, &attrs.PortWWN, 8); 388fcf3ce44SJohn Forte memcpy(&attributes.FabricName, &attrs.FabricName, 8); 389fcf3ce44SJohn Forte memcpy(&attributes.PortSupportedFc4Types, &attrs.PortSupportedFc4Types, 32); 390fcf3ce44SJohn Forte memcpy(&attributes.PortActiveFc4Types, &attrs.PortActiveFc4Types, 32); 391fcf3ce44SJohn Forte memcpy(&attributes.PortSymbolicName, &attrs.PortSymbolicName, 256); 392fcf3ce44SJohn Forte 393fcf3ce44SJohn Forte 394fcf3ce44SJohn Forte return (attributes); 395fcf3ce44SJohn Forte } 396fcf3ce44SJohn Forte 397fcf3ce44SJohn Forte void TgtFCHBAPort::sendRLS(uint64_t destWWN, 398fcf3ce44SJohn Forte void *pRspBuffer, 399fcf3ce44SJohn Forte HBA_UINT32 *pRspBufferSize) { 400fcf3ce44SJohn Forte Trace log("FCHBAPort::sendRLS"); 401fcf3ce44SJohn Forte 402fcf3ce44SJohn Forte fctio_t fctio; 403fcf3ce44SJohn Forte // fc_hba_adapter_port_stats_t fc_port_stat; 404fcf3ce44SJohn Forte uint64_t en_portWWN; 405c946facaSallan uint64_t DestPortID; 406fcf3ce44SJohn Forte 407fcf3ce44SJohn Forte // Validate the arguments 408fcf3ce44SJohn Forte if (pRspBuffer == NULL || 409fcf3ce44SJohn Forte pRspBufferSize == NULL) { 410fcf3ce44SJohn Forte log.userError("NULL hba"); 411fcf3ce44SJohn Forte throw BadArgumentException(); 412fcf3ce44SJohn Forte } 413fcf3ce44SJohn Forte 414fcf3ce44SJohn Forte // check to see if we are sending RLS to the HBA 415fcf3ce44SJohn Forte HBA_PORTATTRIBUTES attrs; 416fcf3ce44SJohn Forte uint64_t tmp; 417fcf3ce44SJohn Forte portWWN = getPortWWN(); 418fcf3ce44SJohn Forte en_portWWN = htonll(portWWN); 419fcf3ce44SJohn Forte 420fcf3ce44SJohn Forte /* The destWWN is either the adapter port or a discovered port. */ 421fcf3ce44SJohn Forte memset(&fctio, 0, sizeof (fctio)); 422c946facaSallan fctio.fctio_cmd = FCTIO_GET_LINK_STATUS; 423fcf3ce44SJohn Forte fctio.fctio_ibuf = (uint64_t)(uintptr_t)&en_portWWN; 424fcf3ce44SJohn Forte fctio.fctio_ilen = (uint32_t)(sizeof (en_portWWN)); 425fcf3ce44SJohn Forte if (portWWN != destWWN) { 426fcf3ce44SJohn Forte attrs = getDiscoveredAttributes(destWWN, tmp); 427c946facaSallan DestPortID = (uint64_t)attrs.PortFcId; 428c946facaSallan fctio.fctio_abuf = (uint64_t)(uintptr_t)&DestPortID; 429c946facaSallan fctio.fctio_alen = (uint32_t)(sizeof (DestPortID)); 430fcf3ce44SJohn Forte } 431fcf3ce44SJohn Forte fctio.fctio_xfer = FCTIO_XFER_READ; 432fcf3ce44SJohn Forte fctio.fctio_flags = 0; 433fcf3ce44SJohn Forte fctio.fctio_obuf = (uint64_t)(uintptr_t)new uchar_t[*pRspBufferSize]; 434fcf3ce44SJohn Forte fctio.fctio_olen = *pRspBufferSize; 435fcf3ce44SJohn Forte 436fcf3ce44SJohn Forte if (fctio.fctio_obuf == NULL) { 437fcf3ce44SJohn Forte log.noMemory(); 438fcf3ce44SJohn Forte throw InternalError(); 439fcf3ce44SJohn Forte } 440fcf3ce44SJohn Forte 441fcf3ce44SJohn Forte fct_ioctl(FCTIO_CMD, &fctio); 442fcf3ce44SJohn Forte memcpy(pRspBuffer, (uchar_t *)(uintptr_t)fctio.fctio_obuf, 443fcf3ce44SJohn Forte *pRspBufferSize); 444fcf3ce44SJohn Forte if (fctio.fctio_obuf != NULL) { 445fcf3ce44SJohn Forte delete((uchar_t *)(uintptr_t)fctio.fctio_obuf); 446fcf3ce44SJohn Forte } 447fcf3ce44SJohn Forte } 448fcf3ce44SJohn Forte 449fcf3ce44SJohn Forte /** 450fcf3ce44SJohn Forte * @memo Validate that the port is still present in the system 451fcf3ce44SJohn Forte * @exception UnavailableException if the port is not present 452fcf3ce44SJohn Forte * @version 1.7 453fcf3ce44SJohn Forte * 454fcf3ce44SJohn Forte * @doc If the port is still present on the system, the routine 455fcf3ce44SJohn Forte * will return normally. If the port is not present 456fcf3ce44SJohn Forte * an exception will be thrown. 457fcf3ce44SJohn Forte */ 458fcf3ce44SJohn Forte void TgtFCHBAPort::validatePresent() { 459fcf3ce44SJohn Forte Trace log("TgtFCHBAPort::validatePresent"); 460fcf3ce44SJohn Forte // We already got the adapter list through the ioctl 461fcf3ce44SJohn Forte // so calling it again to validate it is too expensive. 462fcf3ce44SJohn Forte } 463fcf3ce44SJohn Forte 464fcf3ce44SJohn Forte void TgtFCHBAPort::fct_ioctl(int cmd, fctio_t *fctio) { 465fcf3ce44SJohn Forte Trace log("TgtFCHBAPort::fct_ioctl"); 466fcf3ce44SJohn Forte char fcioErrorString[MAX_FCTIO_MSG_LEN] = ""; 467fcf3ce44SJohn Forte int fd = HBA::_open(FCT_DRIVER_PATH, O_NDELAY | O_RDONLY); 468fcf3ce44SJohn Forte try { 469fcf3ce44SJohn Forte HBA::_ioctl(fd, cmd, (uchar_t *)fctio); 470fcf3ce44SJohn Forte close(fd); 471fcf3ce44SJohn Forte if (fctio->fctio_errno) { 472fcf3ce44SJohn Forte throw IOError("IOCTL transport failure"); 473fcf3ce44SJohn Forte } 474fcf3ce44SJohn Forte } catch (...) { 475fcf3ce44SJohn Forte close(fd); 476fcf3ce44SJohn Forte transportError(fctio->fctio_errno, fcioErrorString); 477fcf3ce44SJohn Forte log.genericIOError("ioctl (0x%x) failed. Transport: \"%s\"", cmd, 478fcf3ce44SJohn Forte fcioErrorString); 479fcf3ce44SJohn Forte switch (fctio->fctio_errno) { 480fcf3ce44SJohn Forte case FC_BADWWN: 481fcf3ce44SJohn Forte throw IllegalWWNException(); 482fcf3ce44SJohn Forte case FC_BADPORT: 483fcf3ce44SJohn Forte throw IllegalWWNException(); 484fcf3ce44SJohn Forte case FC_OUTOFBOUNDS: 485fcf3ce44SJohn Forte throw IllegalIndexException(); 486fcf3ce44SJohn Forte case FC_PBUSY: 487fcf3ce44SJohn Forte case FC_FBUSY: 488fcf3ce44SJohn Forte case FC_TRAN_BUSY: 489fcf3ce44SJohn Forte case FC_STATEC_BUSY: 490fcf3ce44SJohn Forte case FC_DEVICE_BUSY: 491fcf3ce44SJohn Forte throw BusyException(); 492fcf3ce44SJohn Forte case FC_SUCCESS: 493fcf3ce44SJohn Forte default: 494fcf3ce44SJohn Forte throw; 495fcf3ce44SJohn Forte } 496fcf3ce44SJohn Forte } 497fcf3ce44SJohn Forte } 498