4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 #include "FCHBANPIVPort.h"
28 #include <Exceptions.h>
33 #include <sys/types.h>
34 #include <sys/mkdev.h>
40 #include <sys/fibre-channel/fc.h>
41 #include <sys/fibre-channel/fcio.h>
42 #include <sys/fibre-channel/ulp/fcp_util.h>
43 #include <sys/fibre-channel/ulp/fcsm.h>
44 #include <sys/fibre-channel/impl/fc_error.h>
45 #include <sys/fibre-channel/fc_appif.h>
46 #include <sys/scsi/generic/commands.h>
47 #include <sys/scsi/impl/commands.h>
48 #include <sys/scsi/impl/sense.h>
49 #include <sys/scsi/generic/inquiry.h>
50 #include <sys/scsi/generic/status.h>
55 const int FCHBANPIVPort::MAX_FCIO_MSG_LEN
= 256;
57 FCHBANPIVPort::FCHBANPIVPort(string thePath
) : HBANPIVPort() {
58 Trace
log("FCHBANPIVPort::FCHBANPIVPort");
59 log
.debug("Initializing HBA NPIV port %s", thePath
.c_str());
62 path
= lookupControllerPath(thePath
);
64 log
.debug("Unable to lookup controller path and number for %s",
72 HBA_NPIVATTRIBUTES attrs
= getPortAttributes(tmp
);
73 memcpy(&tmp
, &attrs
.PortWWN
, 8);
74 portWWN
= ntohll(tmp
);
75 memcpy(&tmp
, &attrs
.NodeWWN
, 8);
76 nodeWWN
= ntohll(tmp
);
80 HBA_NPIVATTRIBUTES
FCHBANPIVPort::getPortAttributes(uint64_t &stateChange
) {
81 Trace
log("FCHBANPIVPort::getPortAttributes");
83 HBA_NPIVATTRIBUTES attributes
;
85 fc_hba_npiv_attributes_t attrs
;
87 memset(&fcio
, 0, sizeof (fcio
));
88 memset(&attributes
, 0, sizeof (attributes
));
89 fcio
.fcio_cmd
= FCIO_GET_NPIV_ATTRIBUTES
;
90 fcio
.fcio_olen
= sizeof (attrs
);
91 fcio
.fcio_xfer
= FCIO_XFER_READ
;
92 fcio
.fcio_obuf
= (caddr_t
)&attrs
;
93 fp_ioctl(getPath(), FCIO_CMD
, &fcio
);
95 stateChange
= attrs
.lastChange
;
96 memcpy(&attributes
.NodeWWN
, &attrs
.NodeWWN
, 8);
97 memcpy(&attributes
.PortWWN
, &attrs
.PortWWN
, 8);
103 void FCHBANPIVPort::fp_ioctl(string path
, int cmd
, fcio_t
*fcio
) {
104 Trace
log("FCHBANPIVPort::fp_ioctl");
106 char fcioErrorString
[MAX_FCIO_MSG_LEN
] = "";
107 int fd
= HBA::_open(path
, O_NDELAY
| O_RDONLY
);
111 HBA::_ioctl(fd
, cmd
, (uchar_t
*)fcio
);
112 while (fcio
->fcio_errno
== FC_STATEC_BUSY
) {
114 HBA::_ioctl(fd
, cmd
, (uchar_t
*)fcio
);
120 if (fcio
->fcio_errno
) {
121 throw IOError("IOCTL transport failure");
125 transportError(fcio
->fcio_errno
, fcioErrorString
);
126 log
.genericIOError("NPIV Port ioctl (0x%x) failed. Transport: \"%s\"", cmd
,
128 switch (fcio
->fcio_errno
) {
130 throw IllegalWWNException();
132 throw IllegalWWNException();
134 throw IllegalIndexException();
140 throw BusyException();
150 * Interpret the error code in the fcio_t structure
152 * message must be at least MAX_FCIO_MSG_LEN in length.
155 FCHBANPIVPort::transportError(uint32_t fcio_errno
, char *message
) {
156 Trace
log("transportError");
158 string fcioErrorString
;
159 if (message
== NULL
) {
160 log
.internalError("NULL routine argument");
163 switch (fcio_errno
) {
164 case (uint32_t)FC_FAILURE
:
165 fcioErrorString
= "general failure";
167 case (uint32_t)FC_FAILURE_SILENT
:
168 fcioErrorString
= "general failure but fail silently";
171 fcioErrorString
= "successful completion";
174 fcioErrorString
= "FCA capability error";
177 fcioErrorString
= "FCA capability unsettable";
179 case FC_CAP_SETTABLE
:
180 fcioErrorString
= "FCA capability settable";
183 fcioErrorString
= "unbound stuff";
186 fcioErrorString
= "allocation error";
189 fcioErrorString
= "invalid packet specified/supplied";
192 fcioErrorString
= "I/O resource unavailable";
195 fcioErrorString
= "operation on non-loop port";
198 fcioErrorString
= "requested map unavailable";
200 case FC_TRANSPORT_ERROR
:
201 fcioErrorString
= "unable to transport I/O";
204 fcioErrorString
= "ELS rejected by a Fabric";
207 fcioErrorString
= "ELS rejected by an N_port";
210 fcioErrorString
= "ELS rejected by FCA/fctl";
212 case FC_ELS_MALFORMED
:
213 fcioErrorString
= "poorly formed ELS request";
216 fcioErrorString
= "resource request too large";
219 fcioErrorString
= "invalid unsolicited buffer token";
222 fcioErrorString
= "invalid unsol buf request";
225 fcioErrorString
= "buffer already in use";
228 fcioErrorString
= "Unknown ulp";
231 fcioErrorString
= "ULP not registered to handle this FC4 type";
234 fcioErrorString
= "request or data not claimed";
236 case FC_ULP_SAMEMODULE
:
237 fcioErrorString
= "module already in use";
239 case FC_ULP_SAMETYPE
:
240 fcioErrorString
= "FC4 module already in use";
243 fcioErrorString
= "request aborted";
245 case FC_ABORT_FAILED
:
246 fcioErrorString
= "abort request failed";
249 fcioErrorString
= "exchange doesn\325t exist";
252 fcioErrorString
= "WWN not recognized";
255 fcioErrorString
= "device unrecognized";
258 fcioErrorString
= "invalid command issued";
261 fcioErrorString
= "invalid object requested";
264 fcioErrorString
= "invalid port specified";
267 fcioErrorString
= "resource not at this port";
270 fcioErrorString
= "reject at remote N_Port";
273 fcioErrorString
= "reject at remote Fabric";
276 fcioErrorString
= "remote N_Port busy";
279 fcioErrorString
= "remote Fabric busy";
282 fcioErrorString
= "already logged in";
285 fcioErrorString
= "login required";
288 fcioErrorString
= "reset failed";
290 case FC_INVALID_REQUEST
:
291 fcioErrorString
= "request is invalid";
294 fcioErrorString
= "port number is out of bounds";
297 fcioErrorString
= "command transport busy";
300 fcioErrorString
= "port driver currently busy";
303 fcioErrorString
= "transport working on this device";
305 case FC_DEVICE_NOT_TGT
:
306 fcioErrorString
= "device is not a SCSI target";
309 snprintf(message
, MAX_FCIO_MSG_LEN
, "Unknown error code 0x%x",
313 snprintf(message
, MAX_FCIO_MSG_LEN
, "%s", fcioErrorString
.c_str());