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 /*
22c946facaSallan * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23fcf3ce44SJohn Forte * Use is subject to license terms.
24fcf3ce44SJohn Forte */
25fcf3ce44SJohn Forte
26fcf3ce44SJohn Forte
27fcf3ce44SJohn Forte
28fcf3ce44SJohn Forte #include <TgtFCHBAPort.h>
29fcf3ce44SJohn Forte #include <Exceptions.h>
30fcf3ce44SJohn Forte #include <Trace.h>
31fcf3ce44SJohn Forte #include <sun_fc.h>
32fcf3ce44SJohn Forte #include <iostream>
33fcf3ce44SJohn Forte #include <iomanip>
34fcf3ce44SJohn Forte #include <sys/types.h>
35fcf3ce44SJohn Forte #include <sys/mkdev.h>
36fcf3ce44SJohn Forte #include <sys/stat.h>
37fcf3ce44SJohn Forte #include <fcntl.h>
38fcf3ce44SJohn Forte #include <unistd.h>
39fcf3ce44SJohn Forte #include <stropts.h>
40fcf3ce44SJohn Forte #include <dirent.h>
41fcf3ce44SJohn Forte #include <sys/fibre-channel/fc.h>
42fcf3ce44SJohn Forte #include <sys/fctio.h>
43fcf3ce44SJohn Forte #include <sys/fibre-channel/impl/fc_error.h>
44fcf3ce44SJohn Forte #include <sys/fibre-channel/fc_appif.h>
45fcf3ce44SJohn Forte #include <sys/scsi/generic/commands.h>
46fcf3ce44SJohn Forte #include <sys/scsi/impl/commands.h>
47fcf3ce44SJohn Forte #include <sys/scsi/impl/sense.h>
48fcf3ce44SJohn Forte #include <sys/scsi/generic/inquiry.h>
49fcf3ce44SJohn Forte #include <sys/scsi/generic/status.h>
50fcf3ce44SJohn Forte #include <errno.h>
51*f3aaec0aSRichard Lowe #include <cstdlib>
52fcf3ce44SJohn Forte
53fcf3ce44SJohn Forte
54fcf3ce44SJohn Forte using namespace std;
55fcf3ce44SJohn Forte
56fcf3ce44SJohn Forte const int TgtFCHBAPort::MAX_FCTIO_MSG_LEN = 256;
57fcf3ce44SJohn Forte const string TgtFCHBAPort::FCT_DRIVER_PATH = "/devices/pseudo/fct@0:admin";
58fcf3ce44SJohn Forte
59fcf3ce44SJohn Forte /*
60fcf3ce44SJohn Forte * Interpret the error code in the fctio_t structure
61fcf3ce44SJohn Forte *
62fcf3ce44SJohn Forte * message must be at least MAX_FCTIO_MSG_LEN in length.
63fcf3ce44SJohn Forte */
64fcf3ce44SJohn Forte void
transportError(uint32_t fctio_errno,char * message)65fcf3ce44SJohn Forte TgtFCHBAPort::transportError(uint32_t fctio_errno, char *message) {
66fcf3ce44SJohn Forte Trace log("transportError");
67fcf3ce44SJohn Forte string fcioErrorString;
68fcf3ce44SJohn Forte if (message == NULL) {
69fcf3ce44SJohn Forte log.internalError("NULL routine argument");
70fcf3ce44SJohn Forte return;
71fcf3ce44SJohn Forte }
72fcf3ce44SJohn Forte switch (fctio_errno) {
73fcf3ce44SJohn Forte case (uint32_t)FC_FAILURE:
74fcf3ce44SJohn Forte fcioErrorString = "general failure";
75fcf3ce44SJohn Forte break;
76fcf3ce44SJohn Forte case (uint32_t)FC_FAILURE_SILENT:
77fcf3ce44SJohn Forte fcioErrorString = "general failure but fail silently";
78fcf3ce44SJohn Forte break;
79fcf3ce44SJohn Forte case FC_SUCCESS:
80fcf3ce44SJohn Forte fcioErrorString = "successful completion";
81fcf3ce44SJohn Forte break;
82fcf3ce44SJohn Forte case FC_CAP_ERROR:
83fcf3ce44SJohn Forte fcioErrorString = "FCA capability error";
84fcf3ce44SJohn Forte break;
85fcf3ce44SJohn Forte case FC_CAP_FOUND:
86fcf3ce44SJohn Forte fcioErrorString = "FCA capability unsettable";
87fcf3ce44SJohn Forte break;
88fcf3ce44SJohn Forte case FC_CAP_SETTABLE:
89fcf3ce44SJohn Forte fcioErrorString = "FCA capability settable";
90fcf3ce44SJohn Forte break;
91fcf3ce44SJohn Forte case FC_UNBOUND:
92fcf3ce44SJohn Forte fcioErrorString = "unbound stuff";
93fcf3ce44SJohn Forte break;
94fcf3ce44SJohn Forte case FC_NOMEM:
95fcf3ce44SJohn Forte fcioErrorString = "allocation error";
96fcf3ce44SJohn Forte break;
97fcf3ce44SJohn Forte case FC_BADPACKET:
98fcf3ce44SJohn Forte fcioErrorString = "invalid packet specified/supplied";
99fcf3ce44SJohn Forte break;
100fcf3ce44SJohn Forte case FC_OFFLINE:
101fcf3ce44SJohn Forte fcioErrorString = "I/O resource unavailable";
102fcf3ce44SJohn Forte break;
103fcf3ce44SJohn Forte case FC_OLDPORT:
104fcf3ce44SJohn Forte fcioErrorString = "operation on non-loop port";
105fcf3ce44SJohn Forte break;
106fcf3ce44SJohn Forte case FC_NO_MAP:
107fcf3ce44SJohn Forte fcioErrorString = "requested map unavailable";
108fcf3ce44SJohn Forte break;
109fcf3ce44SJohn Forte case FC_TRANSPORT_ERROR:
110fcf3ce44SJohn Forte fcioErrorString = "unable to transport I/O";
111fcf3ce44SJohn Forte break;
112fcf3ce44SJohn Forte case FC_ELS_FREJECT:
113fcf3ce44SJohn Forte fcioErrorString = "ELS rejected by a Fabric";
114fcf3ce44SJohn Forte break;
115fcf3ce44SJohn Forte case FC_ELS_PREJECT:
116fcf3ce44SJohn Forte fcioErrorString = "ELS rejected by an N_port";
117fcf3ce44SJohn Forte break;
118fcf3ce44SJohn Forte case FC_ELS_BAD:
119fcf3ce44SJohn Forte fcioErrorString = "ELS rejected by FCA/fctl";
120fcf3ce44SJohn Forte break;
121fcf3ce44SJohn Forte case FC_ELS_MALFORMED:
122fcf3ce44SJohn Forte fcioErrorString = "poorly formed ELS request";
123fcf3ce44SJohn Forte break;
124fcf3ce44SJohn Forte case FC_TOOMANY:
125fcf3ce44SJohn Forte fcioErrorString = "resource request too large";
126fcf3ce44SJohn Forte break;
127fcf3ce44SJohn Forte case FC_UB_BADTOKEN:
128fcf3ce44SJohn Forte fcioErrorString = "invalid unsolicited buffer token";
129fcf3ce44SJohn Forte break;
130fcf3ce44SJohn Forte case FC_UB_ERROR:
131fcf3ce44SJohn Forte fcioErrorString = "invalid unsol buf request";
132fcf3ce44SJohn Forte break;
133fcf3ce44SJohn Forte case FC_UB_BUSY:
134fcf3ce44SJohn Forte fcioErrorString = "buffer already in use";
135fcf3ce44SJohn Forte break;
136fcf3ce44SJohn Forte case FC_BADULP:
137fcf3ce44SJohn Forte fcioErrorString = "Unknown ulp";
138fcf3ce44SJohn Forte break;
139fcf3ce44SJohn Forte case FC_BADTYPE:
140fcf3ce44SJohn Forte fcioErrorString = "ULP not registered to handle this FC4 type";
141fcf3ce44SJohn Forte break;
142fcf3ce44SJohn Forte case FC_UNCLAIMED:
143fcf3ce44SJohn Forte fcioErrorString = "request or data not claimed";
144fcf3ce44SJohn Forte break;
145fcf3ce44SJohn Forte case FC_ULP_SAMEMODULE:
146fcf3ce44SJohn Forte fcioErrorString = "module already in use";
147fcf3ce44SJohn Forte break;
148fcf3ce44SJohn Forte case FC_ULP_SAMETYPE:
149fcf3ce44SJohn Forte fcioErrorString = "FC4 module already in use";
150fcf3ce44SJohn Forte break;
151fcf3ce44SJohn Forte case FC_ABORTED:
152fcf3ce44SJohn Forte fcioErrorString = "request aborted";
153fcf3ce44SJohn Forte break;
154fcf3ce44SJohn Forte case FC_ABORT_FAILED:
155fcf3ce44SJohn Forte fcioErrorString = "abort request failed";
156fcf3ce44SJohn Forte break;
157fcf3ce44SJohn Forte case FC_BADEXCHANGE:
158fcf3ce44SJohn Forte fcioErrorString = "exchange doesn�t exist";
159fcf3ce44SJohn Forte break;
160fcf3ce44SJohn Forte case FC_BADWWN:
161fcf3ce44SJohn Forte fcioErrorString = "WWN not recognized";
162fcf3ce44SJohn Forte break;
163fcf3ce44SJohn Forte case FC_BADDEV:
164fcf3ce44SJohn Forte fcioErrorString = "device unrecognized";
165fcf3ce44SJohn Forte break;
166fcf3ce44SJohn Forte case FC_BADCMD:
167fcf3ce44SJohn Forte fcioErrorString = "invalid command issued";
168fcf3ce44SJohn Forte break;
169fcf3ce44SJohn Forte case FC_BADOBJECT:
170fcf3ce44SJohn Forte fcioErrorString = "invalid object requested";
171fcf3ce44SJohn Forte break;
172fcf3ce44SJohn Forte case FC_BADPORT:
173fcf3ce44SJohn Forte fcioErrorString = "invalid port specified";
174fcf3ce44SJohn Forte break;
175fcf3ce44SJohn Forte case FC_NOTTHISPORT:
176fcf3ce44SJohn Forte fcioErrorString = "resource not at this port";
177fcf3ce44SJohn Forte break;
178fcf3ce44SJohn Forte case FC_PREJECT:
179fcf3ce44SJohn Forte fcioErrorString = "reject at remote N_Port";
180fcf3ce44SJohn Forte break;
181fcf3ce44SJohn Forte case FC_FREJECT:
182fcf3ce44SJohn Forte fcioErrorString = "reject at remote Fabric";
183fcf3ce44SJohn Forte break;
184fcf3ce44SJohn Forte case FC_PBUSY:
185fcf3ce44SJohn Forte fcioErrorString = "remote N_Port busy";
186fcf3ce44SJohn Forte break;
187fcf3ce44SJohn Forte case FC_FBUSY:
188fcf3ce44SJohn Forte fcioErrorString = "remote Fabric busy";
189fcf3ce44SJohn Forte break;
190fcf3ce44SJohn Forte case FC_ALREADY:
191fcf3ce44SJohn Forte fcioErrorString = "already logged in";
192fcf3ce44SJohn Forte break;
193fcf3ce44SJohn Forte case FC_LOGINREQ:
194fcf3ce44SJohn Forte fcioErrorString = "login required";
195fcf3ce44SJohn Forte break;
196fcf3ce44SJohn Forte case FC_RESETFAIL:
197fcf3ce44SJohn Forte fcioErrorString = "reset failed";
198fcf3ce44SJohn Forte break;
199fcf3ce44SJohn Forte case FC_INVALID_REQUEST:
200fcf3ce44SJohn Forte fcioErrorString = "request is invalid";
201fcf3ce44SJohn Forte break;
202fcf3ce44SJohn Forte case FC_OUTOFBOUNDS:
203fcf3ce44SJohn Forte fcioErrorString = "port number is out of bounds";
204fcf3ce44SJohn Forte break;
205fcf3ce44SJohn Forte case FC_TRAN_BUSY:
206fcf3ce44SJohn Forte fcioErrorString = "command transport busy";
207fcf3ce44SJohn Forte break;
208fcf3ce44SJohn Forte case FC_STATEC_BUSY:
209fcf3ce44SJohn Forte fcioErrorString = "port driver currently busy";
210fcf3ce44SJohn Forte break;
211fcf3ce44SJohn Forte case FC_DEVICE_BUSY:
212fcf3ce44SJohn Forte fcioErrorString = "transport working on this device";
213fcf3ce44SJohn Forte break;
214fcf3ce44SJohn Forte case FC_DEVICE_NOT_TGT:
215fcf3ce44SJohn Forte fcioErrorString = "device is not a SCSI target";
216fcf3ce44SJohn Forte break;
217fcf3ce44SJohn Forte default:
218fcf3ce44SJohn Forte snprintf(message, MAX_FCTIO_MSG_LEN, "Unknown error code 0x%x",
219fcf3ce44SJohn Forte fctio_errno);
220fcf3ce44SJohn Forte return;
221fcf3ce44SJohn Forte }
222fcf3ce44SJohn Forte snprintf(message, MAX_FCTIO_MSG_LEN, "%s", fcioErrorString.c_str());
223fcf3ce44SJohn Forte }
224fcf3ce44SJohn Forte
TgtFCHBAPort(string thePath)225fcf3ce44SJohn Forte TgtFCHBAPort::TgtFCHBAPort(string thePath) : HBAPort() {
226fcf3ce44SJohn Forte Trace log("TgtFCHBAPort::TgtFCHBAPort");
227fcf3ce44SJohn Forte log.debug("Initializing HBA port %s", path.c_str());
228fcf3ce44SJohn Forte path = thePath;
229fcf3ce44SJohn Forte
230fcf3ce44SJohn Forte // This routine is not index based, so we can discard stateChange
231fcf3ce44SJohn Forte uint64_t tmp;
232fcf3ce44SJohn Forte HBA_PORTATTRIBUTES attrs = getPortAttributes(tmp);
233fcf3ce44SJohn Forte memcpy(&tmp, &attrs.PortWWN, 8);
234fcf3ce44SJohn Forte portWWN = ntohll(tmp);
235fcf3ce44SJohn Forte memcpy(&tmp, &attrs.NodeWWN, 8);
236fcf3ce44SJohn Forte nodeWWN = ntohll(tmp);
237fcf3ce44SJohn Forte
238fcf3ce44SJohn Forte // For reference, here's how to dump WWN's through C++ streams.
239fcf3ce44SJohn Forte // cout << "\tPort WWN: " << hex << setfill('0') << setw(16) << portWWN
240fcf3ce44SJohn Forte // << endl;
241fcf3ce44SJohn Forte // cout << "\tNode WWN: " << hex << setfill('0') << setw(16) << nodeWWN
242fcf3ce44SJohn Forte // << endl;
243fcf3ce44SJohn Forte }
244fcf3ce44SJohn Forte
getPortAttributes(uint64_t & stateChange)245fcf3ce44SJohn Forte HBA_PORTATTRIBUTES TgtFCHBAPort::getPortAttributes(uint64_t &stateChange) {
246fcf3ce44SJohn Forte Trace log("TgtFCHBAPort::getPortAttributes");
247fcf3ce44SJohn Forte
248fcf3ce44SJohn Forte HBA_PORTATTRIBUTES attributes;
249fcf3ce44SJohn Forte fctio_t fctio;
250fcf3ce44SJohn Forte fc_tgt_hba_port_attributes_t attrs;
251fcf3ce44SJohn Forte
252fcf3ce44SJohn Forte memset(&fctio, 0, sizeof (fctio));
253fcf3ce44SJohn Forte memset(&attributes, 0, sizeof (attributes));
254fcf3ce44SJohn Forte
255fcf3ce44SJohn Forte uint64_t portwwn = 0;
256fcf3ce44SJohn Forte try {
257fcf3ce44SJohn Forte string::size_type offset = path.find_last_of(".");
258fcf3ce44SJohn Forte if (offset >= 0) {
259fcf3ce44SJohn Forte string portwwnString = path.substr(offset+1);
260fcf3ce44SJohn Forte portwwn = strtoull(portwwnString.c_str(), NULL, 16);
261fcf3ce44SJohn Forte }
262fcf3ce44SJohn Forte } catch (...) {
263fcf3ce44SJohn Forte throw BadArgumentException();
264fcf3ce44SJohn Forte }
265fcf3ce44SJohn Forte
266fcf3ce44SJohn Forte uint64_t en_wwn = htonll(portwwn);
267fcf3ce44SJohn Forte
268fcf3ce44SJohn Forte fctio.fctio_cmd = FCTIO_GET_ADAPTER_PORT_ATTRIBUTES;
269fcf3ce44SJohn Forte fctio.fctio_ilen = 8;
270fcf3ce44SJohn Forte fctio.fctio_ibuf = (uint64_t)(uintptr_t)&en_wwn;
271fcf3ce44SJohn Forte fctio.fctio_xfer = FCTIO_XFER_READ;
272fcf3ce44SJohn Forte fctio.fctio_olen = (uint32_t)(sizeof (attrs));
273fcf3ce44SJohn Forte fctio.fctio_obuf = (uint64_t)(uintptr_t)&attrs;
274fcf3ce44SJohn Forte
275fcf3ce44SJohn Forte fct_ioctl(FCTIO_CMD, &fctio);
276fcf3ce44SJohn Forte
277fcf3ce44SJohn Forte stateChange = attrs.lastChange;
278fcf3ce44SJohn Forte
279fcf3ce44SJohn Forte attributes.PortFcId = attrs.PortFcId;
280fcf3ce44SJohn Forte attributes.PortType = attrs.PortType;
281fcf3ce44SJohn Forte attributes.PortState = attrs.PortState;
282fcf3ce44SJohn Forte attributes.PortSupportedClassofService = attrs.PortSupportedClassofService;
283fcf3ce44SJohn Forte attributes.PortSupportedSpeed = attrs.PortSupportedSpeed;
284fcf3ce44SJohn Forte attributes.PortSpeed = attrs.PortSpeed;
285fcf3ce44SJohn Forte attributes.PortMaxFrameSize = attrs.PortMaxFrameSize;
286fcf3ce44SJohn Forte attributes.NumberofDiscoveredPorts = attrs.NumberofDiscoveredPorts;
287fcf3ce44SJohn Forte memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8);
288fcf3ce44SJohn Forte memcpy(&attributes.PortWWN, &attrs.PortWWN, 8);
289fcf3ce44SJohn Forte memcpy(&attributes.FabricName, &attrs.FabricName, 8);
290fcf3ce44SJohn Forte memcpy(&attributes.PortSupportedFc4Types, &attrs.PortSupportedFc4Types, 32);
291fcf3ce44SJohn Forte memcpy(&attributes.PortActiveFc4Types, &attrs.PortActiveFc4Types, 32);
292fcf3ce44SJohn Forte memcpy(&attributes.PortSymbolicName, &attrs.PortSymbolicName, 256);
293fcf3ce44SJohn Forte
294fcf3ce44SJohn Forte strncpy((char *)attributes.OSDeviceName, "Not Applicable", 15);
295fcf3ce44SJohn Forte return (attributes);
296fcf3ce44SJohn Forte }
297fcf3ce44SJohn Forte
getDiscoveredAttributes(HBA_UINT32 discoveredport,uint64_t & stateChange)298fcf3ce44SJohn Forte HBA_PORTATTRIBUTES TgtFCHBAPort::getDiscoveredAttributes(
299fcf3ce44SJohn Forte HBA_UINT32 discoveredport, uint64_t &stateChange) {
300fcf3ce44SJohn Forte Trace log("TgtFCHBAPort::getDiscoverdAttributes(i)");
301fcf3ce44SJohn Forte
302fcf3ce44SJohn Forte HBA_PORTATTRIBUTES attributes;
303fcf3ce44SJohn Forte fctio_t fctio;
304fcf3ce44SJohn Forte fc_tgt_hba_port_attributes_t attrs;
305fcf3ce44SJohn Forte
306fcf3ce44SJohn Forte memset(&fctio, 0, sizeof (fctio));
307fcf3ce44SJohn Forte memset(&attributes, 0, sizeof (attributes));
308fcf3ce44SJohn Forte
309fcf3ce44SJohn Forte uint64_t portwwn = 0;
310fcf3ce44SJohn Forte try {
311fcf3ce44SJohn Forte string::size_type offset = path.find_last_of(".");
312fcf3ce44SJohn Forte if (offset >= 0) {
313fcf3ce44SJohn Forte string portwwnString = path.substr(offset+1);
314fcf3ce44SJohn Forte portwwn = strtoull(portwwnString.c_str(), NULL, 16);
315fcf3ce44SJohn Forte }
316fcf3ce44SJohn Forte } catch (...) {
317fcf3ce44SJohn Forte throw BadArgumentException();
318fcf3ce44SJohn Forte }
319fcf3ce44SJohn Forte
320fcf3ce44SJohn Forte uint64_t en_wwn = htonll(portwwn);
321fcf3ce44SJohn Forte
322fcf3ce44SJohn Forte fctio.fctio_cmd = FCTIO_GET_DISCOVERED_PORT_ATTRIBUTES;
323fcf3ce44SJohn Forte fctio.fctio_ilen = 8;
324fcf3ce44SJohn Forte fctio.fctio_ibuf = (uint64_t)(uintptr_t)&en_wwn;
325fcf3ce44SJohn Forte fctio.fctio_xfer = FCTIO_XFER_READ;
326fcf3ce44SJohn Forte fctio.fctio_olen = (uint32_t)(sizeof (attrs));
327fcf3ce44SJohn Forte fctio.fctio_obuf = (uint64_t)(uintptr_t)&attrs;
328fcf3ce44SJohn Forte fctio.fctio_alen = (uint32_t)(sizeof (discoveredport));
329fcf3ce44SJohn Forte fctio.fctio_abuf = (uint64_t)(uintptr_t)&discoveredport;
330fcf3ce44SJohn Forte
331fcf3ce44SJohn Forte fct_ioctl(FCTIO_CMD, &fctio);
332fcf3ce44SJohn Forte
333fcf3ce44SJohn Forte stateChange = attrs.lastChange;
334fcf3ce44SJohn Forte
335fcf3ce44SJohn Forte attributes.PortFcId = attrs.PortFcId;
336fcf3ce44SJohn Forte attributes.PortType = attrs.PortType;
337fcf3ce44SJohn Forte attributes.PortState = attrs.PortState;
338fcf3ce44SJohn Forte attributes.PortSupportedClassofService = attrs.PortSupportedClassofService;
339fcf3ce44SJohn Forte attributes.PortSupportedSpeed = attrs.PortSupportedSpeed;
340fcf3ce44SJohn Forte attributes.PortSpeed = attrs.PortSpeed;
341fcf3ce44SJohn Forte attributes.PortMaxFrameSize = attrs.PortMaxFrameSize;
342fcf3ce44SJohn Forte attributes.NumberofDiscoveredPorts = attrs.NumberofDiscoveredPorts;
343fcf3ce44SJohn Forte memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8);
344fcf3ce44SJohn Forte memcpy(&attributes.PortWWN, &attrs.PortWWN, 8);
345fcf3ce44SJohn Forte memcpy(&attributes.FabricName, &attrs.FabricName, 8);
346fcf3ce44SJohn Forte memcpy(&attributes.PortSupportedFc4Types, &attrs.PortSupportedFc4Types, 32);
347fcf3ce44SJohn Forte memcpy(&attributes.PortActiveFc4Types, &attrs.PortActiveFc4Types, 32);
348fcf3ce44SJohn Forte memcpy(&attributes.PortSymbolicName, &attrs.PortSymbolicName, 256);
349fcf3ce44SJohn Forte
350fcf3ce44SJohn Forte
351fcf3ce44SJohn Forte return (attributes);
352fcf3ce44SJohn Forte }
353fcf3ce44SJohn Forte
getDiscoveredAttributes(uint64_t wwn,uint64_t & stateChange)354fcf3ce44SJohn Forte HBA_PORTATTRIBUTES TgtFCHBAPort::getDiscoveredAttributes(
355fcf3ce44SJohn Forte uint64_t wwn, uint64_t &stateChange) {
356fcf3ce44SJohn Forte Trace log("TgtFCHBAPort::getDiscoverdAttributes(p)");
357fcf3ce44SJohn Forte
358fcf3ce44SJohn Forte HBA_PORTATTRIBUTES attributes;
359fcf3ce44SJohn Forte fctio_t fctio;
360fcf3ce44SJohn Forte fc_tgt_hba_port_attributes_t attrs;
361fcf3ce44SJohn Forte
362fcf3ce44SJohn Forte memset(&fctio, 0, sizeof (fctio));
363fcf3ce44SJohn Forte memset(&attributes, 0, sizeof (attributes));
364fcf3ce44SJohn Forte
365fcf3ce44SJohn Forte uint64_t en_wwn = htonll(wwn);
366fcf3ce44SJohn Forte
367fcf3ce44SJohn Forte fctio.fctio_cmd = FCTIO_GET_PORT_ATTRIBUTES;
368fcf3ce44SJohn Forte fctio.fctio_olen = (uint32_t)(sizeof (attrs));
369fcf3ce44SJohn Forte fctio.fctio_xfer = FCTIO_XFER_READ;
370fcf3ce44SJohn Forte fctio.fctio_obuf = (uint64_t)(uintptr_t)&attrs;
371fcf3ce44SJohn Forte fctio.fctio_ilen = (uint32_t)(sizeof (wwn));
372fcf3ce44SJohn Forte fctio.fctio_ibuf = (uint64_t)(uintptr_t)&en_wwn;
373fcf3ce44SJohn Forte
374fcf3ce44SJohn Forte fct_ioctl(FCTIO_CMD, &fctio);
375fcf3ce44SJohn Forte
376fcf3ce44SJohn Forte stateChange = attrs.lastChange;
377fcf3ce44SJohn Forte
378fcf3ce44SJohn Forte attributes.PortFcId = attrs.PortFcId;
379fcf3ce44SJohn Forte attributes.PortType = attrs.PortType;
380fcf3ce44SJohn Forte attributes.PortState = attrs.PortState;
381fcf3ce44SJohn Forte attributes.PortSupportedClassofService = attrs.PortSupportedClassofService;
382fcf3ce44SJohn Forte attributes.PortSupportedSpeed = attrs.PortSupportedSpeed;
383fcf3ce44SJohn Forte attributes.PortSpeed = attrs.PortSpeed;
384fcf3ce44SJohn Forte attributes.PortMaxFrameSize = attrs.PortMaxFrameSize;
385fcf3ce44SJohn Forte attributes.NumberofDiscoveredPorts = attrs.NumberofDiscoveredPorts;
386fcf3ce44SJohn Forte memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8);
387fcf3ce44SJohn Forte memcpy(&attributes.PortWWN, &attrs.PortWWN, 8);
388fcf3ce44SJohn Forte memcpy(&attributes.FabricName, &attrs.FabricName, 8);
389fcf3ce44SJohn Forte memcpy(&attributes.PortSupportedFc4Types, &attrs.PortSupportedFc4Types, 32);
390fcf3ce44SJohn Forte memcpy(&attributes.PortActiveFc4Types, &attrs.PortActiveFc4Types, 32);
391fcf3ce44SJohn Forte memcpy(&attributes.PortSymbolicName, &attrs.PortSymbolicName, 256);
392fcf3ce44SJohn Forte
393fcf3ce44SJohn Forte
394fcf3ce44SJohn Forte return (attributes);
395fcf3ce44SJohn Forte }
396fcf3ce44SJohn Forte
sendRLS(uint64_t destWWN,void * pRspBuffer,HBA_UINT32 * pRspBufferSize)397fcf3ce44SJohn Forte void TgtFCHBAPort::sendRLS(uint64_t destWWN,
398fcf3ce44SJohn Forte void *pRspBuffer,
399fcf3ce44SJohn Forte HBA_UINT32 *pRspBufferSize) {
400fcf3ce44SJohn Forte Trace log("FCHBAPort::sendRLS");
401fcf3ce44SJohn Forte
402fcf3ce44SJohn Forte fctio_t fctio;
403fcf3ce44SJohn Forte // fc_hba_adapter_port_stats_t fc_port_stat;
404fcf3ce44SJohn Forte uint64_t en_portWWN;
405c946facaSallan uint64_t DestPortID;
406fcf3ce44SJohn Forte
407fcf3ce44SJohn Forte // Validate the arguments
408fcf3ce44SJohn Forte if (pRspBuffer == NULL ||
409fcf3ce44SJohn Forte pRspBufferSize == NULL) {
410fcf3ce44SJohn Forte log.userError("NULL hba");
411fcf3ce44SJohn Forte throw BadArgumentException();
412fcf3ce44SJohn Forte }
413fcf3ce44SJohn Forte
414fcf3ce44SJohn Forte // check to see if we are sending RLS to the HBA
415fcf3ce44SJohn Forte HBA_PORTATTRIBUTES attrs;
416fcf3ce44SJohn Forte uint64_t tmp;
417fcf3ce44SJohn Forte portWWN = getPortWWN();
418fcf3ce44SJohn Forte en_portWWN = htonll(portWWN);
419fcf3ce44SJohn Forte
420fcf3ce44SJohn Forte /* The destWWN is either the adapter port or a discovered port. */
421fcf3ce44SJohn Forte memset(&fctio, 0, sizeof (fctio));
422c946facaSallan fctio.fctio_cmd = FCTIO_GET_LINK_STATUS;
423fcf3ce44SJohn Forte fctio.fctio_ibuf = (uint64_t)(uintptr_t)&en_portWWN;
424fcf3ce44SJohn Forte fctio.fctio_ilen = (uint32_t)(sizeof (en_portWWN));
425fcf3ce44SJohn Forte if (portWWN != destWWN) {
426fcf3ce44SJohn Forte attrs = getDiscoveredAttributes(destWWN, tmp);
427c946facaSallan DestPortID = (uint64_t)attrs.PortFcId;
428c946facaSallan fctio.fctio_abuf = (uint64_t)(uintptr_t)&DestPortID;
429c946facaSallan fctio.fctio_alen = (uint32_t)(sizeof (DestPortID));
430fcf3ce44SJohn Forte }
431fcf3ce44SJohn Forte fctio.fctio_xfer = FCTIO_XFER_READ;
432fcf3ce44SJohn Forte fctio.fctio_flags = 0;
433fcf3ce44SJohn Forte fctio.fctio_obuf = (uint64_t)(uintptr_t)new uchar_t[*pRspBufferSize];
434fcf3ce44SJohn Forte fctio.fctio_olen = *pRspBufferSize;
435fcf3ce44SJohn Forte
436fcf3ce44SJohn Forte if (fctio.fctio_obuf == NULL) {
437fcf3ce44SJohn Forte log.noMemory();
438fcf3ce44SJohn Forte throw InternalError();
439fcf3ce44SJohn Forte }
440fcf3ce44SJohn Forte
441fcf3ce44SJohn Forte fct_ioctl(FCTIO_CMD, &fctio);
442fcf3ce44SJohn Forte memcpy(pRspBuffer, (uchar_t *)(uintptr_t)fctio.fctio_obuf,
443fcf3ce44SJohn Forte *pRspBufferSize);
444fcf3ce44SJohn Forte if (fctio.fctio_obuf != NULL) {
445fcf3ce44SJohn Forte delete((uchar_t *)(uintptr_t)fctio.fctio_obuf);
446fcf3ce44SJohn Forte }
447fcf3ce44SJohn Forte }
448fcf3ce44SJohn Forte
449fcf3ce44SJohn Forte /**
450fcf3ce44SJohn Forte * @memo Validate that the port is still present in the system
451fcf3ce44SJohn Forte * @exception UnavailableException if the port is not present
452fcf3ce44SJohn Forte * @version 1.7
453fcf3ce44SJohn Forte *
454fcf3ce44SJohn Forte * @doc If the port is still present on the system, the routine
455fcf3ce44SJohn Forte * will return normally. If the port is not present
456fcf3ce44SJohn Forte * an exception will be thrown.
457fcf3ce44SJohn Forte */
validatePresent()458fcf3ce44SJohn Forte void TgtFCHBAPort::validatePresent() {
459fcf3ce44SJohn Forte Trace log("TgtFCHBAPort::validatePresent");
460fcf3ce44SJohn Forte // We already got the adapter list through the ioctl
461fcf3ce44SJohn Forte // so calling it again to validate it is too expensive.
462fcf3ce44SJohn Forte }
463fcf3ce44SJohn Forte
fct_ioctl(int cmd,fctio_t * fctio)464fcf3ce44SJohn Forte void TgtFCHBAPort::fct_ioctl(int cmd, fctio_t *fctio) {
465fcf3ce44SJohn Forte Trace log("TgtFCHBAPort::fct_ioctl");
466fcf3ce44SJohn Forte char fcioErrorString[MAX_FCTIO_MSG_LEN] = "";
467fcf3ce44SJohn Forte int fd = HBA::_open(FCT_DRIVER_PATH, O_NDELAY | O_RDONLY);
468fcf3ce44SJohn Forte try {
469fcf3ce44SJohn Forte HBA::_ioctl(fd, cmd, (uchar_t *)fctio);
470fcf3ce44SJohn Forte close(fd);
471fcf3ce44SJohn Forte if (fctio->fctio_errno) {
472fcf3ce44SJohn Forte throw IOError("IOCTL transport failure");
473fcf3ce44SJohn Forte }
474fcf3ce44SJohn Forte } catch (...) {
475fcf3ce44SJohn Forte close(fd);
476fcf3ce44SJohn Forte transportError(fctio->fctio_errno, fcioErrorString);
477fcf3ce44SJohn Forte log.genericIOError("ioctl (0x%x) failed. Transport: \"%s\"", cmd,
478fcf3ce44SJohn Forte fcioErrorString);
479fcf3ce44SJohn Forte switch (fctio->fctio_errno) {
480fcf3ce44SJohn Forte case FC_BADWWN:
481fcf3ce44SJohn Forte throw IllegalWWNException();
482fcf3ce44SJohn Forte case FC_BADPORT:
483fcf3ce44SJohn Forte throw IllegalWWNException();
484fcf3ce44SJohn Forte case FC_OUTOFBOUNDS:
485fcf3ce44SJohn Forte throw IllegalIndexException();
486fcf3ce44SJohn Forte case FC_PBUSY:
487fcf3ce44SJohn Forte case FC_FBUSY:
488fcf3ce44SJohn Forte case FC_TRAN_BUSY:
489fcf3ce44SJohn Forte case FC_STATEC_BUSY:
490fcf3ce44SJohn Forte case FC_DEVICE_BUSY:
491fcf3ce44SJohn Forte throw BusyException();
492fcf3ce44SJohn Forte case FC_SUCCESS:
493fcf3ce44SJohn Forte default:
494fcf3ce44SJohn Forte throw;
495fcf3ce44SJohn Forte }
496fcf3ce44SJohn Forte }
497fcf3ce44SJohn Forte }
498