]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c
MdeModulePkg ScsiDiskDxe: Raise the Tpl of async IO callback to TPL_NOTIFY
[mirror_edk2.git] / MdeModulePkg / Bus / Scsi / ScsiDiskDxe / ScsiDisk.c
index 2d6d7e3a0c6377d29c5b977c424f3657ed852260..1cacbb9b4a226f689e3769fc20e7b2abeff1f4e0 100644 (file)
@@ -2609,6 +2609,7 @@ ScsiDiskAsyncReadSectors (
   UINT64                Timeout;\r
   SCSI_BLKIO2_REQUEST   *BlkIo2Req;\r
   EFI_STATUS            Status;\r
+  EFI_TPL               OldTpl;\r
 \r
   if ((Token == NULL) || (Token->Event == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -2620,7 +2621,11 @@ ScsiDiskAsyncReadSectors (
   }\r
 \r
   BlkIo2Req->Token  = Token;\r
+\r
+  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
   InsertTailList (&ScsiDiskDevice->BlkIo2Queue, &BlkIo2Req->Link);\r
+  gBS->RestoreTPL (OldTpl);\r
+\r
   InitializeListHead (&BlkIo2Req->ScsiRWQueue);\r
 \r
   Status            = EFI_SUCCESS;\r
@@ -2727,6 +2732,7 @@ ScsiDiskAsyncReadSectors (
         }\r
       }\r
 \r
+      OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
       if (IsListEmpty (&BlkIo2Req->ScsiRWQueue)) {\r
         //\r
         // Free the SCSI_BLKIO2_REQUEST structure only when there is no other\r
@@ -2735,19 +2741,25 @@ ScsiDiskAsyncReadSectors (
         //\r
         RemoveEntryList (&BlkIo2Req->Link);\r
         FreePool (BlkIo2Req);\r
+        BlkIo2Req = NULL;\r
+        gBS->RestoreTPL (OldTpl);\r
 \r
         //\r
         // It is safe to return error status to the caller, since there is no\r
         // previous SCSI sub-task executing.\r
         //\r
-        return EFI_DEVICE_ERROR;\r
+        Status = EFI_DEVICE_ERROR;\r
+        goto Done;\r
       } else {\r
+        gBS->RestoreTPL (OldTpl);\r
+\r
         //\r
         // There are previous SCSI commands still running, EFI_SUCCESS should\r
         // be returned to make sure that the caller does not free resources\r
         // still using by these SCSI commands.\r
         //\r
-        return EFI_SUCCESS;\r
+        Status = EFI_SUCCESS;\r
+        goto Done;\r
       }\r
     }\r
 \r
@@ -2761,7 +2773,24 @@ ScsiDiskAsyncReadSectors (
     BlocksRemaining -= SectorCount;\r
   }\r
 \r
-  return EFI_SUCCESS;\r
+  Status = EFI_SUCCESS;\r
+\r
+Done:\r
+  if (BlkIo2Req != NULL) {\r
+    BlkIo2Req->LastScsiRW = TRUE;\r
+\r
+    OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+    if (IsListEmpty (&BlkIo2Req->ScsiRWQueue)) {\r
+      RemoveEntryList (&BlkIo2Req->Link);\r
+      FreePool (BlkIo2Req);\r
+      BlkIo2Req = NULL;\r
+\r
+      gBS->SignalEvent (Token->Event);\r
+    }\r
+    gBS->RestoreTPL (OldTpl);\r
+  }\r
+\r
+  return Status;\r
 }\r
 \r
 /**\r
@@ -2797,6 +2826,7 @@ ScsiDiskAsyncWriteSectors (
   UINT64                Timeout;\r
   SCSI_BLKIO2_REQUEST   *BlkIo2Req;\r
   EFI_STATUS            Status;\r
+  EFI_TPL               OldTpl;\r
 \r
   if ((Token == NULL) || (Token->Event == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -2808,7 +2838,11 @@ ScsiDiskAsyncWriteSectors (
   }\r
 \r
   BlkIo2Req->Token  = Token;\r
+\r
+  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
   InsertTailList (&ScsiDiskDevice->BlkIo2Queue, &BlkIo2Req->Link);\r
+  gBS->RestoreTPL (OldTpl);\r
+\r
   InitializeListHead (&BlkIo2Req->ScsiRWQueue);\r
 \r
   Status            = EFI_SUCCESS;\r
@@ -2915,6 +2949,7 @@ ScsiDiskAsyncWriteSectors (
         }\r
       }\r
 \r
+      OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
       if (IsListEmpty (&BlkIo2Req->ScsiRWQueue)) {\r
         //\r
         // Free the SCSI_BLKIO2_REQUEST structure only when there is no other\r
@@ -2923,19 +2958,25 @@ ScsiDiskAsyncWriteSectors (
         //\r
         RemoveEntryList (&BlkIo2Req->Link);\r
         FreePool (BlkIo2Req);\r
+        BlkIo2Req = NULL;\r
+        gBS->RestoreTPL (OldTpl);\r
 \r
         //\r
         // It is safe to return error status to the caller, since there is no\r
         // previous SCSI sub-task executing.\r
         //\r
-        return EFI_DEVICE_ERROR;\r
+        Status = EFI_DEVICE_ERROR;\r
+        goto Done;\r
       } else {\r
+        gBS->RestoreTPL (OldTpl);\r
+\r
         //\r
         // There are previous SCSI commands still running, EFI_SUCCESS should\r
         // be returned to make sure that the caller does not free resources\r
         // still using by these SCSI commands.\r
         //\r
-        return EFI_SUCCESS;\r
+        Status = EFI_SUCCESS;\r
+        goto Done;\r
       }\r
     }\r
 \r
@@ -2949,7 +2990,24 @@ ScsiDiskAsyncWriteSectors (
     BlocksRemaining -= SectorCount;\r
   }\r
 \r
-  return EFI_SUCCESS;\r
+  Status = EFI_SUCCESS;\r
+\r
+Done:\r
+  if (BlkIo2Req != NULL) {\r
+    BlkIo2Req->LastScsiRW = TRUE;\r
+\r
+    OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+    if (IsListEmpty (&BlkIo2Req->ScsiRWQueue)) {\r
+      RemoveEntryList (&BlkIo2Req->Link);\r
+      FreePool (BlkIo2Req);\r
+      BlkIo2Req = NULL;\r
+\r
+      gBS->SignalEvent (Token->Event);\r
+    }\r
+    gBS->RestoreTPL (OldTpl);\r
+  }\r
+\r
+  return Status;\r
 }\r
 \r
 \r
@@ -3713,7 +3771,8 @@ Retry:
 \r
 Exit:\r
   RemoveEntryList (&Request->Link);\r
-  if (IsListEmpty (&Request->BlkIo2Req->ScsiRWQueue)) {\r
+  if ((IsListEmpty (&Request->BlkIo2Req->ScsiRWQueue)) &&\r
+      (Request->BlkIo2Req->LastScsiRW)) {\r
     //\r
     // The last SCSI R/W command of a BlockIo2 request completes\r
     //\r
@@ -3763,6 +3822,7 @@ ScsiDiskAsyncRead10 (
   EFI_STATUS                   Status;\r
   SCSI_ASYNC_RW_REQUEST        *Request;\r
   EFI_EVENT                    AsyncIoEvent;\r
+  EFI_TPL                      OldTpl;\r
 \r
   AsyncIoEvent = NULL;\r
 \r
@@ -3770,7 +3830,10 @@ ScsiDiskAsyncRead10 (
   if (Request == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
+\r
+  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
   InsertTailList (&BlkIo2Req->ScsiRWQueue, &Request->Link);\r
+  gBS->RestoreTPL (OldTpl);\r
 \r
   Request->SenseDataLength = (UINT8) (6 * sizeof (EFI_SCSI_SENSE_DATA));\r
   Request->SenseData       = AllocateZeroPool (Request->SenseDataLength);\r
@@ -3793,7 +3856,7 @@ ScsiDiskAsyncRead10 (
   //\r
   Status = gBS->CreateEvent (\r
                   EVT_NOTIFY_SIGNAL,\r
-                  TPL_CALLBACK,\r
+                  TPL_NOTIFY,\r
                   ScsiDiskNotify,\r
                   Request,\r
                   &AsyncIoEvent\r
@@ -3831,7 +3894,10 @@ ErrorExit:
       FreePool (Request->SenseData);\r
     }\r
 \r
+    OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
     RemoveEntryList (&Request->Link);\r
+    gBS->RestoreTPL (OldTpl);\r
+\r
     FreePool (Request);\r
   }\r
 \r
@@ -3875,6 +3941,7 @@ ScsiDiskAsyncWrite10 (
   EFI_STATUS                   Status;\r
   SCSI_ASYNC_RW_REQUEST        *Request;\r
   EFI_EVENT                    AsyncIoEvent;\r
+  EFI_TPL                      OldTpl;\r
 \r
   AsyncIoEvent = NULL;\r
 \r
@@ -3882,7 +3949,10 @@ ScsiDiskAsyncWrite10 (
   if (Request == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
+\r
+  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
   InsertTailList (&BlkIo2Req->ScsiRWQueue, &Request->Link);\r
+  gBS->RestoreTPL (OldTpl);\r
 \r
   Request->SenseDataLength = (UINT8) (6 * sizeof (EFI_SCSI_SENSE_DATA));\r
   Request->SenseData       = AllocateZeroPool (Request->SenseDataLength);\r
@@ -3905,7 +3975,7 @@ ScsiDiskAsyncWrite10 (
   //\r
   Status = gBS->CreateEvent (\r
                   EVT_NOTIFY_SIGNAL,\r
-                  TPL_CALLBACK,\r
+                  TPL_NOTIFY,\r
                   ScsiDiskNotify,\r
                   Request,\r
                   &AsyncIoEvent\r
@@ -3943,7 +4013,10 @@ ErrorExit:
       FreePool (Request->SenseData);\r
     }\r
 \r
+    OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
     RemoveEntryList (&Request->Link);\r
+    gBS->RestoreTPL (OldTpl);\r
+\r
     FreePool (Request);\r
   }\r
 \r
@@ -3987,6 +4060,7 @@ ScsiDiskAsyncRead16 (
   EFI_STATUS                   Status;\r
   SCSI_ASYNC_RW_REQUEST        *Request;\r
   EFI_EVENT                    AsyncIoEvent;\r
+  EFI_TPL                      OldTpl;\r
 \r
   AsyncIoEvent = NULL;\r
 \r
@@ -3994,7 +4068,10 @@ ScsiDiskAsyncRead16 (
   if (Request == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
+\r
+  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
   InsertTailList (&BlkIo2Req->ScsiRWQueue, &Request->Link);\r
+  gBS->RestoreTPL (OldTpl);\r
 \r
   Request->SenseDataLength = (UINT8) (6 * sizeof (EFI_SCSI_SENSE_DATA));\r
   Request->SenseData       = AllocateZeroPool (Request->SenseDataLength);\r
@@ -4017,7 +4094,7 @@ ScsiDiskAsyncRead16 (
   //\r
   Status = gBS->CreateEvent (\r
                   EVT_NOTIFY_SIGNAL,\r
-                  TPL_CALLBACK,\r
+                  TPL_NOTIFY,\r
                   ScsiDiskNotify,\r
                   Request,\r
                   &AsyncIoEvent\r
@@ -4055,7 +4132,10 @@ ErrorExit:
       FreePool (Request->SenseData);\r
     }\r
 \r
+    OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
     RemoveEntryList (&Request->Link);\r
+    gBS->RestoreTPL (OldTpl);\r
+\r
     FreePool (Request);\r
   }\r
 \r
@@ -4099,6 +4179,7 @@ ScsiDiskAsyncWrite16 (
   EFI_STATUS                   Status;\r
   SCSI_ASYNC_RW_REQUEST        *Request;\r
   EFI_EVENT                    AsyncIoEvent;\r
+  EFI_TPL                      OldTpl;\r
 \r
   AsyncIoEvent = NULL;\r
 \r
@@ -4106,7 +4187,10 @@ ScsiDiskAsyncWrite16 (
   if (Request == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
+\r
+  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
   InsertTailList (&BlkIo2Req->ScsiRWQueue, &Request->Link);\r
+  gBS->RestoreTPL (OldTpl);\r
 \r
   Request->SenseDataLength = (UINT8) (6 * sizeof (EFI_SCSI_SENSE_DATA));\r
   Request->SenseData       = AllocateZeroPool (Request->SenseDataLength);\r
@@ -4129,7 +4213,7 @@ ScsiDiskAsyncWrite16 (
   //\r
   Status = gBS->CreateEvent (\r
                   EVT_NOTIFY_SIGNAL,\r
-                  TPL_CALLBACK,\r
+                  TPL_NOTIFY,\r
                   ScsiDiskNotify,\r
                   Request,\r
                   &AsyncIoEvent\r
@@ -4167,7 +4251,10 @@ ErrorExit:
       FreePool (Request->SenseData);\r
     }\r
 \r
+    OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
     RemoveEntryList (&Request->Link);\r
+    gBS->RestoreTPL (OldTpl);\r
+\r
     FreePool (Request);\r
   }\r
 \r