]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassImpl.c
MdeModulePkg/UsbMassStorage: Add 16 byte SCSI cmds support if the last LBA can not...
[mirror_edk2.git] / MdeModulePkg / Bus / Usb / UsbMassStorageDxe / UsbMassImpl.c
index f440e9fd7c5f78820afbce67ed165630a94a26c3..4cbedfade6caec49755982f504f5f2fe59f7d00b 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   USB Mass Storage Driver that manages USB Mass Storage Device and produces Block I/O Protocol.\r
 \r
-Copyright (c) 2007 - 2008, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2007 - 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
@@ -12,7 +12,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 **/\r
 \r
-#include "UsbMassImpl.h"\r
+#include "UsbMass.h"\r
 \r
 #define USB_MASS_TRANSPORT_COUNT    3\r
 //\r
@@ -113,13 +113,6 @@ UsbMassReadBlocks (
   EFI_TPL             OldTpl;\r
   UINTN               TotalBlock;\r
 \r
-  //\r
-  // First, validate the parameters\r
-  //\r
-  if ((Buffer == NULL) || (BufferSize == 0)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
   //\r
   // Raise TPL to TPL_NOTIFY to serialize all its operations\r
   // to protect shared data structures.\r
@@ -140,6 +133,26 @@ UsbMassReadBlocks (
     }\r
   }\r
 \r
+  if (!(Media->MediaPresent)) {\r
+    Status = EFI_NO_MEDIA;\r
+    goto ON_EXIT;\r
+  }\r
+\r
+  if (MediaId != Media->MediaId) {\r
+    Status = EFI_MEDIA_CHANGED;\r
+    goto ON_EXIT;\r
+  }\r
+\r
+  if (BufferSize == 0) {\r
+    Status = EFI_SUCCESS;\r
+    goto ON_EXIT;\r
+  }\r
+\r
+  if (Buffer == NULL) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto ON_EXIT;\r
+  }\r
+\r
   //\r
   // BufferSize must be a multiple of the intrinsic block size of the device.\r
   //\r
@@ -158,17 +171,12 @@ UsbMassReadBlocks (
     goto ON_EXIT;\r
   }\r
 \r
