]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Ata/AtaBusDxe/AtaPassThruExecute.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Bus / Ata / AtaBusDxe / AtaPassThruExecute.c
index b1bedd80e819a02ea72931d34a58e187bd8f8c9e..fd483cb9a465cf3f00a650697b1fd9473d064acd 100644 (file)
   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
@@ -413,7 +408,7 @@ DiscoverAtaDevice (
   //\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
@@ -494,7 +489,7 @@ TransferAtaDevice (
   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
@@ -582,6 +577,62 @@ FreeAtaSubTask (
   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
@@ -617,6 +668,11 @@ AtaNonBlockingCallBack (
   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
@@ -652,7 +708,7 @@ AtaNonBlockingCallBack (
     //\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
@@ -737,7 +793,7 @@ AccessAtaDevice(
   SubTask    = NULL;\r
   SubEvent   = NULL;\r
   AtaTask    = NULL;\r
-  \r
+\r
   //\r
   // Ensure AtaDevice->Lba48Bit is a valid boolean value\r
   //\r
@@ -750,6 +806,7 @@ AccessAtaDevice(
   //\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
@@ -788,7 +845,7 @@ AccessAtaDevice(
     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
@@ -964,7 +1021,7 @@ TrustTransferAtaDevice (
   //\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