Hi Daisy,
Thank you for your help!
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
I try to send vendor-specific cmd 0xD0 for NVMe passthrough. I have read this document in great detail, however, I can not seem to get the pass-through mechanism to work against NVMe SSD.
I have also verified, that the device is able to send the Command Effects Log with the 0xD0 and 0xD1 commands under Linux environment.
However, when i try to send a Vendor Specific Admin command with any command code from 0xD0 ~ 0xD1 i get the error 1117 (ERROR_IO_DEVICE)
Here is the code i use to send a Vendor Specific Admin command:
BOOL result;
PVOID buffer = NULL;
ULONG bufferLength = 0;
ULONG returnedLength = 0;
ULONG imageBufferLength;
PSTORAGE_PROTOCOL_COMMAND protocolCommand = NULL;
PNVME_COMMAND command = NULL;
//
// Allocate buffer for use.
//
bufferLength = FIELD_OFFSET(STORAGE_PROTOCOL_COMMAND, Command) +
STORAGE_PROTOCOL_COMMAND_LENGTH_NVME + 4096 + sizeof(NVME_ERROR_INFO_LOG);
//bufferLength += imageBufferLength;
_tprintf(_T("\t buffer bufferSize: %d\n"), bufferLength);
buffer = (PVOID)malloc(bufferLength);
if (buffer == NULL) {
_tprintf(_T("allocate buffer failed, error code:%d exit.\n"), GetLastError());
return GetLastError();
}
// Initialize query data structure to get Identify Controller Data.
//
ZeroMemory(buffer, bufferLength);
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->TimeOutValue = 10;
protocolCommand->ErrorInfoOffset = FIELD_OFFSET(STORAGE_PROTOCOL_COMMAND, Command) + STORAGE_PROTOCOL_COMMAND_LENGTH_NVME;
protocolCommand->DataFromDeviceBufferOffset = protocolCommand->ErrorInfoOffset + protocolCommand->ErrorInfoLength;
protocolCommand->CommandSpecific = STORAGE_PROTOCOL_SPECIFIC_NVME_ADMIN_COMMAND;
command = (PNVME_COMMAND)protocolCommand->Command;
command->CDW0.OPC = 0xD0;
command->u.GENERAL.CDW10 = 0;
command->u.GENERAL.CDW12 = 8;
command->u.GENERAL.CDW13 = 0;
command->u.GENERAL.CDW15 = 0;
//
// Send request down.
//
result = DeviceIoControl(hDevice,
IOCTL_STORAGE_PROTOCOL_COMMAND,
buffer,
bufferLength,
buffer,
bufferLength,
&returnedLength,
NULL
);
if (result == FALSE) {
_tprintf(_T("\t IOCTL - Send request failed. %d.\n"), GetLastError());
goto Exit;
}
if (protocolCommand->ReturnStatus != STORAGE_PROTOCOL_STATUS_SUCCESS) {
_tprintf(_T("\t - protocolCommand failed. ReturnCode %d.\n"), protocolCommand->ReturnStatus);
goto Exit;
}
Exit:
if (fileHandle != NULL) {
CloseHandle(fileHandle);
}
if (buffer != NULL) {
free(buffer);
}
return 0;
Please let me know what am i doing wrong since i need to get this to work with our device under windows.
Any help is greatly appreciated!
Hi Daisy,
Thank you for your help!