xref: /illumos-gate/usr/src/lib/sun_fc/common/Handle.cc (revision a7949318)
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