1. 程式人生 > >windows環境之下如何新增NVMe VSC 命令

windows環境之下如何新增NVMe VSC 命令

work with NVMe driver
Vendor Specific Command
筆者剛開始使用pass through傳送VSC的命令總是不能成功,最後發現是這個問題。
windows Inbox Driver 的pass through 機制要求如果要支援VSCcommand, 那麼必須要有Command Support and Effects log,這個log裡面填寫所有主控晶片支援的命令。因此在設定一個新的命令之前需要在主控中實現Command Support and Effects log。
1. 首先在Identify裡面需要將Log Page Attributes (LPA)的bit 1 置為1以告訴Host,我們支援Command Support and Effects log, 主機上電後會先發送Identify command,主機會解析收到的回覆內容
2.後面主機會發行get log page command 來取走Command Support and Effects log.
3.主機解析完所有的Command Support and Effects log,就知道了你的主控晶片支援的命令列表,不在此列表中的命令使用pass through的時候都會被driver擋掉,DeviceIoControl函式的返回值為1(INVALID FUNCTION)
4. 在這之後你就可以愉快地傳送命令了
5. DeviceIOControl函式的用法

    PVOID   buffer = NULL;
    ULONG   bufferLength = 0;
    ULONG   returnedLength = 0;
    PSTORAGE_PROTOCOL_COMMAND protocolCommand = NULL;
    bufferLength = FIELD_OFFSET(STORAGE_PROTOCOL_COMMAND, Command) +
        STORAGE_PROTOCOL_COMMAND_LENGTH_NVME +
        sizeof(NVME_ERROR_INFO_LOG) + 4096
; buffer = malloc(bufferLength); 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 = 0xFF; command->u.GENERAL.CDW10 = 0xto_fill_in; command->u.GENERAL.CDW12 = 0xto_fill_in; command->u.GENERAL.CDW13 = 0xto_fill_in; // // Send request down. // result = DeviceIoControl(DeviceList[DeviceIndex].Handle, IOCTL_STORAGE_PROTOCOL_COMMAND, buffer, bufferLength, buffer, bufferLength, &returnedLength, NULL );

至於Command Support and Effects log裡面的結構體怎麼填寫請自己看 NVMe Express。
參考:https://technet.microsoft.com/zh-cn/mt718131(v=vs.80)
這裡寫圖片描述
log裡面的填寫順序和結構體