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 /*
2210275SReed.Liu@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 #include <unistd.h>
287836SJohn.Forte@Sun.COM
297836SJohn.Forte@Sun.COM #include <FCHBA.h>
307836SJohn.Forte@Sun.COM #include <Exceptions.h>
317836SJohn.Forte@Sun.COM #include <Trace.h>
327836SJohn.Forte@Sun.COM #include <iostream>
337836SJohn.Forte@Sun.COM #include <iomanip>
347836SJohn.Forte@Sun.COM #include <cerrno>
357836SJohn.Forte@Sun.COM #include <cstring>
367836SJohn.Forte@Sun.COM #include <sys/types.h>
377836SJohn.Forte@Sun.COM #include <sys/stat.h>
387836SJohn.Forte@Sun.COM #include <fcntl.h>
397836SJohn.Forte@Sun.COM #include <unistd.h>
407836SJohn.Forte@Sun.COM #include <stropts.h>
417836SJohn.Forte@Sun.COM #include <sys/fibre-channel/fcio.h>
427836SJohn.Forte@Sun.COM #include <sys/fibre-channel/ulp/fcsm.h>
437836SJohn.Forte@Sun.COM #include <FCHBAPort.h>
447836SJohn.Forte@Sun.COM #include <HBAList.h>
457836SJohn.Forte@Sun.COM
46*11156SRenia.Miao@Sun.COM #define EXCPT_RETRY_COUNT 10
47*11156SRenia.Miao@Sun.COM
487836SJohn.Forte@Sun.COM using namespace std;
497836SJohn.Forte@Sun.COM const string FCHBA::FCSM_DRIVER_PATH = "/devices/pseudo/fcsm@0:fcsm";
507836SJohn.Forte@Sun.COM const string FCHBA::FCSM_DRIVER_PKG = "SUNWfcsm";
517836SJohn.Forte@Sun.COM const int FCHBA::MAX_FCIO_MSG_LEN = 256;
527836SJohn.Forte@Sun.COM
FCHBA(string path)537836SJohn.Forte@Sun.COM FCHBA::FCHBA(string path) : HBA() {
547836SJohn.Forte@Sun.COM Trace log("FCHBA::FCHBA");
557836SJohn.Forte@Sun.COM log.debug("Constructing new HBA (%s)", path.c_str());
567836SJohn.Forte@Sun.COM
577836SJohn.Forte@Sun.COM // Add first port
587836SJohn.Forte@Sun.COM addPort(new FCHBAPort(path));
597836SJohn.Forte@Sun.COM
607836SJohn.Forte@Sun.COM name = "INTERNAL-FAILURE"; // Just in case things go wrong
617836SJohn.Forte@Sun.COM try {
627836SJohn.Forte@Sun.COM HBA_ADAPTERATTRIBUTES attrs = getHBAAttributes();
637836SJohn.Forte@Sun.COM name = attrs.Manufacturer;
647836SJohn.Forte@Sun.COM name += "-";
657836SJohn.Forte@Sun.COM name += attrs.Model;
667836SJohn.Forte@Sun.COM
677836SJohn.Forte@Sun.COM // Grab any other ports on this adapter
687836SJohn.Forte@Sun.COM for (int i = 1; i < attrs.NumberOfPorts; i++) {
697836SJohn.Forte@Sun.COM fcio_t fcio;
707836SJohn.Forte@Sun.COM int fd;
717836SJohn.Forte@Sun.COM char nextPath[MAXPATHLEN];
727836SJohn.Forte@Sun.COM
737836SJohn.Forte@Sun.COM log.debug("Fetching other port %d", i);
747836SJohn.Forte@Sun.COM
757836SJohn.Forte@Sun.COM // construct fcio struct
767836SJohn.Forte@Sun.COM memset(&fcio, 0, sizeof (fcio_t));
777836SJohn.Forte@Sun.COM memset(nextPath, 0, sizeof (nextPath));
787836SJohn.Forte@Sun.COM fcio.fcio_cmd = FCIO_GET_OTHER_ADAPTER_PORTS;
797836SJohn.Forte@Sun.COM fcio.fcio_xfer = FCIO_XFER_RW;
807836SJohn.Forte@Sun.COM
817836SJohn.Forte@Sun.COM fcio.fcio_olen = MAXPATHLEN;
827836SJohn.Forte@Sun.COM fcio.fcio_obuf = (char *)nextPath;
837836SJohn.Forte@Sun.COM fcio.fcio_ilen = sizeof (i);
847836SJohn.Forte@Sun.COM fcio.fcio_ibuf = (char *)&i;
857836SJohn.Forte@Sun.COM
867836SJohn.Forte@Sun.COM // open the fcsm node so we can send the ioctl to
877836SJohn.Forte@Sun.COM errno = 0;
887836SJohn.Forte@Sun.COM HBAPort *port = getPortByIndex(0);
897836SJohn.Forte@Sun.COM if ((fd = open(port->getPath().c_str(), O_NDELAY | O_RDONLY)) ==
907836SJohn.Forte@Sun.COM -1) {
917836SJohn.Forte@Sun.COM log.debug("Unable to open %d opened (%s)", i,
927836SJohn.Forte@Sun.COM port->getPath().c_str());
937836SJohn.Forte@Sun.COM if (errno == EBUSY) {
947836SJohn.Forte@Sun.COM throw BusyException();
957836SJohn.Forte@Sun.COM } else if (errno == EAGAIN) {
967836SJohn.Forte@Sun.COM throw TryAgainException();
977836SJohn.Forte@Sun.COM } else if (errno == ENOTSUP) {
987836SJohn.Forte@Sun.COM throw NotSupportedException();
997836SJohn.Forte@Sun.COM } else if (errno == ENOENT) {
1007836SJohn.Forte@Sun.COM throw UnavailableException();
1017836SJohn.Forte@Sun.COM } else {
1027836SJohn.Forte@Sun.COM throw IOError("Unable to open FCSM driver");
1037836SJohn.Forte@Sun.COM }
1047836SJohn.Forte@Sun.COM }
1057836SJohn.Forte@Sun.COM log.debug("Other port %d opened", i);
1067836SJohn.Forte@Sun.COM
1077836SJohn.Forte@Sun.COM errno = 0;
1087836SJohn.Forte@Sun.COM if (ioctl(fd, FCIO_CMD, &fcio) != 0) {
1097836SJohn.Forte@Sun.COM // Interpret the fcio error code
1107836SJohn.Forte@Sun.COM char fcioErrorString[MAX_FCIO_MSG_LEN] = "";
1117836SJohn.Forte@Sun.COM
1127836SJohn.Forte@Sun.COM log.genericIOError(
1137836SJohn.Forte@Sun.COM "ADAPTER_LIST failed: "
1147836SJohn.Forte@Sun.COM "Errno: \"%s\"",
1157836SJohn.Forte@Sun.COM strerror(errno));
1167836SJohn.Forte@Sun.COM close(fd);
1177836SJohn.Forte@Sun.COM if (errno == EBUSY) {
1187836SJohn.Forte@Sun.COM throw BusyException();
1197836SJohn.Forte@Sun.COM } else if (errno == EAGAIN) {
1207836SJohn.Forte@Sun.COM throw TryAgainException();
1217836SJohn.Forte@Sun.COM } else if (errno == ENOTSUP) {
1227836SJohn.Forte@Sun.COM throw NotSupportedException();
1237836SJohn.Forte@Sun.COM } else if (errno == ENOENT) {
1247836SJohn.Forte@Sun.COM throw UnavailableException();
1257836SJohn.Forte@Sun.COM } else {
1267836SJohn.Forte@Sun.COM throw IOError("Unable to build HBA list");
1277836SJohn.Forte@Sun.COM }
1287836SJohn.Forte@Sun.COM }
1297836SJohn.Forte@Sun.COM close(fd);
1307836SJohn.Forte@Sun.COM log.debug("About to add port %d (%s)", i, nextPath);
1317836SJohn.Forte@Sun.COM addPort(new FCHBAPort(nextPath));
1327836SJohn.Forte@Sun.COM }
133*11156SRenia.Miao@Sun.COM } catch (BusyException &e) {
134*11156SRenia.Miao@Sun.COM throw e;
135*11156SRenia.Miao@Sun.COM } catch (TryAgainException &e) {
136*11156SRenia.Miao@Sun.COM throw e;
137*11156SRenia.Miao@Sun.COM } catch (UnavailableException &e) {
138*11156SRenia.Miao@Sun.COM throw e;
1397836SJohn.Forte@Sun.COM } catch (HBAException &e) {
1407836SJohn.Forte@Sun.COM log.internalError(
1417836SJohn.Forte@Sun.COM "Unable to construct HBA.");
1427836SJohn.Forte@Sun.COM throw e;
1437836SJohn.Forte@Sun.COM }
1447836SJohn.Forte@Sun.COM }
1457836SJohn.Forte@Sun.COM
getName()1467836SJohn.Forte@Sun.COM std::string FCHBA::getName() {
1477836SJohn.Forte@Sun.COM Trace log("FCHBA::getName");
1487836SJohn.Forte@Sun.COM return (name);
1497836SJohn.Forte@Sun.COM }
1507836SJohn.Forte@Sun.COM
getHBAAttributes()1517836SJohn.Forte@Sun.COM HBA_ADAPTERATTRIBUTES FCHBA::getHBAAttributes() {
1527836SJohn.Forte@Sun.COM Trace log("FCHBA::getHBAAttributes");
1537836SJohn.Forte@Sun.COM int fd;
1547836SJohn.Forte@Sun.COM
1557836SJohn.Forte@Sun.COM errno = 0;
1567836SJohn.Forte@Sun.COM HBAPort *port = getPortByIndex(0);
1577836SJohn.Forte@Sun.COM if ((fd = open(port->getPath().c_str(), O_NDELAY | O_RDONLY)) == -1) {
1587836SJohn.Forte@Sun.COM // Why did we fail?
1597836SJohn.Forte@Sun.COM if (errno == EBUSY) {
1607836SJohn.Forte@Sun.COM throw BusyException();
1617836SJohn.Forte@Sun.COM } else if (errno == EAGAIN) {
1627836SJohn.Forte@Sun.COM throw TryAgainException();
1637836SJohn.Forte@Sun.COM } else if (errno == ENOTSUP) {
1647836SJohn.Forte@Sun.COM throw NotSupportedException();
1657836SJohn.Forte@Sun.COM } else {
1667836SJohn.Forte@Sun.COM throw IOError(port);
1677836SJohn.Forte@Sun.COM }
1687836SJohn.Forte@Sun.COM }
1697836SJohn.Forte@Sun.COM
1707836SJohn.Forte@Sun.COM HBA_ADAPTERATTRIBUTES attributes;
1717836SJohn.Forte@Sun.COM fcio_t fcio;
1727836SJohn.Forte@Sun.COM fc_hba_adapter_attributes_t attrs;
1737836SJohn.Forte@Sun.COM
1747836SJohn.Forte@Sun.COM memset(&fcio, 0, sizeof (fcio));
1757836SJohn.Forte@Sun.COM
1767836SJohn.Forte@Sun.COM fcio.fcio_cmd = FCIO_GET_ADAPTER_ATTRIBUTES;
1777836SJohn.Forte@Sun.COM fcio.fcio_olen = sizeof (attrs);
1787836SJohn.Forte@Sun.COM fcio.fcio_xfer = FCIO_XFER_READ;
1797836SJohn.Forte@Sun.COM fcio.fcio_obuf = (caddr_t)&attrs;
1807836SJohn.Forte@Sun.COM
1817836SJohn.Forte@Sun.COM
1827836SJohn.Forte@Sun.COM errno = 0;
1837836SJohn.Forte@Sun.COM if (ioctl(fd, FCIO_CMD, &fcio) != 0) {
1847836SJohn.Forte@Sun.COM close(fd);
1857836SJohn.Forte@Sun.COM if (errno == EBUSY) {
1867836SJohn.Forte@Sun.COM throw BusyException();
1877836SJohn.Forte@Sun.COM } else if (errno == EAGAIN) {
1887836SJohn.Forte@Sun.COM throw TryAgainException();
1897836SJohn.Forte@Sun.COM } else if (errno == ENOTSUP) {
1907836SJohn.Forte@Sun.COM throw NotSupportedException();
1917836SJohn.Forte@Sun.COM } else {
1927836SJohn.Forte@Sun.COM throw IOError("Unable to fetch adapter attributes");
1937836SJohn.Forte@Sun.COM }
1947836SJohn.Forte@Sun.COM }
1957836SJohn.Forte@Sun.COM close(fd);
1967836SJohn.Forte@Sun.COM
1977836SJohn.Forte@Sun.COM /* Now copy over the payload */
1987836SJohn.Forte@Sun.COM attributes.NumberOfPorts = attrs.NumberOfPorts;
1997836SJohn.Forte@Sun.COM attributes.VendorSpecificID = attrs.VendorSpecificID;
2007836SJohn.Forte@Sun.COM memcpy(attributes.Manufacturer, attrs.Manufacturer, 64);
2017836SJohn.Forte@Sun.COM memcpy(attributes.SerialNumber, attrs.SerialNumber, 64);
2027836SJohn.Forte@Sun.COM memcpy(attributes.Model, attrs.Model, 256);
2037836SJohn.Forte@Sun.COM memcpy(attributes.ModelDescription, attrs.ModelDescription, 256);
2047836SJohn.Forte@Sun.COM memcpy(attributes.NodeSymbolicName, attrs.NodeSymbolicName, 256);
2057836SJohn.Forte@Sun.COM memcpy(attributes.HardwareVersion, attrs.HardwareVersion, 256);
2067836SJohn.Forte@Sun.COM memcpy(attributes.DriverVersion, attrs.DriverVersion, 256);
2077836SJohn.Forte@Sun.COM memcpy(attributes.OptionROMVersion, attrs.OptionROMVersion, 256);
2087836SJohn.Forte@Sun.COM memcpy(attributes.FirmwareVersion, attrs.FirmwareVersion, 256);
2097836SJohn.Forte@Sun.COM memcpy(attributes.DriverName, attrs.DriverName, 256);
2107836SJohn.Forte@Sun.COM memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8);
2117836SJohn.Forte@Sun.COM
2127836SJohn.Forte@Sun.COM return (attributes);
2137836SJohn.Forte@Sun.COM }
2147836SJohn.Forte@Sun.COM
doForceLip()21510275SReed.Liu@Sun.COM int FCHBA::doForceLip() {
21610275SReed.Liu@Sun.COM Trace log("FCHBA::doForceLip");
21710275SReed.Liu@Sun.COM int fd;
21810275SReed.Liu@Sun.COM fcio_t fcio;
21910275SReed.Liu@Sun.COM uint64_t wwn = 0;
22010275SReed.Liu@Sun.COM HBAPort *port = getPortByIndex(0);
22110275SReed.Liu@Sun.COM
22210275SReed.Liu@Sun.COM errno = 0;
22310275SReed.Liu@Sun.COM if ((fd = open(port->getPath().c_str(), O_RDONLY | O_EXCL)) == -1) {
22410275SReed.Liu@Sun.COM if (errno == EBUSY) {
22510275SReed.Liu@Sun.COM throw BusyException();
22610275SReed.Liu@Sun.COM } else if (errno == EAGAIN) {
22710275SReed.Liu@Sun.COM throw TryAgainException();
22810275SReed.Liu@Sun.COM } else if (errno == ENOTSUP) {
22910275SReed.Liu@Sun.COM throw NotSupportedException();
23010275SReed.Liu@Sun.COM } else {
23110275SReed.Liu@Sun.COM throw IOError(port);
23210275SReed.Liu@Sun.COM }
23310275SReed.Liu@Sun.COM }
23410275SReed.Liu@Sun.COM
23510275SReed.Liu@Sun.COM memset(&fcio, 0, sizeof (fcio));
23610275SReed.Liu@Sun.COM fcio.fcio_cmd = FCIO_RESET_LINK;
23710275SReed.Liu@Sun.COM fcio.fcio_xfer = FCIO_XFER_WRITE;
23810275SReed.Liu@Sun.COM fcio.fcio_ilen = sizeof (wwn);
23910275SReed.Liu@Sun.COM fcio.fcio_ibuf = (caddr_t)&wwn;
24010275SReed.Liu@Sun.COM
24110275SReed.Liu@Sun.COM errno = 0;
24210275SReed.Liu@Sun.COM if (ioctl(fd, FCIO_CMD, &fcio) != 0) {
24310275SReed.Liu@Sun.COM close(fd);
24410275SReed.Liu@Sun.COM
24510275SReed.Liu@Sun.COM if (errno == EBUSY) {
24610275SReed.Liu@Sun.COM throw BusyException();
24710275SReed.Liu@Sun.COM } else if (errno == EAGAIN) {
24810275SReed.Liu@Sun.COM throw TryAgainException();
24910275SReed.Liu@Sun.COM } else if (errno == ENOTSUP) {
25010275SReed.Liu@Sun.COM throw NotSupportedException();
25110275SReed.Liu@Sun.COM } else {
25210275SReed.Liu@Sun.COM throw IOError("Unable to reinitialize the link");
25310275SReed.Liu@Sun.COM }
25410275SReed.Liu@Sun.COM } else {
25510275SReed.Liu@Sun.COM close(fd);
25610275SReed.Liu@Sun.COM return (fcio.fcio_errno);
25710275SReed.Liu@Sun.COM }
25810275SReed.Liu@Sun.COM }
25910275SReed.Liu@Sun.COM
npivGetHBAAttributes()2607836SJohn.Forte@Sun.COM HBA_ADAPTERATTRIBUTES FCHBA::npivGetHBAAttributes() {
2617836SJohn.Forte@Sun.COM Trace log("FCHBA::npivGetHBAAttributes");
2627836SJohn.Forte@Sun.COM int fd;
2637836SJohn.Forte@Sun.COM
2647836SJohn.Forte@Sun.COM errno = 0;
2657836SJohn.Forte@Sun.COM HBAPort *port = getPortByIndex(0);
2667836SJohn.Forte@Sun.COM if ((fd = open(port->getPath().c_str(), O_NDELAY | O_RDONLY)) == -1) {
2677836SJohn.Forte@Sun.COM // Why did we fail?
2687836SJohn.Forte@Sun.COM if (errno == EBUSY) {
2697836SJohn.Forte@Sun.COM throw BusyException();
2707836SJohn.Forte@Sun.COM } else if (errno == EAGAIN) {
2717836SJohn.Forte@Sun.COM throw TryAgainException();
2727836SJohn.Forte@Sun.COM } else if (errno == ENOTSUP) {
2737836SJohn.Forte@Sun.COM throw NotSupportedException();
2747836SJohn.Forte@Sun.COM } else {
2757836SJohn.Forte@Sun.COM throw IOError(port);
2767836SJohn.Forte@Sun.COM }
2777836SJohn.Forte@Sun.COM }
2787836SJohn.Forte@Sun.COM
2797836SJohn.Forte@Sun.COM HBA_ADAPTERATTRIBUTES attributes;
2807836SJohn.Forte@Sun.COM fcio_t fcio;
2817836SJohn.Forte@Sun.COM fc_hba_adapter_attributes_t attrs;
2827836SJohn.Forte@Sun.COM
2837836SJohn.Forte@Sun.COM memset(&fcio, 0, sizeof (fcio));
2847836SJohn.Forte@Sun.COM fcio.fcio_cmd = FCIO_NPIV_GET_ADAPTER_ATTRIBUTES;
2857836SJohn.Forte@Sun.COM fcio.fcio_olen = sizeof (attrs);
2867836SJohn.Forte@Sun.COM fcio.fcio_xfer = FCIO_XFER_READ;
2877836SJohn.Forte@Sun.COM fcio.fcio_obuf = (caddr_t)&attrs;
2887836SJohn.Forte@Sun.COM errno = 0;
2897836SJohn.Forte@Sun.COM
2907836SJohn.Forte@Sun.COM if (ioctl(fd, FCIO_CMD, &fcio) != 0) {
2917836SJohn.Forte@Sun.COM close(fd);
2927836SJohn.Forte@Sun.COM if (errno == EBUSY) {
2937836SJohn.Forte@Sun.COM throw BusyException();
2947836SJohn.Forte@Sun.COM } else if (errno == EAGAIN) {
2957836SJohn.Forte@Sun.COM throw TryAgainException();
2967836SJohn.Forte@Sun.COM } else if (errno == ENOTSUP) {
2977836SJohn.Forte@Sun.COM throw NotSupportedException();
2987836SJohn.Forte@Sun.COM } else {
2997836SJohn.Forte@Sun.COM throw IOError("Unable to fetch adapter attributes");
3007836SJohn.Forte@Sun.COM }
3017836SJohn.Forte@Sun.COM }
3027836SJohn.Forte@Sun.COM close(fd);
3037836SJohn.Forte@Sun.COM
3047836SJohn.Forte@Sun.COM /* Now copy over the payload */
3057836SJohn.Forte@Sun.COM attributes.NumberOfPorts = attrs.NumberOfPorts;
3067836SJohn.Forte@Sun.COM attributes.VendorSpecificID = attrs.VendorSpecificID;
3077836SJohn.Forte@Sun.COM memcpy(attributes.Manufacturer, attrs.Manufacturer, 64);
3087836SJohn.Forte@Sun.COM memcpy(attributes.SerialNumber, attrs.SerialNumber, 64);
3097836SJohn.Forte@Sun.COM memcpy(attributes.Model, attrs.Model, 256);
3107836SJohn.Forte@Sun.COM memcpy(attributes.ModelDescription, attrs.ModelDescription, 256);
3117836SJohn.Forte@Sun.COM memcpy(attributes.NodeSymbolicName, attrs.NodeSymbolicName, 256);
3127836SJohn.Forte@Sun.COM memcpy(attributes.HardwareVersion, attrs.HardwareVersion, 256);
3137836SJohn.Forte@Sun.COM memcpy(attributes.DriverVersion, attrs.DriverVersion, 256);
3147836SJohn.Forte@Sun.COM memcpy(attributes.OptionROMVersion, attrs.OptionROMVersion, 256);
3157836SJohn.Forte@Sun.COM memcpy(attributes.FirmwareVersion, attrs.FirmwareVersion, 256);
3167836SJohn.Forte@Sun.COM memcpy(attributes.DriverName, attrs.DriverName, 256);
3177836SJohn.Forte@Sun.COM memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8);
3187836SJohn.Forte@Sun.COM
3197836SJohn.Forte@Sun.COM return (attributes);
3207836SJohn.Forte@Sun.COM }
3217836SJohn.Forte@Sun.COM
loadAdapters(vector<HBA * > & list)3227836SJohn.Forte@Sun.COM void FCHBA::loadAdapters(vector<HBA*> &list) {
3237836SJohn.Forte@Sun.COM Trace log("FCHBA::loadAdapters");
3247836SJohn.Forte@Sun.COM fcio_t fcio;
3257836SJohn.Forte@Sun.COM fc_hba_list_t *pathList;
3267836SJohn.Forte@Sun.COM int fd;
3277836SJohn.Forte@Sun.COM int size = 64; // default first attempt
3287836SJohn.Forte@Sun.COM bool retry = false;
3297836SJohn.Forte@Sun.COM struct stat sb;
3307836SJohn.Forte@Sun.COM int bufSize;
3317836SJohn.Forte@Sun.COM
3327836SJohn.Forte@Sun.COM /* Before we do anything, let's see if FCSM is on the system */
3337836SJohn.Forte@Sun.COM errno = 0;
3347836SJohn.Forte@Sun.COM if (stat(FCSM_DRIVER_PATH.c_str(), &sb) != 0) {
3357836SJohn.Forte@Sun.COM if (errno == ENOENT) {
3367836SJohn.Forte@Sun.COM log.genericIOError(
3377836SJohn.Forte@Sun.COM "The %s driver is not present. Unable to issue "
3387836SJohn.Forte@Sun.COM "CT commands. Please install the %s package.",
3397836SJohn.Forte@Sun.COM FCSM_DRIVER_PATH.c_str(), FCSM_DRIVER_PKG.c_str());
3407836SJohn.Forte@Sun.COM throw NotSupportedException();
3417836SJohn.Forte@Sun.COM } else {
3427836SJohn.Forte@Sun.COM log.genericIOError(
3437836SJohn.Forte@Sun.COM "Can not stat the %s driver for reason \"%s\" "
3447836SJohn.Forte@Sun.COM "Unable to issue CT commands.",
3457836SJohn.Forte@Sun.COM FCSM_DRIVER_PATH.c_str(), strerror(errno));
3467836SJohn.Forte@Sun.COM throw IOError("Unable to stat FCSM driver");
3477836SJohn.Forte@Sun.COM }
3487836SJohn.Forte@Sun.COM }
3497836SJohn.Forte@Sun.COM
3507836SJohn.Forte@Sun.COM
3517836SJohn.Forte@Sun.COM /* construct fcio struct */
3527836SJohn.Forte@Sun.COM memset(&fcio, 0, sizeof (fcio_t));
3537836SJohn.Forte@Sun.COM fcio.fcio_cmd = FCSMIO_ADAPTER_LIST;
3547836SJohn.Forte@Sun.COM fcio.fcio_xfer = FCIO_XFER_RW;
3557836SJohn.Forte@Sun.COM
3567836SJohn.Forte@Sun.COM
3577836SJohn.Forte@Sun.COM /* open the fcsm node so we can send the ioctl to */
3587836SJohn.Forte@Sun.COM errno = 0;
3597836SJohn.Forte@Sun.COM if ((fd = open(FCSM_DRIVER_PATH.c_str(), O_RDONLY)) < 0) {
3607836SJohn.Forte@Sun.COM if (errno == EBUSY) {
3617836SJohn.Forte@Sun.COM throw BusyException();
3627836SJohn.Forte@Sun.COM } else if (errno == EAGAIN) {
3637836SJohn.Forte@Sun.COM throw TryAgainException();
3647836SJohn.Forte@Sun.COM } else if (errno == ENOTSUP) {
3657836SJohn.Forte@Sun.COM throw NotSupportedException();
3667836SJohn.Forte@Sun.COM } else if (errno == ENOENT) {
3677836SJohn.Forte@Sun.COM throw UnavailableException();
3687836SJohn.Forte@Sun.COM } else {
3697836SJohn.Forte@Sun.COM throw IOError("Unable to open FCSM driver");
3707836SJohn.Forte@Sun.COM }
3717836SJohn.Forte@Sun.COM }
3727836SJohn.Forte@Sun.COM
3737836SJohn.Forte@Sun.COM do {
3747836SJohn.Forte@Sun.COM retry = false;
3757836SJohn.Forte@Sun.COM errno = 0;
3767836SJohn.Forte@Sun.COM bufSize = MAXPATHLEN * size + (int) sizeof (fc_hba_list_t) - 1;
3777836SJohn.Forte@Sun.COM pathList = (fc_hba_list_t *)new uchar_t[bufSize];
3787836SJohn.Forte@Sun.COM pathList->numAdapters = size;
3797836SJohn.Forte@Sun.COM fcio.fcio_olen = bufSize;
3807836SJohn.Forte@Sun.COM fcio.fcio_obuf = (char *)pathList;
3817836SJohn.Forte@Sun.COM if (ioctl(fd, FCSMIO_CMD, &fcio) != 0) {
3827836SJohn.Forte@Sun.COM /* Interpret the fcio error code */
3837836SJohn.Forte@Sun.COM char fcioErrorString[MAX_FCIO_MSG_LEN] = "";
3847836SJohn.Forte@Sun.COM
3857836SJohn.Forte@Sun.COM log.genericIOError(
3867836SJohn.Forte@Sun.COM "ADAPTER_LIST failed: "
3877836SJohn.Forte@Sun.COM "Errno: \"%s\"",
3887836SJohn.Forte@Sun.COM strerror(errno));
3897836SJohn.Forte@Sun.COM delete (pathList);
3907836SJohn.Forte@Sun.COM close(fd);
3917836SJohn.Forte@Sun.COM if (errno == EBUSY) {
3927836SJohn.Forte@Sun.COM throw BusyException();
3937836SJohn.Forte@Sun.COM } else if (errno == EAGAIN) {
3947836SJohn.Forte@Sun.COM throw TryAgainException();
3957836SJohn.Forte@Sun.COM } else if (errno == ENOTSUP) {
3967836SJohn.Forte@Sun.COM throw NotSupportedException();
3977836SJohn.Forte@Sun.COM } else if (errno == ENOENT) {
3987836SJohn.Forte@Sun.COM throw UnavailableException();
3997836SJohn.Forte@Sun.COM } else {
4007836SJohn.Forte@Sun.COM throw IOError("Unable to build HBA list");
4017836SJohn.Forte@Sun.COM }
4027836SJohn.Forte@Sun.COM }
4037836SJohn.Forte@Sun.COM if (pathList->numAdapters > size) {
4047836SJohn.Forte@Sun.COM log.debug(
4057836SJohn.Forte@Sun.COM "Buffer too small for number of HBAs. Retrying.");
4067836SJohn.Forte@Sun.COM size = pathList->numAdapters;
4077836SJohn.Forte@Sun.COM retry = true;
4087836SJohn.Forte@Sun.COM delete (pathList);
4097836SJohn.Forte@Sun.COM }
4107836SJohn.Forte@Sun.COM } while (retry);
4117836SJohn.Forte@Sun.COM
4127836SJohn.Forte@Sun.COM close(fd);
4137836SJohn.Forte@Sun.COM log.debug("Detected %d adapters", pathList->numAdapters);
414*11156SRenia.Miao@Sun.COM for (int i = 0, times =0; i < pathList->numAdapters;) {
4157836SJohn.Forte@Sun.COM try {
4167836SJohn.Forte@Sun.COM HBA *hba = new FCHBA(pathList->hbaPaths[i]);
4177836SJohn.Forte@Sun.COM list.insert(list.begin(), hba);
418*11156SRenia.Miao@Sun.COM i++;
419*11156SRenia.Miao@Sun.COM } catch (BusyException &e) {
420*11156SRenia.Miao@Sun.COM sleep(1);
421*11156SRenia.Miao@Sun.COM if (times++ > EXCPT_RETRY_COUNT) {
422*11156SRenia.Miao@Sun.COM i++;
423*11156SRenia.Miao@Sun.COM times = 0;
424*11156SRenia.Miao@Sun.COM }
425*11156SRenia.Miao@Sun.COM continue;
426*11156SRenia.Miao@Sun.COM } catch (TryAgainException &e) {
427*11156SRenia.Miao@Sun.COM sleep(1);
428*11156SRenia.Miao@Sun.COM if (times++ > EXCPT_RETRY_COUNT) {
429*11156SRenia.Miao@Sun.COM i++;
430*11156SRenia.Miao@Sun.COM times = 0;
431*11156SRenia.Miao@Sun.COM }
432*11156SRenia.Miao@Sun.COM continue;
433*11156SRenia.Miao@Sun.COM } catch (UnavailableException &e) {
434*11156SRenia.Miao@Sun.COM sleep(1);
435*11156SRenia.Miao@Sun.COM if (times++ > EXCPT_RETRY_COUNT) {
436*11156SRenia.Miao@Sun.COM i++;
437*11156SRenia.Miao@Sun.COM times = 0;
438*11156SRenia.Miao@Sun.COM }
439*11156SRenia.Miao@Sun.COM continue;
440*11156SRenia.Miao@Sun.COM } catch (HBAException &e) {
441*11156SRenia.Miao@Sun.COM i++;
442*11156SRenia.Miao@Sun.COM times = 0;
4437836SJohn.Forte@Sun.COM log.debug(
4447836SJohn.Forte@Sun.COM "Ignoring partial failure while loading an HBA");
4457836SJohn.Forte@Sun.COM }
4467836SJohn.Forte@Sun.COM }
4477836SJohn.Forte@Sun.COM if (pathList->numAdapters > HBAList::HBA_MAX_PER_LIST) {
4487836SJohn.Forte@Sun.COM delete(pathList);
4497836SJohn.Forte@Sun.COM throw InternalError(
4507836SJohn.Forte@Sun.COM "Exceeds max number of adatpers that VSL supports.");
4517836SJohn.Forte@Sun.COM }
4527836SJohn.Forte@Sun.COM delete (pathList);
4537836SJohn.Forte@Sun.COM }
454