mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
493 lines
11 KiB
493 lines
11 KiB
//***************************************************************************
|
|
//
|
|
// getdata.c
|
|
//
|
|
// Module: Windows HBA API implmentation
|
|
//
|
|
// Purpose: Contains routines for getting and setting data
|
|
//
|
|
// Copyright (c) 2001 Microsoft Corporation
|
|
//
|
|
//***************************************************************************
|
|
|
|
#include "hbaapip.h"
|
|
|
|
HBA_STATUS HBA_GetAdapterAttributesX(
|
|
HBA_HANDLE HbaHandle,
|
|
HBA_ADAPTERATTRIBUTES *HbaAdapterAttributes,
|
|
BOOLEAN IsAnsi
|
|
)
|
|
{
|
|
HANDLE Handle;
|
|
PADAPTER_HANDLE HandleData;
|
|
ULONG Status;
|
|
HBA_STATUS HbaStatus = HBA_STATUS_ERROR;
|
|
PWNODE_SINGLE_INSTANCE Buffer;
|
|
PUCHAR Data;
|
|
ULONG DataLength;
|
|
PHBA_ADAPTERATTRIBUTES HbaAdapterAttributesA;
|
|
|
|
HandleData = GetDataByHandle(HbaHandle);
|
|
if (HandleData != NULL)
|
|
{
|
|
|
|
Status = WmiOpenBlock((LPGUID)&MSFC_FCAdapterHBAAttributes_GUID,
|
|
GENERIC_READ,
|
|
&Handle);
|
|
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
//
|
|
// Validate adapter name by querying for that adapter name as a
|
|
// WMI instance name
|
|
//
|
|
Status = QuerySingleInstance(Handle,
|
|
HandleData->InstanceName,
|
|
&Buffer);
|
|
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
Status = ParseSingleInstance(Buffer,
|
|
NULL,
|
|
&Data,
|
|
&DataLength);
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
//
|
|
// Skip over AdapterId as it is not needed for HBA
|
|
//
|
|
Data += sizeof(ULONGLONG);
|
|
|
|
//
|
|
// 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 = *(HBA_STATUS *)Data;
|
|
Data += sizeof(HBA_STATUS);
|
|
|
|
if (HbaStatus == HBA_STATUS_OK)
|
|
{
|
|
|
|
//
|
|
// We have got our adapter attributes, so copy them
|
|
// over to the output buffer
|
|
//
|
|
if (IsAnsi)
|
|
{
|
|
HbaAdapterAttributesA = HbaAdapterAttributes;
|
|
|
|
GetDataFromDataBlock(HbaAdapterAttributesA,
|
|
NodeWWN,
|
|
HBA_WWN,
|
|
Data);
|
|
|
|
GetDataFromDataBlock(HbaAdapterAttributesA,
|
|
VendorSpecificID,
|
|
HBA_UINT32,
|
|
Data);
|
|
|
|
GetDataFromDataBlock(HbaAdapterAttributesA,
|
|
NumberOfPorts,
|
|
HBA_UINT32,
|
|
Data);
|
|
|
|
CopyString(&HbaAdapterAttributesA->Manufacturer,
|
|
&Data,
|
|
64,
|
|
IsAnsi);
|
|
|
|
CopyString(&HbaAdapterAttributesA->SerialNumber,
|
|
&Data,
|
|
64,
|
|
IsAnsi);
|
|
|
|
CopyString(&HbaAdapterAttributesA->Model,
|
|
&Data,
|
|
256,
|
|
IsAnsi);
|
|
|
|
CopyString(&HbaAdapterAttributesA->ModelDescription,
|
|
&Data,
|
|
256,
|
|
IsAnsi);
|
|
|
|
CopyString(&HbaAdapterAttributesA->NodeSymbolicName,
|
|
&Data,
|
|
256,
|
|
IsAnsi);
|
|
|
|
CopyString(&HbaAdapterAttributesA->HardwareVersion,
|
|
&Data,
|
|
256,
|
|
IsAnsi);
|
|
|
|
CopyString(&HbaAdapterAttributesA->DriverVersion,
|
|
&Data,
|
|
256,
|
|
IsAnsi);
|
|
|
|
CopyString(&HbaAdapterAttributesA->OptionROMVersion,
|
|
&Data,
|
|
256,
|
|
IsAnsi);
|
|
|
|
CopyString(&HbaAdapterAttributesA->FirmwareVersion,
|
|
&Data,
|
|
256,
|
|
IsAnsi);
|
|
|
|
CopyString(&HbaAdapterAttributesA->DriverName,
|
|
&Data,
|
|
256,
|
|
IsAnsi);
|
|
|
|
} else {
|
|
GetDataFromDataBlock(HbaAdapterAttributes,
|
|
NodeWWN,
|
|
HBA_WWN,
|
|
Data);
|
|
|
|
GetDataFromDataBlock(HbaAdapterAttributes,
|
|
VendorSpecificID,
|
|
HBA_UINT32,
|
|
Data);
|
|
|
|
GetDataFromDataBlock(HbaAdapterAttributes,
|
|
NumberOfPorts,
|
|
HBA_UINT32,
|
|
Data);
|
|
|
|
CopyString(&HbaAdapterAttributes->Manufacturer,
|
|
&Data,
|
|
64,
|
|
IsAnsi);
|
|
|
|
CopyString(&HbaAdapterAttributes->SerialNumber,
|
|
&Data,
|
|
64,
|
|
IsAnsi);
|
|
|
|
CopyString(&HbaAdapterAttributes->Model,
|
|
&Data,
|
|
256,
|
|
IsAnsi);
|
|
|
|
CopyString(&HbaAdapterAttributes->ModelDescription,
|
|
&Data,
|
|
256,
|
|
IsAnsi);
|
|
|
|
CopyString(&HbaAdapterAttributes->NodeSymbolicName,
|
|
&Data,
|
|
256,
|
|
IsAnsi);
|
|
|
|
CopyString(&HbaAdapterAttributes->HardwareVersion,
|
|
&Data,
|
|
256,
|
|
IsAnsi);
|
|
|
|
CopyString(&HbaAdapterAttributes->DriverVersion,
|
|
&Data,
|
|
256,
|
|
IsAnsi);
|
|
|
|
CopyString(&HbaAdapterAttributes->OptionROMVersion,
|
|
&Data,
|
|
256,
|
|
IsAnsi);
|
|
|
|
CopyString(&HbaAdapterAttributes->FirmwareVersion,
|
|
&Data,
|
|
256,
|
|
IsAnsi);
|
|
|
|
CopyString(&HbaAdapterAttributes->DriverName,
|
|
&Data,
|
|
256,
|
|
IsAnsi);
|
|
}
|
|
}
|
|
}
|
|
|
|
FreeMemory(Buffer);
|
|
}
|
|
WmiCloseBlock(Handle);
|
|
}
|
|
} else {
|
|
HbaStatus = HBA_STATUS_ERROR_INVALID_HANDLE;
|
|
}
|
|
return(HbaStatus);
|
|
|
|
}
|
|
|
|
HBA_STATUS HBA_API HBA_GetAdapterAttributes(
|
|
HBA_HANDLE HbaHandle,
|
|
HBA_ADAPTERATTRIBUTES *HbaAdapterAttributes
|
|
)
|
|
{
|
|
return(HBA_GetAdapterAttributesX(HbaHandle,
|
|
HbaAdapterAttributes,
|
|
TRUE));
|
|
}
|
|
|
|
HBA_STATUS HBA_GetAdapterPortAttributesX(
|
|
HBA_HANDLE HbaHandle,
|
|
HBA_UINT32 PortIndex,
|
|
HBA_PORTATTRIBUTES *PortAttributes,
|
|
BOOLEAN IsAnsi
|
|
)
|
|
{
|
|
HANDLE Handle;
|
|
PADAPTER_HANDLE HandleData;
|
|
ULONG Status;
|
|
HBA_STATUS HbaStatus = HBA_STATUS_ERROR;
|
|
PWNODE_SINGLE_INSTANCE Buffer;
|
|
PUCHAR Data;
|
|
ULONG DataLength;
|
|
PWCHAR InstanceName;
|
|
|
|
HandleData = GetDataByHandle(HbaHandle);
|
|
if (HandleData != NULL)
|
|
{
|
|
|
|
Status = WmiOpenBlock((LPGUID)&MSFC_FibrePortHBAAttributes_GUID,
|
|
GENERIC_READ,
|
|
&Handle);
|
|
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
InstanceName = CreatePortInstanceNameW(HandleData->InstanceName,
|
|
PortIndex);
|
|
if (InstanceName != NULL)
|
|
{
|
|
Status = QuerySingleInstance(Handle,
|
|
InstanceName,
|
|
&Buffer);
|
|
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
Status = ParseSingleInstance(Buffer,
|
|
NULL,
|
|
&Data,
|
|
&DataLength);
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
|
|
//
|
|
// Skip over AdapterId as it is not needed for HBA
|
|
//
|
|
Data += sizeof(ULONGLONG);
|
|
|
|
//
|
|
// 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 = *(HBA_STATUS *)Data;
|
|
Data += sizeof(HBA_STATUS);
|
|
|
|
if (HbaStatus == HBA_STATUS_OK)
|
|
{
|
|
CopyPortAttributes(PortAttributes,
|
|
Data,
|
|
IsAnsi);
|
|
}
|
|
}
|
|
FreeMemory(Buffer);
|
|
}
|
|
FreeMemory(InstanceName);
|
|
}
|
|
WmiCloseBlock(Handle);
|
|
}
|
|
} else {
|
|
HbaStatus = HBA_STATUS_ERROR_INVALID_HANDLE;
|
|
}
|
|
return(HbaStatus);
|
|
|
|
}
|
|
|
|
HBA_STATUS HBA_API HBA_GetAdapterPortAttributes(
|
|
HBA_HANDLE HbaHandle,
|
|
HBA_UINT32 PortIndex,
|
|
HBA_PORTATTRIBUTES *PortAttributes
|
|
)
|
|
{
|
|
return(HBA_GetAdapterPortAttributesX(HbaHandle,
|
|
PortIndex,
|
|
PortAttributes,
|
|
TRUE));
|
|
}
|
|
|
|
|
|
|
|
HBA_STATUS HBA_API HBA_GetPortStatistics(
|
|
HBA_HANDLE HbaHandle,
|
|
HBA_UINT32 PortIndex,
|
|
HBA_PORTSTATISTICS *HbaPortStatistics
|
|
)
|
|
{
|
|
HANDLE Handle;
|
|
PADAPTER_HANDLE HandleData;
|
|
ULONG Status;
|
|
HBA_STATUS HbaStatus = HBA_STATUS_ERROR;
|
|
PUCHAR Data;
|
|
ULONG DataLength;
|
|
PWCHAR InstanceName;
|
|
PWNODE_SINGLE_INSTANCE Buffer;
|
|
|
|
HandleData = GetDataByHandle(HbaHandle);
|
|
if (HandleData != NULL)
|
|
{
|
|
|
|
Status = WmiOpenBlock((LPGUID)&MSFC_FibrePortHBAStatistics_GUID,
|
|
GENERIC_READ,
|
|
&Handle);
|
|
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
InstanceName = CreatePortInstanceNameW(HandleData->InstanceName,
|
|
PortIndex);
|
|
if (InstanceName != NULL)
|
|
{
|
|
Status = QuerySingleInstance(Handle,
|
|
InstanceName,
|
|
&Buffer);
|
|
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
Status = ParseSingleInstance(Buffer,
|
|
NULL,
|
|
&Data,
|
|
&DataLength);
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
|
|
//
|
|
// Skip over AdapterId as it is not needed for HBA
|
|
//
|
|
Data += sizeof(ULONGLONG);
|
|
|
|
//
|
|
// 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 = *(HBA_STATUS *)Data;
|
|
Data += sizeof(HBA_STATUS);
|
|
|
|
//
|
|
// Since the data block goes from ULONG to
|
|
// ULONGLONG, we need to account for 4 bytes of
|
|
// padding
|
|
//
|
|
Data += 4;
|
|
|
|
if (HbaStatus == HBA_STATUS_OK)
|
|
{
|
|
//
|
|
// We have got our port statistics, so copy them
|
|
// over to the output buffer
|
|
//
|
|
|
|
GetDataFromDataBlock(HbaPortStatistics,
|
|
SecondsSinceLastReset,
|
|
HBA_INT64,
|
|
Data);
|
|
|
|
GetDataFromDataBlock(HbaPortStatistics,
|
|
TxFrames,
|
|
HBA_INT64,
|
|
Data);
|
|
|
|
GetDataFromDataBlock(HbaPortStatistics,
|
|
TxWords,
|
|
HBA_INT64,
|
|
Data);
|
|
|
|
GetDataFromDataBlock(HbaPortStatistics,
|
|
RxFrames,
|
|
HBA_INT64,
|
|
Data);
|
|
|
|
GetDataFromDataBlock(HbaPortStatistics,
|
|
RxWords,
|
|
HBA_INT64,
|
|
Data);
|
|
|
|
GetDataFromDataBlock(HbaPortStatistics,
|
|
LIPCount,
|
|
HBA_INT64,
|
|
Data);
|
|
|
|
GetDataFromDataBlock(HbaPortStatistics,
|
|
NOSCount,
|
|
HBA_INT64,
|
|
Data);
|
|
|
|
GetDataFromDataBlock(HbaPortStatistics,
|
|
ErrorFrames,
|
|
HBA_INT64,
|
|
Data);
|
|
|
|
GetDataFromDataBlock(HbaPortStatistics,
|
|
DumpedFrames,
|
|
HBA_INT64,
|
|
Data);
|
|
|
|
GetDataFromDataBlock(HbaPortStatistics,
|
|
LinkFailureCount,
|
|
HBA_INT64,
|
|
Data);
|
|
|
|
GetDataFromDataBlock(HbaPortStatistics,
|
|
LossOfSyncCount,
|
|
HBA_INT64,
|
|
Data);
|
|
|
|
GetDataFromDataBlock(HbaPortStatistics,
|
|
LossOfSignalCount,
|
|
HBA_INT64,
|
|
Data);
|
|
|
|
GetDataFromDataBlock(HbaPortStatistics,
|
|
PrimitiveSeqProtocolErrCount,
|
|
HBA_INT64,
|
|
Data);
|
|
|
|
GetDataFromDataBlock(HbaPortStatistics,
|
|
InvalidTxWordCount,
|
|
HBA_INT64,
|
|
Data);
|
|
|
|
GetDataFromDataBlock(HbaPortStatistics,
|
|
InvalidCRCCount,
|
|
HBA_INT64,
|
|
Data);
|
|
}
|
|
}
|
|
|
|
FreeMemory(Buffer);
|
|
}
|
|
FreeMemory(InstanceName);
|
|
}
|
|
WmiCloseBlock(Handle);
|
|
}
|
|
} else {
|
|
HbaStatus = HBA_STATUS_ERROR_INVALID_HANDLE;
|
|
}
|
|
return(HbaStatus);
|
|
|
|
}
|
|
|
|
|