//***************************************************************************
//
//  method.c
// 
//  Module: Windows HBA API implmentation
//
//  Purpose: Contains routines for doing things
//
//  Copyright (c) 2001 Microsoft Corporation
//
//***************************************************************************

#include "hbaapip.h"

HBA_STATUS HBA_GetDiscoveredPortAttributesX(
	HBA_HANDLE HbaHandle,
	HBA_UINT32 PortIndex,
	HBA_UINT32 DiscoveredPortIndex,
	HBA_PORTATTRIBUTES *HbaPortAttributes,
    BOOLEAN IsAnsi
)
{
	HANDLE Handle;
	PADAPTER_HANDLE HandleData;
	ULONG Status;
	HBA_STATUS HbaStatus = HBA_STATUS_ERROR;
	PUCHAR Buffer;
	ULONG DataLength;
	GetDiscoveredPortAttributes_IN InData;
	PGetDiscoveredPortAttributes_OUT OutData;

	HandleData = GetDataByHandle(HbaHandle);
	if (HandleData != NULL)
	{

		Status = WmiOpenBlock((LPGUID)&MSFC_HBAPortMethods_GUID,
							  GENERIC_READ | GENERIC_EXECUTE,
							  &Handle);

		if (Status == ERROR_SUCCESS)
		{
			DataLength = sizeof(GetDiscoveredPortAttributes_OUT);
			Buffer = AllocMemory(DataLength);
			if (Buffer != NULL)
			{
				InData.PortIndex = PortIndex;
				InData.DiscoveredPortIndex = DiscoveredPortIndex;
				OutData = (PGetDiscoveredPortAttributes_OUT)Buffer;

				Status = WmiExecuteMethodW(Handle,
										  HandleData->InstanceName,
										  GetDiscoveredPortAttributes,
										  sizeof(GetDiscoveredPortAttributes_IN),
										  &InData,
										  &DataLength,
                                          OutData);
				
				if (Status == ERROR_SUCCESS)
				{
					//
					// Copy port attribs from buffer into 
					//

					//
					// Get the HBA status returned from the miniport.
					// If the status is HBA_STATUS_OK then the miniport
					// has successfully completed the operation and has
					// returned results to us. If the status is not
					// HBA_STATUS_OK then the miniport is returning an
					// HBA api error which we will in turn return to
					// the caller. In this case the additional results
					// are not valid.
					//
					HbaStatus = OutData->HBAStatus;

					if (HbaStatus == HBA_STATUS_OK)
					{
						CopyPortAttributes(HbaPortAttributes,
										   (PUCHAR)&OutData->PortAttributes,
										  IsAnsi);
					}
				}
				
				FreeMemory(Buffer);
			}
			WmiCloseBlock(Handle);
		}
	}
	
    return(HbaStatus);		
}


HBA_STATUS HBA_API HBA_GetDiscoveredPortAttributes(
	HBA_HANDLE HbaHandle,
	HBA_UINT32 PortIndex,
	HBA_UINT32 DiscoveredPortIndex,
	HBA_PORTATTRIBUTES *HbaPortAttribute
)
{
	return(HBA_GetDiscoveredPortAttributesX(HbaHandle,
										   PortIndex,
										   DiscoveredPortIndex,
										   HbaPortAttribute,
										   TRUE));
}




