4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
29 #include "Exceptions.h"
31 #include "sun_fc_version.h"
43 * @memo Private constructor (used to create singleton instance)
44 * @see HBAList::instance
46 HBAList::HBAList() { }
49 * Internal singleton instance
51 HBAList
* HBAList::_instance
= 0;
54 * Max number of adapters that this class supports.
56 const int32_t HBAList::HBA_MAX_PER_LIST
= INT_MAX
;
59 * @memo Free up resources held by this HBA list
60 * @postcondition All memory used by this list will be freed
61 * @return HBA_STATUS_OK on success
64 HBA_STATUS
HBAList::unload() {
65 Trace
log("HBAList::unload");
69 return (HBA_STATUS_OK
);
73 * @memo Fetch the singleton instance
74 * @return The singleton instance
76 * @doc Only one instance of HBAList must be present
77 * per address space at a time. The singleton design pattern
78 * is used to enforce this behavior.
80 HBAList
* HBAList::instance() {
81 Trace
log("HBAList::instance");
83 _instance
= new HBAList();
89 * @memo Fetch an HBA based on name.
90 * Always returns non-null or throw an Exception.
91 * @precondition HBAs must be loaded in the list
92 * @postcondition A handle will be opened. The caller must close the handle
93 * at some later time to prevent leakage.
94 * @exception BadArgumentException if the name is not properly formatted
95 * @exception IllegalIndexException if the name does not match any
96 * present HBAs within this list.
97 * @return A valid handle for future API calls
98 * @param name The name of the HBA to open
100 * @doc This routine will always return a handle (ie, non null)
101 * or will throw an exception.
103 Handle
* HBAList::openHBA(string name
) {
104 Trace
log("HBAList::openHBA(name)");
107 string::size_type offset
= name
.find_last_of("-");
109 string indexString
= name
.substr(offset
+1);
110 index
= atoi(indexString
.c_str());
113 throw BadArgumentException();
116 if (index
< 0 || index
> hbas
.size()) {
118 throw IllegalIndexException();
120 HBA
*tmp
= hbas
[index
];
122 tmp
->validatePresent();
123 return (new Handle(tmp
));
128 * @memo Fetch an target mode FC HBA based on name.
129 * Always returns non-null or throw an Exception.
130 * @precondition Target mode HBAs must be loaded in the list
131 * @postcondition A handle will be opened. The caller must close the handle
132 * at some later time to prevent leakage.
133 * @exception BadArgumentException if the name is not properly formatted
134 * @exception IllegalIndexException if the name does not match any
135 * present HBAs within this list.
136 * @return A valid handle for future API calls
137 * @param name The name of the target mode HBA to open
139 * @doc This routine will always return a handle (ie, non null)
140 * or will throw an exception.
142 Handle
* HBAList::openTgtHBA(string name
) {
143 Trace
log("HBAList::openHBA(name)");
146 string::size_type offset
= name
.find_last_of("-");
148 string indexString
= name
.substr(offset
+1);
149 index
= atoi(indexString
.c_str());
152 throw BadArgumentException();
155 if (index
< 0 || index
> tgthbas
.size()) {
157 throw IllegalIndexException();
159 HBA
*tmp
= tgthbas
[index
];
161 tmp
->validatePresent();
162 return (new Handle(tmp
));
167 * @memo Get the name of an HBA at the given index
168 * @precondition HBAs must be loaded in the list
169 * @exception IllegalIndexException Thrown if the index doesn't match any
171 * @return The name of the specified HBA
172 * @param index The zero based index of the desired HBA
175 string
HBAList::getHBAName(int index
) {
176 Trace
log("HBAList::getHBAName");
178 if (index
< 0 || index
> hbas
.size()) {
180 throw IllegalIndexException();
182 HBA
*tmp
= hbas
[index
];
184 tmp
->validatePresent();
186 snprintf(buf
, 128, "%s-%d", tmp
->getName().c_str(), index
);
193 * @memo Get the name of an target mode HBA at the given index
194 * @precondition Target mode HBAs must be loaded in the list
195 * @exception IllegalIndexException Thrown if the index doesn't match any
197 * @return The name of the specified target mode HBA
198 * @param index The zero based index of the desired target mode HBA
201 string
HBAList::getTgtHBAName(int index
) {
202 Trace
log("HBAList::getTgtHBAName");
204 if (index
< 0 || index
> tgthbas
.size()) {
206 throw IllegalIndexException();
208 HBA
*tmp
= tgthbas
[index
];
210 tmp
->validatePresent();
212 snprintf(buf
, 128, "%s-%d", tmp
->getName().c_str(), index
);
219 * @memo Open an HBA based on a WWN
220 * @precondition HBAs must be loaded in the list
221 * @postcondition A handle will be opened. The caller must close the handle
222 * at some later time to prevent leakage.
223 * @exception IllegalWWNException Thrown if the wwn doesn't match any
225 * @return A valid Handle for later use by API calls
226 * @param wwn The node or any port WWN of HBA to open
227 * @see HBA::containsWWN
229 * @doc This routine will accept both Node and Port WWNs based
230 * on the HBA routine containsWWN
232 Handle
* HBAList::openHBA(uint64_t wwn
) {
234 Trace
log("HBAList::openHBA(wwn)");
237 for (int i
= 0; i
< hbas
.size(); i
++) {
238 if (hbas
[i
]->containsWWN(wwn
)) {
241 tmp
->validatePresent();
242 return (new Handle(tmp
));
246 throw IllegalWWNException();
250 * @memo Open an target mode HBA based on a WWN
251 * @precondition Targee mode HBAs must be loaded in the list
252 * @postcondition A handle will be opened. The caller must close the handle
253 * at some later time to prevent leakage.
254 * @exception IllegalWWNException Thrown if the wwn doesn't match any
255 * target mode HBA in the list
256 * @return A valid Handle for later use by API calls
257 * @param The node WWN or any port WWN of target mode HBA to open
258 * @see HBA::containsWWN
260 * @doc This routine will accept both Node and Port WWNs based
261 * on the HBA routine containsWWN
263 Handle
* HBAList::openTgtHBA(uint64_t wwn
) {
265 Trace
log("HBAList::openTgtHBA(wwn)");
268 for (int i
= 0; i
< tgthbas
.size(); i
++) {
269 if (tgthbas
[i
]->containsWWN(wwn
)) {
272 tmp
->validatePresent();
273 return (new Handle(tmp
));
277 throw IllegalWWNException();
281 * @memo Get the number of adapters present in the list
282 * @postcondition List of HBAs will be loaded
283 * @exception ... Underlying exceptions will be thrown
284 * @return The number of adapters in the list
286 * @doc This routine will triger discovery of HBAs on the system.
287 * It will also handle addition/removal of HBAs in the list
288 * based on dynamic reconfiguration operations. The max
289 * number of HBAs that HBA API supports is up to the
290 * uint32_t size. VSL supports up to int32_t size thus
291 * it gives enough room for the HBA API library
292 * to handle up to max uint32_t number if adapters.
294 int HBAList::getNumberofAdapters() {
295 Trace
log("HBAList::getNumberofAdapters");
299 if (hbas
.size() == 0) {
300 // First pass, just store them all blindly
301 FCHBA::loadAdapters(hbas
);
303 // Second pass, do the update operation
305 FCHBA::loadAdapters(tmp
);
307 for (int i
= 0; i
< tmp
.size(); i
++) {
309 for (int j
= 0; j
< hbas
.size(); j
++) {
310 if (*tmp
[i
] == *hbas
[j
]) {
318 hbas
.insert(hbas
.end(), tmp
[i
]);
329 // When there is more than HBA_MAX_PER_LIST(= int32_max)
330 // VSL returns an error so it is safe to cast it here.
331 return ((uint32_t)hbas
.size());
335 * @memo Get the number of target mode adapters present in the list
336 * @postcondition List of TgtHBAs will be loaded
337 * @exception ... Underlying exceptions will be thrown
338 * @return The number of target mode adapters in the list
340 * @doc This routine will triger discovery of Target mode HBAs on
341 * the system. It will also handle addition/removal of Target
342 * mode HBAs in the list based on dynamic reconfiguration
343 * operations. The max number of target mode HBAs that
344 * HBA API supports is up to the
345 * uint32_t size. VSL supports up to int32_t size thus
346 * it gives enough room for the HBA API library
347 * to handle up to max uint32_t number of adapters.
349 int HBAList::getNumberofTgtAdapters() {
350 Trace
log("HBAList::getNumberofTgtAdapters");
354 if (tgthbas
.size() == 0) {
355 // First pass, just store them all blindly
356 TgtFCHBA::loadAdapters(tgthbas
);
358 // Second pass, do the update operation
360 TgtFCHBA::loadAdapters(tmp
);
362 for (int i
= 0; i
< tmp
.size(); i
++) {
364 for (int j
= 0; j
< tgthbas
.size(); j
++) {
365 if (*tmp
[i
] == *tgthbas
[j
]) {
373 tgthbas
.insert(tgthbas
.end(), tmp
[i
]);
384 // When there is more than HBA_MAX_PER_LIST(= int32_max)
385 // VSL returns an error so it is safe to cast it here.
386 return ((uint32_t)tgthbas
.size());
390 * @memo Load the list
391 * @return HBA_STATUS_OK
393 * @doc Currently this routine is a no-op and may be a cantidate
394 * for removal in the future.
396 HBA_STATUS
HBAList::load() {
397 Trace
log("HBAList::load");
399 // No lock is required since no VSL specific action requried.
400 return (HBA_STATUS_OK
);
404 * @memo Free up resources
406 HBAList::~HBAList() {
407 Trace
log("HBAList::~HBAList");
408 for (int i
= 0; i
< hbas
.size(); i
++) {
411 for (int i
= 0; i
< tgthbas
.size(); i
++) {
416 HBA_LIBRARYATTRIBUTES
HBAList::getVSLAttributes() {
417 HBA_LIBRARYATTRIBUTES attrs
;
418 char build_time
[] = BUILD_TIME
;
420 memset(&attrs
, 0, sizeof(attrs
));
421 strlcpy(attrs
.VName
, VSL_NAME
, sizeof (attrs
.VName
));
422 strlcpy(attrs
.VVersion
, VSL_STRING_VERSION
, sizeof (attrs
.VVersion
));
423 strptime(build_time
, "%c", &attrs
.build_date
);