-  if (!(Media->MediaPresent)) {\r
-    Status = EFI_NO_MEDIA;\r
-    goto ON_EXIT;\r
-  }\r
-\r
-  if (MediaId != Media->MediaId) {\r
-    Status = EFI_MEDIA_CHANGED;\r
-    goto ON_EXIT;\r
+  if (UsbMass->Cdb16Byte) {\r
+    Status = UsbBootReadBlocks16 (UsbMass, Lba, TotalBlock, Buffer);\r
+  } else {\r
+    Status = UsbBootReadBlocks (UsbMass, (UINT32) Lba, TotalBlock, Buffer);\r
   }\r
 \r
-  Status = UsbBootReadBlocks (UsbMass, (UINT32) Lba, TotalBlock, Buffer);\r
   if (EFI_ERROR (Status)) {\r
     DEBUG ((EFI_D_ERROR, "UsbMassReadBlocks: UsbBootReadBlocks (%r) -> Reset\n", Status));\r
     UsbMassReset (This, TRUE);\r
@@ -221,13 +229,6 @@ UsbMassWriteBlocks (
   EFI_TPL             OldTpl;\r
   UINTN               TotalBlock;\r
 \r
-  //\r
-  // First, validate the parameters\r
-  //\r
-  if ((Buffer == NULL) || (BufferSize == 0)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
   //\r
   // Raise TPL to TPL_NOTIFY to serialize all its operations\r
   // to protect shared data structures.\r
@@ -248,6 +249,26 @@ UsbMassWriteBlocks (
     }\r
   }\r
 \r
+  if (!(Media->MediaPresent)) {\r
+    Status = EFI_NO_MEDIA;\r
+    goto ON_EXIT;\r
+  }\r
+\r
+  if (MediaId != Media->MediaId) {\r
+    Status = EFI_MEDIA_CHANGED;\r
+    goto ON_EXIT;\r
+  }\r
+\r
+  if (BufferSize == 0) {\r
+    Status = EFI_SUCCESS;\r
+    goto ON_EXIT;\r
+  }\r
+\r
+  if (Buffer == NULL) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto ON_EXIT;\r
+  }\r
+\r
   //\r
   // BufferSize must be a multiple of the intrinsic block size of the device.\r
   //\r
@@ -266,21 +287,16 @@ UsbMassWriteBlocks (
     goto ON_EXIT;\r
   }\r
 \r
-  if (!(Media->MediaPresent)) {\r
-    Status = EFI_NO_MEDIA;\r
-    goto ON_EXIT;\r
-  }\r
-\r
-  if (MediaId != Media->MediaId) {\r
-    Status = EFI_MEDIA_CHANGED;\r
-    goto ON_EXIT;\r
-  }\r
-\r
   //\r
   // Try to write the data even the device is marked as ReadOnly,\r
   // and clear the status should the write succeed.\r
   //\r
-  Status = UsbBootWriteBlocks (UsbMass, (UINT32) Lba, TotalBlock, Buffer);\r
+  if (UsbMass->Cdb16Byte) {\r
+    Status = UsbBootWriteBlocks16 (UsbMass, Lba, TotalBlock, Buffer);\r
+  } else {\r
+    Status = UsbBootWriteBlocks (UsbMass, (UINT32) Lba, TotalBlock, Buffer);\r
+  }  \r
+\r
   if (EFI_ERROR (Status)) {\r
     DEBUG ((EFI_D_ERROR, "UsbMassWriteBlocks: UsbBootWriteBlocks (%r) -> Reset\n", Status));\r
     UsbMassReset (This, TRUE);\r
@@ -330,7 +346,6 @@ UsbMassInitMedia (
 {\r
   EFI_BLOCK_IO_MEDIA          *Media;\r
   EFI_STATUS                  Status;\r
-  UINTN                       Index;\r
 \r
   Media = &UsbMass->BlockIoMedia;\r
 \r
@@ -345,25 +360,7 @@ UsbMassInitMedia (
   Media->IoAlign          = 0;\r
   Media->MediaId          = 1;\r
 \r
-  //\r
-  // Some device may spend several seconds before it is ready.\r
-  // Try several times before giving up. Wait 5s at most.\r
-  //\r
-  Status = EFI_SUCCESS;\r
-\r
-  for (Index = 0; Index < USB_BOOT_INIT_MEDIA_RETRY; Index++) {\r
-\r
-    Status = UsbBootGetParams (UsbMass);\r
-    if ((Status != EFI_MEDIA_CHANGED) && (Status != EFI_NOT_READY) && (Status != EFI_TIMEOUT)) {\r
-      break;\r
-    }\r
-\r
-    Status = UsbBootIsUnitReady (UsbMass);\r
-    if (EFI_ERROR (Status)) {\r
-      gBS->Stall (USB_BOOT_RETRY_UNIT_READY_STALL * (Index + 1));\r
-    }\r
-  }\r
-\r
+  Status = UsbBootGetParams (UsbMass);\r
   return Status;\r
 }\r
 \r
@@ -548,6 +545,8 @@ UsbMassInitMultiLun (
       goto ON_ERROR;\r
     }\r
 \r
+    InitializeDiskInfo (UsbMass);\r
+\r
     //\r
     // Create a new handle for each LUN, and install Block I/O Protocol and Device Path Protocol.\r
     //\r
@@ -557,6 +556,8 @@ UsbMassInitMultiLun (
                     UsbMass->DevicePath,\r
                     &gEfiBlockIoProtocolGuid,\r
                     &UsbMass->BlockIo,\r
+                    &gEfiDiskInfoProtocolGuid,\r
+                    &UsbMass->DiskInfo,\r
                     NULL\r
                     );\r
     \r
@@ -585,6 +586,8 @@ UsbMassInitMultiLun (
              UsbMass->DevicePath,\r
              &gEfiBlockIoProtocolGuid,\r
              &UsbMass->BlockIo,\r
+             &gEfiDiskInfoProtocolGuid,\r
+             &UsbMass->DiskInfo,\r
              NULL\r
              );\r
       goto ON_ERROR;\r
@@ -696,11 +699,15 @@ UsbMassInitNonLun (
     goto ON_ERROR;\r
   }\r
     \r
-  Status = gBS->InstallProtocolInterface (\r
+  InitializeDiskInfo (UsbMass);\r
+\r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
                   &Controller,\r
                   &gEfiBlockIoProtocolGuid,\r
-                  EFI_NATIVE_INTERFACE,\r
-                  &UsbMass->BlockIo\r
+                  &UsbMass->BlockIo,\r
+                  &gEfiDiskInfoProtocolGuid,\r
+                  &UsbMass->DiskInfo,\r
+                  NULL\r
                   );\r
   if (EFI_ERROR (Status)) {\r
     goto ON_ERROR;\r
@@ -1001,10 +1008,13 @@ USBMassDriverBindingStop (
     // Uninstall Block I/O protocol from the device handle,\r
     // then call the transport protocol to stop itself.\r
     //\r
-    Status = gBS->UninstallProtocolInterface (\r
+    Status = gBS->UninstallMultipleProtocolInterfaces (\r
                     Controller,\r
                     &gEfiBlockIoProtocolGuid,\r
-                    &UsbMass->BlockIo\r
+                    &UsbMass->BlockIo,\r
+                    &gEfiDiskInfoProtocolGuid,\r
+                    &UsbMass->DiskInfo,\r
+                    NULL\r
                     );\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
@@ -1062,6 +1072,8 @@ USBMassDriverBindingStop (
                     UsbMass->DevicePath,\r
                     &gEfiBlockIoProtocolGuid,\r
                     &UsbMass->BlockIo,\r
+                    &gEfiDiskInfoProtocolGuid,\r
+                    &UsbMass->DiskInfo,\r
                     NULL\r
                     );\r
     \r