HBA_STATUS HBA_GetPortAttributesByWWNX(
	HBA_HANDLE HbaHandle,
	HBA_WWN PortWWN,
	HBA_PORTATTRIBUTES *HbaPortAttributes,
    BOOLEAN IsAnsi
)
{
	HANDLE Handle;
	PADAPTER_HANDLE HandleData;
	ULONG Status;
	HBA_STATUS HbaStatus = HBA_STATUS_ERROR;
	PUCHAR Buffer;
	ULONG DataLength;
	PGetPortAttributesByWWN_IN InData;
	PGetPortAttributesByWWN_OUT OutData;

	HandleData = GetDataByHandle(HbaHandle);
	if (HandleData != NULL)
	{

		Status = WmiOpenBlock((LPGUID)&MSFC_HBAPortMethods_GUID,
							  GENERIC_READ | GENERIC_EXECUTE,
							  &Handle);

		if (Status == ERROR_SUCCESS)
		{
			DataLength = sizeof(GetPortAttributesByWWN_OUT);
			Buffer = (PUCHAR)AllocMemory(DataLength);
			if (Buffer != NULL)
			{
				InData = (PGetPortAttributesByWWN_IN)&PortWWN;
				OutData = (PGetPortAttributesByWWN_OUT)Buffer;

				Status = WmiExecuteMethodW(Handle,
										  HandleData->InstanceName,
										  GetPortAttributesByWWN,
										  sizeof(GetPortAttributesByWWN_IN),
										  InData,
										  &DataLength,
                                          OutData);
				
				if (Status == ERROR_SUCCESS)
				{
					//
					// Copy port attribs from buffer into 
					//
					
					//
					// Get the HBA status returned from the miniport.
					// If the status is HBA_STATUS_OK then the miniport
					// has successfully completed the operation and has
					// returned results to us. If the status is not
					// HBA_STATUS_OK then the miniport is returning an
					// HBA api error which we will in turn return to
					// the caller. In this case the additional results
					// are not valid.
					//
					HbaStatus = OutData->HBAStatus;

					if (HbaStatus == HBA_STATUS_OK)
					{
						CopyPortAttributes(HbaPortAttributes,
										   (PUCHAR)&OutData->PortAttributes,
										   IsAnsi);
					}
				}
				
				FreeMemory(Buffer);
			}
			WmiCloseBlock(Handle);
		}
	}
	
    return(HbaStatus);		
}

HBA_STATUS HBA_API HBA_GetPortAttributesByWWN(
	HBA_HANDLE HbaHandle,
	HBA_WWN PortWWN,
	HBA_PORTATTRIBUTES *HbaPortAttributes
)
{
	return(HBA_GetPortAttributesByWWNX(HbaHandle,
									  PortWWN,
									  HbaPortAttributes,
									  TRUE));
									  
}


HBA_STATUS HBA_API HBA_SendCTPassThru(
	HBA_HANDLE HbaHandle,
	void * pReqBuffer,
	HBA_UINT32 ReqBufferSize,
	void * pRspBuffer,
	HBA_UINT32 RspBufferSize
)
{
	HANDLE Handle;
	PADAPTER_HANDLE HandleData;
	ULONG Status;
	HBA_STATUS HbaStatus = HBA_STATUS_ERROR;
	PUCHAR Buffer;
	ULONG DataLength, InDataLength, OutDataLength;
	PSendCTPassThru_OUT OutData;
	PSendCTPassThru_IN InData;

	HandleData = GetDataByHandle(HbaHandle);
	if (HandleData != NULL)
	{

		Status = WmiOpenBlock((LPGUID)&MSFC_HBAFc3MgmtMethods_GUID,
							  GENERIC_READ | GENERIC_EXECUTE,
							  &Handle);

		if (Status == ERROR_SUCCESS)
		{
			if (ReqBufferSize > RspBufferSize)
			{
				DataLength = ReqBufferSize;
			} else {
				DataLength = RspBufferSize;
			}

			DataLength += sizeof(SendCTPassThru_OUT);
			Buffer = AllocMemory(DataLength);
			if (Buffer != NULL)
			{
				InData = (PSendCTPassThru_IN)Buffer;
				OutData = (PSendCTPassThru_OUT)Buffer;

				InDataLength = sizeof(SendCTPassThru_IN) + ReqBufferSize - 1;
				InData->RequestBufferCount = ReqBufferSize;
				memcpy(InData->RequestBuffer,
					   pReqBuffer,
					   ReqBufferSize);

				OutDataLength = sizeof(SendCTPassThru_OUT) + RspBufferSize - 1;
				Status = WmiExecuteMethodW(Handle,
										  HandleData->InstanceName,
										  SendCTPassThru,
										  InDataLength,
										  InData,
										  &OutDataLength,
                                          OutData);
				
				if (Status == ERROR_SUCCESS)
				{
					if (OutData->ResponseBufferCount <= RspBufferSize)
					{
						RspBufferSize = OutData->ResponseBufferCount;
					} else {
						DebugPrint(("HBAAPI: Response size from SendCTPass is %d and is larger than %d\n",
								  OutData->ResponseBufferCount,
								  RspBufferSize));
					}
					
					//
					// Get the HBA status returned from the miniport.
					// If the status is HBA_STATUS_OK then the miniport
					// has successfully completed the operation and has
					// returned results to us. If the status is not
					// HBA_STATUS_OK then the miniport is returning an
					// HBA api error which we will in turn return to
					// the caller. In this case the additional results
					// are not valid.
					//
					HbaStatus = OutData->HBAStatus;

					if ((HbaStatus == HBA_STATUS_OK) ||
                        (HbaStatus == HBA_STATUS_ERROR_MORE_DATA))
					{
						memcpy(pRspBuffer,
							   OutData->ResponseBuffer,
							   RspBufferSize);
					}
				}
				
				FreeMemory(Buffer);
			}
			WmiCloseBlock(Handle);
		}
	}
	
    return(HbaStatus);	
}


