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
FCHBA(string path)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
getName()146fcf3ce44SJohn Forte std::string FCHBA::getName() {
147fcf3ce44SJohn Forte Trace log("FCHBA::getName");
148fcf3ce44SJohn Forte return (name);
149fcf3ce44SJohn Forte }
150fcf3ce44SJohn Forte
getHBAAttributes()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
doForceLip()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
npivGetHBAAttributes()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
loadAdapters(vector<HBA * > & list)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