summaryrefslogtreecommitdiff
path: root/usr/src/lib/sun_fc/common
diff options
context:
space:
mode:
authorJohn Forte <John.Forte@Sun.COM>2008-10-14 15:09:13 -0700
committerJohn Forte <John.Forte@Sun.COM>2008-10-14 15:09:13 -0700
commitfcf3ce441efd61da9bb2884968af01cb7c1452cc (patch)
tree0e80d59ad41702571586195bf099ccc14222ce02 /usr/src/lib/sun_fc/common
parent247b82a1f1cb5ebd2d163bd9afdb1a3065611962 (diff)
downloadillumos-joyent-fcf3ce441efd61da9bb2884968af01cb7c1452cc.tar.gz
6745433 Merge NWS consolidation into OS/Net consolidation
Diffstat (limited to 'usr/src/lib/sun_fc/common')
-rw-r--r--usr/src/lib/sun_fc/common/AdapterAddEvent.h50
-rw-r--r--usr/src/lib/sun_fc/common/AdapterAddEventBridge.h47
-rw-r--r--usr/src/lib/sun_fc/common/AdapterAddEventListener.cc68
-rw-r--r--usr/src/lib/sun_fc/common/AdapterAddEventListener.h55
-rw-r--r--usr/src/lib/sun_fc/common/AdapterDeviceEvent.h60
-rw-r--r--usr/src/lib/sun_fc/common/AdapterDeviceEventBridge.h48
-rw-r--r--usr/src/lib/sun_fc/common/AdapterDeviceEventListener.cc74
-rw-r--r--usr/src/lib/sun_fc/common/AdapterDeviceEventListener.h59
-rw-r--r--usr/src/lib/sun_fc/common/AdapterEvent.h60
-rw-r--r--usr/src/lib/sun_fc/common/AdapterEventBridge.h47
-rw-r--r--usr/src/lib/sun_fc/common/AdapterEventListener.cc74
-rw-r--r--usr/src/lib/sun_fc/common/AdapterEventListener.h58
-rw-r--r--usr/src/lib/sun_fc/common/AdapterPortEvent.h63
-rw-r--r--usr/src/lib/sun_fc/common/AdapterPortEventBridge.h47
-rw-r--r--usr/src/lib/sun_fc/common/AdapterPortEventListener.cc74
-rw-r--r--usr/src/lib/sun_fc/common/AdapterPortEventListener.h60
-rw-r--r--usr/src/lib/sun_fc/common/AdapterPortStatEvent.h58
-rw-r--r--usr/src/lib/sun_fc/common/AdapterPortStatEventBridge.h47
-rw-r--r--usr/src/lib/sun_fc/common/AdapterPortStatEventListener.cc70
-rw-r--r--usr/src/lib/sun_fc/common/AdapterPortStatEventListener.h57
-rw-r--r--usr/src/lib/sun_fc/common/Event.h39
-rw-r--r--usr/src/lib/sun_fc/common/EventBridgeFactory.cc54
-rw-r--r--usr/src/lib/sun_fc/common/EventBridgeFactory.h63
-rw-r--r--usr/src/lib/sun_fc/common/Exceptions.h231
-rw-r--r--usr/src/lib/sun_fc/common/FCHBA.cc376
-rw-r--r--usr/src/lib/sun_fc/common/FCHBA.h61
-rw-r--r--usr/src/lib/sun_fc/common/FCHBANPIVPort.cc315
-rw-r--r--usr/src/lib/sun_fc/common/FCHBANPIVPort.h70
-rw-r--r--usr/src/lib/sun_fc/common/FCHBAPort.cc1267
-rw-r--r--usr/src/lib/sun_fc/common/FCHBAPort.h149
-rw-r--r--usr/src/lib/sun_fc/common/FCSyseventBridge.cc552
-rw-r--r--usr/src/lib/sun_fc/common/FCSyseventBridge.h94
-rw-r--r--usr/src/lib/sun_fc/common/HBA.cc357
-rw-r--r--usr/src/lib/sun_fc/common/HBA.h87
-rw-r--r--usr/src/lib/sun_fc/common/HBAList.cc423
-rw-r--r--usr/src/lib/sun_fc/common/HBAList.h79
-rw-r--r--usr/src/lib/sun_fc/common/HBANPIVPort.cc114
-rw-r--r--usr/src/lib/sun_fc/common/HBANPIVPort.h54
-rw-r--r--usr/src/lib/sun_fc/common/HBAPort.cc304
-rw-r--r--usr/src/lib/sun_fc/common/HBAPort.h130
-rw-r--r--usr/src/lib/sun_fc/common/HBA_RegisterLibrary.cc66
-rw-r--r--usr/src/lib/sun_fc/common/HBA_RegisterLibraryV2.cc104
-rw-r--r--usr/src/lib/sun_fc/common/Handle.cc437
-rw-r--r--usr/src/lib/sun_fc/common/Handle.h87
-rw-r--r--usr/src/lib/sun_fc/common/HandleNPIVPort.cc141
-rw-r--r--usr/src/lib/sun_fc/common/HandleNPIVPort.h69
-rw-r--r--usr/src/lib/sun_fc/common/HandlePort.cc217
-rw-r--r--usr/src/lib/sun_fc/common/HandlePort.h81
-rw-r--r--usr/src/lib/sun_fc/common/IOError.cc99
-rw-r--r--usr/src/lib/sun_fc/common/InternalError.cc58
-rw-r--r--usr/src/lib/sun_fc/common/LinkEvent.h59
-rw-r--r--usr/src/lib/sun_fc/common/LinkEventBridge.h46
-rw-r--r--usr/src/lib/sun_fc/common/LinkEventListener.cc70
-rw-r--r--usr/src/lib/sun_fc/common/LinkEventListener.h59
-rw-r--r--usr/src/lib/sun_fc/common/Listener.cc112
-rw-r--r--usr/src/lib/sun_fc/common/Listener.h53
-rw-r--r--usr/src/lib/sun_fc/common/Lockable.cc125
-rw-r--r--usr/src/lib/sun_fc/common/Lockable.h50
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcAdapterCreateWWN.cc111
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcAdapterReturnWWN.cc46
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcCloseAdapter.cc54
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcCreateNPIVPort.cc58
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcDeleteNPIVPort.cc57
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcFreeLibrary.cc58
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcGetAdapterAttributes.cc67
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcGetAdapterName.cc70
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcGetAdapterPortAttributes.cc70
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcGetBindingCapability.cc45
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcGetBindingSupport.cc45
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcGetDiscPortAttrs.cc72
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcGetEventBuffer.cc45
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcGetFC4Statistics.cc47
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcGetFCPStatistics.cc46
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcGetFcpPersistentBinding.cc53
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcGetFcpTargetMapping.cc110
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcGetFcpTargetMappingV2.cc77
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcGetNPIVPortInfo.cc57
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcGetNumberOfAdapters.cc59
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcGetNumberOfTgtAdapters.cc49
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcGetPersistentBindingV2.cc45
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcGetPortAttributesByWWN.cc66
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcGetPortNPIVAttributes.cc62
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcGetPortStatistics.cc51
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcGetRNIDMgmtInfo.cc71
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcGetTgtAdapterName.cc70
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcGetVendorLibraryAttributes.cc63
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcGetVersion.cc44
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcLoadLibrary.cc58
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcNPIVGetAdapterAttributes.cc59
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcOpenAdapter.cc63
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcOpenAdapterByWWN.cc65
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcOpenTgtAdapter.cc63
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcOpenTgtAdapterByWWN.cc65
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcRefreshAdapterConfiguration.cc40
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcRefreshInformation.cc53
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcRegisterForAdapterAddEvents.cc74
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcRegisterForAdapterDeviceEvents.cc84
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcRegisterForAdapterEvents.cc77
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcRegisterForAdapterPortEvents.cc82
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcRegisterForAdapterPortStatEvents.cc54
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcRegisterForLinkEvents.cc64
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcRegisterForTargetEvents.cc92
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcRemoveAllPersistentBindings.cc45
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcRemoveCallback.cc44
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcRemovePersistentBinding.cc45
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcResetStatistics.cc43
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcScsiInquiryV2.cc97
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcScsiReadCapacityV2.cc93
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcScsiReportLUNsV2.cc96
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcSendCTPassThru.cc66
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcSendCTPassThruV2.cc85
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcSendLIRR.cc75
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcSendRLS.cc80
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcSendRNID.cc67
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcSendRNIDV2.cc80
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcSendRPL.cc77
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcSendRPS.cc85
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcSendReadCapacity.cc71
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcSendReportLUNs.cc70
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcSendSRL.cc74
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcSendScsiInquiry.cc72
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcSetBindingSupport.cc45
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcSetPersistentBindingV2.cc45
-rw-r--r--usr/src/lib/sun_fc/common/Sun_fcSetRNIDMgmtInfo.cc70
-rw-r--r--usr/src/lib/sun_fc/common/TargetEvent.h63
-rw-r--r--usr/src/lib/sun_fc/common/TargetEventBridge.h48
-rw-r--r--usr/src/lib/sun_fc/common/TargetEventListener.cc85
-rw-r--r--usr/src/lib/sun_fc/common/TargetEventListener.h62
-rw-r--r--usr/src/lib/sun_fc/common/TgtFCHBA.cc278
-rw-r--r--usr/src/lib/sun_fc/common/TgtFCHBA.h63
-rw-r--r--usr/src/lib/sun_fc/common/TgtFCHBAPort.cc494
-rw-r--r--usr/src/lib/sun_fc/common/TgtFCHBAPort.h152
-rw-r--r--usr/src/lib/sun_fc/common/Trace.cc174
-rw-r--r--usr/src/lib/sun_fc/common/Trace.h113
-rw-r--r--usr/src/lib/sun_fc/common/mapfile-vers100
-rw-r--r--usr/src/lib/sun_fc/common/sun_fc.h171
-rw-r--r--usr/src/lib/sun_fc/common/sun_fc_version.h34
137 files changed, 14051 insertions, 0 deletions
diff --git a/usr/src/lib/sun_fc/common/AdapterAddEvent.h b/usr/src/lib/sun_fc/common/AdapterAddEvent.h
new file mode 100644
index 0000000000..c9813352dc
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/AdapterAddEvent.h
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _ADAPTERADDEVENT_H
+#define _ADAPTERADDEVENT_H
+
+
+
+
+#include "Event.h"
+
+/**
+ * @memo Represents an AdapterAdd Event
+ *
+ * @doc When a new adapter is added to the system,
+ * events of this type will be sent to registered
+ * listeners
+ */
+class AdapterAddEvent : public Event {
+public:
+ AdapterAddEvent(uint64_t myWwn) : wwn(myWwn) { }
+ uint64_t getPortWWN() { return (wwn); }
+
+private:
+ uint64_t wwn;
+};
+
+#endif /* _ADAPTERADDEVENT_H */
diff --git a/usr/src/lib/sun_fc/common/AdapterAddEventBridge.h b/usr/src/lib/sun_fc/common/AdapterAddEventBridge.h
new file mode 100644
index 0000000000..0ce3e41bea
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/AdapterAddEventBridge.h
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _ADAPTERADDEVENTBRIDGE_H
+#define _ADAPTERADDEVENTBRIDGE_H
+
+
+#include "AdapterAddEventListener.h"
+
+/**
+ * @memo Bridge interface for adapter Add events
+ *
+ * @doc Used to abstract clients from the specific
+ * underlying details of event management for
+ * the given HBA/driver stack.
+ */
+class AdapterAddEventBridge{
+public:
+ virtual void addListener(AdapterAddEventListener *listener) = 0;
+ virtual void removeListener(AdapterAddEventListener *listener) = 0;
+ virtual int32_t getMaxListener() = 0;
+};
+
+#endif /* _ADAPTERADDEVENTBRIDGE_H */
+
diff --git a/usr/src/lib/sun_fc/common/AdapterAddEventListener.cc b/usr/src/lib/sun_fc/common/AdapterAddEventListener.cc
new file mode 100644
index 0000000000..8c97dac089
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/AdapterAddEventListener.cc
@@ -0,0 +1,68 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#include "AdapterAddEventListener.h"
+#include "AdapterAddEvent.h"
+#include "Exceptions.h"
+#include "Trace.h"
+#include "sun_fc.h"
+
+/**
+ * @memo Create a new AdapterAddEvent listener
+ * @postcondition Listener ready to receive callbacks
+ * @exception BadArgumentException
+ * @param myCallback The listeners callback routine
+ * @param data Opaque data that will be passed to the
+ * callback routine when and event comes in.
+ *
+ */
+AdapterAddEventListener::AdapterAddEventListener(AdapterAddCallback myCallback,
+ void *data) : Listener(data), callback(myCallback) {
+ Trace log("AdapterAddEventListener::AdapterAddEventListener");
+ if (callback == NULL) {
+ throw BadArgumentException();
+ }
+}
+
+/**
+ * @memo Send the event to this listener
+ * @param event The event to send to the listener
+ *
+ * @doc The callback registered in the constructor will
+ * be called.
+ */
+void AdapterAddEventListener::dispatch(Event &event) {
+ Trace log("AdapterAddEventListener::dispatch");
+ AdapterAddEvent *e = static_cast<AdapterAddEvent*> (&event);
+ if (e != NULL) {
+ HBA_WWN wwn;
+ uint64_t lwwn = htonll(e->getPortWWN());
+ memcpy(&wwn, &lwwn, sizeof (wwn));
+ callback(getData(), wwn, HBA_EVENT_ADAPTER_ADD);
+ } else {
+ log.internalError("Unexpected event type.");
+ }
+}
diff --git a/usr/src/lib/sun_fc/common/AdapterAddEventListener.h b/usr/src/lib/sun_fc/common/AdapterAddEventListener.h
new file mode 100644
index 0000000000..f52a953cbe
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/AdapterAddEventListener.h
@@ -0,0 +1,55 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _ADAPTERADDEVENTLISTENER_H
+#define _ADAPTERADDEVENTLISTENER_H
+
+
+
+#include "Listener.h"
+#include <hbaapi.h>
+
+/// Callback routine type
+typedef void (*AdapterAddCallback) (
+ void *data,
+ HBA_WWN PortWWN,
+ HBA_UINT32 eventType);
+
+/**
+ * @memo Encapsulates the callback routine for event dispatch
+ *
+ * @doc This class encapsulates the event callback routine
+ * registered in the public HBA API. When dispatch
+ * is called, the stored callback routine will be called.
+ */
+class AdapterAddEventListener: public Listener {
+public:
+ AdapterAddEventListener(AdapterAddCallback myCallback, void *data);
+ virtual void dispatch(Event &event);
+private:
+ AdapterAddCallback callback;
+};
+
+#endif /* _ADAPTERADDEVENTLISTENER_H */
diff --git a/usr/src/lib/sun_fc/common/AdapterDeviceEvent.h b/usr/src/lib/sun_fc/common/AdapterDeviceEvent.h
new file mode 100644
index 0000000000..6c8eeeed5d
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/AdapterDeviceEvent.h
@@ -0,0 +1,60 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _ADAPTERDEVICEEVENT_H
+#define _ADAPTERDEVICEEVENT_H
+
+
+#include "Event.h"
+#include <hbaapi.h>
+
+
+/*
+ * @memo Represents an Adapter Port Event
+ *
+ * @doc When adapter port events occur on the HBA, an
+ * event of this type will be sent to registered
+ * listeners
+ */
+class AdapterDeviceEvent : public Event {
+public:
+ enum EVENT_TYPE {
+ UNKNOWN = HBA_EVENT_DEVICE_UNKNOWN,
+ OFFLINE = HBA_EVENT_DEVICE_OFFLINE,
+ ONLINE = HBA_EVENT_DEVICE_ONLINE
+ };
+ AdapterDeviceEvent(uint64_t myWwn, EVENT_TYPE myType, uint32_t myID) :
+ wwn(myWwn), type(myType), affectedID(myID) { }
+ uint64_t getPortWWN() { return (wwn); }
+ EVENT_TYPE getType() { return (type); }
+ uint32_t getAffectedPortID() { return (affectedID); }
+
+private:
+ uint64_t wwn;
+ uint32_t affectedID;
+ EVENT_TYPE type;
+};
+
+#endif /* _ADAPTERDEVICEEVENT_H */
diff --git a/usr/src/lib/sun_fc/common/AdapterDeviceEventBridge.h b/usr/src/lib/sun_fc/common/AdapterDeviceEventBridge.h
new file mode 100644
index 0000000000..3cd2ccc3e5
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/AdapterDeviceEventBridge.h
@@ -0,0 +1,48 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _ADAPTERDEVICEEVENTBRIDGE_H
+#define _ADAPTERDEVICEEVENTBRIDGE_H
+
+
+
+#include "AdapterDeviceEventListener.h"
+
+/*
+ * @memo Bridge interface for adapter port events
+ *
+ * @doc Used to abstract clients from the specific
+ * underlying details of event management for
+ * the given HBA/driver stack.
+ */
+class AdapterDeviceEventBridge {
+public:
+ virtual void addListener(AdapterDeviceEventListener *listener,
+ HBAPort *port) = 0;
+ virtual void removeListener(AdapterDeviceEventListener *listener) = 0;
+ virtual int32_t getMaxListener() = 0;
+};
+
+#endif /* _ADAPTERDEVICEEVENTBRIDGE_H */
diff --git a/usr/src/lib/sun_fc/common/AdapterDeviceEventListener.cc b/usr/src/lib/sun_fc/common/AdapterDeviceEventListener.cc
new file mode 100644
index 0000000000..70d1363ca2
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/AdapterDeviceEventListener.cc
@@ -0,0 +1,74 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "AdapterDeviceEventListener.h"
+#include "AdapterDeviceEvent.h"
+#include "Exceptions.h"
+#include "Trace.h"
+#include "sun_fc.h"
+
+/**
+ * @memo Create a new AdapterPortEvent listener
+ * @postcondition Listener ready to receive callbacks
+ * @exception BadArgumentException
+ * @param myCallback The listeners callback routine
+ * @param data Opaque data that will be passed to the
+ * callback routine when and event comes in.
+ *
+ */
+AdapterDeviceEventListener::AdapterDeviceEventListener(
+ HBAPort *myPort, AdapterDeviceCallback myCallback, void *data) :
+ port(myPort), Listener(data), callback(myCallback) {
+ Trace log("AdapterDeviceEventListener::AdapterDeviceEventListener");
+ if (callback == NULL) {
+ throw BadArgumentException();
+ }
+}
+
+/**
+ * @memo Send the event to this listener
+ * @param event The event to send to the listener
+ *
+ * @doc The callback registered in the constructor will
+ * be called.
+ */
+void AdapterDeviceEventListener::dispatch(Event &event) {
+ Trace log("AdapterDeviceEventListener::dispatch");
+ AdapterDeviceEvent *e = static_cast<AdapterDeviceEvent*> (&event);
+ if (e != NULL) {
+ HBA_WWN wwn;
+ uint64_t lwwn = htonll(e->getPortWWN());
+ // Filter out unwanted events
+ if (port->getPortWWN() == lwwn) {
+ memcpy(&wwn, &lwwn, sizeof (wwn));
+ callback(getData(), wwn, e->getType(), e->getAffectedPortID());
+ } // Else ignore
+ } else {
+ log.internalError("Unexpected event type.");
+ }
+}
+
diff --git a/usr/src/lib/sun_fc/common/AdapterDeviceEventListener.h b/usr/src/lib/sun_fc/common/AdapterDeviceEventListener.h
new file mode 100644
index 0000000000..836d0369bb
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/AdapterDeviceEventListener.h
@@ -0,0 +1,59 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+#ifndef _ADAPTERDEVICEEVENTLISTENER_H
+#define _ADAPTERDEVICEEVENTLISTENER_H
+
+
+
+#include "Listener.h"
+#include "Handle.h"
+#include "HBAPort.h"
+#include <hbaapi.h>
+
+typedef void (*AdapterDeviceCallback)(
+ void *data,
+ HBA_WWN PortWWN,
+ HBA_UINT32 eventType,
+ HBA_UINT32 fabricPortID);
+
+/*
+ * @memo Encapsulates the callback routine for event dispatch
+ *
+ * @doc This class encapsulates the event callback routine
+ * registered in the public HBA API. When dispatch
+ * is called, the stored callback routine will be called.
+ */
+class AdapterDeviceEventListener: public Listener {
+public:
+ AdapterDeviceEventListener(HBAPort *port,
+ AdapterDeviceCallback myCallback,
+ void *data);
+ virtual void dispatch(Event &event);
+private:
+ AdapterDeviceCallback callback;
+ HBAPort *port;
+};
+
+#endif /* _ADAPTERDEVICEEVENTLISTENER_H */
diff --git a/usr/src/lib/sun_fc/common/AdapterEvent.h b/usr/src/lib/sun_fc/common/AdapterEvent.h
new file mode 100644
index 0000000000..d2f6eb82d9
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/AdapterEvent.h
@@ -0,0 +1,60 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _ADAPTEREVENT_H
+#define _ADAPTEREVENT_H
+
+
+
+#include "Event.h"
+
+#include <hbaapi.h>
+
+/**
+ * @memo Represents an Adapter Event
+ *
+ * @doc When adapter events occur on the HBA, an
+ * event of this type will be sent to registered
+ * listeners
+ */
+class AdapterEvent : public Event {
+public:
+ enum EVENT_TYPE {
+ UNKNOWN = HBA_EVENT_ADAPTER_UNKNOWN,
+ ADD = HBA_EVENT_ADAPTER_ADD,
+ REMOVE = HBA_EVENT_ADAPTER_REMOVE,
+ CHANGE = HBA_EVENT_ADAPTER_CHANGE
+ };
+ AdapterEvent(uint64_t myWwn, EVENT_TYPE myType) :
+ wwn(myWwn), type(myType) { }
+ uint64_t getPortWWN() { return (wwn); }
+ EVENT_TYPE getType() { return (type); }
+
+private:
+ uint64_t wwn;
+ EVENT_TYPE type;
+};
+
+#endif /* _ADAPTEREVENT_H */
diff --git a/usr/src/lib/sun_fc/common/AdapterEventBridge.h b/usr/src/lib/sun_fc/common/AdapterEventBridge.h
new file mode 100644
index 0000000000..dee8676b15
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/AdapterEventBridge.h
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _ADAPTEREVENTBRIDGE_H
+#define _ADAPTEREVENTBRIDGE_H
+
+
+
+#include "AdapterEventListener.h"
+
+/**
+ * @memo Bridge interface for adapter events
+ *
+ * @doc Used to abstract clients from the specific
+ * underlying details of event management for
+ * the given HBA/driver stack.
+ */
+class AdapterEventBridge{
+public:
+ virtual void addListener(AdapterEventListener *listener, HBA *hba) = 0;
+ virtual void removeListener(AdapterEventListener *listener) = 0;
+ virtual int32_t getMaxListener() = 0;
+};
+
+#endif /* _ADAPTEREVENTBRIDGE_H */
diff --git a/usr/src/lib/sun_fc/common/AdapterEventListener.cc b/usr/src/lib/sun_fc/common/AdapterEventListener.cc
new file mode 100644
index 0000000000..98448e34de
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/AdapterEventListener.cc
@@ -0,0 +1,74 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "AdapterEventListener.h"
+#include "AdapterEvent.h"
+#include "Exceptions.h"
+#include "Trace.h"
+#include "sun_fc.h"
+
+/**
+ * @memo Create a new AdapterEvent listener
+ * @postcondition Listener ready to receive callbacks
+ * @exception BadArgumentException
+ * @param myCallback The listeners callback routine
+ * @param data Opaque data that will be passed to the
+ * callback routine when and event comes in.
+ *
+ */
+AdapterEventListener::AdapterEventListener(HBA *myHBA,
+ AdapterCallback myCallback, void *data) :
+ hba(myHBA), Listener(data), callback(myCallback) {
+ Trace log("AdapterEventListener::AdapterEventListener");
+ if (callback == NULL) {
+ throw BadArgumentException();
+ }
+}
+
+/**
+ * @memo Send the event to this listener
+ * @param event The event to send to the listener
+ *
+ * @doc The callback registered in the constructor will
+ * be called.
+ */
+void AdapterEventListener::dispatch(Event &event) {
+ Trace log("AdapterEventListener::dispatch");
+ AdapterEvent *e = static_cast<AdapterEvent*> (&event);
+ if (e != NULL) {
+ HBA_WWN wwn;
+ uint64_t lwwn = e->getPortWWN();
+ // Filter out unwanted events.
+ if (hba->containsWWN(lwwn)) {
+ lwwn = htonll(lwwn);
+ memcpy(&wwn, &lwwn, sizeof (wwn));
+ callback(getData(), wwn, e->getType());
+ } // Else, ignore it
+ } else {
+ log.internalError("Unexpected event type.");
+ }
+}
diff --git a/usr/src/lib/sun_fc/common/AdapterEventListener.h b/usr/src/lib/sun_fc/common/AdapterEventListener.h
new file mode 100644
index 0000000000..75b4fcacd0
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/AdapterEventListener.h
@@ -0,0 +1,58 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _ADAPTEREVENTLISTENER_H
+#define _ADAPTEREVENTLISTENER_H
+
+
+
+#include "Listener.h"
+#include "Handle.h"
+#include "HBA.h"
+#include <hbaapi.h>
+
+/// Callback type
+typedef void (*AdapterCallback)(
+ void *data,
+ HBA_WWN PortWWN,
+ HBA_UINT32 eventType);
+
+/**
+ * @memo Encapsulates the callback routine for event dispatch
+ *
+ * @doc This class encapsulates the event callback routine
+ * registered in the public HBA API. When dispatch
+ * is called, the stored callback routine will be called.
+ */
+class AdapterEventListener: public Listener {
+public:
+ AdapterEventListener(HBA *hba, AdapterCallback myCallback, void *data);
+ virtual void dispatch(Event &event);
+private:
+ AdapterCallback callback;
+ HBA *hba;
+};
+
+#endif /* _ADAPTEREVENTLISTENER_H */
diff --git a/usr/src/lib/sun_fc/common/AdapterPortEvent.h b/usr/src/lib/sun_fc/common/AdapterPortEvent.h
new file mode 100644
index 0000000000..8697a9bc49
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/AdapterPortEvent.h
@@ -0,0 +1,63 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _ADAPTERPORTEVENT_H
+#define _ADAPTERPORTEVENT_H
+
+
+
+#include "Event.h"
+#include <hbaapi.h>
+
+
+/**
+ * @memo Represents an Adapter Port Event
+ *
+ * @doc When adapter port events occur on the HBA, an
+ * event of this type will be sent to registered
+ * listeners
+ */
+class AdapterPortEvent : public Event {
+public:
+ enum EVENT_TYPE {
+ UNKNOWN = HBA_EVENT_PORT_UNKNOWN,
+ OFFLINE = HBA_EVENT_PORT_OFFLINE,
+ ONLINE = HBA_EVENT_PORT_ONLINE,
+ NEW_TARGETS = HBA_EVENT_PORT_NEW_TARGETS,
+ FABRIC = HBA_EVENT_PORT_FABRIC
+ };
+ AdapterPortEvent(uint64_t myWwn, EVENT_TYPE myType, uint32_t myID) :
+ wwn(myWwn), type(myType), affectedID(myID) { }
+ uint64_t getPortWWN() { return (wwn); }
+ EVENT_TYPE getType() { return (type); }
+ uint32_t getAffectedPortID() { return (affectedID); }
+
+private:
+ uint64_t wwn;
+ uint32_t affectedID;
+ EVENT_TYPE type;
+};
+
+#endif /* _ADAPTERPORTEVENT_H */
diff --git a/usr/src/lib/sun_fc/common/AdapterPortEventBridge.h b/usr/src/lib/sun_fc/common/AdapterPortEventBridge.h
new file mode 100644
index 0000000000..c9f721d314
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/AdapterPortEventBridge.h
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _ADAPTERPORTEVENTBRIDGE_H
+#define _ADAPTERPORTEVENTBRIDGE_H
+
+
+#include "AdapterPortEventListener.h"
+
+/**
+ * @memo Bridge interface for adapter port events
+ *
+ * @doc Used to abstract clients from the specific
+ * underlying details of event management for
+ * the given HBA/driver stack.
+ */
+class AdapterPortEventBridge{
+public:
+ virtual void addListener(AdapterPortEventListener *listener,
+ HBAPort *port) = 0;
+ virtual void removeListener(AdapterPortEventListener *listener) = 0;
+ virtual int32_t getMaxListener() = 0;
+};
+
+#endif /* _ADAPTERPORTEVENTBRIDGE_H */
diff --git a/usr/src/lib/sun_fc/common/AdapterPortEventListener.cc b/usr/src/lib/sun_fc/common/AdapterPortEventListener.cc
new file mode 100644
index 0000000000..8dc2bfd0c4
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/AdapterPortEventListener.cc
@@ -0,0 +1,74 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "AdapterPortEventListener.h"
+#include "AdapterPortEvent.h"
+#include "Exceptions.h"
+#include "Trace.h"
+#include "sun_fc.h"
+
+/**
+ * @memo Create a new AdapterPortEvent listener
+ * @postcondition Listener ready to receive callbacks
+ * @exception BadArgumentException
+ * @param myCallback The listeners callback routine
+ * @param data Opaque data that will be passed to the
+ * callback routine when and event comes in.
+ *
+ */
+AdapterPortEventListener::AdapterPortEventListener(
+ HBAPort *myPort, AdapterPortCallback myCallback, void *data) :
+ port(myPort), Listener(data), callback(myCallback) {
+ Trace log("AdapterPortEventListener::AdapterPortEventListener");
+ if (callback == NULL) {
+ throw BadArgumentException();
+ }
+}
+
+/**
+ * @memo Send the event to this listener
+ * @param event The event to send to the listener
+ *
+ * @doc The callback registered in the constructor will
+ * be called.
+ */
+void AdapterPortEventListener::dispatch(Event &event) {
+ Trace log("AdapterPortEventListener::dispatch");
+ AdapterPortEvent *e = static_cast<AdapterPortEvent*> (&event);
+ if (e != NULL) {
+ HBA_WWN wwn;
+ uint64_t lwwn = e->getPortWWN();
+ // Filter out unwanted events
+ if (port->getPortWWN() == lwwn) {
+ lwwn = htonll(lwwn);
+ memcpy(&wwn, &lwwn, sizeof (wwn));
+ callback(getData(), wwn, e->getType(), e->getAffectedPortID());
+ } // Else ignore
+ } else {
+ log.internalError("Unexpected event type.");
+ }
+}
diff --git a/usr/src/lib/sun_fc/common/AdapterPortEventListener.h b/usr/src/lib/sun_fc/common/AdapterPortEventListener.h
new file mode 100644
index 0000000000..f05491a8c0
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/AdapterPortEventListener.h
@@ -0,0 +1,60 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _ADAPTERPORTEVENTLISTENER_H
+#define _ADAPTERPORTEVENTLISTENER_H
+
+
+
+#include "Listener.h"
+#include "Handle.h"
+#include "HBAPort.h"
+#include <hbaapi.h>
+
+/// Callback type
+typedef void (*AdapterPortCallback)(
+ void *data,
+ HBA_WWN PortWWN,
+ HBA_UINT32 eventType,
+ HBA_UINT32 fabricPortID);
+
+/**
+ * @memo Encapsulates the callback routine for event dispatch
+ *
+ * @doc This class encapsulates the event callback routine
+ * registered in the public HBA API. When dispatch
+ * is called, the stored callback routine will be called.
+ */
+class AdapterPortEventListener: public Listener {
+public:
+ AdapterPortEventListener(HBAPort *port, AdapterPortCallback myCallback,
+ void *data);
+ virtual void dispatch(Event &event);
+private:
+ AdapterPortCallback callback;
+ HBAPort *port;
+};
+
+#endif /* _ADAPTERPORTEVENTLISTENER_H */
diff --git a/usr/src/lib/sun_fc/common/AdapterPortStatEvent.h b/usr/src/lib/sun_fc/common/AdapterPortStatEvent.h
new file mode 100644
index 0000000000..07bad3f585
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/AdapterPortStatEvent.h
@@ -0,0 +1,58 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _ADAPTERPORTEVENT_H
+#define _ADAPTERPORTEVENT_H
+
+
+
+#include "Event.h"
+#include <hbaapi.h>
+
+
+/**
+ * @memo Represents an Adapter Port Statistic Event
+ *
+ * @doc When adapter port statistic events occur on the HBA, an
+ * event of this type will be sent to registered
+ * listeners
+ */
+class AdapterPortStatEvent : public Event {
+public:
+ enum EVENT_TYPE {
+ THRESHOLD = HBA_EVENT_PORT_STAT_THRESHOLD,
+ GROWTH = HBA_EVENT_PORT_STAT_GROWTH
+ };
+ AdapterPortStatEvent(uint64_t myWwn, EVENT_TYPE myType) :
+ wwn(myWwn), type(myType) { }
+ uint64_t getPortWWN() { return (wwn); }
+ EVENT_TYPE getType() { return (type); }
+
+private:
+ uint64_t wwn;
+ EVENT_TYPE type;
+};
+
+#endif /* _ADAPTERPORTEVENT_H */
diff --git a/usr/src/lib/sun_fc/common/AdapterPortStatEventBridge.h b/usr/src/lib/sun_fc/common/AdapterPortStatEventBridge.h
new file mode 100644
index 0000000000..6a634cffca
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/AdapterPortStatEventBridge.h
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _ADAPTERPORTSTATEVENTBRIDGE_H
+#define _ADAPTERPORTSTATEVENTBRIDGE_H
+
+
+
+#include "AdapterPortStatEventListener.h"
+
+/*
+ * @memo Bridge interface for adapter port statistic events
+ *
+ * @doc Used to abstract clients from the specific
+ * underlying details of event management for
+ * the given HBA/driver stack.
+ */
+class AdapterPortStatEventBridge {
+public:
+ virtual void addListener(AdapterPortStatEventListener *listener,
+ HBAPort *port) = 0;
+ virtual void removeListener(AdapterPortStatEventListener *listener) = 0;
+};
+
+#endif /* _ADAPTERPORTSTATEVENTBRIDGE_H */
diff --git a/usr/src/lib/sun_fc/common/AdapterPortStatEventListener.cc b/usr/src/lib/sun_fc/common/AdapterPortStatEventListener.cc
new file mode 100644
index 0000000000..dcb9d3637a
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/AdapterPortStatEventListener.cc
@@ -0,0 +1,70 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "AdapterPortStatEventListener.h"
+#include "AdapterPortStatEvent.h"
+#include "Exceptions.h"
+#include "Trace.h"
+#include "sun_fc.h"
+
+/**
+ * @memo Create a new AdapterPortStatEvent listener
+ * @postcondition Listener ready to receive callbacks
+ * @exception BadArgumentException
+ * @param myCallback The listeners callback routine
+ * @param data Opaque data that will be passed to the
+ * callback routine when and event comes in.
+ *
+ */
+AdapterPortStatEventListener::AdapterPortStatEventListener(
+ AdapterPortStatCallback myCallback, void *data) :
+ Listener(data), callback(myCallback) {
+ Trace log("AdapterPortStatEventListener::AdapterPortStatEventListener");
+ if (callback == NULL) {
+ throw BadArgumentException();
+ }
+}
+
+/**
+ * @memo Send the event to this listener
+ * @param event The event to send to the listener
+ *
+ * @doc The callback registered in the constructor will
+ * be called.
+ */
+void AdapterPortStatEventListener::dispatch(Event &event) {
+ Trace log("AdapterPortStatEventListener::dispatch");
+ AdapterPortStatEvent *e = static_cast<AdapterPortStatEvent*> (&event);
+ if (e != NULL) {
+ HBA_WWN wwn;
+ uint64_t lwwn = htonll(e->getPortWWN());
+ memcpy(&wwn, &lwwn, sizeof (wwn));
+ callback(getData(), wwn, e->getType());
+ } else {
+ log.internalError("Unexpected event type.");
+ }
+}
diff --git a/usr/src/lib/sun_fc/common/AdapterPortStatEventListener.h b/usr/src/lib/sun_fc/common/AdapterPortStatEventListener.h
new file mode 100644
index 0000000000..e6a6884593
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/AdapterPortStatEventListener.h
@@ -0,0 +1,57 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _ADAPTERPORTSTATEVENTLISTENER_H
+#define _ADAPTERPORTSTATEVENTLISTENER_H
+
+
+
+#include "Listener.h"
+#include "Handle.h"
+#include <hbaapi.h>
+
+// Callback type
+typedef void (*AdapterPortStatCallback)(
+ void *data,
+ HBA_WWN PortWWN,
+ HBA_UINT32 eventType);
+
+/*
+ * @memo Encapsulates the callback routine for event dispatch
+ *
+ * @doc This class encapsulates the event callback routine
+ * registered in the public HBA API. When dispatch
+ * is called, the stored callback routine will be called.
+ */
+class AdapterPortStatEventListener: public Listener {
+public:
+ AdapterPortStatEventListener(AdapterPortStatCallback myCallback,
+ void *data);
+ virtual void dispatch(Event &event);
+private:
+ AdapterPortStatCallback callback;
+};
+
+#endif /* _ADAPTERPORTSTATEVENTLISTENER_H */
diff --git a/usr/src/lib/sun_fc/common/Event.h b/usr/src/lib/sun_fc/common/Event.h
new file mode 100644
index 0000000000..557f596446
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Event.h
@@ -0,0 +1,39 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _EVENT_H
+#define _EVENT_H
+
+
+
+
+/**
+ * @memo Super-class for all types of events that are
+ * sent to clients of the API.
+ *
+ */
+class Event { };
+
+#endif /* _EVENT_H */
diff --git a/usr/src/lib/sun_fc/common/EventBridgeFactory.cc b/usr/src/lib/sun_fc/common/EventBridgeFactory.cc
new file mode 100644
index 0000000000..dc6e299d05
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/EventBridgeFactory.cc
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "EventBridgeFactory.h"
+#include "Exceptions.h"
+
+#include "FCSyseventBridge.h"
+
+AdapterAddEventBridge* EventBridgeFactory::fetchAdapterAddEventBridge() {
+ return (FCSyseventBridge::getInstance());
+}
+AdapterEventBridge* EventBridgeFactory::fetchAdapterEventBridge() {
+ return (FCSyseventBridge::getInstance());
+}
+AdapterPortEventBridge* EventBridgeFactory::fetchAdapterPortEventBridge() {
+ return (FCSyseventBridge::getInstance());
+}
+AdapterDeviceEventBridge* EventBridgeFactory::fetchAdapterDeviceEventBridge() {
+ return (FCSyseventBridge::getInstance());
+}
+AdapterPortStatEventBridge*
+EventBridgeFactory::fetchAdapterPortStatEventBridge() {
+ throw NotSupportedException();
+}
+TargetEventBridge* EventBridgeFactory::fetchTargetEventBridge() {
+ return (FCSyseventBridge::getInstance());
+}
+LinkEventBridge* EventBridgeFactory::fetchLinkEventBridge() {
+ throw NotSupportedException();
+}
diff --git a/usr/src/lib/sun_fc/common/EventBridgeFactory.h b/usr/src/lib/sun_fc/common/EventBridgeFactory.h
new file mode 100644
index 0000000000..ac59d135b0
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/EventBridgeFactory.h
@@ -0,0 +1,63 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _EVENTBRIDGEFACTORY_H
+#define _EVENTBRIDGEFACTORY_H
+
+
+
+#include "AdapterAddEventBridge.h"
+#include "AdapterEventBridge.h"
+#include "AdapterPortEventBridge.h"
+#include "AdapterDeviceEventBridge.h"
+#include "AdapterPortStatEventBridge.h"
+#include "LinkEventBridge.h"
+#include "TargetEventBridge.h"
+
+/*
+ * @memo Static routines to build the proper event bridge
+ * for the current version of the library.
+ *
+ * @doc To keep client code isolated from the underlying
+ * event infrastructure (eg: sysevent, IOCTLs, etc.)
+ * Bridge classes are used for registration. This
+ * factory interface allows client code to be compiled
+ * once without knowledge of the underlying details.
+ * The concrete implementation of this class will
+ * define which concrete bridge instance(s)
+ * are returned.
+ */
+class EventBridgeFactory {
+public:
+ static AdapterAddEventBridge* fetchAdapterAddEventBridge();
+ static AdapterEventBridge* fetchAdapterEventBridge();
+ static AdapterPortEventBridge* fetchAdapterPortEventBridge();
+ static AdapterDeviceEventBridge* fetchAdapterDeviceEventBridge();
+ static AdapterPortStatEventBridge* fetchAdapterPortStatEventBridge();
+ static TargetEventBridge* fetchTargetEventBridge();
+ static LinkEventBridge* fetchLinkEventBridge();
+};
+
+#endif /* _EVENTBRIDGEFACTORY_H */
diff --git a/usr/src/lib/sun_fc/common/Exceptions.h b/usr/src/lib/sun_fc/common/Exceptions.h
new file mode 100644
index 0000000000..61ecd1bbe1
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Exceptions.h
@@ -0,0 +1,231 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _EXCEPTIONS_H
+#define _EXCEPTIONS_H
+
+
+
+#include <hbaapi.h>
+#include "Handle.h"
+#include "HBAPort.h"
+#include "Trace.h"
+#include <string>
+
+/**
+ * @memo Superclass for all Exception we'll throw.
+ *
+ * @doc To ensure
+ * no uncaught exceptions squeeze through, all exceptions
+ * will map to some HBA_STATUS error code so we can easily
+ * handle them in catch blocks in our external API.
+ */
+class HBAException {
+public:
+ HBAException(HBA_STATUS err) : errorCode(err) {
+ Trace log("HBAException");
+ log.debug("Error code: %d", err);
+ log.stackTrace();
+ }
+ HBA_STATUS getErrorCode() { return errorCode; }
+private:
+ HBA_STATUS errorCode;
+};
+
+
+/**
+ * @memo Represents HBA API "Not Supported" error
+ */
+class NotSupportedException : public HBAException {
+public:
+ NotSupportedException() : HBAException(HBA_STATUS_ERROR_NOT_SUPPORTED) { }
+};
+
+/**
+ * @memo Represents HBA API "Invalid Handle" error
+ */
+class InvalidHandleException : public HBAException {
+public:
+ InvalidHandleException() : HBAException(HBA_STATUS_ERROR_INVALID_HANDLE) { }
+};
+
+/**
+ * @memo Represents HBA API "Bad Argument" error
+
+ */
+class BadArgumentException : public HBAException {
+public:
+ BadArgumentException() : HBAException(HBA_STATUS_ERROR_ARG) { }
+};
+
+/**
+ * @memo Represents HBA API "Illegal WWN" error
+ */
+class IllegalWWNException : public HBAException {
+public:
+ IllegalWWNException() : HBAException(HBA_STATUS_ERROR_ILLEGAL_WWN) { }
+};
+
+/**
+ * @memo Represents HBA API "Illegal Index" error
+ */
+class IllegalIndexException : public HBAException {
+public:
+ IllegalIndexException() : HBAException(HBA_STATUS_ERROR_ILLEGAL_INDEX) { }
+};
+
+/**
+ * @memo Represents HBA API "More Data" error
+ */
+class MoreDataException : public HBAException {
+public:
+ MoreDataException() : HBAException(HBA_STATUS_ERROR_MORE_DATA) { }
+};
+
+/**
+ * @memo Represents HBA API "Stale Data" error
+ */
+class StaleDataException : public HBAException {
+public:
+ StaleDataException() : HBAException(HBA_STATUS_ERROR_STALE_DATA) { }
+};
+
+/**
+ * @memo Represents HBA API "SCSI Check Condition" error
+ */
+class CheckConditionException : public HBAException {
+public:
+ CheckConditionException() : HBAException(HBA_STATUS_SCSI_CHECK_CONDITION) { }
+};
+
+/**
+ * @memo Represents HBA API "Busy" error
+ */
+class BusyException : public HBAException {
+public:
+ BusyException() : HBAException(HBA_STATUS_ERROR_BUSY) { }
+};
+
+/**
+ * @memo Represents HBA API "Try Again" error
+ */
+class TryAgainException : public HBAException {
+public:
+ TryAgainException() : HBAException(HBA_STATUS_ERROR_TRY_AGAIN) { }
+};
+
+/**
+ * @memo Represents HBA API "Unavailable" error
+ */
+class UnavailableException : public HBAException {
+public:
+ UnavailableException() : HBAException(HBA_STATUS_ERROR_UNAVAILABLE) { }
+};
+
+/**
+ * @memo Represents HBA API "ELS Rejection" error
+ */
+class ELSRejectException : public HBAException {
+public:
+ ELSRejectException() : HBAException(HBA_STATUS_ERROR_ELS_REJECT) { }
+};
+
+/**
+ * @memo Represents HBA API "Invalid Logical Unit Number" error
+ */
+class InvalidLUNException : public HBAException {
+public:
+ InvalidLUNException() : HBAException(HBA_STATUS_ERROR_INVALID_LUN) { }
+};
+
+/**
+ * @memo Represents HBA API "Incompatible" error
+ */
+class IncompatibleException : public HBAException {
+public:
+ IncompatibleException() : HBAException(HBA_STATUS_ERROR_INCOMPATIBLE) { }
+};
+
+/**
+ * @memo Represents HBA API "Ambiguous WWN" error
+ */
+class AmbiguousWWNException : public HBAException {
+public:
+ AmbiguousWWNException() : HBAException(HBA_STATUS_ERROR_AMBIGUOUS_WWN) { }
+};
+
+/**
+ * @memo Represents HBA API "Not a Target" error
+ */
+class NotATargetException : public HBAException {
+public:
+ NotATargetException() : HBAException(HBA_STATUS_ERROR_NOT_A_TARGET) { }
+};
+
+/**
+ * @memo Represents HBA API "Unsupported FC4 type" error
+ */
+class UnsupportedFC4Exception : public HBAException {
+public:
+ UnsupportedFC4Exception() : HBAException(HBA_STATUS_ERROR_UNSUPPORTED_FC4) { }
+};
+
+/**
+ * @memo Represents HBA API "Incapable" error
+ */
+class IncapableException : public HBAException {
+public:
+ IncapableException() : HBAException(HBA_STATUS_ERROR_INCAPABLE) { }
+};
+
+/**
+ * @memo Encapsulate I/O error scenarios.
+ *
+ * @doc If logging is enabled, this will
+ * automatically log the failure with as much detail as possible.
+ */
+class IOError : public HBAException {
+public:
+ IOError(std::string message);
+ IOError(Handle *handle);
+ IOError(HBAPort *port);
+ IOError(HBAPort *port, uint64_t target);
+ IOError(HBAPort *port, uint64_t target, uint64_t lun);
+};
+
+/**
+ * @memo Generic error of unknown type
+ *
+ * @doc
+ * Grab bag for something catastrophic occuring in the internal
+ * logic of the VSL. Hopefully, this should never ever happen.
+ */
+class InternalError : public HBAException {
+public:
+ InternalError();
+ InternalError(std::string message);
+};
+
+#endif /* _EXCEPTIONS_H */
diff --git a/usr/src/lib/sun_fc/common/FCHBA.cc b/usr/src/lib/sun_fc/common/FCHBA.cc
new file mode 100644
index 0000000000..aba53f0b88
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/FCHBA.cc
@@ -0,0 +1,376 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#include <unistd.h>
+
+#include <FCHBA.h>
+#include <Exceptions.h>
+#include <Trace.h>
+#include <iostream>
+#include <iomanip>
+#include <cerrno>
+#include <cstring>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stropts.h>
+#include <sys/fibre-channel/fcio.h>
+#include <sys/fibre-channel/ulp/fcsm.h>
+#include <FCHBAPort.h>
+#include <HBAList.h>
+
+using namespace std;
+const string FCHBA::FCSM_DRIVER_PATH = "/devices/pseudo/fcsm@0:fcsm";
+const string FCHBA::FCSM_DRIVER_PKG = "SUNWfcsm";
+const int FCHBA::MAX_FCIO_MSG_LEN = 256;
+
+FCHBA::FCHBA(string path) : HBA() {
+ Trace log("FCHBA::FCHBA");
+ log.debug("Constructing new HBA (%s)", path.c_str());
+
+ // Add first port
+ addPort(new FCHBAPort(path));
+
+ name = "INTERNAL-FAILURE"; // Just in case things go wrong
+ try {
+ HBA_ADAPTERATTRIBUTES attrs = getHBAAttributes();
+ name = attrs.Manufacturer;
+ name += "-";
+ name += attrs.Model;
+
+ // Grab any other ports on this adapter
+ for (int i = 1; i < attrs.NumberOfPorts; i++) {
+ fcio_t fcio;
+ int fd;
+ char nextPath[MAXPATHLEN];
+
+ log.debug("Fetching other port %d", i);
+
+ // construct fcio struct
+ memset(&fcio, 0, sizeof (fcio_t));
+ memset(nextPath, 0, sizeof (nextPath));
+ fcio.fcio_cmd = FCIO_GET_OTHER_ADAPTER_PORTS;
+ fcio.fcio_xfer = FCIO_XFER_RW;
+
+ fcio.fcio_olen = MAXPATHLEN;
+ fcio.fcio_obuf = (char *)nextPath;
+ fcio.fcio_ilen = sizeof (i);
+ fcio.fcio_ibuf = (char *)&i;
+
+ // open the fcsm node so we can send the ioctl to
+ errno = 0;
+ HBAPort *port = getPortByIndex(0);
+ if ((fd = open(port->getPath().c_str(), O_NDELAY | O_RDONLY)) ==
+ -1) {
+ log.debug("Unable to open %d opened (%s)", i,
+ port->getPath().c_str());
+ if (errno == EBUSY) {
+ throw BusyException();
+ } else if (errno == EAGAIN) {
+ throw TryAgainException();
+ } else if (errno == ENOTSUP) {
+ throw NotSupportedException();
+ } else if (errno == ENOENT) {
+ throw UnavailableException();
+ } else {
+ throw IOError("Unable to open FCSM driver");
+ }
+ }
+ log.debug("Other port %d opened", i);
+
+ errno = 0;
+ if (ioctl(fd, FCIO_CMD, &fcio) != 0) {
+ // Interpret the fcio error code
+ char fcioErrorString[MAX_FCIO_MSG_LEN] = "";
+
+ log.genericIOError(
+ "ADAPTER_LIST failed: "
+ "Errno: \"%s\"",
+ strerror(errno));
+ close(fd);
+ if (errno == EBUSY) {
+ throw BusyException();
+ } else if (errno == EAGAIN) {
+ throw TryAgainException();
+ } else if (errno == ENOTSUP) {
+ throw NotSupportedException();
+ } else if (errno == ENOENT) {
+ throw UnavailableException();
+ } else {
+ throw IOError("Unable to build HBA list");
+ }
+ }
+ close(fd);
+ log.debug("About to add port %d (%s)", i, nextPath);
+ addPort(new FCHBAPort(nextPath));
+ }
+ } catch (HBAException &e) {
+ log.internalError(
+ "Unable to construct HBA.");
+ throw e;
+ }
+}
+
+std::string FCHBA::getName() {
+ Trace log("FCHBA::getName");
+ return (name);
+}
+
+HBA_ADAPTERATTRIBUTES FCHBA::getHBAAttributes() {
+ Trace log("FCHBA::getHBAAttributes");
+ int fd;
+
+ errno = 0;
+ HBAPort *port = getPortByIndex(0);
+ if ((fd = open(port->getPath().c_str(), O_NDELAY | O_RDONLY)) == -1) {
+ // Why did we fail?
+ if (errno == EBUSY) {
+ throw BusyException();
+ } else if (errno == EAGAIN) {
+ throw TryAgainException();
+ } else if (errno == ENOTSUP) {
+ throw NotSupportedException();
+ } else {
+ throw IOError(port);
+ }
+ }
+
+ HBA_ADAPTERATTRIBUTES attributes;
+ fcio_t fcio;
+ fc_hba_adapter_attributes_t attrs;
+
+ memset(&fcio, 0, sizeof (fcio));
+
+ fcio.fcio_cmd = FCIO_GET_ADAPTER_ATTRIBUTES;
+ fcio.fcio_olen = sizeof (attrs);
+ fcio.fcio_xfer = FCIO_XFER_READ;
+ fcio.fcio_obuf = (caddr_t)&attrs;
+
+
+ errno = 0;
+ if (ioctl(fd, FCIO_CMD, &fcio) != 0) {
+ close(fd);
+ if (errno == EBUSY) {
+ throw BusyException();
+ } else if (errno == EAGAIN) {
+ throw TryAgainException();
+ } else if (errno == ENOTSUP) {
+ throw NotSupportedException();
+ } else {
+ throw IOError("Unable to fetch adapter attributes");
+ }
+ }
+ close(fd);
+
+ /* Now copy over the payload */
+ attributes.NumberOfPorts = attrs.NumberOfPorts;
+ attributes.VendorSpecificID = attrs.VendorSpecificID;
+ memcpy(attributes.Manufacturer, attrs.Manufacturer, 64);
+ memcpy(attributes.SerialNumber, attrs.SerialNumber, 64);
+ memcpy(attributes.Model, attrs.Model, 256);
+ memcpy(attributes.ModelDescription, attrs.ModelDescription, 256);
+ memcpy(attributes.NodeSymbolicName, attrs.NodeSymbolicName, 256);
+ memcpy(attributes.HardwareVersion, attrs.HardwareVersion, 256);
+ memcpy(attributes.DriverVersion, attrs.DriverVersion, 256);
+ memcpy(attributes.OptionROMVersion, attrs.OptionROMVersion, 256);
+ memcpy(attributes.FirmwareVersion, attrs.FirmwareVersion, 256);
+ memcpy(attributes.DriverName, attrs.DriverName, 256);
+ memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8);
+
+ return (attributes);
+}
+
+HBA_ADAPTERATTRIBUTES FCHBA::npivGetHBAAttributes() {
+ Trace log("FCHBA::npivGetHBAAttributes");
+ int fd;
+
+ errno = 0;
+ HBAPort *port = getPortByIndex(0);
+ if ((fd = open(port->getPath().c_str(), O_NDELAY | O_RDONLY)) == -1) {
+ // Why did we fail?
+ if (errno == EBUSY) {
+ throw BusyException();
+ } else if (errno == EAGAIN) {
+ throw TryAgainException();
+ } else if (errno == ENOTSUP) {
+ throw NotSupportedException();
+ } else {
+ throw IOError(port);
+ }
+ }
+
+ HBA_ADAPTERATTRIBUTES attributes;
+ fcio_t fcio;
+ fc_hba_adapter_attributes_t attrs;
+
+ memset(&fcio, 0, sizeof (fcio));
+ fcio.fcio_cmd = FCIO_NPIV_GET_ADAPTER_ATTRIBUTES;
+ fcio.fcio_olen = sizeof (attrs);
+ fcio.fcio_xfer = FCIO_XFER_READ;
+ fcio.fcio_obuf = (caddr_t)&attrs;
+ errno = 0;
+
+ if (ioctl(fd, FCIO_CMD, &fcio) != 0) {
+ close(fd);
+ if (errno == EBUSY) {
+ throw BusyException();
+ } else if (errno == EAGAIN) {
+ throw TryAgainException();
+ } else if (errno == ENOTSUP) {
+ throw NotSupportedException();
+ } else {
+ throw IOError("Unable to fetch adapter attributes");
+ }
+ }
+ close(fd);
+
+ /* Now copy over the payload */
+ attributes.NumberOfPorts = attrs.NumberOfPorts;
+ attributes.VendorSpecificID = attrs.VendorSpecificID;
+ memcpy(attributes.Manufacturer, attrs.Manufacturer, 64);
+ memcpy(attributes.SerialNumber, attrs.SerialNumber, 64);
+ memcpy(attributes.Model, attrs.Model, 256);
+ memcpy(attributes.ModelDescription, attrs.ModelDescription, 256);
+ memcpy(attributes.NodeSymbolicName, attrs.NodeSymbolicName, 256);
+ memcpy(attributes.HardwareVersion, attrs.HardwareVersion, 256);
+ memcpy(attributes.DriverVersion, attrs.DriverVersion, 256);
+ memcpy(attributes.OptionROMVersion, attrs.OptionROMVersion, 256);
+ memcpy(attributes.FirmwareVersion, attrs.FirmwareVersion, 256);
+ memcpy(attributes.DriverName, attrs.DriverName, 256);
+ memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8);
+
+ return (attributes);
+}
+
+void FCHBA::loadAdapters(vector<HBA*> &list) {
+ Trace log("FCHBA::loadAdapters");
+ fcio_t fcio;
+ fc_hba_list_t *pathList;
+ int fd;
+ int size = 64; // default first attempt
+ bool retry = false;
+ struct stat sb;
+ int bufSize;
+
+ /* Before we do anything, let's see if FCSM is on the system */
+ errno = 0;
+ if (stat(FCSM_DRIVER_PATH.c_str(), &sb) != 0) {
+ if (errno == ENOENT) {
+ log.genericIOError(
+ "The %s driver is not present. Unable to issue "
+ "CT commands. Please install the %s package.",
+ FCSM_DRIVER_PATH.c_str(), FCSM_DRIVER_PKG.c_str());
+ throw NotSupportedException();
+ } else {
+ log.genericIOError(
+ "Can not stat the %s driver for reason \"%s\" "
+ "Unable to issue CT commands.",
+ FCSM_DRIVER_PATH.c_str(), strerror(errno));
+ throw IOError("Unable to stat FCSM driver");
+ }
+ }
+
+
+ /* construct fcio struct */
+ memset(&fcio, 0, sizeof (fcio_t));
+ fcio.fcio_cmd = FCSMIO_ADAPTER_LIST;
+ fcio.fcio_xfer = FCIO_XFER_RW;
+
+
+ /* open the fcsm node so we can send the ioctl to */
+ errno = 0;
+ if ((fd = open(FCSM_DRIVER_PATH.c_str(), O_RDONLY)) < 0) {
+ if (errno == EBUSY) {
+ throw BusyException();
+ } else if (errno == EAGAIN) {
+ throw TryAgainException();
+ } else if (errno == ENOTSUP) {
+ throw NotSupportedException();
+ } else if (errno == ENOENT) {
+ throw UnavailableException();
+ } else {
+ throw IOError("Unable to open FCSM driver");
+ }
+ }
+
+ do {
+ retry = false;
+ errno = 0;
+ bufSize = MAXPATHLEN * size + (int) sizeof (fc_hba_list_t) - 1;
+ pathList = (fc_hba_list_t *)new uchar_t[bufSize];
+ pathList->numAdapters = size;
+ fcio.fcio_olen = bufSize;
+ fcio.fcio_obuf = (char *)pathList;
+ if (ioctl(fd, FCSMIO_CMD, &fcio) != 0) {
+ /* Interpret the fcio error code */
+ char fcioErrorString[MAX_FCIO_MSG_LEN] = "";
+
+ log.genericIOError(
+ "ADAPTER_LIST failed: "
+ "Errno: \"%s\"",
+ strerror(errno));
+ delete (pathList);
+ close(fd);
+ if (errno == EBUSY) {
+ throw BusyException();
+ } else if (errno == EAGAIN) {
+ throw TryAgainException();
+ } else if (errno == ENOTSUP) {
+ throw NotSupportedException();
+ } else if (errno == ENOENT) {
+ throw UnavailableException();
+ } else {
+ throw IOError("Unable to build HBA list");
+ }
+ }
+ if (pathList->numAdapters > size) {
+ log.debug(
+ "Buffer too small for number of HBAs. Retrying.");
+ size = pathList->numAdapters;
+ retry = true;
+ delete (pathList);
+ }
+ } while (retry);
+
+ close(fd);
+ log.debug("Detected %d adapters", pathList->numAdapters);
+ for (int i = 0; i < pathList->numAdapters; i++) {
+ try {
+ HBA *hba = new FCHBA(pathList->hbaPaths[i]);
+ list.insert(list.begin(), hba);
+ } catch (...) {
+ log.debug(
+ "Ignoring partial failure while loading an HBA");
+ }
+ }
+ if (pathList->numAdapters > HBAList::HBA_MAX_PER_LIST) {
+ delete(pathList);
+ throw InternalError(
+ "Exceeds max number of adatpers that VSL supports.");
+ }
+ delete (pathList);
+}
diff --git a/usr/src/lib/sun_fc/common/FCHBA.h b/usr/src/lib/sun_fc/common/FCHBA.h
new file mode 100644
index 0000000000..d275820327
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/FCHBA.h
@@ -0,0 +1,61 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _FCHBA_H
+#define _FCHBA_H
+
+
+
+
+#include "HBA.h"
+#include "FCHBAPort.h"
+#include <map>
+#include <string>
+#include <hbaapi.h>
+
+
+/*
+ * Represents an individual FCHBA
+ */
+class FCHBA : public HBA {
+public:
+ FCHBA(std::string path);
+ /*
+ * Fetch the name, excluding the trailing "-" and index number
+ */
+ virtual std::string getName();
+ virtual HBA_ADAPTERATTRIBUTES getHBAAttributes();
+ virtual HBA_ADAPTERATTRIBUTES npivGetHBAAttributes();
+ static void loadAdapters(std::vector<HBA*> &list);
+
+private:
+ std::string name;
+ static const std::string FCSM_DRIVER_PATH;
+ static const std::string FCSM_DRIVER_PKG;
+ static const int MAX_FCIO_MSG_LEN;
+};
+
+
+#endif /* _FCHBA_H */
diff --git a/usr/src/lib/sun_fc/common/FCHBANPIVPort.cc b/usr/src/lib/sun_fc/common/FCHBANPIVPort.cc
new file mode 100644
index 0000000000..ad2afe69b2
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/FCHBANPIVPort.cc
@@ -0,0 +1,315 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#include "FCHBANPIVPort.h"
+#include <Exceptions.h>
+#include <Trace.h>
+#include <sun_fc.h>
+#include <iostream>
+#include <iomanip>
+#include <sys/types.h>
+#include <sys/mkdev.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stropts.h>
+#include <dirent.h>
+#include <sys/fibre-channel/fc.h>
+#include <sys/fibre-channel/fcio.h>
+#include <sys/fibre-channel/ulp/fcp_util.h>
+#include <sys/fibre-channel/ulp/fcsm.h>
+#include <sys/fibre-channel/impl/fc_error.h>
+#include <sys/fibre-channel/fc_appif.h>
+#include <sys/scsi/generic/commands.h>
+#include <sys/scsi/impl/commands.h>
+#include <sys/scsi/impl/sense.h>
+#include <sys/scsi/generic/inquiry.h>
+#include <sys/scsi/generic/status.h>
+#include <errno.h>
+
+using namespace std;
+
+const int FCHBANPIVPort::MAX_FCIO_MSG_LEN = 256;
+
+FCHBANPIVPort::FCHBANPIVPort(string thePath) : HBANPIVPort() {
+ Trace log("FCHBANPIVPort::FCHBANPIVPort");
+ log.debug("Initializing HBA NPIV port %s", thePath.c_str());
+
+ try {
+ path = lookupControllerPath(thePath);
+ } catch (...) {
+ log.debug("Unable to lookup controller path and number for %s",
+ thePath.c_str());
+ path = "/devices";
+ path += thePath;
+ path += ":fc";
+ }
+
+ uint64_t tmp;
+ HBA_NPIVATTRIBUTES attrs = getPortAttributes(tmp);
+ memcpy(&tmp, &attrs.PortWWN, 8);
+ portWWN = ntohll(tmp);
+ memcpy(&tmp, &attrs.NodeWWN, 8);
+ nodeWWN = ntohll(tmp);
+}
+
+
+HBA_NPIVATTRIBUTES FCHBANPIVPort::getPortAttributes(uint64_t &stateChange) {
+ Trace log("FCHBANPIVPort::getPortAttributes");
+
+ HBA_NPIVATTRIBUTES attributes;
+ fcio_t fcio;
+ fc_hba_npiv_attributes_t attrs;
+
+ memset(&fcio, 0, sizeof (fcio));
+ memset(&attributes, 0, sizeof (attributes));
+ fcio.fcio_cmd = FCIO_GET_NPIV_ATTRIBUTES;
+ fcio.fcio_olen = sizeof (attrs);
+ fcio.fcio_xfer = FCIO_XFER_READ;
+ fcio.fcio_obuf = (caddr_t)&attrs;
+ fp_ioctl(getPath(), FCIO_CMD, &fcio);
+
+ stateChange = attrs.lastChange;
+ memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8);
+ memcpy(&attributes.PortWWN, &attrs.PortWWN, 8);
+
+ return (attributes);
+}
+
+
+void FCHBANPIVPort::fp_ioctl(string path, int cmd, fcio_t *fcio) {
+ Trace log("FCHBANPIVPort::fp_ioctl");
+
+ char fcioErrorString[MAX_FCIO_MSG_LEN] = "";
+ int fd = HBA::_open(path, O_NDELAY | O_RDONLY);
+
+ try {
+ int times = 0;
+ HBA::_ioctl(fd, cmd, (uchar_t *)fcio);
+ while (fcio->fcio_errno == FC_STATEC_BUSY) {
+ (void) sleep(2);
+ HBA::_ioctl(fd, cmd, (uchar_t *)fcio);
+ if (times++ > 20) {
+ break;
+ }
+ }
+ close(fd);
+ if (fcio->fcio_errno) {
+ throw IOError("IOCTL transport failure");
+ }
+ } catch (...) {
+ close(fd);
+ transportError(fcio->fcio_errno, fcioErrorString);
+ log.genericIOError("NPIV Port ioctl (0x%x) failed. Transport: \"%s\"", cmd,
+ fcioErrorString);
+ switch (fcio->fcio_errno) {
+ case FC_BADWWN:
+ throw IllegalWWNException();
+ case FC_BADPORT:
+ throw IllegalWWNException();
+ case FC_OUTOFBOUNDS:
+ throw IllegalIndexException();
+ case FC_PBUSY:
+ case FC_FBUSY:
+ case FC_TRAN_BUSY:
+ case FC_STATEC_BUSY:
+ case FC_DEVICE_BUSY:
+ throw BusyException();
+ case FC_SUCCESS:
+ default:
+ throw;
+ }
+ }
+}
+
+
+/*
+ * Interpret the error code in the fcio_t structure
+ *
+ * message must be at least MAX_FCIO_MSG_LEN in length.
+ */
+void
+FCHBANPIVPort::transportError(uint32_t fcio_errno, char *message) {
+ Trace log("transportError");
+
+ string fcioErrorString;
+ if (message == NULL) {
+ log.internalError("NULL routine argument");
+ return;
+ }
+ switch (fcio_errno) {
+ case (uint32_t)FC_FAILURE:
+ fcioErrorString = "general failure";
+ break;
+ case (uint32_t)FC_FAILURE_SILENT:
+ fcioErrorString = "general failure but fail silently";
+ break;
+ case FC_SUCCESS:
+ fcioErrorString = "successful completion";
+ break;
+ case FC_CAP_ERROR:
+ fcioErrorString = "FCA capability error";
+ break;
+ case FC_CAP_FOUND:
+ fcioErrorString = "FCA capability unsettable";
+ break;
+ case FC_CAP_SETTABLE:
+ fcioErrorString = "FCA capability settable";
+ break;
+ case FC_UNBOUND:
+ fcioErrorString = "unbound stuff";
+ break;
+ case FC_NOMEM:
+ fcioErrorString = "allocation error";
+ break;
+ case FC_BADPACKET:
+ fcioErrorString = "invalid packet specified/supplied";
+ break;
+ case FC_OFFLINE:
+ fcioErrorString = "I/O resource unavailable";
+ break;
+ case FC_OLDPORT:
+ fcioErrorString = "operation on non-loop port";
+ break;
+ case FC_NO_MAP:
+ fcioErrorString = "requested map unavailable";
+ break;
+ case FC_TRANSPORT_ERROR:
+ fcioErrorString = "unable to transport I/O";
+ break;
+ case FC_ELS_FREJECT:
+ fcioErrorString = "ELS rejected by a Fabric";
+ break;
+ case FC_ELS_PREJECT:
+ fcioErrorString = "ELS rejected by an N_port";
+ break;
+ case FC_ELS_BAD:
+ fcioErrorString = "ELS rejected by FCA/fctl";
+ break;
+ case FC_ELS_MALFORMED:
+ fcioErrorString = "poorly formed ELS request";
+ break;
+ case FC_TOOMANY:
+ fcioErrorString = "resource request too large";
+ break;
+ case FC_UB_BADTOKEN:
+ fcioErrorString = "invalid unsolicited buffer token";
+ break;
+ case FC_UB_ERROR:
+ fcioErrorString = "invalid unsol buf request";
+ break;
+ case FC_UB_BUSY:
+ fcioErrorString = "buffer already in use";
+ break;
+ case FC_BADULP:
+ fcioErrorString = "Unknown ulp";
+ break;
+ case FC_BADTYPE:
+ fcioErrorString = "ULP not registered to handle this FC4 type";
+ break;
+ case FC_UNCLAIMED:
+ fcioErrorString = "request or data not claimed";
+ break;
+ case FC_ULP_SAMEMODULE:
+ fcioErrorString = "module already in use";
+ break;
+ case FC_ULP_SAMETYPE:
+ fcioErrorString = "FC4 module already in use";
+ break;
+ case FC_ABORTED:
+ fcioErrorString = "request aborted";
+ break;
+ case FC_ABORT_FAILED:
+ fcioErrorString = "abort request failed";
+ break;
+ case FC_BADEXCHANGE:
+ fcioErrorString = "exchange doesn\325t exist";
+ break;
+ case FC_BADWWN:
+ fcioErrorString = "WWN not recognized";
+ break;
+ case FC_BADDEV:
+ fcioErrorString = "device unrecognized";
+ break;
+ case FC_BADCMD:
+ fcioErrorString = "invalid command issued";
+ break;
+ case FC_BADOBJECT:
+ fcioErrorString = "invalid object requested";
+ break;
+ case FC_BADPORT:
+ fcioErrorString = "invalid port specified";
+ break;
+ case FC_NOTTHISPORT:
+ fcioErrorString = "resource not at this port";
+ break;
+ case FC_PREJECT:
+ fcioErrorString = "reject at remote N_Port";
+ break;
+ case FC_FREJECT:
+ fcioErrorString = "reject at remote Fabric";
+ break;
+ case FC_PBUSY:
+ fcioErrorString = "remote N_Port busy";
+ break;
+ case FC_FBUSY:
+ fcioErrorString = "remote Fabric busy";
+ break;
+ case FC_ALREADY:
+ fcioErrorString = "already logged in";
+ break;
+ case FC_LOGINREQ:
+ fcioErrorString = "login required";
+ break;
+ case FC_RESETFAIL:
+ fcioErrorString = "reset failed";
+ break;
+ case FC_INVALID_REQUEST:
+ fcioErrorString = "request is invalid";
+ break;
+ case FC_OUTOFBOUNDS:
+ fcioErrorString = "port number is out of bounds";
+ break;
+ case FC_TRAN_BUSY:
+ fcioErrorString = "command transport busy";
+ break;
+ case FC_STATEC_BUSY:
+ fcioErrorString = "port driver currently busy";
+ break;
+ case FC_DEVICE_BUSY:
+ fcioErrorString = "transport working on this device";
+ break;
+ case FC_DEVICE_NOT_TGT:
+ fcioErrorString = "device is not a SCSI target";
+ break;
+ default:
+ snprintf(message, MAX_FCIO_MSG_LEN, "Unknown error code 0x%x",
+ fcio_errno);
+ return;
+ }
+ snprintf(message, MAX_FCIO_MSG_LEN, "%s", fcioErrorString.c_str());
+}
+
diff --git a/usr/src/lib/sun_fc/common/FCHBANPIVPort.h b/usr/src/lib/sun_fc/common/FCHBANPIVPort.h
new file mode 100644
index 0000000000..5c19cecd44
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/FCHBANPIVPort.h
@@ -0,0 +1,70 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _FCHBANPIVPORT_H
+#define _FCHBANPIVPORT_H
+
+
+#include <Lockable.h>
+#include "HBANPIVPort.h"
+#include "HBAPort.h"
+#include <Exceptions.h>
+#include <string>
+#include <hbaapi.h>
+#include <sys/fibre-channel/fcio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Represents a single HBA NPIV port
+ */
+class FCHBANPIVPort : public HBANPIVPort {
+public:
+ FCHBANPIVPort(std::string path);
+ virtual std::string getPath()
+ { return path; }
+ virtual uint64_t getNodeWWN()
+ { return nodeWWN; }
+ virtual uint64_t getPortWWN()
+ { return portWWN; }
+ virtual HBA_NPIVATTRIBUTES getPortAttributes(
+ uint64_t &stateChange);
+
+private:
+ std::string path;
+ uint64_t portWWN;
+ uint64_t nodeWWN;
+ static const int MAX_FCIO_MSG_LEN;
+ static void transportError(uint32_t fcio_error, char *message);
+ static void fp_ioctl(std::string path, int cmd, fcio_t *arg);
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _FCHBANPIVPORT_H */
diff --git a/usr/src/lib/sun_fc/common/FCHBAPort.cc b/usr/src/lib/sun_fc/common/FCHBAPort.cc
new file mode 100644
index 0000000000..14b66a9de4
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/FCHBAPort.cc
@@ -0,0 +1,1267 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include <FCHBAPort.h>
+#include <Exceptions.h>
+#include <Trace.h>
+#include <sun_fc.h>
+#include <iostream>
+#include <iomanip>
+#include <sys/types.h>
+#include <sys/mkdev.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stropts.h>
+#include <dirent.h>
+#include <sys/fibre-channel/fc.h>
+#include <sys/fibre-channel/fcio.h>
+#include <sys/fibre-channel/ulp/fcp_util.h>
+#include <sys/fibre-channel/ulp/fcsm.h>
+#include <sys/fibre-channel/impl/fc_error.h>
+#include <sys/fibre-channel/fc_appif.h>
+#include <sys/scsi/generic/commands.h>
+#include <sys/scsi/impl/commands.h>
+#include <sys/scsi/impl/sense.h>
+#include <sys/scsi/generic/inquiry.h>
+#include <sys/scsi/generic/status.h>
+#include <errno.h>
+#include <FCHBANPIVPort.h>
+
+
+using namespace std;
+
+const int FCHBAPort::MAX_FCIO_MSG_LEN = 256;
+const string FCHBAPort::FCSM_DRIVER_PATH = "/devices/pseudo/fcsm@0:fcsm";
+const string FCHBAPort::FCP_DRIVER_PATH = "/devices/pseudo/fcp@0:fcp";
+
+/*
+ * Interpret the error code in the fcio_t structure
+ *
+ * message must be at least MAX_FCIO_MSG_LEN in length.
+ */
+void
+FCHBAPort::transportError(uint32_t fcio_errno, char *message) {
+ Trace log("transportError");
+ string fcioErrorString;
+ if (message == NULL) {
+ log.internalError("NULL routine argument");
+ return;
+ }
+ switch (fcio_errno) {
+ case (uint32_t)FC_FAILURE:
+ fcioErrorString = "general failure";
+ break;
+ case (uint32_t)FC_FAILURE_SILENT:
+ fcioErrorString = "general failure but fail silently";
+ break;
+ case FC_SUCCESS:
+ fcioErrorString = "successful completion";
+ break;
+ case FC_CAP_ERROR:
+ fcioErrorString = "FCA capability error";
+ break;
+ case FC_CAP_FOUND:
+ fcioErrorString = "FCA capability unsettable";
+ break;
+ case FC_CAP_SETTABLE:
+ fcioErrorString = "FCA capability settable";
+ break;
+ case FC_UNBOUND:
+ fcioErrorString = "unbound stuff";
+ break;
+ case FC_NOMEM:
+ fcioErrorString = "allocation error";
+ break;
+ case FC_BADPACKET:
+ fcioErrorString = "invalid packet specified/supplied";
+ break;
+ case FC_OFFLINE:
+ fcioErrorString = "I/O resource unavailable";
+ break;
+ case FC_OLDPORT:
+ fcioErrorString = "operation on non-loop port";
+ break;
+ case FC_NO_MAP:
+ fcioErrorString = "requested map unavailable";
+ break;
+ case FC_TRANSPORT_ERROR:
+ fcioErrorString = "unable to transport I/O";
+ break;
+ case FC_ELS_FREJECT:
+ fcioErrorString = "ELS rejected by a Fabric";
+ break;
+ case FC_ELS_PREJECT:
+ fcioErrorString = "ELS rejected by an N_port";
+ break;
+ case FC_ELS_BAD:
+ fcioErrorString = "ELS rejected by FCA/fctl";
+ break;
+ case FC_ELS_MALFORMED:
+ fcioErrorString = "poorly formed ELS request";
+ break;
+ case FC_TOOMANY:
+ fcioErrorString = "resource request too large";
+ break;
+ case FC_UB_BADTOKEN:
+ fcioErrorString = "invalid unsolicited buffer token";
+ break;
+ case FC_UB_ERROR:
+ fcioErrorString = "invalid unsol buf request";
+ break;
+ case FC_UB_BUSY:
+ fcioErrorString = "buffer already in use";
+ break;
+ case FC_BADULP:
+ fcioErrorString = "Unknown ulp";
+ break;
+ case FC_BADTYPE:
+ fcioErrorString = "ULP not registered to handle this FC4 type";
+ break;
+ case FC_UNCLAIMED:
+ fcioErrorString = "request or data not claimed";
+ break;
+ case FC_ULP_SAMEMODULE:
+ fcioErrorString = "module already in use";
+ break;
+ case FC_ULP_SAMETYPE:
+ fcioErrorString = "FC4 module already in use";
+ break;
+ case FC_ABORTED:
+ fcioErrorString = "request aborted";
+ break;
+ case FC_ABORT_FAILED:
+ fcioErrorString = "abort request failed";
+ break;
+ case FC_BADEXCHANGE:
+ fcioErrorString = "exchange doesnŐt exist";
+ break;
+ case FC_BADWWN:
+ fcioErrorString = "WWN not recognized";
+ break;
+ case FC_BADDEV:
+ fcioErrorString = "device unrecognized";
+ break;
+ case FC_BADCMD:
+ fcioErrorString = "invalid command issued";
+ break;
+ case FC_BADOBJECT:
+ fcioErrorString = "invalid object requested";
+ break;
+ case FC_BADPORT:
+ fcioErrorString = "invalid port specified";
+ break;
+ case FC_NOTTHISPORT:
+ fcioErrorString = "resource not at this port";
+ break;
+ case FC_PREJECT:
+ fcioErrorString = "reject at remote N_Port";
+ break;
+ case FC_FREJECT:
+ fcioErrorString = "reject at remote Fabric";
+ break;
+ case FC_PBUSY:
+ fcioErrorString = "remote N_Port busy";
+ break;
+ case FC_FBUSY:
+ fcioErrorString = "remote Fabric busy";
+ break;
+ case FC_ALREADY:
+ fcioErrorString = "already logged in";
+ break;
+ case FC_LOGINREQ:
+ fcioErrorString = "login required";
+ break;
+ case FC_RESETFAIL:
+ fcioErrorString = "reset failed";
+ break;
+ case FC_INVALID_REQUEST:
+ fcioErrorString = "request is invalid";
+ break;
+ case FC_OUTOFBOUNDS:
+ fcioErrorString = "port number is out of bounds";
+ break;
+ case FC_TRAN_BUSY:
+ fcioErrorString = "command transport busy";
+ break;
+ case FC_STATEC_BUSY:
+ fcioErrorString = "port driver currently busy";
+ break;
+ case FC_DEVICE_BUSY:
+ fcioErrorString = "transport working on this device";
+ break;
+ case FC_DEVICE_NOT_TGT:
+ fcioErrorString = "device is not a SCSI target";
+ break;
+ default:
+ snprintf(message, MAX_FCIO_MSG_LEN, "Unknown error code 0x%x",
+ fcio_errno);
+ return;
+ }
+ snprintf(message, MAX_FCIO_MSG_LEN, "%s", fcioErrorString.c_str());
+}
+
+static void
+reportSense(struct scsi_extended_sense *sense, const char *routine) {
+ Trace log("reportSense");
+ string msg;
+ if (!sense) {
+ log.internalError("NULL sense argument passed.");
+ return;
+ }
+ if (!routine) {
+ log.internalError("NULL routine argument passed.");
+ return;
+ }
+ log.genericIOError("SCSI FAILURE");
+ switch (sense->es_key) {
+ case KEY_NO_SENSE:
+ msg = "No sense";
+ break;
+ case KEY_RECOVERABLE_ERROR:
+ msg = "Recoverable error";
+ break;
+ case KEY_NOT_READY:
+ msg = "Not ready";
+ break;
+ case KEY_MEDIUM_ERROR:
+ msg = "Medium error";
+ break;
+ case KEY_HARDWARE_ERROR:
+ msg = "Hardware error";
+ break;
+ case KEY_ILLEGAL_REQUEST:
+ msg = "Illegal request";
+ break;
+ case KEY_UNIT_ATTENTION:
+ msg = "Unit attention";
+ break;
+ case KEY_DATA_PROTECT:
+ msg = "Data protect";
+ break;
+ case KEY_BLANK_CHECK:
+ msg = "Blank check";
+ break;
+ case KEY_VENDOR_UNIQUE:
+ msg = "Vendor Unique";
+ break;
+ case KEY_COPY_ABORTED:
+ msg = "Copy aborted";
+ break;
+ case KEY_ABORTED_COMMAND:
+ msg = "Aborted command";
+ break;
+ case KEY_EQUAL:
+ msg = "Equal";
+ break;
+ case KEY_VOLUME_OVERFLOW:
+ msg = "Volume overflow";
+ break;
+ case KEY_MISCOMPARE:
+ msg = "Miscompare";
+ break;
+ case KEY_RESERVED:
+ msg = "Reserved";
+ break;
+ default:
+ msg = "unknown sense key";
+ }
+ log.genericIOError("\tSense key: %s", msg.c_str());
+ log.genericIOError("\tASC = 0x%x", sense->es_add_code);
+ log.genericIOError("\tASCQ = 0x%x", sense->es_qual_code);
+}
+
+/*
+ * Issue a SCSI pass thru command.
+ * Returns a scsi status value.
+ */
+void FCHBAPort::sendSCSIPassThru(struct fcp_scsi_cmd *fscsi,
+ HBA_UINT32 *responseSize, HBA_UINT32 *senseSize,
+ HBA_UINT8 *scsiStatus) {
+ Trace log("FCHBAPort::sendSCSIPassThru");
+ int fd;
+ HBA_STATUS ret;
+ int count;
+ char fcioErrorString[MAX_FCIO_MSG_LEN] = "";
+ hrtime_t start;
+ hrtime_t end;
+ int ioctl_errno;
+ double duration;
+ la_wwn_t wwn;
+
+ if (fscsi == NULL ||
+ responseSize == NULL ||
+ senseSize == NULL ||
+ scsiStatus == NULL) {
+ throw BadArgumentException();
+ }
+
+ memcpy(&wwn, fscsi->scsi_fc_pwwn.raw_wwn, sizeof (la_wwn_t));
+ start = gethrtime();
+ fscsi->scsi_fc_port_num = instanceNumber;
+
+ fd = HBA::_open(FCP_DRIVER_PATH, O_RDONLY | O_NDELAY);
+ count = 0;
+ ioctl_errno = 0;
+
+ if (ioctl(fd, FCP_TGT_SEND_SCSI, fscsi) != 0) {
+ /* save off errno */
+ ioctl_errno = errno;
+ close(fd);
+ /*
+ * collect SCSI status first regrardless of the value.
+ * 0 is a good status so this should be okay
+ */
+ *scsiStatus = fscsi->scsi_bufstatus & STATUS_MASK;
+ transportError(fscsi->scsi_fc_status, fcioErrorString);
+
+ /* Did we get a check condition? */
+ if ((fscsi->scsi_bufstatus & STATUS_MASK) == STATUS_CHECK) {
+ *senseSize = fscsi->scsi_rqlen;
+ throw CheckConditionException();
+ } else if (fscsi->scsi_fc_status == FC_DEVICE_NOT_TGT) {
+ /*
+ * fcp driver returns FC_DEVICE_NOT_TGT when the node is not
+ * scsi-capable like remote hba nodes.
+ */
+ throw NotATargetException();
+ } else if (fscsi->scsi_fc_status == FC_INVALID_LUN) {
+ throw InvalidLUNException();
+ } else if (ioctl_errno == EBUSY) {
+ throw BusyException();
+ } else if (ioctl_errno == EAGAIN) {
+ throw TryAgainException();
+ } else if (ioctl_errno == ENOTSUP) {
+ throw NotSupportedException();
+ } else if (ioctl_errno == ENOENT) {
+ throw UnavailableException();
+ } else {
+ throw IOError(this, wwnConversion(wwn.raw_wwn),
+ fscsi->scsi_lun);
+ }
+ } else {
+ close(fd);
+ /* Just in case, check for a check-condition state */
+ if ((fscsi->scsi_bufstatus & STATUS_MASK) == STATUS_CHECK) {
+ *scsiStatus = fscsi->scsi_bufstatus & STATUS_MASK;
+ *senseSize = fscsi->scsi_rqlen;
+ throw CheckConditionException();
+ }
+ }
+
+ /* Record the response data */
+ *scsiStatus = fscsi->scsi_bufstatus & STATUS_MASK;
+ *responseSize = fscsi->scsi_buflen;
+ *senseSize = fscsi->scsi_rqlen;
+
+ /* Do some quick duration calcuations */
+ end = gethrtime();
+ duration = end - start;
+ duration /= HR_SECOND;
+ log.debug("Total SCSI IO time for HBA %s "
+ "target %016llx was %.4f seconds", getPath().c_str(),
+ wwnConversion(wwn.raw_wwn), duration);
+
+#ifdef DEBUG
+ /* Did we have any failure */
+ if (ret != HBA_STATUS_OK) {
+ log.genericIOError(
+ "Ioctl failed for device \"%s\" target %016llx."
+ " Errno: \"%s\"(%d), "
+ "Transport: \"%s\", SCSI Status: 0x%x"
+ "responseSize = %d, senseSize = %d",
+ getPath().c_str(), wwnConversion(fscsi->scsi_fc_pwwn.raw_wwn),
+ strerror(ioctl_errno), ioctl_errno, fcioErrorString,
+ *scsiStatus, *responseSize, *senseSize);
+ /* We may or may not have sense data */
+ reportSense((struct scsi_extended_sense *)fscsi->scsi_rqbufaddr,
+ ROUTINE);
+ }
+#endif
+
+}
+
+/*
+ * constructs the fcp_scsi_cmd struct for SCSI_Inquiry, SendReadCapacity, or
+ * SendReportLUNs
+ */
+/*#include <fcio.h>
+#include <fcp_util.h>*/
+inline void
+scsi_cmd_init(struct fcp_scsi_cmd *fscsi, const char *portname, void *reqbuf,
+ size_t req_len, void *responseBuffer, size_t resp_len,
+ void *senseBuffer, size_t sense_len) {
+ Trace log("scsi_cmd_init");
+ fscsi->scsi_fc_rspcode = 0;
+ fscsi->scsi_flags = FCP_SCSI_READ;
+ fscsi->scsi_timeout = 10 /* sec */;
+ fscsi->scsi_cdbbufaddr = (char *)reqbuf;
+ fscsi->scsi_cdblen = (uint32_t) req_len;
+ fscsi->scsi_bufaddr = (char *)responseBuffer;
+ fscsi->scsi_buflen = (uint32_t) resp_len;
+ fscsi->scsi_bufresid = 0;
+ fscsi->scsi_bufstatus = 0;
+ fscsi->scsi_rqbufaddr = (char *)senseBuffer;
+ fscsi->scsi_rqlen = (uint32_t) sense_len;
+ fscsi->scsi_rqresid = 0;
+}
+
+
+FCHBAPort::FCHBAPort(string thePath) : HBAPort() {
+ Trace log("FCHBAPort::FCHBAPort");
+ log.debug("Initializing HBA port %s", thePath.c_str());
+ fcio_t fcio;
+ int size = 200;
+ fc_hba_npiv_port_list_t *pathList;
+ bool retry = false;
+ int bufSize;
+
+ try {
+ path = lookupControllerPath(thePath);
+ sscanf(path.c_str(), "/dev/cfg/c%d", &controllerNumber);
+ } catch (...) {
+ log.debug("Unable to lookup controller path and number for %s",
+ thePath.c_str());
+ path = "/devices";
+ path += thePath;
+ path += ":fc";
+ controllerNumber = -1;
+ }
+
+ // Fetch the minor number for later use
+ struct stat sbuf;
+ if (stat(path.c_str(), &sbuf) == -1) {
+ throw IOError("Unable to stat device path: " + path);
+ }
+ instanceNumber = minor(sbuf.st_rdev);
+
+ // This routine is not index based, so we can discard stateChange
+ uint64_t tmp;
+ HBA_PORTATTRIBUTES attrs = getPortAttributes(tmp);
+ memcpy(&tmp, &attrs.PortWWN, 8);
+ portWWN = ntohll(tmp);
+ memcpy(&tmp, &attrs.NodeWWN, 8);
+ nodeWWN = ntohll(tmp);
+
+ // For reference, here's how to dump WWN's through C++ streams.
+ // cout << "\tPort WWN: " << hex << setfill('0') << setw(16) << portWWN
+ // << endl;
+ // cout << "\tNode WWN: " << hex << setfill('0') << setw(16) << nodeWWN
+ // << endl;
+
+ // we should add code here to build NPIVPORT instance
+ // Get Port's NPIV port list ( include nwwn and pwwn and path)
+ memset((caddr_t)&fcio, 0, sizeof (fcio));
+ fcio.fcio_cmd = FCIO_GET_NPIV_PORT_LIST;
+ fcio.fcio_xfer = FCIO_XFER_READ;
+ do {
+ retry = false;
+ bufSize = MAXPATHLEN * size + (int) sizeof (fc_hba_npiv_port_list_t) - 1;
+ pathList = (fc_hba_npiv_port_list_t *) new uchar_t[bufSize];
+ pathList->numAdapters = size;
+ fcio.fcio_olen = bufSize;
+ fcio.fcio_obuf = (char *)pathList;
+ fp_ioctl(getPath(), FCIO_CMD, &fcio);
+ if (pathList->numAdapters > size) {
+ log.debug("Buffer too small for number of NPIV Port.Retry.");
+ size = pathList->numAdapters;
+ retry = true;
+ delete (pathList);
+ }
+ } while (retry);
+ log.debug("Get %d npiv ports", pathList->numAdapters);
+ // Make instance for each NPIV Port
+ for ( int i = 0; i < pathList->numAdapters; i++) {
+ try {
+ addPort(new FCHBANPIVPort(pathList->hbaPaths[i]));
+ } catch (...) {
+ log.debug("Ignoring partial failure");
+ }
+ }
+ delete (pathList);
+}
+
+uint32_t FCHBAPort::deleteNPIVPort(uint64_t vportwwn) {
+ Trace log("FCHBAPort::deleteNPIVPort");
+ fcio_t fcio;
+ la_wwn_t lawwn[1];
+ int ret = 0;
+
+ memset(&fcio, 0, sizeof(fcio));
+ uint64_t en_wwn = htonll(vportwwn);
+ memcpy(&lawwn[0], &en_wwn, sizeof (en_wwn));
+
+ fcio.fcio_cmd = FCIO_DELETE_NPIV_PORT;
+ fcio.fcio_xfer = FCIO_XFER_WRITE;
+ fcio.fcio_ilen = sizeof (la_wwn_t) * 2;
+ fcio.fcio_ibuf = (caddr_t)&lawwn;
+
+ fp_ioctl(getPath(), FCIO_CMD, &fcio);
+
+ return (ret);
+}
+
+uint32_t FCHBAPort::createNPIVPort(uint64_t vnodewwn, uint64_t vportwwn, uint32_t vindex) {
+ Trace log("FCHBAPort::createNPIVPort");
+ fcio_t fcio;
+ la_wwn_t lawwn[2];
+ uint32_t vportindex = 0;
+ HBA_NPIVCREATEENTRY entrybuf;
+
+ memset(&fcio, 0, sizeof(fcio));
+ uint64_t en_wwn = htonll(vnodewwn);
+ memcpy(&entrybuf.VNodeWWN, &en_wwn, sizeof (en_wwn));
+ en_wwn = htonll(vportwwn);
+ memcpy(&entrybuf.VPortWWN, &en_wwn, sizeof (en_wwn));
+ entrybuf.vindex = vindex;
+
+ fcio.fcio_cmd = FCIO_CREATE_NPIV_PORT;
+ fcio.fcio_xfer = FCIO_XFER_READ;
+ fcio.fcio_olen = sizeof (uint32_t);
+ fcio.fcio_obuf = (caddr_t)&vportindex;
+ fcio.fcio_ilen = sizeof (HBA_NPIVCREATEENTRY);
+ fcio.fcio_ibuf = (caddr_t)&entrybuf;
+
+ fp_ioctl(getPath(), FCIO_CMD, &fcio);
+
+ return (vportindex);
+}
+
+HBA_PORTNPIVATTRIBUTES FCHBAPort::getPortNPIVAttributes(uint64_t &stateChange) {
+ Trace log("FCHBAPort::getPortNPIVAttributes");
+
+ HBA_PORTNPIVATTRIBUTES attributes;
+ fc_hba_port_npiv_attributes_t attrs;
+ fcio_t fcio;
+
+ memset(&fcio, 0, sizeof(fcio));
+ memset(&attributes, 0, sizeof(attributes));
+
+ fcio.fcio_cmd = FCIO_GET_ADAPTER_PORT_NPIV_ATTRIBUTES;
+ fcio.fcio_olen = sizeof(attrs);
+ fcio.fcio_xfer = FCIO_XFER_READ;
+ fcio.fcio_obuf = (caddr_t)&attrs;
+
+ fp_ioctl(getPath(), FCIO_CMD, &fcio);
+
+ stateChange = attrs.lastChange;
+ attributes.npivflag = attrs.npivflag;
+ memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8);
+ memcpy(&attributes.PortWWN, &attrs.PortWWN, 8);
+ attributes.MaxNumberOfNPIVPorts = attrs.MaxNumberOfNPIVPorts;
+ attributes.NumberOfNPIVPorts = attrs.NumberOfNPIVPorts;
+
+ return (attributes);
+}
+
+HBA_PORTATTRIBUTES FCHBAPort::getPortAttributes(uint64_t &stateChange) {
+ Trace log("FCHBAPort::getPortAttributes");
+
+ HBA_PORTATTRIBUTES attributes;
+ fcio_t fcio;
+ fc_hba_port_attributes_t attrs;
+
+ memset(&fcio, 0, sizeof (fcio));
+ memset(&attributes, 0, sizeof (attributes));
+
+ fcio.fcio_cmd = FCIO_GET_ADAPTER_PORT_ATTRIBUTES;
+ fcio.fcio_olen = sizeof (attrs);
+ fcio.fcio_xfer = FCIO_XFER_READ;
+ fcio.fcio_obuf = (caddr_t)&attrs;
+
+ fp_ioctl(getPath(), FCIO_CMD, &fcio);
+
+ stateChange = attrs.lastChange;
+
+ attributes.PortFcId = attrs.PortFcId;
+ attributes.PortType = attrs.PortType;
+ attributes.PortState = attrs.PortState;
+ attributes.PortSupportedClassofService = attrs.PortSupportedClassofService;
+ attributes.PortSupportedSpeed = attrs.PortSupportedSpeed;
+ attributes.PortSpeed = attrs.PortSpeed;
+ attributes.PortMaxFrameSize = attrs.PortMaxFrameSize;
+ attributes.NumberofDiscoveredPorts = attrs.NumberofDiscoveredPorts;
+ memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8);
+ memcpy(&attributes.PortWWN, &attrs.PortWWN, 8);
+ memcpy(&attributes.FabricName, &attrs.FabricName, 8);
+ memcpy(&attributes.PortSupportedFc4Types, &attrs.PortSupportedFc4Types, 32);
+ memcpy(&attributes.PortActiveFc4Types, &attrs.PortActiveFc4Types, 32);
+ memcpy(&attributes.PortSymbolicName, &attrs.PortSymbolicName, 256);
+
+ strncpy((char *)attributes.OSDeviceName, getPath().c_str(), 256);
+ return (attributes);
+}
+
+HBA_PORTATTRIBUTES FCHBAPort::getDiscoveredAttributes(
+ HBA_UINT32 discoveredport, uint64_t &stateChange) {
+ Trace log("FCHBAPort::getDiscoverdAttributes(i)");
+
+ HBA_PORTATTRIBUTES attributes;
+ fcio_t fcio;
+ fc_hba_port_attributes_t attrs;
+
+ memset(&fcio, 0, sizeof (fcio));
+ memset(&attributes, 0, sizeof (attributes));
+
+ fcio.fcio_cmd = FCIO_GET_DISCOVERED_PORT_ATTRIBUTES;
+ fcio.fcio_olen = sizeof (attrs);
+ fcio.fcio_xfer = FCIO_XFER_READ;
+ fcio.fcio_obuf = (caddr_t)&attrs;
+ fcio.fcio_ilen = sizeof (discoveredport);
+ fcio.fcio_ibuf = (caddr_t)&discoveredport;
+
+ fp_ioctl(getPath(), FCIO_CMD, &fcio);
+
+ stateChange = attrs.lastChange;
+
+ attributes.PortFcId = attrs.PortFcId;
+ attributes.PortType = attrs.PortType;
+ attributes.PortState = attrs.PortState;
+ attributes.PortSupportedClassofService = attrs.PortSupportedClassofService;
+ attributes.PortSupportedSpeed = attrs.PortSupportedSpeed;
+ attributes.PortSpeed = attrs.PortSpeed;
+ attributes.PortMaxFrameSize = attrs.PortMaxFrameSize;
+ attributes.NumberofDiscoveredPorts = attrs.NumberofDiscoveredPorts;
+ memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8);
+ memcpy(&attributes.PortWWN, &attrs.PortWWN, 8);
+ memcpy(&attributes.FabricName, &attrs.FabricName, 8);
+ memcpy(&attributes.PortSupportedFc4Types, &attrs.PortSupportedFc4Types, 32);
+ memcpy(&attributes.PortActiveFc4Types, &attrs.PortActiveFc4Types, 32);
+ memcpy(&attributes.PortSymbolicName, &attrs.PortSymbolicName, 256);
+
+
+ return (attributes);
+}
+
+HBA_PORTATTRIBUTES FCHBAPort::getDiscoveredAttributes(
+ uint64_t wwn, uint64_t &stateChange) {
+ Trace log("FCHBAPort::getDiscoverdAttributes(p)");
+
+ HBA_PORTATTRIBUTES attributes;
+ fcio_t fcio;
+ fc_hba_port_attributes_t attrs;
+ la_wwn_t lawwn;
+
+ memset(&fcio, 0, sizeof (fcio));
+ memset(&attributes, 0, sizeof (attributes));
+
+ uint64_t en_wwn = htonll(wwn);
+ memcpy(&lawwn, &en_wwn, sizeof (en_wwn));
+
+ fcio.fcio_cmd = FCIO_GET_PORT_ATTRIBUTES;
+ fcio.fcio_olen = sizeof (attrs);
+ fcio.fcio_xfer = FCIO_XFER_READ;
+ fcio.fcio_obuf = (caddr_t)&attrs;
+ fcio.fcio_ilen = sizeof (wwn);
+ fcio.fcio_ibuf = (caddr_t)&lawwn;
+
+ fp_ioctl(getPath(), FCIO_CMD, &fcio);
+
+ stateChange = attrs.lastChange;
+
+ attributes.PortFcId = attrs.PortFcId;
+ attributes.PortType = attrs.PortType;
+ attributes.PortState = attrs.PortState;
+ attributes.PortSupportedClassofService = attrs.PortSupportedClassofService;
+ attributes.PortSupportedSpeed = attrs.PortSupportedSpeed;
+ attributes.PortSpeed = attrs.PortSpeed;
+ attributes.PortMaxFrameSize = attrs.PortMaxFrameSize;
+ attributes.NumberofDiscoveredPorts = attrs.NumberofDiscoveredPorts;
+ memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8);
+ memcpy(&attributes.PortWWN, &attrs.PortWWN, 8);
+ memcpy(&attributes.FabricName, &attrs.FabricName, 8);
+ memcpy(&attributes.PortSupportedFc4Types, &attrs.PortSupportedFc4Types, 32);
+ memcpy(&attributes.PortActiveFc4Types, &attrs.PortActiveFc4Types, 32);
+ memcpy(&attributes.PortSymbolicName, &attrs.PortSymbolicName, 256);
+
+
+ return (attributes);
+}
+
+
+void FCHBAPort::getTargetMappings(PHBA_FCPTARGETMAPPINGV2 userMappings) {
+ Trace log("FCHBAPort::getTargetMappings");
+ int i, index;
+ uint_t total_entries = 0;
+
+ struct fcp_ioctl fioctl;
+ fc_hba_target_mappings_t *mappings;
+ int fd;
+ bool zeroLength = false;
+
+
+ if (userMappings == NULL) {
+ log.userError("Null mapping argument ");
+ throw BadArgumentException();
+ }
+
+ /* It's possible they didn't give any space */
+ if (userMappings->NumberOfEntries == 0) {
+ zeroLength = true;
+ userMappings->NumberOfEntries = 1;
+ /* We have to give the driver at least one space */
+ }
+
+ mappings = (fc_hba_target_mappings_t *)new uchar_t[
+ (sizeof (fc_hba_mapping_entry_t)) *
+ (userMappings->NumberOfEntries - 1) +
+ sizeof (fc_hba_target_mappings_t)];
+ if (mappings == NULL) {
+ log.noMemory();
+ throw InternalError();
+ }
+
+
+ fioctl.fp_minor = instanceNumber;
+ fioctl.listlen = ((uint32_t) (sizeof (fc_hba_mapping_entry_t))) *
+ (userMappings->NumberOfEntries - 1) +
+ (uint32_t) sizeof (fc_hba_target_mappings_t);
+ fioctl.list = (caddr_t)mappings;
+
+ fd = HBA::_open(FCP_DRIVER_PATH, O_RDONLY | O_NDELAY);
+
+ log.debug("Performing IOCTL to fetch mappings");
+
+ if (ioctl(fd, FCP_GET_TARGET_MAPPINGS, &fioctl) != 0) {
+ delete (mappings);
+ close(fd);
+ if (errno == EBUSY) {
+ throw BusyException();
+ } else if (errno == EAGAIN) {
+ throw TryAgainException();
+ } else if (errno == ENOTSUP) {
+ throw NotSupportedException();
+ } else if (errno == ENOENT) {
+ throw UnavailableException();
+ } else {
+ throw IOError("Unable to fetch target mappings");
+ }
+ }
+
+ close(fd);
+ // Quickly iterate through and copy the data over to the client
+ for (i = 0; i < userMappings->NumberOfEntries && !zeroLength &&
+ i < mappings->numLuns; i++) {
+ string raw = mappings->entries[i].targetDriver;
+
+
+ if (raw.length() <= 0) {
+ log.internalError("Bad target mapping without path, truncating.");
+ break;
+ }
+ /*
+ * Ideally, we'd like to ask some standard Solaris interface
+ * "What is the prefered minor node for this target?"
+ * but no such interface exists today. So, for now,
+ * we just hard-code ":n" for tapes, ":c,raw" for disks,
+ * and ":0" for enclosures.
+ * Devices with other generic names will be presented through
+ * first matching /dev path.
+ */
+ if ((raw.find("/st@") != raw.npos) ||
+ (raw.find("/tape@") != raw.npos)) {
+ raw += ":n";
+ } else if ((raw.find("/ssd@") != raw.npos) ||
+ (raw.find("/sd@") != raw.npos) ||
+ (raw.find("/disk@") != raw.npos)) {
+ raw += ":c,raw";
+ } else if ((raw.find("/ses@") != raw.npos) ||
+ (raw.find("/enclosure@") != raw.npos)) {
+ raw += ":0";
+ } else {
+ log.debug(
+ "Unrecognized target driver (%s), using first matching /dev path",
+ raw.c_str());
+ }
+ snprintf(userMappings->entry[i].ScsiId.OSDeviceName,
+ sizeof (userMappings->entry[i].ScsiId.OSDeviceName),
+ "/devices%s", raw.c_str());
+ userMappings->entry[i].ScsiId.ScsiBusNumber =
+ controllerNumber;
+ userMappings->entry[i].ScsiId.ScsiTargetNumber =
+ mappings->entries[i].targetNumber;
+ userMappings->entry[i].ScsiId.ScsiOSLun =
+ mappings->entries[i].osLUN;
+ userMappings->entry[i].FcpId.FcId =
+ mappings->entries[i].d_id;
+ memcpy(userMappings->entry[i].FcpId.NodeWWN.wwn,
+ mappings->entries[i].NodeWWN.raw_wwn,
+ sizeof (la_wwn_t));
+ memcpy(userMappings->entry[i].FcpId.PortWWN.wwn,
+ mappings->entries[i].PortWWN.raw_wwn,
+ sizeof (la_wwn_t));
+
+ userMappings->entry[i].FcpId.FcpLun =
+ mappings->entries[i].samLUN;
+
+ memcpy(userMappings->entry[i].LUID.buffer,
+ mappings->entries[i].guid,
+ sizeof (userMappings->entry[i].LUID.buffer));
+ }
+
+ log.debug("Total mappings: %d %08x %08x",
+ mappings->numLuns, mappings->entries[i].osLUN, mappings->entries[i].samLUN);
+
+ // If everything is good, convert paths to sym-links
+ if (mappings->numLuns > 0 && !zeroLength) {
+ if (userMappings->NumberOfEntries >= mappings->numLuns) {
+ // User buffer is larger than needed. (All is good)
+ userMappings->NumberOfEntries = mappings->numLuns;
+ convertToShortNames(userMappings);
+ } else {
+ // User buffer is non zero, but too small. Don't bother with links
+ userMappings->NumberOfEntries = mappings->numLuns;
+ delete (mappings);
+ throw MoreDataException();
+ }
+ } else if (mappings->numLuns > 0) {
+ // Zero length buffer, but we've got mappings
+ userMappings->NumberOfEntries = mappings->numLuns;
+ delete (mappings);
+ throw MoreDataException();
+ } else {
+ // No mappings, no worries
+ userMappings->NumberOfEntries = 0;
+ delete (mappings);
+ return;
+ }
+ delete (mappings);
+}
+
+void FCHBAPort::getRNIDMgmtInfo(PHBA_MGMTINFO info) {
+ Trace log("FCHBAPort::getRNIDMgmtInfo");
+ HBA_STATUS status = HBA_STATUS_OK;
+ fc_rnid_t rnid;
+ fcio_t fcio;
+
+
+ if (info == NULL) {
+ log.userError("NULL port management info");
+ throw BadArgumentException();
+ }
+
+ // Get the RNID information from the first port
+ memset(&rnid, 0, sizeof (fc_rnid_t));
+ memset((caddr_t)&fcio, 0, sizeof (fcio));
+
+ fcio.fcio_cmd = FCIO_GET_NODE_ID;
+ fcio.fcio_olen = sizeof (fc_rnid_t);
+ fcio.fcio_xfer = FCIO_XFER_READ;
+ fcio.fcio_obuf = (caddr_t)&rnid;
+ fp_ioctl(getPath(), FCIO_CMD, &fcio);
+
+ // Copy out the struct members of rnid into PHBA_MGMTINFO struct
+ memcpy(&info->wwn, &(rnid.global_id), sizeof (info->wwn));
+ memcpy(&info->unittype, &(rnid.unit_type), sizeof (info->unittype));
+ memcpy(&info->PortId, &(rnid.port_id), sizeof (info->PortId));
+ memcpy(&info->NumberOfAttachedNodes, &(rnid.num_attached),
+ sizeof (info->NumberOfAttachedNodes));
+ memcpy(&info->IPVersion, &(rnid.ip_version), sizeof (info->IPVersion));
+ memcpy(&info->UDPPort, &(rnid.udp_port), sizeof (info->UDPPort));
+ memcpy(&info->IPAddress, &(rnid.ip_addr), sizeof (info->IPAddress));
+ memcpy(&info->TopologyDiscoveryFlags, &(rnid.topo_flags),
+ sizeof (info->TopologyDiscoveryFlags));
+}
+
+void FCHBAPort::sendCTPassThru(void *requestBuffer, HBA_UINT32 requestSize,
+ void *responseBuffer, HBA_UINT32 *responseSize) {
+ Trace log("FCHBAPort::sendCTPassThru");
+ fcio_t fcio;
+ struct stat sbuf;
+ minor_t minor_node;
+ hrtime_t start, end;
+ double duration;
+
+ // Validate the arguments
+ if (requestBuffer == NULL) {
+ log.userError("NULL request buffer");
+ throw BadArgumentException();
+ }
+ if (responseBuffer == NULL) {
+ log.userError("NULL response buffer");
+ throw BadArgumentException();
+ }
+
+ minor_node = instanceNumber;
+
+ // construct fcio struct
+ memset(&fcio, 0, sizeof (fcio_t));
+ fcio.fcio_cmd = FCSMIO_CT_CMD;
+ fcio.fcio_xfer = FCIO_XFER_RW;
+
+ fcio.fcio_ilen = requestSize;
+ fcio.fcio_ibuf = (char *)requestBuffer;
+ fcio.fcio_olen = *responseSize;
+ fcio.fcio_obuf = (char *)responseBuffer;
+
+ fcio.fcio_alen = sizeof (minor_t);
+ fcio.fcio_abuf = (char *)&minor_node;
+
+
+ start = gethrtime();
+ fcsm_ioctl(FCSMIO_CMD, &fcio);
+
+ // Do some calculations on the duration of the ioctl.
+ end = gethrtime();
+ duration = end - start;
+ duration /= HR_SECOND;
+ log.debug(
+ "Total CTPASS ioctl call for HBA %s was %.4f seconds",
+ getPath().c_str(), duration);
+}
+
+void FCHBAPort::sendRLS(uint64_t destWWN,
+ void *pRspBuffer,
+ HBA_UINT32 *pRspBufferSize) {
+ Trace log("FCHBAPort::sendRLS");
+
+ fcio_t fcio;
+ fc_portid_t rls_req;
+
+
+ // Validate the arguments
+ if (pRspBuffer == NULL ||
+ pRspBufferSize == NULL) {
+ log.userError("NULL hba");
+ throw BadArgumentException();
+ }
+
+ // check to see if we are sending RLS to the HBA
+ HBA_PORTATTRIBUTES attrs;
+ uint64_t tmp;
+ if (getPortWWN() == destWWN) {
+ attrs = getPortAttributes(tmp);
+ } else {
+ attrs = getDiscoveredAttributes(destWWN, tmp);
+ }
+
+ memcpy(&rls_req, &attrs.PortFcId,
+ sizeof (attrs.PortFcId));
+
+ memset((caddr_t)&fcio, 0, sizeof (fcio));
+ fcio.fcio_cmd = FCIO_LINK_STATUS;
+ fcio.fcio_ibuf = (caddr_t)&rls_req;
+ fcio.fcio_ilen = sizeof (rls_req);
+ fcio.fcio_xfer = FCIO_XFER_RW;
+ fcio.fcio_flags = 0;
+ fcio.fcio_cmd_flags = FCIO_CFLAGS_RLS_DEST_NPORT;
+ fcio.fcio_obuf = (char *)new uchar_t[*pRspBufferSize];
+ fcio.fcio_olen = *pRspBufferSize;
+
+ if (fcio.fcio_obuf == NULL) {
+ log.noMemory();
+ throw InternalError();
+ }
+
+ fp_ioctl(getPath(), FCIO_CMD, &fcio);
+ memcpy(pRspBuffer, fcio.fcio_obuf, *pRspBufferSize);
+ if (fcio.fcio_obuf != NULL) {
+ delete(fcio.fcio_obuf);
+ }
+}
+
+void FCHBAPort::sendReportLUNs(uint64_t wwn,
+ void *responseBuffer, HBA_UINT32 *responseSize,
+ HBA_UINT8 *scsiStatus,
+ void *senseBuffer, HBA_UINT32 *senseSize) {
+ Trace log("FCHBAPort::sendReportLUNs");
+ struct fcp_scsi_cmd fscsi;
+ union scsi_cdb scsi_rl_req;
+ uint64_t targetWwn = htonll(wwn);
+
+ // Validate the arguments
+ if (responseBuffer == NULL ||
+ senseBuffer == NULL ||
+ responseSize == NULL ||
+ senseSize == NULL) {
+ throw BadArgumentException();
+ }
+
+ memset(&fscsi, 0, sizeof (fscsi));
+ memset(&scsi_rl_req, 0, sizeof (scsi_rl_req));
+ memcpy(fscsi.scsi_fc_pwwn.raw_wwn, &targetWwn, sizeof (la_wwn_t));
+
+ scsi_cmd_init(&fscsi, getPath().c_str(), &scsi_rl_req,
+ sizeof (scsi_rl_req), responseBuffer, *responseSize,
+ senseBuffer, *senseSize);
+
+ fscsi.scsi_lun = 0;
+ scsi_rl_req.scc_cmd = SCMD_REPORT_LUNS;
+ FORMG5COUNT(&scsi_rl_req, *responseSize);
+ sendSCSIPassThru(&fscsi, responseSize, senseSize, scsiStatus);
+}
+
+/*
+ * arguments:
+ * wwn - remote target WWN where the SCSI Inquiry shall be sent
+ * fcLun - the SCSI LUN to which the SCSI Inquiry shall be sent
+ * cdb1 - the second byte of the CDB for the SCSI Inquiry
+ * cdb2 - the third byte of teh CDB for the SCSI Inquiry
+ * responseBuffer - shall be a pointer to a buffer to receive the SCSI
+ * Inquiry command response
+ * responseSize - a pointer to the size of the buffer to receive
+ * the SCSI Inquiry.
+ * scsiStatus - a pointer to a buffer to receive SCSI status
+ * senseBuffer - pointer to a buffer to receive SCSI sense data
+ * seneseSize - pointer to the size of the buffer to receive SCSI sense
+ * data
+ */
+void FCHBAPort::sendScsiInquiry(uint64_t wwn, HBA_UINT64 fcLun,
+ HBA_UINT8 cdb1, HBA_UINT8 cdb2, void *responseBuffer,
+ HBA_UINT32 *responseSize, HBA_UINT8 *scsiStatus, void *senseBuffer,
+ HBA_UINT32 *senseSize) {
+ Trace log("FCHBAPort::sendScsiInquiry");
+
+ struct fcp_scsi_cmd fscsi;
+ union scsi_cdb scsi_inq_req;
+ uint64_t targetWwn = htonll(wwn);
+
+ // Validate the arguments
+ if (responseBuffer == NULL ||
+ senseBuffer == NULL ||
+ responseSize == NULL ||
+ senseSize == NULL) {
+ throw BadArgumentException();
+ }
+
+ memset(&fscsi, 0, sizeof (fscsi));
+ memset(&scsi_inq_req, 0, sizeof (scsi_inq_req));
+ memcpy(fscsi.scsi_fc_pwwn.raw_wwn, &targetWwn, sizeof (la_wwn_t));
+
+
+ scsi_cmd_init(&fscsi, getPath().c_str(), &scsi_inq_req,
+ sizeof (scsi_inq_req), responseBuffer, *responseSize,
+ senseBuffer, *senseSize);
+ fscsi.scsi_lun = fcLun;
+
+ scsi_inq_req.scc_cmd = SCMD_INQUIRY;
+ scsi_inq_req.g0_addr1 = cdb2;
+ scsi_inq_req.g0_addr2 = cdb1;
+ scsi_inq_req.g0_count0 = *responseSize;
+
+
+ sendSCSIPassThru(&fscsi, responseSize, senseSize, scsiStatus);
+}
+
+
+void FCHBAPort::sendReadCapacity(uint64_t pwwn,
+ HBA_UINT64 fcLun, void *responseBuffer,
+ HBA_UINT32 *responseSize, HBA_UINT8 *scsiStatus,
+ void *senseBuffer, HBA_UINT32 *senseSize) {
+ Trace log("FCHBAPort::sendReadCapacity");
+
+ struct fcp_scsi_cmd fscsi;
+ union scsi_cdb scsi_rc_req;
+ uint64_t targetWwn = htonll(pwwn);
+
+ // Validate the arguments
+ if (responseBuffer == NULL ||
+ senseBuffer == NULL ||
+ responseSize == NULL ||
+ senseSize == NULL ||
+ scsiStatus == NULL) {
+ throw BadArgumentException();
+ }
+
+ memset(&fscsi, 0, sizeof (fscsi));
+ memset(&scsi_rc_req, 0, sizeof (scsi_rc_req));
+
+ scsi_cmd_init(&fscsi, getPath().c_str(), &scsi_rc_req,
+ sizeof (scsi_rc_req), responseBuffer, *responseSize,
+ senseBuffer, *senseSize);
+
+ memcpy(fscsi.scsi_fc_pwwn.raw_wwn, &targetWwn, sizeof (la_wwn_t));
+ fscsi.scsi_lun = fcLun;
+
+ scsi_rc_req.scc_cmd = SCMD_READ_CAPACITY;
+ scsi_rc_req.g1_reladdr = 0;
+
+ scsi_rc_req.g1_addr3 = 0;
+ scsi_rc_req.g1_count0 = 0;
+
+ sendSCSIPassThru(&fscsi, responseSize, senseSize, scsiStatus);
+}
+
+void FCHBAPort::sendRNID(uint64_t destwwn, HBA_UINT32 destfcid,
+ HBA_UINT32 nodeIdDataFormat, void *pRspBuffer,
+ HBA_UINT32 *RspBufferSize) {
+ Trace log("FCHBAPort::sendRNID");
+ int localportfound, remoteportfound, send;
+ fcio_t fcio;
+
+ // Validate the arguments
+ if (pRspBuffer == NULL ||
+ RspBufferSize == NULL) {
+ throw BadArgumentException();
+ }
+ // NodeIdDataFormat must be within the range of 0x00 and 0xff
+ if (nodeIdDataFormat > 0xff) {
+ log.userError(
+ "NodeIdDataFormat must be within the range of 0x00 "
+ "and 0xFF");
+ throw BadArgumentException();
+ }
+
+
+ remoteportfound = 0;
+ if (destfcid != 0) {
+ try {
+ uint64_t tmp;
+ HBA_PORTATTRIBUTES attrs = getDiscoveredAttributes(destwwn,
+ tmp);
+ if (attrs.PortFcId == destfcid) {
+ send = 1;
+ remoteportfound = 1;
+ } else {
+ send = 0;
+ remoteportfound = 1;
+ }
+ } catch (HBAException &e) {
+ /*
+ * Send RNID if destination port not
+ * present in the discovered ports table
+ */
+ }
+ if (remoteportfound == 0) {
+ send = 1;
+ }
+ } else {
+ send = 1;
+ }
+
+ if (!send) {
+ // Can we log something so we can figure out why?
+ throw BadArgumentException();
+ }
+
+ memset((caddr_t)&fcio, 0, sizeof (fcio));
+ uint64_t netdestwwn = htonll(destwwn);
+ fcio.fcio_cmd = FCIO_SEND_NODE_ID;
+ fcio.fcio_xfer = FCIO_XFER_READ;
+ fcio.fcio_cmd_flags = nodeIdDataFormat;
+ fcio.fcio_ilen = sizeof (la_wwn_t);
+ fcio.fcio_ibuf = (caddr_t)&netdestwwn;
+ fcio.fcio_olen = *RspBufferSize;
+ fcio.fcio_obuf = (char *)new uchar_t[*RspBufferSize];
+
+
+ if (fcio.fcio_obuf == NULL) {
+ log.noMemory();
+ throw InternalError();
+ }
+
+ fp_ioctl(getPath(), FCIO_CMD, &fcio);
+
+ memcpy(pRspBuffer, fcio.fcio_obuf, *RspBufferSize);
+
+ if (fcio.fcio_obuf != NULL) {
+ delete(fcio.fcio_obuf);
+ }
+}
+
+void FCHBAPort::setRNID(HBA_MGMTINFO info) {
+ Trace log("FCHBAPort::setRNID");
+ fc_rnid_t rnid;
+ fcio_t fcio;
+
+ memset(&rnid, 0, sizeof (fc_rnid_t));
+ memset((caddr_t)&fcio, 0, sizeof (fcio));
+
+
+ fcio.fcio_cmd = FCIO_SET_NODE_ID;
+ fcio.fcio_ilen = sizeof (fc_rnid_t);
+ fcio.fcio_xfer = FCIO_XFER_WRITE;
+ fcio.fcio_ibuf = (caddr_t)&rnid;
+
+
+ // Copy the HBA_MGMTINFO into fc_rnid_t struct
+ memcpy(&(rnid.unit_type), &(info.unittype), sizeof (rnid.unit_type));
+ memcpy(&(rnid.port_id), &(info.PortId), sizeof (rnid.port_id));
+ memcpy(&(rnid.global_id), &(info.wwn), sizeof (info.wwn));
+ memcpy(&(rnid.num_attached), &(info.NumberOfAttachedNodes),
+ sizeof (rnid.num_attached));
+ memcpy(&(rnid.ip_version), &(info.IPVersion), sizeof (rnid.ip_version));
+ memcpy(&(rnid.udp_port), &(info.UDPPort), sizeof (rnid.udp_port));
+ memcpy(&(rnid.ip_addr), &info.IPAddress, sizeof (rnid.ip_addr));
+ memcpy(&(rnid.topo_flags), &(info.TopologyDiscoveryFlags),
+ sizeof (rnid.topo_flags));
+
+ fp_ioctl(getPath(), FCIO_CMD, &fcio, O_NDELAY | O_RDONLY | O_EXCL);
+}
+
+void FCHBAPort::fp_ioctl(string path, int cmd, fcio_t *fcio, int openflag) {
+ Trace log("FCHBAPort::fp_ioctl with openflag");
+ char fcioErrorString[MAX_FCIO_MSG_LEN] = "";
+ int fd = HBA::_open(path, openflag);
+ try {
+ int times = 0;
+ HBA::_ioctl(fd, cmd, (uchar_t *)fcio);
+ while (fcio->fcio_errno == FC_STATEC_BUSY) {
+ sleep(1);
+ HBA::_ioctl(fd, cmd, (uchar_t *)fcio);
+ if (times++ > 10) {
+ break;
+ }
+ }
+ close(fd);
+ if (fcio->fcio_errno) {
+ throw IOError("IOCTL transport failure");
+ }
+ } catch (...) {
+ close(fd);
+ transportError(fcio->fcio_errno, fcioErrorString);
+ log.genericIOError("ioctl (0x%x) failed. Transport: \"%s\"", cmd,
+ fcioErrorString);
+ switch (fcio->fcio_errno) {
+ case FC_BADWWN:
+ throw IllegalWWNException();
+ case FC_BADPORT:
+ throw IllegalWWNException();
+ case FC_OUTOFBOUNDS:
+ throw IllegalIndexException();
+ case FC_PBUSY:
+ case FC_FBUSY:
+ case FC_TRAN_BUSY:
+ case FC_STATEC_BUSY:
+ case FC_DEVICE_BUSY:
+ throw BusyException();
+ case FC_SUCCESS:
+ default:
+ throw;
+ }
+ }
+}
+
+void FCHBAPort::fp_ioctl(string path, int cmd, fcio_t *fcio) {
+ Trace log("FCHBAPort::fp_ioctl");
+ fp_ioctl(path, cmd, fcio, O_NDELAY | O_RDONLY);
+}
+
+void FCHBAPort::fcsm_ioctl(int cmd, fcio_t *fcio) {
+ // We use the same error handling as fp, so just re-use
+ fp_ioctl(FCSM_DRIVER_PATH, cmd, fcio);
+}
diff --git a/usr/src/lib/sun_fc/common/FCHBAPort.h b/usr/src/lib/sun_fc/common/FCHBAPort.h
new file mode 100644
index 0000000000..3198942d4d
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/FCHBAPort.h
@@ -0,0 +1,149 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _FCHBAPORT_H
+#define _FCHBAPORT_H
+
+
+
+#include <Lockable.h>
+#include <HBAPort.h>
+#include <Exceptions.h>
+#include <string>
+#include <hbaapi.h>
+#include <sys/param.h>
+#include <sys/fibre-channel/fcio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Represents a single HBA port
+ */
+class FCHBAPort : public HBAPort {
+public:
+ FCHBAPort(std::string path);
+ virtual std::string getPath()
+ { return path; }
+ virtual uint64_t getNodeWWN()
+ { return nodeWWN; }
+ virtual uint64_t getPortWWN()
+ { return portWWN; }
+ virtual HBA_PORTATTRIBUTES getPortAttributes(
+ uint64_t &stateChange);
+ virtual HBA_PORTNPIVATTRIBUTES getPortNPIVAttributes(
+ uint64_t &stateChange);
+ virtual uint32_t createNPIVPort(
+ uint64_t vnodewwn,
+ uint64_t vportwwn,
+ uint32_t vindex);
+ virtual uint32_t deleteNPIVPort(
+ uint64_t vportwwn);
+ virtual HBA_PORTATTRIBUTES getDiscoveredAttributes(
+ HBA_UINT32 discoveredport,
+ uint64_t &stateChange);
+ virtual HBA_PORTATTRIBUTES getDiscoveredAttributes(
+ uint64_t wwn,
+ uint64_t &stateChange);
+ virtual void getTargetMappings(
+ PHBA_FCPTARGETMAPPINGV2 userMappings);
+ virtual void getRNIDMgmtInfo(PHBA_MGMTINFO info);
+ virtual void sendCTPassThru(void *requestBuffer,
+ HBA_UINT32 requestSize,
+ void *responseBuffer,
+ HBA_UINT32 *responseSize);
+ virtual void sendRLS(uint64_t destWWN,
+ void *pRspBuffer,
+ HBA_UINT32 *pRspBufferSize);
+ virtual void sendRPL(uint64_t destWWN,
+ HBA_UINT32 agent_domain,
+ HBA_UINT32 port_index,
+ void *pRspBuffer,
+ HBA_UINT32 *pRspBufferSize) {
+ throw NotSupportedException(); }
+ virtual void sendRPS(uint64_t agentWWN,
+ HBA_UINT32 agentDomain,
+ uint64_t objectWWN,
+ HBA_UINT32 objectPortNum,
+ void *pRspBuffer,
+ HBA_UINT32 *pRspBufferSize) {
+ throw NotSupportedException(); }
+ virtual void sendSRL(uint64_t destWWN,
+ HBA_UINT32 agent_domain,
+ void *pRspBuffer,
+ HBA_UINT32 *pRspBufferSize) {
+ throw NotSupportedException(); }
+ virtual void sendLIRR(uint64_t destWWN,
+ HBA_UINT8 function,
+ HBA_UINT8 type,
+ void *pRspBuffer,
+ HBA_UINT32 *pRspBufferSize) {
+ throw NotSupportedException(); }
+ virtual void sendReportLUNs(uint64_t wwn,
+ void *responseBuffer, HBA_UINT32 *responseSize,
+ HBA_UINT8 *scsiStatus,
+ void *senseBuffer, HBA_UINT32 *senseSize);
+ virtual void sendScsiInquiry(uint64_t wwn, HBA_UINT64 fcLun,
+ HBA_UINT8 cdb1, HBA_UINT8 cdb2,
+ void *responseBuffer, HBA_UINT32 *responseSize,
+ HBA_UINT8 *scsiStatus, void *senseBuffer,
+ HBA_UINT32 *senseSize);
+ virtual void sendReadCapacity(uint64_t pwwn,
+ HBA_UINT64 fcLun, void *responseBuffer,
+ HBA_UINT32 *responseSize, HBA_UINT8 *scsiStatus,
+ void *senseBuffer, HBA_UINT32 *senseSize);
+ virtual void sendRNID(uint64_t destwwn, HBA_UINT32 destfcid,
+ HBA_UINT32 nodeIdDataFormat, void *pRspBuffer,
+ HBA_UINT32 *RspBufferSize);
+ virtual void setRNID(HBA_MGMTINFO info);
+
+
+private:
+ std::string path;
+ uint64_t portWWN;
+ uint64_t nodeWWN;
+ uint32_t instanceNumber;
+ int controllerNumber;
+ void sendSCSIPassThru(struct fcp_scsi_cmd *fscsi,
+ HBA_UINT32 *responseSize, HBA_UINT32 *senseSize,
+ HBA_UINT8 *scsiStatus);
+ static const std::string FCSM_DRIVER_PATH;
+ static const int MAX_FCIO_MSG_LEN;
+ static const std::string FCP_DRIVER_PATH;
+ static void transportError(uint32_t fcio_errno, char *message);
+
+ // Wrapper routines to handle error cases
+ static void fp_ioctl(std::string path, int cmd, fcio_t *arg);
+ static void fp_ioctl(std::string path, int cmd, fcio_t *arg,
+ int openflag);
+ static void fcsm_ioctl(int cmd, fcio_t *arg);
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _FCHBAPORT_H */
diff --git a/usr/src/lib/sun_fc/common/FCSyseventBridge.cc b/usr/src/lib/sun_fc/common/FCSyseventBridge.cc
new file mode 100644
index 0000000000..3b15d5e8db
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/FCSyseventBridge.cc
@@ -0,0 +1,552 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "FCSyseventBridge.h"
+#include "Exceptions.h"
+#include "Trace.h"
+#include "AdapterAddEvent.h"
+#include "AdapterEvent.h"
+#include "AdapterPortEvent.h"
+#include "AdapterDeviceEvent.h"
+#include "TargetEvent.h"
+#include "sun_fc.h"
+#include <libnvpair.h>
+#include <iostream>
+
+using namespace std;
+
+FCSyseventBridge* FCSyseventBridge::_instance = NULL;
+
+FCSyseventBridge* FCSyseventBridge::getInstance() {
+ Trace log("FCSyseventBridge::getInstance");
+ if (_instance == NULL) {
+ _instance = new FCSyseventBridge();
+ }
+ return (_instance);
+
+}
+
+
+void FCSyseventBridge::addListener(AdapterAddEventListener *listener) {
+ lock();
+ try {
+ adapterAddEventListeners.insert(adapterAddEventListeners.begin(),
+ listener);
+ validateRegistration();
+ unlock();
+ } catch (...) {
+ unlock();
+ throw;
+ }
+}
+void FCSyseventBridge::addListener(AdapterEventListener *listener, HBA *hba) {
+ lock();
+ try {
+ adapterEventListeners.insert(adapterEventListeners.begin(), listener);
+ validateRegistration();
+ unlock();
+ } catch (...) {
+ unlock();
+ throw;
+ }
+}
+void FCSyseventBridge::addListener(AdapterPortEventListener *listener,
+ HBAPort *port) {
+ lock();
+ try {
+ adapterPortEventListeners.insert(adapterPortEventListeners.begin(),
+ listener);
+ validateRegistration();
+ unlock();
+ } catch (...) {
+ unlock();
+ throw;
+ }
+}
+void FCSyseventBridge::addListener(AdapterDeviceEventListener *listener,
+ HBAPort *port) {
+ lock();
+ try {
+ adapterDeviceEventListeners.insert(adapterDeviceEventListeners.begin(),
+ listener);
+ validateRegistration();
+ unlock();
+ } catch (...) {
+ unlock();
+ throw;
+ }
+}
+void FCSyseventBridge::addListener(TargetEventListener *listener,
+ HBAPort *port, uint64_t targetWWN, bool filter) {
+ lock();
+ try {
+ targetEventListeners.insert(targetEventListeners.begin(), listener);
+ validateRegistration();
+ unlock();
+ } catch (...) {
+ unlock();
+ throw;
+ }
+}
+
+void FCSyseventBridge::removeListener(AdapterAddEventListener *listener) {
+ lock();
+ try {
+ typedef vector<AdapterAddEventListener *>::iterator Iter;
+ for (Iter tmp = adapterAddEventListeners.begin();
+ tmp != adapterAddEventListeners.end(); tmp++) {
+ if (*tmp == listener) {
+ adapterAddEventListeners.erase(tmp);
+ unlock();
+ return;
+ }
+ }
+ throw InvalidHandleException();
+ } catch (...) {
+ unlock();
+ throw;
+ }
+}
+
+void FCSyseventBridge::removeListener(AdapterEventListener *listener) {
+ lock();
+ try {
+ typedef vector<AdapterEventListener *>::iterator Iter;
+ for (Iter tmp = adapterEventListeners.begin();
+ tmp != adapterEventListeners.end(); tmp++) {
+ if (*tmp == listener) {
+ adapterEventListeners.erase(tmp);
+ unlock();
+ return;
+ }
+ }
+ throw InvalidHandleException();
+ } catch (...) {
+ unlock();
+ throw;
+ }
+}
+
+void FCSyseventBridge::removeListener(AdapterPortEventListener *listener) {
+ lock();
+ try {
+ typedef vector<AdapterPortEventListener *>::iterator Iter;
+ for (Iter tmp = adapterPortEventListeners.begin();
+ tmp != adapterPortEventListeners.end(); tmp++) {
+ if (*tmp == listener) {
+ adapterPortEventListeners.erase(tmp);
+ unlock();
+ return;
+ }
+ }
+ throw InvalidHandleException();
+ } catch (...) {
+ unlock();
+ throw;
+ }
+}
+
+void FCSyseventBridge::removeListener(AdapterDeviceEventListener *listener) {
+ lock();
+ try {
+ typedef vector<AdapterDeviceEventListener *>::iterator Iter;
+ for (Iter tmp = adapterDeviceEventListeners.begin();
+ tmp != adapterDeviceEventListeners.end(); tmp++) {
+ if (*tmp == listener) {
+ adapterDeviceEventListeners.erase(tmp);
+ unlock();
+ return;
+ }
+ }
+ throw InvalidHandleException();
+ } catch (...) {
+ unlock();
+ throw;
+ }
+}
+
+void FCSyseventBridge::removeListener(TargetEventListener *listener) {
+ lock();
+ try {
+ typedef vector<TargetEventListener *>::iterator Iter;
+ for (Iter tmp = targetEventListeners.begin();
+ tmp != targetEventListeners.end(); tmp++) {
+ if (*tmp == listener) {
+ targetEventListeners.erase(tmp);
+ unlock();
+ return;
+ }
+ }
+ throw InvalidHandleException();
+ } catch (...) {
+ unlock();
+ throw;
+ }
+}
+
+extern "C" void static_dispatch(sysevent_t *ev) {
+ Trace log("static_dispatch");
+ FCSyseventBridge::getInstance()->dispatch(ev);
+}
+
+void FCSyseventBridge::dispatch(sysevent_t *ev) {
+ Trace log("FCSyseventBridge::dispatch");
+ nvlist_t *list = NULL;
+ hrtime_t when;
+
+ if (ev == NULL) {
+ log.debug("Null event.");
+ return;
+ }
+
+ if (sysevent_get_attr_list(ev, &list) || list == NULL) {
+ log.debug("Empty event.");
+ return;
+ }
+
+ string eventVendor = sysevent_get_vendor_name(ev);
+ string eventPublisher = sysevent_get_pub_name(ev);
+ string eventClass = sysevent_get_class_name(ev);
+ string eventSubClass = sysevent_get_subclass_name(ev);
+
+ sysevent_get_time(ev, &when);
+
+ // Now that we know what type of event it is, handle it accordingly
+ if (eventClass == "EC_sunfc") {
+
+ // All events of this class type have instance and port-wwn for
+ // the HBA port.
+ uint32_t instance;
+ if (nvlist_lookup_uint32(list, (char *)"instance",
+ &instance)) {
+ log.genericIOError(
+ "Improperly formed event: no instance field.");
+ nvlist_free(list);
+ return;
+ }
+ uchar_t *rawPortWWN;
+ uint32_t rawPortWWNLength;
+
+ if (nvlist_lookup_byte_array(list, (char *)"port-wwn",
+ &rawPortWWN, &rawPortWWNLength)) {
+ log.genericIOError(
+ "Improperly formed event: no port-wwn field.");
+ nvlist_free(list);
+ return;
+ }
+
+ // Now deal with the specific details of each subclass type
+ if (eventSubClass == "ESC_sunfc_port_offline") {
+
+ // Create event instance
+ AdapterPortEvent event(
+ wwnConversion(rawPortWWN),
+ AdapterPortEvent::OFFLINE,
+ 0);
+
+ // Dispatch to interested parties.
+ lock();
+ try {
+ typedef vector<AdapterPortEventListener *>::iterator Iter;
+ for (Iter tmp = adapterPortEventListeners.begin();
+ tmp != adapterPortEventListeners.end(); tmp++) {
+ (*tmp)->dispatch(event);
+ }
+ } catch (...) {
+ unlock();
+ nvlist_free(list);
+ throw;
+ }
+ unlock();
+
+ } else if (eventSubClass == "ESC_sunfc_port_online") {
+
+ // Create event instance
+ AdapterPortEvent event(
+ wwnConversion(rawPortWWN),
+ AdapterPortEvent::ONLINE,
+ 0);
+
+ // Dispatch to interested parties.
+ lock();
+ try {
+ typedef vector<AdapterPortEventListener *>::iterator Iter;
+ for (Iter tmp = adapterPortEventListeners.begin();
+ tmp != adapterPortEventListeners.end(); tmp++) {
+ (*tmp)->dispatch(event);
+ }
+ } catch (...) {
+ unlock();
+ nvlist_free(list);
+ throw;
+ }
+ unlock();
+
+ } else if (eventSubClass == "ESC_sunfc_device_online") {
+ AdapterDeviceEvent event(
+ wwnConversion(rawPortWWN),
+ AdapterDeviceEvent::ONLINE,
+ 0);
+ lock();
+ try {
+ typedef vector<AdapterDeviceEventListener *>::iterator Iter;
+ for (Iter tmp = adapterDeviceEventListeners.begin();
+ tmp != adapterDeviceEventListeners.end(); tmp++) {
+ (*tmp)->dispatch(event);
+ }
+ } catch (...) {
+ unlock();
+ nvlist_free(list);
+ throw;
+ }
+ unlock();
+
+ } else if (eventSubClass == "ESC_sunfc_device_offline") {
+ AdapterDeviceEvent event(
+ wwnConversion(rawPortWWN),
+ AdapterDeviceEvent::OFFLINE,
+ 0);
+ lock();
+ try {
+ typedef vector<AdapterDeviceEventListener *>::iterator Iter;
+ for (Iter tmp = adapterDeviceEventListeners.begin();
+ tmp != adapterDeviceEventListeners.end(); tmp++) {
+ (*tmp)->dispatch(event);
+ }
+ } catch (...) {
+ unlock();
+ nvlist_free(list);
+ throw;
+ }
+ unlock();
+
+ } else if (eventSubClass == "ESC_sunfc_port_rscn") {
+ /*
+ * RSCNs are a little tricky. There can be multiple
+ * affected page properties, each numbered. To make sure
+ * we get them all, we loop through all properties
+ * in the nvlist and if their name begins with "affected_page_"
+ * then we send an event for them.
+ */
+ uint32_t affected_page;
+ nvpair_t *attr = NULL;
+ for (attr = nvlist_next_nvpair(list, NULL);
+ attr != NULL;
+ attr = nvlist_next_nvpair(list, attr)) {
+ string name = nvpair_name(attr);
+ if (name.find("affected_page_") != name.npos) {
+
+ if (nvpair_value_uint32(attr, &affected_page)) {
+ log.genericIOError(
+ "Improperly formed event: "
+ "corrupt affected_page field");
+ continue;
+ }
+ // Create event instance
+ AdapterPortEvent event(
+ wwnConversion(rawPortWWN),
+ AdapterPortEvent::FABRIC,
+ affected_page);
+
+ // Dispatch to interested parties.
+ lock();
+ typedef vector<AdapterPortEventListener *>::iterator Iter;
+ try {
+ for (Iter tmp = adapterPortEventListeners.begin();
+ tmp != adapterPortEventListeners.end(); tmp++) {
+ (*tmp)->dispatch(event);
+ }
+ } catch (...) {
+ unlock();
+ nvlist_free(list);
+ throw;
+ }
+ unlock();
+ }
+ }
+ } else if (eventSubClass == "ESC_sunfc_target_add") {
+ uchar_t *rawTargetPortWWN;
+ uint32_t rawTargetPortWWNLength;
+
+ if (nvlist_lookup_byte_array(list, (char *)"target-port-wwn",
+ &rawTargetPortWWN, &rawTargetPortWWNLength)) {
+ log.genericIOError(
+ "Improperly formed event: no target-port-wwn field.");
+ nvlist_free(list);
+ return;
+ }
+
+ // Create event instance
+ AdapterPortEvent event(
+ wwnConversion(rawPortWWN),
+ AdapterPortEvent::NEW_TARGETS,
+ 0);
+
+ // Dispatch to interested parties.
+ lock();
+ try {
+ typedef vector<AdapterPortEventListener *>::iterator Iter;
+ for (Iter tmp = adapterPortEventListeners.begin();
+ tmp != adapterPortEventListeners.end(); tmp++) {
+ (*tmp)->dispatch(event);
+ }
+ } catch (...) {
+ unlock();
+ nvlist_free(list);
+ throw;
+ }
+ unlock();
+ } else if (eventSubClass == "ESC_sunfc_target_remove") {
+ uchar_t *rawTargetPortWWN;
+ uint32_t rawTargetPortWWNLength;
+
+ if (nvlist_lookup_byte_array(list, (char *)"target-port-wwn",
+ &rawTargetPortWWN, &rawTargetPortWWNLength)) {
+ log.genericIOError(
+ "Improperly formed event: no target-port-wwn field.");
+ nvlist_free(list);
+ return;
+ }
+ // Create event instance
+ TargetEvent event(
+ wwnConversion(rawPortWWN),
+ wwnConversion(rawTargetPortWWN),
+ TargetEvent::REMOVED);
+
+ // Dispatch to interested parties.
+ lock();
+ try {
+ typedef vector<TargetEventListener *>::iterator Iter;
+ for (Iter tmp = targetEventListeners.begin();
+ tmp != targetEventListeners.end(); tmp++) {
+ (*tmp)->dispatch(event);
+ }
+ } catch (...) {
+ unlock();
+ nvlist_free(list);
+ throw;
+ }
+ unlock();
+ } else if (eventSubClass == "ESC_sunfc_port_attach") {
+ // Create event instance
+ AdapterAddEvent event(wwnConversion(rawPortWWN));
+ // Dispatch to interested parties.
+ lock();
+ try {
+ typedef vector<AdapterAddEventListener *>::iterator Iter;
+ for (Iter tmp = adapterAddEventListeners.begin();
+ tmp != adapterAddEventListeners.end(); tmp++) {
+ (*tmp)->dispatch(event);
+ }
+ } catch (...) {
+ unlock();
+ nvlist_free(list);
+ throw;
+ }
+ unlock();
+ } else if (eventSubClass == "ESC_sunfc_port_detach") {
+ // Technically, we should probably try to coalesce
+ // all detach events for the same multi-ported adapter
+ // and only send one event to the client, but for now,
+ // we'll just blindly send duplicates.
+
+ // Create event instance
+ AdapterEvent event(
+ wwnConversion(rawPortWWN),
+ AdapterEvent::REMOVE);
+
+ // Dispatch to interested parties.
+ lock();
+ try {
+ typedef vector<AdapterEventListener *>::iterator Iter;
+ for (Iter tmp = adapterEventListeners.begin();
+ tmp != adapterEventListeners.end(); tmp++) {
+ (*tmp)->dispatch(event);
+ }
+ } catch (...) {
+ unlock();
+ nvlist_free(list);
+ throw;
+ }
+ unlock();
+
+ } else {
+ log.genericIOError(
+ "Unrecognized subclass \"%s\": Ignoring event",
+ eventSubClass.c_str());
+ }
+ } else {
+ // This should not happen, as we only asked for specific classes.
+ log.genericIOError(
+ "Unrecognized class \"%s\": Ignoring event",
+ eventClass.c_str());
+ }
+ nvlist_free(list);
+}
+
+void FCSyseventBridge::validateRegistration() {
+ Trace log("FCSyseventBridge::validateRegistration");
+ uint64_t count = 0;
+ count = adapterAddEventListeners.size() +
+ adapterEventListeners.size() +
+ adapterPortEventListeners.size() +
+ targetEventListeners.size();
+ if (count == 1) {
+ handle = sysevent_bind_handle(static_dispatch);
+ if (handle == NULL) {
+ log.genericIOError(
+ "Unable to bind sysevent handle.");
+ return;
+ }
+ const char *subclass_list[9] = {
+ "ESC_sunfc_port_attach",
+ "ESC_sunfc_port_detach",
+ "ESC_sunfc_port_offline",
+ "ESC_sunfc_port_online",
+ "ESC_sunfc_port_rscn",
+ "ESC_sunfc_target_add",
+ "ESC_sunfc_target_remove",
+ "ESC_sunfc_device_online",
+ "ESC_sunfc_device_offline"
+ };
+ if (sysevent_subscribe_event(handle,
+ "EC_sunfc", (const char **)subclass_list, 9)) {
+ log.genericIOError(
+ "Unable to subscribe to sun_fc events.");
+ sysevent_unbind_handle(handle);
+ handle = NULL;
+ }
+ } else if (count == 0 && handle != NULL) {
+ // Remove subscription
+ sysevent_unbind_handle(handle);
+ handle == NULL;
+ } // Else do nothing
+}
+
+int32_t FCSyseventBridge::getMaxListener() {
+ return (INT_MAX);
+}
diff --git a/usr/src/lib/sun_fc/common/FCSyseventBridge.h b/usr/src/lib/sun_fc/common/FCSyseventBridge.h
new file mode 100644
index 0000000000..43fa400e43
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/FCSyseventBridge.h
@@ -0,0 +1,94 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _FCSYSEVENTBRIDGE_H
+#define _FCSYSEVENTBRIDGE_H
+
+
+
+#include "AdapterAddEventBridge.h"
+#include "AdapterEventBridge.h"
+#include "AdapterPortEventBridge.h"
+#include "AdapterDeviceEventBridge.h"
+#include "TargetEventBridge.h"
+#include "Lockable.h"
+#include <vector>
+#include <libsysevent.h>
+
+/**
+ * Note: Even though we take various arguments in within the API,
+ * we don't actually filter anything, since sys-even is either on
+ * or off. The idea is that the actual Listener themselves will perform
+ * a final filter pass, so why do the work twice. If we were going to
+ * use proprietary IOCTLs or some other event plumbing that allowed filtering,
+ * we could use the passed in arguments to do useful work. In short,
+ * once turned on, we send events of a given type and rely on
+ * someone downstream to filter.
+ */
+class FCSyseventBridge :
+ public AdapterAddEventBridge,
+ public AdapterEventBridge,
+ public AdapterPortEventBridge,
+ public AdapterDeviceEventBridge,
+ public TargetEventBridge,
+ public Lockable {
+public:
+ static FCSyseventBridge* getInstance();
+ virtual int32_t getMaxListener();
+ virtual void addListener(AdapterAddEventListener *listener);
+ virtual void addListener(AdapterEventListener *listener, HBA *hba);
+ virtual void addListener(AdapterPortEventListener *listener, HBAPort *port);
+ virtual void addListener(AdapterDeviceEventListener *listener,
+ HBAPort *port);
+ virtual void addListener(TargetEventListener *listener,
+ HBAPort *port, uint64_t targetWWN, bool filter);
+ virtual void removeListener(AdapterAddEventListener *listener);
+ virtual void removeListener(AdapterEventListener *listener);
+ virtual void removeListener(AdapterPortEventListener *listener);
+ virtual void removeListener(AdapterDeviceEventListener *listener);
+ virtual void removeListener(TargetEventListener *listener);
+
+ /* Private function, called by handler. Friend maybe? */
+ void dispatch(sysevent_t *ev);
+
+private:
+ FCSyseventBridge() :handle(NULL) { }
+ /**
+ * Subscribe if we need to, or unsubscribe if nobody is left
+ * Instance lock must already be held!
+ */
+ void validateRegistration();
+ sysevent_handle_t *handle;
+ static FCSyseventBridge* _instance;
+
+
+ std::vector<AdapterAddEventListener*> adapterAddEventListeners;
+ std::vector<AdapterEventListener*> adapterEventListeners;
+ std::vector<AdapterPortEventListener*> adapterPortEventListeners;
+ std::vector<AdapterDeviceEventListener*> adapterDeviceEventListeners;
+ std::vector<TargetEventListener*> targetEventListeners;
+};
+
+#endif /* _FCSYSEVENTBRIDGE_H */
diff --git a/usr/src/lib/sun_fc/common/HBA.cc b/usr/src/lib/sun_fc/common/HBA.cc
new file mode 100644
index 0000000000..8bba2c59c3
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/HBA.cc
@@ -0,0 +1,357 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "HBA.h"
+#include "Exceptions.h"
+#include "Trace.h"
+#include <iostream>
+#include <iomanip>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stropts.h>
+#include <errno.h>
+
+#define NSECS_PER_SEC 1000000000l
+#define BUSY_SLEEP NSECS_PER_SEC/10 /* 1/10 second */
+#define BUSY_RETRY_TIMER 3000000000UL /* Retry for 3 seconds */
+
+using namespace std;
+
+/**
+ * Max number of Adatper ports per HBA that VSL supports.
+ *
+ */
+const uint8_t HBA::HBA_PORT_MAX = UCHAR_MAX;
+
+/**
+ * @memo Add a new port to this HBA
+ * @precondition Port must be a valid port on this HBA
+ * @postcondition Port will be exposed as one of the ports on this HBA
+ * @exception Throws InternalError when the HBA port count exceeds
+ * max number of ports and throws any underlying exception
+ * @param port The Port to add to this HBA
+ *
+ * @doc When discovering HBAs and their ports, use this
+ * routine to add a port to its existing HBA instance.
+ */
+void HBA::addPort(HBAPort* port) {
+ Trace log("HBA::addPort");
+ lock();
+ // support hba with up to UCHAR_MAX number of ports.
+ if (portsByIndex.size() + 1 > HBA_PORT_MAX) {
+ unlock();
+ throw InternalError("HBA Port count exceeds max number of ports");
+ }
+
+ try {
+ portsByWWN[port->getPortWWN()] = port;
+ portsByIndex.insert(portsByIndex.end(), port);
+ unlock();
+ } catch (...) {
+ unlock();
+ throw;
+ }
+}
+
+/**
+ * @memo Return number of ports to this HBA
+ * @exception No exception for this method.
+ *
+ * @doc Returns the number of ports on this HBA. The max
+ * number of ports that VSL support is up to max uint8_t
+ * size.
+ */
+uint8_t HBA::getNumberOfPorts() {
+ Trace log("HBA::getNumberOfPorts");
+ return (uint8_t)portsByIndex.size();
+}
+
+/**
+ * @memo Retrieve an HBA port based on a Port WWN
+ * @exception IllegalWWNException Thrown if WWN does not match any
+ * known HBA port.
+ * @return HBAPort* to the port with a matching Port WWN
+ * @param wwn The wwn of the desired HBA port
+ *
+ * @doc Fetch an HBA port based on WWN. If the port is not
+ * found, an exception will be thrown. NULL will never
+ * be returned.
+ */
+HBAPort* HBA::getPort(uint64_t wwn) {
+ Trace log("HBA::getPort");
+ HBAPort *port = NULL;
+ lock();
+
+ log.debug("getPort(wwn): WWN %016llx", wwn);
+
+ try {
+ // Make sure it is in the map
+ if (portsByWWN.find(wwn) == portsByWWN.end()) {
+ throw IllegalWWNException();
+ }
+ port = portsByWWN[wwn];
+ unlock();
+ return (port);
+ } catch (...) {
+ unlock();
+ throw;
+ }
+}
+
+/**
+ * Iterator for WWN to HBAPort map type
+ */
+typedef map<uint64_t, HBAPort *>::const_iterator CI;
+
+/**
+ * @memo Return true if this HBA contains the stated WWN
+ * (node or port)
+ * @exception ... underlying exceptions will be thrown
+ * @return TRUE if the wwn is found
+ * @return FALSE if the wwn is not found
+ * @param wwn The wwn to look for
+ *
+ */
+bool HBA::containsWWN(uint64_t wwn) {
+ Trace log("HBA::containsWWN");
+ lock();
+
+ try {
+ for (CI port = portsByWWN.begin(); port != portsByWWN.end();
+ port++) {
+ if (port->second->getPortWWN() == wwn) {
+ unlock();
+ return (true);
+ }
+ if (port->second->getNodeWWN() == wwn) {
+ unlock();
+ return (true);
+ }
+ }
+ unlock();
+ return (false);
+ } catch (...) {
+ unlock();
+ throw;
+ }
+}
+
+/**
+ * @memo Fetch the port based on index.
+ * @exception IllegalIndexException Thrown if the index is not valid
+ * @return HBAPort* the port matching the index
+ * @param index - the zero based index of the port to retrieve
+ *
+ */
+HBAPort* HBA::getPortByIndex(int index) {
+ Trace log("HBA::getPortByIndex");
+ lock();
+ try {
+ log.debug("Port index size %d index %d ", portsByIndex.size(),
+ index);
+
+ if (index >= portsByIndex.size() || index < 0) {
+ throw IllegalIndexException();
+ }
+
+ HBAPort *tmp = portsByIndex[index];
+ unlock();
+ return (tmp);
+ } catch (...) {
+ unlock();
+ throw;
+ }
+}
+
+/**
+ * @memo Compare two HBAs for equality
+ * @precondition Both HBAs should be fully discovered (all ports added)
+ * @exception ... underlying exceptions will be thrown
+ * @return TRUE The two HBA instances represent the same HBA
+ * @return FALSE The two HBA instances are different
+ *
+ * @doc This routine will compare each port within both
+ * HBAs and verify they are the same. The ports must
+ * have been added in the same order.
+ */
+bool HBA::operator==(HBA &comp) {
+ Trace log("HBA::operator==");
+ lock();
+
+ try {
+ bool ret = false;
+ if (portsByIndex.size() == comp.portsByIndex.size()) {
+ if (portsByIndex.size() > 0) {
+ ret = (*portsByIndex[0] == *comp.portsByIndex[0]);
+ }
+ }
+ unlock();
+ return (ret);
+ } catch (...) {
+ unlock();
+ throw;
+ }
+}
+
+/**
+ * @memo Set the RNID data for all the ports in this HBA
+ * @precondition All ports must be added
+ * @postcondition Each port will have the same RNID value set
+ * @exception ... underlying exceptions will be thrown. Partial failure
+ * is possible and will not be cleaned up.
+ * @param info The RNID information to program for each HBA port
+ * @see HBAPort::setRNID
+ *
+ */
+void HBA::setRNID(HBA_MGMTINFO info) {
+ Trace log("HBA::setRNID");
+ lock();
+
+ try {
+ for (CI port = portsByWWN.begin(); port != portsByWWN.end();
+ port++) {
+ port->second->setRNID(info);
+ }
+ unlock();
+ } catch (...) {
+ unlock();
+ throw;
+ }
+}
+
+/**
+ * @memo Verify that this HBA is present on the system
+ * @exception UnavailableException Thrown when HBA not present
+ * @see HBAPort::validatePresent
+ *
+ * @doc This routine is used to verify that a given HBA
+ * has not been removed through dynamic reconfiguration.
+ * If the HBA is present, the routine will return.
+ * If the HBA is not present (if any port is not present)
+ * an exception will be thrown
+ */
+void HBA::validatePresent() {
+ Trace log("HBA::validatePresent");
+ lock();
+ try {
+ for (CI port = portsByWWN.begin(); port != portsByWWN.end();
+ port++) {
+ port->second->validatePresent();
+ }
+ unlock();
+ } catch (...) {
+ unlock();
+ throw;
+ }
+}
+
+/**
+ * Opens a file, throwing exceptions on error.
+ */
+int HBA::_open(std::string path, int flag) {
+ Trace log("HBA::open");
+ int fd;
+ errno = 0;
+ if ((fd = open(path.c_str(), flag)) < 0) {
+ log.debug("Unable to open \"%s\" - reason (%d) %s",
+ path.c_str(), errno, strerror(errno));
+ if (errno == EBUSY) {
+ throw BusyException();
+ } else if (errno == EAGAIN) {
+ throw TryAgainException();
+ } else if (errno == ENOTSUP) {
+ throw NotSupportedException();
+ } else if (errno == ENOENT) {
+ throw UnavailableException();
+ } else {
+ string msg = "Unable to open ";
+ msg += path;
+ throw IOError(msg);
+ }
+ }
+ return (fd);
+}
+
+/**
+ * Issues IOCTL, throwing exceptions on error.
+ * Note, if the IOCTL succeeds, but some IOCTL specific
+ * error is recorded in the response, this routine
+ * will not throw an exception.
+ */
+void HBA::_ioctl(int fd, int type, uchar_t *arg) {
+ Trace log("HBA::ioctl");
+ hrtime_t cur;
+ int saved_errno = 0;
+ struct timespec ts;
+
+ errno = 0;
+ hrtime_t start = gethrtime();
+ hrtime_t end = start + BUSY_RETRY_TIMER;
+ ts.tv_sec = 0;
+ ts.tv_nsec = BUSY_SLEEP;
+ for (cur = start; cur < end; cur = gethrtime()) {
+ if (ioctl(fd, type, arg) != 0) {
+ if (errno == EAGAIN) {
+ saved_errno = errno;
+ nanosleep(&ts, NULL);
+ continue;
+ } else if (errno == EBUSY) {
+ saved_errno = errno;
+ nanosleep(&ts, NULL);
+ continue;
+ } else if (errno == ENOTSUP) {
+ throw NotSupportedException();
+ } else if (errno == ENOENT) {
+ throw UnavailableException();
+ } else {
+ throw IOError("IOCTL failed");
+ }
+ } else {
+ break;
+ }
+ }
+ if (cur >= end) {
+ if (saved_errno == EAGAIN) {
+ throw TryAgainException();
+ } else if (saved_errno == EBUSY) {
+ throw BusyException();
+ } else {
+ throw IOError("IOCTL failed");
+ }
+ }
+}
+
+HBA::~HBA() {
+ Trace log("HBA::~HBA");
+ for (int i = 0; i < getNumberOfPorts(); i++) {
+ delete (getPortByIndex(i));
+ }
+}
+
diff --git a/usr/src/lib/sun_fc/common/HBA.h b/usr/src/lib/sun_fc/common/HBA.h
new file mode 100644
index 0000000000..88505ff4f7
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/HBA.h
@@ -0,0 +1,87 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _HBA_H
+#define _HBA_H
+
+
+
+// Forward declarations
+class HBA;
+class HBAPort;
+
+#include "Lockable.h"
+#include "HBAPort.h"
+#include <map>
+#include <string>
+#include <vector>
+#include <map>
+#include <hbaapi.h>
+#include <hbaapi-sun.h>
+
+
+/*
+ * @memo Used to track an individual HBA
+ * @see HBAList
+ *
+ * @doc During discovery, as HBAs are found on the system,
+ * instances of this class will be created, and stored
+ * in the HBAList class.
+ */
+class HBA : public Lockable {
+public:
+ HBA() {}
+ virtual ~HBA();
+ bool operator == (HBA &comp);
+ static const uint8_t HBA_PORT_MAX;
+ void addPort(HBAPort* port);
+ HBAPort* getPort(uint64_t wwn);
+ bool containsWWN(uint64_t wwn);
+
+ virtual HBA_ADAPTERATTRIBUTES getHBAAttributes() = 0;
+ virtual HBA_ADAPTERATTRIBUTES npivGetHBAAttributes() = 0;
+ void setRNID(HBA_MGMTINFO info);
+ /*
+ * Fetch the name, excluding the trailing "-" and index number
+ */
+ virtual std::string getName() = 0;
+
+ void validatePresent();
+
+ HBAPort* getPortByIndex(int index);
+ uint8_t getNumberOfPorts();
+
+ // Utility routines: Could be moved elsewhere
+ // Each routine throws exceptions on error (and logs)
+ static int _open(std::string path, int flag);
+ static void _ioctl(int fd, int type, uchar_t *arg);
+
+private:
+ std::map<uint64_t, HBAPort *> portsByWWN;
+ std::vector<HBAPort*> portsByIndex;
+};
+
+
+#endif /* _HBA_H */
diff --git a/usr/src/lib/sun_fc/common/HBAList.cc b/usr/src/lib/sun_fc/common/HBAList.cc
new file mode 100644
index 0000000000..59a79f6ead
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/HBAList.cc
@@ -0,0 +1,423 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "HBAList.h"
+#include "Exceptions.h"
+#include "Trace.h"
+#include "sun_fc_version.h"
+#include <string>
+#include <sstream>
+#include "FCHBA.h"
+#include "TgtFCHBA.h"
+
+using namespace std;
+
+/**
+ * @memo Private constructor (used to create singleton instance)
+ * @see HBAList::instance
+ */
+HBAList::HBAList() { }
+
+/**
+ * Internal singleton instance
+ */
+HBAList* HBAList::_instance = 0;
+
+/**
+ * Max number of adapters that this class supports.
+ */
+const int32_t HBAList::HBA_MAX_PER_LIST = INT_MAX;
+
+/**
+ * @memo Free up resources held by this HBA list
+ * @postcondition All memory used by this list will be freed
+ * @return HBA_STATUS_OK on success
+ *
+ */
+HBA_STATUS HBAList::unload() {
+ Trace log("HBAList::unload");
+ lock();
+ _instance = NULL;
+ unlock();
+ return (HBA_STATUS_OK);
+}
+
+/**
+ * @memo Fetch the singleton instance
+ * @return The singleton instance
+ *
+ * @doc Only one instance of HBAList must be present
+ * per address space at a time. The singleton design pattern
+ * is used to enforce this behavior.
+ */
+HBAList* HBAList::instance() {
+ Trace log("HBAList::instance");
+ if (_instance == 0) {
+ _instance = new HBAList();
+ }
+ return (_instance);
+}
+
+/**
+ * @memo Fetch an HBA based on name.
+ * Always returns non-null or throw an Exception.
+ * @precondition HBAs must be loaded in the list
+ * @postcondition A handle will be opened. The caller must close the handle
+ * at some later time to prevent leakage.
+ * @exception BadArgumentException if the name is not properly formatted
+ * @exception IllegalIndexException if the name does not match any
+ * present HBAs within this list.
+ * @return A valid handle for future API calls
+ * @param name The name of the HBA to open
+ *
+ * @doc This routine will always return a handle (ie, non null)
+ * or will throw an exception.
+ */
+Handle* HBAList::openHBA(string name) {
+ Trace log("HBAList::openHBA(name)");
+ int index = -1;
+ try {
+ string::size_type offset = name.find_last_of("-");
+ if (offset >= 0) {
+ string indexString = name.substr(offset+1);
+ index = atoi(indexString.c_str());
+ }
+ } catch (...) {
+ throw BadArgumentException();
+ }
+ lock();
+ if (index < 0 || index > hbas.size()) {
+ unlock();
+ throw IllegalIndexException();
+ } else {
+ HBA *tmp = hbas[index];
+ unlock();
+ tmp->validatePresent();
+ return (new Handle(tmp));
+ }
+}
+
+/**
+ * @memo Fetch an target mode FC HBA based on name.
+ * Always returns non-null or throw an Exception.
+ * @precondition Target mode HBAs must be loaded in the list
+ * @postcondition A handle will be opened. The caller must close the handle
+ * at some later time to prevent leakage.
+ * @exception BadArgumentException if the name is not properly formatted
+ * @exception IllegalIndexException if the name does not match any
+ * present HBAs within this list.
+ * @return A valid handle for future API calls
+ * @param name The name of the target mode HBA to open
+ *
+ * @doc This routine will always return a handle (ie, non null)
+ * or will throw an exception.
+ */
+Handle* HBAList::openTgtHBA(string name) {
+ Trace log("HBAList::openHBA(name)");
+ int index = -1;
+ try {
+ string::size_type offset = name.find_last_of("-");
+ if (offset >= 0) {
+ string indexString = name.substr(offset+1);
+ index = atoi(indexString.c_str());
+ }
+ } catch (...) {
+ throw BadArgumentException();
+ }
+ lock();
+ if (index < 0 || index > tgthbas.size()) {
+ unlock();
+ throw IllegalIndexException();
+ } else {
+ HBA *tmp = tgthbas[index];
+ unlock();
+ tmp->validatePresent();
+ return (new Handle(tmp));
+ }
+}
+
+/**
+ * @memo Get the name of an HBA at the given index
+ * @precondition HBAs must be loaded in the list
+ * @exception IllegalIndexException Thrown if the index doesn't match any
+ * HBA in the list
+ * @return The name of the specified HBA
+ * @param index The zero based index of the desired HBA
+ *
+ */
+string HBAList::getHBAName(int index) {
+ Trace log("HBAList::getHBAName");
+ lock();
+ if (index < 0 || index > hbas.size()) {
+ unlock();
+ throw IllegalIndexException();
+ } else {
+ HBA *tmp = hbas[index];
+ unlock();
+ tmp->validatePresent();
+ char buf[128];
+ snprintf(buf, 128, "%s-%d", tmp->getName().c_str(), index);
+ string name = buf;
+ return (name);
+ }
+}
+
+/**
+ * @memo Get the name of an target mode HBA at the given index
+ * @precondition Target mode HBAs must be loaded in the list
+ * @exception IllegalIndexException Thrown if the index doesn't match any
+ * HBA in the list
+ * @return The name of the specified target mode HBA
+ * @param index The zero based index of the desired target mode HBA
+ *
+ */
+string HBAList::getTgtHBAName(int index) {
+ Trace log("HBAList::getTgtHBAName");
+ lock();
+ if (index < 0 || index > tgthbas.size()) {
+ unlock();
+ throw IllegalIndexException();
+ } else {
+ HBA *tmp = tgthbas[index];
+ unlock();
+ tmp->validatePresent();
+ char buf[128];
+ snprintf(buf, 128, "%s-%d", tmp->getName().c_str(), index);
+ string name = buf;
+ return (name);
+ }
+}
+
+/**
+ * @memo Open an HBA based on a WWN
+ * @precondition HBAs must be loaded in the list
+ * @postcondition A handle will be opened. The caller must close the handle
+ * at some later time to prevent leakage.
+ * @exception IllegalWWNException Thrown if the wwn doesn't match any
+ * HBA in the list
+ * @return A valid Handle for later use by API calls
+ * @param wwn The node or any port WWN of HBA to open
+ * @see HBA::containsWWN
+ *
+ * @doc This routine will accept both Node and Port WWNs based
+ * on the HBA routine containsWWN
+ */
+Handle* HBAList::openHBA(uint64_t wwn) {
+
+ Trace log("HBAList::openHBA(wwn)");
+ lock();
+ HBA *tmp;
+ for (int i = 0; i < hbas.size(); i++) {
+ if (hbas[i]->containsWWN(wwn)) {
+ tmp = hbas[i];
+ unlock();
+ tmp->validatePresent();
+ return (new Handle(tmp));
+ }
+ }
+ unlock();
+ throw IllegalWWNException();
+}
+
+/**
+ * @memo Open an target mode HBA based on a WWN
+ * @precondition Targee mode HBAs must be loaded in the list
+ * @postcondition A handle will be opened. The caller must close the handle
+ * at some later time to prevent leakage.
+ * @exception IllegalWWNException Thrown if the wwn doesn't match any
+ * target mode HBA in the list
+ * @return A valid Handle for later use by API calls
+ * @param The node WWN or any port WWN of target mode HBA to open
+ * @see HBA::containsWWN
+ *
+ * @doc This routine will accept both Node and Port WWNs based
+ * on the HBA routine containsWWN
+ */
+Handle* HBAList::openTgtHBA(uint64_t wwn) {
+
+ Trace log("HBAList::openTgtHBA(wwn)");
+ lock();
+ HBA *tmp;
+ for (int i = 0; i < tgthbas.size(); i++) {
+ if (tgthbas[i]->containsWWN(wwn)) {
+ tmp = tgthbas[i];
+ unlock();
+ tmp->validatePresent();
+ return (new Handle(tmp));
+ }
+ }
+ unlock();
+ throw IllegalWWNException();
+}
+
+/**
+ * @memo Get the number of adapters present in the list
+ * @postcondition List of HBAs will be loaded
+ * @exception ... Underlying exceptions will be thrown
+ * @return The number of adapters in the list
+ *
+ * @doc This routine will triger discovery of HBAs on the system.
+ * It will also handle addition/removal of HBAs in the list
+ * based on dynamic reconfiguration operations. The max
+ * number of HBAs that HBA API supports is up to the
+ * uint32_t size. VSL supports up to int32_t size thus
+ * it gives enough room for the HBA API library
+ * to handle up to max uint32_t number if adapters.
+ */
+int HBAList::getNumberofAdapters() {
+ Trace log("HBAList::getNumberofAdapters");
+ lock();
+
+ try {
+ if (hbas.size() == 0) {
+ // First pass, just store them all blindly
+ FCHBA::loadAdapters(hbas);
+ } else {
+ // Second pass, do the update operation
+ vector<HBA*> tmp;
+ FCHBA::loadAdapters(tmp);
+ bool matched;
+ for (int i = 0; i < tmp.size(); i++) {
+ matched = false;
+ for (int j = 0; j < hbas.size(); j++) {
+ if (*tmp[i] == *hbas[j]) {
+ matched = true;
+ break;
+ }
+ }
+ if (matched) {
+ delete (tmp[i]);
+ } else {
+ hbas.insert(hbas.end(), tmp[i]);
+ }
+ }
+ }
+ } catch (...) {
+ unlock();
+ throw;
+ }
+
+ unlock();
+
+ // When there is more than HBA_MAX_PER_LIST(= int32_max)
+ // VSL returns an error so it is safe to cast it here.
+ return ((uint32_t)hbas.size());
+}
+
+/**
+ * @memo Get the number of target mode adapters present in the list
+ * @postcondition List of TgtHBAs will be loaded
+ * @exception ... Underlying exceptions will be thrown
+ * @return The number of target mode adapters in the list
+ *
+ * @doc This routine will triger discovery of Target mode HBAs on
+ * the system. It will also handle addition/removal of Target
+ * mode HBAs in the list based on dynamic reconfiguration
+ * operations. The max number of target mode HBAs that
+ * HBA API supports is up to the
+ * uint32_t size. VSL supports up to int32_t size thus
+ * it gives enough room for the HBA API library
+ * to handle up to max uint32_t number of adapters.
+ */
+int HBAList::getNumberofTgtAdapters() {
+ Trace log("HBAList::getNumberofTgtAdapters");
+ lock();
+
+ try {
+ if (tgthbas.size() == 0) {
+ // First pass, just store them all blindly
+ TgtFCHBA::loadAdapters(tgthbas);
+ } else {
+ // Second pass, do the update operation
+ vector<HBA*> tmp;
+ TgtFCHBA::loadAdapters(tmp);
+ bool matched;
+ for (int i = 0; i < tmp.size(); i++) {
+ matched = false;
+ for (int j = 0; j < tgthbas.size(); j++) {
+ if (*tmp[i] == *tgthbas[j]) {
+ matched = true;
+ break;
+ }
+ }
+ if (matched) {
+ delete (tmp[i]);
+ } else {
+ tgthbas.insert(tgthbas.end(), tmp[i]);
+ }
+ }
+ }
+ } catch (...) {
+ unlock();
+ throw;
+ }
+
+ unlock();
+
+ // When there is more than HBA_MAX_PER_LIST(= int32_max)
+ // VSL returns an error so it is safe to cast it here.
+ return ((uint32_t)tgthbas.size());
+}
+
+/**
+ * @memo Load the list
+ * @return HBA_STATUS_OK
+ *
+ * @doc Currently this routine is a no-op and may be a cantidate
+ * for removal in the future.
+ */
+HBA_STATUS HBAList::load() {
+ Trace log("HBAList::load");
+
+ // No lock is required since no VSL specific action requried.
+ return (HBA_STATUS_OK);
+}
+
+/**
+ * @memo Free up resources
+ */
+HBAList::~HBAList() {
+ Trace log("HBAList::~HBAList");
+ for (int i = 0; i < hbas.size(); i++) {
+ delete (hbas[i]);
+ }
+ for (int i = 0; i < tgthbas.size(); i++) {
+ delete (tgthbas[i]);
+ }
+}
+
+HBA_LIBRARYATTRIBUTES HBAList::getVSLAttributes() {
+ HBA_LIBRARYATTRIBUTES attrs;
+ char build_time[] = BUILD_TIME;
+ attrs.final = 0;
+ memset(&attrs, 0, sizeof(attrs));
+ strlcpy(attrs.VName, VSL_NAME, sizeof (attrs.VName));
+ strlcpy(attrs.VVersion, VSL_STRING_VERSION, sizeof (attrs.VVersion));
+ strptime(build_time, "%c", &attrs.build_date);
+
+ return (attrs);
+}
diff --git a/usr/src/lib/sun_fc/common/HBAList.h b/usr/src/lib/sun_fc/common/HBAList.h
new file mode 100644
index 0000000000..cf386fcfb5
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/HBAList.h
@@ -0,0 +1,79 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _HBALIST_H
+#define _HBALIST_H
+
+
+
+#include "Lockable.h"
+#include "HBA.h"
+#include "Handle.h"
+#include <vector>
+#include <string>
+#include <hbaapi.h>
+
+/**
+ * @memo Singleton class that represents the entire list of HBAs
+ * known to the system.
+ *
+ * @doc This class and its single instance is used to track
+ * all the known HBAs on the system. This class
+ * will gracefully handle dynamic reconfiguration
+ * in accordance with the FC-HBA specification.
+ * HBA_MAX_PER_LIST represents the maximum number of
+ * adapters that are supported by this class.
+ */
+class HBAList : public Lockable{
+public:
+ static HBAList* instance();
+ ~HBAList();
+ static const int32_t HBA_MAX_PER_LIST;
+ HBA_STATUS load();
+ HBA_STATUS unload();
+ int getNumberofAdapters();
+ int getNumberofTgtAdapters();
+ std::string getHBAName(int index);
+ std::string getTgtHBAName(int index);
+ Handle* openHBA(std::string name);
+ Handle* openTgtHBA(std::string name);
+ Handle* openHBA(uint64_t wwn);
+ Handle* openTgtHBA(uint64_t wwn);
+ HBA_LIBRARYATTRIBUTES getVSLAttributes();
+
+protected:
+ HBAList(); // Singleton
+
+ // Prevent ambiguity
+ using Lockable::lock;
+ using Lockable::unlock;
+
+private:
+ static HBAList* _instance;
+ std::vector<HBA*> hbas;
+ std::vector<HBA*> tgthbas;
+};
+
+#endif /* _HBALIST_H */
diff --git a/usr/src/lib/sun_fc/common/HBANPIVPort.cc b/usr/src/lib/sun_fc/common/HBANPIVPort.cc
new file mode 100644
index 0000000000..42c89ab3fa
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/HBANPIVPort.cc
@@ -0,0 +1,114 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#include "HBANPIVPort.h"
+#include "Exceptions.h"
+#include "Trace.h"
+#include <iostream>
+#include <iomanip>
+#include <cerrno>
+#include <cstring>
+#include <sys/types.h>
+#include <sys/mkdev.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stropts.h>
+#include <dirent.h>
+#include <libdevinfo.h>
+
+using namespace std;
+
+
+/**
+ * @memo Construct a new deafult HBA Port
+ * @version 1.7
+ */
+HBANPIVPort::HBANPIVPort() {
+}
+
+/**
+ * @memo Compare two HBA ports for equality
+ * @return TRUE if both ports are the same
+ * @return FALSE if the ports are different
+ * @version 1.7
+ *
+ * @doc Comparison is based on Node WWN, Port WWN and path
+ */
+bool HBANPIVPort::operator==(HBANPIVPort &comp) {
+ return (this->getPortWWN() == comp.getPortWWN() &&
+ this->getNodeWWN() == comp.getNodeWWN());
+}
+
+/*
+ * Finds controller path for a give device path.
+ *
+ * Return vale: controller path.
+ */
+string HBANPIVPort::lookupControllerPath(string path) {
+ Trace log("lookupControllerPath");
+ DIR *dp;
+ char buf[MAXPATHLEN];
+ char node[MAXPATHLEN];
+ struct dirent **dirpp, *dirp;
+ const char dir[] = "/dev/cfg";
+ ssize_t count;
+ uchar_t *dir_buf = new uchar_t[sizeof (struct dirent) + MAXPATHLEN];
+
+ if ((dp = opendir(dir)) == NULL) {
+ string tmp = "Unable to open ";
+ tmp += dir;
+ tmp += "to find controller number.";
+ delete (dir_buf);
+ throw IOError(tmp);
+ }
+
+ dirp = (struct dirent *) dir_buf;
+ dirpp = &dirp;
+ while ((readdir_r(dp, dirp, dirpp)) == 0 && dirp != NULL) {
+ if (strcmp(dirp->d_name, ".") == 0 ||
+ strcmp(dirp->d_name, "..") == 0) {
+ continue;
+ }
+ sprintf(node, "%s/%s", dir, dirp->d_name);
+ if ((count = readlink(node,buf,sizeof(buf)))) {
+ buf[count] = '\0';
+ if (strstr(buf, path.c_str())) {
+ string cfg_path = dir;
+ cfg_path += "/";
+ cfg_path += dirp->d_name;
+ closedir(dp);
+ delete (dir_buf);
+ return (cfg_path);
+ }
+ }
+ }
+
+ closedir(dp);
+ delete (dir_buf);
+ throw InternalError("Unable to find controller path");
+}
+
diff --git a/usr/src/lib/sun_fc/common/HBANPIVPort.h b/usr/src/lib/sun_fc/common/HBANPIVPort.h
new file mode 100644
index 0000000000..267cf6074c
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/HBANPIVPort.h
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _HBANPIVPORT_H
+#define _HBANPIVPORT_H
+
+
+
+#include "Lockable.h"
+#include <string>
+#include <hbaapi.h>
+#include <hbaapi-sun.h>
+
+/*
+ * @memo Represents a single HBA NPIV port
+ *
+ */
+class HBANPIVPort : public Lockable {
+public:
+ HBANPIVPort();
+ virtual ~HBANPIVPort() {};
+ bool operator == (HBANPIVPort &comp);
+ virtual std::string getPath() = 0;
+ virtual uint64_t getNodeWWN() = 0;
+ virtual uint64_t getPortWWN() = 0;
+ virtual HBA_NPIVATTRIBUTES getPortAttributes(
+ uint64_t &stateChange) = 0;
+protected:
+ std::string lookupControllerPath(std::string path);
+};
+
+#endif /* _HBANPIVPORT_H */
diff --git a/usr/src/lib/sun_fc/common/HBAPort.cc b/usr/src/lib/sun_fc/common/HBAPort.cc
new file mode 100644
index 0000000000..29fbb10641
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/HBAPort.cc
@@ -0,0 +1,304 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "HBAPort.h"
+#include "Exceptions.h"
+#include "Trace.h"
+#include <iostream>
+#include <iomanip>
+#include <cerrno>
+#include <cstring>
+#include <sys/types.h>
+#include <sys/mkdev.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stropts.h>
+#include <dirent.h>
+#include <libdevinfo.h>
+
+using namespace std;
+
+/**
+ * Standard definition for general topology lookup (See T11 FC-FS)
+ */
+const int HBAPort::RNID_GENERAL_TOPOLOGY_DATA_FORMAT = 0xDF;
+const uint8_t HBAPort::HBA_NPIV_PORT_MAX = UCHAR_MAX;
+
+/**
+ * @memo Construct a new deafult HBA Port
+ */
+HBAPort::HBAPort() {
+}
+
+/**
+ * @memo Compare two HBA ports for equality
+ * @return TRUE if both ports are the same
+ * @return FALSE if the ports are different
+ *
+ * @doc Comparison is based on Node WWN, Port WWN and path
+ */
+bool HBAPort::operator==(HBAPort &comp) {
+ return (this->getPortWWN() == comp.getPortWWN() &&
+ this->getNodeWWN() == comp.getNodeWWN() &&
+ this->getPath() == comp.getPath());
+}
+
+/**
+ * @memo Validate that the port is still present in the system
+ * @exception UnavailableException if the port is not present
+ *
+ * @doc If the port is still present on the system, the routine
+ * will return normally. If the port is not present
+ * an exception will be thrown.
+ */
+void HBAPort::validatePresent() {
+ Trace log("HBAPort::validatePresent");
+ string path = getPath();
+ struct stat sbuf;
+ if (stat(path.c_str(), &sbuf) == -1) {
+ if (errno == ENOENT) {
+ throw UnavailableException();
+ } else {
+ log.debug("Unable to stat %s: %s", path.c_str(),
+ strerror(errno));
+ throw InternalError();
+ }
+ }
+}
+
+
+/*
+ * structure for di_devlink_walk
+ */
+typedef struct walk_devlink {
+ char *path;
+ size_t len;
+ char **linkpp;
+} walk_devlink_t;
+
+/**
+ * @memo callback funtion for di_devlink_walk
+ * @postcondition Find matching /dev link for the given path argument.
+ * @param devlink element and callback function argument.
+ *
+ * @doc The input path is expected to not have "/devices".
+ */
+extern "C" int
+get_devlink(di_devlink_t devlink, void *arg) {
+ Trace log("get_devlink");
+ walk_devlink_t *warg = (walk_devlink_t *)arg;
+
+ /*
+ * When path is specified, it doesn't have minor
+ * name. Therefore, the ../.. prefixes needs to be stripped.
+ */
+ if (warg->path) {
+ // di_devlink_content contains /devices
+ char *content = (char *)di_devlink_content(devlink);
+ char *start = strstr(content, "/devices");
+
+ if (start == NULL ||
+ strncmp(start, warg->path, warg->len) != 0 ||
+ // make it sure the device path has minor name
+ start[warg->len] != ':')
+ return (DI_WALK_CONTINUE);
+ }
+
+ *(warg->linkpp) = strdup(di_devlink_path(devlink));
+ return (DI_WALK_TERMINATE);
+}
+
+/**
+ * @memo Convert /devices paths to /dev sym-link paths.
+ * @postcondition The mapping buffer OSDeviceName paths will be
+ * converted to short names.
+ * @param mappings The target mappings data to convert to
+ * short names
+ *
+ * @doc If no link
+ * is found, the long path is left as is.
+ * Note: The NumberOfEntries field MUST not be greater than the size
+ * of the array passed in.
+ */
+void HBAPort::convertToShortNames(PHBA_FCPTARGETMAPPINGV2 mappings) {
+ Trace log("HBAPort::convertToShortNames");
+ di_devlink_handle_t hdl;
+ walk_devlink_t warg;
+ char *minor_path, *devlinkp;
+
+ if ((hdl = di_devlink_init(NULL, 0)) == NULL) {
+ log.internalError("di_devlink_init failed. Errno:%d", errno);
+ // no need to check further, just return here.
+ return;
+ }
+
+ for (int j = 0; j < mappings->NumberOfEntries; j++) {
+ if (strchr(mappings->entry[j].ScsiId.OSDeviceName, ':')) {
+ // search link for minor node
+ minor_path = mappings->entry[j].ScsiId.OSDeviceName;
+ if (strstr(minor_path, "/devices") != NULL) {
+ minor_path = mappings->entry[j].ScsiId.OSDeviceName +
+ strlen("/devices");
+ } else {
+ minor_path = mappings->entry[j].ScsiId.OSDeviceName;
+ }
+ warg.path = NULL;
+ } else {
+ minor_path = NULL;
+ if (strstr(mappings->entry[j].ScsiId.OSDeviceName,
+ "/devices") != NULL) {
+ warg.len = strlen (mappings->entry[j].ScsiId.OSDeviceName) -
+ strlen ("/devices");
+ warg.path = mappings->entry[j].ScsiId.OSDeviceName +
+ strlen ("/devices");
+ } else {
+ warg.len = strlen(mappings->entry[j].ScsiId.OSDeviceName);
+ warg.path = mappings->entry[j].ScsiId.OSDeviceName;
+ }
+ }
+
+ devlinkp = NULL;
+ warg.linkpp = &devlinkp;
+ (void) di_devlink_walk(hdl, NULL, minor_path, DI_PRIMARY_LINK,
+ (void *)&warg, get_devlink);
+
+ if (devlinkp != NULL) {
+ snprintf(mappings->entry[j].ScsiId.OSDeviceName,
+ sizeof (mappings->entry[j].ScsiId.OSDeviceName),
+ "%s", devlinkp);
+ free(devlinkp);
+ } // else leave OSDeviceName alone.
+
+ }
+
+ di_devlink_fini(&hdl);
+
+}
+
+/*
+ * Finds controller path for a give device path.
+ *
+ * Return vale: controller path.
+ */
+string HBAPort::lookupControllerPath(string path) {
+ Trace log("lookupControllerPath");
+ DIR *dp;
+ char buf[MAXPATHLEN];
+ char node[MAXPATHLEN];
+ struct dirent **dirpp, *dirp;
+ const char dir[] = "/dev/cfg";
+ ssize_t count;
+ uchar_t *dir_buf = new uchar_t[sizeof (struct dirent) + MAXPATHLEN];
+
+ if ((dp = opendir(dir)) == NULL) {
+ string tmp = "Unable to open ";
+ tmp += dir;
+ tmp += "to find controller number.";
+ delete (dir_buf);
+ throw IOError(tmp);
+ }
+
+ dirp = (struct dirent *) dir_buf;
+ dirpp = &dirp;
+ while ((readdir_r(dp, dirp, dirpp)) == 0 && dirp != NULL) {
+ if (strcmp(dirp->d_name, ".") == 0 ||
+ strcmp(dirp->d_name, "..") == 0) {
+ continue;
+ }
+ sprintf(node, "%s/%s", dir, dirp->d_name);
+ if ((count = readlink(node,buf,sizeof(buf)))) {
+ buf[count] = '\0';
+ if (strstr(buf, path.c_str())) {
+ string cfg_path = dir;
+ cfg_path += "/";
+ cfg_path += dirp->d_name;
+ closedir(dp);
+ delete (dir_buf);
+ return (cfg_path);
+ }
+ }
+ }
+
+ closedir(dp);
+ delete (dir_buf);
+ throw InternalError("Unable to find controller path");
+}
+
+void HBAPort::addPort(HBANPIVPort *port) {
+ Trace log("HBAPort::addPort");
+ lock();
+ // support hba with up to UCHAR_MAX number of ports.
+ if (npivportsByIndex.size() + 1 > HBA_NPIV_PORT_MAX) {
+ unlock();
+ throw InternalError("HBA NPIV Port count exceeds max number of ports");
+ }
+
+ try {
+ npivportsByWWN[port->getPortWWN()] = port;
+ npivportsByIndex.insert(npivportsByIndex.end(), port);
+ unlock();
+ } catch (...) {
+ unlock();
+ throw;
+ }
+}
+
+HBANPIVPort* HBAPort::getPort(uint64_t wwn) {
+ Trace log("HBAPort::getPort");
+ HBANPIVPort *port = NULL;
+
+ lock();
+ try {
+ if (npivportsByWWN.find(wwn) == npivportsByWWN.end()) {
+ throw IllegalWWNException();
+ }
+ port = npivportsByWWN[wwn];
+ unlock();
+ return (port);
+ } catch (...) {
+ unlock();
+ throw;
+ }
+}
+
+HBANPIVPort* HBAPort::getPortByIndex(int index) {
+ Trace log("HBAPort::getPortByIndex");
+ lock();
+ try {
+ if (index >= npivportsByIndex.size() || index < 0) {
+ throw IllegalIndexException();
+ }
+ HBANPIVPort *tmp = npivportsByIndex[index];
+ unlock();
+ return (tmp);
+ } catch (...) {
+ unlock();
+ throw;
+ }
+}
+
diff --git a/usr/src/lib/sun_fc/common/HBAPort.h b/usr/src/lib/sun_fc/common/HBAPort.h
new file mode 100644
index 0000000000..501bda06d0
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/HBAPort.h
@@ -0,0 +1,130 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _HBAPORT_H
+#define _HBAPORT_H
+
+
+
+#include "Lockable.h"
+#include "HBANPIVPort.h"
+#include <string>
+#include <map>
+#include <vector>
+#include <hbaapi.h>
+#include <hbaapi-sun.h>
+
+/**
+ * @memo Represents a single HBA port
+ *
+ */
+class HBAPort : public Lockable {
+public:
+ HBAPort();
+ virtual ~HBAPort() {}
+ bool operator==(HBAPort &comp);
+ virtual void validatePresent();
+ virtual std::string getPath() = 0;
+ virtual uint64_t getNodeWWN() = 0;
+ virtual uint64_t getPortWWN() = 0;
+ virtual HBA_PORTATTRIBUTES getPortAttributes(
+ uint64_t &stateChange) = 0;
+ virtual HBA_PORTATTRIBUTES getDiscoveredAttributes(
+ HBA_UINT32 discoveredport,
+ uint64_t &stateChange) = 0;
+ virtual HBA_PORTATTRIBUTES getDiscoveredAttributes(
+ uint64_t wwn,
+ uint64_t &stateChange) = 0;
+ virtual void getTargetMappings(
+ PHBA_FCPTARGETMAPPINGV2 userMappings) = 0;
+ virtual void getRNIDMgmtInfo(PHBA_MGMTINFO info) = 0;
+ virtual void sendCTPassThru(void *requestBuffer,
+ HBA_UINT32 requestSize,
+ void *responseBuffer,
+ HBA_UINT32 *responseSize) = 0;
+ virtual void sendRLS(uint64_t destWWN,
+ void *pRspBuffer,
+ HBA_UINT32 *pRspBufferSize) = 0;
+ virtual void sendRPL(uint64_t destWWN,
+ HBA_UINT32 agent_domain,
+ HBA_UINT32 port_index,
+ void *pRspBuffer,
+ HBA_UINT32 *pRspBufferSize) = 0;
+ virtual void sendRPS(uint64_t agentWWN,
+ HBA_UINT32 agentDomain,
+ uint64_t objectWWN,
+ HBA_UINT32 objectPortNum,
+ void *pRspBuffer,
+ HBA_UINT32 *pRspBufferSize) = 0;
+ virtual void sendSRL(uint64_t destWWN,
+ HBA_UINT32 agent_domain,
+ void *pRspBuffer,
+ HBA_UINT32 *pRspBufferSize) = 0;
+ virtual void sendLIRR(uint64_t destWWN,
+ HBA_UINT8 function,
+ HBA_UINT8 type,
+ void *pRspBuffer,
+ HBA_UINT32 *pRspBufferSize) = 0;
+ virtual void sendReportLUNs(uint64_t wwn,
+ void *responseBuffer, HBA_UINT32 *responseSize,
+ HBA_UINT8 *scsiStatus,
+ void *senseBuffer, HBA_UINT32 *senseSize) = 0;
+ virtual void sendScsiInquiry(uint64_t wwn, HBA_UINT64 fcLun,
+ HBA_UINT8 cdb1, HBA_UINT8 cdb2,
+ void *responseBuffer, HBA_UINT32 *responseSize,
+ HBA_UINT8 *scsiStatus, void *senseBuffer,
+ HBA_UINT32 *senseSize) = 0;
+ virtual void sendReadCapacity(uint64_t pwwn,
+ HBA_UINT64 fcLun, void *responseBuffer,
+ HBA_UINT32 *responseSize, HBA_UINT8 *scsiStatus,
+ void *senseBuffer, HBA_UINT32 *senseSize) = 0;
+
+ static const int RNID_GENERAL_TOPOLOGY_DATA_FORMAT;
+ virtual void sendRNID(uint64_t destwwn, HBA_UINT32 destfcid,
+ HBA_UINT32 nodeIdDataFormat, void *pRspBuffer,
+ HBA_UINT32 *RspBufferSize) = 0;
+ virtual void setRNID(HBA_MGMTINFO info) = 0;
+
+ static const uint8_t HBA_NPIV_PORT_MAX;
+ void addPort(HBANPIVPort* port);
+ HBANPIVPort* getPort(uint64_t wwn);
+ HBANPIVPort* getPortByIndex(int index);
+ virtual HBA_PORTNPIVATTRIBUTES getPortNPIVAttributes(
+ uint64_t &stateChange) = 0;
+ virtual uint32_t createNPIVPort(
+ uint64_t vnodewwn,
+ uint64_t vportwwn,
+ uint32_t vindex) = 0;
+ virtual uint32_t deleteNPIVPort(
+ uint64_t vportwwn) = 0;
+protected:
+ void convertToShortNames(PHBA_FCPTARGETMAPPINGV2 mappings);
+ std::string lookupControllerPath(std::string path);
+ std::map<uint64_t, HBANPIVPort*> npivportsByWWN;
+ std::vector<HBANPIVPort*> npivportsByIndex;
+};
+
+
+#endif /* _HBAPORT_H */
diff --git a/usr/src/lib/sun_fc/common/HBA_RegisterLibrary.cc b/usr/src/lib/sun_fc/common/HBA_RegisterLibrary.cc
new file mode 100644
index 0000000000..c05fade892
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/HBA_RegisterLibrary.cc
@@ -0,0 +1,66 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "sun_fc.h"
+#include "Trace.h"
+
+/**
+ * @memo Set up entry points for V1 API
+ * @return HBA_STATUS_OK if the entry points were filled in
+ * @param entrypoints user allocated buffer to store entry points
+ *
+ */
+HBA_STATUS HBA_RegisterLibrary(PHBA_ENTRYPOINTS entrypoints) {
+ Trace log("HBA_RegisterLibrary");
+ entrypoints->GetVersionHandler = Sun_fcGetVersion;
+ entrypoints->LoadLibraryHandler = Sun_fcLoadLibrary;
+ entrypoints->FreeLibraryHandler = Sun_fcFreeLibrary;
+ entrypoints->GetNumberOfAdaptersHandler = Sun_fcGetNumberOfAdapters;
+ entrypoints->GetAdapterNameHandler = Sun_fcGetAdapterName;
+ entrypoints->OpenAdapterHandler = Sun_fcOpenAdapter;
+ entrypoints->CloseAdapterHandler = Sun_fcCloseAdapter;
+ entrypoints->GetAdapterAttributesHandler = Sun_fcGetAdapterAttributes;
+ entrypoints->GetAdapterPortAttributesHandler =
+ Sun_fcGetAdapterPortAttributes;
+ entrypoints->GetPortStatisticsHandler = Sun_fcGetPortStatistics;
+ entrypoints->GetDiscoveredPortAttributesHandler =
+ Sun_fcGetDiscoveredPortAttributes;
+ entrypoints->GetPortAttributesByWWNHandler = Sun_fcGetPortAttributesByWWN;
+ entrypoints->SendCTPassThruHandler = Sun_fcSendCTPassThru;
+ entrypoints->RefreshInformationHandler = Sun_fcRefreshInformation;
+ entrypoints->ResetStatisticsHandler = Sun_fcResetStatistics;
+ entrypoints->GetFcpTargetMappingHandler = Sun_fcGetFcpTargetMapping;
+ entrypoints->GetFcpPersistentBindingHandler = Sun_fcGetFcpPersistentBinding;
+ entrypoints->GetEventBufferHandler = Sun_fcGetEventBuffer;
+ entrypoints->SetRNIDMgmtInfoHandler = Sun_fcSetRNIDMgmtInfo;
+ entrypoints->GetRNIDMgmtInfoHandler = Sun_fcGetRNIDMgmtInfo;
+ entrypoints->SendRNIDHandler = Sun_fcSendRNID;
+ entrypoints->ScsiInquiryHandler = Sun_fcSendScsiInquiry;
+ entrypoints->ReportLUNsHandler = Sun_fcSendReportLUNs;
+ entrypoints->ReadCapacityHandler = Sun_fcSendReadCapacity;
+ return (HBA_STATUS_OK);
+}
diff --git a/usr/src/lib/sun_fc/common/HBA_RegisterLibraryV2.cc b/usr/src/lib/sun_fc/common/HBA_RegisterLibraryV2.cc
new file mode 100644
index 0000000000..3b59ef52ad
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/HBA_RegisterLibraryV2.cc
@@ -0,0 +1,104 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "sun_fc.h"
+#include "Trace.h"
+
+/**
+ * @memo Entry points for the V2 API
+ * @postcondition entrypoints contains the function pointers to this API
+ * @return HBA_STATUS_OK if entrypoints updated
+ * @param entrypoints The user-allocated buffer to store the API
+ *
+ */
+HBA_STATUS HBA_RegisterLibraryV2(PHBA_ENTRYPOINTSV2 entrypoints) {
+ Trace log("HBA_RegisterLibrary");
+ entrypoints->GetVersionHandler = Sun_fcGetVersion;
+ entrypoints->LoadLibraryHandler = Sun_fcLoadLibrary;
+ entrypoints->FreeLibraryHandler = Sun_fcFreeLibrary;
+ entrypoints->GetNumberOfAdaptersHandler = Sun_fcGetNumberOfAdapters;
+ entrypoints->GetAdapterNameHandler = Sun_fcGetAdapterName;
+ entrypoints->OpenAdapterHandler = Sun_fcOpenAdapter;
+ entrypoints->CloseAdapterHandler = Sun_fcCloseAdapter;
+ entrypoints->GetAdapterAttributesHandler = Sun_fcGetAdapterAttributes;
+ entrypoints->GetAdapterPortAttributesHandler =
+ Sun_fcGetAdapterPortAttributes;
+ entrypoints->GetPortStatisticsHandler = Sun_fcGetPortStatistics;
+ entrypoints->GetDiscoveredPortAttributesHandler =
+ Sun_fcGetDiscoveredPortAttributes;
+ entrypoints->GetPortAttributesByWWNHandler = Sun_fcGetPortAttributesByWWN;
+ entrypoints->SendCTPassThruHandler = Sun_fcSendCTPassThru;
+ entrypoints->RefreshInformationHandler = Sun_fcRefreshInformation;
+ entrypoints->ResetStatisticsHandler = Sun_fcResetStatistics;
+ entrypoints->GetFcpTargetMappingHandler = Sun_fcGetFcpTargetMapping;
+ entrypoints->GetFcpPersistentBindingHandler = Sun_fcGetFcpPersistentBinding;
+ entrypoints->GetEventBufferHandler = Sun_fcGetEventBuffer;
+ entrypoints->SetRNIDMgmtInfoHandler = Sun_fcSetRNIDMgmtInfo;
+ entrypoints->GetRNIDMgmtInfoHandler = Sun_fcGetRNIDMgmtInfo;
+ entrypoints->SendRNIDHandler = Sun_fcSendRNID;
+ entrypoints->ScsiInquiryHandler = Sun_fcSendScsiInquiry;
+ entrypoints->ReportLUNsHandler = Sun_fcSendReportLUNs;
+ entrypoints->ReadCapacityHandler = Sun_fcSendReadCapacity;
+ entrypoints->OpenAdapterByWWNHandler = Sun_fcOpenAdapterByWWN;
+ entrypoints->GetFcpTargetMappingV2Handler = Sun_fcGetFcpTargetMappingV2;
+ entrypoints->SendCTPassThruV2Handler = Sun_fcSendCTPassThruV2;
+ entrypoints->RefreshAdapterConfigurationHandler =
+ Sun_fcRefreshAdapterConfiguration;
+ entrypoints->GetBindingCapabilityHandler = Sun_fcGetBindingCapability;
+ entrypoints->GetBindingSupportHandler = Sun_fcGetBindingSupport;
+ entrypoints->SetBindingSupportHandler = Sun_fcSetBindingSupport;
+ entrypoints->SetPersistentBindingV2Handler = Sun_fcSetPersistentBindingV2;
+ entrypoints->GetPersistentBindingV2Handler = Sun_fcGetPersistentBindingV2;
+ entrypoints->RemovePersistentBindingHandler = Sun_fcRemovePersistentBinding;
+ entrypoints->RemoveAllPersistentBindingsHandler =
+ Sun_fcRemoveAllPersistentBindings;
+ entrypoints->SendRNIDV2Handler = Sun_fcSendRNIDV2;
+ entrypoints->ScsiInquiryV2Handler = Sun_fcScsiInquiryV2;
+ entrypoints->ScsiReportLUNsV2Handler = Sun_fcScsiReportLUNsV2;
+ entrypoints->ScsiReadCapacityV2Handler = Sun_fcScsiReadCapacityV2;
+ entrypoints->GetVendorLibraryAttributesHandler =
+ Sun_fcGetVendorLibraryAttributes;
+ entrypoints->RemoveCallbackHandler = Sun_fcRemoveCallback;
+ entrypoints->RegisterForAdapterAddEventsHandler =
+ Sun_fcRegisterForAdapterAddEvents;
+ entrypoints->RegisterForAdapterEventsHandler =
+ Sun_fcRegisterForAdapterEvents;
+ entrypoints->RegisterForAdapterPortEventsHandler =
+ Sun_fcRegisterForAdapterPortEvents;
+ entrypoints->RegisterForAdapterPortStatEventsHandler =
+ Sun_fcRegisterForAdapterPortStatEvents;
+ entrypoints->RegisterForTargetEventsHandler = Sun_fcRegisterForTargetEvents;
+ entrypoints->RegisterForLinkEventsHandler = Sun_fcRegisterForLinkEvents;
+ entrypoints->SendRLSHandler = Sun_fcSendRLS;
+ entrypoints->SendRPLHandler = Sun_fcSendRPL;
+ entrypoints->SendRPSHandler = Sun_fcSendRPS;
+ entrypoints->SendSRLHandler = Sun_fcSendSRL;
+ entrypoints->SendLIRRHandler = Sun_fcSendLIRR;
+ entrypoints->GetFC4StatisticsHandler = Sun_fcGetFC4Statistics;
+ entrypoints->GetFCPStatisticsHandler = Sun_fcGetFCPStatistics;
+ return (HBA_STATUS_OK);
+}
diff --git a/usr/src/lib/sun_fc/common/Handle.cc b/usr/src/lib/sun_fc/common/Handle.cc
new file mode 100644
index 0000000000..e9a37348bb
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Handle.cc
@@ -0,0 +1,437 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Handle.h"
+#include "Exceptions.h"
+#include "Trace.h"
+#include <libdevinfo.h>
+#include <iostream>
+#include <iomanip>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stropts.h>
+
+#define MAX_INIT_HANDLE_ID 0x7fff
+#define MAX_TGT_HANDLE_ID 0xffff
+
+using namespace std;
+
+/**
+ * Global lock for list of Handles
+ */
+pthread_mutex_t Handle::staticLock = PTHREAD_MUTEX_INITIALIZER;
+
+/**
+ * Tracking for the previous handle we have opened
+ */
+HBA_HANDLE Handle::prevOpen = 0;
+
+/**
+ * Tracking for the previous target HBA handle we have opened
+ */
+HBA_HANDLE Handle::prevTgtOpen = 0x8000;
+
+/**
+ * Global map from HBA_HANDLE to Handle pointers (our global list)
+ */
+map<HBA_HANDLE, Handle*> Handle::openHandles;
+
+/**
+ * @memo Create a new open handle for a specified HBA
+ * @precondition HBA port(s) must be loaded
+ * @postcondition An open handle will be present in the global tracking list
+ * and must be closed at some point to prevent leakage. If no
+ * handle could be assigned (the track list is full), an
+ * exception will be thrown. Scope for valid ids in the track
+ * list is [1, MAX_INIT_HANDLE_ID].
+ * @param myhba The HBA to open a handle for
+ */
+Handle::Handle(HBA *myhba) {
+ map<HBA_HANDLE, Handle*>::iterator mapend;
+ Trace log("Handle::Handle");
+ modeVal = INITIATOR;
+ lock(&staticLock);
+ mapend = openHandles.end();
+ /* Start the search for a free id from the previously assigned one */
+ id = prevOpen + 1;
+ while (id != prevOpen) {
+ /* Exceeds the max valid value, continue the search from 1 */
+ if (id > MAX_INIT_HANDLE_ID)
+ id = 1;
+
+ if (openHandles.find(id) == mapend) {
+ /* the id is not in use */
+ break;
+ }
+ id ++;
+ }
+ if (id == prevOpen) {
+ /* no usable id for now */
+ unlock(&staticLock);
+ throw TryAgainException();
+ }
+ prevOpen = id;
+ hba = myhba;
+ openHandles[id] = this;
+ unlock(&staticLock);
+}
+
+/**
+ * @memo Create a new open handle for a specified HBA
+ * @precondition HBA port(s) must be loaded
+ * @postcondition An open handle will be present in the global tracking list
+ * and must be closed at some point to prevent leakage. If no
+ * handle could be assigned (the track list is full), an
+ * exception will be thrown. Scope for valid ids in the track
+ * list is [0x8000, MAX_TGT_HANDLE_ID].
+ * @param myhba The HBA to open a handle for
+ * m The mode of HBA to open handle for
+ */
+#if 0
+// appears unused
+Handle::Handle(HBA *myhba, MODE m) {
+ map<HBA_HANDLE, Handle*>::iterator mapend;
+ Trace log("Handle::Handle");
+ lock(&staticLock);
+ modeVal = m;
+
+
+ // if initiator mode call constructor for initiator.
+ if (m == INITIATOR) {
+ Handle(myhba, TARGET);
+ }
+
+ mapend = openHandles.end();
+ /* Start the search for a free id from the previously assigned one */
+ id = prevTgtOpen + 1;
+ while (id != prevTgtOpen) {
+ /*
+ * Exceeds the max valid target id value,
+ * continue the search from 1.
+ */
+ if (id > MAX_TGT_HANDLE_ID)
+ id = 0x8001;
+
+ if (openHandles.find(id) == mapend) {
+ /* the id is not in use */
+ break;
+ }
+ id ++;
+ }
+ if (id == prevTgtOpen) {
+ /* no usable id for now */
+ unlock(&staticLock);
+ throw TryAgainException();
+ }
+ prevTgtOpen = id;
+ hba = myhba;
+ openHandles[id] = this;
+ unlock(&staticLock);
+}
+#endif
+/**
+ * @memo Free up the handle (aka, close it)
+ * @postcondition This handle will be removed from the global list
+ * @exception ... underlying exceptions will be thrown
+ */
+Handle::~Handle() {
+ Trace log("Handle::~Handle");
+ // Remove this handle from the global list
+ lock(&staticLock);
+ try {
+ openHandles.erase(openHandles.find(getHandle()));
+ unlock(&staticLock);
+ } catch (...) {
+ unlock(&staticLock);
+ throw;
+ }
+
+ // Now nuke all internal dynamic allocations
+ typedef map<uint64_t, HandlePort *>::const_iterator CI;
+ lock();
+ try {
+ for (CI port = portHandles.begin(); port != portHandles.end();
+ port++) {
+ delete port->second;
+ }
+ portHandles.clear();
+ unlock();
+ } catch (...) {
+ unlock();
+ throw;
+ }
+}
+
+/**
+ * @memo Locate a handle in the global list of open handles
+ * @precondition The requested handle must already be open
+ * @exception InvalidHandleException Thrown if the id does not match
+ * an open handle
+ * @return The open Handle
+ * @param id The id of the handle to fetch
+ *
+ * @doc The HBA API uses a simple integer type to represent
+ * an open Handle, but we use an instance of the Handle
+ * class. This interface allows a caller to quickly convert
+ * from the API integer value to related the Handle instance.
+ */
+Handle* Handle::findHandle(HBA_HANDLE id) {
+ Trace log("Handle::findHandle(id)");
+ Handle *tmp = NULL;
+ lock(&staticLock);
+ try {
+ if (openHandles.find(id) == openHandles.end()) {
+ throw InvalidHandleException();
+ }
+ tmp = openHandles[id];
+ unlock(&staticLock);
+ return (tmp);
+ } catch (...) {
+ unlock(&staticLock);
+ throw;
+ }
+}
+
+/**
+ * @memo Find an open handle based on Node or Port WWN
+ * @precondition The given HBA must already be open
+ * @exception IllegalWWNException Thrown if no matching open Handle found
+ * @return The open handle matching the wwn argument
+ * @param wwn The Node or Port WWN of the HBA whos open handle
+ * is requested.
+ *
+ */
+Handle* Handle::findHandle(uint64_t wwn) {
+ Trace log("Handle::findHandle(wwn)");
+ Handle *tmp = NULL;
+ lock(&staticLock);
+ try {
+ for (int i = 0; i < openHandles.size(); i++) {
+ tmp = openHandles[i];
+ if (tmp->getHBA()->containsWWN(wwn)) {
+ unlock(&staticLock);
+ return (tmp);
+ }
+ }
+ tmp = NULL;
+ } catch (...) { tmp = NULL; }
+ unlock(&staticLock);
+ if (tmp == NULL) {
+ throw IllegalWWNException();
+ }
+ return (tmp);
+}
+
+/**
+ * @memo Refresh underlying index values
+ * @postcondition All HandlePorts will be reset and prior index values
+ * will be undefined.
+ * @exception ... underlying exceptions will be thrown
+ *
+ * @doc A number of APIs in the standard interface require
+ * the use of index values for identifying what "thing"
+ * to operate on. When dynamic reconfiguration occurs
+ * these indexes may become inconsistent. This routine
+ * is called to reset the indexes and signify that the caller
+ * no longer holds or will refer to any old indexes.
+ */
+void Handle::refresh() {
+ Trace log("Handle::refresh");
+ lock();
+ try {
+ typedef map<uint64_t, HandlePort *>::const_iterator CI;
+ for (CI port = portHandles.begin(); port != portHandles.end();
+ port++) {
+ port->second->refresh();
+ }
+ unlock();
+ } catch (...) {
+ unlock();
+ throw;
+ }
+}
+
+/**
+ * @memo Close the specified handle
+ * @precondition The handle must be open
+ * @postcondition The handle will be closed and should be discarded.
+ * @param id The handle to close
+ */
+void Handle::closeHandle(HBA_HANDLE id) {
+ Trace log("Handle::closeHandle");
+ Handle *myHandle = findHandle(id);
+ delete myHandle;
+}
+
+/**
+ * @memo Get the integer value for return to the API
+ * @exception ... underlying exceptions will be thrown
+ * @return The integer value representing the handle
+ *
+ * @doc The HBA API uses integer values to represent handles.
+ * Call this routine to convert a Handle instance into
+ * its representative integer value.
+ */
+HBA_HANDLE Handle::getHandle() {
+ Trace log("Handle::getHandle");
+ HBA_HANDLE tmp;
+ lock();
+ try {
+ tmp = (HBA_HANDLE) id;
+ unlock();
+ return (tmp);
+ } catch (...) {
+ unlock();
+ throw;
+ }
+}
+
+/**
+ * @memo Compare two handles for equality
+ * @return TRUE if the handles are the same
+ * @return FALSE if the handles are different
+ */
+bool Handle::operator==(Handle comp) {
+ Trace log("Handle::operator==");
+ return (this->id == comp.id);
+}
+
+/**
+ * @memo Get the underlying Handle port based on index
+ * @return The Handle port for the given port index
+ * @param index The index of the desired port
+ */
+HandlePort* Handle::getHandlePortByIndex(int index) {
+ Trace log("Handle::getHandlePortByIndex");
+ HBAPort* port = hba->getPortByIndex(index);
+ return (getHandlePort(port->getPortWWN()));
+}
+
+/**
+ * @memo Get the underlying Handle port based on Port wwn
+ * @exception IllegalWWNException thrown if the wwn is not found
+ * @return The handle port for the specified WWN
+ * @param wwn The Port WWN of the HBA port
+ *
+ */
+HandlePort* Handle::getHandlePort(uint64_t wwn) {
+ Trace log("Handle::getHandlePort");
+ lock();
+ try {
+ // Check to see if the wwn is in the map
+ if (portHandles.find(wwn) == portHandles.end()) {
+ // Not found, add a new one
+ HBAPort* port = hba->getPort(wwn);
+ portHandles[wwn] = new HandlePort(this, hba, port);
+ }
+ HandlePort *portHandle = portHandles[wwn];
+ unlock();
+ return (portHandle);
+ } catch (...) {
+ unlock();
+ throw;
+ }
+}
+
+/**
+ * @memo Get the HBA attributes from the underlying HBA
+ *
+ * @see HBA::getHBAAttributes
+ */
+HBA_ADAPTERATTRIBUTES Handle::getHBAAttributes() {
+ Trace log("Handle::getHBAAttributes");
+ lock();
+ try {
+ HBA_ADAPTERATTRIBUTES attributes = hba->getHBAAttributes();
+ unlock();
+ return (attributes);
+ } catch (...) {
+ unlock();
+ throw;
+ }
+}
+
+HBA_ADAPTERATTRIBUTES Handle::npivGetHBAAttributes() {
+ Trace log("Handle::npivGetHBAAttributes");
+ lock();
+ try {
+ HBA_ADAPTERATTRIBUTES attributes = hba->npivGetHBAAttributes();
+ unlock();
+ return (attributes);
+ } catch (...) {
+ unlock();
+ throw;
+ }
+}
+
+
+/**
+ * @memo Get the HBA port attributes from the HBA
+ * @see HBAPort::getPortAttributes
+ * @see HBAPort::getDisoveredAttributes
+ *
+ * @doc This routine will return either HBA port
+ * attributes, or discovered port attributes
+ *
+ */
+HBA_PORTATTRIBUTES Handle::getPortAttributes(uint64_t wwn) {
+ Trace log("Handle::getPortAttributes");
+ uint64_t tmp;
+ HBA_PORTATTRIBUTES attributes;
+
+ lock();
+ try {
+ // Is this a WWN for one of the adapter ports?
+ if (hba->containsWWN(wwn)) {
+ attributes = hba->getPort(wwn)->getPortAttributes(tmp);
+ unlock();
+ return (attributes);
+ } else { // Is this a target we know about?
+ // Loop through all ports and look for the first match
+
+ for (int i = 0; i < hba->getNumberOfPorts(); i++) {
+ try {
+ attributes =
+ hba->getPortByIndex(i)->getDiscoveredAttributes(
+ wwn, tmp);
+ unlock();
+ return (attributes);
+ } catch (HBAException &e) {
+ continue;
+ }
+ }
+
+ // If we get to here, then we don't see this WWN on this HBA
+ throw IllegalWWNException();
+ }
+ } catch (...) {
+ unlock();
+ throw;
+ }
+}
diff --git a/usr/src/lib/sun_fc/common/Handle.h b/usr/src/lib/sun_fc/common/Handle.h
new file mode 100644
index 0000000000..e0bb6bb68b
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Handle.h
@@ -0,0 +1,87 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _HANDLE_H
+#define _HANDLE_H
+
+
+
+// Forward Declarations
+class Handle;
+class HandlePort;
+
+#include "Lockable.h"
+#include "HBA.h"
+#include "HandlePort.h"
+#include <map>
+#include <hbaapi.h>
+#include <hbaapi-sun.h>
+
+
+/**
+ * @memo Represents an open HBA port
+ *
+ * @doc This class represents an open HBA. However,
+ * what we really care about is the HBA port's underneath.
+ * So, we also track HandlePorts internally.
+ */
+class Handle : public Lockable {
+public:
+ enum MODE { INITIATOR, TARGET };
+ Handle(HBA *hba); // Generate ID, and add to vector
+ // Handle(HBA *hba, MODE m); // Generate ID based on target or initiator mode
+ ~Handle(); // Free and remove from vector
+
+ static Handle* findHandle(HBA_HANDLE index);
+ static Handle* findHandle(uint64_t wwn);
+ static void closeHandle(HBA_HANDLE index);
+
+ HBA_HANDLE getHandle();
+
+ bool operator==(Handle comp);
+
+ HBA* getHBA() { return (hba); }
+ HandlePort* getHandlePortByIndex(int index);
+ HandlePort* getHandlePort(uint64_t wwn);
+ MODE getMode() { return (modeVal); };
+ void refresh();
+
+ HBA_ADAPTERATTRIBUTES getHBAAttributes();
+ HBA_ADAPTERATTRIBUTES npivGetHBAAttributes();
+ HBA_PORTATTRIBUTES getPortAttributes(uint64_t wwn);
+
+private:
+ HBA *hba;
+ HBA_HANDLE id;
+ MODE modeVal;
+ static pthread_mutex_t staticLock;
+
+ static HBA_HANDLE prevOpen;
+ static HBA_HANDLE prevTgtOpen;
+ static std::map<HBA_HANDLE, Handle*> openHandles;
+ std::map<uint64_t, HandlePort*> portHandles;
+};
+
+#endif /* _HANDLE_H */
diff --git a/usr/src/lib/sun_fc/common/HandleNPIVPort.cc b/usr/src/lib/sun_fc/common/HandleNPIVPort.cc
new file mode 100644
index 0000000000..3129351f21
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/HandleNPIVPort.cc
@@ -0,0 +1,141 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "HandleNPIVPort.h"
+#include "Exceptions.h"
+#include "Trace.h"
+#include <iostream>
+#include <iomanip>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stropts.h>
+
+using namespace std;
+
+/**
+ * @memo Construct a new HandleNPIVPort for state tracking
+ * @precondition Handle must be open
+ * @param myHandle The open handle for this HBA
+ * @param myHandlePort The open handle for this HBA Port
+ * @param myHBA The HBA for this port
+ * @param myPort The HBA Port for this npiv port
+ * @param myvPort The NPIV port to open
+ * @version 1.2
+ */
+HandleNPIVPort::HandleNPIVPort(Handle *myHandle, HandlePort *myHandlePort,
+ HBA *myHBA, HBAPort *myPort, HBANPIVPort *myvPort) :
+ handle(myHandle), handleport(myHandlePort), hba(myHBA),
+ port(myPort), active(false), vport(myvPort) {
+ Trace log("HandleNPIVPort::HandleNPIVPort");
+}
+
+/**
+ * @memo Reset the state tracking values for stale index detection
+ * @postcondition The first subsequent call to any index based routine
+ * will always succed.
+ * @version 1.2
+ */
+void HandleNPIVPort::refresh() {
+ Trace log("HandleNPIVPort::refresh");
+ lock();
+ active = false;
+ unlock();
+}
+
+/**
+ * @memo Validate the current state of the handle port
+ * @exception StaleDataException Thrown if the state has changed
+ * @param newState The new state of the port
+ * @version 1.2
+ *
+ * @doc After opening a port or refreshing, no state is tracked.
+ * The first time validate is called, the state is recorded.
+ * Subsequent calls will verify that the state is the same.
+ * If the state has changed, the exception will be thrown.
+ */
+void HandleNPIVPort::validate(uint64_t newState) {
+ Trace log("HandleNPIVPort::validate");
+ log.debug("Port %016llx state %016llx",
+ vport->getPortWWN(), newState);
+ lock();
+ if (active) {
+ if (lastState != newState) {
+ unlock();
+ throw StaleDataException();
+ }
+ } else {
+ active = true;
+ lastState = newState;
+ }
+ unlock();
+}
+
+/**
+ * @memo Verify this port has the stated port wwn
+ * @return TRUE if the argument matches this port
+ * @return FALSE if the argument does not match this port
+ * @param portWWN The Port WWN to compare against this port
+ * @version 1.2
+ */
+bool HandleNPIVPort::match(uint64_t portWWN) {
+ Trace log("HandleNPIVPort::match(wwn)");
+ bool ret = false;
+ ret = (portWWN == vport->getPortWWN());
+ return (ret);
+}
+
+/**
+ * @memo Verify this port is the stated index
+ * @return TRUE if the argument matches this port
+ * @return FALSE if the argument does not match this port
+ * @param index The index value to compare against this port
+ * @version 1.2
+ */
+bool HandleNPIVPort::match(int index) {
+ Trace log("HandleNPIVPort::match(index)");
+ return (*vport == *(port->getPortByIndex(index)));
+}
+
+/**
+ * @memo Get attributes from this port.
+ * @exception ... underlying exceptions will be thrown
+ * @return The port attributes
+ * @version 1.2
+ * @see HandlePort::validate
+ *
+ * @doc This routine will perform state validation
+ */
+HBA_NPIVATTRIBUTES HandleNPIVPort::getPortAttributes() {
+ Trace log("HandleNPIVPort::getPortAttributes");
+ uint64_t newState;
+ HBA_NPIVATTRIBUTES attributes = vport->getPortAttributes(newState);
+ validate(newState);
+ return (attributes);
+}
+
diff --git a/usr/src/lib/sun_fc/common/HandleNPIVPort.h b/usr/src/lib/sun_fc/common/HandleNPIVPort.h
new file mode 100644
index 0000000000..3a0b34e204
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/HandleNPIVPort.h
@@ -0,0 +1,69 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _HANDLENPIVPORT_H
+#define _HANDLENPIVPORT_H
+
+
+
+// Forward Declarations
+class Handle;
+class HandlePort;
+class HandleNPIVPort;
+
+#include "Lockable.h"
+#include "Handle.h"
+#include "HandlePort.h"
+#include "HBA.h"
+#include "HBAPort.h"
+#include "HBANPIVPort.h"
+#include <hbaapi.h>
+#include <hbaapi-sun.h>
+
+/*
+ * @memo Represents this handles state for each NPIV port.
+ */
+class HandleNPIVPort : public Lockable {
+public:
+ HandleNPIVPort(Handle *handle, HandlePort *porthandle,
+ HBA *hba, HBAPort *port, HBANPIVPort *vport);
+
+ void refresh();
+ void validate(uint64_t newState);
+ bool match(uint64_t portWWN);
+ bool match(int index);
+
+ HBA_NPIVATTRIBUTES getPortAttributes();
+private:
+ uint64_t lastState;
+ bool active;
+ Handle *handle;
+ HandlePort *handleport;
+ HBAPort *port;
+ HBA *hba;
+ HBANPIVPort *vport;
+};
+
+#endif /* _HANDLENPIVPORT_H */
diff --git a/usr/src/lib/sun_fc/common/HandlePort.cc b/usr/src/lib/sun_fc/common/HandlePort.cc
new file mode 100644
index 0000000000..718c8beea2
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/HandlePort.cc
@@ -0,0 +1,217 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "HandlePort.h"
+#include "Exceptions.h"
+#include "Trace.h"
+#include <iostream>
+#include <iomanip>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stropts.h>
+
+
+using namespace std;
+
+/**
+ * @memo Construct a new HandlePort for state tracking
+ * @precondition Handle must be open
+ * @param myHandle The open handle for this HBA
+ * @param myHBA The HBA for this port
+ * @param myPort The HBA Port to open
+ */
+HandlePort::HandlePort(Handle *myHandle, HBA *myHBA, HBAPort *myPort) :
+ handle(myHandle), hba(myHBA), port(myPort), active(false) {
+ Trace log("HandlePort::HandlePort");
+}
+
+/**
+ * @memo Reset the state tracking values for stale index detection
+ * @postcondition The first subsequent call to any index based routine
+ * will always succed.
+ */
+void HandlePort::refresh() {
+ Trace log("HandlePort::refresh");
+ lock();
+ active = false;
+ unlock();
+}
+
+/**
+ * @memo Validate the current state of the handle port
+ * @exception StaleDataException Thrown if the state has changed
+ * @param newState The new state of the port
+ *
+ * @doc After opening a port or refreshing, no state is tracked.
+ * The first time validate is called, the state is recorded.
+ * Subsequent calls will verify that the state is the same.
+ * If the state has changed, the exception will be thrown.
+ */
+void HandlePort::validate(uint64_t newState) {
+ Trace log("HandlePort::validate");
+ log.debug("Port %016llx state %016llx", port->getPortWWN(), newState);
+ lock();
+ if (active) {
+ if (lastState != newState) {
+ unlock();
+ throw StaleDataException();
+ }
+ } else {
+ active = true;
+ lastState = newState;
+ }
+ unlock();
+}
+
+/**
+ * @memo Verify this port has the stated port wwn
+ * @return TRUE if the argument matches this port
+ * @return FALSE if the argument does not match this port
+ * @param portWWN The Port WWN to compare against this port
+ */
+bool HandlePort::match(uint64_t portWWN) {
+ Trace log("HandlePort::match(wwn)");
+ bool ret = false;
+ ret = (portWWN == port->getPortWWN());
+ return (ret);
+}
+
+/**
+ * @memo Verify this port is the stated index
+ * @return TRUE if the argument matches this port
+ * @return FALSE if the argument does not match this port
+ * @param index The index value to compare against this port
+ */
+bool HandlePort::match(int index) {
+ Trace log("HandlePort::match(index)");
+ return (*port == *(hba->getPortByIndex(index)));
+}
+
+/**
+ * @memo Get attributes from a discovered port.
+ * @exception ... underlying exceptions will be thrown
+ * @return The discovered port attributes
+ * @param wwn The node or port wwn of the discovered port
+ *
+ * @doc This routine will not perform any state validation
+ */
+HBA_PORTATTRIBUTES HandlePort::getDiscoveredAttributes(uint64_t wwn) {
+ Trace log("HandlePort::getDiscoveredAttributes(wwn)");
+ uint64_t newState;
+ HBA_PORTATTRIBUTES attributes = port->getDiscoveredAttributes(
+ wwn, newState);
+ // We don't validate when a WWN was used
+ return (attributes);
+}
+
+/**
+ * @memo Get attributes from this port.
+ * @exception ... underlying exceptions will be thrown
+ * @return The port attributes
+ * @see HandlePort::validate
+ *
+ * @doc This routine will perform state validation
+ */
+HBA_PORTATTRIBUTES HandlePort::getPortAttributes() {
+ Trace log("HandlePort::getPortAttributes");
+ uint64_t newState;
+ HBA_PORTATTRIBUTES attributes = port->getPortAttributes(newState);
+ validate(newState);
+ return (attributes);
+}
+
+/**
+ * @memo Get attributes from a discovered port.
+ * @exception ... underlying exceptions will be thrown
+ * @return The discovered port attributes
+ * @param discoveredport The index of the discovered port
+ * @see HandlePort::validate
+ *
+ * @doc This routine will perform state validation
+ */
+HBA_PORTATTRIBUTES
+HandlePort::getDiscoveredAttributes(HBA_UINT32 discoveredport) {
+ Trace log("HandlePort::getDiscoveredAttributes(index)");
+ uint64_t newState;
+ HBA_PORTATTRIBUTES attributes = port->getDiscoveredAttributes(
+ discoveredport, newState);
+ validate(newState);
+ return (attributes);
+}
+
+HBA_PORTNPIVATTRIBUTES HandlePort::getPortNPIVAttributes() {
+ Trace log("HandlePort::getPortNPIVAttributes");
+ uint64_t newState;
+ HBA_PORTNPIVATTRIBUTES attributes = port->getPortNPIVAttributes(newState);
+ validate(newState);
+ return (attributes);
+}
+
+uint32_t HandlePort::deleteNPIVPort(uint64_t vportwwn) {
+ Trace log("HandlePort::deleteNPIVPort");
+ uint32_t ret = port->deleteNPIVPort(vportwwn);
+
+ return (ret);
+}
+
+uint32_t HandlePort::createNPIVPort(uint64_t vnodewwn,
+ uint64_t vportwwn, uint32_t vindex) {
+ Trace log("HandlePort::createNPIVPort");
+ uint32_t vportindex;
+
+ vportindex = port->createNPIVPort(vnodewwn, vportwwn, vindex);
+ return (vportindex);
+}
+
+HandleNPIVPort* HandlePort::getHandleNPIVPortByIndex(int index) {
+ Trace log("HandlePort::getHandleNPIVPortByIndex(int index)");
+
+ HBANPIVPort* vport = port->getPortByIndex(index);
+ return (getHandleNPIVPort(vport->getPortWWN()));
+}
+
+HandleNPIVPort* HandlePort::getHandleNPIVPort(uint64_t wwn) {
+ Trace log("HandlePort::getHandleNPIVPort");
+ lock();
+ try {
+ // Check to see if the wwn is in the map
+ if (npivportHandles.find(wwn) == npivportHandles.end()) {
+ // Not found, add a new one
+ HBANPIVPort* vport = port->getPort(wwn);
+ npivportHandles[wwn] = new HandleNPIVPort(handle, this, hba, port, vport);
+ }
+ HandleNPIVPort *npivportHandle = npivportHandles[wwn];
+ unlock();
+ return (npivportHandle);
+ } catch (...) {
+ unlock();
+ throw;
+ }
+}
+
diff --git a/usr/src/lib/sun_fc/common/HandlePort.h b/usr/src/lib/sun_fc/common/HandlePort.h
new file mode 100644
index 0000000000..0584330134
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/HandlePort.h
@@ -0,0 +1,81 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _HANDLEPORT_H
+#define _HANDLEPORT_H
+
+
+
+// Forward Declarations
+class Handle;
+class HandlePort;
+class HandleNPIVPort;
+
+#include "Lockable.h"
+#include "Handle.h"
+#include "HBA.h"
+#include "HBAPort.h"
+#include "HandleNPIVPort.h"
+#include <hbaapi.h>
+#include <hbaapi-sun.h>
+
+/**
+ * @memo Represents this handles state for each HBA port.
+ *
+ * @doc
+ * This is required to track the state change value for
+ * a given port for this open handle. This class is used exclusivly
+ * by instances of the Handle class.
+ */
+class HandlePort : public Lockable {
+public:
+ HandlePort(Handle *handle, HBA *hba, HBAPort *port);
+
+ void refresh();
+ void validate(uint64_t newState);
+ bool match(uint64_t portWWN);
+ bool match(int index);
+
+
+ HBA_PORTATTRIBUTES getPortAttributes();
+ HBA_PORTATTRIBUTES getDiscoveredAttributes(
+ HBA_UINT32 discoveredport);
+ HBA_PORTATTRIBUTES getDiscoveredAttributes(uint64_t wwn);
+ HBA_PORTNPIVATTRIBUTES getPortNPIVAttributes();
+ uint32_t createNPIVPort(uint64_t vnodewwn,
+ uint64_t vportwwn, uint32_t vindex);
+ uint32_t deleteNPIVPort(uint64_t vportwwn);
+ HandleNPIVPort* getHandleNPIVPortByIndex(int index);
+ HandleNPIVPort* getHandleNPIVPort(uint64_t wwn);
+private:
+ uint64_t lastState;
+ bool active;
+ Handle *handle;
+ HBAPort *port;
+ HBA *hba;
+ std::map<uint64_t, HandleNPIVPort*> npivportHandles;
+};
+
+#endif /* _HANDLEPORT_H */
diff --git a/usr/src/lib/sun_fc/common/IOError.cc b/usr/src/lib/sun_fc/common/IOError.cc
new file mode 100644
index 0000000000..eb28e744bc
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/IOError.cc
@@ -0,0 +1,99 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Exceptions.h"
+#include "Trace.h"
+#include "sun_fc.h"
+#include <iostream>
+#include <iomanip>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stropts.h>
+#include <cstring>
+#include <cerrno>
+using namespace std;
+
+/**
+ * @memo Log a simple I/O error message
+ * @param message The message to log
+ */
+IOError::IOError(string message) : HBAException(HBA_STATUS_ERROR) {
+ Trace log("IOError::IOError(string)");
+ log.genericIOError("%s (%s)", message.c_str(), strerror(errno));
+}
+
+/**
+ * @memo Log a handle I/O error message
+ * @param handle The handle where the I/O error took place
+ */
+IOError::IOError(Handle *handle) : HBAException(HBA_STATUS_ERROR) {
+ Trace log("IOError::IOError(Handle)");
+ log.genericIOError(
+ "On handle %08lx (%s)", handle->getHandle(), strerror(errno));
+}
+
+/**
+ * @memo Log an HBAPort I/O error message
+ * @param port The port where the I/O error took place
+ */
+IOError::IOError(HBAPort *port) : HBAException(HBA_STATUS_ERROR) {
+ Trace log("IOError::IOError(HBAPort)");
+ log.genericIOError(
+ "On HBA port %016llx (%s)", port->getPortWWN(),
+ strerror(errno));
+}
+
+/**
+ * @memo Log a target I/O error message
+ * @param port The port where the I/O error took place
+ * @param target The target wwn which failed
+ */
+IOError::IOError(HBAPort *port, uint64_t target) :
+ HBAException(HBA_STATUS_ERROR) {
+ Trace log("IOError::IOError(HBAPort, wwn)");
+ log.genericIOError(
+ "On HBA port %016llx target %016llx (%s)", port->getPortWWN(),
+ target, strerror(errno));
+}
+
+/**
+ * @memo Log a LUN I/O error message
+ * @param port The port where the I/O error took place
+ * @param target The target wwn which failed
+ * @param lun The unit number which failed
+ */
+IOError::IOError(HBAPort *port, uint64_t target, uint64_t lun) :
+ HBAException(HBA_STATUS_ERROR) {
+ Trace log("IOError::IOError(HBAPort, wwn, lun)");
+ log.genericIOError(
+ "On HBA port %016llx target %016llx lun %016llx (%s)",
+ port->getPortWWN(),
+ target,
+ lun, strerror(errno));
+}
diff --git a/usr/src/lib/sun_fc/common/InternalError.cc b/usr/src/lib/sun_fc/common/InternalError.cc
new file mode 100644
index 0000000000..45446b30d7
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/InternalError.cc
@@ -0,0 +1,58 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Exceptions.h"
+#include "Trace.h"
+#include "sun_fc.h"
+#include <iostream>
+#include <iomanip>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stropts.h>
+#include <cstring>
+#include <cerrno>
+using namespace std;
+
+/**
+ * @memo Log a simple internal error message
+ * @param message The message to log
+ * @version 1.1
+ */
+InternalError::InternalError(string message) : HBAException(HBA_STATUS_ERROR) {
+ Trace log("InternalError::InternalError(string)");
+ log.internalError(message.c_str());
+}
+
+/**
+ * @memo Log internal error without error message
+ * @version 1.1
+ */
+InternalError::InternalError() : HBAException(HBA_STATUS_ERROR) {
+ Trace log("InternalError::InternalError()");
+}
diff --git a/usr/src/lib/sun_fc/common/LinkEvent.h b/usr/src/lib/sun_fc/common/LinkEvent.h
new file mode 100644
index 0000000000..a95b85598d
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/LinkEvent.h
@@ -0,0 +1,59 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LINKEVENT_H
+#define _LINKEVENT_H
+
+#include "Event.h"
+#include <hbaapi.h>
+
+/**
+ * @memo Represents a Link Event
+ *
+ * @doc When link events occur on the HBA, an
+ * event of this type will be sent to registered
+ * listeners
+ */
+class LinkEvent : public Event {
+public:
+ enum EVENT_TYPE {
+ UNKNOWN = HBA_EVENT_LINK_UNKNOWN,
+ INCIDENT = HBA_EVENT_LINK_INCIDENT
+ };
+ LinkEvent(uint64_t myWwn, void *myBuf, uint32_t mySize, EVENT_TYPE myType) :
+ wwn(myWwn), buf(myBuf), size(mySize), type(myType) { }
+ uint64_t getPortWWN() { return (wwn); }
+ void* getBuf() { return (buf); }
+ uint32_t getSize() { return (size); }
+ EVENT_TYPE getType() { return (type); }
+
+private:
+ uint64_t wwn;
+ void *buf;
+ uint32_t size;
+ EVENT_TYPE type;
+};
+
+#endif /* _LINKEVENT_H */
diff --git a/usr/src/lib/sun_fc/common/LinkEventBridge.h b/usr/src/lib/sun_fc/common/LinkEventBridge.h
new file mode 100644
index 0000000000..87e60d07fe
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/LinkEventBridge.h
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LINKEVENTBRIDGE_H
+#define _LINKEVENTBRIDGE_H
+
+
+
+#include "LinkEventListener.h"
+
+/**
+ * @memo Bridge interface for link events
+ *
+ * @doc Used to abstract clients from the specific
+ * underlying details of event management for
+ * the given HBA/driver stack.
+ */
+class LinkEventBridge{
+public:
+ virtual void addListener(LinkEventListener *listener, HBAPort *port) = 0;
+ virtual void removeListener(LinkEventListener *listener) = 0;
+};
+
+#endif /* _LINKEVENTBRIDGE_H */
diff --git a/usr/src/lib/sun_fc/common/LinkEventListener.cc b/usr/src/lib/sun_fc/common/LinkEventListener.cc
new file mode 100644
index 0000000000..a5a7417506
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/LinkEventListener.cc
@@ -0,0 +1,70 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "LinkEventListener.h"
+#include "LinkEvent.h"
+#include "Exceptions.h"
+#include "Trace.h"
+#include "sun_fc.h"
+
+/**
+ * @memo Create a new LinkEvent listener
+ * @postcondition Listener ready to receive callbacks
+ * @exception BadArgumentException
+ * @param myCallback The listeners callback routine
+ * @param data Opaque data that will be passed to the
+ * callback routine when and event comes in.
+ *
+ */
+LinkEventListener::LinkEventListener(LinkCallback myCallback,
+ void *data, void *myBuf, uint32_t mySize) :
+ Listener(data), callback(myCallback), buf(myBuf), size(mySize) {
+ Trace log("LinkEventListener::LinkEventListener");
+ if (callback == NULL) {
+ throw BadArgumentException();
+ }
+}
+
+/**
+ * @memo Send the event to this listener
+ * @param event The event to send to the listener
+ *
+ * @doc The callback registered in the constructor will
+ * be called.
+ */
+void LinkEventListener::dispatch(Event &event) {
+ Trace log("LinkEventListener::dispatch");
+ LinkEvent *e = static_cast<LinkEvent*> (&event);
+ if (e != NULL) {
+ HBA_WWN wwn;
+ uint64_t lwwn = htonll(e->getPortWWN());
+ memcpy(&wwn, &lwwn, sizeof (wwn));
+ callback(getData(), wwn, e->getType(), e->getBuf(), e->getSize());
+ } else {
+ log.internalError("Unexpected event type.");
+ }
+}
diff --git a/usr/src/lib/sun_fc/common/LinkEventListener.h b/usr/src/lib/sun_fc/common/LinkEventListener.h
new file mode 100644
index 0000000000..e89011230f
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/LinkEventListener.h
@@ -0,0 +1,59 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LINKEVENTLISTENER_H
+#define _LINKEVENTLISTENER_H
+
+
+
+#include "Listener.h"
+#include <hbaapi.h>
+
+/// Callback type
+typedef void (*LinkCallback)(
+ void *data,
+ HBA_WWN adapterWWN,
+ HBA_UINT32 eventType,
+ void *pRLIRBuffer,
+ HBA_UINT32 RLIRBufferSize);
+
+/**
+ * @memo Encapsulates the callback routine for event dispatch
+ *
+ * @doc This class encapsulates the event callback routine
+ * registered in the public HBA API. When dispatch
+ * is called, the stored callback routine will be called.
+ */
+class LinkEventListener: public Listener {
+public:
+ LinkEventListener(LinkCallback myCallback, void *data,
+ void *buf, uint32_t size);
+ virtual void dispatch(Event &event);
+private:
+ LinkCallback callback;
+ void *buf;
+ uint32_t size;
+};
+#endif /* _LINKEVENTLISTENER_H */
diff --git a/usr/src/lib/sun_fc/common/Listener.cc b/usr/src/lib/sun_fc/common/Listener.cc
new file mode 100644
index 0000000000..cc862aff9e
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Listener.cc
@@ -0,0 +1,112 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Listener.h"
+#include "Exceptions.h"
+#include "Lockable.h"
+
+using namespace std;
+
+/**
+ * Global lock for list of listeners
+ */
+pthread_mutex_t Listener::staticLock = PTHREAD_MUTEX_INITIALIZER;
+
+/**
+ * Global list of listeners
+ */
+vector<Listener*> Listener::listeners;
+
+/**
+ * Type for listener list iteration
+ */
+typedef vector<Listener *>::iterator ListenerIterator;
+
+/**
+ * @memo Create a new generic listener
+ * @exception ... underlying exceptions will be thrown
+ * @param userData The opaque user data for event callback
+ *
+ */
+Listener::Listener(void *userData) {
+ data = userData;
+ Lockable::lock(&staticLock);
+ try {
+ listeners.insert(listeners.begin(), this);
+ } catch (...) {
+ Lockable::unlock(&staticLock);
+ throw;
+ }
+ Lockable::unlock(&staticLock);
+}
+
+/**
+ * @memo Free up a generic listener, keeping global list in sync.
+ * @exception ... underlying exceptions will be thrown
+ */
+Listener::~Listener() {
+ Lockable::lock(&staticLock);
+ try {
+ for (ListenerIterator tmp = listeners.begin();
+ tmp != listeners.end(); tmp++) {
+ if (*tmp == this) {
+ listeners.erase(tmp);
+ Lockable::unlock(&staticLock);
+ return;
+ }
+ }
+ } catch (...) {
+ Lockable::unlock(&staticLock);
+ throw;
+ }
+ Lockable::unlock(&staticLock);
+}
+
+/**
+ * @memo Find a listener based on the callback handle
+ * @exception InvalidHandleException if the callback handle does not
+ * match any listeners
+ * @return The Listener who matches the callback handle
+ * @param cbh The callback handle
+ */
+Listener* Listener::findListener(void *cbh) {
+ Lockable::lock(&staticLock);
+ try {
+ for (ListenerIterator tmp = listeners.begin();
+ tmp != listeners.end(); tmp++) {
+ if (*tmp == cbh) {
+ Lockable::unlock(&staticLock);
+ return (*tmp);
+ }
+ }
+ } catch (...) {
+ Lockable::unlock(&staticLock);
+ throw;
+ }
+ Lockable::unlock(&staticLock);
+ throw InvalidHandleException();
+}
diff --git a/usr/src/lib/sun_fc/common/Listener.h b/usr/src/lib/sun_fc/common/Listener.h
new file mode 100644
index 0000000000..a0cf460718
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Listener.h
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LISTENER_H
+#define _LISTENER_H
+
+
+
+#include "Event.h"
+#include <vector>
+#include <pthread.h>
+
+/**
+ * @memo Generic listener super-class for event dispatch
+ *
+ * @doc All listener interfaces sub-class this interface
+ */
+class Listener {
+public:
+ Listener(void *userData);
+ ~Listener();
+ virtual void dispatch(Event &event) = 0;
+ static Listener* findListener(void *cbh);
+ void* getData() { return (data); }
+private:
+ static pthread_mutex_t staticLock;
+ static std::vector<Listener*> listeners;
+ void *data;
+};
+
+#endif /* _LISTENER_H */
diff --git a/usr/src/lib/sun_fc/common/Lockable.cc b/usr/src/lib/sun_fc/common/Lockable.cc
new file mode 100644
index 0000000000..bb9abd712d
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Lockable.cc
@@ -0,0 +1,125 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Lockable.h"
+#include <iostream>
+#include <cstdio>
+#include <cerrno>
+#include <unistd.h>
+
+using namespace std;
+
+#define DEADLOCK_WARNING 10
+#define LOCK_SLEEP 1
+
+/**
+ * @memo Create a lockable instance and initialize internal locks
+ */
+Lockable::Lockable() {
+ if (pthread_mutex_init(&mutex, NULL)) {
+ }
+}
+
+/**
+ * @memo Free up a lockable instance
+ */
+Lockable::~Lockable() {
+ if (pthread_mutex_destroy(&mutex)) {
+ }
+}
+
+/**
+ * @memo Unlock the instance
+ * @precondition This thread must have locked the instance
+ * @postcondition The instance will be unlocked
+ */
+void Lockable::unlock() {
+ unlock(&mutex);
+}
+
+/**
+ * @memo Unlock a given mutex lock
+ * @precondition The lock must be held by this thread
+ * @postcondition The lock will be released
+ * @param myMutex The lock to unlock
+ */
+void Lockable::unlock(pthread_mutex_t *myMutex) {
+ pthread_mutex_unlock(myMutex);
+}
+
+/**
+ * @memo Lock the instance
+ * @postcondition The lock will be held by this thread.
+ */
+void Lockable::lock() {
+ lock(&mutex);
+}
+
+/**
+ * @memo Lock the given mutex lock
+ * @postcondition The lock will be held by this thread
+ * @param myMutex The mutex lock to take
+ */
+void Lockable::lock(pthread_mutex_t *myMutex) {
+ int status;
+ int loop = 0;
+ do {
+ loop++;
+ status = pthread_mutex_trylock(myMutex);
+ if (status) {
+ switch (pthread_mutex_trylock(myMutex)) {
+ case EFAULT:
+ cerr << "Lock failed: Fault" << endl;
+ break;
+ case EINVAL:
+ cerr << "Lock failed: Invalid" << endl;
+ break;
+ case EBUSY:
+ if (loop > DEADLOCK_WARNING) {
+ cerr << "Lock failed: Deadlock" << endl;
+ }
+ break;
+ case EOWNERDEAD:
+ cerr << "Lock failed: Owner died" << endl;
+ break;
+ case ELOCKUNMAPPED:
+ cerr << "Lock failed: Unmapped" << endl;
+ break;
+ case ENOTRECOVERABLE:
+ cerr << "Lock failed: not recoverable" << endl;
+ default:
+ if (loop > DEADLOCK_WARNING) {
+ cerr << "Lock failed: " <<strerror(status) << endl;
+ break;
+ }
+ }
+ } else {
+ break; // Lock taken succesfully
+ }
+ sleep(LOCK_SLEEP);
+ } while (status);
+}
diff --git a/usr/src/lib/sun_fc/common/Lockable.h b/usr/src/lib/sun_fc/common/Lockable.h
new file mode 100644
index 0000000000..5f2254732a
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Lockable.h
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LOCKABLE_H
+#define _LOCKABLE_H
+
+
+
+#include <pthread.h>
+
+/**
+ * @memo Utility class to abstract away locking primitives
+ */
+class Lockable {
+public:
+ static void lock(pthread_mutex_t* mutex);
+ static void unlock(pthread_mutex_t* mutex);
+protected:
+ Lockable();
+ ~Lockable();
+ void lock();
+ void unlock();
+
+private:
+ pthread_mutex_t mutex;
+};
+
+#endif /* _LOCKABLE_H */
diff --git a/usr/src/lib/sun_fc/common/Sun_fcAdapterCreateWWN.cc b/usr/src/lib/sun_fc/common/Sun_fcAdapterCreateWWN.cc
new file mode 100644
index 0000000000..8e1f607530
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcAdapterCreateWWN.cc
@@ -0,0 +1,111 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include <fstream>
+#include "fcntl.h"
+#include "Handle.h"
+#include "Trace.h"
+#include "Exceptions.h"
+#include "sun_fc.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void get_random_bytes(HBA_UINT8 *ptr, size_t len) {
+ int fd = open("/dev/urandom", O_RDONLY);
+ size_t resid = len;
+ ssize_t bytes;
+
+ while (resid != 0) {
+ bytes = read(fd, ptr, resid);
+ ptr += bytes;
+ resid -= bytes;
+ }
+ close (fd);
+ return;
+}
+
+HBA_STATUS Sun_fcAdapterCreateWWN(HBA_HANDLE handle,
+ HBA_UINT32 portindex, HBA_WWN *nwwn, HBA_WWN *pwwn,
+ HBA_WWN *OUI, HBA_INT32 method) {
+ HBA_UINT8 randombyte[5] = {0};
+ HBA_WWN randomwwn = {0};
+ int index = 0;
+
+ Trace log("Sun_fcAdapterCreateWWN");
+
+ if ((nwwn == NULL) || (pwwn == NULL)) {
+ log.userError(
+ "NULL WWN pointer");
+ return (HBA_STATUS_ERROR_ARG);
+ }
+ if (method == HBA_CREATE_WWN_FACTORY) {
+ return (HBA_STATUS_ERROR_NOT_SUPPORTED);
+ }
+
+ try {
+ /* create EUI-64 Mapped WWN */
+ if (OUI == NULL) {
+ /* if no OUI spec'd, used one of Sun's */
+ randomwwn.wwn[index++] = 0x0;
+ randomwwn.wwn[index++] = 0x0;
+ randomwwn.wwn[index++] = 0x7D;
+ } else {
+ memcpy(randomwwn.wwn, OUI->wwn, sizeof(HBA_WWN));
+ index += 3;
+ }
+ /*
+ * for EUI-64 mapped, shift OUI first byte right two bits
+ * then set top two bits to 11
+ */
+ randomwwn.wwn[0] = randomwwn.wwn[0] >> 2;
+ randomwwn.wwn[0] = randomwwn.wwn[0] | 0xc0;
+
+ /* now create and add 40 random bits */
+ get_random_bytes(randombyte, 5);
+ memcpy(randomwwn.wwn+index, randombyte, 5);
+
+ memcpy(nwwn->wwn, randomwwn.wwn, sizeof(HBA_WWN));
+
+ /* toggle lowest bit, to make NWWN and PWWN unique */
+ randomwwn.wwn[7] = randomwwn.wwn[7] ^ 1;
+ memcpy(pwwn->wwn, randomwwn.wwn, sizeof(HBA_WWN));
+
+ return (HBA_STATUS_OK);
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcAdapterReturnWWN.cc b/usr/src/lib/sun_fc/common/Sun_fcAdapterReturnWWN.cc
new file mode 100644
index 0000000000..ac3137376b
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcAdapterReturnWWN.cc
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Handle.h"
+#include "Trace.h"
+#include "Exceptions.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+HBA_STATUS Sun_fcAdapterReturnWWN(HBA_HANDLE handle,
+ HBA_UINT32 portindex, HBA_WWN *nwwn,
+ HBA_WWN *pwwn) {
+ Trace log("Sun_fcAdapterReturnWWN");
+ return (HBA_STATUS_ERROR_NOT_SUPPORTED);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/usr/src/lib/sun_fc/common/Sun_fcCloseAdapter.cc b/usr/src/lib/sun_fc/common/Sun_fcCloseAdapter.cc
new file mode 100644
index 0000000000..3c06b5ea26
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcCloseAdapter.cc
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Handle.h"
+#include "Trace.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Closes an adapter
+ * @precondition Handle must be valid and open
+ * @postcondition Handle will be closed and should be discarded by caller
+ * @param handle the handle to close
+ *
+ * @doc See T11 FC-HBA for standard definition
+ */
+void Sun_fcCloseAdapter(HBA_HANDLE handle) {
+ Trace log("Sun_fcCloseAdapter");
+ try {
+ Handle::closeHandle(handle);
+ } catch (...) {
+ log.internalError("Uncaught exception");
+ return;
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcCreateNPIVPort.cc b/usr/src/lib/sun_fc/common/Sun_fcCreateNPIVPort.cc
new file mode 100644
index 0000000000..35bf620673
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcCreateNPIVPort.cc
@@ -0,0 +1,58 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#include "sun_fc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+HBA_STATUS Sun_fcCreateNPIVPort(HBA_HANDLE handle, HBA_UINT32 portindex,
+ HBA_WWN vnodeWWN, HBA_WWN vportWWN, HBA_UINT32 *vportindex) {
+
+ Trace log("Sun_fcCreateNPIVPort");
+
+ try {
+ Handle *myHandle = Handle::findHandle(handle);
+ HandlePort *myPort = myHandle->getHandlePortByIndex(portindex);
+ *vportindex = myPort->createNPIVPort(wwnConversion(vnodeWWN.wwn),
+ wwnConversion(vportWWN.wwn), *vportindex);
+ return (HBA_STATUS_OK);
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/usr/src/lib/sun_fc/common/Sun_fcDeleteNPIVPort.cc b/usr/src/lib/sun_fc/common/Sun_fcDeleteNPIVPort.cc
new file mode 100644
index 0000000000..762ae7d805
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcDeleteNPIVPort.cc
@@ -0,0 +1,57 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#include "sun_fc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+HBA_STATUS Sun_fcDeleteNPIVPort(HBA_HANDLE handle, HBA_UINT32 portindex,
+ HBA_WWN vportWWN) {
+
+ Trace log("Sun_fcGetNPIVPortInfo");
+
+ try {
+ Handle *myHandle = Handle::findHandle(handle);
+ HandlePort *myPort = myHandle->getHandlePortByIndex(portindex);
+ myPort->deleteNPIVPort(wwnConversion(vportWWN.wwn));
+ return (HBA_STATUS_OK);
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/usr/src/lib/sun_fc/common/Sun_fcFreeLibrary.cc b/usr/src/lib/sun_fc/common/Sun_fcFreeLibrary.cc
new file mode 100644
index 0000000000..7a51da33a6
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcFreeLibrary.cc
@@ -0,0 +1,58 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "HBAList.h"
+#include "Trace.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Frees the HBA Library.
+ * @precondition Library must have been loaded previously
+ * @postcondition Library will be free. No further APIs should be called
+ * except LoadLibrary
+ * @return HBA_STATUS_OK if library was unloaded properly
+ * @return HBA_STATUS_ERROR if library was not unloaded
+ *
+ * @doc See T11 FC-HBA for standard definition
+ */
+HBA_STATUS Sun_fcFreeLibrary() {
+ Trace log("Sun_fcFreeLibrary");
+ try {
+ HBAList* list = HBAList::instance();
+ HBA_STATUS status = list->unload();
+ delete (list);
+ return (status);
+ } catch (...) {
+ log.internalError("Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcGetAdapterAttributes.cc b/usr/src/lib/sun_fc/common/Sun_fcGetAdapterAttributes.cc
new file mode 100644
index 0000000000..a2ccf50c50
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcGetAdapterAttributes.cc
@@ -0,0 +1,67 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Handle.h"
+#include "Trace.h"
+#include "Exceptions.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Retrieves the attributes for an adapter
+ * @precondition Library must be loaded
+ * @return HBA_STATUS_OK if attributes were filled in
+ * @param handle The desired HBA
+ * @param attributes The user-allocated buffer
+ *
+ */
+HBA_STATUS Sun_fcGetAdapterAttributes(HBA_HANDLE handle,
+ PHBA_ADAPTERATTRIBUTES attributes) {
+ Trace log("Sun_fcGetAdapterAttributes");
+
+ if (attributes == NULL) {
+ log.userError(
+ "NULL attributes pointer");
+ return (HBA_STATUS_ERROR_ARG);
+ }
+
+ try {
+ Handle *myHandle = Handle::findHandle(handle);
+ *attributes = myHandle->getHBAAttributes();
+ return (HBA_STATUS_OK);
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcGetAdapterName.cc b/usr/src/lib/sun_fc/common/Sun_fcGetAdapterName.cc
new file mode 100644
index 0000000000..fb9b6db605
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcGetAdapterName.cc
@@ -0,0 +1,70 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "HBAList.h"
+#include "Trace.h"
+#include "Exceptions.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Get the adapters name
+ * @precondition name parameter must be sufficient length to fit the name
+ * @postcondition name contains the name of the given adapter
+ * @return HBA_STATUS_OK on success, or other error code
+ * @param index the index to which adapter to retrieve the name
+ * @param name buffer to which the adapter name will be placed
+ *
+ * @doc
+ * Returns the text string which describes this adapter and which is used to
+ * open the adapter with the library.
+ */
+HBA_STATUS Sun_fcGetAdapterName(HBA_UINT32 index, char *name) {
+ Trace log("Sun_fcGetAdapterName");
+ if (name == NULL) {
+ log.userError(
+ "NULL name pointer");
+ return (HBA_STATUS_ERROR_ARG);
+ }
+ try {
+ HBAList* list = HBAList::instance();
+ std::string sname = list->getHBAName(index);
+ strcpy(name, sname.c_str());
+ return (HBA_STATUS_OK);
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcGetAdapterPortAttributes.cc b/usr/src/lib/sun_fc/common/Sun_fcGetAdapterPortAttributes.cc
new file mode 100644
index 0000000000..2268224202
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcGetAdapterPortAttributes.cc
@@ -0,0 +1,70 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Handle.h"
+#include "HandlePort.h"
+#include "Trace.h"
+#include "Exceptions.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Retrieves the attributes for a specified port of an adapter
+ * @precondition Library is loaded
+ * @return HBA_STATUS_OK if attributes were filled in
+ * @param handle The desired HBA
+ * @param port The desired HBA port
+ * @param attributes The user-allocated buffer to store results in
+ *
+ */
+HBA_STATUS Sun_fcGetAdapterPortAttributes(HBA_HANDLE handle,
+ HBA_UINT32 port, PHBA_PORTATTRIBUTES attributes) {
+ Trace log("Sun_fcGetAdapterPortAttributes");
+
+ if (attributes == NULL) {
+ log.userError(
+ "NULL attributes pointer");
+ return (HBA_STATUS_ERROR_ARG);
+ }
+
+ try {
+ Handle *myHandle = Handle::findHandle(handle);
+ HandlePort *myPort = myHandle->getHandlePortByIndex(port);
+ *attributes = myPort->getPortAttributes();
+ return (HBA_STATUS_OK);
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcGetBindingCapability.cc b/usr/src/lib/sun_fc/common/Sun_fcGetBindingCapability.cc
new file mode 100644
index 0000000000..5b61e0a991
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcGetBindingCapability.cc
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Not Supported
+ */
+/*ARGSUSED*/
+HBA_STATUS Sun_fcGetBindingCapability(HBA_HANDLE hande,
+ HBA_WWN portWWN, HBA_BIND_CAPABILITY *caps) {
+ Trace log("Sun_fcGetBindingCapability");
+ return (HBA_STATUS_ERROR_NOT_SUPPORTED);
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcGetBindingSupport.cc b/usr/src/lib/sun_fc/common/Sun_fcGetBindingSupport.cc
new file mode 100644
index 0000000000..4b8844cde5
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcGetBindingSupport.cc
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Not Supported
+ */
+/*ARGSUSED*/
+HBA_STATUS Sun_fcGetBindingSupport(HBA_HANDLE hande, HBA_WWN portWWN,
+ HBA_BIND_CAPABILITY *caps) {
+ Trace log("Sun_fcGetBindingSupport");
+ return (HBA_STATUS_ERROR_NOT_SUPPORTED);
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcGetDiscPortAttrs.cc b/usr/src/lib/sun_fc/common/Sun_fcGetDiscPortAttrs.cc
new file mode 100644
index 0000000000..143de59db3
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcGetDiscPortAttrs.cc
@@ -0,0 +1,72 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Handle.h"
+#include "HandlePort.h"
+#include "Trace.h"
+#include "Exceptions.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Retrieves the attributes for a specified port discovered
+ * in the network
+ * @return HBA_STATUS_OK if the attributes were filled in
+ * @param handle The handle for the desired HBA
+ * @param port The index of desired HBA port
+ * @param discoverdPort The index of the desired discovered port
+ * @param attributes The user-allocated buffer to store the attrs
+ *
+ */
+HBA_STATUS Sun_fcGetDiscoveredPortAttributes(HBA_HANDLE handle,
+ HBA_UINT32 port, HBA_UINT32 discoveredport,
+ PHBA_PORTATTRIBUTES attributes) {
+ Trace log("Sun_fcGetDiscoveredPortAttributes");
+
+ if (attributes == NULL) {
+ log.userError(
+ "NULL attributes pointer");
+ return (HBA_STATUS_ERROR_ARG);
+ }
+
+ try {
+ Handle *myHandle = Handle::findHandle(handle);
+ HandlePort *myPort = myHandle->getHandlePortByIndex(port);
+ *attributes = myPort->getDiscoveredAttributes(discoveredport);
+ return (HBA_STATUS_OK);
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcGetEventBuffer.cc b/usr/src/lib/sun_fc/common/Sun_fcGetEventBuffer.cc
new file mode 100644
index 0000000000..bbf388dc21
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcGetEventBuffer.cc
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Not supported
+ */
+/*ARGSUSED*/
+HBA_STATUS Sun_fcGetEventBuffer(HBA_HANDLE handle,
+ PHBA_EVENTINFO buffer, HBA_UINT32 *count) {
+ Trace log("Sun_fcGetEventBuffer");
+ return (HBA_STATUS_ERROR_NOT_SUPPORTED);
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcGetFC4Statistics.cc b/usr/src/lib/sun_fc/common/Sun_fcGetFC4Statistics.cc
new file mode 100644
index 0000000000..13f6131dda
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcGetFC4Statistics.cc
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Not Supported
+ */
+/*ARGSUSED*/
+HBA_STATUS Sun_fcGetFC4Statistics(HBA_HANDLE handle,
+ HBA_WWN portWWN,
+ HBA_UINT8 FC4type,
+ HBA_FC4STATISTICS *pstatistics) {
+ Trace log("Sun_fcGetFC4Statistics");
+ return (HBA_STATUS_ERROR_NOT_SUPPORTED);
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcGetFCPStatistics.cc b/usr/src/lib/sun_fc/common/Sun_fcGetFCPStatistics.cc
new file mode 100644
index 0000000000..f996c95948
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcGetFCPStatistics.cc
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Not Supported
+ */
+/*ARGSUSED*/
+HBA_STATUS Sun_fcGetFCPStatistics(HBA_HANDLE handle,
+ const HBA_SCSIID *lunit,
+ HBA_FC4STATISTICS *pstatistics) {
+ Trace log("Sun_fcGetFCPStatistics");
+ return (HBA_STATUS_ERROR_NOT_SUPPORTED);
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcGetFcpPersistentBinding.cc b/usr/src/lib/sun_fc/common/Sun_fcGetFcpPersistentBinding.cc
new file mode 100644
index 0000000000..6574b39055
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcGetFcpPersistentBinding.cc
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Not Supported
+ */
+/*ARGSUSED*/
+HBA_STATUS Sun_fcGetFcpPersistentBinding(HBA_HANDLE handle,
+ PHBA_FCPBINDING binding) {
+
+ Trace log("Sun_fcGetFcpPersistentBinding");
+
+ if (binding == NULL) {
+ log.userError("NULL mapping argument.");
+ return (HBA_STATUS_ERROR_ARG);
+ }
+ /* on error, need to set NumberOfEntries to 0 */
+ binding->NumberOfEntries = 0;
+ return (HBA_STATUS_ERROR_NOT_SUPPORTED);
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcGetFcpTargetMapping.cc b/usr/src/lib/sun_fc/common/Sun_fcGetFcpTargetMapping.cc
new file mode 100644
index 0000000000..7a08e91b3b
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcGetFcpTargetMapping.cc
@@ -0,0 +1,110 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#include "sun_fc.h"
+
+
+
+#include <string.h>
+#include "Handle.h"
+#include "HBA.h"
+#include "HBAPort.h"
+inline HBA_WWN
+getFirstAdapterPortWWN(HBA_HANDLE handle) {
+ HBA_WWN hba_wwn;
+ memset(hba_wwn.wwn, 0, sizeof (hba_wwn));
+ try {
+ Handle *myHandle = Handle::findHandle(handle);
+ HBA *hba = myHandle->getHBA();
+ HBAPort *port = hba->getPortByIndex(0);
+ uint64_t tmp = htonll(port->getPortWWN());
+ memcpy(hba_wwn.wwn, &tmp, sizeof (hba_wwn));
+ } catch (...) { }
+ return (hba_wwn);
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Retrieves the mapping between FCP targets and OS
+ * SCSI information
+ * @return HBA_STATUS_OK if the mapping structure contains valid
+ * mapping data.
+ * @param handle The HBA to fetch mappings for
+ * @param mapping The user-allocated mapping structure
+ *
+ * @doc This routine will call the V2 interface and convert
+ * the results to the old data structure. It will
+ * call the V2 interface for all ports on the HBA.
+ */
+HBA_STATUS
+Sun_fcGetFcpTargetMapping(HBA_HANDLE handle, PHBA_FCPTARGETMAPPING mapping) {
+ HBA_STATUS status;
+ int count;
+ PHBA_FCPTARGETMAPPINGV2 mappingV2;
+
+ Trace log("Sun_fcGetFcpTargetMapping");
+
+ if (mapping == NULL) {
+ log.userError("NULL mapping argument.");
+ return (HBA_STATUS_ERROR_ARG);
+ }
+ mappingV2 = (PHBA_FCPTARGETMAPPINGV2) new uchar_t[
+ (sizeof (HBA_FCPSCSIENTRYV2)*(mapping->NumberOfEntries-1)) +
+ sizeof (HBA_FCPTARGETMAPPINGV2)];
+ mappingV2->NumberOfEntries = mapping->NumberOfEntries;
+
+
+
+ status = Sun_fcGetFcpTargetMappingV2(handle,
+ getFirstAdapterPortWWN(handle), mappingV2);
+ mapping->NumberOfEntries = mappingV2->NumberOfEntries;
+ if (status == HBA_STATUS_OK) {
+ /*
+ * need to copy from PHBA_FCPTARGETMAPPINGV2 to
+ * PHBA_FCPTARGETMAPPING
+ */
+ for (count = 0; count < mapping->NumberOfEntries; count++) {
+ memcpy(&mapping->entry[count].ScsiId,
+ &mappingV2->entry[count].ScsiId,
+ sizeof (mapping->entry[count].ScsiId));
+ memcpy(&mapping->entry[count].FcpId,
+ &mappingV2->entry[count].FcpId,
+ sizeof (mapping->entry[count].FcpId));
+ }
+ }
+
+ delete(mappingV2);
+ return (status);
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcGetFcpTargetMappingV2.cc b/usr/src/lib/sun_fc/common/Sun_fcGetFcpTargetMappingV2.cc
new file mode 100644
index 0000000000..0187d20efb
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcGetFcpTargetMappingV2.cc
@@ -0,0 +1,77 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Handle.h"
+#include "HBA.h"
+#include "HBAPort.h"
+#include "Trace.h"
+#include "Exceptions.h"
+#include "sun_fc.h"
+#include <sys/types.h>
+#include <sys/mkdev.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stropts.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Retrieves the mapping between FCP targets and OS
+ * SCSI information
+ * @return HBA_STATUS_OK if userMappings contains valid response data
+ * @return HBA_STATUS_ERROR if an error was encountered. The
+ * contents of userMappings is undefined
+ * @param handle The HBA to fetch mappings on
+ * @param portWWN The HBA Port to fetch mappings on
+ * @param userMappings a pre-allocated user structure to store
+ * the mappings within. NumberOfEntries must be set
+ * to indicate the size of the allocated buffer.
+ *
+ */
+HBA_STATUS Sun_fcGetFcpTargetMappingV2(HBA_HANDLE handle, HBA_WWN portWWN,
+ PHBA_FCPTARGETMAPPINGV2 userMappings) {
+ Trace log("Sun_fcGetFcpTargetMappingV2");
+
+ try {
+ Handle *myHandle = Handle::findHandle(handle);
+ HBA *hba = myHandle->getHBA();
+ HBAPort *port = hba->getPort(wwnConversion(portWWN.wwn));
+ port->getTargetMappings(userMappings);
+ return (HBA_STATUS_OK);
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcGetNPIVPortInfo.cc b/usr/src/lib/sun_fc/common/Sun_fcGetNPIVPortInfo.cc
new file mode 100644
index 0000000000..3dae39ceb9
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcGetNPIVPortInfo.cc
@@ -0,0 +1,57 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#include "sun_fc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+HBA_STATUS Sun_fcGetNPIVPortInfo(HBA_HANDLE handle, HBA_UINT32 portindex,
+ HBA_UINT32 vportindex, HBA_NPIVATTRIBUTES *attributes) {
+
+ Trace log("Sun_fcGetNPIVPortInfo");
+ try {
+ Handle *myHandle = Handle::findHandle(handle);
+ HandlePort *myPort = myHandle->getHandlePortByIndex(portindex);
+ HandleNPIVPort *myNPIVPort = myPort->getHandleNPIVPortByIndex(vportindex);
+ *attributes = myNPIVPort->getPortAttributes();
+ return (HBA_STATUS_OK);
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/usr/src/lib/sun_fc/common/Sun_fcGetNumberOfAdapters.cc b/usr/src/lib/sun_fc/common/Sun_fcGetNumberOfAdapters.cc
new file mode 100644
index 0000000000..d1956c849a
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcGetNumberOfAdapters.cc
@@ -0,0 +1,59 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "HBAList.h"
+#include "Trace.h"
+#include <libdevinfo.h>
+
+/**
+ * @memo Returns the number of HBAs supported by the library.
+ * @precondition Load library must have been called
+ * @return The number of adapters detected by this VSL
+ * @doc Refer to the HBAList documentation for behavior
+ * @see HBAList::getNnumberofAdapters
+ *
+ */
+extern "C" HBA_UINT32 Sun_fcGetNumberOfAdapters() {
+ Trace log("Sun_fcGetNumberOfAdapters");
+ try {
+ HBAList* list = HBAList::instance();
+ HBA_UINT32 ret = list->getNumberofAdapters();
+ if (ret == 0) {
+ /* run di_init to forceattach fp and retry it */
+ di_node_t root_node;
+ if ((root_node = di_init("/", DINFOSUBTREE|DINFOFORCE)) != DI_NODE_NIL) {
+ di_fini(root_node);
+ return (list->getNumberofAdapters());
+ }
+ }
+ return (ret);
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (0);
+ }
+}
diff --git a/usr/src/lib/sun_fc/common/Sun_fcGetNumberOfTgtAdapters.cc b/usr/src/lib/sun_fc/common/Sun_fcGetNumberOfTgtAdapters.cc
new file mode 100644
index 0000000000..a7f09b3371
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcGetNumberOfTgtAdapters.cc
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "HBAList.h"
+#include "Trace.h"
+
+/**
+ * @memo Returns the number of HBAs supported by the library.
+ * @precondition Load library must have been called
+ * @return The number of adapters detected by this VSL
+ * @doc Refer to the HBAList documentation for behavior
+ * @see HBAList::getNnumberofAdapters
+ *
+ */
+extern "C" HBA_UINT32 Sun_fcGetNumberOfTgtAdapters() {
+ Trace log("Sun_fcGetNumberOfTgtAdapters");
+ try {
+ HBAList* list = HBAList::instance();
+ return (list->getNumberofTgtAdapters());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (0);
+ }
+}
diff --git a/usr/src/lib/sun_fc/common/Sun_fcGetPersistentBindingV2.cc b/usr/src/lib/sun_fc/common/Sun_fcGetPersistentBindingV2.cc
new file mode 100644
index 0000000000..89f9644f97
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcGetPersistentBindingV2.cc
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Not Supported
+ */
+/*ARGSUSED*/
+HBA_STATUS Sun_fcGetPersistentBindingV2(HBA_HANDLE hande,
+ HBA_WWN portWWN, HBA_FCPBINDING2 *binding) {
+ Trace log("Sun_fcGetPersistentBindingV2");
+ return (HBA_STATUS_ERROR_NOT_SUPPORTED);
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcGetPortAttributesByWWN.cc b/usr/src/lib/sun_fc/common/Sun_fcGetPortAttributesByWWN.cc
new file mode 100644
index 0000000000..f5fa86211f
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcGetPortAttributesByWWN.cc
@@ -0,0 +1,66 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#include "sun_fc.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Retrieves the attributes for a specific discovered port
+ * by WWN
+ * @return HBA_STATUS_OK if the attributes are filled in
+ * @param handle The HBA to operate on
+ * @param pwwn The wwn of the desired target
+ * @param attributes The user-allocated attributes buffer
+ *
+ */
+HBA_STATUS Sun_fcGetPortAttributesByWWN(HBA_HANDLE handle, HBA_WWN pwwn,
+ PHBA_PORTATTRIBUTES attributes) {
+ Trace log("Sun_fcGetPortAttributesByWWN");
+
+ if (attributes == NULL) {
+ log.userError("NULL attributes pointer");
+ return (HBA_STATUS_ERROR_ARG);
+ }
+
+ try {
+ Handle *myHandle = Handle::findHandle(handle);
+ *attributes = myHandle->getPortAttributes(wwnConversion(pwwn.wwn));
+ return (HBA_STATUS_OK);
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError("Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcGetPortNPIVAttributes.cc b/usr/src/lib/sun_fc/common/Sun_fcGetPortNPIVAttributes.cc
new file mode 100644
index 0000000000..1bf61c3d68
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcGetPortNPIVAttributes.cc
@@ -0,0 +1,62 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#include "sun_fc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+HBA_STATUS Sun_fcGetPortNPIVAttributes(HBA_HANDLE handle,
+ HBA_UINT32 port, PHBA_PORTNPIVATTRIBUTES attributes) {
+
+ Trace log("Sun_fcGetPortNPIVAttributes");
+ if (attributes == NULL) {
+ log.userError(
+ "NULL attributes pointer");
+ return (HBA_STATUS_ERROR_ARG);
+ }
+
+ try {
+ Handle *myHandle = Handle::findHandle(handle);
+ HandlePort *myPort = myHandle->getHandlePortByIndex(port);
+ *attributes = myPort->getPortNPIVAttributes();
+ return (HBA_STATUS_OK);
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/usr/src/lib/sun_fc/common/Sun_fcGetPortStatistics.cc b/usr/src/lib/sun_fc/common/Sun_fcGetPortStatistics.cc
new file mode 100644
index 0000000000..7548fa6ef6
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcGetPortStatistics.cc
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Not Supported
+ */
+HBA_STATUS Sun_fcGetPortStatistics(HBA_HANDLE handle,
+ HBA_UINT32 port, PHBA_PORTSTATISTICS statistics) {
+ Trace log("Sun_fcGetPortStatistics");
+
+ // Validate the arguments
+ if (statistics == NULL) {
+ log.userError("NULL response buffer");
+ return (HBA_STATUS_ERROR_ARG);
+ }
+
+ return (HBA_STATUS_ERROR_NOT_SUPPORTED);
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcGetRNIDMgmtInfo.cc b/usr/src/lib/sun_fc/common/Sun_fcGetRNIDMgmtInfo.cc
new file mode 100644
index 0000000000..6a9bb77cdb
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcGetRNIDMgmtInfo.cc
@@ -0,0 +1,71 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#include "Handle.h"
+#include "HBA.h"
+#include "HBAPort.h"
+#include "sun_fc.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stropts.h>
+#include <errno.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+/**
+ * @memo Returns the RNID from port 0 on the HBA
+ * @return HBA_STATUS_OK if value is fetched
+ * @param handle The HBA to operate on
+ * @param info Pointer to user-allocated buffer for results
+ */
+HBA_STATUS Sun_fcGetRNIDMgmtInfo(HBA_HANDLE handle,
+ PHBA_MGMTINFO info) {
+ Trace log("Sun_fcGetRNIDMgmtInfo");
+
+ try {
+ Handle *myHandle = Handle::findHandle(handle);
+ HBA *hba = myHandle->getHBA();
+ HBAPort *port = hba->getPortByIndex(0); // Always use port zero
+ port->getRNIDMgmtInfo(info);
+ return (HBA_STATUS_OK);
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError("Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcGetTgtAdapterName.cc b/usr/src/lib/sun_fc/common/Sun_fcGetTgtAdapterName.cc
new file mode 100644
index 0000000000..6a5ae00294
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcGetTgtAdapterName.cc
@@ -0,0 +1,70 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "HBAList.h"
+#include "Trace.h"
+#include "Exceptions.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Get the adapters name
+ * @precondition name parameter must be sufficient length to fit the name
+ * @postcondition name contains the name of the given adapter
+ * @return HBA_STATUS_OK on success, or other error code
+ * @param index the index to which adapter to retrieve the name
+ * @param name buffer to which the adapter name will be placed
+ *
+ * @doc
+ * Returns the text string which describes this adapter and which is used to
+ * open the adapter with the library.
+ */
+HBA_STATUS Sun_fcGetTgtAdapterName(HBA_UINT32 index, char *name) {
+ Trace log("Sun_fcGetTgtAdapterName");
+ if (name == NULL) {
+ log.userError(
+ "NULL name pointer");
+ return (HBA_STATUS_ERROR_ARG);
+ }
+ try {
+ HBAList* list = HBAList::instance();
+ std::string sname = list->getTgtHBAName(index);
+ strcpy(name, sname.c_str());
+ return (HBA_STATUS_OK);
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcGetVendorLibraryAttributes.cc b/usr/src/lib/sun_fc/common/Sun_fcGetVendorLibraryAttributes.cc
new file mode 100644
index 0000000000..a2d9b7f1dc
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcGetVendorLibraryAttributes.cc
@@ -0,0 +1,63 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#include "sun_fc_version.h"
+#include "HBAList.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Return information about this vendor library
+ * @return The version of the API we support
+ * @param attrs The user-allocated buffer
+ */
+HBA_UINT32
+Sun_fcGetVendorLibraryAttributes(HBA_LIBRARYATTRIBUTES *attrs) {
+ Trace log("Sun_fcGetVendorLibraryAttributes");
+
+ /* Validate the arguments */
+ if (attrs == NULL) {
+ log.userError("NULL attrs structure");
+ return (VSL_NUMERIC_VERSION);
+ }
+ try {
+ HBAList* list = HBAList::instance();
+ *attrs = list->getVSLAttributes();
+ return (VSL_NUMERIC_VERSION);
+ } catch (...) {
+ log.internalError("Uncaught exception");
+ memset(attrs, 0, sizeof (*attrs));
+ return (VSL_NUMERIC_VERSION);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcGetVersion.cc b/usr/src/lib/sun_fc/common/Sun_fcGetVersion.cc
new file mode 100644
index 0000000000..d6be3fdf43
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcGetVersion.cc
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "sun_fc_version.h"
+#include "Exceptions.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Returns the version which the common HBA API library
+ * is compatible with.
+ * @return The version of the library
+ */
+HBA_UINT32 Sun_fcGetVersion() {
+ return (VSL_NUMERIC_VERSION);
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcLoadLibrary.cc b/usr/src/lib/sun_fc/common/Sun_fcLoadLibrary.cc
new file mode 100644
index 0000000000..23f0283daf
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcLoadLibrary.cc
@@ -0,0 +1,58 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "HBAList.h"
+#include "Exceptions.h"
+#include "Trace.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Loads the HBA Library.
+ * @precondition Load library not called previouslly (or free called)
+ * @postcondition On success, other library APIs may be called
+ * @exception LIST_OF_EXCEPTIONS
+ * @return HBA_STATUS_OK library properly loaded
+ * @return HBA_STATUS_ERROR library loaded incorrectly
+ *
+ * @doc Must be called before calling any HBA library functions
+ */
+HBA_STATUS Sun_fcLoadLibrary() {
+ Trace log("Sun_fcLoadLibrary");
+ try {
+ HBAList* list = HBAList::instance();
+ return (list->load());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcNPIVGetAdapterAttributes.cc b/usr/src/lib/sun_fc/common/Sun_fcNPIVGetAdapterAttributes.cc
new file mode 100644
index 0000000000..6791fd8021
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcNPIVGetAdapterAttributes.cc
@@ -0,0 +1,59 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#include "Handle.h"
+#include "Trace.h"
+#include "Exceptions.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+HBA_STATUS Sun_fcNPIVGetAdapterAttributes(HBA_HANDLE handle,
+ PHBA_ADAPTERATTRIBUTES attributes) {
+ Trace log("Sun_fcNPIVGetAdapterAttributes");
+
+ if (attributes == NULL) {
+ log.userError(
+ "NULL attributes pointer");
+ return (HBA_STATUS_ERROR_ARG);
+ }
+
+ try {
+ Handle *myHandle = Handle::findHandle(handle);
+ *attributes = myHandle->npivGetHBAAttributes();
+ return (HBA_STATUS_OK);
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/usr/src/lib/sun_fc/common/Sun_fcOpenAdapter.cc b/usr/src/lib/sun_fc/common/Sun_fcOpenAdapter.cc
new file mode 100644
index 0000000000..43c02cba77
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcOpenAdapter.cc
@@ -0,0 +1,63 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "HBAList.h"
+#include "Handle.h"
+#include "Exceptions.h"
+
+#define HANDLE_ERROR 0
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Opens a named adapter.
+ * @precondition Library already loaded
+ * @postcondition Open handle must be closed at a later point in time
+ * @return An open handle, or (0) on error
+ * @param name The name of the adapter to open
+ */
+HBA_HANDLE Sun_fcOpenAdapter(char *name) {
+ Trace log("Sun_fcOpenAdapter");
+ if (name == NULL) {
+ log.userError("Null argument");
+ return (HANDLE_ERROR);
+ }
+
+ try {
+ return (HBAList::instance()->openHBA(name)->getHandle());
+ } catch (HBAException &e) {
+ return (0);
+ } catch (...) {
+ log.internalError("Uncaught exception");
+ return (0);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcOpenAdapterByWWN.cc b/usr/src/lib/sun_fc/common/Sun_fcOpenAdapterByWWN.cc
new file mode 100644
index 0000000000..fa62d98ef3
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcOpenAdapterByWWN.cc
@@ -0,0 +1,65 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Handle.h"
+#include "HBAList.h"
+#include "Exceptions.h"
+#include "Trace.h"
+#include "sun_fc.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Opens a adapter based on the specified WWN.
+ * @return HBA_STATUS_OK if adapter was opened
+ * @param handle Output argument where open handle is stored
+ * @param wwn The Node or Port WWN of the HBA to open
+ */
+HBA_STATUS Sun_fcOpenAdapterByWWN(HBA_HANDLE *handle, HBA_WWN wwn) {
+ Trace log("Sun_fcOpenAdapterByWWN");
+
+ // Validate args
+ if (handle == NULL) {
+ log.userError("NULL handle pointer");
+ return (HBA_STATUS_ERROR_ARG);
+ }
+ try {
+ *handle = HBAList::instance()->
+ openHBA(wwnConversion(wwn.wwn))->getHandle();
+ return (HBA_STATUS_OK);
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcOpenTgtAdapter.cc b/usr/src/lib/sun_fc/common/Sun_fcOpenTgtAdapter.cc
new file mode 100644
index 0000000000..5319ce0ae4
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcOpenTgtAdapter.cc
@@ -0,0 +1,63 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "HBAList.h"
+#include "Handle.h"
+#include "Exceptions.h"
+
+#define HANDLE_ERROR 0
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Opens a named adapter.
+ * @precondition Library already loaded
+ * @postcondition Open handle must be closed at a later point in time
+ * @return An open handle, or (0) on error
+ * @param name The name of the adapter to open
+ */
+HBA_HANDLE Sun_fcOpenTgtAdapter(char *name) {
+ Trace log("Sun_fcOpenTgtAdapter");
+ if (name == NULL) {
+ log.userError("Null argument");
+ return (HANDLE_ERROR);
+ }
+
+ try {
+ return (HBAList::instance()->openTgtHBA(name)->getHandle());
+ } catch (HBAException &e) {
+ return (0);
+ } catch (...) {
+ log.internalError("Uncaught exception");
+ return (0);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcOpenTgtAdapterByWWN.cc b/usr/src/lib/sun_fc/common/Sun_fcOpenTgtAdapterByWWN.cc
new file mode 100644
index 0000000000..1071b75776
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcOpenTgtAdapterByWWN.cc
@@ -0,0 +1,65 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Handle.h"
+#include "HBAList.h"
+#include "Exceptions.h"
+#include "Trace.h"
+#include "sun_fc.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Opens a adapter based on the specified WWN.
+ * @return HBA_STATUS_OK if adapter was opened
+ * @param handle Output argument where open handle is stored
+ * @param wwn The Node or Port WWN of the HBA to open
+ */
+HBA_STATUS Sun_fcOpenTgtAdapterByWWN(HBA_HANDLE *handle, HBA_WWN wwn) {
+ Trace log("Sun_fcOpenTgtAdapterByWWN");
+
+ // Validate args
+ if (handle == NULL) {
+ log.userError("NULL handle pointer");
+ return (HBA_STATUS_ERROR_ARG);
+ }
+ try {
+ *handle = HBAList::instance()->
+ openTgtHBA(wwnConversion(wwn.wwn))->getHandle();
+ return (HBA_STATUS_OK);
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcRefreshAdapterConfiguration.cc b/usr/src/lib/sun_fc/common/Sun_fcRefreshAdapterConfiguration.cc
new file mode 100644
index 0000000000..d7ec0ad809
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcRefreshAdapterConfiguration.cc
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#include "Trace.h"
+
+/**
+ * @memo Not applicable (no-op)
+ *
+ * @doc
+ * This routine is a no-op for our implementation.
+ * We always keep the list of adapters up to date
+ * and use the semi-static table model. See HBAList
+ */
+extern "C" void Sun_fcRefreshAdapterConfiguration() {
+ Trace log("Sun_fcRefreshAdapterConfiguration");
+ // No-op
+}
diff --git a/usr/src/lib/sun_fc/common/Sun_fcRefreshInformation.cc b/usr/src/lib/sun_fc/common/Sun_fcRefreshInformation.cc
new file mode 100644
index 0000000000..406804c657
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcRefreshInformation.cc
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "sun_fc.h"
+#include "Exceptions.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Refreshes information about an HBA
+ * @param handle The HBA to refresh
+ */
+void Sun_fcRefreshInformation(HBA_HANDLE handle) {
+ Trace log("Sun_fcRefreshInformation");
+ try {
+ Handle *myHandle = Handle::findHandle(handle);
+ myHandle->refresh();
+ } catch (HBAException &e) {
+ log.debug("Error encountered: %d", e.getErrorCode());
+ } catch (...) {
+ log.internalError("Uncaught exception");
+ return;
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcRegisterForAdapterAddEvents.cc b/usr/src/lib/sun_fc/common/Sun_fcRegisterForAdapterAddEvents.cc
new file mode 100644
index 0000000000..07e4caf04d
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcRegisterForAdapterAddEvents.cc
@@ -0,0 +1,74 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#include "AdapterAddEventListener.h"
+#include "EventBridgeFactory.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @memo Register for Adapter Add Event callbacks
+ * @return HBA_STATUS_OK if callback is registered
+ * @param callback The routine to call when the event occurs
+ * @param userData Opaque data to pass to the callback when the event
+ * occurs.
+ * @param callbackHandle Output argument used for later removal of
+ * subscription.
+ */
+HBA_STATUS Sun_fcRegisterForAdapterAddEvents(
+ void (*callback) (
+ void *data,
+ HBA_WWN PortWWN,
+ HBA_UINT32 eventType),
+ void *userData,
+ HBA_CALLBACKHANDLE *callbackHandle) {
+ Trace log("Sun_fcRegisterForAdapterAddEvents");
+
+ try {
+ if (callback == NULL) throw BadArgumentException();
+ if (callbackHandle == NULL) throw BadArgumentException();
+ AdapterAddEventListener *listener = new AdapterAddEventListener(
+ (AdapterAddCallback)callback, userData);
+ AdapterAddEventBridge *bridge =
+ EventBridgeFactory::fetchAdapterAddEventBridge();
+ bridge->addListener(listener);
+ *callbackHandle = (void *)listener;
+ return (HBA_STATUS_OK);
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError("Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcRegisterForAdapterDeviceEvents.cc b/usr/src/lib/sun_fc/common/Sun_fcRegisterForAdapterDeviceEvents.cc
new file mode 100644
index 0000000000..8a6a13dd0c
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcRegisterForAdapterDeviceEvents.cc
@@ -0,0 +1,84 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#include "Handle.h"
+#include "HBA.h"
+#include "AdapterDeviceEventListener.h"
+#include "sun_fc.h"
+#include "EventBridgeFactory.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Register for Adapter Port Event callbacks
+ * @return HBA_STATUS_OK if callback is registered
+ * @param callback The routine to call when the event occurs
+ * @param userData Opaque data to pass to the callback when the event
+ * occurs.
+ * @param callbackHandle Output argument used for later removal of
+ * subscription.
+ * @param PortWWN Identifies the HBA port of interest
+ * @version 1.2
+ */
+HBA_STATUS Sun_fcRegisterForAdapterDeviceEvents(
+ void (*callback)(
+ void *data,
+ HBA_WWN PortWWN,
+ HBA_UINT32 eventType,
+ HBA_UINT32 fabricPortID),
+ void *userData,
+ HBA_HANDLE handle,
+ HBA_WWN PortWWN,
+ HBA_CALLBACKHANDLE *callbackHandle) {
+ Trace log("Sun_fcRegisterForAdapterDeviceEvents");
+ try {
+ if (callback == NULL) throw BadArgumentException();
+ if (callbackHandle == NULL) throw BadArgumentException();
+ Handle *myHandle = Handle::findHandle(handle);
+ HBA *hba = myHandle->getHBA();
+ HBAPort *port = hba->getPort(wwnConversion(PortWWN.wwn));
+ AdapterDeviceEventListener *listener = new AdapterDeviceEventListener(
+ port, (AdapterDeviceCallback)callback, userData);
+ AdapterDeviceEventBridge *bridge =
+ EventBridgeFactory::fetchAdapterDeviceEventBridge();
+ bridge->addListener(listener, port);
+ *callbackHandle = (void *)listener;
+ return (HBA_STATUS_OK);
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError("Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/usr/src/lib/sun_fc/common/Sun_fcRegisterForAdapterEvents.cc b/usr/src/lib/sun_fc/common/Sun_fcRegisterForAdapterEvents.cc
new file mode 100644
index 0000000000..7c06d5060a
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcRegisterForAdapterEvents.cc
@@ -0,0 +1,77 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#include "Handle.h"
+#include "HBA.h"
+#include "AdapterEventListener.h"
+#include "EventBridgeFactory.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Register for Adapter Event callbacks
+ * @return HBA_STATUS_OK if callback is registered
+ * @param callback The routine to call when the event occurs
+ * @param userData Opaque data to pass to the callback when the event
+ * occurs.
+ * @param callbackHandle Output argument used for later removal of
+ * subscription.
+ */
+HBA_STATUS Sun_fcRegisterForAdapterEvents(
+ void (*callback)(
+ void *data,
+ HBA_WWN PortWWN,
+ HBA_UINT32 eventType),
+ void *userData,
+ HBA_HANDLE handle,
+ HBA_CALLBACKHANDLE *callbackHandle) {
+ Trace log("Sun_fcRegisterForAdapterEvents");
+ try {
+ if (callback == NULL) throw BadArgumentException();
+ if (callbackHandle == NULL) throw BadArgumentException();
+ Handle *myHandle = Handle::findHandle(handle);
+ HBA *hba = myHandle->getHBA();
+ AdapterEventListener *listener = new AdapterEventListener(hba,
+ (AdapterCallback)callback, userData);
+ AdapterEventBridge *bridge =
+ EventBridgeFactory::fetchAdapterEventBridge();
+ bridge->addListener(listener, hba);
+ *callbackHandle = (void *)listener;
+ return (HBA_STATUS_OK);
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError("Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcRegisterForAdapterPortEvents.cc b/usr/src/lib/sun_fc/common/Sun_fcRegisterForAdapterPortEvents.cc
new file mode 100644
index 0000000000..bc55bd3f75
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcRegisterForAdapterPortEvents.cc
@@ -0,0 +1,82 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#include "Handle.h"
+#include "HBA.h"
+#include "AdapterPortEventListener.h"
+#include "sun_fc.h"
+#include "EventBridgeFactory.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Register for Adapter Port Event callbacks
+ * @return HBA_STATUS_OK if callback is registered
+ * @param callback The routine to call when the event occurs
+ * @param userData Opaque data to pass to the callback when the event
+ * occurs.
+ * @param callbackHandle Output argument used for later removal of
+ * subscription.
+ * @param PortWWN Identifies the HBA port of interest
+ */
+HBA_STATUS Sun_fcRegisterForAdapterPortEvents(
+ void (*callback)(
+ void *data,
+ HBA_WWN PortWWN,
+ HBA_UINT32 eventType,
+ HBA_UINT32 fabricPortID),
+ void *userData,
+ HBA_HANDLE handle,
+ HBA_WWN PortWWN,
+ HBA_CALLBACKHANDLE *callbackHandle) {
+ Trace log("Sun_fcRegisterForAdapterPortEvents");
+ try {
+ if (callback == NULL) throw BadArgumentException();
+ if (callbackHandle == NULL) throw BadArgumentException();
+ Handle *myHandle = Handle::findHandle(handle);
+ HBA *hba = myHandle->getHBA();
+ HBAPort *port = hba->getPort(wwnConversion(PortWWN.wwn));
+ AdapterPortEventListener *listener = new AdapterPortEventListener(
+ port, (AdapterPortCallback)callback, userData);
+ AdapterPortEventBridge *bridge =
+ EventBridgeFactory::fetchAdapterPortEventBridge();
+ bridge->addListener(listener, port);
+ *callbackHandle = (void *)listener;
+ return (HBA_STATUS_OK);
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError("Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcRegisterForAdapterPortStatEvents.cc b/usr/src/lib/sun_fc/common/Sun_fcRegisterForAdapterPortStatEvents.cc
new file mode 100644
index 0000000000..b8cd8a05d3
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcRegisterForAdapterPortStatEvents.cc
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Not Supported
+ */
+/*ARGSUSED*/
+HBA_STATUS Sun_fcRegisterForAdapterPortStatEvents(
+ void (*callback)(
+ void *data,
+ HBA_WWN PortWWN,
+ HBA_UINT32 eventType),
+ void *userData,
+ HBA_HANDLE handle,
+ HBA_WWN PortWWN,
+ HBA_PORTSTATISTICS stats,
+ HBA_UINT32 statType,
+ HBA_CALLBACKHANDLE *callbackHandle) {
+ Trace log("Sun_fcRegisterForAdapterPortStatEvents");
+ return (HBA_STATUS_ERROR_NOT_SUPPORTED);
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcRegisterForLinkEvents.cc b/usr/src/lib/sun_fc/common/Sun_fcRegisterForLinkEvents.cc
new file mode 100644
index 0000000000..4654f6a4eb
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcRegisterForLinkEvents.cc
@@ -0,0 +1,64 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * NOT SUPPORTED
+ * @memo Register for Link Event callbacks
+ * @return HBA_STATUS_OK if callback is registered
+ * @param callback The routine to call when the event occurs
+ * @param userData Opaque data to pass to the callback when the event
+ * occurs.
+ * @param callbackHandle Output argument used for later removal of
+ * subscription.
+ * @param pRLIRBuffer Buffer containing the type of events
+ * @param RLIRBufferSize Indicates the size of the buffer
+ */
+/*ARGSUSED*/
+HBA_STATUS Sun_fcRegisterForLinkEvents(
+ void (*callback)(
+ void *data,
+ HBA_WWN adapterWWN,
+ HBA_UINT32 eventType,
+ void *pRLIRBuffer,
+ HBA_UINT32 RLIRBufferSize),
+ void *userData,
+ void *pRLIRBuffer,
+ HBA_UINT32 RLIRBufferSize,
+ HBA_HANDLE handle,
+ HBA_CALLBACKHANDLE *callbackHandle) {
+ Trace log("Sun_fcRegisterForLinkEvents");
+ return (HBA_STATUS_ERROR_NOT_SUPPORTED);
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcRegisterForTargetEvents.cc b/usr/src/lib/sun_fc/common/Sun_fcRegisterForTargetEvents.cc
new file mode 100644
index 0000000000..a9e1172075
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcRegisterForTargetEvents.cc
@@ -0,0 +1,92 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#include "Handle.h"
+#include "HBA.h"
+#include "TargetEventListener.h"
+#include "sun_fc.h"
+#include "EventBridgeFactory.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Register for Target Event callbacks
+ * @return HBA_STATUS_OK if callback is registered
+ * @param callback The routine to call when the event occurs
+ * @param userData Opaque data to pass to the callback when the event
+ * occurs.
+ * @param callbackHandle Output argument used for later removal of
+ * subscription.
+ * @param hbaPortWWN Identifies the HBA port of interest
+ * @param discoveredPortWWN Identifies the requested target port
+ * @param allTargets If non-zero, indicates subscription is for
+ * all targets, and the discoveredPortWWN argument is ignored
+ */
+HBA_STATUS Sun_fcRegisterForTargetEvents(
+ void (*callback)(
+ void *data,
+ HBA_WWN hbaPortWWN,
+ HBA_WWN discoveredPortWWN,
+ HBA_UINT32 eventType),
+ void *userData,
+ HBA_HANDLE handle,
+ HBA_WWN hbaPortWWN,
+ HBA_WWN discoveredPortWWN,
+ HBA_CALLBACKHANDLE *callbackHandle,
+ HBA_UINT32 allTargets) {
+ Trace log("Sun_fcRegisterForTargetEvents");
+ bool filter = true;
+ try {
+ if (callback == NULL) throw BadArgumentException();
+ if (callbackHandle == NULL) throw BadArgumentException();
+ if (allTargets) filter = false;
+ Handle *myHandle = Handle::findHandle(handle);
+ HBA *hba = myHandle->getHBA();
+ HBAPort *port = hba->getPort(wwnConversion(hbaPortWWN.wwn));
+ TargetEventListener *listener = new TargetEventListener(port,
+ (TargetCallback)callback, userData,
+ wwnConversion(discoveredPortWWN.wwn), filter);
+ TargetEventBridge *bridge =
+ EventBridgeFactory::fetchTargetEventBridge();
+ bridge->addListener(listener, port,
+ wwnConversion(discoveredPortWWN.wwn), filter);
+ *callbackHandle = (void *)listener;
+ return (HBA_STATUS_OK);
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcRemoveAllPersistentBindings.cc b/usr/src/lib/sun_fc/common/Sun_fcRemoveAllPersistentBindings.cc
new file mode 100644
index 0000000000..4305e4efc9
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcRemoveAllPersistentBindings.cc
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Not Supported
+ */
+/*ARGSUSED*/
+HBA_STATUS Sun_fcRemoveAllPersistentBindings(HBA_HANDLE hande,
+ HBA_WWN portWWN) {
+ Trace log("Sun_fcRemoveAllPersistentBindings");
+ return (HBA_STATUS_ERROR_NOT_SUPPORTED);
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcRemoveCallback.cc b/usr/src/lib/sun_fc/common/Sun_fcRemoveCallback.cc
new file mode 100644
index 0000000000..5aa290a76e
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcRemoveCallback.cc
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Not Supported
+ */
+/*ARGSUSED*/
+HBA_STATUS Sun_fcRemoveCallback(HBA_CALLBACKHANDLE callbackHandle) {
+ Trace log("Sun_fcRemoveCallback");
+ return (HBA_STATUS_ERROR_NOT_SUPPORTED);
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcRemovePersistentBinding.cc b/usr/src/lib/sun_fc/common/Sun_fcRemovePersistentBinding.cc
new file mode 100644
index 0000000000..a550c40944
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcRemovePersistentBinding.cc
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Not Supported
+ */
+/*ARGSUSED*/
+HBA_STATUS Sun_fcRemovePersistentBinding(HBA_HANDLE hande,
+ HBA_WWN portWWN, const HBA_FCPBINDING2 *binding) {
+ Trace log("Sun_fcRemovePersistentBinding");
+ return (HBA_STATUS_ERROR_NOT_SUPPORTED);
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcResetStatistics.cc b/usr/src/lib/sun_fc/common/Sun_fcResetStatistics.cc
new file mode 100644
index 0000000000..e47d07e2d4
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcResetStatistics.cc
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Not supported
+ */
+/*ARGSUSED*/
+void Sun_fcResetStatistics(HBA_HANDLE handle, HBA_UINT32 port) {
+ Trace log("Sun_fcResetStatistics");
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcScsiInquiryV2.cc b/usr/src/lib/sun_fc/common/Sun_fcScsiInquiryV2.cc
new file mode 100644
index 0000000000..577a62b722
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcScsiInquiryV2.cc
@@ -0,0 +1,97 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Handle.h"
+#include "HBA.h"
+#include "HBAPort.h"
+#include "Exceptions.h"
+#include "sun_fc.h"
+#include <unistd.h>
+
+#define BUSY_SLEEP 1000000 /* 1/100 second */
+#define BUSY_RETRY_TIMER 5000000000ULL /* Retry for 5 seconds */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Send a SCSI inquiry to a remote WWN
+ * @return HBA_STATUS_OK or other error code
+ * scsiStatus should be checked to ensure SCSI command
+ * was a success.
+ * @param handle The HBA to operate on
+ * @param portWWN Indicates the HBA port to send command through
+ * @param targetPortWWN Indicates the target to send command to
+ * @param fcLun Indicates the target unit to send command to
+ * @param cdb1 The first CDB byte
+ * @param cdb2 The second CDB byte
+ * @param responseBuffer User-allocated response buffer
+ * @param responseSize Size of User-allocated response buffer
+ * @param scsiStatus User-allocated scsi status byte
+ *
+ * @doc This routine will attempt a limited number of retries
+ * When busy or again errors are encountered.
+ */
+HBA_STATUS
+Sun_fcScsiInquiryV2(HBA_HANDLE handle, HBA_WWN portWWN, HBA_WWN targetPortWWN,
+ HBA_UINT64 fcLun, HBA_UINT8 cdb1, HBA_UINT8 cdb2,
+ void *responseBuffer, HBA_UINT32 *responseSize,
+ HBA_UINT8 *scsiStatus,
+ void *senseBuffer, HBA_UINT32 *senseSize) {
+ Trace log("Sun_fcScsiInquiryV2");
+
+ hrtime_t start = gethrtime();
+ hrtime_t end = start + BUSY_RETRY_TIMER;
+ for (hrtime_t cur = start; cur < end; cur = gethrtime()) {
+ try {
+ Handle *myHandle = Handle::findHandle(handle);
+ HBA *hba = myHandle->getHBA();
+ HBAPort *port = hba->getPort(wwnConversion(portWWN.wwn));
+
+ port->sendScsiInquiry(wwnConversion(targetPortWWN.wwn), fcLun,
+ cdb1, cdb2, responseBuffer, responseSize,
+ scsiStatus, senseBuffer, senseSize);
+ return (HBA_STATUS_OK);
+ } catch (BusyException &e) {
+ usleep(BUSY_SLEEP);
+ continue;
+ } catch (TryAgainException &e) {
+ usleep(BUSY_SLEEP);
+ continue;
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcScsiReadCapacityV2.cc b/usr/src/lib/sun_fc/common/Sun_fcScsiReadCapacityV2.cc
new file mode 100644
index 0000000000..e9e4969d16
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcScsiReadCapacityV2.cc
@@ -0,0 +1,93 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "HBA.h"
+#include "HBAPort.h"
+#include "Exceptions.h"
+#include "sun_fc.h"
+#include <unistd.h>
+
+#define BUSY_SLEEP 1000 /* 1/100 second */
+#define BUSY_RETRY_TIMER 5000000000ULL /* Retry for 5 seconds */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Send a read capacity to a remote WWN
+ * @return HBA_STATUS_OK or other error code
+ * scsiStatus should be checked to ensure SCSI command
+ * was a success.
+ * @param handle The HBA to operate on
+ * @param portWWN Indicates the HBA port to send command through
+ * @param targetPortWWN Indicates the target to send command to
+ * @param fcLun Indicates the target unit to send command to
+ * @param responseBuffer User-allocated response buffer
+ * @param responseSize Size of User-allocated response buffer
+ * @param scsiStatus User-allocated scsi status byte
+ *
+ * @doc This routine will attempt a limited number of retries
+ * When busy or again errors are encountered.
+ */
+HBA_STATUS
+Sun_fcScsiReadCapacityV2(HBA_HANDLE handle, HBA_WWN portWWN,
+ HBA_WWN targetPortWWN, HBA_UINT64 fcLun,
+ void *responseBuffer, HBA_UINT32 *responseSize,
+ HBA_UINT8 *scsiStatus,
+ void *senseBuffer, HBA_UINT32 *senseSize) {
+ Trace log("Sun_fcScsiReadCapacityV2");
+
+ hrtime_t start = gethrtime();
+ hrtime_t end = start + BUSY_RETRY_TIMER;
+ for (hrtime_t cur = start; cur < end; cur = gethrtime()) {
+ try {
+ Handle *myHandle = Handle::findHandle(handle);
+ HBA *hba = myHandle->getHBA();
+ HBAPort *port = hba->getPort(wwnConversion(portWWN.wwn));
+ port->sendReadCapacity(wwnConversion(targetPortWWN.wwn),
+ fcLun, responseBuffer, responseSize, scsiStatus,
+ senseBuffer, senseSize);
+ return (HBA_STATUS_OK);
+ } catch (BusyException &e) {
+ usleep(BUSY_SLEEP);
+ continue;
+ } catch (TryAgainException &e) {
+ usleep(BUSY_SLEEP);
+ continue;
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcScsiReportLUNsV2.cc b/usr/src/lib/sun_fc/common/Sun_fcScsiReportLUNsV2.cc
new file mode 100644
index 0000000000..88e69845ba
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcScsiReportLUNsV2.cc
@@ -0,0 +1,96 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "HBA.h"
+#include "HBAPort.h"
+#include "Exceptions.h"
+#include "sun_fc.h"
+#include <unistd.h>
+
+#define BUSY_SLEEP 10000 /* 1/10 second */
+#define BUSY_RETRY_TIMER 5000000000ULL /* Retry for 5 seconds */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Send a SCSI report luns command to a remote WWN
+ * @return HBA_STATUS_OK or other error code
+ * scsiStatus should be checked to ensure SCSI command
+ * was a success.
+ * @param handle The HBA to operate on
+ * @param portWWN Indicates the HBA port to send command through
+ * @param targetPortWWN Indicates the target to send command to
+ * @param responseBuffer User-allocated response buffer
+ * @param responseSize Size of User-allocated response buffer
+ * @param scsiStatus User-allocated scsi status byte
+ *
+ * @doc This routine will attempt a limited number of retries
+ * When busy or again errors are encountered.
+ */
+HBA_STATUS Sun_fcScsiReportLUNsV2(HBA_HANDLE handle, HBA_WWN portWWN,
+ HBA_WWN targetPortWWN,
+ void *responseBuffer, HBA_UINT32 *responseSize,
+ HBA_UINT8 *scsiStatus,
+ void *senseBuffer, HBA_UINT32 *senseSize) {
+ Trace log("Sun_fcScsiReportLUNsV2");
+
+ HBA_STATUS status = HBA_STATUS_OK;
+
+ hrtime_t start = gethrtime();
+ hrtime_t end = start + BUSY_RETRY_TIMER;
+ for (hrtime_t cur = start; cur < end; cur = gethrtime()) {
+ try {
+ Handle *myHandle = Handle::findHandle(handle);
+ HBA *hba = myHandle->getHBA();
+ HBAPort *port = hba->getPort(wwnConversion(portWWN.wwn));
+ port->sendReportLUNs(wwnConversion(targetPortWWN.wwn),
+ responseBuffer, responseSize, scsiStatus,
+ senseBuffer, senseSize);
+ return (HBA_STATUS_OK);
+ } catch (BusyException &e) {
+ usleep(BUSY_SLEEP);
+ status = HBA_STATUS_ERROR_BUSY;
+ continue;
+ } catch (TryAgainException &e) {
+ usleep(BUSY_SLEEP);
+ status = HBA_STATUS_ERROR_TRY_AGAIN;
+ continue;
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+ }
+ return (status);
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcSendCTPassThru.cc b/usr/src/lib/sun_fc/common/Sun_fcSendCTPassThru.cc
new file mode 100644
index 0000000000..0752724ff1
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcSendCTPassThru.cc
@@ -0,0 +1,66 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Handle.h"
+#include "HBA.h"
+#include "HBAPort.h"
+#include "Exceptions.h"
+#include "sun_fc.h"
+#include "Trace.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @depricated Use SendCTPassThruV2 instead.
+ */
+HBA_STATUS Sun_fcSendCTPassThru(HBA_HANDLE handle,
+ void *requestBuffer, HBA_UINT32 requestSize,
+ void *responseBuffer, HBA_UINT32 responseSize) {
+ Trace log("Sun_fcSendCTPassThru");
+
+ try {
+ Handle *myHandle = Handle::findHandle(handle);
+ HBA *hba = myHandle->getHBA();
+ HBAPort *port = hba->getPortByIndex(0);
+ uint64_t tmp = htonll(port->getPortWWN());
+ HBA_WWN wwn;
+ memcpy(wwn.wwn, &tmp, sizeof (wwn));
+ return (Sun_fcSendCTPassThruV2(handle,
+ wwn, requestBuffer, requestSize,
+ responseBuffer, &responseSize));
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcSendCTPassThruV2.cc b/usr/src/lib/sun_fc/common/Sun_fcSendCTPassThruV2.cc
new file mode 100644
index 0000000000..ebac3169fe
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcSendCTPassThruV2.cc
@@ -0,0 +1,85 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Handle.h"
+#include "HBA.h"
+#include "HBAPort.h"
+#include "Exceptions.h"
+#include "sun_fc.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mkdev.h>
+#include <errno.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Send a CT passthrough frame to the fabric
+ * @return HBA_STATUS_OK or other error code
+ * @param handle The HBA to operate on
+ * @param portWWN Identifies the HBA port to use
+ * @param requestBuffer Contains the user requested CT command
+ * @param requestSize The size of the request
+ * @param responseBuffer Contains the user-allocated response buf
+ * @param responseSize The size of the response buf
+ */
+HBA_STATUS Sun_fcSendCTPassThruV2(HBA_HANDLE handle, HBA_WWN portWWN,
+ void *requestBuffer, HBA_UINT32 requestSize,
+ void *responseBuffer, HBA_UINT32 *responseSize) {
+ Trace log("Sun_fcSendCTPassThruV2");
+
+ /* Validate the arguments */
+ if (requestBuffer == NULL ||
+ responseBuffer == NULL ||
+ responseSize == NULL) {
+ log.userError("NULL argument");
+ return (HBA_STATUS_ERROR_ARG);
+ }
+
+ try {
+ Handle *myHandle = Handle::findHandle(handle);
+ HBA *hba = myHandle->getHBA();
+ HBAPort *port = hba->getPort(wwnConversion(portWWN.wwn));
+
+ port->sendCTPassThru(requestBuffer, requestSize,
+ responseBuffer, responseSize);
+ return (HBA_STATUS_OK);
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcSendLIRR.cc b/usr/src/lib/sun_fc/common/Sun_fcSendLIRR.cc
new file mode 100644
index 0000000000..146a9eac39
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcSendLIRR.cc
@@ -0,0 +1,75 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#include "sun_fc.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Send ELS LIRR command out on the wire
+ * @return HBA_STATUS_OK or error code
+ * @param handle The HBA to operate on
+ * @param hbaPortWWN Identifies the HBA port to use
+ * @param destWWN The target to send the command to
+ * @param function ???
+ * @param type ???
+ * @param pRspBuffer The user-allocated response buffer
+ * @param pRspBufferSize The size of user-allocated response buffer
+ */
+HBA_STATUS Sun_fcSendLIRR(HBA_HANDLE handle,
+ HBA_WWN hbaPortWWN,
+ HBA_WWN destWWN,
+ HBA_UINT8 function,
+ HBA_UINT8 type,
+ void *pRspBuffer,
+ HBA_UINT32 *pRspBufferSize) {
+ Trace log("Sun_fcSendLIRR");
+ try {
+ Handle *myHandle = Handle::findHandle(handle);
+ HBA *hba = myHandle->getHBA();
+ HBAPort *port = hba->getPort(wwnConversion(hbaPortWWN.wwn));
+ if (destWWN.wwn == NULL) {
+ port->sendLIRR(0, function, type, pRspBuffer, pRspBufferSize);
+ } else {
+ port->sendLIRR(wwnConversion(destWWN.wwn), function, type,
+ pRspBuffer, pRspBufferSize);
+ }
+ return (HBA_STATUS_OK);
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcSendRLS.cc b/usr/src/lib/sun_fc/common/Sun_fcSendRLS.cc
new file mode 100644
index 0000000000..2910148d29
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcSendRLS.cc
@@ -0,0 +1,80 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Handle.h"
+#include "HandlePort.h"
+#include "Exceptions.h"
+#include "sun_fc.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mkdev.h>
+#include <unistd.h>
+#include <errno.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Send ELS RLS command out on the wire
+ * @return HBA_STATUS_OK or error code
+ * @param handle The HBA to operate on
+ * @param hbaPortWWN Identifies the HBA port to use
+ * @param destWWN The target to send the command to
+ * @param pRspBuffer The user-allocated response buffer
+ * @param pRspBufferSize The size of user-allocated response buffer
+ *
+ * @doc
+ * issues a Read Link Error Status Block (RLS) Extended Link Service through
+ * the specified HBA Nx_Port
+ */
+HBA_STATUS Sun_fcSendRLS(HBA_HANDLE handle,
+ HBA_WWN hbaPortWWN,
+ HBA_WWN destWWN,
+ void *pRspBuffer,
+ HBA_UINT32 *pRspBufferSize) {
+ Trace log("Sun_fcSendRLS");
+
+ try {
+ Handle *myHandle = Handle::findHandle(handle);
+ HBA *hba = myHandle->getHBA();
+ HBAPort *port = hba->getPort(wwnConversion(hbaPortWWN.wwn));
+ port->sendRLS(wwnConversion(destWWN.wwn), pRspBuffer,
+ pRspBufferSize);
+ return (HBA_STATUS_OK);
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcSendRNID.cc b/usr/src/lib/sun_fc/common/Sun_fcSendRNID.cc
new file mode 100644
index 0000000000..8e3931d7a5
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcSendRNID.cc
@@ -0,0 +1,67 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Handle.h"
+#include "HBA.h"
+#include "HBAPort.h"
+#include "Exceptions.h"
+#include "sun_fc.h"
+#include "Trace.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @depricated Use V2 interface
+ */
+HBA_STATUS Sun_fcSendRNID(HBA_HANDLE handle, HBA_WWN wwn,
+ HBA_WWNTYPE type, void *responseBuffer, HBA_UINT32 *length) {
+ Trace log("Sun_fcSendRNID");
+
+ try {
+ Handle *myHandle = Handle::findHandle(handle);
+ HBA *hba = myHandle->getHBA();
+ HBAPort *port = hba->getPortByIndex(0);
+ uint64_t tmp = htonll(port->getPortWWN());
+ HBA_WWN hba_wwn;
+ memcpy(hba_wwn.wwn, &tmp, sizeof (hba_wwn));
+
+ return (Sun_fcSendRNIDV2(handle,
+ hba_wwn, wwn,
+ 0, HBAPort::RNID_GENERAL_TOPOLOGY_DATA_FORMAT,
+ responseBuffer, length));
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcSendRNIDV2.cc b/usr/src/lib/sun_fc/common/Sun_fcSendRNIDV2.cc
new file mode 100644
index 0000000000..7d632d3697
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcSendRNIDV2.cc
@@ -0,0 +1,80 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#include "Trace.h"
+#include "Handle.h"
+#include "HBA.h"
+#include "HBAPort.h"
+#include "Exceptions.h"
+#include "sun_fc.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mkdev.h>
+#include <unistd.h>
+#include <errno.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Issues and ELS RNID to another node
+ * @return HBA_STATUS_OK or error code
+ * @param handle The HBA to operate on
+ * @param hbaportwwn Identifies which HBA port to use
+ * @param destwwn Identifies the remote target to send command to
+ * @param destfcid Identifies the remote target to send command to
+ * @param nodeIdDataFormat Identifies which RNID type to send
+ * @param pRspBuffer User-allocated response buffer
+ * @param pRspBufferSize Size of user-allocated response buffer
+ *
+ * @doc FREE_FLOWING_MULTILINE_DESCRIPTION
+ */
+HBA_STATUS Sun_fcSendRNIDV2(HBA_HANDLE handle, HBA_WWN hbaportwwn,
+ HBA_WWN destwwn, HBA_UINT32 destfcid,
+ HBA_UINT32 nodeIdDataFormat, void *pRspBuffer,
+ HBA_UINT32 *RspBufferSize) {
+ Trace log("Sun_fcSendRNIDV2");
+
+ try {
+ Handle *myHandle = Handle::findHandle(handle);
+ HBA *hba = myHandle->getHBA();
+ HBAPort *port = hba->getPort(wwnConversion(hbaportwwn.wwn));
+ port->sendRNID(wwnConversion(destwwn.wwn), destfcid,
+ nodeIdDataFormat, pRspBuffer, RspBufferSize);
+ return (HBA_STATUS_OK);
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcSendRPL.cc b/usr/src/lib/sun_fc/common/Sun_fcSendRPL.cc
new file mode 100644
index 0000000000..7a9d27b86d
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcSendRPL.cc
@@ -0,0 +1,77 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#include "sun_fc.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Send ELS RPL command out on the wire
+ * @return HBA_STATUS_OK or error code
+ * @param handle The HBA to operate on
+ * @param hbaPortWWN Identifies the HBA port to use
+ * @param agent_wwn ???
+ * @param agent_domain ???
+ * @param portindex ???
+ * @param pRspBuffer The user-allocated response buffer
+ * @param pRspBufferSize The size of user-allocated response buffer
+ */
+HBA_STATUS Sun_fcSendRPL(HBA_HANDLE handle,
+ HBA_WWN hbaPortWWN,
+ HBA_WWN agent_wwn,
+ HBA_UINT32 agent_domain,
+ HBA_UINT32 portindex,
+ void *pRspBuffer,
+ HBA_UINT32 *pRspBufferSize) {
+ Trace log("Sun_fcSendRPL");
+
+ try {
+ Handle *myHandle = Handle::findHandle(handle);
+ HBA *hba = myHandle->getHBA();
+ HBAPort *port = hba->getPort(wwnConversion(hbaPortWWN.wwn));
+ if (agent_wwn.wwn == NULL) {
+ port->sendRPL(0, agent_domain, portindex,
+ pRspBuffer, pRspBufferSize);
+ } else {
+ port->sendRPL(wwnConversion(agent_wwn.wwn), agent_domain,
+ portindex, pRspBuffer, pRspBufferSize);
+ }
+ return (HBA_STATUS_OK);
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcSendRPS.cc b/usr/src/lib/sun_fc/common/Sun_fcSendRPS.cc
new file mode 100644
index 0000000000..735ed6b2a9
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcSendRPS.cc
@@ -0,0 +1,85 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#include "sun_fc.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Send ELS RPS command out on the wire
+ * @return HBA_STATUS_OK or error code
+ * @param handle The HBA to operate on
+ * @param hbaPortWWN Identifies the HBA port to use
+ * @param agent_wwn ???
+ * @param agent_domain ???
+ * @param object_wwn ???
+ * @param object_port_number ???
+ * @param pRspBuffer The user-allocated response buffer
+ * @param pRspBufferSize The size of user-allocated response buffer
+ */
+HBA_STATUS Sun_fcSendRPS(HBA_HANDLE handle,
+ HBA_WWN hbaPortWWN,
+ HBA_WWN agent_wwn,
+ HBA_UINT32 agent_domain,
+ HBA_WWN object_wwn,
+ HBA_UINT32 object_port_number,
+ void *pRspBuffer,
+ HBA_UINT32 *pRspBufferSize) {
+ Trace log("Sun_fcSendRPS");
+ uint64_t a_wwn, o_wwn;
+
+ try {
+ Handle *myHandle = Handle::findHandle(handle);
+ HBA *hba = myHandle->getHBA();
+ HBAPort *port = hba->getPort(wwnConversion(hbaPortWWN.wwn));
+ if (agent_wwn.wwn == NULL) {
+ a_wwn = 0;
+ } else {
+ a_wwn = wwnConversion(agent_wwn.wwn);
+ }
+ if (object_wwn.wwn == NULL) {
+ o_wwn = 0;
+ } else {
+ o_wwn = wwnConversion(object_wwn.wwn);
+ }
+ port->sendRPS(a_wwn, agent_domain, o_wwn, object_port_number,
+ pRspBuffer, pRspBufferSize);
+ return (HBA_STATUS_OK);
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcSendReadCapacity.cc b/usr/src/lib/sun_fc/common/Sun_fcSendReadCapacity.cc
new file mode 100644
index 0000000000..fa3e4b89fd
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcSendReadCapacity.cc
@@ -0,0 +1,71 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#include "Handle.h"
+#include "HBA.h"
+#include "HBAPort.h"
+#include "sun_fc.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @depricated Use V2 interface instead
+ */
+HBA_STATUS
+Sun_fcSendReadCapacity(HBA_HANDLE handle, HBA_WWN wwn,
+ HBA_UINT64 fcLun, void *responseBuffer, HBA_UINT32 responseSize,
+ void *senseBuffer, HBA_UINT32 senseSize) {
+ Trace log("Sun_fcSendReadCapacity");
+ HBA_UINT8 status;
+
+ try {
+ Handle *myHandle = Handle::findHandle(handle);
+ HBA *hba = myHandle->getHBA();
+ HBAPort *port = hba->getPortByIndex(0);
+ uint64_t tmp = htonll(port->getPortWWN());
+ HBA_WWN hba_wwn;
+ memcpy(hba_wwn.wwn, &tmp, sizeof (hba_wwn));
+
+ return (Sun_fcScsiReadCapacityV2(handle,
+ hba_wwn, wwn,
+ fcLun, responseBuffer, &responseSize, &status,
+ senseBuffer, &senseSize));
+
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcSendReportLUNs.cc b/usr/src/lib/sun_fc/common/Sun_fcSendReportLUNs.cc
new file mode 100644
index 0000000000..16dfb0eb00
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcSendReportLUNs.cc
@@ -0,0 +1,70 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Handle.h"
+#include "HBA.h"
+#include "HBAPort.h"
+#include "Trace.h"
+#include "Exceptions.h"
+#include "sun_fc.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @depricated Use ScsiReportLunsV2.
+ */
+HBA_STATUS Sun_fcSendReportLUNs(HBA_HANDLE handle, HBA_WWN wwn,
+ void *responseBuffer, HBA_UINT32 responseSize,
+ void *senseBuffer, HBA_UINT32 senseSize) {
+ Trace log("Sun_fcSendReportLUNs");
+
+ try {
+ Handle *myHandle = Handle::findHandle(handle);
+ HBA *hba = myHandle->getHBA();
+ HBAPort *port = hba->getPortByIndex(0);
+ uint64_t tmp = htonll(port->getPortWWN());
+ HBA_WWN hba_wwn;
+ memcpy(hba_wwn.wwn, &tmp, sizeof (hba_wwn));
+
+ HBA_UINT8 status;
+ return (Sun_fcScsiReportLUNsV2(handle,
+ hba_wwn, wwn,
+ responseBuffer, &responseSize,
+ &status,
+ senseBuffer, &senseSize));
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcSendSRL.cc b/usr/src/lib/sun_fc/common/Sun_fcSendSRL.cc
new file mode 100644
index 0000000000..ac01bfbef8
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcSendSRL.cc
@@ -0,0 +1,74 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#include "sun_fc.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Send an SRL command out on the wire
+ * @return HBA_STATUS_OK or other error code
+ * @param handle The HBA to operate on
+ * @param hbaPortWWN Identifies which port on the HBA to use
+ * @param wwn Identifies the target to send command to
+ * @param domain ???
+ * @param pRspBuffer User-allocated response buffer
+ * @param pRspBufferSize Size of user-allocated response buffer
+ */
+HBA_STATUS Sun_fcSendSRL(HBA_HANDLE handle,
+ HBA_WWN hbaPortWWN,
+ HBA_WWN wwn,
+ HBA_UINT32 domain,
+ void *pRspBuffer,
+ HBA_UINT32 *pRspBufferSize) {
+ Trace log("Sun_fcSendSRL");
+
+ try {
+ Handle *myHandle = Handle::findHandle(handle);
+ HBA *hba = myHandle->getHBA();
+ HBAPort *port = hba->getPort(wwnConversion(hbaPortWWN.wwn));
+ if (wwn.wwn == NULL) {
+ port->sendSRL(0, domain, pRspBuffer, pRspBufferSize);
+ } else {
+ port->sendSRL(wwnConversion(wwn.wwn), domain,
+ pRspBuffer, pRspBufferSize);
+ }
+ return (HBA_STATUS_OK);
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcSendScsiInquiry.cc b/usr/src/lib/sun_fc/common/Sun_fcSendScsiInquiry.cc
new file mode 100644
index 0000000000..b02b6e370f
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcSendScsiInquiry.cc
@@ -0,0 +1,72 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Handle.h"
+#include "HBA.h"
+#include "HBAPort.h"
+#include "Trace.h"
+#include "Exceptions.h"
+#include "sun_fc.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @depricated. Use ScsiInquiryV2.
+ */
+HBA_STATUS Sun_fcSendScsiInquiry(HBA_HANDLE handle, HBA_WWN wwn,
+ HBA_UINT64 fcLun, HBA_UINT8 evpd, HBA_UINT32 pageCode,
+ void *responseBuffer, HBA_UINT32 responseSize,
+ void *senseBuffer, HBA_UINT32 senseSize) {
+ Trace log("Sun_fcSendScsiInquiry");
+
+ try {
+ Handle *myHandle = Handle::findHandle(handle);
+ HBA *hba = myHandle->getHBA();
+ HBAPort *port = hba->getPortByIndex(0);
+ uint64_t tmp = htonll(port->getPortWWN());
+ HBA_WWN hba_wwn;
+ memcpy(hba_wwn.wwn, &tmp, sizeof (hba_wwn));
+
+ HBA_UINT8 status;
+ return (Sun_fcScsiInquiryV2(handle,
+ hba_wwn, wwn, fcLun,
+ evpd, (HBA_UINT8)pageCode,
+ responseBuffer, &responseSize,
+ &status,
+ senseBuffer, &senseSize));
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcSetBindingSupport.cc b/usr/src/lib/sun_fc/common/Sun_fcSetBindingSupport.cc
new file mode 100644
index 0000000000..183dbfe0e9
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcSetBindingSupport.cc
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Not Supported
+ */
+/*ARGSUSED*/
+HBA_STATUS Sun_fcSetBindingSupport(HBA_HANDLE hande, HBA_WWN portWWN,
+ HBA_BIND_CAPABILITY caps) {
+ Trace log("Sun_fcSetBindingSupport");
+ return (HBA_STATUS_ERROR_NOT_SUPPORTED);
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcSetPersistentBindingV2.cc b/usr/src/lib/sun_fc/common/Sun_fcSetPersistentBindingV2.cc
new file mode 100644
index 0000000000..a0e8ab05aa
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcSetPersistentBindingV2.cc
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Not Supported
+ */
+/*ARGSUSED*/
+HBA_STATUS Sun_fcSetPersistentBindingV2(HBA_HANDLE hande,
+ HBA_WWN portWWN, const HBA_FCPBINDING2 *binding) {
+ Trace log("Sun_fcSetPersistentBindingV2");
+ return (HBA_STATUS_ERROR_NOT_SUPPORTED);
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/Sun_fcSetRNIDMgmtInfo.cc b/usr/src/lib/sun_fc/common/Sun_fcSetRNIDMgmtInfo.cc
new file mode 100644
index 0000000000..5265216692
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Sun_fcSetRNIDMgmtInfo.cc
@@ -0,0 +1,70 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include "Exceptions.h"
+#include "Handle.h"
+#include "HBA.h"
+#include "HBAPort.h"
+#include "sun_fc.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mkdev.h>
+#include <unistd.h>
+#include <errno.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @memo Sets the RNID for the HBA
+ * @return HBA_STATUS_OK if the set operation completed
+ * @param handle The HBA to operate on
+ * @param info The RNID information to set on the HBA
+ */
+HBA_STATUS Sun_fcSetRNIDMgmtInfo(HBA_HANDLE handle,
+ HBA_MGMTINFO info) {
+ Trace log("Sun_fcSetRNIDMgmtInfo");
+
+
+ try {
+ Handle *myHandle = Handle::findHandle(handle);
+ HBA *hba = myHandle->getHBA();
+ hba->setRNID(info);
+ return (HBA_STATUS_OK);
+ } catch (HBAException &e) {
+ return (e.getErrorCode());
+ } catch (...) {
+ log.internalError(
+ "Uncaught exception");
+ return (HBA_STATUS_ERROR);
+ }
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/usr/src/lib/sun_fc/common/TargetEvent.h b/usr/src/lib/sun_fc/common/TargetEvent.h
new file mode 100644
index 0000000000..82dd6639a1
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/TargetEvent.h
@@ -0,0 +1,63 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _TARGETEVENT_H
+#define _TARGETEVENT_H
+
+
+
+#include "Event.h"
+#include <hbaapi.h>
+
+
+/**
+ * @memo Represents a target Event
+ *
+ * @doc When target events occur on the HBA, an
+ * event of this type will be sent to registered
+ * listeners
+ */
+class TargetEvent : public Event {
+public:
+ enum EVENT_TYPE {
+ UNKNOWN = HBA_EVENT_TARGET_UNKNOWN,
+ OFFLINE = HBA_EVENT_TARGET_OFFLINE,
+ ONLINE = HBA_EVENT_TARGET_ONLINE,
+ REMOVED = HBA_EVENT_TARGET_REMOVED
+ };
+ TargetEvent(uint64_t myHBAPortWWN, uint64_t myTargetPortWWN,
+ EVENT_TYPE myType) :
+ hbaWWN(myHBAPortWWN), targetWWN(myTargetPortWWN), type(myType) { }
+ uint64_t getHBAPortWWN() { return (hbaWWN); }
+ uint64_t getTargetPortWWN() { return (targetWWN); }
+ EVENT_TYPE getType() { return (type); }
+
+private:
+ uint64_t hbaWWN;
+ uint64_t targetWWN;
+ EVENT_TYPE type;
+};
+
+#endif /* _TARGETEVENT_H */
diff --git a/usr/src/lib/sun_fc/common/TargetEventBridge.h b/usr/src/lib/sun_fc/common/TargetEventBridge.h
new file mode 100644
index 0000000000..4ba3b74b93
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/TargetEventBridge.h
@@ -0,0 +1,48 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _TARGETEVENTBRIDGE_H
+#define _TARGETEVENTBRIDGE_H
+
+
+
+#include "TargetEventListener.h"
+
+/**
+ * @memo Bridge interface for target events
+ *
+ * @doc Used to abstract clients from the specific
+ * underlying details of event management for
+ * the given HBA/driver stack.
+ */
+class TargetEventBridge{
+public:
+ virtual void addListener(TargetEventListener *listener,
+ HBAPort *port, uint64_t targetWWN, bool filter) = 0;
+ virtual void removeListener(TargetEventListener *listener) = 0;
+ virtual int32_t getMaxListener() = 0;
+};
+
+#endif /* _TARGETEVENTBRIDGE_H */
diff --git a/usr/src/lib/sun_fc/common/TargetEventListener.cc b/usr/src/lib/sun_fc/common/TargetEventListener.cc
new file mode 100644
index 0000000000..288d52cb22
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/TargetEventListener.cc
@@ -0,0 +1,85 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+
+#include "TargetEventListener.h"
+#include "TargetEvent.h"
+#include "Exceptions.h"
+#include "Trace.h"
+#include "sun_fc.h"
+
+/**
+ * @memo Create a new TargetEvent listener
+ * @postcondition Listener ready to receive callbacks
+ * @exception BadArgumentException
+ * @param myCallback The listeners callback routine
+ * @param data Opaque data that will be passed to the
+ * callback routine when and event comes in.
+ */
+TargetEventListener::TargetEventListener(HBAPort *myPort,
+ TargetCallback myCallback, void *data, uint64_t wwn, bool myFilter) :
+ port(myPort), Listener(data), callback(myCallback), targetPortWWN(wwn),
+ filter(myFilter) {
+
+ Trace log("TargetEventListener::TargetEventListener");
+ if (callback == NULL) {
+ throw BadArgumentException();
+ }
+}
+
+/**
+ * @memo Send the event to this listener
+ * @param event The event to send to the listener
+ *
+ * @doc The callback registered in the constructor will
+ * be called.
+ */
+void TargetEventListener::dispatch(Event &event) {
+ Trace log("TargetEventListener::dispatch");
+ TargetEvent *e = static_cast<TargetEvent*> (&event);
+ if (e != NULL) {
+ HBA_WWN hbawwn;
+ uint64_t hbalwwn = e->getHBAPortWWN();
+ // Filter out unwanted events
+ if (port->getPortWWN() != hbalwwn) {
+ return;
+ }
+ if (filter) {
+ if (targetPortWWN != e->getTargetPortWWN()) {
+ return;
+ }
+ }
+ hbalwwn = htonll(hbalwwn);
+ memcpy(&hbawwn, &hbalwwn, sizeof (hbawwn));
+ HBA_WWN tgtwwn;
+ uint64_t tgtlwwn = htonll(e->getTargetPortWWN());
+ memcpy(&tgtwwn, &tgtlwwn, sizeof (tgtwwn));
+ callback(getData(), hbawwn, tgtwwn, e->getType());
+ } else {
+ log.internalError("Unexpected event type.");
+ }
+}
diff --git a/usr/src/lib/sun_fc/common/TargetEventListener.h b/usr/src/lib/sun_fc/common/TargetEventListener.h
new file mode 100644
index 0000000000..006cfa2f50
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/TargetEventListener.h
@@ -0,0 +1,62 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _TARGETEVENTLISTENER_H
+#define _TARGETEVENTLISTENER_H
+
+
+
+#include "Listener.h"
+#include "HBAPort.h"
+#include <hbaapi.h>
+
+/// Callback type
+typedef void (*TargetCallback)(
+ void *data,
+ HBA_WWN hbaPortWWN,
+ HBA_WWN discoveredPortWWN,
+ HBA_UINT32 eventType);
+
+/**
+ * @memo Encapsulates the callback routine for event dispatch
+ *
+ * @doc This class encapsulates the event callback routine
+ * registered in the public HBA API. When dispatch
+ * is called, the stored callback routine will be called.
+ */
+class TargetEventListener: public Listener {
+public:
+ TargetEventListener(HBAPort *port, TargetCallback myCallback,
+ void *data, uint64_t targetPortWWN, bool myFilter);
+ virtual void dispatch(Event &event);
+private:
+ TargetCallback callback;
+ bool filter;
+ uint64_t targetPortWWN;
+ HBAPort *port;
+};
+
+
+#endif /* _TARGETEVENTLISTENER_H */
diff --git a/usr/src/lib/sun_fc/common/TgtFCHBA.cc b/usr/src/lib/sun_fc/common/TgtFCHBA.cc
new file mode 100644
index 0000000000..4b0d4b2b56
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/TgtFCHBA.cc
@@ -0,0 +1,278 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#include <unistd.h>
+
+#include <TgtFCHBA.h>
+#include <Exceptions.h>
+#include <Trace.h>
+#include <iostream>
+#include <iomanip>
+#include <cerrno>
+#include <cstring>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stropts.h>
+#include <sys/fctio.h>
+#include <sys/fibre-channel/impl/fc_error.h>
+#include <TgtFCHBAPort.h>
+#include <HBAList.h>
+#include <sun_fc.h>
+
+using namespace std;
+const string TgtFCHBA::FCT_DRIVER_PATH = "/devices/pseudo/fct@0:admin";
+const string TgtFCHBA::FCT_ADAPTER_NAME_PREFIX = "/devices/pseudo/fct@0";
+const string TgtFCHBA::FCT_DRIVER_PKG = "SUNWfct";
+const int TgtFCHBA::MAX_FCTIO_MSG_LEN = 256;
+
+TgtFCHBA::TgtFCHBA(string path) : HBA()
+{
+ Trace log("TgtFCHBA::TgtFCHBA");
+ log.debug("Constructing new Target mode HBA (%s)", path.c_str());
+
+ // Add a target FCHBA port. With fct driver architecuture, all target mode
+ // FCHBA will have a single port regardless of the multiport support on
+ // FCA layer.
+ addPort(new TgtFCHBAPort(path));
+ name = "INTERNAL-FAILURE"; // Just in case things go wrong
+ try {
+ HBA_ADAPTERATTRIBUTES attrs = getHBAAttributes();
+ name = attrs.Manufacturer;
+ name += "-";
+ name += attrs.Model;
+ name += "-Tgt";
+
+ } catch (HBAException &e) {
+ log.debug(
+ "Failed to get HBA attribute for %s", path.c_str());
+ throw e;
+ }
+}
+
+std::string TgtFCHBA::getName()
+{
+ Trace log("TgtFCHBA::getName");
+ return (name);
+}
+
+HBA_ADAPTERATTRIBUTES TgtFCHBA::getHBAAttributes()
+{
+ Trace log("TgtFCHBA::getHBAAttributes");
+ int fd;
+
+ errno = 0;
+ HBAPort *port = getPortByIndex(0);
+
+ HBA_ADAPTERATTRIBUTES attributes;
+ fctio_t fctio;
+ fc_tgt_hba_adapter_attributes_t attrs;
+ uint64_t portwwn;
+
+ if ((fd = open(FCT_DRIVER_PATH.c_str(), O_NDELAY | O_RDONLY)) == -1) {
+ // Why did we fail?
+ if (errno == EBUSY) {
+ throw BusyException();
+ } else if (errno == EAGAIN) {
+ throw TryAgainException();
+ } else if (errno == ENOTSUP) {
+ throw NotSupportedException();
+ } else {
+ throw IOError(port);
+ }
+ }
+
+ try {
+ std::string path = port->getPath();
+ string::size_type offset = path.find_last_of(".");
+ if (offset >= 0) {
+ string portwwnString = path.substr(offset+1);
+ portwwn = strtoull(portwwnString.c_str(), NULL, 16);
+ }
+ } catch (...) {
+ throw BadArgumentException();
+ }
+
+ uint64_t en_wwn = htonll(portwwn);
+
+ memset(&fctio, 0, sizeof (fctio));
+ fctio.fctio_cmd = FCTIO_GET_ADAPTER_ATTRIBUTES;
+ fctio.fctio_olen = (uint32_t)(sizeof (attrs));
+ fctio.fctio_xfer = FCTIO_XFER_READ;
+ fctio.fctio_obuf = (uint64_t)(uintptr_t)&attrs;
+ fctio.fctio_ilen = 8;
+ fctio.fctio_ibuf = (uint64_t)(uintptr_t)&en_wwn;
+
+ errno = 0;
+ if (ioctl(fd, FCTIO_CMD, &fctio) != 0) {
+ close(fd);
+ if (errno == EBUSY) {
+ throw BusyException();
+ } else if (errno == EAGAIN) {
+ throw TryAgainException();
+ } else if (errno == ENOTSUP) {
+ throw NotSupportedException();
+ } else {
+ throw IOError("Unable to fetch adapter attributes");
+ }
+ }
+ close(fd);
+
+ /* Now copy over the payload */
+ attributes.NumberOfPorts = attrs.NumberOfPorts;
+ attributes.VendorSpecificID = attrs.VendorSpecificID;
+ memcpy(attributes.Manufacturer, attrs.Manufacturer, 64);
+ memcpy(attributes.SerialNumber, attrs.SerialNumber, 64);
+ memcpy(attributes.Model, attrs.Model, 256);
+ memcpy(attributes.ModelDescription, attrs.ModelDescription, 256);
+ memcpy(attributes.NodeSymbolicName, attrs.NodeSymbolicName, 256);
+ memcpy(attributes.HardwareVersion, attrs.HardwareVersion, 256);
+ memcpy(attributes.DriverVersion, attrs.DriverVersion, 256);
+ memcpy(attributes.OptionROMVersion, attrs.OptionROMVersion, 256);
+ memcpy(attributes.FirmwareVersion, attrs.FirmwareVersion, 256);
+ memcpy(attributes.DriverName, attrs.DriverName, 256);
+ memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8);
+
+ return (attributes);
+}
+
+void TgtFCHBA::loadAdapters(vector<HBA*> &list)
+{
+ Trace log("TgtFCHBA::loadAdapters");
+ fctio_t fctio;
+ fc_tgt_hba_list_t *tgthbaList;
+ int fd;
+ int size = 64; // default first attempt
+ bool retry = false;
+ struct stat sb;
+ int bufSize;
+ char wwnStr[17];
+
+ /* Before we do anything, let's see if FCT is on the system */
+ errno = 0;
+ if (stat(FCT_DRIVER_PATH.c_str(), &sb) != 0) {
+ if (errno == ENOENT) {
+ log.genericIOError(
+ "The %s driver is not present."
+ " Please install the %s package.",
+ FCT_DRIVER_PATH.c_str(), FCT_DRIVER_PKG.c_str());
+ throw NotSupportedException();
+ } else {
+ log.genericIOError(
+ "Can not stat the %s driver for reason \"%s\" "
+ "Unable to get target mode FC adapters.",
+ FCT_DRIVER_PATH.c_str(), strerror(errno));
+ throw IOError("Unable to stat FCSM driver");
+ }
+ }
+
+
+ /* construct fcio struct */
+ memset(&fctio, 0, sizeof (fctio_t));
+ fctio.fctio_cmd = FCTIO_ADAPTER_LIST;
+ fctio.fctio_xfer = FCTIO_XFER_RW;
+
+ /* open the fcsm node so we can send the ioctl to */
+ errno = 0;
+ if ((fd = open(FCT_DRIVER_PATH.c_str(), O_RDONLY)) < 0) {
+ if (errno == EBUSY) {
+ throw BusyException();
+ } else if (errno == EAGAIN) {
+ throw TryAgainException();
+ } else if (errno == ENOTSUP) {
+ throw NotSupportedException();
+ } else if (errno == ENOENT) {
+ throw UnavailableException();
+ } else {
+ throw IOError("Unable to open FCT driver");
+ }
+ }
+
+ do {
+ retry = false;
+ errno = 0;
+ bufSize = 8 * (size - 1) + (int) sizeof (fc_tgt_hba_list_t);
+ tgthbaList = (fc_tgt_hba_list_t *)new uchar_t[bufSize];
+ tgthbaList->numPorts = size;
+ fctio.fctio_olen = bufSize;
+ fctio.fctio_obuf = (uint64_t)(uintptr_t)tgthbaList;
+ if (ioctl(fd, FCTIO_CMD, &fctio) != 0) {
+ /* Interpret the fcio error code */
+ char fcioErrorString[MAX_FCTIO_MSG_LEN] = "";
+
+ log.genericIOError(
+ "TGT_ADAPTER_LIST failed: "
+ "Errno: \"%s\"",
+ strerror(errno));
+ delete (tgthbaList);
+ close(fd);
+ if (errno == EBUSY) {
+ throw BusyException();
+ } else if (errno == EAGAIN) {
+ throw TryAgainException();
+ } else if (errno == ENOTSUP) {
+ throw NotSupportedException();
+ } else if (errno == ENOENT) {
+ throw UnavailableException();
+ } else {
+ throw IOError("Unable to build HBA list");
+ }
+ }
+ if (tgthbaList->numPorts > size) {
+ log.debug(
+ "Buffer too small for number of target mode HBAs. Retrying.");
+ size = tgthbaList->numPorts;
+ retry = true;
+ delete (tgthbaList);
+ }
+ } while (retry);
+
+ close(fd);
+ log.debug("Detected %d target mode adapters", tgthbaList->numPorts);
+ for (int i = 0; i < tgthbaList->numPorts; i++) {
+ try {
+ std::string hbapath = FCT_ADAPTER_NAME_PREFIX.c_str();
+ hbapath += ".";
+ // move the row with two dimentional uint8 array for WWN
+ uint64_t tmp = ntohll(*((uint64_t *)&tgthbaList->port_wwn[i][0]));
+ sprintf(wwnStr, "%llx", tmp);
+ hbapath += wwnStr;
+
+ HBA *hba = new TgtFCHBA(hbapath);
+ list.insert(list.begin(), hba);
+ } catch (...) {
+ log.debug(
+ "Ignoring partial failure while loading an HBA");
+ }
+ }
+ if (tgthbaList->numPorts > HBAList::HBA_MAX_PER_LIST) {
+ delete(tgthbaList);
+ throw InternalError(
+ "Exceeds max number of adatpers that VSL supports.");
+ }
+ delete (tgthbaList);
+}
diff --git a/usr/src/lib/sun_fc/common/TgtFCHBA.h b/usr/src/lib/sun_fc/common/TgtFCHBA.h
new file mode 100644
index 0000000000..dc727fb5bc
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/TgtFCHBA.h
@@ -0,0 +1,63 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _TGTFCHBA_H
+#define _TGTFCHBA_H
+
+
+
+
+#include "HBA.h"
+#include "TgtFCHBAPort.h"
+#include <map>
+#include <string>
+#include <hbaapi.h>
+
+
+/**
+ * Represents an individual FCHBA
+ */
+class TgtFCHBA : public HBA {
+public:
+ TgtFCHBA(std::string path);
+ /**
+ * Fetch the name, excluding the trailing "-" and index number
+ */
+ virtual std::string getName();
+ virtual HBA_ADAPTERATTRIBUTES getHBAAttributes();
+ static void loadAdapters(std::vector<HBA*> &list);
+ virtual HBA_ADAPTERATTRIBUTES npivGetHBAAttributes() {
+ throw NotSupportedException(); }
+
+private:
+ std::string name;
+ static const std::string FCT_DRIVER_PATH;
+ static const std::string FCT_ADAPTER_NAME_PREFIX;
+ static const std::string FCT_DRIVER_PKG;
+ static const int MAX_FCTIO_MSG_LEN;
+};
+
+
+#endif /* _TGTFCHBA_H */
diff --git a/usr/src/lib/sun_fc/common/TgtFCHBAPort.cc b/usr/src/lib/sun_fc/common/TgtFCHBAPort.cc
new file mode 100644
index 0000000000..511df32308
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/TgtFCHBAPort.cc
@@ -0,0 +1,494 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include <TgtFCHBAPort.h>
+#include <Exceptions.h>
+#include <Trace.h>
+#include <sun_fc.h>
+#include <iostream>
+#include <iomanip>
+#include <sys/types.h>
+#include <sys/mkdev.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stropts.h>
+#include <dirent.h>
+#include <sys/fibre-channel/fc.h>
+#include <sys/fctio.h>
+#include <sys/fibre-channel/impl/fc_error.h>
+#include <sys/fibre-channel/fc_appif.h>
+#include <sys/scsi/generic/commands.h>
+#include <sys/scsi/impl/commands.h>
+#include <sys/scsi/impl/sense.h>
+#include <sys/scsi/generic/inquiry.h>
+#include <sys/scsi/generic/status.h>
+#include <errno.h>
+
+
+using namespace std;
+
+const int TgtFCHBAPort::MAX_FCTIO_MSG_LEN = 256;
+const string TgtFCHBAPort::FCT_DRIVER_PATH = "/devices/pseudo/fct@0:admin";
+
+/*
+ * Interpret the error code in the fctio_t structure
+ *
+ * message must be at least MAX_FCTIO_MSG_LEN in length.
+ */
+void
+TgtFCHBAPort::transportError(uint32_t fctio_errno, char *message) {
+ Trace log("transportError");
+ string fcioErrorString;
+ if (message == NULL) {
+ log.internalError("NULL routine argument");
+ return;
+ }
+ switch (fctio_errno) {
+ case (uint32_t)FC_FAILURE:
+ fcioErrorString = "general failure";
+ break;
+ case (uint32_t)FC_FAILURE_SILENT:
+ fcioErrorString = "general failure but fail silently";
+ break;
+ case FC_SUCCESS:
+ fcioErrorString = "successful completion";
+ break;
+ case FC_CAP_ERROR:
+ fcioErrorString = "FCA capability error";
+ break;
+ case FC_CAP_FOUND:
+ fcioErrorString = "FCA capability unsettable";
+ break;
+ case FC_CAP_SETTABLE:
+ fcioErrorString = "FCA capability settable";
+ break;
+ case FC_UNBOUND:
+ fcioErrorString = "unbound stuff";
+ break;
+ case FC_NOMEM:
+ fcioErrorString = "allocation error";
+ break;
+ case FC_BADPACKET:
+ fcioErrorString = "invalid packet specified/supplied";
+ break;
+ case FC_OFFLINE:
+ fcioErrorString = "I/O resource unavailable";
+ break;
+ case FC_OLDPORT:
+ fcioErrorString = "operation on non-loop port";
+ break;
+ case FC_NO_MAP:
+ fcioErrorString = "requested map unavailable";
+ break;
+ case FC_TRANSPORT_ERROR:
+ fcioErrorString = "unable to transport I/O";
+ break;
+ case FC_ELS_FREJECT:
+ fcioErrorString = "ELS rejected by a Fabric";
+ break;
+ case FC_ELS_PREJECT:
+ fcioErrorString = "ELS rejected by an N_port";
+ break;
+ case FC_ELS_BAD:
+ fcioErrorString = "ELS rejected by FCA/fctl";
+ break;
+ case FC_ELS_MALFORMED:
+ fcioErrorString = "poorly formed ELS request";
+ break;
+ case FC_TOOMANY:
+ fcioErrorString = "resource request too large";
+ break;
+ case FC_UB_BADTOKEN:
+ fcioErrorString = "invalid unsolicited buffer token";
+ break;
+ case FC_UB_ERROR:
+ fcioErrorString = "invalid unsol buf request";
+ break;
+ case FC_UB_BUSY:
+ fcioErrorString = "buffer already in use";
+ break;
+ case FC_BADULP:
+ fcioErrorString = "Unknown ulp";
+ break;
+ case FC_BADTYPE:
+ fcioErrorString = "ULP not registered to handle this FC4 type";
+ break;
+ case FC_UNCLAIMED:
+ fcioErrorString = "request or data not claimed";
+ break;
+ case FC_ULP_SAMEMODULE:
+ fcioErrorString = "module already in use";
+ break;
+ case FC_ULP_SAMETYPE:
+ fcioErrorString = "FC4 module already in use";
+ break;
+ case FC_ABORTED:
+ fcioErrorString = "request aborted";
+ break;
+ case FC_ABORT_FAILED:
+ fcioErrorString = "abort request failed";
+ break;
+ case FC_BADEXCHANGE:
+ fcioErrorString = "exchange doesnŐt exist";
+ break;
+ case FC_BADWWN:
+ fcioErrorString = "WWN not recognized";
+ break;
+ case FC_BADDEV:
+ fcioErrorString = "device unrecognized";
+ break;
+ case FC_BADCMD:
+ fcioErrorString = "invalid command issued";
+ break;
+ case FC_BADOBJECT:
+ fcioErrorString = "invalid object requested";
+ break;
+ case FC_BADPORT:
+ fcioErrorString = "invalid port specified";
+ break;
+ case FC_NOTTHISPORT:
+ fcioErrorString = "resource not at this port";
+ break;
+ case FC_PREJECT:
+ fcioErrorString = "reject at remote N_Port";
+ break;
+ case FC_FREJECT:
+ fcioErrorString = "reject at remote Fabric";
+ break;
+ case FC_PBUSY:
+ fcioErrorString = "remote N_Port busy";
+ break;
+ case FC_FBUSY:
+ fcioErrorString = "remote Fabric busy";
+ break;
+ case FC_ALREADY:
+ fcioErrorString = "already logged in";
+ break;
+ case FC_LOGINREQ:
+ fcioErrorString = "login required";
+ break;
+ case FC_RESETFAIL:
+ fcioErrorString = "reset failed";
+ break;
+ case FC_INVALID_REQUEST:
+ fcioErrorString = "request is invalid";
+ break;
+ case FC_OUTOFBOUNDS:
+ fcioErrorString = "port number is out of bounds";
+ break;
+ case FC_TRAN_BUSY:
+ fcioErrorString = "command transport busy";
+ break;
+ case FC_STATEC_BUSY:
+ fcioErrorString = "port driver currently busy";
+ break;
+ case FC_DEVICE_BUSY:
+ fcioErrorString = "transport working on this device";
+ break;
+ case FC_DEVICE_NOT_TGT:
+ fcioErrorString = "device is not a SCSI target";
+ break;
+ default:
+ snprintf(message, MAX_FCTIO_MSG_LEN, "Unknown error code 0x%x",
+ fctio_errno);
+ return;
+ }
+ snprintf(message, MAX_FCTIO_MSG_LEN, "%s", fcioErrorString.c_str());
+}
+
+TgtFCHBAPort::TgtFCHBAPort(string thePath) : HBAPort() {
+ Trace log("TgtFCHBAPort::TgtFCHBAPort");
+ log.debug("Initializing HBA port %s", path.c_str());
+ path = thePath;
+
+ // This routine is not index based, so we can discard stateChange
+ uint64_t tmp;
+ HBA_PORTATTRIBUTES attrs = getPortAttributes(tmp);
+ memcpy(&tmp, &attrs.PortWWN, 8);
+ portWWN = ntohll(tmp);
+ memcpy(&tmp, &attrs.NodeWWN, 8);
+ nodeWWN = ntohll(tmp);
+
+ // For reference, here's how to dump WWN's through C++ streams.
+ // cout << "\tPort WWN: " << hex << setfill('0') << setw(16) << portWWN
+ // << endl;
+ // cout << "\tNode WWN: " << hex << setfill('0') << setw(16) << nodeWWN
+ // << endl;
+}
+
+HBA_PORTATTRIBUTES TgtFCHBAPort::getPortAttributes(uint64_t &stateChange) {
+ Trace log("TgtFCHBAPort::getPortAttributes");
+
+ HBA_PORTATTRIBUTES attributes;
+ fctio_t fctio;
+ fc_tgt_hba_port_attributes_t attrs;
+
+ memset(&fctio, 0, sizeof (fctio));
+ memset(&attributes, 0, sizeof (attributes));
+
+ uint64_t portwwn = 0;
+ try {
+ string::size_type offset = path.find_last_of(".");
+ if (offset >= 0) {
+ string portwwnString = path.substr(offset+1);
+ portwwn = strtoull(portwwnString.c_str(), NULL, 16);
+ }
+ } catch (...) {
+ throw BadArgumentException();
+ }
+
+ uint64_t en_wwn = htonll(portwwn);
+
+ fctio.fctio_cmd = FCTIO_GET_ADAPTER_PORT_ATTRIBUTES;
+ fctio.fctio_ilen = 8;
+ fctio.fctio_ibuf = (uint64_t)(uintptr_t)&en_wwn;
+ fctio.fctio_xfer = FCTIO_XFER_READ;
+ fctio.fctio_olen = (uint32_t)(sizeof (attrs));
+ fctio.fctio_obuf = (uint64_t)(uintptr_t)&attrs;
+
+ fct_ioctl(FCTIO_CMD, &fctio);
+
+ stateChange = attrs.lastChange;
+
+ attributes.PortFcId = attrs.PortFcId;
+ attributes.PortType = attrs.PortType;
+ attributes.PortState = attrs.PortState;
+ attributes.PortSupportedClassofService = attrs.PortSupportedClassofService;
+ attributes.PortSupportedSpeed = attrs.PortSupportedSpeed;
+ attributes.PortSpeed = attrs.PortSpeed;
+ attributes.PortMaxFrameSize = attrs.PortMaxFrameSize;
+ attributes.NumberofDiscoveredPorts = attrs.NumberofDiscoveredPorts;
+ memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8);
+ memcpy(&attributes.PortWWN, &attrs.PortWWN, 8);
+ memcpy(&attributes.FabricName, &attrs.FabricName, 8);
+ memcpy(&attributes.PortSupportedFc4Types, &attrs.PortSupportedFc4Types, 32);
+ memcpy(&attributes.PortActiveFc4Types, &attrs.PortActiveFc4Types, 32);
+ memcpy(&attributes.PortSymbolicName, &attrs.PortSymbolicName, 256);
+
+ strncpy((char *)attributes.OSDeviceName, "Not Applicable", 15);
+ return (attributes);
+}
+
+HBA_PORTATTRIBUTES TgtFCHBAPort::getDiscoveredAttributes(
+ HBA_UINT32 discoveredport, uint64_t &stateChange) {
+ Trace log("TgtFCHBAPort::getDiscoverdAttributes(i)");
+
+ HBA_PORTATTRIBUTES attributes;
+ fctio_t fctio;
+ fc_tgt_hba_port_attributes_t attrs;
+
+ memset(&fctio, 0, sizeof (fctio));
+ memset(&attributes, 0, sizeof (attributes));
+
+ uint64_t portwwn = 0;
+ try {
+ string::size_type offset = path.find_last_of(".");
+ if (offset >= 0) {
+ string portwwnString = path.substr(offset+1);
+ portwwn = strtoull(portwwnString.c_str(), NULL, 16);
+ }
+ } catch (...) {
+ throw BadArgumentException();
+ }
+
+ uint64_t en_wwn = htonll(portwwn);
+
+ fctio.fctio_cmd = FCTIO_GET_DISCOVERED_PORT_ATTRIBUTES;
+ fctio.fctio_ilen = 8;
+ fctio.fctio_ibuf = (uint64_t)(uintptr_t)&en_wwn;
+ fctio.fctio_xfer = FCTIO_XFER_READ;
+ fctio.fctio_olen = (uint32_t)(sizeof (attrs));
+ fctio.fctio_obuf = (uint64_t)(uintptr_t)&attrs;
+ fctio.fctio_alen = (uint32_t)(sizeof (discoveredport));
+ fctio.fctio_abuf = (uint64_t)(uintptr_t)&discoveredport;
+
+ fct_ioctl(FCTIO_CMD, &fctio);
+
+ stateChange = attrs.lastChange;
+
+ attributes.PortFcId = attrs.PortFcId;
+ attributes.PortType = attrs.PortType;
+ attributes.PortState = attrs.PortState;
+ attributes.PortSupportedClassofService = attrs.PortSupportedClassofService;
+ attributes.PortSupportedSpeed = attrs.PortSupportedSpeed;
+ attributes.PortSpeed = attrs.PortSpeed;
+ attributes.PortMaxFrameSize = attrs.PortMaxFrameSize;
+ attributes.NumberofDiscoveredPorts = attrs.NumberofDiscoveredPorts;
+ memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8);
+ memcpy(&attributes.PortWWN, &attrs.PortWWN, 8);
+ memcpy(&attributes.FabricName, &attrs.FabricName, 8);
+ memcpy(&attributes.PortSupportedFc4Types, &attrs.PortSupportedFc4Types, 32);
+ memcpy(&attributes.PortActiveFc4Types, &attrs.PortActiveFc4Types, 32);
+ memcpy(&attributes.PortSymbolicName, &attrs.PortSymbolicName, 256);
+
+
+ return (attributes);
+}
+
+HBA_PORTATTRIBUTES TgtFCHBAPort::getDiscoveredAttributes(
+ uint64_t wwn, uint64_t &stateChange) {
+ Trace log("TgtFCHBAPort::getDiscoverdAttributes(p)");
+
+ HBA_PORTATTRIBUTES attributes;
+ fctio_t fctio;
+ fc_tgt_hba_port_attributes_t attrs;
+
+ memset(&fctio, 0, sizeof (fctio));
+ memset(&attributes, 0, sizeof (attributes));
+
+ uint64_t en_wwn = htonll(wwn);
+
+ fctio.fctio_cmd = FCTIO_GET_PORT_ATTRIBUTES;
+ fctio.fctio_olen = (uint32_t)(sizeof (attrs));
+ fctio.fctio_xfer = FCTIO_XFER_READ;
+ fctio.fctio_obuf = (uint64_t)(uintptr_t)&attrs;
+ fctio.fctio_ilen = (uint32_t)(sizeof (wwn));
+ fctio.fctio_ibuf = (uint64_t)(uintptr_t)&en_wwn;
+
+ fct_ioctl(FCTIO_CMD, &fctio);
+
+ stateChange = attrs.lastChange;
+
+ attributes.PortFcId = attrs.PortFcId;
+ attributes.PortType = attrs.PortType;
+ attributes.PortState = attrs.PortState;
+ attributes.PortSupportedClassofService = attrs.PortSupportedClassofService;
+ attributes.PortSupportedSpeed = attrs.PortSupportedSpeed;
+ attributes.PortSpeed = attrs.PortSpeed;
+ attributes.PortMaxFrameSize = attrs.PortMaxFrameSize;
+ attributes.NumberofDiscoveredPorts = attrs.NumberofDiscoveredPorts;
+ memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8);
+ memcpy(&attributes.PortWWN, &attrs.PortWWN, 8);
+ memcpy(&attributes.FabricName, &attrs.FabricName, 8);
+ memcpy(&attributes.PortSupportedFc4Types, &attrs.PortSupportedFc4Types, 32);
+ memcpy(&attributes.PortActiveFc4Types, &attrs.PortActiveFc4Types, 32);
+ memcpy(&attributes.PortSymbolicName, &attrs.PortSymbolicName, 256);
+
+
+ return (attributes);
+}
+
+void TgtFCHBAPort::sendRLS(uint64_t destWWN,
+ void *pRspBuffer,
+ HBA_UINT32 *pRspBufferSize) {
+ Trace log("FCHBAPort::sendRLS");
+
+ fctio_t fctio;
+ // fc_hba_adapter_port_stats_t fc_port_stat;
+ uint64_t en_portWWN;
+
+ // Validate the arguments
+ if (pRspBuffer == NULL ||
+ pRspBufferSize == NULL) {
+ log.userError("NULL hba");
+ throw BadArgumentException();
+ }
+
+ // check to see if we are sending RLS to the HBA
+ HBA_PORTATTRIBUTES attrs;
+ uint64_t tmp;
+ portWWN = getPortWWN();
+ en_portWWN = htonll(portWWN);
+
+ /* The destWWN is either the adapter port or a discovered port. */
+ memset(&fctio, 0, sizeof (fctio));
+ fctio.fctio_cmd = FCTIO_GET_ADAPTER_PORT_STATS;
+ fctio.fctio_ibuf = (uint64_t)(uintptr_t)&en_portWWN;
+ fctio.fctio_ilen = (uint32_t)(sizeof (en_portWWN));
+ if (portWWN != destWWN) {
+ attrs = getDiscoveredAttributes(destWWN, tmp);
+ fctio.fctio_abuf = (uint64_t)(uintptr_t)&attrs.PortFcId;
+ fctio.fctio_alen = (uint32_t)(sizeof (attrs.PortFcId));
+ }
+ fctio.fctio_xfer = FCTIO_XFER_READ;
+ fctio.fctio_flags = 0;
+ fctio.fctio_obuf = (uint64_t)(uintptr_t)new uchar_t[*pRspBufferSize];
+ fctio.fctio_olen = *pRspBufferSize;
+
+ if (fctio.fctio_obuf == NULL) {
+ log.noMemory();
+ throw InternalError();
+ }
+
+ fct_ioctl(FCTIO_CMD, &fctio);
+ memcpy(pRspBuffer, (uchar_t *)(uintptr_t)fctio.fctio_obuf,
+ *pRspBufferSize);
+ if (fctio.fctio_obuf != NULL) {
+ delete((uchar_t *)(uintptr_t)fctio.fctio_obuf);
+ }
+}
+
+/**
+ * @memo Validate that the port is still present in the system
+ * @exception UnavailableException if the port is not present
+ * @version 1.7
+ *
+ * @doc If the port is still present on the system, the routine
+ * will return normally. If the port is not present
+ * an exception will be thrown.
+ */
+void TgtFCHBAPort::validatePresent() {
+ Trace log("TgtFCHBAPort::validatePresent");
+ // We already got the adapter list through the ioctl
+ // so calling it again to validate it is too expensive.
+}
+
+void TgtFCHBAPort::fct_ioctl(int cmd, fctio_t *fctio) {
+ Trace log("TgtFCHBAPort::fct_ioctl");
+ char fcioErrorString[MAX_FCTIO_MSG_LEN] = "";
+ int fd = HBA::_open(FCT_DRIVER_PATH, O_NDELAY | O_RDONLY);
+ try {
+ HBA::_ioctl(fd, cmd, (uchar_t *)fctio);
+ close(fd);
+ if (fctio->fctio_errno) {
+ throw IOError("IOCTL transport failure");
+ }
+ } catch (...) {
+ close(fd);
+ transportError(fctio->fctio_errno, fcioErrorString);
+ log.genericIOError("ioctl (0x%x) failed. Transport: \"%s\"", cmd,
+ fcioErrorString);
+ switch (fctio->fctio_errno) {
+ case FC_BADWWN:
+ throw IllegalWWNException();
+ case FC_BADPORT:
+ throw IllegalWWNException();
+ case FC_OUTOFBOUNDS:
+ throw IllegalIndexException();
+ case FC_PBUSY:
+ case FC_FBUSY:
+ case FC_TRAN_BUSY:
+ case FC_STATEC_BUSY:
+ case FC_DEVICE_BUSY:
+ throw BusyException();
+ case FC_SUCCESS:
+ default:
+ throw;
+ }
+ }
+}
diff --git a/usr/src/lib/sun_fc/common/TgtFCHBAPort.h b/usr/src/lib/sun_fc/common/TgtFCHBAPort.h
new file mode 100644
index 0000000000..aa14e83a05
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/TgtFCHBAPort.h
@@ -0,0 +1,152 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _TGTFCHBAPORT_H
+#define _TGTFCHBAPORT_H
+
+
+
+#include <Lockable.h>
+#include <HBAPort.h>
+#include <Exceptions.h>
+#include <string>
+#include <hbaapi.h>
+#include <sys/fctio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Represents a single HBA port
+ */
+class TgtFCHBAPort : public HBAPort {
+public:
+ TgtFCHBAPort(std::string path);
+ virtual std::string getPath()
+ { return path; }
+ virtual uint64_t getNodeWWN()
+ { return nodeWWN; }
+ virtual uint64_t getPortWWN()
+ { return portWWN; }
+ virtual HBA_PORTATTRIBUTES getPortAttributes(
+ uint64_t &stateChange);
+ virtual HBA_PORTATTRIBUTES getDiscoveredAttributes(
+ HBA_UINT32 discoveredport,
+ uint64_t &stateChange);
+ virtual HBA_PORTATTRIBUTES getDiscoveredAttributes(
+ uint64_t wwn,
+ uint64_t &stateChange);
+ virtual void validatePresent();
+ virtual void getTargetMappings(
+ PHBA_FCPTARGETMAPPINGV2 userMappings) {
+ throw NotSupportedException(); }
+ virtual void getRNIDMgmtInfo(PHBA_MGMTINFO info) {
+ throw NotSupportedException(); }
+ virtual void sendCTPassThru(void *requestBuffer,
+ HBA_UINT32 requestSize,
+ void *responseBuffer,
+ HBA_UINT32 *responseSize) {
+ throw NotSupportedException(); }
+ virtual void sendRLS(uint64_t destWWN,
+ void *pRspBuffer,
+ HBA_UINT32 *pRspBufferSize);
+ virtual void sendRPL(uint64_t destWWN,
+ HBA_UINT32 agent_domain,
+ HBA_UINT32 port_index,
+ void *pRspBuffer,
+ HBA_UINT32 *pRspBufferSize) {
+ throw NotSupportedException(); }
+ virtual void sendRPS(uint64_t agentWWN,
+ HBA_UINT32 agentDomain,
+ uint64_t objectWWN,
+ HBA_UINT32 objectPortNum,
+ void *pRspBuffer,
+ HBA_UINT32 *pRspBufferSize) {
+ throw NotSupportedException(); }
+ virtual void sendSRL(uint64_t destWWN,
+ HBA_UINT32 agent_domain,
+ void *pRspBuffer,
+ HBA_UINT32 *pRspBufferSize) {
+ throw NotSupportedException(); }
+ virtual void sendLIRR(uint64_t destWWN,
+ HBA_UINT8 function,
+ HBA_UINT8 type,
+ void *pRspBuffer,
+ HBA_UINT32 *pRspBufferSize) {
+ throw NotSupportedException(); }
+ virtual void sendReportLUNs(uint64_t wwn,
+ void *responseBuffer, HBA_UINT32 *responseSize,
+ HBA_UINT8 *scsiStatus,
+ void *senseBuffer, HBA_UINT32 *senseSize) {
+ throw NotSupportedException(); }
+ virtual void sendScsiInquiry(uint64_t wwn, HBA_UINT64 fcLun,
+ HBA_UINT8 cdb1, HBA_UINT8 cdb2,
+ void *responseBuffer, HBA_UINT32 *responseSize,
+ HBA_UINT8 *scsiStatus, void *senseBuffer,
+ HBA_UINT32 *senseSize) {
+ throw NotSupportedException(); }
+ virtual void sendReadCapacity(uint64_t pwwn,
+ HBA_UINT64 fcLun, void *responseBuffer,
+ HBA_UINT32 *responseSize, HBA_UINT8 *scsiStatus,
+ void *senseBuffer, HBA_UINT32 *senseSize) {
+ throw NotSupportedException(); }
+ virtual void sendRNID(uint64_t destwwn, HBA_UINT32 destfcid,
+ HBA_UINT32 nodeIdDataFormat, void *pRspBuffer,
+ HBA_UINT32 *RspBufferSize) {
+ throw NotSupportedException(); }
+ virtual void setRNID(HBA_MGMTINFO info) {
+ throw NotSupportedException(); }
+ virtual HBA_PORTNPIVATTRIBUTES getPortNPIVAttributes(
+ uint64_t &stateChange) {
+ throw NotSupportedException(); }
+ virtual uint32_t createNPIVPort(
+ uint64_t vnodewwn,
+ uint64_t vportwwn,
+ uint32_t vindex) {
+ throw NotSupportedException(); }
+ virtual uint32_t deleteNPIVPort(
+ uint64_t vportwwn) {
+ throw NotSupportedException(); }
+
+private:
+ std::string path;
+ uint64_t portWWN;
+ uint64_t nodeWWN;
+ uint32_t instanceNumber;
+ int controllerNumber;
+ static const std::string FCT_DRIVER_PATH;
+ static const int MAX_FCTIO_MSG_LEN;
+ static void transportError(uint32_t fcio_errno, char *message);
+
+ // Wrapper routines to handle error cases
+ static void fct_ioctl(int cmd, fctio_t *arg);
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TGTFCHBAPORT_H */
diff --git a/usr/src/lib/sun_fc/common/Trace.cc b/usr/src/lib/sun_fc/common/Trace.cc
new file mode 100644
index 0000000000..1fc1b64463
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Trace.cc
@@ -0,0 +1,174 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include "Trace.h"
+#include <cstdarg>
+#include <string>
+#include <cstdio>
+#include <string>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+using namespace std;
+
+/**
+ * Tracking for the stacks
+ */
+vector<vector<Trace *> > Trace::stacks;
+
+/**
+ * The indentation string for output
+ */
+vector<string> Trace::indent;
+
+#define MAX_MSG_PREFIX_LEN 128
+#define CTIME_LEN 26
+#define DEBUG_FILE "/var/adm/sun_fc.debug"
+#define LOG_FILE "/var/adm/sun_fc"
+
+/**
+ * @memo Log a message
+ * @param priority The priority of the message (see syslog man page)
+ * @param msg The message string
+ *
+ * @doc If the debug file is present, we will log everything to
+ * that file. Otherwise, if the normal log file is present,
+ * we'll log all non-debug messages to that file. Lastly,
+ * if neither file is present, the message will be
+ * silently discarded.
+ */
+void Trace::message(int priority, const char *msg) {
+ char prefix[MAX_MSG_PREFIX_LEN];
+ char message[MAX_MSG_PREFIX_LEN + MAX_MSG_LEN + 2];
+ int fd;
+ // char time[CTIME_LEN+1];
+ std::string priString;
+
+
+ /* If we can open the log file, write there, else use the cim log */
+ fd = open(DEBUG_FILE, O_WRONLY|O_APPEND); /* will only open if exists */
+ if (fd == -1) {
+ /* No debug file, how about the log file? */
+ if (priority == LOG_DEBUG) {
+ return; /* Ignore debug */
+ }
+ fd = open(LOG_FILE, O_WRONLY|O_APPEND);
+ /* We catch open failures later */
+ }
+
+ // now(time);
+ /* First interpret the priority value */
+ switch (priority) {
+ case INTERNAL_ERROR:
+ priString = "INTERNAL";
+ break;
+ case STACK_TRACE:
+ priString = "STACK";
+ break;
+ case IO_ERROR:
+ priString = "IO";
+ break;
+ case USER_ERROR:
+ priString = "USER";
+ break;
+ case LOG_DEBUG:
+ priString = "DEBUG";
+ break;
+ default:
+ priString = "UNKNOWN";
+ break;
+ }
+
+ if (fd != -1) {
+ /* Format the prefix string for the log file */
+ snprintf(prefix, MAX_MSG_PREFIX_LEN, "%d:%d:%s%s:%s",
+ time(NULL),
+ tid,
+ indent[tid].c_str(),
+ routine.c_str(),
+ priString.c_str());
+
+ /* Format the message string for the log file */
+ snprintf(message, strlen(prefix) + MAX_MSG_LEN + 2, "%s:%s\n",
+ prefix,
+ msg);
+ write(fd, message, strlen(message));
+ close(fd);
+ } /* Else discard the log message */
+}
+
+/**
+ * @memo Create a new Trace instance and update stack.
+ * @param myRoutine The name of the routine
+ *
+ * @doc This class was developed to provide a Java
+ * like stack trace capability, as C++ does not provide
+ * a run-time stack lookup feature. Instances of the
+ * Trace class should be created on the stack so they
+ * will be automatically freed when the stack is popped
+ * when the function returns.
+ */
+Trace::Trace(std::string myRoutine) : routine(myRoutine) {
+ tid = pthread_self();
+ if (stacks.size() < tid+1) {
+ stacks.resize(tid+1);
+ indent.resize(tid+1);
+ indent[tid] = "";
+ }
+ message(LOG_DEBUG, "entered");
+ stacks[tid].push_back(this);
+ indent[tid] += " ";
+}
+
+/**
+ * @memo Delete a trace instances and update the stack
+ */
+Trace::~Trace() {
+ string::size_type len = indent[tid].size();
+ if (len > 0) {
+ indent[tid].resize(len - 1);
+ }
+ message(LOG_DEBUG, "exited");
+ stacks[tid].pop_back();
+}
+
+/**
+ * @memo Print out the current stack trace information
+ */
+void Trace::stackTrace() {
+ message(STACK_TRACE, "Stack trace follows");
+ for (vector<Trace *>::size_type i = stacks[tid].size() - 1; ; i--) {
+ string msg = " ";
+ msg += (stacks[tid])[i]->label();
+ message(STACK_TRACE, msg.c_str());
+ if (i == 0) {
+ break;
+ }
+ }
+}
diff --git a/usr/src/lib/sun_fc/common/Trace.h b/usr/src/lib/sun_fc/common/Trace.h
new file mode 100644
index 0000000000..5753fde720
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/Trace.h
@@ -0,0 +1,113 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _TRACE_H
+#define _TRACE_H
+
+
+
+#include <cstdarg>
+#include <string>
+#include <vector>
+#include <stack>
+#include <pthread.h>
+
+#ifndef MAX_MSG_LEN
+#define MAX_MSG_LEN 2048
+#endif
+
+/*
+ * @memo Tracing, Logging, and debugging facility
+ * @field ONE_FIELD_DESCRIPTION
+ *
+ * @doc The Trace class provides stack tracing, and basic
+ * logging/debugging facilities.
+ */
+class Trace {
+public:
+ Trace(std::string myRoutine);
+
+ ~Trace();
+
+ std::string label() {
+ return (routine);
+ }
+
+ void noMemory() {
+ message(1, "Out of memory");
+ }
+
+ void debug(const char *fmt, ...) {
+ char msg[MAX_MSG_LEN];
+ va_list ap;
+ va_start(ap, fmt);
+ vsnprintf(msg, sizeof (msg), fmt, ap);
+ message(LOG_DEBUG, msg);
+ va_end(ap);
+ }
+
+ void genericIOError(const char *fmt, ...) {
+ char msg[MAX_MSG_LEN];
+ va_list ap;
+ va_start(ap, fmt);
+ vsnprintf(msg, sizeof (msg), fmt, ap);
+ message(IO_ERROR, msg);
+ va_end(ap);
+ }
+
+ void internalError(const char *fmt, ...) {
+ char msg[MAX_MSG_LEN];
+ va_list ap;
+ va_start(ap, fmt);
+ vsnprintf(msg, sizeof (msg), fmt, ap);
+ message(INTERNAL_ERROR, msg);
+ va_end(ap);
+ }
+
+ void userError(const char *fmt, ...) {
+ char msg[MAX_MSG_LEN];
+ va_list ap;
+ va_start(ap, fmt);
+ vsnprintf(msg, sizeof (msg), fmt, ap);
+ message(USER_ERROR, msg);
+ va_end(ap);
+ }
+
+ void stackTrace();
+
+private:
+ std::string routine;
+ pthread_t tid;
+ static const int INTERNAL_ERROR = 3;
+ static const int STACK_TRACE = 4;
+ static const int IO_ERROR = 5;
+ static const int USER_ERROR = 6;
+ static const int LOG_DEBUG = 7;
+ void message(int priority, const char *msg);
+ static std::vector<std::vector<Trace *> > stacks;
+ static std::vector<std::string> indent;
+};
+
+#endif /* _TRACE_H */
diff --git a/usr/src/lib/sun_fc/common/mapfile-vers b/usr/src/lib/sun_fc/common/mapfile-vers
new file mode 100644
index 0000000000..5d978f37d7
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/mapfile-vers
@@ -0,0 +1,100 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+
+SUNWprivate {
+ global:
+ HBA_RegisterLibrary;
+ HBA_RegisterLibraryV2;
+ Sun_fcAdapterCreateWWN;
+ Sun_fcAdapterReturnWWN;
+ Sun_fcCloseAdapter;
+ Sun_fcCreateNPIVPort;
+ Sun_fcDeleteNPIVPort;
+ Sun_fcFreeLibrary;
+ Sun_fcGetAdapterAttributes;
+ Sun_fcGetAdapterName;
+ Sun_fcGetAdapterPortAttributes;
+ Sun_fcGetBindingCapability;
+ Sun_fcGetBindingSupport;
+ Sun_fcGetDiscoveredPortAttributes;
+ Sun_fcGetEventBuffer;
+ Sun_fcGetFC4Statistics;
+ Sun_fcGetFCPStatistics;
+ Sun_fcGetFcpPersistentBinding;
+ Sun_fcGetFcpTargetMapping;
+ Sun_fcGetFcpTargetMappingV2;
+ Sun_fcGetNPIVPortInfo;
+ Sun_fcGetNumberOfAdapters;
+ Sun_fcGetNumberOfTgtAdapters;
+ Sun_fcGetPersistentBindingV2;
+ Sun_fcGetPortAttributesByWWN;
+ Sun_fcGetPortNPIVAttributes;
+ Sun_fcGetPortStatistics;
+ Sun_fcGetRNIDMgmtInfo;
+ Sun_fcGetTgtAdapterName;
+ Sun_fcGetVendorLibraryAttributes;
+ Sun_fcGetVersion;
+ Sun_fcLoadLibrary;
+ Sun_fcNPIVGetAdapterAttributes;
+ Sun_fcOpenAdapter;
+ Sun_fcOpenAdapterByWWN;
+ Sun_fcOpenTgtAdapter;
+ Sun_fcOpenTgtAdapterByWWN;
+ Sun_fcRefreshAdapterConfiguration;
+ Sun_fcRefreshInformation;
+ Sun_fcRegisterForAdapterAddEvents;
+ Sun_fcRegisterForAdapterDeviceEvents;
+ Sun_fcRegisterForAdapterEvents;
+ Sun_fcRegisterForAdapterPortEvents;
+ Sun_fcRegisterForAdapterPortStatEvents;
+ Sun_fcRegisterForLinkEvents;
+ Sun_fcRegisterForTargetEvents;
+ Sun_fcRemoveAllPersistentBindings;
+ Sun_fcRemoveCallback;
+ Sun_fcRemovePersistentBinding;
+ Sun_fcResetStatistics;
+ Sun_fcScsiInquiryV2;
+ Sun_fcScsiReadCapacityV2;
+ Sun_fcScsiReportLUNsV2;
+ Sun_fcSendCTPassThru;
+ Sun_fcSendCTPassThruV2;
+ Sun_fcSendLIRR;
+ Sun_fcSendRLS;
+ Sun_fcSendRNID;
+ Sun_fcSendRNIDV2;
+ Sun_fcSendRPL;
+ Sun_fcSendRPS;
+ Sun_fcSendReadCapacity;
+ Sun_fcSendReportLUNs;
+ Sun_fcSendSRL;
+ Sun_fcSendScsiInquiry;
+ Sun_fcSetBindingSupport;
+ Sun_fcSetPersistentBindingV2;
+ Sun_fcSetRNIDMgmtInfo;
+
+ local:
+ *;
+};
diff --git a/usr/src/lib/sun_fc/common/sun_fc.h b/usr/src/lib/sun_fc/common/sun_fc.h
new file mode 100644
index 0000000000..92aecb73c2
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/sun_fc.h
@@ -0,0 +1,171 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SUN_FC_H
+#define _SUN_FC_H
+
+
+
+#include <hbaapi.h>
+#include <vendorhbaapi.h>
+
+#define HR_SECOND 1000000000
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+// Public External routines
+extern HBA_STATUS HBA_RegisterLibrary(PHBA_ENTRYPOINTS);
+extern HBA_UINT32 Sun_fcGetVersion();
+extern HBA_STATUS Sun_fcLoadLibrary();
+extern HBA_STATUS Sun_fcFreeLibrary();
+extern HBA_UINT32 Sun_fcGetNumberOfAdapters();
+extern HBA_STATUS Sun_fcGetAdapterName(HBA_UINT32, char *);
+extern HBA_HANDLE Sun_fcOpenAdapter(char *);
+extern void Sun_fcCloseAdapter(HBA_HANDLE);
+extern HBA_STATUS Sun_fcGetAdapterAttributes(HBA_HANDLE,
+ PHBA_ADAPTERATTRIBUTES);
+extern HBA_STATUS Sun_fcGetAdapterPortAttributes(HBA_HANDLE, HBA_UINT32,
+ PHBA_PORTATTRIBUTES);
+extern HBA_STATUS Sun_fcGetPortStatistics(HBA_HANDLE, HBA_UINT32,
+ PHBA_PORTSTATISTICS);
+extern HBA_STATUS Sun_fcGetDiscoveredPortAttributes(HBA_HANDLE, HBA_UINT32,
+ HBA_UINT32, PHBA_PORTATTRIBUTES);
+extern HBA_STATUS Sun_fcGetPortAttributesByWWN(HBA_HANDLE, HBA_WWN,
+ PHBA_PORTATTRIBUTES);
+extern HBA_STATUS Sun_fcSendCTPassThru(HBA_HANDLE, void *, HBA_UINT32, void *,
+ HBA_UINT32);
+extern void Sun_fcRefreshInformation(HBA_HANDLE);
+extern void Sun_fcResetStatistics(HBA_HANDLE handle, HBA_UINT32 port);
+extern HBA_STATUS Sun_fcGetFcpTargetMapping(HBA_HANDLE, PHBA_FCPTARGETMAPPING);
+extern HBA_STATUS Sun_fcGetFcpPersistentBinding(HBA_HANDLE, PHBA_FCPBINDING);
+extern HBA_STATUS Sun_fcGetEventBuffer(HBA_HANDLE, PHBA_EVENTINFO,
+ HBA_UINT32 *);
+extern HBA_STATUS Sun_fcSetRNIDMgmtInfo(HBA_HANDLE, HBA_MGMTINFO);
+extern HBA_STATUS Sun_fcGetRNIDMgmtInfo(HBA_HANDLE, PHBA_MGMTINFO);
+extern HBA_STATUS Sun_fcSendRNID(HBA_HANDLE, HBA_WWN, HBA_WWNTYPE,
+ void *, HBA_UINT32 *);
+extern HBA_STATUS Sun_fcSendScsiInquiry(HBA_HANDLE, HBA_WWN, HBA_UINT64,
+ HBA_UINT8, HBA_UINT32, void *, HBA_UINT32, void *, HBA_UINT32);
+extern HBA_STATUS Sun_fcSendReportLUNs(HBA_HANDLE, HBA_WWN, void *, HBA_UINT32,
+ void *, HBA_UINT32);
+extern HBA_STATUS Sun_fcSendReadCapacity(HBA_HANDLE, HBA_WWN, HBA_UINT64,
+ void *, HBA_UINT32, void *, HBA_UINT32);
+
+// V2 external routines
+extern HBA_STATUS Sun_fcOpenAdapterByWWN(HBA_HANDLE *, HBA_WWN);
+extern HBA_STATUS Sun_fcGetFcpTargetMappingV2(HBA_HANDLE, HBA_WWN,
+ HBA_FCPTARGETMAPPINGV2 *);
+extern HBA_STATUS Sun_fcSendCTPassThruV2(HBA_HANDLE, HBA_WWN, void *,
+ HBA_UINT32, void *, HBA_UINT32 *);
+extern void Sun_fcRefreshAdapterConfiguration(void);
+extern HBA_STATUS Sun_fcGetBindingCapability(HBA_HANDLE, HBA_WWN,
+ HBA_BIND_CAPABILITY *);
+extern HBA_STATUS Sun_fcGetBindingSupport(HBA_HANDLE, HBA_WWN,
+ HBA_BIND_CAPABILITY *);
+extern HBA_STATUS Sun_fcSetBindingSupport(HBA_HANDLE, HBA_WWN,
+ HBA_BIND_CAPABILITY);
+extern HBA_STATUS Sun_fcSetPersistentBindingV2(HBA_HANDLE, HBA_WWN,
+ const HBA_FCPBINDING2 *);
+extern HBA_STATUS Sun_fcGetPersistentBindingV2(HBA_HANDLE, HBA_WWN,
+ HBA_FCPBINDING2 *);
+extern HBA_STATUS Sun_fcRemovePersistentBinding(HBA_HANDLE, HBA_WWN,
+ const HBA_FCPBINDING2 *);
+extern HBA_STATUS Sun_fcRemoveAllPersistentBindings(HBA_HANDLE, HBA_WWN);
+extern HBA_STATUS Sun_fcSendRNIDV2(HBA_HANDLE, HBA_WWN, HBA_WWN, HBA_UINT32,
+ HBA_UINT32, void *, HBA_UINT32*);
+extern HBA_STATUS Sun_fcScsiInquiryV2(HBA_HANDLE, HBA_WWN, HBA_WWN, HBA_UINT64,
+ HBA_UINT8, HBA_UINT8, void *, HBA_UINT32 *, HBA_UINT8 *, void *,
+ HBA_UINT32 *);
+extern HBA_STATUS Sun_fcScsiReportLUNsV2(HBA_HANDLE, HBA_WWN, HBA_WWN, void *,
+ HBA_UINT32 *, HBA_UINT8 *, void *, HBA_UINT32 *);
+extern HBA_STATUS Sun_fcScsiReadCapacityV2(HBA_HANDLE, HBA_WWN, HBA_WWN,
+ HBA_UINT64, void *, HBA_UINT32 *, HBA_UINT8 *, void *, HBA_UINT32 *);
+extern HBA_UINT32 Sun_fcGetVendorLibraryAttributes(HBA_LIBRARYATTRIBUTES *);
+extern HBA_STATUS Sun_fcRemoveCallback(HBA_CALLBACKHANDLE);
+extern HBA_STATUS Sun_fcRegisterForAdapterAddEvents(void (*)(void *, HBA_WWN,
+ HBA_UINT32), void *, HBA_CALLBACKHANDLE *);
+extern HBA_STATUS Sun_fcRegisterForAdapterEvents(void (*)(void *, HBA_WWN,
+ HBA_UINT32), void *, HBA_HANDLE, HBA_CALLBACKHANDLE *);
+extern HBA_STATUS Sun_fcRegisterForAdapterPortEvents(void (*)(void *, HBA_WWN,
+ HBA_UINT32, HBA_UINT32), void *, HBA_HANDLE, HBA_WWN, HBA_CALLBACKHANDLE *);
+extern HBA_STATUS Sun_fcRegisterForAdapterPortStatEvents(void (*)(void *,
+ HBA_WWN, HBA_UINT32), void *, HBA_HANDLE, HBA_WWN,
+ HBA_PORTSTATISTICS, HBA_UINT32, HBA_CALLBACKHANDLE *);
+extern HBA_STATUS Sun_fcRegisterForTargetEvents(void (*)(void *, HBA_WWN,
+ HBA_WWN, HBA_UINT32), void *, HBA_HANDLE, HBA_WWN, HBA_WWN,
+ HBA_CALLBACKHANDLE *, HBA_UINT32);
+extern HBA_STATUS Sun_fcRegisterForLinkEvents(void (*)(void *, HBA_WWN,
+ HBA_UINT32, void *, HBA_UINT32), void *, void *, HBA_UINT32, HBA_HANDLE,
+ HBA_CALLBACKHANDLE *);
+extern HBA_STATUS Sun_fcSendRLS(HBA_HANDLE, HBA_WWN, HBA_WWN,
+ void *, HBA_UINT32 *);
+extern HBA_STATUS Sun_fcSendRPL(HBA_HANDLE, HBA_WWN, HBA_WWN, HBA_UINT32,
+ HBA_UINT32, void *, HBA_UINT32 *);
+extern HBA_STATUS Sun_fcSendRPS(HBA_HANDLE, HBA_WWN, HBA_WWN, HBA_UINT32,
+ HBA_WWN, HBA_UINT32, void *, HBA_UINT32 *);
+extern HBA_STATUS Sun_fcSendSRL(HBA_HANDLE, HBA_WWN, HBA_WWN, HBA_UINT32,
+ void *, HBA_UINT32 *);
+extern HBA_STATUS Sun_fcSendLIRR(HBA_HANDLE, HBA_WWN, HBA_WWN, HBA_UINT8,
+ HBA_UINT8, void *, HBA_UINT32 *);
+extern HBA_STATUS Sun_fcGetFC4Statistics(HBA_HANDLE, HBA_WWN, HBA_UINT8,
+ HBA_FC4STATISTICS *);
+extern HBA_STATUS Sun_fcGetFCPStatistics(HBA_HANDLE, const HBA_SCSIID *,
+ HBA_FC4STATISTICS *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <inttypes.h>
+#ifdef _BIG_ENDIAN
+#define htonll(x) (x)
+#define ntohll(x) (x)
+#else
+#define htonll(x) ((((uint64_t)htonl(x)) << 32) + htonl(x >> 32))
+#define ntohll(x) ((((uint64_t)ntohl(x)) << 32) + ntohl(x >> 32))
+#endif
+
+
+
+#include <string.h>
+inline u_longlong_t
+wwnConversion(uchar_t *wwn) {
+ u_longlong_t tmp;
+ memcpy(&tmp, wwn, sizeof (u_longlong_t));
+ return (ntohll(tmp));
+}
+
+#ifndef SCMD_REPORT_LUNS
+#define SCMD_REPORT_LUNS 0xA0
+#endif
+
+
+
+#endif /* _SUN_FC_H */
diff --git a/usr/src/lib/sun_fc/common/sun_fc_version.h b/usr/src/lib/sun_fc/common/sun_fc_version.h
new file mode 100644
index 0000000000..2cfec9e2ff
--- /dev/null
+++ b/usr/src/lib/sun_fc/common/sun_fc_version.h
@@ -0,0 +1,34 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SUN_FC_VERSION_H
+#define _SUN_FC_VERSION_H
+
+
+#define VSL_NUMERIC_VERSION 2
+#define VSL_STRING_VERSION "Version 2"
+#define VSL_NAME "Sun T11 FC-HBA Vendor Library"
+
+#endif /* _SUN_FC_VERSION_H */