HBA_STATUS HBA_API HBA_SendRNID(
	HBA_HANDLE HbaHandle,
	HBA_WWN wwn,
	HBA_WWNTYPE wwntype,
	void * pRspBuffer,
	HBA_UINT32 *RspBufferSize
)
{
	HANDLE Handle;
	PADAPTER_HANDLE HandleData;
	ULONG Status;
	HBA_STATUS HbaStatus = HBA_STATUS_ERROR;
	PUCHAR Buffer;
	ULONG DataLength;
	SendRNID_IN InData;
	PSendRNID_OUT OutData;

	HandleData = GetDataByHandle(HbaHandle);
	if (HandleData != NULL)
	{

		Status = WmiOpenBlock((LPGUID)&MSFC_HBAFc3MgmtMethods_GUID,
							  GENERIC_READ | GENERIC_EXECUTE,
							  &Handle);

		if (Status == ERROR_SUCCESS)
		{
			DataLength = sizeof(SendRNID_OUT) -1 + *RspBufferSize;
			Buffer = AllocMemory(DataLength);
			if (Buffer != NULL)
			{
				memcpy(InData.wwn,
					   &wwn.wwn,
					   sizeof(HBA_WWN));
				InData.wwntype = (ULONG)wwntype;
				OutData = (PSendRNID_OUT)Buffer;

				Status = WmiExecuteMethodW(Handle,
										  HandleData->InstanceName,
										  SendRNID,
										  sizeof(SendRNID_IN),
										  &InData,
										  &DataLength,
                                          OutData);
				
				if (Status == ERROR_SUCCESS)
				{
					//
					// Get the HBA status returned from the miniport.
					// If the status is HBA_STATUS_OK then the miniport
					// has successfully completed the operation and has
					// returned results to us. If the status is not
					// HBA_STATUS_OK then the miniport is returning an
					// HBA api error which we will in turn return to
					// the caller. In this case the additional results
					// are not valid.
					//
					HbaStatus = OutData->HBAStatus;

					if ((HbaStatus == HBA_STATUS_OK) ||
						(HbaStatus == HBA_STATUS_ERROR_MORE_DATA))
					{
						if (OutData->ResponseBufferCount <= *RspBufferSize)
						{
							*RspBufferSize = OutData->ResponseBufferCount;
						} else {
							DebugPrint(("HBAAPI: Response size from SendRNID is %d and is larger than %d\n",
									  OutData->ResponseBufferCount,
									  *RspBufferSize));
						}

						memcpy(pRspBuffer,
							   OutData->ResponseBuffer,
							   *RspBufferSize);
					}
				}
				
				FreeMemory(Buffer);
			}
			WmiCloseBlock(Handle);
		}
	}
	
    return(HbaStatus);		
}

