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