902 lines
21 KiB
C
902 lines
21 KiB
C
//***************************************************************************
|
|
//
|
|
// 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);
|
|
}
|