_inline void CopyScsiId(
    PHBA_SCSIID HbaScsiId,
    PHBAScsiID WmiScsiId,
    BOOLEAN IsAnsi
    )
{
	PUCHAR p;

	p = (PUCHAR)WmiScsiId->OSDeviceName;
	CopyString(HbaScsiId->OSDeviceName,
				&p,
				256,
				IsAnsi);
					
	HbaScsiId->ScsiBusNumber = WmiScsiId->ScsiBusNumber;
	HbaScsiId->ScsiTargetNumber = WmiScsiId->ScsiTargetNumber;
	HbaScsiId->ScsiOSLun = WmiScsiId->ScsiOSLun;
	
}

_inline void CopyFcpId(
    PHBA_FCPID HbaFcpId,
    PHBAFCPID WmiFcpId
    )
{
	HbaFcpId->FcId = WmiFcpId->Fcid;
	HbaFcpId->FcpLun = WmiFcpId->FcpLun;
	memcpy(&HbaFcpId->NodeWWN,
		   &WmiFcpId->NodeWWN,
		   sizeof(HBA_WWN));
	memcpy(&HbaFcpId->PortWWN,
		   &WmiFcpId->PortWWN,
		   sizeof(HBA_WWN));	
}

HBA_STATUS HBA_GetFcpTargetMappingX (
    HBA_HANDLE HbaHandle,
    PHBA_FCPTARGETMAPPING Mapping,
    BOOLEAN IsAnsi
)
{
	HANDLE Handle;
	PADAPTER_HANDLE HandleData;
	ULONG Status;
	HBA_STATUS HbaStatus = HBA_STATUS_ERROR;
	ULONG DataLength;
	PGetFcpTargetMapping_OUT OutData;
	ULONG MapCount, ActualCount, i;
	PHBA_FCPSCSIENTRY MapEntry;
	PHBAFCPScsiEntry OutEntry;

	HandleData = GetDataByHandle(HbaHandle);
	if (HandleData != NULL)
	{

		Status = WmiOpenBlock((LPGUID)&(MSFC_HBAFCPInfo_GUID),
							  GENERIC_READ | GENERIC_EXECUTE,
							  &Handle);

		if (Status == ERROR_SUCCESS)
		{
			Status = ExecuteMethod(Handle,
								   HandleData->InstanceName,
								   GetFcpTargetMapping,
								   0,
								   NULL,
								   &DataLength,
								   (PUCHAR *)&OutData);
			
			if (Status == ERROR_SUCCESS)
			{
				//
				// Get the HBA status returned from the miniport.
				// If the status is HBA_STATUS_OK then the miniport
				// has successfully completed the operation and has
				// returned results to us. If the status is not
				// HBA_STATUS_OK then the miniport is returning an
				// HBA api error which we will in turn return to
				// the caller. In this case the additional results
				// are not valid.
				//
				HbaStatus = OutData->HBAStatus;

				if (HbaStatus == HBA_STATUS_OK)
				{

					MapCount = Mapping->NumberOfEntries;
					ActualCount = OutData->EntryCount;

					Mapping->NumberOfEntries = ActualCount;

					if (MapCount > ActualCount)
					{
						MapCount = ActualCount;
						HbaStatus = HBA_STATUS_ERROR_MORE_DATA;
					}

					for (i = 0; i < MapCount; i++)
					{
						MapEntry = &Mapping->entry[i];
						OutEntry = &OutData->Entry[i];

						CopyScsiId(&MapEntry->ScsiId,
								   &OutEntry->ScsiId,
								   IsAnsi);

						CopyFcpId(&MapEntry->FcpId,
								  &OutEntry->FCPId);

					}
				}
				
				FreeMemory(OutData);
			}
			WmiCloseBlock(Handle);
		}
	}
	
    return(HbaStatus);		
}

HBA_STATUS HBA_API HBA_GetFcpTargetMapping (
    HBA_HANDLE HbaHandle,
    PHBA_FCPTARGETMAPPING Mapping
)
{
	return(HBA_GetFcpTargetMappingX(HbaHandle,
									Mapping,
									TRUE));
}


