//*************************************************************************** // // hbatest.c // // Module: Windows HBA API implmentation test application // // Purpose: Contains routines for getting and setting data // // Copyright (c) 2001 Microsoft Corporation // // This is provided for informational purposes only. Do not // redistribute. // //*************************************************************************** #include #include #include #include #include #include #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); }