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 2009 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 "Trace.h"
2N/A#include "Exceptions.h"
2N/A#include "sun_fc.h"
2N/A
2N/A
2N/A
2N/A#include <string.h>
2N/A#include "Handle.h"
2N/A#include "HBA.h"
2N/A#include "HBAPort.h"
2N/Ainline HBA_WWN
2N/AgetAdapterPortWWN(HBA_HANDLE handle,HBA_UINT32 index) {
2N/A HBA_WWN hba_wwn;
2N/A memset(hba_wwn.wwn, 0, sizeof (hba_wwn));
2N/A try {
2N/A Handle *myHandle = Handle::findHandle(handle);
2N/A HBA *hba = myHandle->getHBA();
2N/A HBAPort *port = hba->getPortByIndex(index);
2N/A uint64_t tmp = htonll(port->getPortWWN());
2N/A memcpy(hba_wwn.wwn, &tmp, sizeof (hba_wwn));
2N/A } catch (...) { }
2N/A return (hba_wwn);
2N/A}
2N/A
2N/A#ifdef __cplusplus
2N/Aextern "C" {
2N/A#endif
2N/A
2N/A/**
2N/A * @memo Retrieves the mapping between FCP targets and OS
2N/A * SCSI information
2N/A * @return HBA_STATUS_OK if the mapping structure contains valid
2N/A * mapping data.
2N/A * @param handle The HBA to fetch mappings for
2N/A * @param mapping The user-allocated mapping structure
2N/A *
2N/A * @doc This routine will call the V2 interface and convert
2N/A * the results to the old data structure. It will
2N/A * call the V2 interface for all ports on the HBA.
2N/A */
2N/AHBA_STATUS
2N/ASun_fcGetFcpTargetMapping(HBA_HANDLE handle, PHBA_FCPTARGETMAPPING mapping) {
2N/A HBA_STATUS status;
2N/A int count;
2N/A PHBA_FCPTARGETMAPPINGV2 mappingV2;
2N/A HBA_ADAPTERATTRIBUTES attributes;
2N/A HBA_UINT32 entries = 0;
2N/A HBA_UINT32 current = 0;
2N/A HBA_UINT32 port;
2N/A HBA_UINT32 limit;
2N/A
2N/A Trace log("Sun_fcGetFcpTargetMapping");
2N/A
2N/A if (mapping == NULL) {
2N/A log.userError("NULL mapping argument.");
2N/A return (HBA_STATUS_ERROR_ARG);
2N/A }
2N/A
2N/A entries = mapping->NumberOfEntries;
2N/A
2N/A /* get adapter attributes for number of ports */
2N/A status = Sun_fcGetAdapterAttributes(handle,&attributes);
2N/A if (status != HBA_STATUS_OK) {
2N/A log.userError("Unable to get adapter attributes");
2N/A return HBA_STATUS_ERROR;
2N/A }
2N/A
2N/A mappingV2 = (PHBA_FCPTARGETMAPPINGV2) new uchar_t[
2N/A (sizeof (HBA_FCPSCSIENTRYV2)*(mapping->NumberOfEntries-1)) +
2N/A sizeof (HBA_FCPTARGETMAPPINGV2)];
2N/A mapping->NumberOfEntries = 0;
2N/A
2N/A for(port = 0; port < attributes.NumberOfPorts; port++) {
2N/A mappingV2->NumberOfEntries = mapping->NumberOfEntries < entries ?
2N/A entries - mapping->NumberOfEntries : 0 ;
2N/A status = Sun_fcGetFcpTargetMappingV2(handle,
2N/A getAdapterPortWWN(handle,port), mappingV2);
2N/A mapping->NumberOfEntries += mappingV2->NumberOfEntries;
2N/A
2N/A if (status != HBA_STATUS_OK && status != HBA_STATUS_ERROR_MORE_DATA) {
2N/A log.userError("Unable to get mappings for port");
2N/A return status;
2N/A }
2N/A /*
2N/A * need to copy from PHBA_FCPTARGETMAPPINGV2 to
2N/A * PHBA_FCPTARGETMAPPING
2N/A */
2N/A limit = (mapping->NumberOfEntries < entries) ? mapping->NumberOfEntries : entries;
2N/A for (count = current; count < limit; count++) {
2N/A memcpy(&mapping->entry[count].ScsiId,
2N/A &mappingV2->entry[count-current].ScsiId,
2N/A sizeof (mapping->entry[count].ScsiId));
2N/A memcpy(&mapping->entry[count].FcpId,
2N/A &mappingV2->entry[count-current].FcpId,
2N/A sizeof (mapping->entry[count].FcpId));
2N/A }
2N/A current = mapping->NumberOfEntries;
2N/A }
2N/A
2N/A delete(mappingV2);
2N/A return (status);
2N/A}
2N/A#ifdef __cplusplus
2N/A}
2N/A#endif