+ gBS->RestoreTPL (OldTpl);\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Reads a specified number of bytes from a device.\r
+\r
+ @param This Indicates a pointer to the calling context.\r
+ @param MediaId ID of the medium to be read.\r
+ @param Offset The starting byte offset on the logical block I/O device to read from.\r
+ @param Token A pointer to the token associated with the transaction.\r
+ If this field is NULL, synchronous/blocking IO is performed.\r
+ @param BufferSize The size in bytes of Buffer. The number of bytes to read from the device.\r
+ @param Buffer A pointer to the destination buffer for the data.\r
+ The caller is responsible either having implicit or explicit ownership of the buffer.\r
+\r
+ @retval EFI_SUCCESS If Event is NULL (blocking I/O): The data was read correctly from the device.\r
+ If Event is not NULL (asynchronous I/O): The request was successfully queued for processing.\r
+ Event will be signaled upon completion.\r
+ @retval EFI_DEVICE_ERROR The device reported an error while performing the write.\r
+ @retval EFI_NO_MEDIA There is no medium in the device.\r
+ @retval EFI_MEDIA_CHNAGED The MediaId is not for the current medium.\r
+ @retval EFI_INVALID_PARAMETER The read request contains device addresses that are not valid for the device.\r
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DiskIo2ReadDiskEx (\r
+ IN EFI_DISK_IO2_PROTOCOL *This,\r
+ IN UINT32 MediaId,\r
+ IN UINT64 Offset,\r
+ IN OUT EFI_DISK_IO2_TOKEN *Token,\r
+ IN UINTN BufferSize,\r
+ OUT VOID *Buffer\r
+ )\r
+{\r
+ return DiskIo2ReadWriteDisk (\r
+ DISK_IO_PRIVATE_DATA_FROM_DISK_IO2 (This),\r
+ FALSE, MediaId, Offset, Token, BufferSize, (UINT8 *) Buffer\r
+ );\r
+}\r
+\r
+/**\r
+ Writes a specified number of bytes to a device.\r
+\r
+ @param This Indicates a pointer to the calling context.\r
+ @param MediaId ID of the medium to be written.\r
+ @param Offset The starting byte offset on the logical block I/O device to write to.\r
+ @param Token A pointer to the token associated with the transaction.\r
+ If this field is NULL, synchronous/blocking IO is performed.\r
+ @param BufferSize The size in bytes of Buffer. The number of bytes to write to the device.\r
+ @param Buffer A pointer to the buffer containing the data to be written.\r
+\r
+ @retval EFI_SUCCESS If Event is NULL (blocking I/O): The data was written correctly to the device.\r
+ If Event is not NULL (asynchronous I/O): The request was successfully queued for processing.\r
+ Event will be signaled upon completion.\r
+ @retval EFI_WRITE_PROTECTED The device cannot be written to.\r
+ @retval EFI_DEVICE_ERROR The device reported an error while performing the write operation.\r
+ @retval EFI_NO_MEDIA There is no medium in the device.\r
+ @retval EFI_MEDIA_CHNAGED The MediaId is not for the current medium.\r
+ @retval EFI_INVALID_PARAMETER The write request contains device addresses that are not valid for the device.\r
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DiskIo2WriteDiskEx (\r
+ IN EFI_DISK_IO2_PROTOCOL *This,\r
+ IN UINT32 MediaId,\r
+ IN UINT64 Offset,\r
+ IN OUT EFI_DISK_IO2_TOKEN *Token,\r
+ IN UINTN BufferSize,\r
+ IN VOID *Buffer\r
+ )\r
+{\r
+ return DiskIo2ReadWriteDisk (\r
+ DISK_IO_PRIVATE_DATA_FROM_DISK_IO2 (This),\r
+ TRUE, MediaId, Offset, Token, BufferSize, (UINT8 *) Buffer\r
+ );\r
+}\r
+\r
+/**\r
+ The callback for the BlockIo2 FlushBlocksEx.\r
+ @param Event Event whose notification function is being invoked.\r
+ @param Context The pointer to the notification function's context,\r
+ which points to the DISK_IO2_FLUSH_TASK instance.\r
+**/\r
+VOID\r
+EFIAPI\r
+DiskIo2OnFlushComplete (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ DISK_IO2_FLUSH_TASK *Task;\r
+\r
+ gBS->CloseEvent (Event);\r
+\r
+ Task = (DISK_IO2_FLUSH_TASK *) Context;\r
+ ASSERT (Task->Signature == DISK_IO2_FLUSH_TASK_SIGNATURE);\r
+ Task->Token->TransactionStatus = Task->BlockIo2Token.TransactionStatus;\r
+ gBS->SignalEvent (Task->Token->Event);\r
+}\r
+\r
+/**\r
+ Flushes all modified data to the physical device.\r
+\r
+ @param This Indicates a pointer to the calling context.\r
+ @param Token A pointer to the token associated with the transaction.\r
+ If this field is NULL, synchronous/blocking IO is performed.\r
+\r
+ @retval EFI_SUCCESS If Event is NULL (blocking I/O): The data was flushed successfully to the device.\r
+ If Event is not NULL (asynchronous I/O): The request was successfully queued for processing.\r
+ Event will be signaled upon completion.\r
+ @retval EFI_WRITE_PROTECTED The device cannot be written to.\r
+ @retval EFI_DEVICE_ERROR The device reported an error while performing the write operation.\r
+ @retval EFI_NO_MEDIA There is no medium in the device.\r
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DiskIo2FlushDiskEx (\r
+ IN EFI_DISK_IO2_PROTOCOL *This,\r
+ IN OUT EFI_DISK_IO2_TOKEN *Token\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ DISK_IO2_FLUSH_TASK *Task;\r
+ DISK_IO_PRIVATE_DATA *Private;\r
+\r
+ Private = DISK_IO_PRIVATE_DATA_FROM_DISK_IO2 (This);\r
+\r
+ if ((Token != NULL) && (Token->Event != NULL)) {\r
+ Task = AllocatePool (sizeof (DISK_IO2_FLUSH_TASK));\r
+ if (Task == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_CALLBACK,\r
+ DiskIo2OnFlushComplete,\r
+ Task,\r
+ &Task->BlockIo2Token.Event\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ FreePool (Task);\r
+ return Status;\r
+ }\r
+ Task->Signature = DISK_IO2_FLUSH_TASK_SIGNATURE;\r
+ Status = Private->BlockIo2->FlushBlocksEx (Private->BlockIo2, &Task->BlockIo2Token);\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->CloseEvent (Task->BlockIo2Token.Event);\r
+ FreePool (Task);\r
+ }\r
+ } else {\r
+ Status = Private->BlockIo2->FlushBlocksEx (Private->BlockIo2, NULL);\r