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 /* 22a7949318SReed * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23fcf3ce44SJohn Forte * Use is subject to license terms. 24fcf3ce44SJohn Forte */ 25fcf3ce44SJohn Forte 26fcf3ce44SJohn Forte 27fcf3ce44SJohn Forte #include <unistd.h> 28fcf3ce44SJohn Forte 29fcf3ce44SJohn Forte #include <FCHBA.h> 30fcf3ce44SJohn Forte #include <Exceptions.h> 31fcf3ce44SJohn Forte #include <Trace.h> 32fcf3ce44SJohn Forte #include <iostream> 33fcf3ce44SJohn Forte #include <iomanip> 34fcf3ce44SJohn Forte #include <cerrno> 35fcf3ce44SJohn Forte #include <cstring> 36fcf3ce44SJohn Forte #include <sys/types.h> 37fcf3ce44SJohn Forte #include <sys/stat.h> 38fcf3ce44SJohn Forte #include <fcntl.h> 39fcf3ce44SJohn Forte #include <unistd.h> 40fcf3ce44SJohn Forte #include <stropts.h> 41fcf3ce44SJohn Forte #include <sys/fibre-channel/fcio.h> 42fcf3ce44SJohn Forte #include <sys/fibre-channel/ulp/fcsm.h> 43fcf3ce44SJohn Forte #include <FCHBAPort.h> 44fcf3ce44SJohn Forte #include <HBAList.h> 45fcf3ce44SJohn Forte 461770502eSYu Renia Miao #define EXCPT_RETRY_COUNT 10 471770502eSYu Renia Miao 48fcf3ce44SJohn Forte using namespace std; 49fcf3ce44SJohn Forte const string FCHBA::FCSM_DRIVER_PATH = "/devices/pseudo/fcsm@0:fcsm"; 50fcf3ce44SJohn Forte const string FCHBA::FCSM_DRIVER_PKG = "SUNWfcsm"; 51fcf3ce44SJohn Forte const int FCHBA::MAX_FCIO_MSG_LEN = 256; 52fcf3ce44SJohn Forte 53fcf3ce44SJohn Forte FCHBA::FCHBA(string path) : HBA() { 54fcf3ce44SJohn Forte Trace log("FCHBA::FCHBA"); 55fcf3ce44SJohn Forte log.debug("Constructing new HBA (%s)", path.c_str()); 56fcf3ce44SJohn Forte 57fcf3ce44SJohn Forte // Add first port 58fcf3ce44SJohn Forte addPort(new FCHBAPort(path)); 59fcf3ce44SJohn Forte 60fcf3ce44SJohn Forte name = "INTERNAL-FAILURE"; // Just in case things go wrong 61fcf3ce44SJohn Forte try { 62fcf3ce44SJohn Forte HBA_ADAPTERATTRIBUTES attrs = getHBAAttributes(); 63fcf3ce44SJohn Forte name = attrs.Manufacturer; 64fcf3ce44SJohn Forte name += "-"; 65fcf3ce44SJohn Forte name += attrs.Model; 66fcf3ce44SJohn Forte 67fcf3ce44SJohn Forte // Grab any other ports on this adapter 68fcf3ce44SJohn Forte for (int i = 1; i < attrs.NumberOfPorts; i++) { 69fcf3ce44SJohn Forte fcio_t fcio; 70fcf3ce44SJohn Forte int fd; 71fcf3ce44SJohn Forte char nextPath[MAXPATHLEN]; 72fcf3ce44SJohn Forte 73fcf3ce44SJohn Forte log.debug("Fetching other port %d", i); 74fcf3ce44SJohn Forte 75fcf3ce44SJohn Forte // construct fcio struct 76fcf3ce44SJohn Forte memset(&fcio, 0, sizeof (fcio_t)); 77fcf3ce44SJohn Forte memset(nextPath, 0, sizeof (nextPath)); 78fcf3ce44SJohn Forte fcio.fcio_cmd = FCIO_GET_OTHER_ADAPTER_PORTS; 79fcf3ce44SJohn Forte fcio.fcio_xfer = FCIO_XFER_RW; 80fcf3ce44SJohn Forte 81fcf3ce44SJohn Forte fcio.fcio_olen = MAXPATHLEN; 82fcf3ce44SJohn Forte fcio.fcio_obuf = (char *)nextPath; 83fcf3ce44SJohn Forte fcio.fcio_ilen = sizeof (i); 84fcf3ce44SJohn Forte fcio.fcio_ibuf = (char *)&i; 85fcf3ce44SJohn Forte 86fcf3ce44SJohn Forte // open the fcsm node so we can send the ioctl to 87fcf3ce44SJohn Forte errno = 0; 88fcf3ce44SJohn Forte HBAPort *port = getPortByIndex(0); 89fcf3ce44SJohn Forte if ((fd = open(port->getPath().c_str(), O_NDELAY | O_RDONLY)) == 90fcf3ce44SJohn Forte -1) { 91fcf3ce44SJohn Forte log.debug("Unable to open %d opened (%s)", i, 92fcf3ce44SJohn Forte port->getPath().c_str()); 93fcf3ce44SJohn Forte if (errno == EBUSY) { 94fcf3ce44SJohn Forte throw BusyException(); 95fcf3ce44SJohn Forte } else if (errno == EAGAIN) { 96fcf3ce44SJohn Forte throw TryAgainException(); 97fcf3ce44SJohn Forte } else if (errno == ENOTSUP) { 98fcf3ce44SJohn Forte throw NotSupportedException(); 99fcf3ce44SJohn Forte } else if (errno == ENOENT) { 100fcf3ce44SJohn Forte throw UnavailableException(); 101fcf3ce44SJohn Forte } else { 102fcf3ce44SJohn Forte throw IOError("Unable to open FCSM driver"); 103fcf3ce44SJohn Forte } 104fcf3ce44SJohn Forte } 105fcf3ce44SJohn Forte log.debug("Other port %d opened", i); 106fcf3ce44SJohn Forte 107fcf3ce44SJohn Forte errno = 0; 108fcf3ce44SJohn Forte if (ioctl(fd, FCIO_CMD, &fcio) != 0) { 109fcf3ce44SJohn Forte // Interpret the fcio error code 110fcf3ce44SJohn Forte char fcioErrorString[MAX_FCIO_MSG_LEN] = ""; 111fcf3ce44SJohn Forte 112fcf3ce44SJohn Forte log.genericIOError( 113fcf3ce44SJohn Forte "ADAPTER_LIST failed: " 114fcf3ce44SJohn Forte "Errno: \"%s\"", 115fcf3ce44SJohn Forte strerror(errno)); 116fcf3ce44SJohn Forte close(fd); 117fcf3ce44SJohn Forte if (errno == EBUSY) { 118fcf3ce44SJohn Forte throw BusyException(); 119fcf3ce44SJohn Forte } else if (errno == EAGAIN) { 120fcf3ce44SJohn Forte throw TryAgainException(); 121fcf3ce44SJohn Forte } else if (errno == ENOTSUP) { 122fcf3ce44SJohn Forte throw NotSupportedException(); 123fcf3ce44SJohn Forte } else if (errno == ENOENT) { 124fcf3ce44SJohn Forte throw UnavailableException(); 125fcf3ce44SJohn Forte } else { 126fcf3ce44SJohn Forte throw IOError("Unable to build HBA list"); 127fcf3ce44SJohn Forte } 128fcf3ce44SJohn Forte } 129fcf3ce44SJohn Forte close(fd); 130fcf3ce44SJohn Forte log.debug("About to add port %d (%s)", i, nextPath); 131fcf3ce44SJohn Forte addPort(new FCHBAPort(nextPath)); 132fcf3ce44SJohn Forte } 1331770502eSYu Renia Miao } catch (BusyException &e) { 1341770502eSYu Renia Miao throw e; 1351770502eSYu Renia Miao } catch (TryAgainException &e) { 1361770502eSYu Renia Miao throw e; 1371770502eSYu Renia Miao } catch (UnavailableException &e) { 1381770502eSYu Renia Miao throw e; 139fcf3ce44SJohn Forte } catch (HBAException &e) { 140fcf3ce44SJohn Forte log.internalError( 141fcf3ce44SJohn Forte "Unable to construct HBA."); 142fcf3ce44SJohn Forte throw e; 143fcf3ce44SJohn Forte } 144fcf3ce44SJohn Forte } 145fcf3ce44SJohn Forte 146fcf3ce44SJohn Forte std::string FCHBA::getName() { 147fcf3ce44SJohn Forte Trace log("FCHBA::getName"); 148fcf3ce44SJohn Forte return (name); 149fcf3ce44SJohn Forte } 150fcf3ce44SJohn Forte 151fcf3ce44SJohn Forte HBA_ADAPTERATTRIBUTES FCHBA::getHBAAttributes() { 152fcf3ce44SJohn Forte Trace log("FCHBA::getHBAAttributes"); 153fcf3ce44SJohn Forte int fd; 154fcf3ce44SJohn Forte 155fcf3ce44SJohn Forte errno = 0; 156fcf3ce44SJohn Forte HBAPort *port = getPortByIndex(0); 157fcf3ce44SJohn Forte if ((fd = open(port->getPath().c_str(), O_NDELAY | O_RDONLY)) == -1) { 158fcf3ce44SJohn Forte // Why did we fail? 159fcf3ce44SJohn Forte if (errno == EBUSY) { 160fcf3ce44SJohn Forte throw BusyException(); 161fcf3ce44SJohn Forte } else if (errno == EAGAIN) { 162fcf3ce44SJohn Forte throw TryAgainException(); 163fcf3ce44SJohn Forte } else if (errno == ENOTSUP) { 164fcf3ce44SJohn Forte throw NotSupportedException(); 165fcf3ce44SJohn Forte } else { 166fcf3ce44SJohn Forte throw IOError(port); 167fcf3ce44SJohn Forte } 168fcf3ce44SJohn Forte } 169fcf3ce44SJohn Forte 170fcf3ce44SJohn Forte HBA_ADAPTERATTRIBUTES attributes; 171fcf3ce44SJohn Forte fcio_t fcio; 172fcf3ce44SJohn Forte fc_hba_adapter_attributes_t attrs; 173fcf3ce44SJohn Forte 174fcf3ce44SJohn Forte memset(&fcio, 0, sizeof (fcio)); 175fcf3ce44SJohn Forte 176fcf3ce44SJohn Forte fcio.fcio_cmd = FCIO_GET_ADAPTER_ATTRIBUTES; 177fcf3ce44SJohn Forte fcio.fcio_olen = sizeof (attrs); 178fcf3ce44SJohn Forte fcio.fcio_xfer = FCIO_XFER_READ; 179fcf3ce44SJohn Forte fcio.fcio_obuf = (caddr_t)&attrs; 180fcf3ce44SJohn Forte 181fcf3ce44SJohn Forte 182fcf3ce44SJohn Forte errno = 0; 183fcf3ce44SJohn Forte if (ioctl(fd, FCIO_CMD, &fcio) != 0) { 184fcf3ce44SJohn Forte close(fd); 185fcf3ce44SJohn Forte if (errno == EBUSY) { 186fcf3ce44SJohn Forte throw BusyException(); 187fcf3ce44SJohn Forte } else if (errno == EAGAIN) { 188fcf3ce44SJohn Forte throw TryAgainException(); 189fcf3ce44SJohn Forte } else if (errno == ENOTSUP) { 190fcf3ce44SJohn Forte throw NotSupportedException(); 191fcf3ce44SJohn Forte } else { 192fcf3ce44SJohn Forte throw IOError("Unable to fetch adapter attributes"); 193fcf3ce44SJohn Forte } 194fcf3ce44SJohn Forte } 195fcf3ce44SJohn Forte close(fd); 196fcf3ce44SJohn Forte 197fcf3ce44SJohn Forte /* Now copy over the payload */ 198fcf3ce44SJohn Forte attributes.NumberOfPorts = attrs.NumberOfPorts; 199fcf3ce44SJohn Forte attributes.VendorSpecificID = attrs.VendorSpecificID; 200fcf3ce44SJohn Forte memcpy(attributes.Manufacturer, attrs.Manufacturer, 64); 201fcf3ce44SJohn Forte memcpy(attributes.SerialNumber, attrs.SerialNumber, 64); 202fcf3ce44SJohn Forte memcpy(attributes.Model, attrs.Model, 256); 203fcf3ce44SJohn Forte memcpy(attributes.ModelDescription, attrs.ModelDescription, 256); 204fcf3ce44SJohn Forte memcpy(attributes.NodeSymbolicName, attrs.NodeSymbolicName, 256); 205fcf3ce44SJohn Forte memcpy(attributes.HardwareVersion, attrs.HardwareVersion, 256); 206fcf3ce44SJohn Forte memcpy(attributes.DriverVersion, attrs.DriverVersion, 256); 207fcf3ce44SJohn Forte memcpy(attributes.OptionROMVersion, attrs.OptionROMVersion, 256); 208fcf3ce44SJohn Forte memcpy(attributes.FirmwareVersion, attrs.FirmwareVersion, 256); 209fcf3ce44SJohn Forte memcpy(attributes.DriverName, attrs.DriverName, 256); 210fcf3ce44SJohn Forte memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8); 211fcf3ce44SJohn Forte 212fcf3ce44SJohn Forte return (attributes); 213fcf3ce44SJohn Forte } 214fcf3ce44SJohn Forte 215a7949318SReed int FCHBA::doForceLip() { 216a7949318SReed Trace log("FCHBA::doForceLip"); 217a7949318SReed int fd; 218a7949318SReed fcio_t fcio; 219a7949318SReed uint64_t wwn = 0; 220a7949318SReed HBAPort *port = getPortByIndex(0); 221a7949318SReed 222a7949318SReed errno = 0; 223a7949318SReed if ((fd = open(port->getPath().c_str(), O_RDONLY | O_EXCL)) == -1) { 224a7949318SReed if (errno == EBUSY) { 225a7949318SReed throw BusyException(); 226a7949318SReed } else if (errno == EAGAIN) { 227a7949318SReed throw TryAgainException(); 228a7949318SReed } else if (errno == ENOTSUP) { 229a7949318SReed throw NotSupportedException(); 230a7949318SReed } else { 231a7949318SReed throw IOError(port); 232a7949318SReed } 233a7949318SReed } 234a7949318SReed 235a7949318SReed memset(&fcio, 0, sizeof (fcio)); 236a7949318SReed fcio.fcio_cmd = FCIO_RESET_LINK; 237a7949318SReed fcio.fcio_xfer = FCIO_XFER_WRITE; 238a7949318SReed fcio.fcio_ilen = sizeof (wwn); 239a7949318SReed fcio.fcio_ibuf = (caddr_t)&wwn; 240a7949318SReed 241a7949318SReed errno = 0; 242a7949318SReed if (ioctl(fd, FCIO_CMD, &fcio) != 0) { 243a7949318SReed close(fd); 244a7949318SReed 245a7949318SReed if (errno == EBUSY) { 246a7949318SReed throw BusyException(); 247a7949318SReed } else if (errno == EAGAIN) { 248a7949318SReed throw TryAgainException(); 249a7949318SReed } else if (errno == ENOTSUP) { 250a7949318SReed throw NotSupportedException(); 251a7949318SReed } else { 252a7949318SReed throw IOError("Unable to reinitialize the link"); 253a7949318SReed } 254a7949318SReed } else { 255a7949318SReed close(fd); 256a7949318SReed return (fcio.fcio_errno); 257a7949318SReed } 258a7949318SReed } 259a7949318SReed 260fcf3ce44SJohn Forte HBA_ADAPTERATTRIBUTES FCHBA::npivGetHBAAttributes() { 261fcf3ce44SJohn Forte Trace log("FCHBA::npivGetHBAAttributes"); 262fcf3ce44SJohn Forte int fd; 263fcf3ce44SJohn Forte 264fcf3ce44SJohn Forte errno = 0; 265fcf3ce44SJohn Forte HBAPort *port = getPortByIndex(0); 266fcf3ce44SJohn Forte if ((fd = open(port->getPath().c_str(), O_NDELAY | O_RDONLY)) == -1) { 267fcf3ce44SJohn Forte // Why did we fail? 268fcf3ce44SJohn Forte if (errno == EBUSY) { 269fcf3ce44SJohn Forte throw BusyException(); 270fcf3ce44SJohn Forte } else if (errno == EAGAIN) { 271fcf3ce44SJohn Forte throw TryAgainException(); 272fcf3ce44SJohn Forte } else if (errno == ENOTSUP) { 273fcf3ce44SJohn Forte throw NotSupportedException(); 274fcf3ce44SJohn Forte } else { 275fcf3ce44SJohn Forte throw IOError(port); 276fcf3ce44SJohn Forte } 277fcf3ce44SJohn Forte } 278fcf3ce44SJohn Forte 279fcf3ce44SJohn Forte HBA_ADAPTERATTRIBUTES attributes; 280fcf3ce44SJohn Forte fcio_t fcio; 281fcf3ce44SJohn Forte fc_hba_adapter_attributes_t attrs; 282fcf3ce44SJohn Forte 283fcf3ce44SJohn Forte memset(&fcio, 0, sizeof (fcio)); 284fcf3ce44SJohn Forte fcio.fcio_cmd = FCIO_NPIV_GET_ADAPTER_ATTRIBUTES; 285fcf3ce44SJohn Forte fcio.fcio_olen = sizeof (attrs); 286fcf3ce44SJohn Forte fcio.fcio_xfer = FCIO_XFER_READ; 287fcf3ce44SJohn Forte fcio.fcio_obuf = (caddr_t)&attrs; 288fcf3ce44SJohn Forte errno = 0; 289fcf3ce44SJohn Forte 290fcf3ce44SJohn Forte if (ioctl(fd, FCIO_CMD, &fcio) != 0) { 291fcf3ce44SJohn Forte close(fd); 292fcf3ce44SJohn Forte if (errno == EBUSY) { 293fcf3ce44SJohn Forte throw BusyException(); 294fcf3ce44SJohn Forte } else if (errno == EAGAIN) { 295fcf3ce44SJohn Forte throw TryAgainException(); 296fcf3ce44SJohn Forte } else if (errno == ENOTSUP) { 297fcf3ce44SJohn Forte throw NotSupportedException(); 298fcf3ce44SJohn Forte } else { 299fcf3ce44SJohn Forte throw IOError("Unable to fetch adapter attributes"); 300fcf3ce44SJohn Forte } 301fcf3ce44SJohn Forte } 302fcf3ce44SJohn Forte close(fd); 303fcf3ce44SJohn Forte 304fcf3ce44SJohn Forte /* Now copy over the payload */ 305fcf3ce44SJohn Forte attributes.NumberOfPorts = attrs.NumberOfPorts; 306fcf3ce44SJohn Forte attributes.VendorSpecificID = attrs.VendorSpecificID; 307fcf3ce44SJohn Forte memcpy(attributes.Manufacturer, attrs.Manufacturer, 64); 308fcf3ce44SJohn Forte memcpy(attributes.SerialNumber, attrs.SerialNumber, 64); 309fcf3ce44SJohn Forte memcpy(attributes.Model, attrs.Model, 256); 310fcf3ce44SJohn Forte memcpy(attributes.ModelDescription, attrs.ModelDescription, 256); 311fcf3ce44SJohn Forte memcpy(attributes.NodeSymbolicName, attrs.NodeSymbolicName, 256); 312fcf3ce44SJohn Forte memcpy(attributes.HardwareVersion, attrs.HardwareVersion, 256); 313fcf3ce44SJohn Forte memcpy(attributes.DriverVersion, attrs.DriverVersion, 256); 314fcf3ce44SJohn Forte memcpy(attributes.OptionROMVersion, attrs.OptionROMVersion, 256); 315fcf3ce44SJohn Forte memcpy(attributes.FirmwareVersion, attrs.FirmwareVersion, 256); 316fcf3ce44SJohn Forte memcpy(attributes.DriverName, attrs.DriverName, 256); 317fcf3ce44SJohn Forte memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8); 318fcf3ce44SJohn Forte 319fcf3ce44SJohn Forte return (attributes); 320fcf3ce44SJohn Forte } 321fcf3ce44SJohn Forte 322fcf3ce44SJohn Forte void FCHBA::loadAdapters(vector<HBA*> &list) { 323fcf3ce44SJohn Forte Trace log("FCHBA::loadAdapters"); 324fcf3ce44SJohn Forte fcio_t fcio; 325fcf3ce44SJohn Forte fc_hba_list_t *pathList; 326fcf3ce44SJohn Forte int fd; 327fcf3ce44SJohn Forte int size = 64; // default first attempt 328fcf3ce44SJohn Forte bool retry = false; 329fcf3ce44SJohn Forte struct stat sb; 330fcf3ce44SJohn Forte int bufSize; 331fcf3ce44SJohn Forte 332fcf3ce44SJohn Forte /* Before we do anything, let's see if FCSM is on the system */ 333fcf3ce44SJohn Forte errno = 0; 334fcf3ce44SJohn Forte if (stat(FCSM_DRIVER_PATH.c_str(), &sb) != 0) { 335fcf3ce44SJohn Forte if (errno == ENOENT) { 336fcf3ce44SJohn Forte log.genericIOError( 337fcf3ce44SJohn Forte "The %s driver is not present. Unable to issue " 338fcf3ce44SJohn Forte "CT commands. Please install the %s package.", 339fcf3ce44SJohn Forte FCSM_DRIVER_PATH.c_str(), FCSM_DRIVER_PKG.c_str()); 340fcf3ce44SJohn Forte throw NotSupportedException(); 341fcf3ce44SJohn Forte } else { 342fcf3ce44SJohn Forte log.genericIOError( 343fcf3ce44SJohn Forte "Can not stat the %s driver for reason \"%s\" " 344fcf3ce44SJohn Forte "Unable to issue CT commands.", 345fcf3ce44SJohn Forte FCSM_DRIVER_PATH.c_str(), strerror(errno)); 346fcf3ce44SJohn Forte throw IOError("Unable to stat FCSM driver"); 347fcf3ce44SJohn Forte } 348fcf3ce44SJohn Forte } 349fcf3ce44SJohn Forte 350fcf3ce44SJohn Forte 351fcf3ce44SJohn Forte /* construct fcio struct */ 352fcf3ce44SJohn Forte memset(&fcio, 0, sizeof (fcio_t)); 353fcf3ce44SJohn Forte fcio.fcio_cmd = FCSMIO_ADAPTER_LIST; 354fcf3ce44SJohn Forte fcio.fcio_xfer = FCIO_XFER_RW; 355fcf3ce44SJohn Forte 356fcf3ce44SJohn Forte 357fcf3ce44SJohn Forte /* open the fcsm node so we can send the ioctl to */ 358fcf3ce44SJohn Forte errno = 0; 359fcf3ce44SJohn Forte if ((fd = open(FCSM_DRIVER_PATH.c_str(), O_RDONLY)) < 0) { 360fcf3ce44SJohn Forte if (errno == EBUSY) { 361fcf3ce44SJohn Forte throw BusyException(); 362fcf3ce44SJohn Forte } else if (errno == EAGAIN) { 363fcf3ce44SJohn Forte throw TryAgainException(); 364fcf3ce44SJohn Forte } else if (errno == ENOTSUP) { 365fcf3ce44SJohn Forte throw NotSupportedException(); 366fcf3ce44SJohn Forte } else if (errno == ENOENT) { 367fcf3ce44SJohn Forte throw UnavailableException(); 368fcf3ce44SJohn Forte } else { 369fcf3ce44SJohn Forte throw IOError("Unable to open FCSM driver"); 370fcf3ce44SJohn Forte } 371fcf3ce44SJohn Forte } 372fcf3ce44SJohn Forte 373fcf3ce44SJohn Forte do { 374fcf3ce44SJohn Forte retry = false; 375fcf3ce44SJohn Forte errno = 0; 376fcf3ce44SJohn Forte bufSize = MAXPATHLEN * size + (int) sizeof (fc_hba_list_t) - 1; 377fcf3ce44SJohn Forte pathList = (fc_hba_list_t *)new uchar_t[bufSize]; 378fcf3ce44SJohn Forte pathList->numAdapters = size; 379fcf3ce44SJohn Forte fcio.fcio_olen = bufSize; 380fcf3ce44SJohn Forte fcio.fcio_obuf = (char *)pathList; 381fcf3ce44SJohn Forte if (ioctl(fd, FCSMIO_CMD, &fcio) != 0) { 382fcf3ce44SJohn Forte /* Interpret the fcio error code */ 383fcf3ce44SJohn Forte char fcioErrorString[MAX_FCIO_MSG_LEN] = ""; 384fcf3ce44SJohn Forte 385fcf3ce44SJohn Forte log.genericIOError( 386fcf3ce44SJohn Forte "ADAPTER_LIST failed: " 387fcf3ce44SJohn Forte "Errno: \"%s\"", 388fcf3ce44SJohn Forte strerror(errno)); 389fcf3ce44SJohn Forte delete (pathList); 390fcf3ce44SJohn Forte close(fd); 391fcf3ce44SJohn Forte if (errno == EBUSY) { 392fcf3ce44SJohn Forte throw BusyException(); 393fcf3ce44SJohn Forte } else if (errno == EAGAIN) { 394fcf3ce44SJohn Forte throw TryAgainException(); 395fcf3ce44SJohn Forte } else if (errno == ENOTSUP) { 396fcf3ce44SJohn Forte throw NotSupportedException(); 397fcf3ce44SJohn Forte } else if (errno == ENOENT) { 398fcf3ce44SJohn Forte throw UnavailableException(); 399fcf3ce44SJohn Forte } else { 400fcf3ce44SJohn Forte throw IOError("Unable to build HBA list"); 401fcf3ce44SJohn Forte } 402fcf3ce44SJohn Forte } 403fcf3ce44SJohn Forte if (pathList->numAdapters > size) { 404fcf3ce44SJohn Forte log.debug( 405fcf3ce44SJohn Forte "Buffer too small for number of HBAs. Retrying."); 406fcf3ce44SJohn Forte size = pathList->numAdapters; 407fcf3ce44SJohn Forte retry = true; 408fcf3ce44SJohn Forte delete (pathList); 409fcf3ce44SJohn Forte } 410fcf3ce44SJohn Forte } while (retry); 411fcf3ce44SJohn Forte 412fcf3ce44SJohn Forte close(fd); 413fcf3ce44SJohn Forte log.debug("Detected %d adapters", pathList->numAdapters); 4141770502eSYu Renia Miao for (int i = 0, times =0; i < pathList->numAdapters;) { 415fcf3ce44SJohn Forte try { 416fcf3ce44SJohn Forte HBA *hba = new FCHBA(pathList->hbaPaths[i]); 417fcf3ce44SJohn Forte list.insert(list.begin(), hba); 4181770502eSYu Renia Miao i++; 4191770502eSYu Renia Miao } catch (BusyException &e) { 4201770502eSYu Renia Miao sleep(1); 4211770502eSYu Renia Miao if (times++ > EXCPT_RETRY_COUNT) { 4221770502eSYu Renia Miao i++; 4231770502eSYu Renia Miao times = 0; 4241770502eSYu Renia Miao } 4251770502eSYu Renia Miao continue; 4261770502eSYu Renia Miao } catch (TryAgainException &e) { 4271770502eSYu Renia Miao sleep(1); 4281770502eSYu Renia Miao if (times++ > EXCPT_RETRY_COUNT) { 4291770502eSYu Renia Miao i++; 4301770502eSYu Renia Miao times = 0; 4311770502eSYu Renia Miao } 4321770502eSYu Renia Miao continue; 4331770502eSYu Renia Miao } catch (UnavailableException &e) { 4341770502eSYu Renia Miao sleep(1); 4351770502eSYu Renia Miao if (times++ > EXCPT_RETRY_COUNT) { 4361770502eSYu Renia Miao i++; 4371770502eSYu Renia Miao times = 0; 4381770502eSYu Renia Miao } 4391770502eSYu Renia Miao continue; 4401770502eSYu Renia Miao } catch (HBAException &e) { 4411770502eSYu Renia Miao i++; 4421770502eSYu Renia Miao times = 0; 443fcf3ce44SJohn Forte log.debug( 444fcf3ce44SJohn Forte "Ignoring partial failure while loading an HBA"); 445fcf3ce44SJohn Forte } 446fcf3ce44SJohn Forte } 447fcf3ce44SJohn Forte if (pathList->numAdapters > HBAList::HBA_MAX_PER_LIST) { 448fcf3ce44SJohn Forte delete(pathList); 449fcf3ce44SJohn Forte throw InternalError( 450*0778188fSHengqing Hu "Exceeds max number of adapters that VSL supports."); 451fcf3ce44SJohn Forte } 452fcf3ce44SJohn Forte delete (pathList); 453fcf3ce44SJohn Forte } 454