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*10275SReed.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 <TgtFCHBA.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/fctio.h>
427836SJohn.Forte@Sun.COM #include <sys/fibre-channel/impl/fc_error.h>
437836SJohn.Forte@Sun.COM #include <TgtFCHBAPort.h>
447836SJohn.Forte@Sun.COM #include <HBAList.h>
457836SJohn.Forte@Sun.COM #include <sun_fc.h>
467836SJohn.Forte@Sun.COM
477836SJohn.Forte@Sun.COM using namespace std;
487836SJohn.Forte@Sun.COM const string TgtFCHBA::FCT_DRIVER_PATH = "/devices/pseudo/fct@0:admin";
497836SJohn.Forte@Sun.COM const string TgtFCHBA::FCT_ADAPTER_NAME_PREFIX = "/devices/pseudo/fct@0";
507836SJohn.Forte@Sun.COM const string TgtFCHBA::FCT_DRIVER_PKG = "SUNWfct";
517836SJohn.Forte@Sun.COM const int TgtFCHBA::MAX_FCTIO_MSG_LEN = 256;
527836SJohn.Forte@Sun.COM
TgtFCHBA(string path)537836SJohn.Forte@Sun.COM TgtFCHBA::TgtFCHBA(string path) : HBA()
547836SJohn.Forte@Sun.COM {
557836SJohn.Forte@Sun.COM Trace log("TgtFCHBA::TgtFCHBA");
567836SJohn.Forte@Sun.COM log.debug("Constructing new Target mode HBA (%s)", path.c_str());
577836SJohn.Forte@Sun.COM
587836SJohn.Forte@Sun.COM // Add a target FCHBA port. With fct driver architecuture, all target mode
597836SJohn.Forte@Sun.COM // FCHBA will have a single port regardless of the multiport support on
607836SJohn.Forte@Sun.COM // FCA layer.
617836SJohn.Forte@Sun.COM addPort(new TgtFCHBAPort(path));
627836SJohn.Forte@Sun.COM name = "INTERNAL-FAILURE"; // Just in case things go wrong
637836SJohn.Forte@Sun.COM try {
647836SJohn.Forte@Sun.COM HBA_ADAPTERATTRIBUTES attrs = getHBAAttributes();
657836SJohn.Forte@Sun.COM name = attrs.Manufacturer;
667836SJohn.Forte@Sun.COM name += "-";
677836SJohn.Forte@Sun.COM name += attrs.Model;
687836SJohn.Forte@Sun.COM name += "-Tgt";
697836SJohn.Forte@Sun.COM
707836SJohn.Forte@Sun.COM } catch (HBAException &e) {
717836SJohn.Forte@Sun.COM log.debug(
727836SJohn.Forte@Sun.COM "Failed to get HBA attribute for %s", path.c_str());
737836SJohn.Forte@Sun.COM throw e;
747836SJohn.Forte@Sun.COM }
757836SJohn.Forte@Sun.COM }
767836SJohn.Forte@Sun.COM
getName()777836SJohn.Forte@Sun.COM std::string TgtFCHBA::getName()
787836SJohn.Forte@Sun.COM {
797836SJohn.Forte@Sun.COM Trace log("TgtFCHBA::getName");
807836SJohn.Forte@Sun.COM return (name);
817836SJohn.Forte@Sun.COM }
827836SJohn.Forte@Sun.COM
getHBAAttributes()837836SJohn.Forte@Sun.COM HBA_ADAPTERATTRIBUTES TgtFCHBA::getHBAAttributes()
847836SJohn.Forte@Sun.COM {
857836SJohn.Forte@Sun.COM Trace log("TgtFCHBA::getHBAAttributes");
867836SJohn.Forte@Sun.COM int fd;
877836SJohn.Forte@Sun.COM
887836SJohn.Forte@Sun.COM errno = 0;
897836SJohn.Forte@Sun.COM HBAPort *port = getPortByIndex(0);
907836SJohn.Forte@Sun.COM
917836SJohn.Forte@Sun.COM HBA_ADAPTERATTRIBUTES attributes;
927836SJohn.Forte@Sun.COM fctio_t fctio;
937836SJohn.Forte@Sun.COM fc_tgt_hba_adapter_attributes_t attrs;
947836SJohn.Forte@Sun.COM uint64_t portwwn;
957836SJohn.Forte@Sun.COM
967836SJohn.Forte@Sun.COM if ((fd = open(FCT_DRIVER_PATH.c_str(), O_NDELAY | O_RDONLY)) == -1) {
977836SJohn.Forte@Sun.COM // Why did we fail?
987836SJohn.Forte@Sun.COM if (errno == EBUSY) {
997836SJohn.Forte@Sun.COM throw BusyException();
1007836SJohn.Forte@Sun.COM } else if (errno == EAGAIN) {
1017836SJohn.Forte@Sun.COM throw TryAgainException();
1027836SJohn.Forte@Sun.COM } else if (errno == ENOTSUP) {
1037836SJohn.Forte@Sun.COM throw NotSupportedException();
1047836SJohn.Forte@Sun.COM } else {
1057836SJohn.Forte@Sun.COM throw IOError(port);
1067836SJohn.Forte@Sun.COM }
1077836SJohn.Forte@Sun.COM }
1087836SJohn.Forte@Sun.COM
1097836SJohn.Forte@Sun.COM try {
1107836SJohn.Forte@Sun.COM std::string path = port->getPath();
1117836SJohn.Forte@Sun.COM string::size_type offset = path.find_last_of(".");
1127836SJohn.Forte@Sun.COM if (offset >= 0) {
1137836SJohn.Forte@Sun.COM string portwwnString = path.substr(offset+1);
1147836SJohn.Forte@Sun.COM portwwn = strtoull(portwwnString.c_str(), NULL, 16);
1157836SJohn.Forte@Sun.COM }
1167836SJohn.Forte@Sun.COM } catch (...) {
1177836SJohn.Forte@Sun.COM throw BadArgumentException();
1187836SJohn.Forte@Sun.COM }
1197836SJohn.Forte@Sun.COM
1207836SJohn.Forte@Sun.COM uint64_t en_wwn = htonll(portwwn);
1217836SJohn.Forte@Sun.COM
1227836SJohn.Forte@Sun.COM memset(&fctio, 0, sizeof (fctio));
1237836SJohn.Forte@Sun.COM fctio.fctio_cmd = FCTIO_GET_ADAPTER_ATTRIBUTES;
1247836SJohn.Forte@Sun.COM fctio.fctio_olen = (uint32_t)(sizeof (attrs));
1257836SJohn.Forte@Sun.COM fctio.fctio_xfer = FCTIO_XFER_READ;
1267836SJohn.Forte@Sun.COM fctio.fctio_obuf = (uint64_t)(uintptr_t)&attrs;
1277836SJohn.Forte@Sun.COM fctio.fctio_ilen = 8;
1287836SJohn.Forte@Sun.COM fctio.fctio_ibuf = (uint64_t)(uintptr_t)&en_wwn;
1297836SJohn.Forte@Sun.COM
1307836SJohn.Forte@Sun.COM errno = 0;
1317836SJohn.Forte@Sun.COM if (ioctl(fd, FCTIO_CMD, &fctio) != 0) {
1327836SJohn.Forte@Sun.COM close(fd);
1337836SJohn.Forte@Sun.COM if (errno == EBUSY) {
1347836SJohn.Forte@Sun.COM throw BusyException();
1357836SJohn.Forte@Sun.COM } else if (errno == EAGAIN) {
1367836SJohn.Forte@Sun.COM throw TryAgainException();
1377836SJohn.Forte@Sun.COM } else if (errno == ENOTSUP) {
1387836SJohn.Forte@Sun.COM throw NotSupportedException();
1397836SJohn.Forte@Sun.COM } else {
1407836SJohn.Forte@Sun.COM throw IOError("Unable to fetch adapter attributes");
1417836SJohn.Forte@Sun.COM }
1427836SJohn.Forte@Sun.COM }
1437836SJohn.Forte@Sun.COM close(fd);
1447836SJohn.Forte@Sun.COM
1457836SJohn.Forte@Sun.COM /* Now copy over the payload */
1467836SJohn.Forte@Sun.COM attributes.NumberOfPorts = attrs.NumberOfPorts;
1477836SJohn.Forte@Sun.COM attributes.VendorSpecificID = attrs.VendorSpecificID;
1487836SJohn.Forte@Sun.COM memcpy(attributes.Manufacturer, attrs.Manufacturer, 64);
1497836SJohn.Forte@Sun.COM memcpy(attributes.SerialNumber, attrs.SerialNumber, 64);
1507836SJohn.Forte@Sun.COM memcpy(attributes.Model, attrs.Model, 256);
1517836SJohn.Forte@Sun.COM memcpy(attributes.ModelDescription, attrs.ModelDescription, 256);
1527836SJohn.Forte@Sun.COM memcpy(attributes.NodeSymbolicName, attrs.NodeSymbolicName, 256);
1537836SJohn.Forte@Sun.COM memcpy(attributes.HardwareVersion, attrs.HardwareVersion, 256);
1547836SJohn.Forte@Sun.COM memcpy(attributes.DriverVersion, attrs.DriverVersion, 256);
1557836SJohn.Forte@Sun.COM memcpy(attributes.OptionROMVersion, attrs.OptionROMVersion, 256);
1567836SJohn.Forte@Sun.COM memcpy(attributes.FirmwareVersion, attrs.FirmwareVersion, 256);
1577836SJohn.Forte@Sun.COM memcpy(attributes.DriverName, attrs.DriverName, 256);
1587836SJohn.Forte@Sun.COM memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8);
1597836SJohn.Forte@Sun.COM
1607836SJohn.Forte@Sun.COM return (attributes);
1617836SJohn.Forte@Sun.COM }
1627836SJohn.Forte@Sun.COM
doForceLip()163*10275SReed.Liu@Sun.COM int TgtFCHBA::doForceLip()
164*10275SReed.Liu@Sun.COM {
165*10275SReed.Liu@Sun.COM Trace log("TgtFCHBA::doForceLip");
166*10275SReed.Liu@Sun.COM int fd;
167*10275SReed.Liu@Sun.COM HBAPort *port = getPortByIndex(0);
168*10275SReed.Liu@Sun.COM fctio_t fctio;
169*10275SReed.Liu@Sun.COM uint64_t portwwn;
170*10275SReed.Liu@Sun.COM
171*10275SReed.Liu@Sun.COM errno = 0;
172*10275SReed.Liu@Sun.COM if ((fd = open(FCT_DRIVER_PATH.c_str(), O_NDELAY | O_RDONLY)) == -1) {
173*10275SReed.Liu@Sun.COM if (errno == EBUSY) {
174*10275SReed.Liu@Sun.COM throw BusyException();
175*10275SReed.Liu@Sun.COM } else if (errno == EAGAIN) {
176*10275SReed.Liu@Sun.COM throw TryAgainException();
177*10275SReed.Liu@Sun.COM } else if (errno == ENOTSUP) {
178*10275SReed.Liu@Sun.COM throw NotSupportedException();
179*10275SReed.Liu@Sun.COM } else {
180*10275SReed.Liu@Sun.COM throw IOError(port);
181*10275SReed.Liu@Sun.COM }
182*10275SReed.Liu@Sun.COM }
183*10275SReed.Liu@Sun.COM
184*10275SReed.Liu@Sun.COM try {
185*10275SReed.Liu@Sun.COM std::string path = port->getPath();
186*10275SReed.Liu@Sun.COM string::size_type offset = path.find_last_of(".");
187*10275SReed.Liu@Sun.COM if (offset >= 0) {
188*10275SReed.Liu@Sun.COM string portwwnString = path.substr(offset+1);
189*10275SReed.Liu@Sun.COM portwwn = strtoull(portwwnString.c_str(), NULL, 16);
190*10275SReed.Liu@Sun.COM }
191*10275SReed.Liu@Sun.COM } catch (...) {
192*10275SReed.Liu@Sun.COM throw BadArgumentException();
193*10275SReed.Liu@Sun.COM }
194*10275SReed.Liu@Sun.COM
195*10275SReed.Liu@Sun.COM uint64_t en_wwn = htonll(portwwn);
196*10275SReed.Liu@Sun.COM memset(&fctio, 0, sizeof (fctio));
197*10275SReed.Liu@Sun.COM fctio.fctio_cmd = FCTIO_FORCE_LIP;
198*10275SReed.Liu@Sun.COM fctio.fctio_xfer = FCTIO_XFER_READ;
199*10275SReed.Liu@Sun.COM fctio.fctio_ilen = 8;
200*10275SReed.Liu@Sun.COM fctio.fctio_ibuf = (uint64_t)(uintptr_t)&en_wwn;
201*10275SReed.Liu@Sun.COM
202*10275SReed.Liu@Sun.COM errno = 0;
203*10275SReed.Liu@Sun.COM if (ioctl(fd, FCTIO_CMD, &fctio) != 0) {
204*10275SReed.Liu@Sun.COM close(fd);
205*10275SReed.Liu@Sun.COM if (errno == EBUSY) {
206*10275SReed.Liu@Sun.COM throw BusyException();
207*10275SReed.Liu@Sun.COM } else if (errno == EAGAIN) {
208*10275SReed.Liu@Sun.COM throw TryAgainException();
209*10275SReed.Liu@Sun.COM } else if (errno == ENOTSUP) {
210*10275SReed.Liu@Sun.COM throw NotSupportedException();
211*10275SReed.Liu@Sun.COM } else {
212*10275SReed.Liu@Sun.COM throw IOError("Unable to reinitialize the link");
213*10275SReed.Liu@Sun.COM }
214*10275SReed.Liu@Sun.COM } else {
215*10275SReed.Liu@Sun.COM close(fd);
216*10275SReed.Liu@Sun.COM return ((int)fctio.fctio_errno);
217*10275SReed.Liu@Sun.COM }
218*10275SReed.Liu@Sun.COM }
219*10275SReed.Liu@Sun.COM
loadAdapters(vector<HBA * > & list)2207836SJohn.Forte@Sun.COM void TgtFCHBA::loadAdapters(vector<HBA*> &list)
2217836SJohn.Forte@Sun.COM {
2227836SJohn.Forte@Sun.COM Trace log("TgtFCHBA::loadAdapters");
2237836SJohn.Forte@Sun.COM fctio_t fctio;
2247836SJohn.Forte@Sun.COM fc_tgt_hba_list_t *tgthbaList;
2257836SJohn.Forte@Sun.COM int fd;
2267836SJohn.Forte@Sun.COM int size = 64; // default first attempt
2277836SJohn.Forte@Sun.COM bool retry = false;
2287836SJohn.Forte@Sun.COM struct stat sb;
2297836SJohn.Forte@Sun.COM int bufSize;
2307836SJohn.Forte@Sun.COM char wwnStr[17];
2317836SJohn.Forte@Sun.COM
2327836SJohn.Forte@Sun.COM /* Before we do anything, let's see if FCT is on the system */
2337836SJohn.Forte@Sun.COM errno = 0;
2347836SJohn.Forte@Sun.COM if (stat(FCT_DRIVER_PATH.c_str(), &sb) != 0) {
2357836SJohn.Forte@Sun.COM if (errno == ENOENT) {
2367836SJohn.Forte@Sun.COM log.genericIOError(
2377836SJohn.Forte@Sun.COM "The %s driver is not present."
2387836SJohn.Forte@Sun.COM " Please install the %s package.",
2397836SJohn.Forte@Sun.COM FCT_DRIVER_PATH.c_str(), FCT_DRIVER_PKG.c_str());
2407836SJohn.Forte@Sun.COM throw NotSupportedException();
2417836SJohn.Forte@Sun.COM } else {
2427836SJohn.Forte@Sun.COM log.genericIOError(
2437836SJohn.Forte@Sun.COM "Can not stat the %s driver for reason \"%s\" "
2447836SJohn.Forte@Sun.COM "Unable to get target mode FC adapters.",
2457836SJohn.Forte@Sun.COM FCT_DRIVER_PATH.c_str(), strerror(errno));
2467836SJohn.Forte@Sun.COM throw IOError("Unable to stat FCSM driver");
2477836SJohn.Forte@Sun.COM }
2487836SJohn.Forte@Sun.COM }
2497836SJohn.Forte@Sun.COM
2507836SJohn.Forte@Sun.COM
2517836SJohn.Forte@Sun.COM /* construct fcio struct */
2527836SJohn.Forte@Sun.COM memset(&fctio, 0, sizeof (fctio_t));
2537836SJohn.Forte@Sun.COM fctio.fctio_cmd = FCTIO_ADAPTER_LIST;
2547836SJohn.Forte@Sun.COM fctio.fctio_xfer = FCTIO_XFER_RW;
2557836SJohn.Forte@Sun.COM
2567836SJohn.Forte@Sun.COM /* open the fcsm node so we can send the ioctl to */
2577836SJohn.Forte@Sun.COM errno = 0;
2587836SJohn.Forte@Sun.COM if ((fd = open(FCT_DRIVER_PATH.c_str(), O_RDONLY)) < 0) {
2597836SJohn.Forte@Sun.COM if (errno == EBUSY) {
2607836SJohn.Forte@Sun.COM throw BusyException();
2617836SJohn.Forte@Sun.COM } else if (errno == EAGAIN) {
2627836SJohn.Forte@Sun.COM throw TryAgainException();
2637836SJohn.Forte@Sun.COM } else if (errno == ENOTSUP) {
2647836SJohn.Forte@Sun.COM throw NotSupportedException();
2657836SJohn.Forte@Sun.COM } else if (errno == ENOENT) {
2667836SJohn.Forte@Sun.COM throw UnavailableException();
2677836SJohn.Forte@Sun.COM } else {
2687836SJohn.Forte@Sun.COM throw IOError("Unable to open FCT driver");
2697836SJohn.Forte@Sun.COM }
2707836SJohn.Forte@Sun.COM }
2717836SJohn.Forte@Sun.COM
2727836SJohn.Forte@Sun.COM do {
2737836SJohn.Forte@Sun.COM retry = false;
2747836SJohn.Forte@Sun.COM errno = 0;
2757836SJohn.Forte@Sun.COM bufSize = 8 * (size - 1) + (int) sizeof (fc_tgt_hba_list_t);
2767836SJohn.Forte@Sun.COM tgthbaList = (fc_tgt_hba_list_t *)new uchar_t[bufSize];
2777836SJohn.Forte@Sun.COM tgthbaList->numPorts = size;
2787836SJohn.Forte@Sun.COM fctio.fctio_olen = bufSize;
2797836SJohn.Forte@Sun.COM fctio.fctio_obuf = (uint64_t)(uintptr_t)tgthbaList;
2807836SJohn.Forte@Sun.COM if (ioctl(fd, FCTIO_CMD, &fctio) != 0) {
2817836SJohn.Forte@Sun.COM /* Interpret the fcio error code */
2827836SJohn.Forte@Sun.COM char fcioErrorString[MAX_FCTIO_MSG_LEN] = "";
2837836SJohn.Forte@Sun.COM
2847836SJohn.Forte@Sun.COM log.genericIOError(
2857836SJohn.Forte@Sun.COM "TGT_ADAPTER_LIST failed: "
2867836SJohn.Forte@Sun.COM "Errno: \"%s\"",
2877836SJohn.Forte@Sun.COM strerror(errno));
2887836SJohn.Forte@Sun.COM delete (tgthbaList);
2897836SJohn.Forte@Sun.COM close(fd);
2907836SJohn.Forte@Sun.COM if (errno == EBUSY) {
2917836SJohn.Forte@Sun.COM throw BusyException();
2927836SJohn.Forte@Sun.COM } else if (errno == EAGAIN) {
2937836SJohn.Forte@Sun.COM throw TryAgainException();
2947836SJohn.Forte@Sun.COM } else if (errno == ENOTSUP) {
2957836SJohn.Forte@Sun.COM throw NotSupportedException();
2967836SJohn.Forte@Sun.COM } else if (errno == ENOENT) {
2977836SJohn.Forte@Sun.COM throw UnavailableException();
2987836SJohn.Forte@Sun.COM } else {
2997836SJohn.Forte@Sun.COM throw IOError("Unable to build HBA list");
3007836SJohn.Forte@Sun.COM }
3017836SJohn.Forte@Sun.COM }
3027836SJohn.Forte@Sun.COM if (tgthbaList->numPorts > size) {
3037836SJohn.Forte@Sun.COM log.debug(
3047836SJohn.Forte@Sun.COM "Buffer too small for number of target mode HBAs. Retrying.");
3057836SJohn.Forte@Sun.COM size = tgthbaList->numPorts;
3067836SJohn.Forte@Sun.COM retry = true;
3077836SJohn.Forte@Sun.COM delete (tgthbaList);
3087836SJohn.Forte@Sun.COM }
3097836SJohn.Forte@Sun.COM } while (retry);
3107836SJohn.Forte@Sun.COM
3117836SJohn.Forte@Sun.COM close(fd);
3127836SJohn.Forte@Sun.COM log.debug("Detected %d target mode adapters", tgthbaList->numPorts);
3137836SJohn.Forte@Sun.COM for (int i = 0; i < tgthbaList->numPorts; i++) {
3147836SJohn.Forte@Sun.COM try {
3157836SJohn.Forte@Sun.COM std::string hbapath = FCT_ADAPTER_NAME_PREFIX.c_str();
3167836SJohn.Forte@Sun.COM hbapath += ".";
317*10275SReed.Liu@Sun.COM // move the row with two dimentional uint8 array for WWN
3187836SJohn.Forte@Sun.COM uint64_t tmp = ntohll(*((uint64_t *)&tgthbaList->port_wwn[i][0]));
3197836SJohn.Forte@Sun.COM sprintf(wwnStr, "%llx", tmp);
3207836SJohn.Forte@Sun.COM hbapath += wwnStr;
321*10275SReed.Liu@Sun.COM
3227836SJohn.Forte@Sun.COM HBA *hba = new TgtFCHBA(hbapath);
3237836SJohn.Forte@Sun.COM list.insert(list.begin(), hba);
3247836SJohn.Forte@Sun.COM } catch (...) {
3257836SJohn.Forte@Sun.COM log.debug(
3267836SJohn.Forte@Sun.COM "Ignoring partial failure while loading an HBA");
3277836SJohn.Forte@Sun.COM }
3287836SJohn.Forte@Sun.COM }
3297836SJohn.Forte@Sun.COM if (tgthbaList->numPorts > HBAList::HBA_MAX_PER_LIST) {
3307836SJohn.Forte@Sun.COM delete(tgthbaList);
3317836SJohn.Forte@Sun.COM throw InternalError(
3327836SJohn.Forte@Sun.COM "Exceeds max number of adatpers that VSL supports.");
3337836SJohn.Forte@Sun.COM }
3347836SJohn.Forte@Sun.COM delete (tgthbaList);
3357836SJohn.Forte@Sun.COM }
336