@param This Indicates a pointer to the calling context.\r
@param Token A pointer to the token associated with the transaction.\r
\r
- @retval EFI_SUCCESS All outstanding data was written to the device.\r
- @retval EFI_DEVICE_ERROR The device reported an error while writing back the\r
- data.\r
- @retval EFI_NO_MEDIA There is no media in the device.\r
+ @retval EFI_SUCCESS All outstanding data was written to the device.\r
+ @retval EFI_DEVICE_ERROR The device reported an error while attempting to\r
+ write data.\r
+ @retval EFI_WRITE_PROTECTED The device cannot be written to.\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
\r
**/\r
EFI_STATUS\r
IN OUT EFI_BLOCK_IO2_TOKEN *Token\r
)\r
{\r
+ SCSI_DISK_DEV *ScsiDiskDevice;\r
+ EFI_BLOCK_IO_MEDIA *Media;\r
+ EFI_STATUS Status;\r
+ BOOLEAN MediaChange;\r
+ EFI_TPL OldTpl;\r
+\r
+ MediaChange = FALSE;\r
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+ ScsiDiskDevice = SCSI_DISK_DEV_FROM_BLKIO2 (This);\r
+\r
+ if (!IS_DEVICE_FIXED(ScsiDiskDevice)) {\r
+\r
+ Status = ScsiDiskDetectMedia (ScsiDiskDevice, FALSE, &MediaChange);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto Done;\r
+ }\r
+\r
+ if (MediaChange) {\r
+ gBS->ReinstallProtocolInterface (\r
+ ScsiDiskDevice->Handle,\r
+ &gEfiBlockIoProtocolGuid,\r
+ &ScsiDiskDevice->BlkIo,\r
+ &ScsiDiskDevice->BlkIo\r
+ );\r
+ gBS->ReinstallProtocolInterface (\r
+ ScsiDiskDevice->Handle,\r
+ &gEfiBlockIo2ProtocolGuid,\r
+ &ScsiDiskDevice->BlkIo2,\r
+ &ScsiDiskDevice->BlkIo2\r
+ );\r
+ Status = EFI_MEDIA_CHANGED;\r
+ goto Done;\r
+ }\r
+ }\r
+\r
+ Media = ScsiDiskDevice->BlkIo2.Media;\r
+\r
+ if (!(Media->MediaPresent)) {\r
+ Status = EFI_NO_MEDIA;\r
+ goto Done;\r
+ }\r
+\r
+ if (Media->ReadOnly) {\r
+ Status = EFI_WRITE_PROTECTED;\r
+ goto Done;\r
+ }\r
+\r
//\r
- // Signal event and return directly.\r
+ // Wait for the BlockIo2 requests queue to become empty\r
+ //\r
+ while (!IsListEmpty (&ScsiDiskDevice->BlkIo2Queue));\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ //\r
+ // Signal caller event\r
//\r
if ((Token != NULL) && (Token->Event != NULL)) {\r
Token->TransactionStatus = EFI_SUCCESS;\r
gBS->SignalEvent (Token->Event);\r
}\r
\r
- return EFI_SUCCESS;\r
+Done:\r
+ gBS->RestoreTPL (OldTpl);\r
+ return Status;\r
}\r
\r
\r
@param This Indicates a pointer to the calling context.\r
@param Token A pointer to the token associated with the transaction.\r
\r
- @retval EFI_SUCCESS All outstanding data was written to the device.\r
- @retval EFI_DEVICE_ERROR The device reported an error while writing back the\r
- data.\r
- @retval EFI_NO_MEDIA There is no media in the device.\r
+ @retval EFI_SUCCESS All outstanding data was written to the device.\r
+ @retval EFI_DEVICE_ERROR The device reported an error while attempting to\r
+ write data.\r
+ @retval EFI_WRITE_PROTECTED The device cannot be written to.\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
\r
**/\r
EFI_STATUS\r