for Security Protocol Specific layout. This implementation uses big endian for\r
Cylinder register.\r
\r
- Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
+ (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
\r
**/\r
//\r
Acb = ZeroMem (&AtaDevice->Acb, sizeof (EFI_ATA_COMMAND_BLOCK));\r
Acb->AtaCommand = ATA_CMD_IDENTIFY_DRIVE;\r
- Acb->AtaDeviceHead = (UINT8) (BIT7 | BIT6 | BIT5 | (AtaDevice->PortMultiplierPort << 4));\r
+ Acb->AtaDeviceHead = (UINT8) (BIT7 | BIT6 | BIT5 | (AtaDevice->PortMultiplierPort == 0xFFFF ? 0 : (AtaDevice->PortMultiplierPort << 4)));\r
\r
//\r
// Prepare for ATA pass through packet.\r
Acb->AtaSectorNumber = (UINT8) StartLba;\r
Acb->AtaCylinderLow = (UINT8) RShiftU64 (StartLba, 8);\r
Acb->AtaCylinderHigh = (UINT8) RShiftU64 (StartLba, 16);\r
- Acb->AtaDeviceHead = (UINT8) (BIT7 | BIT6 | BIT5 | (AtaDevice->PortMultiplierPort << 4));\r
+ Acb->AtaDeviceHead = (UINT8) (BIT7 | BIT6 | BIT5 | (AtaDevice->PortMultiplierPort == 0xFFFF ? 0 : (AtaDevice->PortMultiplierPort << 4)));\r
Acb->AtaSectorCount = (UINT8) TransferLength;\r
if (AtaDevice->Lba48Bit) {\r
Acb->AtaSectorNumberExp = (UINT8) RShiftU64 (StartLba, 24);\r
FreePool (Task);\r
}\r
\r
+/**\r
+ Terminate any in-flight non-blocking I/O requests by signaling an EFI_ABORTED\r
+ in the TransactionStatus member of the EFI_BLOCK_IO2_TOKEN for the non-blocking\r
+ I/O. After that it is safe to free any Token or Buffer data structures that\r
+ were allocated to initiate the non-blockingI/O requests that were in-flight for\r
+ this device.\r
+\r
+ @param[in] AtaDevice The ATA child device involved for the operation.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AtaTerminateNonBlockingTask (\r
+ IN ATA_DEVICE *AtaDevice\r
+ )\r
+{\r
+ BOOLEAN SubTaskEmpty;\r
+ EFI_TPL OldTpl;\r
+ ATA_BUS_ASYN_TASK *AtaTask;\r
+ LIST_ENTRY *Entry;\r
+ LIST_ENTRY *List;\r
+\r
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+ //\r
+ // Abort all executing tasks from now.\r
+ //\r
+ AtaDevice->Abort = TRUE;\r
+\r
+ List = &AtaDevice->AtaTaskList;\r
+ for (Entry = GetFirstNode (List); !IsNull (List, Entry);) {\r
+ AtaTask = ATA_ASYN_TASK_FROM_ENTRY (Entry);\r
+ AtaTask->Token->TransactionStatus = EFI_ABORTED;\r
+ gBS->SignalEvent (AtaTask->Token->Event);\r
+\r
+ Entry = RemoveEntryList (Entry);\r
+ FreePool (AtaTask);\r
+ }\r
+ gBS->RestoreTPL (OldTpl);\r
+\r
+ do {\r
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+ //\r
+ // Wait for executing subtasks done.\r
+ //\r
+ SubTaskEmpty = IsListEmpty (&AtaDevice->AtaSubTaskList);\r
+ gBS->RestoreTPL (OldTpl);\r
+ } while (!SubTaskEmpty);\r
+\r
+ //\r
+ // Aborting operation has been done. From now on, don't need to abort normal operation.\r
+ //\r
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+ AtaDevice->Abort = FALSE;\r
+ gBS->RestoreTPL (OldTpl);\r
+}\r
+\r
/**\r
Call back funtion when the event is signaled.\r
\r
if ((!(*Task->IsError)) && ((Task->Packet.Asb->AtaStatus & 0x01) == 0x01)) {\r
Task->Token->TransactionStatus = EFI_DEVICE_ERROR;\r
}\r
+\r
+ if (AtaDevice->Abort) {\r
+ Task->Token->TransactionStatus = EFI_ABORTED;\r
+ }\r
+\r
DEBUG ((\r
EFI_D_BLKIO,\r
"NON-BLOCKING EVENT FINISHED!- STATUS = %r\n",\r
//\r
if (!IsListEmpty (&AtaDevice->AtaTaskList)) {\r
Entry = GetFirstNode (&AtaDevice->AtaTaskList);\r
- AtaTask = ATA_AYNS_TASK_FROM_ENTRY (Entry);\r
+ AtaTask = ATA_ASYN_TASK_FROM_ENTRY (Entry);\r
DEBUG ((EFI_D_BLKIO, "Start to embark a new Ata Task\n"));\r
DEBUG ((EFI_D_BLKIO, "AtaTask->NumberOfBlocks = %x; AtaTask->Token=%x\n", AtaTask->NumberOfBlocks, AtaTask->Token));\r
Status = AccessAtaDevice (\r
SubTask = NULL;\r
SubEvent = NULL;\r
AtaTask = NULL;\r
- \r
+\r
//\r
// Ensure AtaDevice->Lba48Bit is a valid boolean value\r
//\r
//\r
if ((Token != NULL) && (Token->Event != NULL)) {\r
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+\r
if (!IsListEmpty (&AtaDevice->AtaSubTaskList)) {\r
AtaTask = AllocateZeroPool (sizeof (ATA_BUS_ASYN_TASK));\r
if (AtaTask == NULL) {\r
DEBUG ((EFI_D_BLKIO, "AccessAtaDevice, NumberOfBlocks=%x\n", NumberOfBlocks));\r
DEBUG ((EFI_D_BLKIO, "AccessAtaDevice, MaxTransferBlockNumber=%x\n", MaxTransferBlockNumber));\r
DEBUG ((EFI_D_BLKIO, "AccessAtaDevice, EventCount=%x\n", TempCount));\r
- }else {\r
+ } else {\r
while (!IsListEmpty (&AtaDevice->AtaTaskList) || !IsListEmpty (&AtaDevice->AtaSubTaskList)) {\r
//\r
// Stall for 100us.\r
//\r
Acb->AtaCylinderHigh = (UINT8) SecurityProtocolSpecificData;\r
Acb->AtaCylinderLow = (UINT8) (SecurityProtocolSpecificData >> 8);\r
- Acb->AtaDeviceHead = (UINT8) (BIT7 | BIT6 | BIT5 | (AtaDevice->PortMultiplierPort << 4));\r
+ Acb->AtaDeviceHead = (UINT8) (BIT7 | BIT6 | BIT5 | (AtaDevice->PortMultiplierPort == 0xFFFF ? 0 : (AtaDevice->PortMultiplierPort << 4)));\r
\r
//\r
// Prepare for ATA pass through packet.\r