HBA_STATUS HBA_GetFcpPersistentBindingX (
    HBA_HANDLE HbaHandle,
    PHBA_FCPBINDING binding,
    BOOLEAN IsAnsi
)
{
	HANDLE Handle;
	PADAPTER_HANDLE HandleData;
	ULONG Status;
	HBA_STATUS HbaStatus = HBA_STATUS_ERROR;
	ULONG DataLength;
	PGetFcpPersistentBinding_OUT OutData;
	ULONG MapCount, ActualCount, i;
	PHBA_FCPBINDINGENTRY MapEntry;
	PHBAFCPBindingEntry OutEntry;

	HandleData = GetDataByHandle(HbaHandle);
	if (HandleData != NULL)
	{

		Status = WmiOpenBlock((LPGUID)&MSFC_HBAFCPInfo_GUID,
							  GENERIC_READ | GENERIC_EXECUTE,
							  &Handle);

		if (Status == ERROR_SUCCESS)
		{
			Status = ExecuteMethod(Handle,
								   HandleData->InstanceName,
								   GetFcpTargetMapping,
								   0,
								   NULL,
								   &DataLength,
								   (PUCHAR *)&OutData);
			
			if (Status == ERROR_SUCCESS)
			{
				//
				// Get the HBA status returned from the miniport.
				// If the status is HBA_STATUS_OK then the miniport
				// has successfully completed the operation and has
				// returned results to us. If the status is not
				// HBA_STATUS_OK then the miniport is returning an
				// HBA api error which we will in turn return to
				// the caller. In this case the additional results
				// are not valid.
				//
				HbaStatus = OutData->HBAStatus;

				if (HbaStatus == HBA_STATUS_OK)
				{				
					MapCount = binding->NumberOfEntries;
					ActualCount = OutData->EntryCount;

					binding->NumberOfEntries = ActualCount;

					if (MapCount > ActualCount)
					{
						MapCount = ActualCount;
						HbaStatus = HBA_STATUS_ERROR_MORE_DATA;
					}

					for (i = 0; i < MapCount; i++)
					{
						MapEntry = &binding->entry[i];
						OutEntry = &OutData->Entry[i];

						MapEntry->type = OutEntry->Type;

						CopyScsiId(&MapEntry->ScsiId,
								   &OutEntry->ScsiId,
								   IsAnsi);

						CopyFcpId(&MapEntry->FcpId,
								  &OutEntry->FCPId);

					}
				}
				
				FreeMemory(OutData);
			}
			WmiCloseBlock(Handle);
		}
	}
	
    return(HbaStatus);		
}

HBA_STATUS HBA_API HBA_GetFcpPersistentBinding (
    HBA_HANDLE handle,
    PHBA_FCPBINDING binding
)
{
	return(HBA_GetFcpPersistentBindingX(handle,
										binding,
										TRUE));
}

void HBA_API HBA_ResetStatistics(
    HBA_HANDLE HbaHandle,
	HBA_UINT32 PortIndex
    )
{
	HANDLE Handle;
	PADAPTER_HANDLE HandleData;
	ULONG Status;
	PWCHAR InstanceName;
	ULONG DataLength;

	HandleData = GetDataByHandle(HbaHandle);
	if (HandleData != NULL)
	{

		Status = WmiOpenBlock((LPGUID)&MSFC_FibrePortHBAMethods_GUID,
							  GENERIC_READ | GENERIC_EXECUTE,
							  &Handle);

		if (Status == ERROR_SUCCESS)
		{
			InstanceName = CreatePortInstanceNameW(HandleData->InstanceName,
				                                  PortIndex);
			if (InstanceName != NULL)
			{
				DataLength = 0;
				Status = WmiExecuteMethodW(Handle,
										  InstanceName,
										  ResetStatistics,
										  0,
										  NULL,
										  &DataLength,
                                          NULL);
#if DBG
				if (Status != ERROR_SUCCESS)
				{
					DebugPrint(("HBAAPI: ResetStatistics method failed %d\n",
								Status));
				}
#endif
								
				FreeMemory(InstanceName);
			}
			WmiCloseBlock(Handle);
		}
	}	
}

