2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A/*
2N/A * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
2N/A * Use is subject to license terms.
2N/A */
2N/A
2N/A
2N/A
2N/A#include "HandlePort.h"
2N/A#include "Exceptions.h"
2N/A#include "Trace.h"
2N/A#include <iostream>
2N/A#include <iomanip>
2N/A#include <sys/types.h>
2N/A#include <sys/stat.h>
2N/A#include <fcntl.h>
2N/A#include <unistd.h>
2N/A#include <stropts.h>
2N/A
2N/A
2N/Ausing namespace std;
2N/A
2N/A/**
2N/A * @memo Construct a new HandlePort for state tracking
2N/A * @precondition Handle must be open
2N/A * @param myHandle The open handle for this HBA
2N/A * @param myHBA The HBA for this port
2N/A * @param myPort The HBA Port to open
2N/A */
2N/AHandlePort::HandlePort(Handle *myHandle, HBA *myHBA, HBAPort *myPort) :
2N/A handle(myHandle), hba(myHBA), port(myPort), active(false) {
2N/A Trace log("HandlePort::HandlePort");
2N/A}
2N/A
2N/A/**
2N/A * @memo Reset the state tracking values for stale index detection
2N/A * @postcondition The first subsequent call to any index based routine
2N/A * will always succed.
2N/A */
2N/Avoid HandlePort::refresh() {
2N/A Trace log("HandlePort::refresh");
2N/A lock();
2N/A active = false;
2N/A unlock();
2N/A}
2N/A
2N/A/**
2N/A * @memo Validate the current state of the handle port
2N/A * @exception StaleDataException Thrown if the state has changed
2N/A * @param newState The new state of the port
2N/A *
2N/A * @doc After opening a port or refreshing, no state is tracked.
2N/A * The first time validate is called, the state is recorded.
2N/A * Subsequent calls will verify that the state is the same.
2N/A * If the state has changed, the exception will be thrown.
2N/A */
2N/Avoid HandlePort::validate(uint64_t newState) {
2N/A Trace log("HandlePort::validate");
2N/A log.debug("Port %016llx state %016llx", port->getPortWWN(), newState);
2N/A lock();
2N/A if (active) {
2N/A if (lastState != newState) {
2N/A unlock();
2N/A throw StaleDataException();
2N/A }
2N/A } else {
2N/A active = true;
2N/A lastState = newState;
2N/A }
2N/A unlock();
2N/A}
2N/A
2N/A/**
2N/A * @memo Verify this port has the stated port wwn
2N/A * @return TRUE if the argument matches this port
2N/A * @return FALSE if the argument does not match this port
2N/A * @param portWWN The Port WWN to compare against this port
2N/A */
2N/Abool HandlePort::match(uint64_t portWWN) {
2N/A Trace log("HandlePort::match(wwn)");
2N/A bool ret = false;
2N/A ret = (portWWN == port->getPortWWN());
2N/A return (ret);
2N/A}
2N/A
2N/A/**
2N/A * @memo Verify this port is the stated index
2N/A * @return TRUE if the argument matches this port
2N/A * @return FALSE if the argument does not match this port
2N/A * @param index The index value to compare against this port
2N/A */
2N/Abool HandlePort::match(int index) {
2N/A Trace log("HandlePort::match(index)");
2N/A return (*port == *(hba->getPortByIndex(index)));
2N/A}
2N/A
2N/A/**
2N/A * @memo Get attributes from a discovered port.
2N/A * @exception ... underlying exceptions will be thrown
2N/A * @return The discovered port attributes
2N/A * @param wwn The node or port wwn of the discovered port
2N/A *
2N/A * @doc This routine will not perform any state validation
2N/A */
2N/AHBA_PORTATTRIBUTES HandlePort::getDiscoveredAttributes(uint64_t wwn) {
2N/A Trace log("HandlePort::getDiscoveredAttributes(wwn)");
2N/A uint64_t newState;
2N/A HBA_PORTATTRIBUTES attributes = port->getDiscoveredAttributes(
2N/A wwn, newState);
2N/A // We don't validate when a WWN was used
2N/A return (attributes);
2N/A}
2N/A
2N/A/**
2N/A * @memo Get attributes from this port.
2N/A * @exception ... underlying exceptions will be thrown
2N/A * @return The port attributes
2N/A * @see HandlePort::validate
2N/A *
2N/A * @doc This routine will perform state validation
2N/A */
2N/AHBA_PORTATTRIBUTES HandlePort::getPortAttributes() {
2N/A Trace log("HandlePort::getPortAttributes");
2N/A uint64_t newState;
2N/A HBA_PORTATTRIBUTES attributes = port->getPortAttributes(newState);
2N/A validate(newState);
2N/A return (attributes);
2N/A}
2N/A
2N/A/**
2N/A * @memo Get attributes from a discovered port.
2N/A * @exception ... underlying exceptions will be thrown
2N/A * @return The discovered port attributes
2N/A * @param discoveredport The index of the discovered port
2N/A * @see HandlePort::validate
2N/A *
2N/A * @doc This routine will perform state validation
2N/A */
2N/AHBA_PORTATTRIBUTES
2N/AHandlePort::getDiscoveredAttributes(HBA_UINT32 discoveredport) {
2N/A Trace log("HandlePort::getDiscoveredAttributes(index)");
2N/A uint64_t newState;
2N/A HBA_PORTATTRIBUTES attributes = port->getDiscoveredAttributes(
2N/A discoveredport, newState);
2N/A validate(newState);
2N/A return (attributes);
2N/A}
2N/A
2N/AHBA_PORTNPIVATTRIBUTES HandlePort::getPortNPIVAttributes() {
2N/A Trace log("HandlePort::getPortNPIVAttributes");
2N/A uint64_t newState;
2N/A HBA_PORTNPIVATTRIBUTES attributes = port->getPortNPIVAttributes(newState);
2N/A validate(newState);
2N/A return (attributes);
2N/A}
2N/A
2N/Auint32_t HandlePort::deleteNPIVPort(uint64_t vportwwn) {
2N/A Trace log("HandlePort::deleteNPIVPort");
2N/A uint32_t ret = port->deleteNPIVPort(vportwwn);
2N/A
2N/A return (ret);
2N/A}
2N/A
2N/Auint32_t HandlePort::createNPIVPort(uint64_t vnodewwn,
2N/A uint64_t vportwwn, uint32_t vindex) {
2N/A Trace log("HandlePort::createNPIVPort");
2N/A uint32_t vportindex;
2N/A
2N/A vportindex = port->createNPIVPort(vnodewwn, vportwwn, vindex);
2N/A return (vportindex);
2N/A}
2N/A
2N/AHandleNPIVPort* HandlePort::getHandleNPIVPortByIndex(int index) {
2N/A Trace log("HandlePort::getHandleNPIVPortByIndex(int index)");
2N/A
2N/A HBANPIVPort* vport = port->getPortByIndex(index);
2N/A return (getHandleNPIVPort(vport->getPortWWN()));
2N/A}
2N/A
2N/AHandleNPIVPort* HandlePort::getHandleNPIVPort(uint64_t wwn) {
2N/A Trace log("HandlePort::getHandleNPIVPort");
2N/A lock();
2N/A try {
2N/A // Check to see if the wwn is in the map
2N/A if (npivportHandles.find(wwn) == npivportHandles.end()) {
2N/A // Not found, add a new one
2N/A HBANPIVPort* vport = port->getPort(wwn);
2N/A npivportHandles[wwn] = new HandleNPIVPort(handle, this, hba, port, vport);
2N/A }
2N/A HandleNPIVPort *npivportHandle = npivportHandles[wwn];
2N/A unlock();
2N/A return (npivportHandle);
2N/A } catch (...) {
2N/A unlock();
2N/A throw;
2N/A }
2N/A}
2N/A