xref: /onnv-gate/usr/src/lib/sun_fc/common/Handle.cc (revision 10275:f0b35eb34c31)
17836SJohn.Forte@Sun.COM /*
27836SJohn.Forte@Sun.COM  * CDDL HEADER START
37836SJohn.Forte@Sun.COM  *
47836SJohn.Forte@Sun.COM  * The contents of this file are subject to the terms of the
57836SJohn.Forte@Sun.COM  * Common Development and Distribution License (the "License").
67836SJohn.Forte@Sun.COM  * You may not use this file except in compliance with the License.
77836SJohn.Forte@Sun.COM  *
87836SJohn.Forte@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97836SJohn.Forte@Sun.COM  * or http://www.opensolaris.org/os/licensing.
107836SJohn.Forte@Sun.COM  * See the License for the specific language governing permissions
117836SJohn.Forte@Sun.COM  * and limitations under the License.
127836SJohn.Forte@Sun.COM  *
137836SJohn.Forte@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
147836SJohn.Forte@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157836SJohn.Forte@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
167836SJohn.Forte@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
177836SJohn.Forte@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
187836SJohn.Forte@Sun.COM  *
197836SJohn.Forte@Sun.COM  * CDDL HEADER END
207836SJohn.Forte@Sun.COM  */
217836SJohn.Forte@Sun.COM /*
22*10275SReed.Liu@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237836SJohn.Forte@Sun.COM  * Use is subject to license terms.
247836SJohn.Forte@Sun.COM  */
257836SJohn.Forte@Sun.COM 
267836SJohn.Forte@Sun.COM 
277836SJohn.Forte@Sun.COM 
287836SJohn.Forte@Sun.COM #include "Handle.h"
297836SJohn.Forte@Sun.COM #include "Exceptions.h"
307836SJohn.Forte@Sun.COM #include "Trace.h"
317836SJohn.Forte@Sun.COM #include <libdevinfo.h>
327836SJohn.Forte@Sun.COM #include <iostream>
337836SJohn.Forte@Sun.COM #include <iomanip>
347836SJohn.Forte@Sun.COM #include <sys/types.h>
357836SJohn.Forte@Sun.COM #include <sys/stat.h>
367836SJohn.Forte@Sun.COM #include <fcntl.h>
377836SJohn.Forte@Sun.COM #include <unistd.h>
387836SJohn.Forte@Sun.COM #include <stropts.h>
397836SJohn.Forte@Sun.COM 
407836SJohn.Forte@Sun.COM #define	MAX_INIT_HANDLE_ID	0x7fff
417836SJohn.Forte@Sun.COM #define	MAX_TGT_HANDLE_ID	0xffff
427836SJohn.Forte@Sun.COM 
437836SJohn.Forte@Sun.COM using namespace std;
447836SJohn.Forte@Sun.COM 
457836SJohn.Forte@Sun.COM /**
467836SJohn.Forte@Sun.COM  * Global lock for list of Handles
477836SJohn.Forte@Sun.COM  */
487836SJohn.Forte@Sun.COM pthread_mutex_t Handle::staticLock = PTHREAD_MUTEX_INITIALIZER;
497836SJohn.Forte@Sun.COM 
507836SJohn.Forte@Sun.COM /**
517836SJohn.Forte@Sun.COM  * Tracking for the previous handle we have opened
527836SJohn.Forte@Sun.COM  */
537836SJohn.Forte@Sun.COM HBA_HANDLE Handle::prevOpen = 0;
547836SJohn.Forte@Sun.COM 
557836SJohn.Forte@Sun.COM /**
567836SJohn.Forte@Sun.COM  * Tracking for the previous target HBA handle we have opened
577836SJohn.Forte@Sun.COM  */
587836SJohn.Forte@Sun.COM HBA_HANDLE Handle::prevTgtOpen = 0x8000;
597836SJohn.Forte@Sun.COM 
607836SJohn.Forte@Sun.COM /**
617836SJohn.Forte@Sun.COM  * Global map from HBA_HANDLE to Handle pointers (our global list)
627836SJohn.Forte@Sun.COM  */
637836SJohn.Forte@Sun.COM map<HBA_HANDLE, Handle*> Handle::openHandles;
647836SJohn.Forte@Sun.COM 
657836SJohn.Forte@Sun.COM /**
667836SJohn.Forte@Sun.COM  * @memo	    Create a new open handle for a specified HBA
677836SJohn.Forte@Sun.COM  * @precondition    HBA port(s) must be loaded
687836SJohn.Forte@Sun.COM  * @postcondition   An open handle will be present in the global tracking list
697836SJohn.Forte@Sun.COM  *		    and must be closed at some point to prevent leakage. If no
707836SJohn.Forte@Sun.COM  *		    handle could be assigned (the track list is full), an
717836SJohn.Forte@Sun.COM  *		    exception will be thrown. Scope for valid ids in the track
727836SJohn.Forte@Sun.COM  *		    list is [1, MAX_INIT_HANDLE_ID].
737836SJohn.Forte@Sun.COM  * @param	    myhba The HBA to open a handle for
747836SJohn.Forte@Sun.COM  */
Handle(HBA * myhba)757836SJohn.Forte@Sun.COM Handle::Handle(HBA *myhba) {
767836SJohn.Forte@Sun.COM 	map<HBA_HANDLE, Handle*>::iterator mapend;
777836SJohn.Forte@Sun.COM 	Trace log("Handle::Handle");
787836SJohn.Forte@Sun.COM 	modeVal = INITIATOR;
797836SJohn.Forte@Sun.COM 	lock(&staticLock);
807836SJohn.Forte@Sun.COM 	mapend = openHandles.end();
817836SJohn.Forte@Sun.COM 	/* Start the search for a free id from the previously assigned one */
827836SJohn.Forte@Sun.COM 	id = prevOpen + 1;
837836SJohn.Forte@Sun.COM 	while (id != prevOpen) {
847836SJohn.Forte@Sun.COM 		/* Exceeds the max valid value, continue the search from 1 */
857836SJohn.Forte@Sun.COM 		if (id > MAX_INIT_HANDLE_ID)
867836SJohn.Forte@Sun.COM 			id = 1;
877836SJohn.Forte@Sun.COM 
887836SJohn.Forte@Sun.COM 		if (openHandles.find(id) == mapend) {
897836SJohn.Forte@Sun.COM 			/* the id is not in use */
907836SJohn.Forte@Sun.COM 			break;
917836SJohn.Forte@Sun.COM 		}
927836SJohn.Forte@Sun.COM 		id ++;
937836SJohn.Forte@Sun.COM 	}
947836SJohn.Forte@Sun.COM 	if (id == prevOpen) {
957836SJohn.Forte@Sun.COM 		/* no usable id for now */
967836SJohn.Forte@Sun.COM 		unlock(&staticLock);
977836SJohn.Forte@Sun.COM 		throw TryAgainException();
987836SJohn.Forte@Sun.COM 	}
997836SJohn.Forte@Sun.COM 	prevOpen = id;
1007836SJohn.Forte@Sun.COM 	hba = myhba;
1017836SJohn.Forte@Sun.COM 	openHandles[id] = this;
1027836SJohn.Forte@Sun.COM 	unlock(&staticLock);
1037836SJohn.Forte@Sun.COM }
1047836SJohn.Forte@Sun.COM 
1057836SJohn.Forte@Sun.COM /**
1067836SJohn.Forte@Sun.COM  * @memo	    Create a new open handle for a specified HBA
1077836SJohn.Forte@Sun.COM  * @precondition    HBA port(s) must be loaded
1087836SJohn.Forte@Sun.COM  * @postcondition   An open handle will be present in the global tracking list
1097836SJohn.Forte@Sun.COM  *		    and must be closed at some point to prevent leakage. If no
1107836SJohn.Forte@Sun.COM  *		    handle could be assigned (the track list is full), an
1117836SJohn.Forte@Sun.COM  *		    exception will be thrown. Scope for valid ids in the track
1127836SJohn.Forte@Sun.COM  *		    list is [0x8000, MAX_TGT_HANDLE_ID].
1137836SJohn.Forte@Sun.COM  * @param	    myhba The HBA to open a handle for
1147836SJohn.Forte@Sun.COM  *		    m The mode of HBA to open handle for
1157836SJohn.Forte@Sun.COM  */
1167836SJohn.Forte@Sun.COM #if 0
1177836SJohn.Forte@Sun.COM // appears unused
1187836SJohn.Forte@Sun.COM Handle::Handle(HBA *myhba, MODE m) {
1197836SJohn.Forte@Sun.COM 	map<HBA_HANDLE, Handle*>::iterator mapend;
1207836SJohn.Forte@Sun.COM 	Trace log("Handle::Handle");
1217836SJohn.Forte@Sun.COM 	lock(&staticLock);
1227836SJohn.Forte@Sun.COM 	modeVal = m;
1237836SJohn.Forte@Sun.COM 
1247836SJohn.Forte@Sun.COM 
1257836SJohn.Forte@Sun.COM 	// if initiator mode call constructor for initiator.
126*10275SReed.Liu@Sun.COM 	if (m == INITIATOR) {
1277836SJohn.Forte@Sun.COM 		Handle(myhba, TARGET);
1287836SJohn.Forte@Sun.COM 	}
1297836SJohn.Forte@Sun.COM 
1307836SJohn.Forte@Sun.COM 	mapend = openHandles.end();
1317836SJohn.Forte@Sun.COM 	/* Start the search for a free id from the previously assigned one */
1327836SJohn.Forte@Sun.COM 	id = prevTgtOpen + 1;
1337836SJohn.Forte@Sun.COM 	while (id != prevTgtOpen) {
1347836SJohn.Forte@Sun.COM 		/*
1357836SJohn.Forte@Sun.COM 		 * Exceeds the max valid target id value,
1367836SJohn.Forte@Sun.COM 		 * continue the search from 1.
1377836SJohn.Forte@Sun.COM 		 */
1387836SJohn.Forte@Sun.COM 		if (id > MAX_TGT_HANDLE_ID)
1397836SJohn.Forte@Sun.COM 			id = 0x8001;
1407836SJohn.Forte@Sun.COM 
1417836SJohn.Forte@Sun.COM 		if (openHandles.find(id) == mapend) {
1427836SJohn.Forte@Sun.COM 			/* the id is not in use */
1437836SJohn.Forte@Sun.COM 			break;
1447836SJohn.Forte@Sun.COM 		}
1457836SJohn.Forte@Sun.COM 		id ++;
1467836SJohn.Forte@Sun.COM 	}
1477836SJohn.Forte@Sun.COM 	if (id == prevTgtOpen) {
1487836SJohn.Forte@Sun.COM 		/* no usable id for now */
1497836SJohn.Forte@Sun.COM 		unlock(&staticLock);
1507836SJohn.Forte@Sun.COM 		throw TryAgainException();
1517836SJohn.Forte@Sun.COM 	}
1527836SJohn.Forte@Sun.COM 	prevTgtOpen = id;
1537836SJohn.Forte@Sun.COM 	hba = myhba;
1547836SJohn.Forte@Sun.COM 	openHandles[id] = this;
1557836SJohn.Forte@Sun.COM 	unlock(&staticLock);
1567836SJohn.Forte@Sun.COM }
1577836SJohn.Forte@Sun.COM #endif
1587836SJohn.Forte@Sun.COM /**
1597836SJohn.Forte@Sun.COM  * @memo	    Free up the handle (aka, close it)
1607836SJohn.Forte@Sun.COM  * @postcondition   This handle will be removed from the global list
1617836SJohn.Forte@Sun.COM  * @exception	    ... underlying exceptions will be thrown
1627836SJohn.Forte@Sun.COM  */
~Handle()1637836SJohn.Forte@Sun.COM Handle::~Handle() {
1647836SJohn.Forte@Sun.COM 	Trace log("Handle::~Handle");
1657836SJohn.Forte@Sun.COM 	// Remove this handle from the global list
1667836SJohn.Forte@Sun.COM 	lock(&staticLock);
1677836SJohn.Forte@Sun.COM 	try {
1687836SJohn.Forte@Sun.COM 	    openHandles.erase(openHandles.find(getHandle()));
1697836SJohn.Forte@Sun.COM 	    unlock(&staticLock);
1707836SJohn.Forte@Sun.COM 	} catch (...) {
1717836SJohn.Forte@Sun.COM 	    unlock(&staticLock);
1727836SJohn.Forte@Sun.COM 	    throw;
1737836SJohn.Forte@Sun.COM 	}
1747836SJohn.Forte@Sun.COM 
1757836SJohn.Forte@Sun.COM 	// Now nuke all internal dynamic allocations
1767836SJohn.Forte@Sun.COM 	typedef map<uint64_t, HandlePort *>::const_iterator CI;
1777836SJohn.Forte@Sun.COM 	lock();
1787836SJohn.Forte@Sun.COM 	try {
1797836SJohn.Forte@Sun.COM 	    for (CI port = portHandles.begin(); port != portHandles.end();
1807836SJohn.Forte@Sun.COM 		    port++) {
1817836SJohn.Forte@Sun.COM 		delete port->second;
1827836SJohn.Forte@Sun.COM 	    }
1837836SJohn.Forte@Sun.COM 	    portHandles.clear();
1847836SJohn.Forte@Sun.COM 	    unlock();
1857836SJohn.Forte@Sun.COM 	} catch (...) {
1867836SJohn.Forte@Sun.COM 	    unlock();
1877836SJohn.Forte@Sun.COM 	    throw;
1887836SJohn.Forte@Sun.COM 	}
1897836SJohn.Forte@Sun.COM }
1907836SJohn.Forte@Sun.COM 
1917836SJohn.Forte@Sun.COM /**
1927836SJohn.Forte@Sun.COM  * @memo	    Locate a handle in the global list of open handles
1937836SJohn.Forte@Sun.COM  * @precondition    The requested handle must already be open
1947836SJohn.Forte@Sun.COM  * @exception	    InvalidHandleException Thrown if the id does not match
1957836SJohn.Forte@Sun.COM  *		    an open handle
1967836SJohn.Forte@Sun.COM  * @return	    The open Handle
1977836SJohn.Forte@Sun.COM  * @param	    id The id of the handle to fetch
1987836SJohn.Forte@Sun.COM  *
1997836SJohn.Forte@Sun.COM  * @doc		    The HBA API uses a simple integer type to represent
2007836SJohn.Forte@Sun.COM  *		    an open Handle, but we use an instance of the Handle
2017836SJohn.Forte@Sun.COM  *		    class.  This interface allows a caller to quickly convert
2027836SJohn.Forte@Sun.COM  *		    from the API integer value to related the Handle instance.
2037836SJohn.Forte@Sun.COM  */
findHandle(HBA_HANDLE id)2047836SJohn.Forte@Sun.COM Handle* Handle::findHandle(HBA_HANDLE id) {
2057836SJohn.Forte@Sun.COM 	Trace log("Handle::findHandle(id)");
2067836SJohn.Forte@Sun.COM 	Handle *tmp = NULL;
2077836SJohn.Forte@Sun.COM 	lock(&staticLock);
2087836SJohn.Forte@Sun.COM 	try {
2097836SJohn.Forte@Sun.COM 	    if (openHandles.find(id) == openHandles.end()) {
2107836SJohn.Forte@Sun.COM 		throw InvalidHandleException();
2117836SJohn.Forte@Sun.COM 	    }
2127836SJohn.Forte@Sun.COM 	    tmp = openHandles[id];
2137836SJohn.Forte@Sun.COM 	    unlock(&staticLock);
2147836SJohn.Forte@Sun.COM 	    return (tmp);
2157836SJohn.Forte@Sun.COM 	} catch (...) {
2167836SJohn.Forte@Sun.COM 	    unlock(&staticLock);
2177836SJohn.Forte@Sun.COM 	    throw;
2187836SJohn.Forte@Sun.COM 	}
2197836SJohn.Forte@Sun.COM }
2207836SJohn.Forte@Sun.COM 
2217836SJohn.Forte@Sun.COM /**
2227836SJohn.Forte@Sun.COM  * @memo	    Find an open handle based on Node or Port WWN
2237836SJohn.Forte@Sun.COM  * @precondition    The given HBA must already be open
2247836SJohn.Forte@Sun.COM  * @exception	    IllegalWWNException Thrown if no matching open Handle found
2257836SJohn.Forte@Sun.COM  * @return	    The open handle matching the wwn argument
2267836SJohn.Forte@Sun.COM  * @param	    wwn The Node or Port WWN of the HBA whos open handle
2277836SJohn.Forte@Sun.COM  *		    is requested.
2287836SJohn.Forte@Sun.COM  *
2297836SJohn.Forte@Sun.COM  */
findHandle(uint64_t wwn)2307836SJohn.Forte@Sun.COM Handle* Handle::findHandle(uint64_t wwn) {
2317836SJohn.Forte@Sun.COM 	Trace log("Handle::findHandle(wwn)");
2327836SJohn.Forte@Sun.COM 	Handle *tmp = NULL;
2337836SJohn.Forte@Sun.COM 	lock(&staticLock);
2347836SJohn.Forte@Sun.COM 	try {
2357836SJohn.Forte@Sun.COM 	    for (int i = 0; i < openHandles.size(); i++) {
2367836SJohn.Forte@Sun.COM 		tmp = openHandles[i];
2377836SJohn.Forte@Sun.COM 		if (tmp->getHBA()->containsWWN(wwn)) {
2387836SJohn.Forte@Sun.COM 		    unlock(&staticLock);
2397836SJohn.Forte@Sun.COM 		    return (tmp);
2407836SJohn.Forte@Sun.COM 		}
2417836SJohn.Forte@Sun.COM 	    }
2427836SJohn.Forte@Sun.COM 	    tmp = NULL;
2437836SJohn.Forte@Sun.COM 	} catch (...) { tmp = NULL; }
2447836SJohn.Forte@Sun.COM 	unlock(&staticLock);
2457836SJohn.Forte@Sun.COM 	if (tmp == NULL) {
2467836SJohn.Forte@Sun.COM 	    throw IllegalWWNException();
2477836SJohn.Forte@Sun.COM 	}
2487836SJohn.Forte@Sun.COM 	return (tmp);
2497836SJohn.Forte@Sun.COM }
2507836SJohn.Forte@Sun.COM 
2517836SJohn.Forte@Sun.COM /**
2527836SJohn.Forte@Sun.COM  * @memo	    Refresh underlying index values
2537836SJohn.Forte@Sun.COM  * @postcondition   All HandlePorts will be reset and prior index values
2547836SJohn.Forte@Sun.COM  *		    will be undefined.
2557836SJohn.Forte@Sun.COM  * @exception	    ... underlying exceptions will be thrown
2567836SJohn.Forte@Sun.COM  *
2577836SJohn.Forte@Sun.COM  * @doc		    A number of APIs in the standard interface require
2587836SJohn.Forte@Sun.COM  *		    the use of index values for identifying what "thing"
2597836SJohn.Forte@Sun.COM  *		    to operate on.  When dynamic reconfiguration occurs
2607836SJohn.Forte@Sun.COM  *		    these indexes may become inconsistent.  This routine
2617836SJohn.Forte@Sun.COM  *		    is called to reset the indexes and signify that the caller
2627836SJohn.Forte@Sun.COM  *		    no longer holds or will refer to any old indexes.
2637836SJohn.Forte@Sun.COM  */
refresh()2647836SJohn.Forte@Sun.COM void Handle::refresh() {
2657836SJohn.Forte@Sun.COM 	Trace log("Handle::refresh");
2667836SJohn.Forte@Sun.COM 	lock();
2677836SJohn.Forte@Sun.COM 	try {
2687836SJohn.Forte@Sun.COM 	    typedef map<uint64_t, HandlePort *>::const_iterator CI;
2697836SJohn.Forte@Sun.COM 	    for (CI port = portHandles.begin(); port != portHandles.end();
2707836SJohn.Forte@Sun.COM 		    port++) {
2717836SJohn.Forte@Sun.COM 		port->second->refresh();
2727836SJohn.Forte@Sun.COM 	    }
2737836SJohn.Forte@Sun.COM 	    unlock();
2747836SJohn.Forte@Sun.COM 	} catch (...) {
2757836SJohn.Forte@Sun.COM 	    unlock();
2767836SJohn.Forte@Sun.COM 	    throw;
2777836SJohn.Forte@Sun.COM 	}
2787836SJohn.Forte@Sun.COM }
2797836SJohn.Forte@Sun.COM 
2807836SJohn.Forte@Sun.COM /**
2817836SJohn.Forte@Sun.COM  * @memo	    Close the specified handle
2827836SJohn.Forte@Sun.COM  * @precondition    The handle must be open
2837836SJohn.Forte@Sun.COM  * @postcondition   The handle will be closed and should be discarded.
2847836SJohn.Forte@Sun.COM  * @param	    id The handle to close
2857836SJohn.Forte@Sun.COM  */
closeHandle(HBA_HANDLE id)2867836SJohn.Forte@Sun.COM void Handle::closeHandle(HBA_HANDLE id) {
2877836SJohn.Forte@Sun.COM 	Trace log("Handle::closeHandle");
2887836SJohn.Forte@Sun.COM 	Handle *myHandle = findHandle(id);
2897836SJohn.Forte@Sun.COM 	delete myHandle;
2907836SJohn.Forte@Sun.COM }
2917836SJohn.Forte@Sun.COM 
2927836SJohn.Forte@Sun.COM /**
2937836SJohn.Forte@Sun.COM  * @memo	    Get the integer value for return to the API
2947836SJohn.Forte@Sun.COM  * @exception	    ... underlying exceptions will be thrown
2957836SJohn.Forte@Sun.COM  * @return	    The integer value representing the handle
2967836SJohn.Forte@Sun.COM  *
2977836SJohn.Forte@Sun.COM  * @doc		    The HBA API uses integer values to represent handles.
2987836SJohn.Forte@Sun.COM  *		    Call this routine to convert a Handle instance into
2997836SJohn.Forte@Sun.COM  *		    its representative integer value.
3007836SJohn.Forte@Sun.COM  */
getHandle()3017836SJohn.Forte@Sun.COM HBA_HANDLE Handle::getHandle() {
3027836SJohn.Forte@Sun.COM 	Trace log("Handle::getHandle");
3037836SJohn.Forte@Sun.COM 	HBA_HANDLE tmp;
3047836SJohn.Forte@Sun.COM 	lock();
3057836SJohn.Forte@Sun.COM 	try {
3067836SJohn.Forte@Sun.COM 	    tmp = (HBA_HANDLE) id;
3077836SJohn.Forte@Sun.COM 	    unlock();
3087836SJohn.Forte@Sun.COM 	    return (tmp);
3097836SJohn.Forte@Sun.COM 	} catch (...) {
3107836SJohn.Forte@Sun.COM 	    unlock();
3117836SJohn.Forte@Sun.COM 	    throw;
3127836SJohn.Forte@Sun.COM 	}
3137836SJohn.Forte@Sun.COM }
3147836SJohn.Forte@Sun.COM 
3157836SJohn.Forte@Sun.COM /**
3167836SJohn.Forte@Sun.COM  * @memo	    Compare two handles for equality
3177836SJohn.Forte@Sun.COM  * @return	    TRUE if the handles are the same
3187836SJohn.Forte@Sun.COM  * @return	    FALSE if the handles are different
3197836SJohn.Forte@Sun.COM  */
operator ==(Handle comp)3207836SJohn.Forte@Sun.COM bool Handle::operator==(Handle comp) {
3217836SJohn.Forte@Sun.COM 	Trace log("Handle::operator==");
3227836SJohn.Forte@Sun.COM 	return (this->id == comp.id);
3237836SJohn.Forte@Sun.COM }
3247836SJohn.Forte@Sun.COM 
3257836SJohn.Forte@Sun.COM /**
3267836SJohn.Forte@Sun.COM  * @memo	    Get the underlying Handle port based on index
3277836SJohn.Forte@Sun.COM  * @return	    The Handle port for the given port index
3287836SJohn.Forte@Sun.COM  * @param	    index The index of the desired port
3297836SJohn.Forte@Sun.COM  */
getHandlePortByIndex(int index)3307836SJohn.Forte@Sun.COM HandlePort* Handle::getHandlePortByIndex(int index) {
3317836SJohn.Forte@Sun.COM 	Trace log("Handle::getHandlePortByIndex");
3327836SJohn.Forte@Sun.COM 	HBAPort* port = hba->getPortByIndex(index);
3337836SJohn.Forte@Sun.COM 	return (getHandlePort(port->getPortWWN()));
3347836SJohn.Forte@Sun.COM }
3357836SJohn.Forte@Sun.COM 
3367836SJohn.Forte@Sun.COM /**
3377836SJohn.Forte@Sun.COM  * @memo	    Get the underlying Handle port based on Port wwn
3387836SJohn.Forte@Sun.COM  * @exception	    IllegalWWNException thrown if the wwn is not found
3397836SJohn.Forte@Sun.COM  * @return	    The handle port for the specified WWN
3407836SJohn.Forte@Sun.COM  * @param	    wwn The Port WWN of the HBA port
3417836SJohn.Forte@Sun.COM  *
3427836SJohn.Forte@Sun.COM  */
getHandlePort(uint64_t wwn)3437836SJohn.Forte@Sun.COM HandlePort* Handle::getHandlePort(uint64_t wwn) {
3447836SJohn.Forte@Sun.COM 	Trace log("Handle::getHandlePort");
3457836SJohn.Forte@Sun.COM 	lock();
3467836SJohn.Forte@Sun.COM 	try {
3477836SJohn.Forte@Sun.COM 	    // Check to see if the wwn is in the map
3487836SJohn.Forte@Sun.COM 	    if (portHandles.find(wwn) == portHandles.end()) {
3497836SJohn.Forte@Sun.COM 		// Not found, add a new one
3507836SJohn.Forte@Sun.COM 		HBAPort* port = hba->getPort(wwn);
3517836SJohn.Forte@Sun.COM 		portHandles[wwn] = new HandlePort(this, hba, port);
3527836SJohn.Forte@Sun.COM 	    }
3537836SJohn.Forte@Sun.COM 	    HandlePort *portHandle = portHandles[wwn];
3547836SJohn.Forte@Sun.COM 	    unlock();
3557836SJohn.Forte@Sun.COM 	    return (portHandle);
3567836SJohn.Forte@Sun.COM 	} catch (...) {
3577836SJohn.Forte@Sun.COM 	    unlock();
3587836SJohn.Forte@Sun.COM 	    throw;
3597836SJohn.Forte@Sun.COM 	}
3607836SJohn.Forte@Sun.COM }
3617836SJohn.Forte@Sun.COM 
3627836SJohn.Forte@Sun.COM /**
3637836SJohn.Forte@Sun.COM  * @memo	    Get the HBA attributes from the underlying HBA
3647836SJohn.Forte@Sun.COM  *
3657836SJohn.Forte@Sun.COM  * @see		    HBA::getHBAAttributes
3667836SJohn.Forte@Sun.COM  */
getHBAAttributes()3677836SJohn.Forte@Sun.COM HBA_ADAPTERATTRIBUTES Handle::getHBAAttributes() {
3687836SJohn.Forte@Sun.COM 	Trace log("Handle::getHBAAttributes");
3697836SJohn.Forte@Sun.COM 	lock();
3707836SJohn.Forte@Sun.COM 	try {
3717836SJohn.Forte@Sun.COM 	    HBA_ADAPTERATTRIBUTES attributes = hba->getHBAAttributes();
3727836SJohn.Forte@Sun.COM 	    unlock();
3737836SJohn.Forte@Sun.COM 	    return (attributes);
3747836SJohn.Forte@Sun.COM 	} catch (...) {
3757836SJohn.Forte@Sun.COM 	    unlock();
3767836SJohn.Forte@Sun.COM 	    throw;
3777836SJohn.Forte@Sun.COM 	}
3787836SJohn.Forte@Sun.COM }
3797836SJohn.Forte@Sun.COM 
380*10275SReed.Liu@Sun.COM /**
381*10275SReed.Liu@Sun.COM  * @memo	    Do FORCELIP
382*10275SReed.Liu@Sun.COM  *
383*10275SReed.Liu@Sun.COM  * @see		    HBA::doForceLip
384*10275SReed.Liu@Sun.COM  */
doForceLip()385*10275SReed.Liu@Sun.COM int Handle::doForceLip() {
386*10275SReed.Liu@Sun.COM 	Trace log("Handle::doForceLip");
387*10275SReed.Liu@Sun.COM 	lock();
388*10275SReed.Liu@Sun.COM 	try {
389*10275SReed.Liu@Sun.COM 	    int rval = hba->doForceLip();
390*10275SReed.Liu@Sun.COM 	    unlock();
391*10275SReed.Liu@Sun.COM 	    return (rval);
392*10275SReed.Liu@Sun.COM 	} catch (...) {
393*10275SReed.Liu@Sun.COM 	    unlock();
394*10275SReed.Liu@Sun.COM 	    throw;
395*10275SReed.Liu@Sun.COM 	}
396*10275SReed.Liu@Sun.COM }
397*10275SReed.Liu@Sun.COM 
npivGetHBAAttributes()3987836SJohn.Forte@Sun.COM HBA_ADAPTERATTRIBUTES Handle::npivGetHBAAttributes() {
3997836SJohn.Forte@Sun.COM 	Trace log("Handle::npivGetHBAAttributes");
4007836SJohn.Forte@Sun.COM 	lock();
4017836SJohn.Forte@Sun.COM 	try {
4027836SJohn.Forte@Sun.COM 		HBA_ADAPTERATTRIBUTES attributes = hba->npivGetHBAAttributes();
4037836SJohn.Forte@Sun.COM 		unlock();
4047836SJohn.Forte@Sun.COM 		return (attributes);
4057836SJohn.Forte@Sun.COM 	} catch (...) {
4067836SJohn.Forte@Sun.COM 		unlock();
4077836SJohn.Forte@Sun.COM 		throw;
4087836SJohn.Forte@Sun.COM 	}
4097836SJohn.Forte@Sun.COM }
4107836SJohn.Forte@Sun.COM 
4117836SJohn.Forte@Sun.COM 
4127836SJohn.Forte@Sun.COM /**
4137836SJohn.Forte@Sun.COM  * @memo	    Get the HBA port attributes from the HBA
4147836SJohn.Forte@Sun.COM  * @see		    HBAPort::getPortAttributes
4157836SJohn.Forte@Sun.COM  * @see		    HBAPort::getDisoveredAttributes
4167836SJohn.Forte@Sun.COM  *
4177836SJohn.Forte@Sun.COM  * @doc		    This routine will return either HBA port
4187836SJohn.Forte@Sun.COM  *		    attributes, or discovered port attributes
4197836SJohn.Forte@Sun.COM  *
4207836SJohn.Forte@Sun.COM  */
getPortAttributes(uint64_t wwn)4217836SJohn.Forte@Sun.COM HBA_PORTATTRIBUTES Handle::getPortAttributes(uint64_t wwn) {
4227836SJohn.Forte@Sun.COM 	Trace log("Handle::getPortAttributes");
4237836SJohn.Forte@Sun.COM 	uint64_t tmp;
4247836SJohn.Forte@Sun.COM 	HBA_PORTATTRIBUTES attributes;
4257836SJohn.Forte@Sun.COM 
4267836SJohn.Forte@Sun.COM 	lock();
4277836SJohn.Forte@Sun.COM 	try {
4287836SJohn.Forte@Sun.COM 	    // Is this a WWN for one of the adapter ports?
4297836SJohn.Forte@Sun.COM 	    if (hba->containsWWN(wwn)) {
4307836SJohn.Forte@Sun.COM 		attributes = hba->getPort(wwn)->getPortAttributes(tmp);
4317836SJohn.Forte@Sun.COM 		unlock();
4327836SJohn.Forte@Sun.COM 		return (attributes);
4337836SJohn.Forte@Sun.COM 	    } else { // Is this a target we know about?
4347836SJohn.Forte@Sun.COM 		// Loop through all ports and look for the first match
4357836SJohn.Forte@Sun.COM 
4367836SJohn.Forte@Sun.COM 		for (int i = 0; i < hba->getNumberOfPorts(); i++) {
4377836SJohn.Forte@Sun.COM 		    try {
4387836SJohn.Forte@Sun.COM 			attributes =
4397836SJohn.Forte@Sun.COM 			    hba->getPortByIndex(i)->getDiscoveredAttributes(
4407836SJohn.Forte@Sun.COM 			    wwn, tmp);
4417836SJohn.Forte@Sun.COM 			unlock();
4427836SJohn.Forte@Sun.COM 			return (attributes);
4437836SJohn.Forte@Sun.COM 		    } catch (HBAException &e) {
4447836SJohn.Forte@Sun.COM 			continue;
4457836SJohn.Forte@Sun.COM 		    }
4467836SJohn.Forte@Sun.COM 		}
4477836SJohn.Forte@Sun.COM 
4487836SJohn.Forte@Sun.COM 		// If we get to here, then we don't see this WWN on this HBA
4497836SJohn.Forte@Sun.COM 		throw IllegalWWNException();
4507836SJohn.Forte@Sun.COM 	    }
4517836SJohn.Forte@Sun.COM 	} catch (...) {
4527836SJohn.Forte@Sun.COM 	    unlock();
4537836SJohn.Forte@Sun.COM 	    throw;
4547836SJohn.Forte@Sun.COM 	}
4557836SJohn.Forte@Sun.COM }
456