HBA_STATUS HBA_API HBA_SetRNIDMgmtInfo(
	HBA_HANDLE HbaHandle,
	HBA_MGMTINFO *HbaMgmtInfo
    )
{
	HANDLE Handle;
	PADAPTER_HANDLE HandleData;
	ULONG Status;
	HBA_STATUS HbaStatus = HBA_STATUS_ERROR;
	ULONG DataLength;
	SetFC3MgmtInfo_IN InData;
	SetFC3MgmtInfo_OUT OutData;

	HandleData = GetDataByHandle(HbaHandle);
	if (HandleData != NULL)
	{

		Status = WmiOpenBlock((LPGUID)&MSFC_HBAFc3MgmtMethods_GUID,
							  GENERIC_EXECUTE,
							  &Handle);

		if (Status == ERROR_SUCCESS)
		{

			//
			// We have got our Management info, so copy them
			// over to the input buffer
			//
			memcpy(InData.MgmtInfo.wwn,
				   &HbaMgmtInfo->wwn,
				   sizeof(HBA_WWN));
			InData.MgmtInfo.unittype = HbaMgmtInfo->unittype;
			InData.MgmtInfo.PortId = HbaMgmtInfo->PortId;
			InData.MgmtInfo.NumberOfAttachedNodes = HbaMgmtInfo->NumberOfAttachedNodes;
			InData.MgmtInfo.IPVersion = HbaMgmtInfo->IPVersion;
			InData.MgmtInfo.UDPPort = HbaMgmtInfo->UDPPort;
			memcpy(InData.MgmtInfo.IPAddress,
				   HbaMgmtInfo->IPAddress,
				   16);
			InData.MgmtInfo.reserved = HbaMgmtInfo->reserved;
			InData.MgmtInfo.TopologyDiscoveryFlags = HbaMgmtInfo->TopologyDiscoveryFlags;
			
			DataLength = sizeof(SetFC3MgmtInfo_OUT);
			Status = WmiExecuteMethodW(Handle,
									  HandleData->InstanceName,
									  SetFC3MgmtInfo,
									  sizeof(SetFC3MgmtInfo_IN),
									  &InData,
									  &DataLength,
									  &OutData);

			if (Status == ERROR_SUCCESS)
			{
				//
				// Get the HBA status returned from the miniport.
				// If the miniport returns HBA_STATUS_OK then all
				// data is filled in the data block. If any other
				// HBA status is returned then the miniport is
				// reporting an error and we want to return that
				// HBA error code to the caller
				//
				HbaStatus = OutData.HBAStatus;
			}
			WmiCloseBlock(Handle);
		}
	} else {
		HbaStatus = HBA_STATUS_ERROR_INVALID_HANDLE;
	}
	return(HbaStatus);
}

HBA_STATUS HBA_API HBA_GetRNIDMgmtInfo(
	HBA_HANDLE HbaHandle,
	HBA_MGMTINFO *HbaMgmtInfo
    )
{
	HANDLE Handle;
	PADAPTER_HANDLE HandleData;
	ULONG Status;
	HBA_STATUS HbaStatus = HBA_STATUS_ERROR;
	ULONG DataLength;
	GetFC3MgmtInfo_OUT OutData;

	HandleData = GetDataByHandle(HbaHandle);
	if (HandleData != NULL)
	{

		Status = WmiOpenBlock((LPGUID)&MSFC_HBAFc3MgmtMethods_GUID,
							  GENERIC_EXECUTE,
							  &Handle);

		if (Status == ERROR_SUCCESS)
		{
			DataLength = sizeof(GetFC3MgmtInfo_OUT);
			Status = WmiExecuteMethodW(Handle,
									  HandleData->InstanceName,
									  GetFC3MgmtInfo,
									  0,
									  NULL,
									  &DataLength,
									  &OutData);

			if (Status == ERROR_SUCCESS)
			{
				//
				// Get the HBA status returned from the miniport.
				// If the miniport returns HBA_STATUS_OK then all
				// data is filled in the data block. If any other
				// HBA status is returned then the miniport is
				// reporting an error and we want to return that
				// HBA error code to the caller
				//
				HbaStatus = OutData.HBAStatus;
				
				if (HbaStatus == HBA_STATUS_OK)
				{

					//
					// We have got our Management info, so copy them
					// over to the output buffer
					//
					memcpy(&HbaMgmtInfo->wwn,
						   OutData.MgmtInfo.wwn,
						   sizeof(HBA_WWN));
					HbaMgmtInfo->unittype = OutData.MgmtInfo.unittype;
					HbaMgmtInfo->PortId = OutData.MgmtInfo.PortId;
					HbaMgmtInfo->NumberOfAttachedNodes = OutData.MgmtInfo.NumberOfAttachedNodes;
					HbaMgmtInfo->IPVersion = OutData.MgmtInfo.IPVersion;
				    HbaMgmtInfo->UDPPort = OutData.MgmtInfo.UDPPort;
				    memcpy(HbaMgmtInfo->IPAddress,
						   OutData.MgmtInfo.IPAddress,
						   16);
				    HbaMgmtInfo->reserved = OutData.MgmtInfo.reserved;
					HbaMgmtInfo->TopologyDiscoveryFlags = OutData.MgmtInfo.TopologyDiscoveryFlags;
				}
					
			}
			WmiCloseBlock(Handle);
		}
	} else {
		HbaStatus = HBA_STATUS_ERROR_INVALID_HANDLE;
	}
	return(HbaStatus);
}


