windows-nt/Source/XPSP1/NT/base/wmi/fchba/testapp/hbatest.c
2020-09-26 16:20:57 +08:00

714 lines
16 KiB
C

#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include "hbaapi.h"
#define MAX_ADAPTERS 64
void CallMiscFunctions()
{
HBA_STATUS Status;
HBA_UINT32 Version;
Status = HBA_RegisterLibrary(NULL);
if (Status != HBA_STATUS_ERROR_NOT_SUPPORTED)
{
printf("HBA_RegisterLibrary -> %d\n", Status);
}
Version = HBA_GetVersion();
if (Version != HBA_VERSION)
{
printf("HBA_GetVersion -> %d\n", Version);
}
Status = HBA_LoadLibrary();
if (Status != HBA_STATUS_OK)
{
printf("HBA_LoadLibrary -> %d\n", Status);
}
Status = HBA_FreeLibrary();
if (Status != HBA_STATUS_OK)
{
printf("HBA_FreeLibrary -> %d\n", Status);
}
// TODO: These functions
#if 0
HBA_API HBA_STATUS 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);
HBA_API HBA_STATUS HBA_SendReportLUNs (
HBA_HANDLE handle,
HBA_WWN portWWN,
void * pRspBuffer,
HBA_UINT32 RspBufferSize,
void * pSenseBuffer,
HBA_UINT32 SenseBufferSize
);
HBA_API HBA_STATUS HBA_SendReadCapacity (
HBA_HANDLE handle,
HBA_WWN portWWN,
HBA_UINT64 fcLUN,
void * pRspBuffer,
HBA_UINT32 RspBufferSize,
void * pSenseBuffer,
HBA_UINT32 SenseBufferSize
);
#endif
}
HBA_STATUS BuildAdapterList(
PULONG AdapterCount,
TCHAR **Adapters
)
{
HBA_UINT32 Count, i;
PTCHAR Name;
HBA_STATUS Status;
Count = HBA_GetNumberOfAdapters();
if (Count > MAX_ADAPTERS)
{
printf("%d is above limit of %d adapters\n", Count, MAX_ADAPTERS);
Count = MAX_ADAPTERS;
}
*AdapterCount = Count;
Status = HBA_STATUS_OK;
for (i = 0; i < Count; i++)
{
Name = malloc(256 * sizeof(TCHAR));
Status = HBA_GetAdapterName(i, Name);
if (Status == HBA_STATUS_OK)
{
Adapters[i] = Name;
} else {
printf("HBA_GetAdapterName(%d) -> %d\n", i, Status);
break;
}
}
return(Status);
}
void PrintHBA_WWN(
PCHAR s,
HBA_WWN wwn
)
{
printf(s);
printf(" %02x %02x %02x %02x %02x %02x %02x %02x \n",
wwn.wwn[0], wwn.wwn[1], wwn.wwn[2], wwn.wwn[3],
wwn.wwn[4], wwn.wwn[5], wwn.wwn[6], wwn.wwn[7]);
}
void PrintHBA_UINT32(
PCHAR s,
HBA_UINT32 u
)
{
printf(s);
printf(": 0x%x\n", u);
}
#ifdef UNICODE
void Printchar(
PCHAR s,
PWCHAR w
)
{
printf(s);
printf(": %ws\n", w);
}
#else
void Printchar(
PCHAR s,
PCHAR w
)
{
printf(s);
printf(": %s\n", w);
}
#endif
HBA_STATUS GetAdapterAttributes(
HBA_HANDLE Handle,
HBA_UINT32 *PortCount
)
{
HBA_STATUS Status;
HBA_ADAPTERATTRIBUTES Attributes;
Status = HBA_GetAdapterAttributes(Handle,
&Attributes);
if (Status == HBA_STATUS_OK)
{
printf("\nAdapter Attributes:\n");
PrintHBA_WWN("NodeWWN", Attributes.NodeWWN);
PrintHBA_UINT32("VendorSpecificID", Attributes.VendorSpecificID);
PrintHBA_UINT32("NumberOfPorts", Attributes.NumberOfPorts);
*PortCount = Attributes.NumberOfPorts;
Printchar("Manufacturer", Attributes.Manufacturer);
Printchar("SerialNumber", Attributes.SerialNumber);
Printchar("Model", Attributes.Model);
Printchar("ModelDescription", Attributes.ModelDescription);
Printchar("NodeSymbolicName", Attributes.NodeSymbolicName);
Printchar("HardwareVersion", Attributes.HardwareVersion);
Printchar("DriverVersion", Attributes.DriverVersion);
Printchar("OptionROMVersion", Attributes.OptionROMVersion);
Printchar("FirmwareVersion", Attributes.FirmwareVersion);
Printchar("DriverName", Attributes.DriverName);
} else {
printf("HBA_GetAdapterAttributes -> %d\n", Status);
}
return(Status);
}
void PrintHBA_PORTTYPE(
PCHAR s,
HBA_PORTTYPE u
)
{
// TODO: symbolic constants
printf(s);
printf(": 0x%x\n", u);
}
void PrintHBA_PORTSPEED(
PCHAR s,
HBA_PORTSPEED u
)
{
// TODO: symbolic constants
printf(s);
printf(": 0x%x\n", u);
}
void PrintHBA_PORTSTATE(
PCHAR s,
HBA_PORTSTATE u
)
{
// TODO: symbolic constants
printf(s);
printf(": 0x%x\n", u);
}
void PrintHBA_COS(
PCHAR s,
HBA_COS u
)
{
// TODO: symbolic constants
printf(s);
printf(": 0x%x\n", u);
}
void PrintHBA_FC4TYPES(
PCHAR s,
HBA_FC4TYPES Fc4
)
{
ULONG i;
// TODO: symbolic constants
printf(s);
printf(":");
for (i = 0; i < 32; i++)
{
printf(" %02x", Fc4.bits[i]);
}
printf("\n");
}
void PrintHBA_UINT64(
PCHAR s,
HBA_UINT64 u
)
{
printf(s);
printf(": 0x%x\n", u);
}
void PrintHBA_INT64(
PCHAR s,
HBA_INT64 u
)
{
printf(s);
printf(": 0x%x\n", u);
}
void PrintHBA_UINT16(
PCHAR s,
HBA_UINT16 u
)
{
printf(s);
printf(": 0x%x\n", u);
}
void PrintHBA_UINT8A(
PCHAR s,
HBA_UINT8 *u,
ULONG Len
)
{
ULONG i;
printf(s);
printf(":");
for (i = 0; i < Len; i++)
{
printf(" 0x%x\n", u[i]);
}
printf("\n");
}
void PrintHBA_PORTATTRIBUTES(
PHBA_PORTATTRIBUTES Attributes
)
{
PrintHBA_WWN("NodeWWN", Attributes->NodeWWN);
PrintHBA_WWN("PortWWN", Attributes->PortWWN);
PrintHBA_UINT32("PortFcId", Attributes->PortFcId);
PrintHBA_PORTTYPE("PortType", Attributes->PortType);
PrintHBA_PORTSTATE("PortState", Attributes->PortState);
PrintHBA_COS("PortSupportedClassofService", Attributes->PortSupportedClassofService);
PrintHBA_FC4TYPES("PortSupportedFc4Types", Attributes->PortSupportedFc4Types);
PrintHBA_FC4TYPES("PortActiveFc4Types", Attributes->PortActiveFc4Types);
Printchar("PortSymbolicName", Attributes->PortSymbolicName);
Printchar("OSDeviceName", Attributes->OSDeviceName);
PrintHBA_PORTSPEED("PortSupportedSpeed", Attributes->PortSupportedSpeed);
PrintHBA_PORTSPEED("PortSpeed", Attributes->PortSpeed);
PrintHBA_UINT32("PortMaxFrameSize", Attributes->PortMaxFrameSize);
PrintHBA_WWN("FabricName", Attributes->FabricName);
PrintHBA_UINT32("NumberofDiscoveredPorts", Attributes->NumberofDiscoveredPorts);
}
HBA_STATUS GetPortInformation(
HBA_HANDLE Handle,
HBA_UINT32 PortIndex
)
{
HBA_STATUS Status;
HBA_PORTATTRIBUTES Attributes;
HBA_PORTSTATISTICS Statistics;
UINT i;
HBA_ResetStatistics(Handle, PortIndex);
Status = HBA_GetAdapterPortAttributes(Handle,
PortIndex,
&Attributes);
if (Status == HBA_STATUS_OK)
{
PrintHBA_PORTATTRIBUTES(&Attributes);
Status = HBA_GetPortStatistics(Handle,
PortIndex,
&Statistics);
if (Status == HBA_STATUS_OK)
{
PrintHBA_INT64("SecondsSinceLastReset", Statistics.SecondsSinceLastReset);
PrintHBA_INT64("TxFrames", Statistics.TxFrames);
PrintHBA_INT64("TxWords", Statistics.TxWords);
PrintHBA_INT64("RxFrames", Statistics.RxFrames);
PrintHBA_INT64("RxWords", Statistics.RxWords);
PrintHBA_INT64("LIPCount", Statistics.LIPCount);
PrintHBA_INT64("NOSCount", Statistics.NOSCount);
PrintHBA_INT64("ErrorFrames", Statistics.ErrorFrames);
PrintHBA_INT64("DumpedFrames", Statistics.DumpedFrames);
PrintHBA_INT64("LinkFailureCount", Statistics.LinkFailureCount);
PrintHBA_INT64("LossOfSyncCount", Statistics.LossOfSyncCount);
PrintHBA_INT64("LossOfSignalCount", Statistics.LossOfSignalCount);
PrintHBA_INT64("PrimitiveSeqProtocolErrCount", Statistics.PrimitiveSeqProtocolErrCount);
PrintHBA_INT64("InvalidTxWordCount", Statistics.InvalidTxWordCount);
PrintHBA_INT64("InvalidCRCCount", Statistics.InvalidCRCCount);
for (i = 0; i < 4; i++)
{
printf("\nDiscovered port %d\n", i);
Status = HBA_GetDiscoveredPortAttributes(Handle,
PortIndex,
i,
&Attributes);
if (Status == HBA_STATUS_OK)
{
HBA_WWN wwn = {0}; // TODO: make wwn meaningful
PrintHBA_PORTATTRIBUTES(&Attributes);
Status = HBA_GetPortAttributesByWWN(Handle,
wwn,
&Attributes);
if (Status == HBA_STATUS_OK)
{
PrintHBA_PORTATTRIBUTES(&Attributes);
} else {
printf("HBA_GetPortAttributesByWWN -> %d\n", Status);
}
} else {
printf("HBA_GetDiscoveredPortAttributes -> %d\n", Status);
}
}
} else {
printf("HBA_GetPortStatistics -> %d\n", Status);
}
} else {
printf("HBA_GetPortAttributes -> %d\n", Status);
}
return(Status);
}
HBA_STATUS GetSetMgmtInfo(
HBA_HANDLE Handle
)
{
HBA_MGMTINFO MgmtInfo;
HBA_STATUS Status;
Status = HBA_GetRNIDMgmtInfo(Handle,
&MgmtInfo);
if (Status == HBA_STATUS_OK)
{
PrintHBA_WWN("wwn", MgmtInfo.wwn);
PrintHBA_UINT32("unittype", MgmtInfo.unittype);
PrintHBA_UINT32("PortId", MgmtInfo.PortId);
PrintHBA_UINT32("NumberOfAttachedNodes", MgmtInfo.NumberOfAttachedNodes);
PrintHBA_UINT16("IPVersion", MgmtInfo.IPVersion);
PrintHBA_UINT16("UDPPort", MgmtInfo.UDPPort);
PrintHBA_UINT8A("IPAddress", MgmtInfo.IPAddress, 16);
PrintHBA_UINT16("reserved", MgmtInfo.reserved);
PrintHBA_UINT16("TopologyDiscoveryFlags", MgmtInfo.TopologyDiscoveryFlags);
Status = HBA_SetRNIDMgmtInfo(Handle,
&MgmtInfo);
if (Status != HBA_STATUS_OK)
{
printf("HBA_SetRNIDMgmtInfo -> %d\n", Status);
}
} else {
printf("HBA_GetRNIDMgmtInfo -> %d\n", Status);
}
return(Status);
}
UCHAR RspBuffer[0x1000];
UCHAR ReqBuffer[0x800];
HBA_STATUS SendPassThroughs(
HBA_HANDLE Handle
)
{
HBA_STATUS Status;
HBA_UINT32 RspBufferSize;
HBA_WWN wwn = {0};
HBA_WWNTYPE wwnType = 0;
memset(ReqBuffer, 0x80, sizeof(ReqBuffer));
Status = HBA_SendCTPassThru(Handle,
ReqBuffer,
sizeof(ReqBuffer),
RspBuffer,
sizeof(RspBuffer)/2);
if (Status != HBA_STATUS_OK)
{
printf("HBA_SendCTPassThru too small -> %d\n", Status);
}
memset(ReqBuffer, 0x81, sizeof(ReqBuffer));
Status = HBA_SendCTPassThru(Handle,
ReqBuffer,
sizeof(ReqBuffer),
RspBuffer,
sizeof(RspBuffer));
if (Status != HBA_STATUS_OK)
{
printf("HBA_SendCTPassThru -> %d\n", Status);
}
//
// Now do RNID
//
RspBufferSize = 0;
memset(ReqBuffer, 0x80, sizeof(ReqBuffer));
Status = HBA_SendRNID(Handle,
wwn,
wwnType,
RspBuffer,
&RspBufferSize);
if (Status != HBA_STATUS_OK)
{
printf("HBA_SendRNID too small -> %d\n", Status);
} else {
printf("HBA_SENDRNID too small RspBufferSize = %d\n", RspBufferSize);
}
memset(ReqBuffer, 0x81, sizeof(ReqBuffer));
RspBufferSize = 100;
Status = HBA_SendRNID(Handle,
wwn,
wwnType,
RspBuffer,
&RspBufferSize);
if (Status != HBA_STATUS_OK)
{
printf("HBA_SendRNID -> %d\n", Status);
} else {
printf("HBA_SENDRNID RspBufferSize = %d\n", RspBufferSize);
}
return(Status);
}
void PrintHBA_SCSIID(
PHBA_SCSIID ScsiId
)
{
Printchar("OSDeviceName", ScsiId->OSDeviceName);
PrintHBA_UINT32("ScsiBusNumber", ScsiId->ScsiBusNumber);
PrintHBA_UINT32("ScsiTargetNumber", ScsiId->ScsiTargetNumber);
PrintHBA_UINT32("ScsiOSLun", ScsiId->ScsiOSLun);
}
void PrintHBA_FCPID(
PHBA_FCPID FcpId
)
{
PrintHBA_UINT32("FcId", FcpId->FcId);
PrintHBA_WWN("NodeWWN", FcpId->NodeWWN);
PrintHBA_WWN("PortWWN", FcpId->PortWWN);
PrintHBA_UINT64("FcpLun", FcpId->FcpLun);
}
void PrintHBA_FCPSCSIENTRY(
PHBA_FCPSCSIENTRY entry
)
{
PrintHBA_SCSIID(&entry->ScsiId);
PrintHBA_FCPID(&entry->FcpId);
}
void PrintHBA_FCPBINDINGTYPE(
PCHAR s,
HBA_FCPBINDINGTYPE type
)
{
printf(s);
if (type == TO_D_ID)
{
printf(": TO_D_ID\n");
} else if (type == TO_WWN) {
printf(": TO_WWN\n");
} else {
printf(": ?? UNKNOWN ??\n");
}
}
void PrintHBA_FCPBINDINGENTRY(
PHBA_FCPBINDINGENTRY entry
)
{
PrintHBA_FCPBINDINGTYPE("type", entry->type);
PrintHBA_SCSIID(&entry->ScsiId);
PrintHBA_FCPID(&entry->FcpId);
}
HBA_STATUS GetMappings(
HBA_HANDLE Handle
)
{
HBA_FCPTARGETMAPPING FcpMappingStatic;
PHBA_FCPTARGETMAPPING FcpMapping;
HBA_FCPBINDING FcpBindingStatic;
PHBA_FCPBINDING FcpBinding;
ULONG i, SizeNeeded;
HBA_STATUS Status;
printf("FcpTargetMapping\n");
FcpMappingStatic.NumberOfEntries = 0;
Status = HBA_GetFcpTargetMapping(Handle,
&FcpMappingStatic);
if (Status == HBA_STATUS_ERROR_MORE_DATA)
{
SizeNeeded = (sizeof(HBA_FCPTARGETMAPPING) +
(FcpMappingStatic.NumberOfEntries * sizeof(HBA_FCPSCSIENTRY)));
FcpMapping = (PHBA_FCPTARGETMAPPING)malloc(SizeNeeded);
if (FcpMapping != NULL)
{
FcpMapping->NumberOfEntries = FcpMappingStatic.NumberOfEntries;
Status = HBA_GetFcpTargetMapping(Handle,
FcpMapping);
if (Status == HBA_STATUS_OK)
{
printf("Entries = %d\n", FcpMapping->NumberOfEntries);
for (i = 0; i < FcpMapping->NumberOfEntries; i++)
{
PrintHBA_FCPSCSIENTRY(&FcpMapping->entry[i]);
}
} else {
printf("HBA_GetFcpTargetMapping full -> %d\n", Status);
}
} else {
printf("Alloc for %d FCPMapping failed\n", SizeNeeded);
}
} else {
printf("HBA_GetFcpTargetMapping -> %d\n", Status);
}
printf("FcpBinding\n");
FcpBindingStatic.NumberOfEntries = 0;
Status = HBA_GetFcpPersistentBinding(Handle,
&FcpBindingStatic);
if (Status == HBA_STATUS_ERROR_MORE_DATA)
{
SizeNeeded = (sizeof(HBA_FCPBINDING) +
(FcpBindingStatic.NumberOfEntries * sizeof(HBA_FCPBINDINGENTRY)));
FcpBinding = (PHBA_FCPBINDING)malloc(SizeNeeded);
if (FcpBinding != NULL)
{
FcpBinding->NumberOfEntries = FcpBindingStatic.NumberOfEntries;
Status = HBA_GetFcpPersistentBinding(Handle,
FcpBinding);
if (Status == HBA_STATUS_OK)
{
printf("NumberOfEntries = %d\n", FcpBinding->NumberOfEntries);
for (i = 0; i < FcpBinding->NumberOfEntries; i++)
{
PrintHBA_FCPBINDINGENTRY(&FcpBinding->entry[i]);
}
} else {
printf("HBA_GetPersistentBinding full -> %d\n", Status);
}
} else {
printf("Alloc for %d FcpBinding failed\n", SizeNeeded);
}
} else {
printf("HBA_GetFcpPersistenBinding -> %d\n", Status);
}
return(Status);
}
HBA_STATUS GetAdapterInformation(
PTCHAR AdapterName
)
{
HBA_STATUS Status;
HBA_HANDLE Handle;
HBA_UINT32 i, PortCount;
Handle = HBA_OpenAdapter(AdapterName);
if (Handle != 0)
{
HBA_RefreshInformation(Handle);
Status = GetAdapterAttributes(Handle, &PortCount);
if (Status == HBA_STATUS_OK)
{
for (i = 0; i < PortCount; i++)
{
printf("Port %d\n", i);
Status = GetPortInformation(Handle, i);
if (Status != HBA_STATUS_OK)
{
printf("GetPortAttributes(%d) -> %d\n", i, Status);
}
}
Status = GetSetMgmtInfo(Handle);
if (Status != HBA_STATUS_OK)
{
printf("GetSetMgmtInfo -> %d\n", Status);
}
Status = SendPassThroughs(Handle);
if (Status != HBA_STATUS_OK)
{
printf("DoPassthroughs -> %d\n", Status);
}
Status = GetMappings(Handle);
if (Status != HBA_STATUS_OK)
{
printf("GetMappings -> %d\n", Status);
}
}
HBA_CloseAdapter(Handle);
} else {
#ifdef UNICODE
printf("HBA_OpenAdapter(%ws) Error\n", AdapterName);
#else
printf("HBA_OpenAdapter(%s) Error\n", AdapterName);
#endif
}
return(Status);
}
int _cdecl main(int argc, char *argv[])
{
TCHAR *Adapters[MAX_ADAPTERS];
ULONG AdapterCount;
HBA_STATUS Status;
ULONG i;
CallMiscFunctions();
Status = BuildAdapterList(&AdapterCount, Adapters);
if (Status == HBA_STATUS_OK)
{
printf("%d adapters discovered\n", AdapterCount);
for (i = 0; i < AdapterCount; i++)
{
#ifdef UNICODE
printf("Adapter: %ws\n", Adapters[i]);
#else
printf("Adapter: %s\n", Adapters[i]);
#endif
Status = GetAdapterInformation(Adapters[i]);
if (Status != HBA_STATUS_OK)
{
#ifdef UNICODE
printf("GetAdapterInformation(%ws) -> %d\n",
Adapters[i], Status);
#else
printf("GetAdapterInformation(%s) -> %d\n",
Adapters[i], Status);
#endif
}
}
}
return(0);
}