/** @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\r
-All rights reserved. This program and the accompanying materials\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
http://opensource.org/licenses/bsd-license.php\r
\r
**/\r
\r
-#include "UsbMassImpl.h"\r
+#include "UsbMass.h"\r
\r
#define USB_MASS_TRANSPORT_COUNT 3\r
//\r
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
}\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
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
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
}\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
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
{\r
EFI_BLOCK_IO_MEDIA *Media;\r
EFI_STATUS Status;\r
- UINTN Index;\r
\r
Media = &UsbMass->BlockIoMedia;\r
\r
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
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
UsbMass->DevicePath,\r
&gEfiBlockIoProtocolGuid,\r
&UsbMass->BlockIo,\r
+ &gEfiDiskInfoProtocolGuid,\r
+ &UsbMass->DiskInfo,\r
NULL\r
);\r
\r
UsbMass->DevicePath,\r
&gEfiBlockIoProtocolGuid,\r
&UsbMass->BlockIo,\r
+ &gEfiDiskInfoProtocolGuid,\r
+ &UsbMass->DiskInfo,\r
NULL\r
);\r
goto ON_ERROR;\r
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
UINT8 MaxLun;\r
EFI_STATUS Status;\r
EFI_USB_IO_PROTOCOL *UsbIo; \r
- \r
+ EFI_TPL OldTpl;\r
+\r
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
Transport = NULL;\r
Context = NULL;\r
MaxLun = 0;\r
\r
if (EFI_ERROR (Status)) {\r
DEBUG ((EFI_D_ERROR, "USBMassDriverBindingStart: UsbMassInitTransport (%r)\n", Status));\r
- return Status;\r
+ goto Exit;\r
}\r
if (MaxLun == 0) {\r
//\r
\r
if (EFI_ERROR (Status)) {\r
DEBUG ((EFI_D_ERROR, "USBMassDriverBindingStart: OpenDevicePathProtocol By Driver (%r)\n", Status));\r
- return Status;\r
+ goto Exit;\r
}\r
\r
Status = gBS->OpenProtocol (\r
This->DriverBindingHandle,\r
Controller\r
);\r
- return Status;\r
+ goto Exit;\r
}\r
\r
//\r
DEBUG ((EFI_D_ERROR, "USBMassDriverBindingStart: UsbMassInitMultiLun (%r) with Maxlun=%d\n", Status, MaxLun));\r
}\r
}\r
+Exit:\r
+ gBS->RestoreTPL (OldTpl);\r
return Status;\r
}\r
\r
// 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
UsbMass->DevicePath,\r
&gEfiBlockIoProtocolGuid,\r
&UsbMass->BlockIo,\r
+ &gEfiDiskInfoProtocolGuid,\r
+ &UsbMass->DiskInfo,\r
NULL\r
);\r
\r