1*fcf3ce44SJohn Forte /*
2*fcf3ce44SJohn Forte  * CDDL HEADER START
3*fcf3ce44SJohn Forte  *
4*fcf3ce44SJohn Forte  * The contents of this file are subject to the terms of the
5*fcf3ce44SJohn Forte  * Common Development and Distribution License (the "License").
6*fcf3ce44SJohn Forte  * You may not use this file except in compliance with the License.
7*fcf3ce44SJohn Forte  *
8*fcf3ce44SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*fcf3ce44SJohn Forte  * or http://www.opensolaris.org/os/licensing.
10*fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11*fcf3ce44SJohn Forte  * and limitations under the License.
12*fcf3ce44SJohn Forte  *
13*fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14*fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16*fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17*fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18*fcf3ce44SJohn Forte  *
19*fcf3ce44SJohn Forte  * CDDL HEADER END
20*fcf3ce44SJohn Forte  */
21*fcf3ce44SJohn Forte /*
22*fcf3ce44SJohn Forte  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23*fcf3ce44SJohn Forte  * Use is subject to license terms.
24*fcf3ce44SJohn Forte  */
25*fcf3ce44SJohn Forte 
26*fcf3ce44SJohn Forte 
27*fcf3ce44SJohn Forte 
28*fcf3ce44SJohn Forte #include "HandlePort.h"
29*fcf3ce44SJohn Forte #include "Exceptions.h"
30*fcf3ce44SJohn Forte #include "Trace.h"
31*fcf3ce44SJohn Forte #include <iostream>
32*fcf3ce44SJohn Forte #include <iomanip>
33*fcf3ce44SJohn Forte #include <sys/types.h>
34*fcf3ce44SJohn Forte #include <sys/stat.h>
35*fcf3ce44SJohn Forte #include <fcntl.h>
36*fcf3ce44SJohn Forte #include <unistd.h>
37*fcf3ce44SJohn Forte #include <stropts.h>
38*fcf3ce44SJohn Forte 
39*fcf3ce44SJohn Forte 
40*fcf3ce44SJohn Forte using namespace std;
41*fcf3ce44SJohn Forte 
42*fcf3ce44SJohn Forte /**
43*fcf3ce44SJohn Forte  * @memo	    Construct a new HandlePort for state tracking
44*fcf3ce44SJohn Forte  * @precondition    Handle must be open
45*fcf3ce44SJohn Forte  * @param	    myHandle The open handle for this HBA
46*fcf3ce44SJohn Forte  * @param	    myHBA The HBA for this port
47*fcf3ce44SJohn Forte  * @param	    myPort The HBA Port to open
48*fcf3ce44SJohn Forte  */
HandlePort(Handle * myHandle,HBA * myHBA,HBAPort * myPort)49*fcf3ce44SJohn Forte HandlePort::HandlePort(Handle *myHandle, HBA *myHBA, HBAPort *myPort) :
50*fcf3ce44SJohn Forte 	handle(myHandle), hba(myHBA), port(myPort), active(false) {
51*fcf3ce44SJohn Forte 	Trace log("HandlePort::HandlePort");
52*fcf3ce44SJohn Forte }
53*fcf3ce44SJohn Forte 
54*fcf3ce44SJohn Forte /**
55*fcf3ce44SJohn Forte  * @memo	    Reset the state tracking values for stale index detection
56*fcf3ce44SJohn Forte  * @postcondition   The first subsequent call to any index based routine
57*fcf3ce44SJohn Forte  *		    will always succed.
58*fcf3ce44SJohn Forte  */
refresh()59*fcf3ce44SJohn Forte void HandlePort::refresh() {
60*fcf3ce44SJohn Forte 	Trace log("HandlePort::refresh");
61*fcf3ce44SJohn Forte 	lock();
62*fcf3ce44SJohn Forte 	active = false;
63*fcf3ce44SJohn Forte 	unlock();
64*fcf3ce44SJohn Forte }
65*fcf3ce44SJohn Forte 
66*fcf3ce44SJohn Forte /**
67*fcf3ce44SJohn Forte  * @memo	    Validate the current state of the handle port
68*fcf3ce44SJohn Forte  * @exception	    StaleDataException Thrown if the state has changed
69*fcf3ce44SJohn Forte  * @param	    newState The new state of the port
70*fcf3ce44SJohn Forte  *
71*fcf3ce44SJohn Forte  * @doc		    After opening a port or refreshing, no state is tracked.
72*fcf3ce44SJohn Forte  *		    The first time validate is called, the state is recorded.
73*fcf3ce44SJohn Forte  *		    Subsequent calls will verify that the state is the same.
74*fcf3ce44SJohn Forte  *		    If the state has changed, the exception will be thrown.
75*fcf3ce44SJohn Forte  */
validate(uint64_t newState)76*fcf3ce44SJohn Forte void HandlePort::validate(uint64_t newState) {
77*fcf3ce44SJohn Forte 	Trace log("HandlePort::validate");
78*fcf3ce44SJohn Forte 	log.debug("Port %016llx state %016llx", port->getPortWWN(), newState);
79*fcf3ce44SJohn Forte 	lock();
80*fcf3ce44SJohn Forte 	if (active) {
81*fcf3ce44SJohn Forte 	    if (lastState != newState) {
82*fcf3ce44SJohn Forte 		unlock();
83*fcf3ce44SJohn Forte 		throw StaleDataException();
84*fcf3ce44SJohn Forte 	    }
85*fcf3ce44SJohn Forte 	} else {
86*fcf3ce44SJohn Forte 	    active = true;
87*fcf3ce44SJohn Forte 	    lastState = newState;
88*fcf3ce44SJohn Forte 	}
89*fcf3ce44SJohn Forte 	unlock();
90*fcf3ce44SJohn Forte }
91*fcf3ce44SJohn Forte 
92*fcf3ce44SJohn Forte /**
93*fcf3ce44SJohn Forte  * @memo	    Verify this port has the stated port wwn
94*fcf3ce44SJohn Forte  * @return	    TRUE if the argument matches this port
95*fcf3ce44SJohn Forte  * @return	    FALSE if the argument does not match this port
96*fcf3ce44SJohn Forte  * @param	    portWWN The Port WWN to compare against this port
97*fcf3ce44SJohn Forte  */
match(uint64_t portWWN)98*fcf3ce44SJohn Forte bool HandlePort::match(uint64_t portWWN) {
99*fcf3ce44SJohn Forte 	Trace log("HandlePort::match(wwn)");
100*fcf3ce44SJohn Forte 	bool ret = false;
101*fcf3ce44SJohn Forte 	ret = (portWWN == port->getPortWWN());
102*fcf3ce44SJohn Forte 	return (ret);
103*fcf3ce44SJohn Forte }
104*fcf3ce44SJohn Forte 
105*fcf3ce44SJohn Forte /**
106*fcf3ce44SJohn Forte  * @memo	    Verify this port is the stated index
107*fcf3ce44SJohn Forte  * @return	    TRUE if the argument matches this port
108*fcf3ce44SJohn Forte  * @return	    FALSE if the argument does not match this port
109*fcf3ce44SJohn Forte  * @param	    index The index value to compare against this port
110*fcf3ce44SJohn Forte  */
match(int index)111*fcf3ce44SJohn Forte bool HandlePort::match(int index) {
112*fcf3ce44SJohn Forte 	Trace log("HandlePort::match(index)");
113*fcf3ce44SJohn Forte 	return (*port == *(hba->getPortByIndex(index)));
114*fcf3ce44SJohn Forte }
115*fcf3ce44SJohn Forte 
116*fcf3ce44SJohn Forte /**
117*fcf3ce44SJohn Forte  * @memo	    Get attributes from a discovered port.
118*fcf3ce44SJohn Forte  * @exception	    ... underlying exceptions will be thrown
119*fcf3ce44SJohn Forte  * @return	    The discovered port attributes
120*fcf3ce44SJohn Forte  * @param	    wwn The node or port wwn of the discovered port
121*fcf3ce44SJohn Forte  *
122*fcf3ce44SJohn Forte  * @doc		    This routine will not perform any state validation
123*fcf3ce44SJohn Forte  */
getDiscoveredAttributes(uint64_t wwn)124*fcf3ce44SJohn Forte HBA_PORTATTRIBUTES HandlePort::getDiscoveredAttributes(uint64_t wwn) {
125*fcf3ce44SJohn Forte 	Trace log("HandlePort::getDiscoveredAttributes(wwn)");
126*fcf3ce44SJohn Forte 	uint64_t newState;
127*fcf3ce44SJohn Forte 	HBA_PORTATTRIBUTES attributes = port->getDiscoveredAttributes(
128*fcf3ce44SJohn Forte 		wwn, newState);
129*fcf3ce44SJohn Forte 	// We don't validate when a WWN was used
130*fcf3ce44SJohn Forte 	return (attributes);
131*fcf3ce44SJohn Forte }
132*fcf3ce44SJohn Forte 
133*fcf3ce44SJohn Forte /**
134*fcf3ce44SJohn Forte  * @memo	    Get attributes from this port.
135*fcf3ce44SJohn Forte  * @exception	    ... underlying exceptions will be thrown
136*fcf3ce44SJohn Forte  * @return	    The port attributes
137*fcf3ce44SJohn Forte  * @see		    HandlePort::validate
138*fcf3ce44SJohn Forte  *
139*fcf3ce44SJohn Forte  * @doc		    This routine will perform state validation
140*fcf3ce44SJohn Forte  */
getPortAttributes()141*fcf3ce44SJohn Forte HBA_PORTATTRIBUTES HandlePort::getPortAttributes() {
142*fcf3ce44SJohn Forte 	Trace log("HandlePort::getPortAttributes");
143*fcf3ce44SJohn Forte 	uint64_t newState;
144*fcf3ce44SJohn Forte 	HBA_PORTATTRIBUTES attributes = port->getPortAttributes(newState);
145*fcf3ce44SJohn Forte 	validate(newState);
146*fcf3ce44SJohn Forte 	return (attributes);
147*fcf3ce44SJohn Forte }
148*fcf3ce44SJohn Forte 
149*fcf3ce44SJohn Forte /**
150*fcf3ce44SJohn Forte  * @memo	    Get attributes from a discovered port.
151*fcf3ce44SJohn Forte  * @exception	    ... underlying exceptions will be thrown
152*fcf3ce44SJohn Forte  * @return	    The discovered port attributes
153*fcf3ce44SJohn Forte  * @param	    discoveredport The index of the discovered port
154*fcf3ce44SJohn Forte  * @see		    HandlePort::validate
155*fcf3ce44SJohn Forte  *
156*fcf3ce44SJohn Forte  * @doc		    This routine will perform state validation
157*fcf3ce44SJohn Forte  */
158*fcf3ce44SJohn Forte HBA_PORTATTRIBUTES
getDiscoveredAttributes(HBA_UINT32 discoveredport)159*fcf3ce44SJohn Forte HandlePort::getDiscoveredAttributes(HBA_UINT32 discoveredport) {
160*fcf3ce44SJohn Forte 	Trace log("HandlePort::getDiscoveredAttributes(index)");
161*fcf3ce44SJohn Forte 	uint64_t newState;
162*fcf3ce44SJohn Forte 	HBA_PORTATTRIBUTES attributes = port->getDiscoveredAttributes(
163*fcf3ce44SJohn Forte 		discoveredport, newState);
164*fcf3ce44SJohn Forte 	validate(newState);
165*fcf3ce44SJohn Forte 	return (attributes);
166*fcf3ce44SJohn Forte }
167*fcf3ce44SJohn Forte 
getPortNPIVAttributes()168*fcf3ce44SJohn Forte HBA_PORTNPIVATTRIBUTES HandlePort::getPortNPIVAttributes() {
169*fcf3ce44SJohn Forte 	Trace log("HandlePort::getPortNPIVAttributes");
170*fcf3ce44SJohn Forte 	uint64_t newState;
171*fcf3ce44SJohn Forte 	HBA_PORTNPIVATTRIBUTES attributes = port->getPortNPIVAttributes(newState);
172*fcf3ce44SJohn Forte 	validate(newState);
173*fcf3ce44SJohn Forte 	return (attributes);
174*fcf3ce44SJohn Forte }
175*fcf3ce44SJohn Forte 
deleteNPIVPort(uint64_t vportwwn)176*fcf3ce44SJohn Forte uint32_t HandlePort::deleteNPIVPort(uint64_t vportwwn) {
177*fcf3ce44SJohn Forte 	Trace log("HandlePort::deleteNPIVPort");
178*fcf3ce44SJohn Forte 	uint32_t ret = port->deleteNPIVPort(vportwwn);
179*fcf3ce44SJohn Forte 
180*fcf3ce44SJohn Forte 	return (ret);
181*fcf3ce44SJohn Forte }
182*fcf3ce44SJohn Forte 
createNPIVPort(uint64_t vnodewwn,uint64_t vportwwn,uint32_t vindex)183*fcf3ce44SJohn Forte uint32_t HandlePort::createNPIVPort(uint64_t vnodewwn,
184*fcf3ce44SJohn Forte     uint64_t vportwwn, uint32_t vindex) {
185*fcf3ce44SJohn Forte 	Trace log("HandlePort::createNPIVPort");
186*fcf3ce44SJohn Forte 	uint32_t vportindex;
187*fcf3ce44SJohn Forte 
188*fcf3ce44SJohn Forte 	vportindex = port->createNPIVPort(vnodewwn, vportwwn, vindex);
189*fcf3ce44SJohn Forte 	return (vportindex);
190*fcf3ce44SJohn Forte }
191*fcf3ce44SJohn Forte 
getHandleNPIVPortByIndex(int index)192*fcf3ce44SJohn Forte HandleNPIVPort* HandlePort::getHandleNPIVPortByIndex(int index) {
193*fcf3ce44SJohn Forte 	Trace log("HandlePort::getHandleNPIVPortByIndex(int index)");
194*fcf3ce44SJohn Forte 
195*fcf3ce44SJohn Forte 	HBANPIVPort* vport = port->getPortByIndex(index);
196*fcf3ce44SJohn Forte 	return (getHandleNPIVPort(vport->getPortWWN()));
197*fcf3ce44SJohn Forte }
198*fcf3ce44SJohn Forte 
getHandleNPIVPort(uint64_t wwn)199*fcf3ce44SJohn Forte HandleNPIVPort* HandlePort::getHandleNPIVPort(uint64_t wwn) {
200*fcf3ce44SJohn Forte 	Trace log("HandlePort::getHandleNPIVPort");
201*fcf3ce44SJohn Forte 	lock();
202*fcf3ce44SJohn Forte 	try {
203*fcf3ce44SJohn Forte 		// Check to see if the wwn is in the map
204*fcf3ce44SJohn Forte 		if (npivportHandles.find(wwn) == npivportHandles.end()) {
205*fcf3ce44SJohn Forte 			// Not found, add a new one
206*fcf3ce44SJohn Forte 			HBANPIVPort* vport = port->getPort(wwn);
207*fcf3ce44SJohn Forte 			npivportHandles[wwn] = new HandleNPIVPort(handle, this, hba, port, vport);
208*fcf3ce44SJohn Forte 		}
209*fcf3ce44SJohn Forte 		HandleNPIVPort *npivportHandle = npivportHandles[wwn];
210*fcf3ce44SJohn Forte 		unlock();
211*fcf3ce44SJohn Forte 		return (npivportHandle);
212*fcf3ce44SJohn Forte 	} catch (...) {
213*fcf3ce44SJohn Forte 		unlock();
214*fcf3ce44SJohn Forte 		throw;
215*fcf3ce44SJohn Forte 	}
216*fcf3ce44SJohn Forte }
217*fcf3ce44SJohn Forte