+\r
+\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+ScsiioToPassThruPacket (\r
+ IN EFI_SCSI_IO_SCSI_REQUEST_PACKET *Packet,\r
+ IN OUT EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *CommandPacket\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Convert EFI_SCSI_IO_SCSI_REQUEST_PACKET packet to \r
+ EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET packet\r
+ \r
+Arguments:\r
+\r
+ Packet - The pointer of EFI_SCSI_IO_SCSI_REQUEST_PACKET\r
+ CommandPacket - The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET\r
+ \r
+Returns:\r
+\r
+ NONE\r
+\r
+--*/\r
+{\r
+ //\r
+ //EFI 1.10 doesn't support Bi-Direction Command.\r
+ //\r
+ if (Packet->DataDirection == EFI_SCSI_IO_DATA_DIRECTION_BIDIRECTIONAL) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ \r
+ ZeroMem (CommandPacket, sizeof (EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET));\r
+\r
+ CommandPacket->Timeout = Packet->Timeout;\r
+ CommandPacket->Cdb = Packet->Cdb;\r
+ CommandPacket->CdbLength = Packet->CdbLength;\r
+ CommandPacket->DataDirection = Packet->DataDirection;\r
+ CommandPacket->HostAdapterStatus = Packet->HostAdapterStatus;\r
+ CommandPacket->TargetStatus = Packet->TargetStatus;\r
+ CommandPacket->SenseData = Packet->SenseData;\r
+ CommandPacket->SenseDataLength = Packet->SenseDataLength;\r
+\r
+ if (Packet->DataDirection == EFI_SCSI_IO_DATA_DIRECTION_READ) {\r
+ CommandPacket->DataBuffer = Packet->InDataBuffer;\r
+ CommandPacket->TransferLength = Packet->InTransferLength;\r
+ } else if (Packet->DataDirection == EFI_SCSI_IO_DATA_DIRECTION_WRITE) {\r
+ CommandPacket->DataBuffer = Packet->OutDataBuffer;\r
+ CommandPacket->TransferLength = Packet->OutTransferLength;\r
+ }\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+PassThruToScsiioPacket (\r
+ IN EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *ScsiPacket,\r
+ IN OUT EFI_SCSI_IO_SCSI_REQUEST_PACKET *Packet\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Convert EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET packet to \r
+ EFI_SCSI_IO_SCSI_REQUEST_PACKET packet\r
+ \r
+Arguments:\r
+\r
+ ScsiPacket - The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET\r
+ Packet - The pointer of EFI_SCSI_IO_SCSI_REQUEST_PACKET\r
+ \r
+Returns:\r
+\r
+ NONE\r
+\r
+--*/\r
+{\r
+ Packet->Timeout = ScsiPacket->Timeout;\r
+ Packet->Cdb = ScsiPacket->Cdb;\r
+ Packet->CdbLength = ScsiPacket->CdbLength;\r
+ Packet->DataDirection = ScsiPacket->DataDirection;\r
+ Packet->HostAdapterStatus = ScsiPacket->HostAdapterStatus;\r
+ Packet->TargetStatus = ScsiPacket->TargetStatus;\r
+ Packet->SenseData = ScsiPacket->SenseData;\r
+ Packet->SenseDataLength = ScsiPacket->SenseDataLength;\r
+\r
+ if (ScsiPacket->DataDirection == EFI_SCSI_IO_DATA_DIRECTION_READ) {\r
+ Packet->InDataBuffer = ScsiPacket->DataBuffer;\r
+ Packet->InTransferLength = ScsiPacket->TransferLength;\r
+ } else if (Packet->DataDirection == EFI_SCSI_IO_DATA_DIRECTION_WRITE) {\r
+ Packet->OutDataBuffer = ScsiPacket->DataBuffer;\r
+ Packet->OutTransferLength = ScsiPacket->TransferLength;\r
+ }\r
+ \r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+\r
+STATIC\r
+VOID\r
+EFIAPI\r
+NotifyFunction (\r
+ EFI_EVENT Event,\r
+ VOID *Context\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Notify Function in which convert EFI1.0 PassThru Packet back to UEF2.0 \r
+ SCSI IO Packet.\r
+ \r
+Arguments:\r
+\r
+ Event - The instance of EFI_EVENT.\r
+ Context - The parameter passed in.\r
+ \r
+Returns:\r
+\r
+ NONE\r
+\r
+--*/ \r
+{\r
+ EFI_SCSI_IO_SCSI_REQUEST_PACKET *Packet;\r
+ EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *ScsiPacket;\r
+ EFI_EVENT CallerEvent;\r
+ SCSI_EVENT_DATA *PassData; \r
+\r
+ PassData = (SCSI_EVENT_DATA*)Context;\r
+ Packet = (EFI_SCSI_IO_SCSI_REQUEST_PACKET *)PassData->Data1;\r
+ ScsiPacket = (EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET*)WorkingBuffer;\r
+\r
+ //\r
+ // Convert EFI1.0 PassThru packet to UEFI2.0 SCSI IO Packet.\r
+ //\r
+ PassThruToScsiioPacket(ScsiPacket, Packet);\r
+ \r
+ //\r
+ // After converting EFI1.0 PassThru Packet back to UEFI2.0 SCSI IO Packet,\r
+ // free WorkingBuffer.\r
+ //\r
+ gBS->FreePool(WorkingBuffer);\r
+\r
+ //\r
+ // Signal Event to tell caller to pick up UEFI2.0 SCSI IO Packet.\r
+ //\r
+ CallerEvent = PassData->Data2;\r
+ gBS->CloseEvent(Event);\r
+ gBS->SignalEvent(CallerEvent);\r
+}\r