xref: /illumos-gate/usr/src/lib/sun_fc/common/HBAList.cc (revision f3aaec0a97c3584095582719a0149d5e94c06ea2)
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 /*
22fcf3ce44SJohn Forte  * Copyright 2008 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 "HBAList.h"
29fcf3ce44SJohn Forte #include "Exceptions.h"
30fcf3ce44SJohn Forte #include "Trace.h"
31fcf3ce44SJohn Forte #include "sun_fc_version.h"
32fcf3ce44SJohn Forte #include <string>
33fcf3ce44SJohn Forte #include <sstream>
34fcf3ce44SJohn Forte #include "FCHBA.h"
35fcf3ce44SJohn Forte #include "TgtFCHBA.h"
36*f3aaec0aSRichard Lowe #include <cstring>
37*f3aaec0aSRichard Lowe #include <climits>
38*f3aaec0aSRichard Lowe #include <cstdlib>
39fcf3ce44SJohn Forte 
40fcf3ce44SJohn Forte using namespace std;
41fcf3ce44SJohn Forte 
42fcf3ce44SJohn Forte /**
43fcf3ce44SJohn Forte  * @memo	    Private constructor (used to create singleton instance)
44fcf3ce44SJohn Forte  * @see		    HBAList::instance
45fcf3ce44SJohn Forte  */
HBAList()46fcf3ce44SJohn Forte HBAList::HBAList() { }
47fcf3ce44SJohn Forte 
48fcf3ce44SJohn Forte /**
49fcf3ce44SJohn Forte  * Internal singleton instance
50fcf3ce44SJohn Forte  */
51fcf3ce44SJohn Forte HBAList* HBAList::_instance = 0;
52fcf3ce44SJohn Forte 
53fcf3ce44SJohn Forte /**
54fcf3ce44SJohn Forte  * Max number of adapters that this class supports.
55fcf3ce44SJohn Forte  */
56fcf3ce44SJohn Forte const int32_t HBAList::HBA_MAX_PER_LIST = INT_MAX;
57fcf3ce44SJohn Forte 
58fcf3ce44SJohn Forte /**
59fcf3ce44SJohn Forte  * @memo	    Free up resources held by this HBA list
60fcf3ce44SJohn Forte  * @postcondition   All memory used by this list will be freed
61fcf3ce44SJohn Forte  * @return	    HBA_STATUS_OK on success
62fcf3ce44SJohn Forte  *
63fcf3ce44SJohn Forte  */
unload()64fcf3ce44SJohn Forte HBA_STATUS HBAList::unload() {
65fcf3ce44SJohn Forte 	Trace log("HBAList::unload");
66fcf3ce44SJohn Forte 	lock();
67fcf3ce44SJohn Forte 	_instance = NULL;
68fcf3ce44SJohn Forte 	unlock();
69fcf3ce44SJohn Forte 	return (HBA_STATUS_OK);
70fcf3ce44SJohn Forte }
71fcf3ce44SJohn Forte 
72fcf3ce44SJohn Forte /**
73fcf3ce44SJohn Forte  * @memo	    Fetch the singleton instance
74fcf3ce44SJohn Forte  * @return	    The singleton instance
75fcf3ce44SJohn Forte  *
76fcf3ce44SJohn Forte  * @doc		    Only one instance of HBAList must be present
77fcf3ce44SJohn Forte  *		    per address space at a time.  The singleton design pattern
78fcf3ce44SJohn Forte  *		    is used to enforce this behavior.
79fcf3ce44SJohn Forte  */
instance()80fcf3ce44SJohn Forte HBAList* HBAList::instance() {
81fcf3ce44SJohn Forte 	Trace log("HBAList::instance");
82fcf3ce44SJohn Forte 	if (_instance == 0) {
83fcf3ce44SJohn Forte 	    _instance = new HBAList();
84fcf3ce44SJohn Forte 	}
85fcf3ce44SJohn Forte 	return (_instance);
86fcf3ce44SJohn Forte }
87fcf3ce44SJohn Forte 
88fcf3ce44SJohn Forte /**
89fcf3ce44SJohn Forte  * @memo	    Fetch an HBA based on name.
90fcf3ce44SJohn Forte  *		    Always returns  non-null or throw an Exception.
91fcf3ce44SJohn Forte  * @precondition    HBAs must be loaded in the list
92fcf3ce44SJohn Forte  * @postcondition   A handle will be opened.  The caller must close the handle
93fcf3ce44SJohn Forte  *		    at some later time to prevent leakage.
94fcf3ce44SJohn Forte  * @exception	    BadArgumentException if the name is not properly formatted
95fcf3ce44SJohn Forte  * @exception	    IllegalIndexException if the name does not match any
96fcf3ce44SJohn Forte  *		    present HBAs within this list.
97fcf3ce44SJohn Forte  * @return	    A valid handle for future API calls
98fcf3ce44SJohn Forte  * @param	    name The name of the HBA to open
99fcf3ce44SJohn Forte  *
100fcf3ce44SJohn Forte  * @doc		    This routine will always return a handle (ie, non null)
101fcf3ce44SJohn Forte  *		    or will throw an exception.
102fcf3ce44SJohn Forte  */
openHBA(string name)103fcf3ce44SJohn Forte Handle* HBAList::openHBA(string name) {
104fcf3ce44SJohn Forte 	Trace log("HBAList::openHBA(name)");
105fcf3ce44SJohn Forte 	int index = -1;
106fcf3ce44SJohn Forte 	try {
107fcf3ce44SJohn Forte 	    string::size_type offset = name.find_last_of("-");
108fcf3ce44SJohn Forte 	    if (offset >= 0) {
109fcf3ce44SJohn Forte 		string indexString = name.substr(offset+1);
110fcf3ce44SJohn Forte 		index = atoi(indexString.c_str());
111fcf3ce44SJohn Forte 	    }
112fcf3ce44SJohn Forte 	} catch (...) {
113fcf3ce44SJohn Forte 	    throw BadArgumentException();
114fcf3ce44SJohn Forte 	}
115fcf3ce44SJohn Forte 	lock();
116fcf3ce44SJohn Forte 	if (index < 0 || index > hbas.size()) {
117fcf3ce44SJohn Forte 	    unlock();
118fcf3ce44SJohn Forte 	    throw IllegalIndexException();
119fcf3ce44SJohn Forte 	} else {
120fcf3ce44SJohn Forte 	    HBA *tmp = hbas[index];
121fcf3ce44SJohn Forte 	    unlock();
122fcf3ce44SJohn Forte 	    tmp->validatePresent();
123fcf3ce44SJohn Forte 	    return (new Handle(tmp));
124fcf3ce44SJohn Forte 	}
125fcf3ce44SJohn Forte }
126fcf3ce44SJohn Forte 
127fcf3ce44SJohn Forte /**
128fcf3ce44SJohn Forte  * @memo	    Fetch an target mode FC HBA based on name.
129fcf3ce44SJohn Forte  *		    Always returns  non-null or throw an Exception.
130fcf3ce44SJohn Forte  * @precondition    Target mode HBAs must be loaded in the list
131fcf3ce44SJohn Forte  * @postcondition   A handle will be opened.  The caller must close the handle
132fcf3ce44SJohn Forte  *		    at some later time to prevent leakage.
133fcf3ce44SJohn Forte  * @exception	    BadArgumentException if the name is not properly formatted
134fcf3ce44SJohn Forte  * @exception	    IllegalIndexException if the name does not match any
135fcf3ce44SJohn Forte  *		    present HBAs within this list.
136fcf3ce44SJohn Forte  * @return	    A valid handle for future API calls
137fcf3ce44SJohn Forte  * @param	    name The name of the target mode HBA to open
138fcf3ce44SJohn Forte  *
139fcf3ce44SJohn Forte  * @doc		    This routine will always return a handle (ie, non null)
140fcf3ce44SJohn Forte  *		    or will throw an exception.
141fcf3ce44SJohn Forte  */
openTgtHBA(string name)142fcf3ce44SJohn Forte Handle* HBAList::openTgtHBA(string name) {
143fcf3ce44SJohn Forte 	Trace log("HBAList::openHBA(name)");
144fcf3ce44SJohn Forte 	int index = -1;
145fcf3ce44SJohn Forte 	try {
146fcf3ce44SJohn Forte 	    string::size_type offset = name.find_last_of("-");
147fcf3ce44SJohn Forte 	    if (offset >= 0) {
148fcf3ce44SJohn Forte 		string indexString = name.substr(offset+1);
149fcf3ce44SJohn Forte 		index = atoi(indexString.c_str());
150fcf3ce44SJohn Forte 	    }
151fcf3ce44SJohn Forte 	} catch (...) {
152fcf3ce44SJohn Forte 	    throw BadArgumentException();
153fcf3ce44SJohn Forte 	}
154fcf3ce44SJohn Forte 	lock();
155fcf3ce44SJohn Forte 	if (index < 0 || index > tgthbas.size()) {
156fcf3ce44SJohn Forte 	    unlock();
157fcf3ce44SJohn Forte 	    throw IllegalIndexException();
158fcf3ce44SJohn Forte 	} else {
159fcf3ce44SJohn Forte 	    HBA *tmp = tgthbas[index];
160fcf3ce44SJohn Forte 	    unlock();
161fcf3ce44SJohn Forte 	    tmp->validatePresent();
162fcf3ce44SJohn Forte 	    return (new Handle(tmp));
163fcf3ce44SJohn Forte 	}
164fcf3ce44SJohn Forte }
165fcf3ce44SJohn Forte 
166fcf3ce44SJohn Forte /**
167fcf3ce44SJohn Forte  * @memo	    Get the name of an HBA at the given index
168fcf3ce44SJohn Forte  * @precondition    HBAs must be loaded in the list
169fcf3ce44SJohn Forte  * @exception	    IllegalIndexException Thrown if the index doesn't match any
170fcf3ce44SJohn Forte  *		    HBA in the list
171fcf3ce44SJohn Forte  * @return	    The name of the specified HBA
172fcf3ce44SJohn Forte  * @param	    index The zero based index of the desired HBA
173fcf3ce44SJohn Forte  *
174fcf3ce44SJohn Forte  */
getHBAName(int index)175fcf3ce44SJohn Forte string HBAList::getHBAName(int index) {
176fcf3ce44SJohn Forte 	Trace log("HBAList::getHBAName");
177fcf3ce44SJohn Forte 	lock();
178fcf3ce44SJohn Forte 	if (index < 0 || index > hbas.size()) {
179fcf3ce44SJohn Forte 	    unlock();
180fcf3ce44SJohn Forte 	    throw IllegalIndexException();
181fcf3ce44SJohn Forte 	} else {
182fcf3ce44SJohn Forte 	    HBA *tmp = hbas[index];
183fcf3ce44SJohn Forte 	    unlock();
184fcf3ce44SJohn Forte 	    tmp->validatePresent();
185fcf3ce44SJohn Forte 	    char buf[128];
186fcf3ce44SJohn Forte 	    snprintf(buf, 128, "%s-%d", tmp->getName().c_str(), index);
187fcf3ce44SJohn Forte 	    string name = buf;
188fcf3ce44SJohn Forte 	    return (name);
189fcf3ce44SJohn Forte 	}
190fcf3ce44SJohn Forte }
191fcf3ce44SJohn Forte 
192fcf3ce44SJohn Forte /**
193fcf3ce44SJohn Forte  * @memo	    Get the name of an target mode HBA at the given index
194fcf3ce44SJohn Forte  * @precondition    Target mode HBAs must be loaded in the list
195fcf3ce44SJohn Forte  * @exception	    IllegalIndexException Thrown if the index doesn't match any
196fcf3ce44SJohn Forte  *		    HBA in the list
197fcf3ce44SJohn Forte  * @return	    The name of the specified target mode HBA
198fcf3ce44SJohn Forte  * @param	    index The zero based index of the desired target mode HBA
199fcf3ce44SJohn Forte  *
200fcf3ce44SJohn Forte  */
getTgtHBAName(int index)201fcf3ce44SJohn Forte string HBAList::getTgtHBAName(int index) {
202fcf3ce44SJohn Forte 	Trace log("HBAList::getTgtHBAName");
203fcf3ce44SJohn Forte 	lock();
204fcf3ce44SJohn Forte 	if (index < 0 || index > tgthbas.size()) {
205fcf3ce44SJohn Forte 	    unlock();
206fcf3ce44SJohn Forte 	    throw IllegalIndexException();
207fcf3ce44SJohn Forte 	} else {
208fcf3ce44SJohn Forte 	    HBA *tmp = tgthbas[index];
209fcf3ce44SJohn Forte 	    unlock();
210fcf3ce44SJohn Forte 	    tmp->validatePresent();
211fcf3ce44SJohn Forte 	    char buf[128];
212fcf3ce44SJohn Forte 	    snprintf(buf, 128, "%s-%d", tmp->getName().c_str(), index);
213fcf3ce44SJohn Forte 	    string name = buf;
214fcf3ce44SJohn Forte 	    return (name);
215fcf3ce44SJohn Forte 	}
216fcf3ce44SJohn Forte }
217fcf3ce44SJohn Forte 
218fcf3ce44SJohn Forte /**
219fcf3ce44SJohn Forte  * @memo	    Open an HBA based on a WWN
220fcf3ce44SJohn Forte  * @precondition    HBAs must be loaded in the list
221fcf3ce44SJohn Forte  * @postcondition   A handle will be opened.  The caller must close the handle
222fcf3ce44SJohn Forte  *		    at some later time to prevent leakage.
223fcf3ce44SJohn Forte  * @exception	    IllegalWWNException Thrown if the wwn doesn't match any
224fcf3ce44SJohn Forte  *		    HBA in the list
225fcf3ce44SJohn Forte  * @return	    A valid Handle for later use by API calls
226fcf3ce44SJohn Forte  * @param	    wwn The node or any port WWN of HBA to open
227fcf3ce44SJohn Forte  * @see		    HBA::containsWWN
228fcf3ce44SJohn Forte  *
229fcf3ce44SJohn Forte  * @doc		    This routine will accept both Node and Port WWNs based
230fcf3ce44SJohn Forte  *		    on the HBA routine containsWWN
231fcf3ce44SJohn Forte  */
openHBA(uint64_t wwn)232fcf3ce44SJohn Forte Handle* HBAList::openHBA(uint64_t wwn) {
233fcf3ce44SJohn Forte 
234fcf3ce44SJohn Forte 	Trace log("HBAList::openHBA(wwn)");
235fcf3ce44SJohn Forte 	lock();
236fcf3ce44SJohn Forte 	HBA *tmp;
237fcf3ce44SJohn Forte 	for (int i = 0; i < hbas.size(); i++) {
238fcf3ce44SJohn Forte 	    if (hbas[i]->containsWWN(wwn)) {
239fcf3ce44SJohn Forte 		tmp = hbas[i];
240fcf3ce44SJohn Forte 		unlock();
241fcf3ce44SJohn Forte 		tmp->validatePresent();
242fcf3ce44SJohn Forte 		return (new Handle(tmp));
243fcf3ce44SJohn Forte 	    }
244fcf3ce44SJohn Forte 	}
245fcf3ce44SJohn Forte 	unlock();
246fcf3ce44SJohn Forte 	throw IllegalWWNException();
247fcf3ce44SJohn Forte }
248fcf3ce44SJohn Forte 
249fcf3ce44SJohn Forte /**
250fcf3ce44SJohn Forte  * @memo	    Open an target mode HBA based on a WWN
251fcf3ce44SJohn Forte  * @precondition    Targee mode HBAs must be loaded in the list
252fcf3ce44SJohn Forte  * @postcondition   A handle will be opened.  The caller must close the handle
253fcf3ce44SJohn Forte  *		    at some later time to prevent leakage.
254fcf3ce44SJohn Forte  * @exception	    IllegalWWNException Thrown if the wwn doesn't match any
255fcf3ce44SJohn Forte  *		    target mode HBA in the list
256fcf3ce44SJohn Forte  * @return	    A valid Handle for later use by API calls
257fcf3ce44SJohn Forte  * @param	    The node WWN or any port WWN of target mode HBA to open
258fcf3ce44SJohn Forte  * @see		    HBA::containsWWN
259fcf3ce44SJohn Forte  *
260fcf3ce44SJohn Forte  * @doc		    This routine will accept both Node and Port WWNs based
261fcf3ce44SJohn Forte  *		    on the HBA routine containsWWN
262fcf3ce44SJohn Forte  */
openTgtHBA(uint64_t wwn)263fcf3ce44SJohn Forte Handle* HBAList::openTgtHBA(uint64_t wwn) {
264fcf3ce44SJohn Forte 
265fcf3ce44SJohn Forte 	Trace log("HBAList::openTgtHBA(wwn)");
266fcf3ce44SJohn Forte 	lock();
267fcf3ce44SJohn Forte 	HBA *tmp;
268fcf3ce44SJohn Forte 	for (int i = 0; i < tgthbas.size(); i++) {
269fcf3ce44SJohn Forte 	    if (tgthbas[i]->containsWWN(wwn)) {
270fcf3ce44SJohn Forte 		tmp = tgthbas[i];
271fcf3ce44SJohn Forte 		unlock();
272fcf3ce44SJohn Forte 		tmp->validatePresent();
273fcf3ce44SJohn Forte 		return (new Handle(tmp));
274fcf3ce44SJohn Forte 	    }
275fcf3ce44SJohn Forte 	}
276fcf3ce44SJohn Forte 	unlock();
277fcf3ce44SJohn Forte 	throw IllegalWWNException();
278fcf3ce44SJohn Forte }
279fcf3ce44SJohn Forte 
280fcf3ce44SJohn Forte /**
281fcf3ce44SJohn Forte  * @memo	    Get the number of adapters present in the list
282fcf3ce44SJohn Forte  * @postcondition   List of HBAs will be loaded
283fcf3ce44SJohn Forte  * @exception	    ... Underlying exceptions will be thrown
284fcf3ce44SJohn Forte  * @return	    The number of adapters in the list
285fcf3ce44SJohn Forte  *
286fcf3ce44SJohn Forte  * @doc		    This routine will triger discovery of HBAs on the system.
287fcf3ce44SJohn Forte  *		    It will also handle addition/removal of HBAs in the list
288fcf3ce44SJohn Forte  *		    based on dynamic reconfiguration operations.  The max
289fcf3ce44SJohn Forte  *		    number of HBAs that HBA API supports is up to the
290fcf3ce44SJohn Forte  *		    uint32_t size.  VSL supports up to int32_t size thus
291fcf3ce44SJohn Forte  *		    it gives enough room for the HBA API library
292fcf3ce44SJohn Forte  *		    to handle up to max uint32_t number if adapters.
293fcf3ce44SJohn Forte  */
getNumberofAdapters()294fcf3ce44SJohn Forte int HBAList::getNumberofAdapters() {
295fcf3ce44SJohn Forte 	Trace log("HBAList::getNumberofAdapters");
296fcf3ce44SJohn Forte 	lock();
297fcf3ce44SJohn Forte 
298fcf3ce44SJohn Forte 	try {
299fcf3ce44SJohn Forte 	if (hbas.size() == 0) {
300fcf3ce44SJohn Forte 	    // First pass, just store them all blindly
301fcf3ce44SJohn Forte 	    FCHBA::loadAdapters(hbas);
302fcf3ce44SJohn Forte 	} else {
303fcf3ce44SJohn Forte 	    // Second pass, do the update operation
304fcf3ce44SJohn Forte 	    vector<HBA*> tmp;
305fcf3ce44SJohn Forte 	    FCHBA::loadAdapters(tmp);
306fcf3ce44SJohn Forte 	    bool matched;
307fcf3ce44SJohn Forte 	    for (int i = 0; i < tmp.size(); i++) {
308fcf3ce44SJohn Forte 		matched = false;
309fcf3ce44SJohn Forte 		for (int j = 0; j < hbas.size(); j++) {
310fcf3ce44SJohn Forte 		    if (*tmp[i] == *hbas[j]) {
311fcf3ce44SJohn Forte 			matched = true;
312fcf3ce44SJohn Forte 			break;
313fcf3ce44SJohn Forte 		    }
314fcf3ce44SJohn Forte 		}
315fcf3ce44SJohn Forte 		if (matched) {
316fcf3ce44SJohn Forte 		    delete (tmp[i]);
317fcf3ce44SJohn Forte 		} else {
318fcf3ce44SJohn Forte 		    hbas.insert(hbas.end(), tmp[i]);
319fcf3ce44SJohn Forte 		}
320fcf3ce44SJohn Forte 	    }
321fcf3ce44SJohn Forte 	}
322fcf3ce44SJohn Forte 	} catch (...) {
323fcf3ce44SJohn Forte 	    unlock();
324fcf3ce44SJohn Forte 	    throw;
325fcf3ce44SJohn Forte 	}
326fcf3ce44SJohn Forte 
327fcf3ce44SJohn Forte 	unlock();
328fcf3ce44SJohn Forte 
329fcf3ce44SJohn Forte 	// When there is more than HBA_MAX_PER_LIST(= int32_max)
330fcf3ce44SJohn Forte 	// VSL returns an error so it is safe to cast it here.
331fcf3ce44SJohn Forte 	return ((uint32_t)hbas.size());
332fcf3ce44SJohn Forte }
333fcf3ce44SJohn Forte 
334fcf3ce44SJohn Forte /**
335fcf3ce44SJohn Forte  * @memo	    Get the number of target mode adapters present in the list
336fcf3ce44SJohn Forte  * @postcondition   List of TgtHBAs will be loaded
337fcf3ce44SJohn Forte  * @exception	    ... Underlying exceptions will be thrown
338fcf3ce44SJohn Forte  * @return	    The number of target mode adapters in the list
339fcf3ce44SJohn Forte  *
340fcf3ce44SJohn Forte  * @doc		    This routine will triger discovery of Target mode HBAs on
341fcf3ce44SJohn Forte  *		    the system. It will also handle addition/removal of Target
342fcf3ce44SJohn Forte  * 		    mode HBAs in the list based on dynamic reconfiguration
343fcf3ce44SJohn Forte  *		    operations. The max number of target mode HBAs that
344fcf3ce44SJohn Forte  *		    HBA API supports is up to the
345fcf3ce44SJohn Forte  *		    uint32_t size.  VSL supports up to int32_t size thus
346fcf3ce44SJohn Forte  *		    it gives enough room for the HBA API library
347fcf3ce44SJohn Forte  *		    to handle up to max uint32_t number of adapters.
348fcf3ce44SJohn Forte  */
getNumberofTgtAdapters()349fcf3ce44SJohn Forte int HBAList::getNumberofTgtAdapters() {
350fcf3ce44SJohn Forte 	Trace log("HBAList::getNumberofTgtAdapters");
351fcf3ce44SJohn Forte 	lock();
352fcf3ce44SJohn Forte 
353fcf3ce44SJohn Forte 	try {
354fcf3ce44SJohn Forte 	    if (tgthbas.size() == 0) {
355fcf3ce44SJohn Forte 		// First pass, just store them all blindly
356fcf3ce44SJohn Forte 		TgtFCHBA::loadAdapters(tgthbas);
357fcf3ce44SJohn Forte 	    } else {
358fcf3ce44SJohn Forte 		// Second pass, do the update operation
359fcf3ce44SJohn Forte 		vector<HBA*> tmp;
360fcf3ce44SJohn Forte 		TgtFCHBA::loadAdapters(tmp);
361fcf3ce44SJohn Forte 		bool matched;
362fcf3ce44SJohn Forte 		for (int i = 0; i < tmp.size(); i++) {
363fcf3ce44SJohn Forte 		    matched = false;
364fcf3ce44SJohn Forte 		    for (int j = 0; j < tgthbas.size(); j++) {
365fcf3ce44SJohn Forte 			if (*tmp[i] == *tgthbas[j]) {
366fcf3ce44SJohn Forte 			    matched = true;
367fcf3ce44SJohn Forte 			    break;
368fcf3ce44SJohn Forte 			}
369fcf3ce44SJohn Forte 		    }
370fcf3ce44SJohn Forte 		    if (matched) {
371fcf3ce44SJohn Forte 			delete (tmp[i]);
372fcf3ce44SJohn Forte 		    } else {
373fcf3ce44SJohn Forte 			tgthbas.insert(tgthbas.end(), tmp[i]);
374fcf3ce44SJohn Forte 		    }
375fcf3ce44SJohn Forte 		}
376fcf3ce44SJohn Forte 	    }
377fcf3ce44SJohn Forte 	} catch (...) {
378fcf3ce44SJohn Forte 	    unlock();
379fcf3ce44SJohn Forte 	    throw;
380fcf3ce44SJohn Forte 	}
381fcf3ce44SJohn Forte 
382fcf3ce44SJohn Forte 	unlock();
383fcf3ce44SJohn Forte 
384fcf3ce44SJohn Forte 	// When there is more than HBA_MAX_PER_LIST(= int32_max)
385fcf3ce44SJohn Forte 	// VSL returns an error so it is safe to cast it here.
386fcf3ce44SJohn Forte 	return ((uint32_t)tgthbas.size());
387fcf3ce44SJohn Forte }
388fcf3ce44SJohn Forte 
389fcf3ce44SJohn Forte /**
390fcf3ce44SJohn Forte  * @memo	    Load the list
391fcf3ce44SJohn Forte  * @return	    HBA_STATUS_OK
392fcf3ce44SJohn Forte  *
393fcf3ce44SJohn Forte  * @doc		    Currently this routine is a no-op and may be a cantidate
394fcf3ce44SJohn Forte  *		    for removal in the future.
395fcf3ce44SJohn Forte  */
load()396fcf3ce44SJohn Forte HBA_STATUS HBAList::load() {
397fcf3ce44SJohn Forte 	Trace log("HBAList::load");
398fcf3ce44SJohn Forte 
399fcf3ce44SJohn Forte 	// No lock is required since no VSL specific action requried.
400fcf3ce44SJohn Forte 	return (HBA_STATUS_OK);
401fcf3ce44SJohn Forte }
402fcf3ce44SJohn Forte 
403fcf3ce44SJohn Forte /**
404fcf3ce44SJohn Forte  * @memo	    Free up resources
405fcf3ce44SJohn Forte  */
~HBAList()406fcf3ce44SJohn Forte HBAList::~HBAList() {
407fcf3ce44SJohn Forte 	Trace log("HBAList::~HBAList");
408fcf3ce44SJohn Forte 	for (int i = 0; i < hbas.size(); i++) {
409fcf3ce44SJohn Forte 	    delete (hbas[i]);
410fcf3ce44SJohn Forte 	}
411fcf3ce44SJohn Forte 	for (int i = 0; i < tgthbas.size(); i++) {
412fcf3ce44SJohn Forte 	    delete (tgthbas[i]);
413fcf3ce44SJohn Forte 	}
414fcf3ce44SJohn Forte }
415fcf3ce44SJohn Forte 
getVSLAttributes()416fcf3ce44SJohn Forte HBA_LIBRARYATTRIBUTES HBAList::getVSLAttributes() {
417fcf3ce44SJohn Forte 	HBA_LIBRARYATTRIBUTES attrs;
418fcf3ce44SJohn Forte 	char	build_time[] = BUILD_TIME;
419fcf3ce44SJohn Forte 	attrs.final = 0;
420fcf3ce44SJohn Forte 	memset(&attrs, 0, sizeof(attrs));
421fcf3ce44SJohn Forte 	strlcpy(attrs.VName, VSL_NAME, sizeof (attrs.VName));
422fcf3ce44SJohn Forte 	strlcpy(attrs.VVersion, VSL_STRING_VERSION, sizeof (attrs.VVersion));
423fcf3ce44SJohn Forte 	strptime(build_time, "%c", &attrs.build_date);
424fcf3ce44SJohn Forte 
425fcf3ce44SJohn Forte 	return (attrs);
426fcf3ce44SJohn Forte }
427