NVMe Sef-Test Windows 10

  • Thread starter Thread starter Ashok_ai
  • Start date Start date
A

Ashok_ai

Guest
I am trying to develop self test for NVMe drives on Windows 10 OS using IOCTL's. However, DeviceIoControl() method returned 0 and GetLastError() method showed error code as 87 on RS2 (and 317 error code on RS3). I tested the code on NVMe 1.3 version drives (WDC PC SN720 SDAPNTW-512G-1006 and others) "Drive self Test" bit is enabled in Idenitfy structure.


Can some one suggest what could be wrong with the following code. And also I would like to know if RS3 OS supports NVMe self Test implementation.


BOOL NVMeTest::NVMeSelfTest(std::string driveHandleStr)
{
BOOL result;
PVOID buffer = NULL;
ULONG bufferLength = 0;
ULONG returnedLength = 0;

PSTORAGE_PROPERTY_QUERY query = NULL;
PSTORAGE_PROTOCOL_SPECIFIC_DATA protocolData = NULL;
PSTORAGE_PROTOCOL_DATA_DESCRIPTOR protocolDataDescr = NULL;

HANDLE hPhyDrive = CreateFile(LPCSTR(driveHandleStr.c_str()),
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);

if (hPhyDrive == INVALID_HANDLE_VALUE)
{
//printf("Invalid handle!");
return FALSE;
}
//
// Allocate buffer for use.
//
ULONG testlength = FIELD_OFFSET(STORAGE_PROTOCOL_COMMAND, Command);
bufferLength = FIELD_OFFSET(STORAGE_PROTOCOL_COMMAND, Command) + STORAGE_PROTOCOL_COMMAND_LENGTH_NVME +
4096 + sizeof(NVME_ERROR_INFO_LOG);
buffer = malloc(bufferLength);
ZeroMemory(buffer, bufferLength);
if (buffer == NULL) {
//printf("DeviceNVMeQueryProtocolDataTest: allocate buffer failed, exit.\n");
return FALSE;
}

PSTORAGE_PROTOCOL_COMMAND protocolCommand = (PSTORAGE_PROTOCOL_COMMAND)buffer;

protocolCommand->Version = STORAGE_PROTOCOL_STRUCTURE_VERSION;
protocolCommand->Length = sizeof(STORAGE_PROTOCOL_COMMAND);
protocolCommand->ProtocolType = ProtocolTypeNvme;
protocolCommand->Flags = STORAGE_PROTOCOL_COMMAND_FLAG_ADAPTER_REQUEST;
protocolCommand->CommandLength = STORAGE_PROTOCOL_COMMAND_LENGTH_NVME;
protocolCommand->ErrorInfoLength = sizeof(NVME_ERROR_INFO_LOG);
// protocolCommand->DataFromDeviceTransferLength = 4096;
protocolCommand->DataToDeviceTransferLength = 4096; // 4096;
protocolCommand->TimeOutValue = 180;
protocolCommand->ErrorInfoOffset = FIELD_OFFSET(STORAGE_PROTOCOL_COMMAND, Command) + STORAGE_PROTOCOL_COMMAND_LENGTH_NVME;
// protocolCommand->DataFromDeviceBufferOffset = protocolCommand->ErrorInfoOffset + protocolCommand->ErrorInfoLength;
protocolCommand->DataToDeviceBufferOffset = protocolCommand->ErrorInfoOffset + protocolCommand->ErrorInfoLength;
protocolCommand->CommandSpecific = STORAGE_PROTOCOL_SPECIFIC_NVME_ADMIN_COMMAND;

PNVME_COMMAND command = (PNVME_COMMAND)protocolCommand->Command;

command->CDW0.OPC = 0x14;
//command->NSID = 0x01;
command->u.GENERAL.CDW10 = 0x01;

//
// Send request down.
//
result = DeviceIoControl(hPhyDrive,
IOCTL_STORAGE_PROTOCOL_COMMAND,
buffer,
bufferLength,
buffer,
bufferLength,
&returnedLength,
NULL
);
if (result == 0)
{
printf("Error occurred %d\n", GetLastError()); // Returns 87 for RS2 OS and 317 for RS3 OS
free(buffer);
return FALSE;
}

return TRUE;
}

Continue reading...
 
Back
Top