\r
Status = NvmeControllerInit (Private);\r
\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ }\r
+\r
gBS->RestoreTPL (OldTpl);\r
\r
return Status;\r
\r
return Status;\r
}\r
+\r
+/**\r
+ Trust transfer data from/to NVMe device.\r
+\r
+ This function performs one NVMe transaction to do a trust transfer from/to NVMe device.\r
+\r
+ @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure.\r
+ @param Buffer The pointer to the current transaction buffer.\r
+ @param SecurityProtocolId The value of the "Security Protocol" parameter of\r
+ the security protocol command to be sent.\r
+ @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter\r
+ of the security protocol command to be sent.\r
+ @param TransferLength The block number or sector count of the transfer.\r
+ @param IsTrustSend Indicates whether it is a trust send operation or not.\r
+ @param Timeout The timeout, in 100ns units, to use for the execution\r
+ of the security protocol command. A Timeout value of 0\r
+ means that this function will wait indefinitely for the\r
+ security protocol command to execute. If Timeout is greater\r
+ than zero, then this function will return EFI_TIMEOUT\r
+ if the time required to execute the receive data command\r
+ is greater than Timeout.\r
+ @param TransferLengthOut A pointer to a buffer to store the size in bytes of the data\r
+ written to the buffer. Ignore it when IsTrustSend is TRUE.\r
+\r
+ @retval EFI_SUCCESS The data transfer is complete successfully.\r
+ @return others Some error occurs when transferring data.\r
+\r
+**/\r
+EFI_STATUS\r
+TrustTransferNvmeDevice (\r
+ IN OUT NVME_CONTROLLER_PRIVATE_DATA *Private,\r
+ IN OUT VOID *Buffer,\r
+ IN UINT8 SecurityProtocolId,\r
+ IN UINT16 SecurityProtocolSpecificData,\r
+ IN UINTN TransferLength,\r
+ IN BOOLEAN IsTrustSend,\r
+ IN UINT64 Timeout,\r
+ OUT UINTN *TransferLengthOut\r
+ )\r
+{\r
+ EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket;\r
+ EFI_NVM_EXPRESS_COMMAND Command;\r
+ EFI_NVM_EXPRESS_COMPLETION Completion;\r
+ EFI_STATUS Status;\r
+ UINT16 SpecificData;\r
+\r
+ ZeroMem (&CommandPacket, sizeof (EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));\r
+ ZeroMem (&Command, sizeof (EFI_NVM_EXPRESS_COMMAND));\r
+ ZeroMem (&Completion, sizeof (EFI_NVM_EXPRESS_COMPLETION));\r
+\r
+ CommandPacket.NvmeCmd = &Command;\r
+ CommandPacket.NvmeCompletion = &Completion;\r
+\r
+ // \r
+ // Change Endianness of SecurityProtocolSpecificData\r
+ //\r
+ SpecificData = (((SecurityProtocolSpecificData << 8) & 0xFF00) | (SecurityProtocolSpecificData >> 8));\r
+\r
+ if (IsTrustSend) {\r
+ Command.Cdw0.Opcode = NVME_ADMIN_SECURITY_SEND_CMD;\r
+ CommandPacket.TransferBuffer = Buffer;\r
+ CommandPacket.TransferLength = (UINT32)TransferLength;\r
+ CommandPacket.NvmeCmd->Cdw10 = (UINT32)((SecurityProtocolId << 24) | (SpecificData << 8));\r
+ CommandPacket.NvmeCmd->Cdw11 = (UINT32)TransferLength;\r
+ } else {\r
+ Command.Cdw0.Opcode = NVME_ADMIN_SECURITY_RECEIVE_CMD;\r
+ CommandPacket.TransferBuffer = Buffer;\r
+ CommandPacket.TransferLength = (UINT32)TransferLength;\r
+ CommandPacket.NvmeCmd->Cdw10 = (UINT32)((SecurityProtocolId << 24) | (SpecificData << 8));\r
+ CommandPacket.NvmeCmd->Cdw11 = (UINT32)TransferLength;\r
+ }\r
+\r
+ CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID;\r
+ CommandPacket.NvmeCmd->Nsid = NVME_CONTROLLER_ID;\r
+ CommandPacket.CommandTimeout = Timeout;\r
+ CommandPacket.QueueType = NVME_ADMIN_QUEUE;\r
+\r
+ Status = Private->Passthru.PassThru (\r
+ &Private->Passthru,\r
+ NVME_CONTROLLER_ID,\r
+ &CommandPacket,\r
+ NULL\r
+ );\r
+\r
+ if (!IsTrustSend) {\r
+ if (EFI_ERROR (Status)) {\r
+ *TransferLengthOut = 0;\r
+ } else {\r
+ *TransferLengthOut = (UINTN) TransferLength;\r
+ }\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Send a security protocol command to a device that receives data and/or the result\r
+ of one or more commands sent by SendData.\r
+\r
+ The ReceiveData function sends a security protocol command to the given MediaId.\r
+ The security protocol command sent is defined by SecurityProtocolId and contains\r
+ the security protocol specific data SecurityProtocolSpecificData. The function\r
+ returns the data from the security protocol command in PayloadBuffer.\r
+\r
+ For devices supporting the SCSI command set, the security protocol command is sent\r
+ using the SECURITY PROTOCOL IN command defined in SPC-4.\r
+\r
+ For devices supporting the ATA command set, the security protocol command is sent\r
+ using one of the TRUSTED RECEIVE commands defined in ATA8-ACS if PayloadBufferSize\r
+ is non-zero.\r
+\r
+ If the PayloadBufferSize is zero, the security protocol command is sent using the\r
+ Trusted Non-Data command defined in ATA8-ACS.\r
+\r
+ If PayloadBufferSize is too small to store the available data from the security\r
+ protocol command, the function shall copy PayloadBufferSize bytes into the\r
+ PayloadBuffer and return EFI_WARN_BUFFER_TOO_SMALL.\r
+\r
+ If PayloadBuffer or PayloadTransferSize is NULL and PayloadBufferSize is non-zero,\r
+ the function shall return EFI_INVALID_PARAMETER.\r
+\r
+ If the given MediaId does not support security protocol commands, the function shall\r
+ return EFI_UNSUPPORTED. If there is no media in the device, the function returns\r
+ EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the device,\r
+ the function returns EFI_MEDIA_CHANGED.\r
+\r
+ If the security protocol fails to complete within the Timeout period, the function\r
+ shall return EFI_TIMEOUT.\r
+\r
+ If the security protocol command completes without an error, the function shall\r
+ return EFI_SUCCESS. If the security protocol command completes with an error, the\r
+ function shall return EFI_DEVICE_ERROR.\r
+\r
+ @param This Indicates a pointer to the calling context.\r
+ @param MediaId ID of the medium to receive data from.\r
+ @param Timeout The timeout, in 100ns units, to use for the execution\r
+ of the security protocol command. A Timeout value of 0\r
+ means that this function will wait indefinitely for the\r
+ security protocol command to execute. If Timeout is greater\r
+ than zero, then this function will return EFI_TIMEOUT\r
+ if the time required to execute the receive data command\r
+ is greater than Timeout.\r
+ @param SecurityProtocolId The value of the "Security Protocol" parameter of\r
+ the security protocol command to be sent.\r
+ @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter\r
+ of the security protocol command to be sent.\r
+ @param PayloadBufferSize Size in bytes of the payload data buffer.\r
+ @param PayloadBuffer A pointer to a destination buffer to store the security\r
+ protocol command specific payload data for the security\r
+ protocol command. The caller is responsible for having\r
+ either implicit or explicit ownership of the buffer.\r
+ @param PayloadTransferSize A pointer to a buffer to store the size in bytes of the\r
+ data written to the payload data buffer.\r
+\r
+ @retval EFI_SUCCESS The security protocol command completed successfully.\r
+ @retval EFI_WARN_BUFFER_TOO_SMALL The PayloadBufferSize was too small to store the available\r
+ data from the device. The PayloadBuffer contains the truncated data.\r
+ @retval EFI_UNSUPPORTED The given MediaId does not support security protocol commands.\r
+ @retval EFI_DEVICE_ERROR The security protocol command completed with an error.\r
+ @retval EFI_NO_MEDIA There is no media in the device.\r
+ @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.\r
+ @retval EFI_INVALID_PARAMETER The PayloadBuffer or PayloadTransferSize is NULL and\r
+ PayloadBufferSize is non-zero.\r
+ @retval EFI_TIMEOUT A timeout occurred while waiting for the security\r
+ protocol command to execute.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+NvmeStorageSecurityReceiveData (\r
+ IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This,\r
+ IN UINT32 MediaId,\r
+ IN UINT64 Timeout,\r
+ IN UINT8 SecurityProtocolId,\r
+ IN UINT16 SecurityProtocolSpecificData,\r
+ IN UINTN PayloadBufferSize,\r
+ OUT VOID *PayloadBuffer,\r
+ OUT UINTN *PayloadTransferSize\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ NVME_DEVICE_PRIVATE_DATA *Device;\r
+ \r
+ Status = EFI_SUCCESS;\r
+\r
+ if ((PayloadBuffer == NULL) || (PayloadTransferSize == NULL) || (PayloadBufferSize == 0)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Device = NVME_DEVICE_PRIVATE_DATA_FROM_STORAGE_SECURITY (This);\r
+\r
+ if (MediaId != Device->BlockIo.Media->MediaId) {\r
+ return EFI_MEDIA_CHANGED;\r
+ }\r
+\r
+ if (!Device->BlockIo.Media->MediaPresent) {\r
+ return EFI_NO_MEDIA;\r
+ }\r
+\r
+ Status = TrustTransferNvmeDevice (\r
+ Device->Controller,\r
+ PayloadBuffer,\r
+ SecurityProtocolId,\r
+ SecurityProtocolSpecificData,\r
+ PayloadBufferSize,\r
+ FALSE,\r
+ Timeout,\r
+ PayloadTransferSize\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Send a security protocol command to a device.\r
+\r
+ The SendData function sends a security protocol command containing the payload\r
+ PayloadBuffer to the given MediaId. The security protocol command sent is\r
+ defined by SecurityProtocolId and contains the security protocol specific data\r
+ SecurityProtocolSpecificData. If the underlying protocol command requires a\r
+ specific padding for the command payload, the SendData function shall add padding\r
+ bytes to the command payload to satisfy the padding requirements.\r
+\r
+ For devices supporting the SCSI command set, the security protocol command is sent\r
+ using the SECURITY PROTOCOL OUT command defined in SPC-4.\r
+\r
+ For devices supporting the ATA command set, the security protocol command is sent\r
+ using one of the TRUSTED SEND commands defined in ATA8-ACS if PayloadBufferSize\r
+ is non-zero. If the PayloadBufferSize is zero, the security protocol command is\r
+ sent using the Trusted Non-Data command defined in ATA8-ACS.\r
+\r
+ If PayloadBuffer is NULL and PayloadBufferSize is non-zero, the function shall\r
+ return EFI_INVALID_PARAMETER.\r
+\r
+ If the given MediaId does not support security protocol commands, the function\r
+ shall return EFI_UNSUPPORTED. If there is no media in the device, the function\r
+ returns EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the\r
+ device, the function returns EFI_MEDIA_CHANGED.\r
+\r
+ If the security protocol fails to complete within the Timeout period, the function\r
+ shall return EFI_TIMEOUT.\r
+\r
+ If the security protocol command completes without an error, the function shall return\r
+ EFI_SUCCESS. If the security protocol command completes with an error, the function\r
+ shall return EFI_DEVICE_ERROR.\r
+\r
+ @param This Indicates a pointer to the calling context.\r
+ @param MediaId ID of the medium to receive data from.\r
+ @param Timeout The timeout, in 100ns units, to use for the execution\r
+ of the security protocol command. A Timeout value of 0\r
+ means that this function will wait indefinitely for the\r
+ security protocol command to execute. If Timeout is greater\r
+ than zero, then this function will return EFI_TIMEOUT\r
+ if the time required to execute the send data command\r
+ is greater than Timeout.\r
+ @param SecurityProtocolId The value of the "Security Protocol" parameter of\r
+ the security protocol command to be sent.\r
+ @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter\r
+ of the security protocol command to be sent.\r
+ @param PayloadBufferSize Size in bytes of the payload data buffer.\r
+ @param PayloadBuffer A pointer to a destination buffer to store the security\r
+ protocol command specific payload data for the security\r
+ protocol command.\r
+\r
+ @retval EFI_SUCCESS The security protocol command completed successfully.\r
+ @retval EFI_UNSUPPORTED The given MediaId does not support security protocol commands.\r
+ @retval EFI_DEVICE_ERROR The security protocol command completed with an error.\r
+ @retval EFI_NO_MEDIA There is no media in the device.\r
+ @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.\r
+ @retval EFI_INVALID_PARAMETER The PayloadBuffer is NULL and PayloadBufferSize is non-zero.\r
+ @retval EFI_TIMEOUT A timeout occurred while waiting for the security\r
+ protocol command to execute.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+NvmeStorageSecuritySendData (\r
+ IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This,\r
+ IN UINT32 MediaId,\r
+ IN UINT64 Timeout,\r
+ IN UINT8 SecurityProtocolId,\r
+ IN UINT16 SecurityProtocolSpecificData,\r
+ IN UINTN PayloadBufferSize,\r
+ IN VOID *PayloadBuffer\r
+ )\r
+{\r
+ EFI_STATUS Status; \r
+ NVME_DEVICE_PRIVATE_DATA *Device;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ if ((PayloadBuffer == NULL) && (PayloadBufferSize != 0)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Device = NVME_DEVICE_PRIVATE_DATA_FROM_STORAGE_SECURITY (This);\r
+\r
+ if (MediaId != Device->BlockIo.Media->MediaId) {\r
+ return EFI_MEDIA_CHANGED;\r
+ }\r
+\r
+ if (!Device->BlockIo.Media->MediaPresent) {\r
+ return EFI_NO_MEDIA;\r
+ }\r
+\r
+ Status = TrustTransferNvmeDevice (\r
+ Device->Controller,\r
+ PayloadBuffer,\r
+ SecurityProtocolId,\r
+ SecurityProtocolSpecificData,\r
+ PayloadBufferSize,\r
+ TRUE,\r
+ Timeout,\r
+ NULL\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+\r
+\r