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