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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 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 */ 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