1*fcf3ce44SJohn Forte /* 2*fcf3ce44SJohn Forte * CDDL HEADER START 3*fcf3ce44SJohn Forte * 4*fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the 5*fcf3ce44SJohn Forte * Common Development and Distribution License (the "License"). 6*fcf3ce44SJohn Forte * You may not use this file except in compliance with the License. 7*fcf3ce44SJohn Forte * 8*fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing. 10*fcf3ce44SJohn Forte * See the License for the specific language governing permissions 11*fcf3ce44SJohn Forte * and limitations under the License. 12*fcf3ce44SJohn Forte * 13*fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 14*fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 16*fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 17*fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 18*fcf3ce44SJohn Forte * 19*fcf3ce44SJohn Forte * CDDL HEADER END 20*fcf3ce44SJohn Forte */ 21*fcf3ce44SJohn Forte /* 22*fcf3ce44SJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23*fcf3ce44SJohn Forte * Use is subject to license terms. 24*fcf3ce44SJohn Forte */ 25*fcf3ce44SJohn Forte 26*fcf3ce44SJohn Forte 27*fcf3ce44SJohn Forte #include "FCHBANPIVPort.h" 28*fcf3ce44SJohn Forte #include <Exceptions.h> 29*fcf3ce44SJohn Forte #include <Trace.h> 30*fcf3ce44SJohn Forte #include <sun_fc.h> 31*fcf3ce44SJohn Forte #include <iostream> 32*fcf3ce44SJohn Forte #include <iomanip> 33*fcf3ce44SJohn Forte #include <sys/types.h> 34*fcf3ce44SJohn Forte #include <sys/mkdev.h> 35*fcf3ce44SJohn Forte #include <sys/stat.h> 36*fcf3ce44SJohn Forte #include <fcntl.h> 37*fcf3ce44SJohn Forte #include <unistd.h> 38*fcf3ce44SJohn Forte #include <stropts.h> 39*fcf3ce44SJohn Forte #include <dirent.h> 40*fcf3ce44SJohn Forte #include <sys/fibre-channel/fc.h> 41*fcf3ce44SJohn Forte #include <sys/fibre-channel/fcio.h> 42*fcf3ce44SJohn Forte #include <sys/fibre-channel/ulp/fcp_util.h> 43*fcf3ce44SJohn Forte #include <sys/fibre-channel/ulp/fcsm.h> 44*fcf3ce44SJohn Forte #include <sys/fibre-channel/impl/fc_error.h> 45*fcf3ce44SJohn Forte #include <sys/fibre-channel/fc_appif.h> 46*fcf3ce44SJohn Forte #include <sys/scsi/generic/commands.h> 47*fcf3ce44SJohn Forte #include <sys/scsi/impl/commands.h> 48*fcf3ce44SJohn Forte #include <sys/scsi/impl/sense.h> 49*fcf3ce44SJohn Forte #include <sys/scsi/generic/inquiry.h> 50*fcf3ce44SJohn Forte #include <sys/scsi/generic/status.h> 51*fcf3ce44SJohn Forte #include <errno.h> 52*fcf3ce44SJohn Forte 53*fcf3ce44SJohn Forte using namespace std; 54*fcf3ce44SJohn Forte 55*fcf3ce44SJohn Forte const int FCHBANPIVPort::MAX_FCIO_MSG_LEN = 256; 56*fcf3ce44SJohn Forte 57*fcf3ce44SJohn Forte FCHBANPIVPort::FCHBANPIVPort(string thePath) : HBANPIVPort() { 58*fcf3ce44SJohn Forte Trace log("FCHBANPIVPort::FCHBANPIVPort"); 59*fcf3ce44SJohn Forte log.debug("Initializing HBA NPIV port %s", thePath.c_str()); 60*fcf3ce44SJohn Forte 61*fcf3ce44SJohn Forte try { 62*fcf3ce44SJohn Forte path = lookupControllerPath(thePath); 63*fcf3ce44SJohn Forte } catch (...) { 64*fcf3ce44SJohn Forte log.debug("Unable to lookup controller path and number for %s", 65*fcf3ce44SJohn Forte thePath.c_str()); 66*fcf3ce44SJohn Forte path = "/devices"; 67*fcf3ce44SJohn Forte path += thePath; 68*fcf3ce44SJohn Forte path += ":fc"; 69*fcf3ce44SJohn Forte } 70*fcf3ce44SJohn Forte 71*fcf3ce44SJohn Forte uint64_t tmp; 72*fcf3ce44SJohn Forte HBA_NPIVATTRIBUTES attrs = getPortAttributes(tmp); 73*fcf3ce44SJohn Forte memcpy(&tmp, &attrs.PortWWN, 8); 74*fcf3ce44SJohn Forte portWWN = ntohll(tmp); 75*fcf3ce44SJohn Forte memcpy(&tmp, &attrs.NodeWWN, 8); 76*fcf3ce44SJohn Forte nodeWWN = ntohll(tmp); 77*fcf3ce44SJohn Forte } 78*fcf3ce44SJohn Forte 79*fcf3ce44SJohn Forte 80*fcf3ce44SJohn Forte HBA_NPIVATTRIBUTES FCHBANPIVPort::getPortAttributes(uint64_t &stateChange) { 81*fcf3ce44SJohn Forte Trace log("FCHBANPIVPort::getPortAttributes"); 82*fcf3ce44SJohn Forte 83*fcf3ce44SJohn Forte HBA_NPIVATTRIBUTES attributes; 84*fcf3ce44SJohn Forte fcio_t fcio; 85*fcf3ce44SJohn Forte fc_hba_npiv_attributes_t attrs; 86*fcf3ce44SJohn Forte 87*fcf3ce44SJohn Forte memset(&fcio, 0, sizeof (fcio)); 88*fcf3ce44SJohn Forte memset(&attributes, 0, sizeof (attributes)); 89*fcf3ce44SJohn Forte fcio.fcio_cmd = FCIO_GET_NPIV_ATTRIBUTES; 90*fcf3ce44SJohn Forte fcio.fcio_olen = sizeof (attrs); 91*fcf3ce44SJohn Forte fcio.fcio_xfer = FCIO_XFER_READ; 92*fcf3ce44SJohn Forte fcio.fcio_obuf = (caddr_t)&attrs; 93*fcf3ce44SJohn Forte fp_ioctl(getPath(), FCIO_CMD, &fcio); 94*fcf3ce44SJohn Forte 95*fcf3ce44SJohn Forte stateChange = attrs.lastChange; 96*fcf3ce44SJohn Forte memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8); 97*fcf3ce44SJohn Forte memcpy(&attributes.PortWWN, &attrs.PortWWN, 8); 98*fcf3ce44SJohn Forte 99*fcf3ce44SJohn Forte return (attributes); 100*fcf3ce44SJohn Forte } 101*fcf3ce44SJohn Forte 102*fcf3ce44SJohn Forte 103*fcf3ce44SJohn Forte void FCHBANPIVPort::fp_ioctl(string path, int cmd, fcio_t *fcio) { 104*fcf3ce44SJohn Forte Trace log("FCHBANPIVPort::fp_ioctl"); 105*fcf3ce44SJohn Forte 106*fcf3ce44SJohn Forte char fcioErrorString[MAX_FCIO_MSG_LEN] = ""; 107*fcf3ce44SJohn Forte int fd = HBA::_open(path, O_NDELAY | O_RDONLY); 108*fcf3ce44SJohn Forte 109*fcf3ce44SJohn Forte try { 110*fcf3ce44SJohn Forte int times = 0; 111*fcf3ce44SJohn Forte HBA::_ioctl(fd, cmd, (uchar_t *)fcio); 112*fcf3ce44SJohn Forte while (fcio->fcio_errno == FC_STATEC_BUSY) { 113*fcf3ce44SJohn Forte (void) sleep(2); 114*fcf3ce44SJohn Forte HBA::_ioctl(fd, cmd, (uchar_t *)fcio); 115*fcf3ce44SJohn Forte if (times++ > 20) { 116*fcf3ce44SJohn Forte break; 117*fcf3ce44SJohn Forte } 118*fcf3ce44SJohn Forte } 119*fcf3ce44SJohn Forte close(fd); 120*fcf3ce44SJohn Forte if (fcio->fcio_errno) { 121*fcf3ce44SJohn Forte throw IOError("IOCTL transport failure"); 122*fcf3ce44SJohn Forte } 123*fcf3ce44SJohn Forte } catch (...) { 124*fcf3ce44SJohn Forte close(fd); 125*fcf3ce44SJohn Forte transportError(fcio->fcio_errno, fcioErrorString); 126*fcf3ce44SJohn Forte log.genericIOError("NPIV Port ioctl (0x%x) failed. Transport: \"%s\"", cmd, 127*fcf3ce44SJohn Forte fcioErrorString); 128*fcf3ce44SJohn Forte switch (fcio->fcio_errno) { 129*fcf3ce44SJohn Forte case FC_BADWWN: 130*fcf3ce44SJohn Forte throw IllegalWWNException(); 131*fcf3ce44SJohn Forte case FC_BADPORT: 132*fcf3ce44SJohn Forte throw IllegalWWNException(); 133*fcf3ce44SJohn Forte case FC_OUTOFBOUNDS: 134*fcf3ce44SJohn Forte throw IllegalIndexException(); 135*fcf3ce44SJohn Forte case FC_PBUSY: 136*fcf3ce44SJohn Forte case FC_FBUSY: 137*fcf3ce44SJohn Forte case FC_TRAN_BUSY: 138*fcf3ce44SJohn Forte case FC_STATEC_BUSY: 139*fcf3ce44SJohn Forte case FC_DEVICE_BUSY: 140*fcf3ce44SJohn Forte throw BusyException(); 141*fcf3ce44SJohn Forte case FC_SUCCESS: 142*fcf3ce44SJohn Forte default: 143*fcf3ce44SJohn Forte throw; 144*fcf3ce44SJohn Forte } 145*fcf3ce44SJohn Forte } 146*fcf3ce44SJohn Forte } 147*fcf3ce44SJohn Forte 148*fcf3ce44SJohn Forte 149*fcf3ce44SJohn Forte /* 150*fcf3ce44SJohn Forte * Interpret the error code in the fcio_t structure 151*fcf3ce44SJohn Forte * 152*fcf3ce44SJohn Forte * message must be at least MAX_FCIO_MSG_LEN in length. 153*fcf3ce44SJohn Forte */ 154*fcf3ce44SJohn Forte void 155*fcf3ce44SJohn Forte FCHBANPIVPort::transportError(uint32_t fcio_errno, char *message) { 156*fcf3ce44SJohn Forte Trace log("transportError"); 157*fcf3ce44SJohn Forte 158*fcf3ce44SJohn Forte string fcioErrorString; 159*fcf3ce44SJohn Forte if (message == NULL) { 160*fcf3ce44SJohn Forte log.internalError("NULL routine argument"); 161*fcf3ce44SJohn Forte return; 162*fcf3ce44SJohn Forte } 163*fcf3ce44SJohn Forte switch (fcio_errno) { 164*fcf3ce44SJohn Forte case (uint32_t)FC_FAILURE: 165*fcf3ce44SJohn Forte fcioErrorString = "general failure"; 166*fcf3ce44SJohn Forte break; 167*fcf3ce44SJohn Forte case (uint32_t)FC_FAILURE_SILENT: 168*fcf3ce44SJohn Forte fcioErrorString = "general failure but fail silently"; 169*fcf3ce44SJohn Forte break; 170*fcf3ce44SJohn Forte case FC_SUCCESS: 171*fcf3ce44SJohn Forte fcioErrorString = "successful completion"; 172*fcf3ce44SJohn Forte break; 173*fcf3ce44SJohn Forte case FC_CAP_ERROR: 174*fcf3ce44SJohn Forte fcioErrorString = "FCA capability error"; 175*fcf3ce44SJohn Forte break; 176*fcf3ce44SJohn Forte case FC_CAP_FOUND: 177*fcf3ce44SJohn Forte fcioErrorString = "FCA capability unsettable"; 178*fcf3ce44SJohn Forte break; 179*fcf3ce44SJohn Forte case FC_CAP_SETTABLE: 180*fcf3ce44SJohn Forte fcioErrorString = "FCA capability settable"; 181*fcf3ce44SJohn Forte break; 182*fcf3ce44SJohn Forte case FC_UNBOUND: 183*fcf3ce44SJohn Forte fcioErrorString = "unbound stuff"; 184*fcf3ce44SJohn Forte break; 185*fcf3ce44SJohn Forte case FC_NOMEM: 186*fcf3ce44SJohn Forte fcioErrorString = "allocation error"; 187*fcf3ce44SJohn Forte break; 188*fcf3ce44SJohn Forte case FC_BADPACKET: 189*fcf3ce44SJohn Forte fcioErrorString = "invalid packet specified/supplied"; 190*fcf3ce44SJohn Forte break; 191*fcf3ce44SJohn Forte case FC_OFFLINE: 192*fcf3ce44SJohn Forte fcioErrorString = "I/O resource unavailable"; 193*fcf3ce44SJohn Forte break; 194*fcf3ce44SJohn Forte case FC_OLDPORT: 195*fcf3ce44SJohn Forte fcioErrorString = "operation on non-loop port"; 196*fcf3ce44SJohn Forte break; 197*fcf3ce44SJohn Forte case FC_NO_MAP: 198*fcf3ce44SJohn Forte fcioErrorString = "requested map unavailable"; 199*fcf3ce44SJohn Forte break; 200*fcf3ce44SJohn Forte case FC_TRANSPORT_ERROR: 201*fcf3ce44SJohn Forte fcioErrorString = "unable to transport I/O"; 202*fcf3ce44SJohn Forte break; 203*fcf3ce44SJohn Forte case FC_ELS_FREJECT: 204*fcf3ce44SJohn Forte fcioErrorString = "ELS rejected by a Fabric"; 205*fcf3ce44SJohn Forte break; 206*fcf3ce44SJohn Forte case FC_ELS_PREJECT: 207*fcf3ce44SJohn Forte fcioErrorString = "ELS rejected by an N_port"; 208*fcf3ce44SJohn Forte break; 209*fcf3ce44SJohn Forte case FC_ELS_BAD: 210*fcf3ce44SJohn Forte fcioErrorString = "ELS rejected by FCA/fctl"; 211*fcf3ce44SJohn Forte break; 212*fcf3ce44SJohn Forte case FC_ELS_MALFORMED: 213*fcf3ce44SJohn Forte fcioErrorString = "poorly formed ELS request"; 214*fcf3ce44SJohn Forte break; 215*fcf3ce44SJohn Forte case FC_TOOMANY: 216*fcf3ce44SJohn Forte fcioErrorString = "resource request too large"; 217*fcf3ce44SJohn Forte break; 218*fcf3ce44SJohn Forte case FC_UB_BADTOKEN: 219*fcf3ce44SJohn Forte fcioErrorString = "invalid unsolicited buffer token"; 220*fcf3ce44SJohn Forte break; 221*fcf3ce44SJohn Forte case FC_UB_ERROR: 222*fcf3ce44SJohn Forte fcioErrorString = "invalid unsol buf request"; 223*fcf3ce44SJohn Forte break; 224*fcf3ce44SJohn Forte case FC_UB_BUSY: 225*fcf3ce44SJohn Forte fcioErrorString = "buffer already in use"; 226*fcf3ce44SJohn Forte break; 227*fcf3ce44SJohn Forte case FC_BADULP: 228*fcf3ce44SJohn Forte fcioErrorString = "Unknown ulp"; 229*fcf3ce44SJohn Forte break; 230*fcf3ce44SJohn Forte case FC_BADTYPE: 231*fcf3ce44SJohn Forte fcioErrorString = "ULP not registered to handle this FC4 type"; 232*fcf3ce44SJohn Forte break; 233*fcf3ce44SJohn Forte case FC_UNCLAIMED: 234*fcf3ce44SJohn Forte fcioErrorString = "request or data not claimed"; 235*fcf3ce44SJohn Forte break; 236*fcf3ce44SJohn Forte case FC_ULP_SAMEMODULE: 237*fcf3ce44SJohn Forte fcioErrorString = "module already in use"; 238*fcf3ce44SJohn Forte break; 239*fcf3ce44SJohn Forte case FC_ULP_SAMETYPE: 240*fcf3ce44SJohn Forte fcioErrorString = "FC4 module already in use"; 241*fcf3ce44SJohn Forte break; 242*fcf3ce44SJohn Forte case FC_ABORTED: 243*fcf3ce44SJohn Forte fcioErrorString = "request aborted"; 244*fcf3ce44SJohn Forte break; 245*fcf3ce44SJohn Forte case FC_ABORT_FAILED: 246*fcf3ce44SJohn Forte fcioErrorString = "abort request failed"; 247*fcf3ce44SJohn Forte break; 248*fcf3ce44SJohn Forte case FC_BADEXCHANGE: 249*fcf3ce44SJohn Forte fcioErrorString = "exchange doesn\325t exist"; 250*fcf3ce44SJohn Forte break; 251*fcf3ce44SJohn Forte case FC_BADWWN: 252*fcf3ce44SJohn Forte fcioErrorString = "WWN not recognized"; 253*fcf3ce44SJohn Forte break; 254*fcf3ce44SJohn Forte case FC_BADDEV: 255*fcf3ce44SJohn Forte fcioErrorString = "device unrecognized"; 256*fcf3ce44SJohn Forte break; 257*fcf3ce44SJohn Forte case FC_BADCMD: 258*fcf3ce44SJohn Forte fcioErrorString = "invalid command issued"; 259*fcf3ce44SJohn Forte break; 260*fcf3ce44SJohn Forte case FC_BADOBJECT: 261*fcf3ce44SJohn Forte fcioErrorString = "invalid object requested"; 262*fcf3ce44SJohn Forte break; 263*fcf3ce44SJohn Forte case FC_BADPORT: 264*fcf3ce44SJohn Forte fcioErrorString = "invalid port specified"; 265*fcf3ce44SJohn Forte break; 266*fcf3ce44SJohn Forte case FC_NOTTHISPORT: 267*fcf3ce44SJohn Forte fcioErrorString = "resource not at this port"; 268*fcf3ce44SJohn Forte break; 269*fcf3ce44SJohn Forte case FC_PREJECT: 270*fcf3ce44SJohn Forte fcioErrorString = "reject at remote N_Port"; 271*fcf3ce44SJohn Forte break; 272*fcf3ce44SJohn Forte case FC_FREJECT: 273*fcf3ce44SJohn Forte fcioErrorString = "reject at remote Fabric"; 274*fcf3ce44SJohn Forte break; 275*fcf3ce44SJohn Forte case FC_PBUSY: 276*fcf3ce44SJohn Forte fcioErrorString = "remote N_Port busy"; 277*fcf3ce44SJohn Forte break; 278*fcf3ce44SJohn Forte case FC_FBUSY: 279*fcf3ce44SJohn Forte fcioErrorString = "remote Fabric busy"; 280*fcf3ce44SJohn Forte break; 281*fcf3ce44SJohn Forte case FC_ALREADY: 282*fcf3ce44SJohn Forte fcioErrorString = "already logged in"; 283*fcf3ce44SJohn Forte break; 284*fcf3ce44SJohn Forte case FC_LOGINREQ: 285*fcf3ce44SJohn Forte fcioErrorString = "login required"; 286*fcf3ce44SJohn Forte break; 287*fcf3ce44SJohn Forte case FC_RESETFAIL: 288*fcf3ce44SJohn Forte fcioErrorString = "reset failed"; 289*fcf3ce44SJohn Forte break; 290*fcf3ce44SJohn Forte case FC_INVALID_REQUEST: 291*fcf3ce44SJohn Forte fcioErrorString = "request is invalid"; 292*fcf3ce44SJohn Forte break; 293*fcf3ce44SJohn Forte case FC_OUTOFBOUNDS: 294*fcf3ce44SJohn Forte fcioErrorString = "port number is out of bounds"; 295*fcf3ce44SJohn Forte break; 296*fcf3ce44SJohn Forte case FC_TRAN_BUSY: 297*fcf3ce44SJohn Forte fcioErrorString = "command transport busy"; 298*fcf3ce44SJohn Forte break; 299*fcf3ce44SJohn Forte case FC_STATEC_BUSY: 300*fcf3ce44SJohn Forte fcioErrorString = "port driver currently busy"; 301*fcf3ce44SJohn Forte break; 302*fcf3ce44SJohn Forte case FC_DEVICE_BUSY: 303*fcf3ce44SJohn Forte fcioErrorString = "transport working on this device"; 304*fcf3ce44SJohn Forte break; 305*fcf3ce44SJohn Forte case FC_DEVICE_NOT_TGT: 306*fcf3ce44SJohn Forte fcioErrorString = "device is not a SCSI target"; 307*fcf3ce44SJohn Forte break; 308*fcf3ce44SJohn Forte default: 309*fcf3ce44SJohn Forte snprintf(message, MAX_FCIO_MSG_LEN, "Unknown error code 0x%x", 310*fcf3ce44SJohn Forte fcio_errno); 311*fcf3ce44SJohn Forte return; 312*fcf3ce44SJohn Forte } 313*fcf3ce44SJohn Forte snprintf(message, MAX_FCIO_MSG_LEN, "%s", fcioErrorString.c_str()); 314*fcf3ce44SJohn Forte } 315*fcf3ce44SJohn Forte 316