]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Allocate aligned buffer to satisfy the IoAlign requirement of high level protocol.
authorlzeng14 <lzeng14@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 25 Nov 2011 09:52:12 +0000 (09:52 +0000)
committerlzeng14 <lzeng14@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 25 Nov 2011 09:52:12 +0000 (09:52 +0000)
Signed-off-by: lzeng14
Reviewed-by: erictian
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12788 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBus.c
MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBus.c
MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c

index 27d0a1c3dbd3fe1208546da85ce32d69055dc2ab..0d9d066df9bd2f7532114b15df8e0abca3aaec84 100644 (file)
@@ -129,7 +129,7 @@ FreeAlignedBuffer (
   )\r
 {\r
   if (Buffer != NULL) {\r
-    FreePages (Buffer, EFI_SIZE_TO_PAGES (BufferSize));\r
+    FreeAlignedPages (Buffer, EFI_SIZE_TO_PAGES (BufferSize));\r
   }\r
 }\r
 \r
index b1c4d207f9de8bf415b3b7a157906391dcba334e..7387a44dbedf3f1e3b52502db034234a053e6dde 100644 (file)
@@ -2,7 +2,7 @@
   SCSI Bus driver that layers on every SCSI Pass Thru and\r
   Extended SCSI Pass Thru protocol in the system.\r
 \r
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2011, 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
@@ -71,6 +71,49 @@ NotifyFunction (
   IN  VOID       *Context\r
   );\r
 \r
