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