diff options
author | John Forte <John.Forte@Sun.COM> | 2008-10-14 15:09:13 -0700 |
---|---|---|
committer | John Forte <John.Forte@Sun.COM> | 2008-10-14 15:09:13 -0700 |
commit | fcf3ce441efd61da9bb2884968af01cb7c1452cc (patch) | |
tree | 0e80d59ad41702571586195bf099ccc14222ce02 /usr/src/lib/sun_fc/common | |
parent | 247b82a1f1cb5ebd2d163bd9afdb1a3065611962 (diff) | |
download | illumos-joyent-fcf3ce441efd61da9bb2884968af01cb7c1452cc.tar.gz |
6745433 Merge NWS consolidation into OS/Net consolidation
Diffstat (limited to 'usr/src/lib/sun_fc/common')
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 */ |