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
}\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
}\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
//\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
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
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
}\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
}\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
//\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
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
\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
EFI_STATUS Status;\r
SCSI_ASYNC_RW_REQUEST *Request;\r
EFI_EVENT AsyncIoEvent;\r
+ EFI_TPL OldTpl;\r
\r
AsyncIoEvent = NULL;\r
\r
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
//\r
Status = gBS->CreateEvent (\r
EVT_NOTIFY_SIGNAL,\r
- TPL_CALLBACK,\r
+ TPL_NOTIFY,\r
ScsiDiskNotify,\r
Request,\r
&AsyncIoEvent\r
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
EFI_STATUS Status;\r
SCSI_ASYNC_RW_REQUEST *Request;\r
EFI_EVENT AsyncIoEvent;\r
+ EFI_TPL OldTpl;\r
\r
AsyncIoEvent = NULL;\r
\r
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
//\r
Status = gBS->CreateEvent (\r
EVT_NOTIFY_SIGNAL,\r
- TPL_CALLBACK,\r
+ TPL_NOTIFY,\r
ScsiDiskNotify,\r
Request,\r
&AsyncIoEvent\r
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
EFI_STATUS Status;\r
SCSI_ASYNC_RW_REQUEST *Request;\r
EFI_EVENT AsyncIoEvent;\r
+ EFI_TPL OldTpl;\r
\r
AsyncIoEvent = NULL;\r
\r
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
//\r
Status = gBS->CreateEvent (\r
EVT_NOTIFY_SIGNAL,\r
- TPL_CALLBACK,\r
+ TPL_NOTIFY,\r
ScsiDiskNotify,\r
Request,\r
&AsyncIoEvent\r
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
EFI_STATUS Status;\r
SCSI_ASYNC_RW_REQUEST *Request;\r
EFI_EVENT AsyncIoEvent;\r
+ EFI_TPL OldTpl;\r
\r
AsyncIoEvent = NULL;\r
\r
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
//\r
Status = gBS->CreateEvent (\r
EVT_NOTIFY_SIGNAL,\r
- TPL_CALLBACK,\r
+ TPL_NOTIFY,\r
ScsiDiskNotify,\r
Request,\r
&AsyncIoEvent\r
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