void HBA_API HBA_RefreshInformation(
    HBA_HANDLE HbaHandle
	)
{
	HANDLE Handle;
	PADAPTER_HANDLE HandleData;
	ULONG Status;
	ULONG DataLength;

	HandleData = GetDataByHandle(HbaHandle);
	if (HandleData != NULL)
	{

		Status = WmiOpenBlock((LPGUID)&MSFC_HBAPortMethods_GUID,
							  GENERIC_READ | GENERIC_EXECUTE,
							  &Handle);

		if (Status == ERROR_SUCCESS)
		{
			DataLength = 0;
			Status = WmiExecuteMethodW(Handle,
									   HandleData->InstanceName,
									   RefreshInformation,
									   0,
									   NULL,
									   &DataLength,
									   NULL);
#if DBG
			if (Status != ERROR_SUCCESS)
			{
				DebugPrint(("HBAAPI: RefreshInformation method failed %d\n",
							Status));
			}
#endif
			WmiCloseBlock(Handle);
		}
	}		
}


//
// Not implemented yet
//
HBA_STATUS HBA_API HBA_GetEventBuffer(
	HBA_HANDLE handle,
	PHBA_EVENTINFO EventBuffer,
	HBA_UINT32 *EventCount
    )
{
	return(HBA_STATUS_ERROR_NOT_SUPPORTED);
}


//
// SCSI apis are not supported by design
//
HBA_STATUS HBA_API HBA_SendScsiInquiry (
	HBA_HANDLE handle,
	HBA_WWN PortWWN,
	HBA_UINT64 fcLUN,
	HBA_UINT8 EVPD,
	HBA_UINT32 PageCode,
	void * pRspBuffer,
	HBA_UINT32 RspBufferSize,
	void * pSenseBuffer,
	HBA_UINT32 SenseBufferSize)
{
	return(HBA_STATUS_ERROR_NOT_SUPPORTED);
}

HBA_STATUS HBA_API HBA_SendReportLUNs (
	HBA_HANDLE handle,
	HBA_WWN portWWN,
	void * pRspBuffer,
	HBA_UINT32 RspBufferSize,
	void * pSenseBuffer,
	HBA_UINT32 SenseBufferSize
)
{
	return(HBA_STATUS_ERROR_NOT_SUPPORTED);
}

HBA_STATUS HBA_API HBA_SendReadCapacity (
	HBA_HANDLE handle,
	HBA_WWN portWWN,
	HBA_UINT64 fcLUN,
	void * pRspBuffer,
	HBA_UINT32 RspBufferSize,
	void * pSenseBuffer,
	HBA_UINT32 SenseBufferSize
)
{
	return(HBA_STATUS_ERROR_NOT_SUPPORTED);
}