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 /*
22*a7949318SReed * 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 "Handle.h"
29fcf3ce44SJohn Forte #include "Exceptions.h"
30fcf3ce44SJohn Forte #include "Trace.h"
31fcf3ce44SJohn Forte #include <libdevinfo.h>
32fcf3ce44SJohn Forte #include <iostream>
33fcf3ce44SJohn Forte #include <iomanip>
34fcf3ce44SJohn Forte #include <sys/types.h>
35fcf3ce44SJohn Forte #include <sys/stat.h>
36fcf3ce44SJohn Forte #include <fcntl.h>
37fcf3ce44SJohn Forte #include <unistd.h>
38fcf3ce44SJohn Forte #include <stropts.h>
39fcf3ce44SJohn Forte
40fcf3ce44SJohn Forte #define MAX_INIT_HANDLE_ID 0x7fff
41fcf3ce44SJohn Forte #define MAX_TGT_HANDLE_ID 0xffff
42fcf3ce44SJohn Forte
43fcf3ce44SJohn Forte using namespace std;
44fcf3ce44SJohn Forte
45fcf3ce44SJohn Forte /**
46fcf3ce44SJohn Forte * Global lock for list of Handles
47fcf3ce44SJohn Forte */
48fcf3ce44SJohn Forte pthread_mutex_t Handle::staticLock = PTHREAD_MUTEX_INITIALIZER;
49fcf3ce44SJohn Forte
50fcf3ce44SJohn Forte /**
51fcf3ce44SJohn Forte * Tracking for the previous handle we have opened
52fcf3ce44SJohn Forte */
53fcf3ce44SJohn Forte HBA_HANDLE Handle::prevOpen = 0;
54fcf3ce44SJohn Forte
55fcf3ce44SJohn Forte /**
56fcf3ce44SJohn Forte * Tracking for the previous target HBA handle we have opened
57fcf3ce44SJohn Forte */
58fcf3ce44SJohn Forte HBA_HANDLE Handle::prevTgtOpen = 0x8000;
59fcf3ce44SJohn Forte
60fcf3ce44SJohn Forte /**
61fcf3ce44SJohn Forte * Global map from HBA_HANDLE to Handle pointers (our global list)
62fcf3ce44SJohn Forte */
63fcf3ce44SJohn Forte map<HBA_HANDLE, Handle*> Handle::openHandles;
64fcf3ce44SJohn Forte
65fcf3ce44SJohn Forte /**
66fcf3ce44SJohn Forte * @memo Create a new open handle for a specified HBA
67fcf3ce44SJohn Forte * @precondition HBA port(s) must be loaded
68fcf3ce44SJohn Forte * @postcondition An open handle will be present in the global tracking list
69fcf3ce44SJohn Forte * and must be closed at some point to prevent leakage. If no
70fcf3ce44SJohn Forte * handle could be assigned (the track list is full), an
71fcf3ce44SJohn Forte * exception will be thrown. Scope for valid ids in the track
72fcf3ce44SJohn Forte * list is [1, MAX_INIT_HANDLE_ID].
73fcf3ce44SJohn Forte * @param myhba The HBA to open a handle for
74fcf3ce44SJohn Forte */
Handle(HBA * myhba)75fcf3ce44SJohn Forte Handle::Handle(HBA *myhba) {
76fcf3ce44SJohn Forte map<HBA_HANDLE, Handle*>::iterator mapend;
77fcf3ce44SJohn Forte Trace log("Handle::Handle");
78fcf3ce44SJohn Forte modeVal = INITIATOR;
79fcf3ce44SJohn Forte lock(&staticLock);
80fcf3ce44SJohn Forte mapend = openHandles.end();
81fcf3ce44SJohn Forte /* Start the search for a free id from the previously assigned one */
82fcf3ce44SJohn Forte id = prevOpen + 1;
83fcf3ce44SJohn Forte while (id != prevOpen) {
84fcf3ce44SJohn Forte /* Exceeds the max valid value, continue the search from 1 */
85fcf3ce44SJohn Forte if (id > MAX_INIT_HANDLE_ID)
86fcf3ce44SJohn Forte id = 1;
87fcf3ce44SJohn Forte
88fcf3ce44SJohn Forte if (openHandles.find(id) == mapend) {
89fcf3ce44SJohn Forte /* the id is not in use */
90fcf3ce44SJohn Forte break;
91fcf3ce44SJohn Forte }
92fcf3ce44SJohn Forte id ++;
93fcf3ce44SJohn Forte }
94fcf3ce44SJohn Forte if (id == prevOpen) {
95fcf3ce44SJohn Forte /* no usable id for now */
96fcf3ce44SJohn Forte unlock(&staticLock);
97fcf3ce44SJohn Forte throw TryAgainException();
98fcf3ce44SJohn Forte }
99fcf3ce44SJohn Forte prevOpen = id;
100fcf3ce44SJohn Forte hba = myhba;
101fcf3ce44SJohn Forte openHandles[id] = this;
102fcf3ce44SJohn Forte unlock(&staticLock);
103fcf3ce44SJohn Forte }
104fcf3ce44SJohn Forte
105fcf3ce44SJohn Forte /**
106fcf3ce44SJohn Forte * @memo Create a new open handle for a specified HBA
107fcf3ce44SJohn Forte * @precondition HBA port(s) must be loaded
108fcf3ce44SJohn Forte * @postcondition An open handle will be present in the global tracking list
109fcf3ce44SJohn Forte * and must be closed at some point to prevent leakage. If no
110fcf3ce44SJohn Forte * handle could be assigned (the track list is full), an
111fcf3ce44SJohn Forte * exception will be thrown. Scope for valid ids in the track
112fcf3ce44SJohn Forte * list is [0x8000, MAX_TGT_HANDLE_ID].
113fcf3ce44SJohn Forte * @param myhba The HBA to open a handle for
114fcf3ce44SJohn Forte * m The mode of HBA to open handle for
115fcf3ce44SJohn Forte */
116fcf3ce44SJohn Forte #if 0
117fcf3ce44SJohn Forte // appears unused
118fcf3ce44SJohn Forte Handle::Handle(HBA *myhba, MODE m) {
119fcf3ce44SJohn Forte map<HBA_HANDLE, Handle*>::iterator mapend;
120fcf3ce44SJohn Forte Trace log("Handle::Handle");
121fcf3ce44SJohn Forte lock(&staticLock);
122fcf3ce44SJohn Forte modeVal = m;
123fcf3ce44SJohn Forte
124fcf3ce44SJohn Forte
125fcf3ce44SJohn Forte // if initiator mode call constructor for initiator.
126fcf3ce44SJohn Forte if (m == INITIATOR) {
127fcf3ce44SJohn Forte Handle(myhba, TARGET);
128fcf3ce44SJohn Forte }
129fcf3ce44SJohn Forte
130fcf3ce44SJohn Forte mapend = openHandles.end();
131fcf3ce44SJohn Forte /* Start the search for a free id from the previously assigned one */
132fcf3ce44SJohn Forte id = prevTgtOpen + 1;
133fcf3ce44SJohn Forte while (id != prevTgtOpen) {
134fcf3ce44SJohn Forte /*
135fcf3ce44SJohn Forte * Exceeds the max valid target id value,
136fcf3ce44SJohn Forte * continue the search from 1.
137fcf3ce44SJohn Forte */
138fcf3ce44SJohn Forte if (id > MAX_TGT_HANDLE_ID)
139fcf3ce44SJohn Forte id = 0x8001;
140fcf3ce44SJohn Forte
141fcf3ce44SJohn Forte if (openHandles.find(id) == mapend) {
142fcf3ce44SJohn Forte /* the id is not in use */
143fcf3ce44SJohn Forte break;
144fcf3ce44SJohn Forte }
145fcf3ce44SJohn Forte id ++;
146fcf3ce44SJohn Forte }
147fcf3ce44SJohn Forte if (id == prevTgtOpen) {
148fcf3ce44SJohn Forte /* no usable id for now */
149fcf3ce44SJohn Forte unlock(&staticLock);
150fcf3ce44SJohn Forte throw TryAgainException();
151fcf3ce44SJohn Forte }
152fcf3ce44SJohn Forte prevTgtOpen = id;
153fcf3ce44SJohn Forte hba = myhba;
154fcf3ce44SJohn Forte openHandles[id] = this;
155fcf3ce44SJohn Forte unlock(&staticLock);
156fcf3ce44SJohn Forte }
157fcf3ce44SJohn Forte #endif
158fcf3ce44SJohn Forte /**
159fcf3ce44SJohn Forte * @memo Free up the handle (aka, close it)
160fcf3ce44SJohn Forte * @postcondition This handle will be removed from the global list
161fcf3ce44SJohn Forte * @exception ... underlying exceptions will be thrown
162fcf3ce44SJohn Forte */
~Handle()163fcf3ce44SJohn Forte Handle::~Handle() {
164fcf3ce44SJohn Forte Trace log("Handle::~Handle");
165fcf3ce44SJohn Forte // Remove this handle from the global list
166fcf3ce44SJohn Forte lock(&staticLock);
167fcf3ce44SJohn Forte try {
168fcf3ce44SJohn Forte openHandles.erase(openHandles.find(getHandle()));
169fcf3ce44SJohn Forte unlock(&staticLock);
170fcf3ce44SJohn Forte } catch (...) {
171fcf3ce44SJohn Forte unlock(&staticLock);
172fcf3ce44SJohn Forte throw;
173fcf3ce44SJohn Forte }
174fcf3ce44SJohn Forte
175fcf3ce44SJohn Forte // Now nuke all internal dynamic allocations
176fcf3ce44SJohn Forte typedef map<uint64_t, HandlePort *>::const_iterator CI;
177fcf3ce44SJohn Forte lock();
178fcf3ce44SJohn Forte try {
179fcf3ce44SJohn Forte for (CI port = portHandles.begin(); port != portHandles.end();
180fcf3ce44SJohn Forte port++) {
181fcf3ce44SJohn Forte delete port->second;
182fcf3ce44SJohn Forte }
183fcf3ce44SJohn Forte portHandles.clear();
184fcf3ce44SJohn Forte unlock();
185fcf3ce44SJohn Forte } catch (...) {
186fcf3ce44SJohn Forte unlock();
187fcf3ce44SJohn Forte throw;
188fcf3ce44SJohn Forte }
189fcf3ce44SJohn Forte }
190fcf3ce44SJohn Forte
191fcf3ce44SJohn Forte /**
192fcf3ce44SJohn Forte * @memo Locate a handle in the global list of open handles
193fcf3ce44SJohn Forte * @precondition The requested handle must already be open
194fcf3ce44SJohn Forte * @exception InvalidHandleException Thrown if the id does not match
195fcf3ce44SJohn Forte * an open handle
196fcf3ce44SJohn Forte * @return The open Handle
197fcf3ce44SJohn Forte * @param id The id of the handle to fetch
198fcf3ce44SJohn Forte *
199fcf3ce44SJohn Forte * @doc The HBA API uses a simple integer type to represent
200fcf3ce44SJohn Forte * an open Handle, but we use an instance of the Handle
201fcf3ce44SJohn Forte * class. This interface allows a caller to quickly convert
202fcf3ce44SJohn Forte * from the API integer value to related the Handle instance.
203fcf3ce44SJohn Forte */
findHandle(HBA_HANDLE id)204fcf3ce44SJohn Forte Handle* Handle::findHandle(HBA_HANDLE id) {
205fcf3ce44SJohn Forte Trace log("Handle::findHandle(id)");
206fcf3ce44SJohn Forte Handle *tmp = NULL;
207fcf3ce44SJohn Forte lock(&staticLock);
208fcf3ce44SJohn Forte try {
209fcf3ce44SJohn Forte if (openHandles.find(id) == openHandles.end()) {
210fcf3ce44SJohn Forte throw InvalidHandleException();
211fcf3ce44SJohn Forte }
212fcf3ce44SJohn Forte tmp = openHandles[id];
213fcf3ce44SJohn Forte unlock(&staticLock);
214fcf3ce44SJohn Forte return (tmp);
215fcf3ce44SJohn Forte } catch (...) {
216fcf3ce44SJohn Forte unlock(&staticLock);
217fcf3ce44SJohn Forte throw;
218fcf3ce44SJohn Forte }
219fcf3ce44SJohn Forte }
220fcf3ce44SJohn Forte
221fcf3ce44SJohn Forte /**
222fcf3ce44SJohn Forte * @memo Find an open handle based on Node or Port WWN
223fcf3ce44SJohn Forte * @precondition The given HBA must already be open
224fcf3ce44SJohn Forte * @exception IllegalWWNException Thrown if no matching open Handle found
225fcf3ce44SJohn Forte * @return The open handle matching the wwn argument
226fcf3ce44SJohn Forte * @param wwn The Node or Port WWN of the HBA whos open handle
227fcf3ce44SJohn Forte * is requested.
228fcf3ce44SJohn Forte *
229fcf3ce44SJohn Forte */
findHandle(uint64_t wwn)230fcf3ce44SJohn Forte Handle* Handle::findHandle(uint64_t wwn) {
231fcf3ce44SJohn Forte Trace log("Handle::findHandle(wwn)");
232fcf3ce44SJohn Forte Handle *tmp = NULL;
233fcf3ce44SJohn Forte lock(&staticLock);
234fcf3ce44SJohn Forte try {
235fcf3ce44SJohn Forte for (int i = 0; i < openHandles.size(); i++) {
236fcf3ce44SJohn Forte tmp = openHandles[i];
237fcf3ce44SJohn Forte if (tmp->getHBA()->containsWWN(wwn)) {
238fcf3ce44SJohn Forte unlock(&staticLock);
239fcf3ce44SJohn Forte return (tmp);
240fcf3ce44SJohn Forte }
241fcf3ce44SJohn Forte }
242fcf3ce44SJohn Forte tmp = NULL;
243fcf3ce44SJohn Forte } catch (...) { tmp = NULL; }
244fcf3ce44SJohn Forte unlock(&staticLock);
245fcf3ce44SJohn Forte if (tmp == NULL) {
246fcf3ce44SJohn Forte throw IllegalWWNException();
247fcf3ce44SJohn Forte }
248fcf3ce44SJohn Forte return (tmp);
249fcf3ce44SJohn Forte }
250fcf3ce44SJohn Forte
251fcf3ce44SJohn Forte /**
252fcf3ce44SJohn Forte * @memo Refresh underlying index values
253fcf3ce44SJohn Forte * @postcondition All HandlePorts will be reset and prior index values
254fcf3ce44SJohn Forte * will be undefined.
255fcf3ce44SJohn Forte * @exception ... underlying exceptions will be thrown
256fcf3ce44SJohn Forte *
257fcf3ce44SJohn Forte * @doc A number of APIs in the standard interface require
258fcf3ce44SJohn Forte * the use of index values for identifying what "thing"
259fcf3ce44SJohn Forte * to operate on. When dynamic reconfiguration occurs
260fcf3ce44SJohn Forte * these indexes may become inconsistent. This routine
261fcf3ce44SJohn Forte * is called to reset the indexes and signify that the caller
262fcf3ce44SJohn Forte * no longer holds or will refer to any old indexes.
263fcf3ce44SJohn Forte */
refresh()264fcf3ce44SJohn Forte void Handle::refresh() {
265fcf3ce44SJohn Forte Trace log("Handle::refresh");
266fcf3ce44SJohn Forte lock();
267fcf3ce44SJohn Forte try {
268fcf3ce44SJohn Forte typedef map<uint64_t, HandlePort *>::const_iterator CI;
269fcf3ce44SJohn Forte for (CI port = portHandles.begin(); port != portHandles.end();
270fcf3ce44SJohn Forte port++) {
271fcf3ce44SJohn Forte port->second->refresh();
272fcf3ce44SJohn Forte }
273fcf3ce44SJohn Forte unlock();
274fcf3ce44SJohn Forte } catch (...) {
275fcf3ce44SJohn Forte unlock();
276fcf3ce44SJohn Forte throw;
277fcf3ce44SJohn Forte }
278fcf3ce44SJohn Forte }
279fcf3ce44SJohn Forte
280fcf3ce44SJohn Forte /**
281fcf3ce44SJohn Forte * @memo Close the specified handle
282fcf3ce44SJohn Forte * @precondition The handle must be open
283fcf3ce44SJohn Forte * @postcondition The handle will be closed and should be discarded.
284fcf3ce44SJohn Forte * @param id The handle to close
285fcf3ce44SJohn Forte */
closeHandle(HBA_HANDLE id)286fcf3ce44SJohn Forte void Handle::closeHandle(HBA_HANDLE id) {
287fcf3ce44SJohn Forte Trace log("Handle::closeHandle");
288fcf3ce44SJohn Forte Handle *myHandle = findHandle(id);
289fcf3ce44SJohn Forte delete myHandle;
290fcf3ce44SJohn Forte }
291fcf3ce44SJohn Forte
292fcf3ce44SJohn Forte /**
293fcf3ce44SJohn Forte * @memo Get the integer value for return to the API
294fcf3ce44SJohn Forte * @exception ... underlying exceptions will be thrown
295fcf3ce44SJohn Forte * @return The integer value representing the handle
296fcf3ce44SJohn Forte *
297fcf3ce44SJohn Forte * @doc The HBA API uses integer values to represent handles.
298fcf3ce44SJohn Forte * Call this routine to convert a Handle instance into
299fcf3ce44SJohn Forte * its representative integer value.
300fcf3ce44SJohn Forte */
getHandle()301fcf3ce44SJohn Forte HBA_HANDLE Handle::getHandle() {
302fcf3ce44SJohn Forte Trace log("Handle::getHandle");
303fcf3ce44SJohn Forte HBA_HANDLE tmp;
304fcf3ce44SJohn Forte lock();
305fcf3ce44SJohn Forte try {
306fcf3ce44SJohn Forte tmp = (HBA_HANDLE) id;
307fcf3ce44SJohn Forte unlock();
308fcf3ce44SJohn Forte return (tmp);
309fcf3ce44SJohn Forte } catch (...) {
310fcf3ce44SJohn Forte unlock();
311fcf3ce44SJohn Forte throw;
312fcf3ce44SJohn Forte }
313fcf3ce44SJohn Forte }
314fcf3ce44SJohn Forte
315fcf3ce44SJohn Forte /**
316fcf3ce44SJohn Forte * @memo Compare two handles for equality
317fcf3ce44SJohn Forte * @return TRUE if the handles are the same
318fcf3ce44SJohn Forte * @return FALSE if the handles are different
319fcf3ce44SJohn Forte */
operator ==(Handle comp)320fcf3ce44SJohn Forte bool Handle::operator==(Handle comp) {
321fcf3ce44SJohn Forte Trace log("Handle::operator==");
322fcf3ce44SJohn Forte return (this->id == comp.id);
323fcf3ce44SJohn Forte }
324fcf3ce44SJohn Forte
325fcf3ce44SJohn Forte /**
326fcf3ce44SJohn Forte * @memo Get the underlying Handle port based on index
327fcf3ce44SJohn Forte * @return The Handle port for the given port index
328fcf3ce44SJohn Forte * @param index The index of the desired port
329fcf3ce44SJohn Forte */
getHandlePortByIndex(int index)330fcf3ce44SJohn Forte HandlePort* Handle::getHandlePortByIndex(int index) {
331fcf3ce44SJohn Forte Trace log("Handle::getHandlePortByIndex");
332fcf3ce44SJohn Forte HBAPort* port = hba->getPortByIndex(index);
333fcf3ce44SJohn Forte return (getHandlePort(port->getPortWWN()));
334fcf3ce44SJohn Forte }
335fcf3ce44SJohn Forte
336fcf3ce44SJohn Forte /**
337fcf3ce44SJohn Forte * @memo Get the underlying Handle port based on Port wwn
338fcf3ce44SJohn Forte * @exception IllegalWWNException thrown if the wwn is not found
339fcf3ce44SJohn Forte * @return The handle port for the specified WWN
340fcf3ce44SJohn Forte * @param wwn The Port WWN of the HBA port
341fcf3ce44SJohn Forte *
342fcf3ce44SJohn Forte */
getHandlePort(uint64_t wwn)343fcf3ce44SJohn Forte HandlePort* Handle::getHandlePort(uint64_t wwn) {
344fcf3ce44SJohn Forte Trace log("Handle::getHandlePort");
345fcf3ce44SJohn Forte lock();
346fcf3ce44SJohn Forte try {
347fcf3ce44SJohn Forte // Check to see if the wwn is in the map
348fcf3ce44SJohn Forte if (portHandles.find(wwn) == portHandles.end()) {
349fcf3ce44SJohn Forte // Not found, add a new one
350fcf3ce44SJohn Forte HBAPort* port = hba->getPort(wwn);
351fcf3ce44SJohn Forte portHandles[wwn] = new HandlePort(this, hba, port);
352fcf3ce44SJohn Forte }
353fcf3ce44SJohn Forte HandlePort *portHandle = portHandles[wwn];
354fcf3ce44SJohn Forte unlock();
355fcf3ce44SJohn Forte return (portHandle);
356fcf3ce44SJohn Forte } catch (...) {
357fcf3ce44SJohn Forte unlock();
358fcf3ce44SJohn Forte throw;
359fcf3ce44SJohn Forte }
360fcf3ce44SJohn Forte }
361fcf3ce44SJohn Forte
362fcf3ce44SJohn Forte /**
363fcf3ce44SJohn Forte * @memo Get the HBA attributes from the underlying HBA
364fcf3ce44SJohn Forte *
365fcf3ce44SJohn Forte * @see HBA::getHBAAttributes
366fcf3ce44SJohn Forte */
getHBAAttributes()367fcf3ce44SJohn Forte HBA_ADAPTERATTRIBUTES Handle::getHBAAttributes() {
368fcf3ce44SJohn Forte Trace log("Handle::getHBAAttributes");
369fcf3ce44SJohn Forte lock();
370fcf3ce44SJohn Forte try {
371fcf3ce44SJohn Forte HBA_ADAPTERATTRIBUTES attributes = hba->getHBAAttributes();
372fcf3ce44SJohn Forte unlock();
373fcf3ce44SJohn Forte return (attributes);
374fcf3ce44SJohn Forte } catch (...) {
375fcf3ce44SJohn Forte unlock();
376fcf3ce44SJohn Forte throw;
377fcf3ce44SJohn Forte }
378fcf3ce44SJohn Forte }
379fcf3ce44SJohn Forte
380*a7949318SReed /**
381*a7949318SReed * @memo Do FORCELIP
382*a7949318SReed *
383*a7949318SReed * @see HBA::doForceLip
384*a7949318SReed */
doForceLip()385*a7949318SReed int Handle::doForceLip() {
386*a7949318SReed Trace log("Handle::doForceLip");
387*a7949318SReed lock();
388*a7949318SReed try {
389*a7949318SReed int rval = hba->doForceLip();
390*a7949318SReed unlock();
391*a7949318SReed return (rval);
392*a7949318SReed } catch (...) {
393*a7949318SReed unlock();
394*a7949318SReed throw;
395*a7949318SReed }
396*a7949318SReed }
397*a7949318SReed
npivGetHBAAttributes()398fcf3ce44SJohn Forte HBA_ADAPTERATTRIBUTES Handle::npivGetHBAAttributes() {
399fcf3ce44SJohn Forte Trace log("Handle::npivGetHBAAttributes");
400fcf3ce44SJohn Forte lock();
401fcf3ce44SJohn Forte try {
402fcf3ce44SJohn Forte HBA_ADAPTERATTRIBUTES attributes = hba->npivGetHBAAttributes();
403fcf3ce44SJohn Forte unlock();
404fcf3ce44SJohn Forte return (attributes);
405fcf3ce44SJohn Forte } catch (...) {
406fcf3ce44SJohn Forte unlock();
407fcf3ce44SJohn Forte throw;
408fcf3ce44SJohn Forte }
409fcf3ce44SJohn Forte }
410fcf3ce44SJohn Forte
411fcf3ce44SJohn Forte
412fcf3ce44SJohn Forte /**
413fcf3ce44SJohn Forte * @memo Get the HBA port attributes from the HBA
414fcf3ce44SJohn Forte * @see HBAPort::getPortAttributes
415fcf3ce44SJohn Forte * @see HBAPort::getDisoveredAttributes
416fcf3ce44SJohn Forte *
417fcf3ce44SJohn Forte * @doc This routine will return either HBA port
418fcf3ce44SJohn Forte * attributes, or discovered port attributes
419fcf3ce44SJohn Forte *
420fcf3ce44SJohn Forte */
getPortAttributes(uint64_t wwn)421fcf3ce44SJohn Forte HBA_PORTATTRIBUTES Handle::getPortAttributes(uint64_t wwn) {
422fcf3ce44SJohn Forte Trace log("Handle::getPortAttributes");
423fcf3ce44SJohn Forte uint64_t tmp;
424fcf3ce44SJohn Forte HBA_PORTATTRIBUTES attributes;
425fcf3ce44SJohn Forte
426fcf3ce44SJohn Forte lock();
427fcf3ce44SJohn Forte try {
428fcf3ce44SJohn Forte // Is this a WWN for one of the adapter ports?
429fcf3ce44SJohn Forte if (hba->containsWWN(wwn)) {
430fcf3ce44SJohn Forte attributes = hba->getPort(wwn)->getPortAttributes(tmp);
431fcf3ce44SJohn Forte unlock();
432fcf3ce44SJohn Forte return (attributes);
433fcf3ce44SJohn Forte } else { // Is this a target we know about?
434fcf3ce44SJohn Forte // Loop through all ports and look for the first match
435fcf3ce44SJohn Forte
436fcf3ce44SJohn Forte for (int i = 0; i < hba->getNumberOfPorts(); i++) {
437fcf3ce44SJohn Forte try {
438fcf3ce44SJohn Forte attributes =
439fcf3ce44SJohn Forte hba->getPortByIndex(i)->getDiscoveredAttributes(
440fcf3ce44SJohn Forte wwn, tmp);
441fcf3ce44SJohn Forte unlock();
442fcf3ce44SJohn Forte return (attributes);
443fcf3ce44SJohn Forte } catch (HBAException &e) {
444fcf3ce44SJohn Forte continue;
445fcf3ce44SJohn Forte }
446fcf3ce44SJohn Forte }
447fcf3ce44SJohn Forte
448fcf3ce44SJohn Forte // If we get to here, then we don't see this WWN on this HBA
449fcf3ce44SJohn Forte throw IllegalWWNException();
450fcf3ce44SJohn Forte }
451fcf3ce44SJohn Forte } catch (...) {
452fcf3ce44SJohn Forte unlock();
453fcf3ce44SJohn Forte throw;
454fcf3ce44SJohn Forte }
455fcf3ce44SJohn Forte }
456