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)
windows环境之下如何添加NVMe VSC 命令_第1张图片
windows环境之下如何添加NVMe VSC 命令_第2张图片

你可能感兴趣的:(SSD)