+/**\r
+  Allocates an aligned buffer for SCSI device.\r
+\r
+  This function allocates an aligned buffer for the SCSI device to perform\r
+  SCSI pass through operations. The alignment requirement is from SCSI pass\r
+  through interface.\r
+\r
+  @param  ScsiIoDevice      The SCSI child device involved for the operation.\r
+  @param  BufferSize        The request buffer size.\r
+\r
+  @return A pointer to the aligned buffer or NULL if the allocation fails.\r
+\r
+**/\r
+VOID *\r
+AllocateAlignedBuffer (\r
+  IN SCSI_IO_DEV              *ScsiIoDevice,\r
+  IN UINTN                    BufferSize\r
+  )\r
+{\r
+  return AllocateAlignedPages (EFI_SIZE_TO_PAGES (BufferSize), ScsiIoDevice->ScsiIo.IoAlign);\r
+}\r
+\r
+/**\r
+  Frees an aligned buffer for SCSI device.\r
+\r
+  This function frees an aligned buffer for the SCSI device to perform\r
+  SCSI pass through operations.\r
+\r
+  @param  Buffer            The aligned buffer to be freed.\r
+  @param  BufferSize        The request buffer size.\r
+\r
+**/\r
+VOID\r
+FreeAlignedBuffer (\r
+  IN VOID                     *Buffer,\r
+  IN UINTN                    BufferSize\r
+  )\r
+{\r
+  if (Buffer != NULL) {\r
+    FreeAlignedPages (Buffer, EFI_SIZE_TO_PAGES (BufferSize));\r
+  }\r
+}\r
+\r
 /**\r
   The user Entry Point for module ScsiBus. The user code starts with this function.\r
 \r
@@ -1178,30 +1221,37 @@ DiscoverScsiDevice (
   UINT8                 SenseDataLength;\r
   UINT8                 HostAdapterStatus;\r
   UINT8                 TargetStatus;\r
-  EFI_SCSI_SENSE_DATA   SenseData;\r
-  EFI_SCSI_INQUIRY_DATA InquiryData;\r
+  EFI_SCSI_INQUIRY_DATA *InquiryData;\r
   UINT8                 MaxRetry;\r
   UINT8                 Index;\r
+  BOOLEAN               ScsiDeviceFound;\r
 \r
   HostAdapterStatus = 0;\r
   TargetStatus      = 0;\r
+\r
+  InquiryData = AllocateAlignedBuffer (ScsiIoDevice, sizeof (EFI_SCSI_INQUIRY_DATA));\r
+  if (InquiryData == NULL) {\r
+    ScsiDeviceFound = FALSE;\r
+    goto Done;\r
+  }\r
+\r
   //\r
   // Using Inquiry command to scan for the device\r
   //\r
   InquiryDataLength = sizeof (EFI_SCSI_INQUIRY_DATA);\r
-  SenseDataLength   = (UINT8) sizeof (EFI_SCSI_SENSE_DATA);\r
-  ZeroMem (&InquiryData, InquiryDataLength);\r
+  SenseDataLength   = 0;\r
+  ZeroMem (InquiryData, InquiryDataLength);\r
 \r
   MaxRetry = 2;\r
   for (Index = 0; Index < MaxRetry; Index++) {\r
     Status = ScsiInquiryCommand (\r
               &ScsiIoDevice->ScsiIo,\r
               EFI_TIMER_PERIOD_SECONDS (1),\r
-              (VOID *) &SenseData,\r
+              NULL,\r
               &SenseDataLength,\r
               &HostAdapterStatus,\r
               &TargetStatus,\r
-              (VOID *) &InquiryData,\r
+              (VOID *) InquiryData,\r
               &InquiryDataLength,\r
               FALSE\r
               );\r
@@ -1210,47 +1260,57 @@ DiscoverScsiDevice (
     } else if ((Status == EFI_BAD_BUFFER_SIZE) || \r
                (Status == EFI_INVALID_PARAMETER) ||\r
                (Status == EFI_UNSUPPORTED)) {\r
-      return FALSE;\r
+      ScsiDeviceFound = FALSE;\r
+      goto Done;\r
     }\r
   }\r
 \r
   if (Index == MaxRetry) {\r
-    return FALSE;\r
+    ScsiDeviceFound = FALSE;\r
+    goto Done;\r
   }\r
   \r
   //\r
   // Retrieved inquiry data successfully\r
   //\r
-  if ((InquiryData.Peripheral_Qualifier != 0) &&\r
-      (InquiryData.Peripheral_Qualifier != 3)) {\r
-    return FALSE;\r
+  if ((InquiryData->Peripheral_Qualifier != 0) &&\r
+      (InquiryData->Peripheral_Qualifier != 3)) {\r
+    ScsiDeviceFound = FALSE;\r
+    goto Done;\r
   }\r
 \r
-  if (InquiryData.Peripheral_Qualifier == 3) {\r
-    if (InquiryData.Peripheral_Type != 0x1f) {\r
-      return FALSE;\r
+  if (InquiryData->Peripheral_Qualifier == 3) {\r
+    if (InquiryData->Peripheral_Type != 0x1f) {\r
+      ScsiDeviceFound = FALSE;\r
+      goto Done;\r
     }\r
   }\r
 \r
-  if (0x1e >= InquiryData.Peripheral_Type && InquiryData.Peripheral_Type >= 0xa) {\r
-    return FALSE;\r
+  if (0x1e >= InquiryData->Peripheral_Type && InquiryData->Peripheral_Type >= 0xa) {\r
+    ScsiDeviceFound = FALSE;\r
+    goto Done;\r
   }\r
 \r
   //\r
   // valid device type and peripheral qualifier combination.\r
   //\r
-  ScsiIoDevice->ScsiDeviceType  = InquiryData.Peripheral_Type;\r
-  ScsiIoDevice->RemovableDevice = InquiryData.Rmb;\r
-  if (InquiryData.Version == 0) {\r
+  ScsiIoDevice->ScsiDeviceType  = InquiryData->Peripheral_Type;\r
+  ScsiIoDevice->RemovableDevice = InquiryData->Rmb;\r
+  if (InquiryData->Version == 0) {\r
     ScsiIoDevice->ScsiVersion = 0;\r
   } else {\r
     //\r
     // ANSI-approved version\r
     //\r
-    ScsiIoDevice->ScsiVersion = (UINT8) (InquiryData.Version & 0x07);\r
+    ScsiIoDevice->ScsiVersion = (UINT8) (InquiryData->Version & 0x07);\r
   }\r
 \r
-  return TRUE;\r
+  ScsiDeviceFound = TRUE;\r
+\r
+Done:\r
+  FreeAlignedBuffer (InquiryData, sizeof (EFI_SCSI_INQUIRY_DATA));\r
+\r
+  return ScsiDeviceFound;\r
 }\r
 \r
 \r
index 0e8aa34ad63c61e6dc26d370db253d7b29c0cc9c..f47cfe07e1a7a6e175597bbfa6bf1aa14036cc2f 100644 (file)
@@ -32,6 +32,48 @@ EFI_DISK_INFO_PROTOCOL gScsiDiskInfoProtocolTemplate = {
   ScsiDiskInfoWhichIde\r
 };\r
 \r
+/**\r
+  Allocates an aligned buffer for SCSI disk.\r
+\r
+  This function allocates an aligned buffer for the SCSI disk to perform\r
+  SCSI IO operations. The alignment requirement is from SCSI IO interface.\r
+\r
+  @param  ScsiDiskDevice    The SCSI disk involved for the operation.\r
+  @param  BufferSize        The request buffer size.\r
+\r
+  @return A pointer to the aligned buffer or NULL if the allocation fails.\r
+\r
+**/\r
+VOID *\r
+AllocateAlignedBuffer (\r
+  IN SCSI_DISK_DEV            *ScsiDiskDevice,\r
+  IN UINTN                    BufferSize\r
+  )\r
+{\r
+  return AllocateAlignedPages (EFI_SIZE_TO_PAGES (BufferSize), ScsiDiskDevice->ScsiIo->IoAlign);\r
+}\r
+\r
+/**\r
+  Frees an aligned buffer for SCSI disk.\r
+\r
+  This function frees an aligned buffer for the SCSI disk to perform\r
+  SCSI IO operations.\r
+\r
+  @param  Buffer            The aligned buffer to be freed.\r
+  @param  BufferSize        The request buffer size.\r
+\r
+**/\r
+VOID\r
+FreeAlignedBuffer (\r
+  IN VOID                     *Buffer,\r
+  IN UINTN                    BufferSize\r
+  )\r
+{\r
+  if (Buffer != NULL) {\r
+    FreeAlignedPages (Buffer, EFI_SIZE_TO_PAGES (BufferSize));\r
+  }\r
+}\r
+\r
 /**\r
   The user Entry Point for module ScsiDisk.\r
 \r
@@ -902,8 +944,8 @@ ScsiDiskInquiryDevice (
   EFI_STATUS                            Status;\r
   UINT8                                 MaxRetry;\r
   UINT8                                 Index;\r
-  EFI_SCSI_SUPPORTED_VPD_PAGES_VPD_PAGE SupportedVpdPages;\r
-  EFI_SCSI_BLOCK_LIMITS_VPD_PAGE        BlockLimits;\r
+  EFI_SCSI_SUPPORTED_VPD_PAGES_VPD_PAGE *SupportedVpdPages;\r
+  EFI_SCSI_BLOCK_LIMITS_VPD_PAGE        *BlockLimits;\r
   UINTN                                 PageLength;\r
 \r
   InquiryDataLength = sizeof (EFI_SCSI_INQUIRY_DATA);\r
@@ -930,8 +972,13 @@ ScsiDiskInquiryDevice (
       //\r
       // Check whether the device supports Block Limits VPD page (0xB0)\r
       //\r
-      ZeroMem (&SupportedVpdPages, sizeof (SupportedVpdPages));\r
-      InquiryDataLength = sizeof (SupportedVpdPages);\r
+      SupportedVpdPages = AllocateAlignedBuffer (ScsiDiskDevice, sizeof (EFI_SCSI_SUPPORTED_VPD_PAGES_VPD_PAGE));\r
+      if (SupportedVpdPages == NULL) {\r
+        *NeedRetry = FALSE;\r
+        return EFI_DEVICE_ERROR;\r
+      }\r
+      ZeroMem (SupportedVpdPages, sizeof (EFI_SCSI_SUPPORTED_VPD_PAGES_VPD_PAGE));\r
+      InquiryDataLength = sizeof (EFI_SCSI_SUPPORTED_VPD_PAGES_VPD_PAGE);\r
       SenseDataLength   = 0;\r
       Status = ScsiInquiryCommandEx (\r
                  ScsiDiskDevice->ScsiIo,\r
@@ -940,16 +987,16 @@ ScsiDiskInquiryDevice (
                  &SenseDataLength,\r
                  &HostAdapterStatus,\r
                  &TargetStatus,\r
-                 (VOID *) &SupportedVpdPages,\r
+                 (VOID *) SupportedVpdPages,\r
                  &InquiryDataLength,\r
                  TRUE,\r
                  EFI_SCSI_PAGE_CODE_SUPPORTED_VPD\r
                  );\r
       if (!EFI_ERROR (Status)) {\r
-        PageLength = (SupportedVpdPages.PageLength2 << 8)\r
-                   |  SupportedVpdPages.PageLength1;\r
+        PageLength = (SupportedVpdPages->PageLength2 << 8)\r
+                   |  SupportedVpdPages->PageLength1;\r
         for (Index = 0; Index < PageLength; Index++) {\r
-          if (SupportedVpdPages.SupportedVpdPageList[Index] == EFI_SCSI_PAGE_CODE_BLOCK_LIMITS_VPD) {\r
+          if (SupportedVpdPages->SupportedVpdPageList[Index] == EFI_SCSI_PAGE_CODE_BLOCK_LIMITS_VPD) {\r
             break;\r
           }\r
         }\r
@@ -958,8 +1005,14 @@ ScsiDiskInquiryDevice (
         // Query the Block Limits VPD page\r
         //\r
         if (Index < PageLength) {\r
-          ZeroMem (&BlockLimits, sizeof (BlockLimits));\r
-          InquiryDataLength = sizeof (BlockLimits);\r
+          BlockLimits = AllocateAlignedBuffer (ScsiDiskDevice, sizeof (EFI_SCSI_BLOCK_LIMITS_VPD_PAGE));\r
+          if (BlockLimits == NULL) {\r
+            FreeAlignedBuffer (SupportedVpdPages, sizeof (EFI_SCSI_SUPPORTED_VPD_PAGES_VPD_PAGE));\r
+            *NeedRetry = FALSE;\r
+            return EFI_DEVICE_ERROR;\r
+          }\r
+          ZeroMem (BlockLimits, sizeof (EFI_SCSI_BLOCK_LIMITS_VPD_PAGE));\r
+          InquiryDataLength = sizeof (EFI_SCSI_BLOCK_LIMITS_VPD_PAGE);\r
           SenseDataLength   = 0;\r
           Status = ScsiInquiryCommandEx (\r
                      ScsiDiskDevice->ScsiIo,\r
@@ -968,18 +1021,22 @@ ScsiDiskInquiryDevice (
                      &SenseDataLength,\r
                      &HostAdapterStatus,\r
                      &TargetStatus,\r
-                     (VOID *) &BlockLimits,\r
+                     (VOID *) BlockLimits,\r
                      &InquiryDataLength,\r
                      TRUE,\r
                      EFI_SCSI_PAGE_CODE_BLOCK_LIMITS_VPD\r
                      );\r
           if (!EFI_ERROR (Status)) {\r
             ScsiDiskDevice->BlkIo.Media->OptimalTransferLengthGranularity = \r
-              (BlockLimits.OptimalTransferLengthGranularity2 << 8) |\r
-               BlockLimits.OptimalTransferLengthGranularity1;\r
+              (BlockLimits->OptimalTransferLengthGranularity2 << 8) |\r
+               BlockLimits->OptimalTransferLengthGranularity1;\r
           }\r
+\r
+          FreeAlignedBuffer (BlockLimits, sizeof (EFI_SCSI_BLOCK_LIMITS_VPD_PAGE));\r
         }\r
       }\r
+\r
+      FreeAlignedBuffer (SupportedVpdPages, sizeof (EFI_SCSI_SUPPORTED_VPD_PAGES_VPD_PAGE));\r
     }\r
   }\r
 \r
@@ -1285,15 +1342,26 @@ ScsiDiskReadCapacity (
   UINT8                         SenseDataLength;\r
   UINT32                        DataLength10;\r
   UINT32                        DataLength16;\r
-  EFI_SCSI_DISK_CAPACITY_DATA   CapacityData10;\r
-  EFI_SCSI_DISK_CAPACITY_DATA16 CapacityData16;\r
+  EFI_SCSI_DISK_CAPACITY_DATA   *CapacityData10;\r
+  EFI_SCSI_DISK_CAPACITY_DATA16 *CapacityData16;\r
 \r
+  CapacityData10 = AllocateAlignedBuffer (ScsiDiskDevice, sizeof (EFI_SCSI_DISK_CAPACITY_DATA));\r
+  if (CapacityData10 == NULL) {\r
+    *NeedRetry = FALSE;\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+  CapacityData16 = AllocateAlignedBuffer (ScsiDiskDevice, sizeof (EFI_SCSI_DISK_CAPACITY_DATA16));\r
+  if (CapacityData16 == NULL) {\r
+    FreeAlignedBuffer (CapacityData10, sizeof (EFI_SCSI_DISK_CAPACITY_DATA));\r
+    *NeedRetry = FALSE;\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
 \r
   SenseDataLength       = 0;\r
   DataLength10          = sizeof (EFI_SCSI_DISK_CAPACITY_DATA);\r
   DataLength16          = sizeof (EFI_SCSI_DISK_CAPACITY_DATA16);\r
-  ZeroMem (&CapacityData10, sizeof (EFI_SCSI_DISK_CAPACITY_DATA));\r
-  ZeroMem (&CapacityData16, sizeof (EFI_SCSI_DISK_CAPACITY_DATA16));\r
+  ZeroMem (CapacityData10, sizeof (EFI_SCSI_DISK_CAPACITY_DATA));\r
+  ZeroMem (CapacityData16, sizeof (EFI_SCSI_DISK_CAPACITY_DATA16));\r
 \r
   *NumberOfSenseKeys  = 0;\r
   *NeedRetry          = FALSE;\r
@@ -1309,14 +1377,14 @@ ScsiDiskReadCapacity (
                     &SenseDataLength,\r
                     &HostAdapterStatus,\r
                     &TargetStatus,\r
-                    (VOID *) &CapacityData10,\r
+                    (VOID *) CapacityData10,\r
                     &DataLength10,\r
                     FALSE\r
                     );\r
 \r
   ScsiDiskDevice->Cdb16Byte = FALSE;\r
-  if ((!EFI_ERROR (CommandStatus)) && (CapacityData10.LastLba3 == 0xff) && (CapacityData10.LastLba2 == 0xff) &&\r
-      (CapacityData10.LastLba1 == 0xff) && (CapacityData10.LastLba0 == 0xff)) {\r
+  if ((!EFI_ERROR (CommandStatus)) && (CapacityData10->LastLba3 == 0xff) && (CapacityData10->LastLba2 == 0xff) &&\r
+      (CapacityData10->LastLba1 == 0xff) && (CapacityData10->LastLba0 == 0xff)) {\r
     //\r
     // use Read Capacity (16), Read (16) and Write (16) next when hard disk size > 2TB\r
     //\r
@@ -1332,7 +1400,7 @@ ScsiDiskReadCapacity (
                       &SenseDataLength,\r
                       &HostAdapterStatus,\r
                       &TargetStatus,\r
-                      (VOID *) &CapacityData16,\r
+                      (VOID *) CapacityData16,\r
                       &DataLength16,\r
                       FALSE\r
                       );\r
@@ -1342,17 +1410,23 @@ ScsiDiskReadCapacity (
     // no need to check HostAdapterStatus and TargetStatus\r
     //\r
    if (CommandStatus == EFI_SUCCESS) {\r
-     GetMediaInfo (ScsiDiskDevice, &CapacityData10,&CapacityData16);\r
+     GetMediaInfo (ScsiDiskDevice, CapacityData10, CapacityData16);\r
+     FreeAlignedBuffer (CapacityData10, sizeof (EFI_SCSI_DISK_CAPACITY_DATA));\r
+     FreeAlignedBuffer (CapacityData16, sizeof (EFI_SCSI_DISK_CAPACITY_DATA16));\r
      return EFI_SUCCESS;\r
\r
-   } else if (CommandStatus == EFI_NOT_READY) {\r
+   }\r
+\r
+   FreeAlignedBuffer (CapacityData10, sizeof (EFI_SCSI_DISK_CAPACITY_DATA));\r
+   FreeAlignedBuffer (CapacityData16, sizeof (EFI_SCSI_DISK_CAPACITY_DATA16));\r
+\r
+   if (CommandStatus == EFI_NOT_READY) {\r
      *NeedRetry = TRUE;\r
      return EFI_DEVICE_ERROR;\r
\r
    } else if ((CommandStatus == EFI_INVALID_PARAMETER) || (CommandStatus == EFI_UNSUPPORTED)) {\r
      *NeedRetry = FALSE;\r
      return EFI_DEVICE_ERROR;\r
    }\r
+\r
    //\r
    // go ahead to check HostAdapterStatus and TargetStatus\r
    // (EFI_TIMEOUT, EFI_DEVICE_ERROR, EFI_WARN_BUFFER_TOO_SMALL)\r