]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Bus / Ufs / UfsPassThruDxe / UfsPassThru.c
index bfba7aafe8543e8d7de264be7ed8d9473682b14b..1518b251d88a903ded02bf4d7fad1cfb313b2c46 100644 (file)
@@ -1,13 +1,7 @@
 /** @file\r
 \r
-  Copyright (c) 2014 - 2015, 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
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+  Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -18,7 +12,7 @@
 //\r
 UFS_PASS_THRU_PRIVATE_DATA gUfsPassThruTemplate = {\r
   UFS_PASS_THRU_SIG,              // Signature\r
-  NULL,                           // Handle  \r
+  NULL,                           // Handle\r
   {                               // ExtScsiPassThruMode\r
     0xFFFFFFFF,\r
     EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL | EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_NONBLOCKIO,\r
@@ -34,6 +28,11 @@ UFS_PASS_THRU_PRIVATE_DATA gUfsPassThruTemplate = {
     UfsPassThruResetTargetLun,\r
     UfsPassThruGetNextTarget\r
   },\r
+  {                               // UfsDevConfig\r
+    UfsRwUfsDescriptor,\r
+    UfsRwUfsFlag,\r
+    UfsRwUfsAttribute\r
+  },\r
   0,                              // UfsHostController\r
   0,                              // UfsHcBase\r
   0,                              // Capabilities\r
@@ -204,7 +203,7 @@ UfsPassThruPassThru (
     if ((Private->Luns.BitMask & (BIT0 << Index)) == 0) {\r
       continue;\r
     }\r
-  \r
+\r
     if (Private->Luns.Lun[Index] == UfsLun) {\r
       break;\r
     }\r
@@ -408,7 +407,7 @@ UfsPassThruBuildDevicePath (
     if ((Private->Luns.BitMask & (BIT0 << Index)) == 0) {\r
       continue;\r
     }\r
-  \r
+\r
     if (Private->Luns.Lun[Index] == UfsLun) {\r
       break;\r
     }\r
@@ -479,10 +478,10 @@ UfsPassThruGetTargetLun (
   }\r
 \r
   //\r
-  // Check whether the DevicePath belongs to SCSI_DEVICE_PATH\r
+  // Check whether the DevicePath belongs to UFS_DEVICE_PATH\r
   //\r
   if ((DevicePath->Type != MESSAGING_DEVICE_PATH) || (DevicePath->SubType != MSG_UFS_DP) ||\r
-      (DevicePathNodeLength(DevicePath) != sizeof(SCSI_DEVICE_PATH))) {\r
+      (DevicePathNodeLength(DevicePath) != sizeof(UFS_DEVICE_PATH))) {\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
@@ -499,7 +498,7 @@ UfsPassThruGetTargetLun (
     if ((Private->Luns.BitMask & (BIT0 << Index)) == 0) {\r
       continue;\r
     }\r
-  \r
+\r
     if (Private->Luns.Lun[Index] == UfsLun) {\r
       break;\r
     }\r
@@ -605,10 +604,6 @@ UfsPassThruGetNextTarget (
   IN OUT UINT8                           **Target\r
   )\r
 {\r
-  UFS_PASS_THRU_PRIVATE_DATA      *Private;\r
-\r
-  Private = UFS_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);\r
-\r
   if (Target == NULL || *Target == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
@@ -729,7 +724,49 @@ UfsPassThruDriverBindingSupported (
         This->DriverBindingHandle,\r
         Controller\r
         );\r
-        \r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Finishes device initialization by setting fDeviceInit flag and waiting untill device responds by\r
+  clearing it.\r
+\r
+  @param[in] Private  Pointer to the UFS_PASS_THRU_PRIVATE_DATA.\r
+\r
+  @retval EFI_SUCCESS  The operation succeeds.\r
+  @retval Others       The operation fails.\r
+\r
+**/\r
+EFI_STATUS\r
+UfsFinishDeviceInitialization (\r
+  IN UFS_PASS_THRU_PRIVATE_DATA  *Private\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT8  DeviceInitStatus;\r
+  UINT8  Timeout;\r
+\r
+  DeviceInitStatus = 0xFF;\r
+\r
+  //\r
+  // The host enables the device initialization completion by setting fDeviceInit flag.\r
+  //\r
+  Status = UfsSetFlag (Private, UfsFlagDevInit);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Timeout = 5;\r
+  do {\r
+    Status = UfsReadFlag (Private, UfsFlagDevInit, &DeviceInitStatus);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+    MicroSecondDelay (1);\r
+    Timeout--;\r
+  } while (DeviceInitStatus != 0 && Timeout != 0);\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -781,14 +818,15 @@ UfsPassThruDriverBindingStart (
   UFS_PASS_THRU_PRIVATE_DATA            *Private;\r
   UINTN                                 UfsHcBase;\r
   UINT32                                Index;\r
-  UFS_CONFIG_DESC                       Config;\r
+  UFS_UNIT_DESC                         UnitDescriptor;\r
+  UINT32                                UnitDescriptorSize;\r
 \r
   Status    = EFI_SUCCESS;\r
   UfsHc     = NULL;\r
   Private   = NULL;\r
   UfsHcBase = 0;\r
 \r
-  DEBUG ((EFI_D_INFO, "==UfsPassThru Start== Controller = %x\n", Controller));\r
+  DEBUG ((DEBUG_INFO, "==UfsPassThru Start== Controller = %x\n", Controller));\r
 \r
   Status  = gBS->OpenProtocol (\r
                    Controller,\r
@@ -800,7 +838,7 @@ UfsPassThruDriverBindingStart (
                    );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "Open Ufs Host Controller Protocol Error, Status = %r\n", Status));\r
+    DEBUG ((DEBUG_ERROR, "Open Ufs Host Controller Protocol Error, Status = %r\n", Status));\r
     goto Error;\r
   }\r
 \r
@@ -809,7 +847,7 @@ UfsPassThruDriverBindingStart (
   //\r
   Status = UfsHc->GetUfsHcMmioBar (UfsHc, &UfsHcBase);\r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "Get Ufs Host Controller Mmio Bar Error, Status = %r\n", Status));\r
+    DEBUG ((DEBUG_ERROR, "Get Ufs Host Controller Mmio Bar Error, Status = %r\n", Status));\r
     goto Error;\r
   }\r
 \r
@@ -818,7 +856,7 @@ UfsPassThruDriverBindingStart (
   //\r
   Private = AllocateCopyPool (sizeof (UFS_PASS_THRU_PRIVATE_DATA), &gUfsPassThruTemplate);\r
   if (Private == NULL) {\r
-    DEBUG ((EFI_D_ERROR, "Unable to allocate Ufs Pass Thru private data\n"));\r
+    DEBUG ((DEBUG_ERROR, "Unable to allocate Ufs Pass Thru private data\n"));\r
     Status = EFI_OUT_OF_RESOURCES;\r
     goto Error;\r
   }\r
@@ -833,36 +871,24 @@ UfsPassThruDriverBindingStart (
   //\r
   Status = UfsControllerInit (Private);\r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "Ufs Host Controller Initialization Error, Status = %r\n", Status));\r
+    DEBUG ((DEBUG_ERROR, "Ufs Host Controller Initialization Error, Status = %r\n", Status));\r
     goto Error;\r
   }\r
 \r
   //\r
   // UFS 2.0 spec Section 13.1.3.3:\r
-  // At the end of the UFS Interconnect Layer initialization on both host and device side, \r
-  // the host shall send a NOP OUT UPIU to verify that the device UTP Layer is ready. \r
+  // At the end of the UFS Interconnect Layer initialization on both host and device side,\r
+  // the host shall send a NOP OUT UPIU to verify that the device UTP Layer is ready.\r
   //\r
   Status = UfsExecNopCmds (Private);\r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "Ufs Sending NOP IN command Error, Status = %r\n", Status));\r
-    goto Error;\r
-  }\r
-\r
-  //\r
-  // The host enables the device initialization completion by setting fDeviceInit flag.\r
-  //\r
-  Status = UfsSetFlag (Private, UfsFlagDevInit);\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "Ufs Set fDeviceInit Flag Error, Status = %r\n", Status));\r
+    DEBUG ((DEBUG_ERROR, "Ufs Sending NOP IN command Error, Status = %r\n", Status));\r
     goto Error;\r
   }\r
 \r
-  //\r
-  // Get Ufs Device's Lun Info by reading Configuration Descriptor.\r
-  //\r
-  Status = UfsRwDeviceDesc (Private, TRUE, UfsConfigDesc, 0, 0, &Config, sizeof (UFS_CONFIG_DESC));\r
+  Status = UfsFinishDeviceInitialization (Private);\r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "Ufs Get Configuration Descriptor Error, Status = %r\n", Status));\r
+    DEBUG ((DEBUG_ERROR, "Device failed to finish initialization, Status = %r\n", Status));\r
     goto Error;\r
   }\r
 \r
@@ -870,10 +896,16 @@ UfsPassThruDriverBindingStart (
   // Check if 8 common luns are active and set corresponding bit mask.\r
   // TODO: Parse device descriptor to decide if exposing RPMB LUN to upper layer for authentication access.\r
   //\r
+  UnitDescriptorSize = sizeof (UFS_UNIT_DESC);\r
   for (Index = 0; Index < 8; Index++) {\r
-    if (Config.UnitDescConfParams[Index].LunEn != 0) {\r
+    Status = UfsRwDeviceDesc (Private, TRUE, UfsUnitDesc, (UINT8) Index, 0, &UnitDescriptor, &UnitDescriptorSize);\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((DEBUG_ERROR, "Failed to read unit descriptor, index = %X, status = %r\n", Index, Status));\r
+      continue;\r
+    }\r
+    if (UnitDescriptor.LunEn == 0x1) {\r
+      DEBUG ((DEBUG_INFO, "UFS LUN %X is enabled\n", Index));\r
       Private->Luns.BitMask |= (BIT0 << Index);\r
-      DEBUG ((EFI_D_INFO, "Ufs Lun %d is enabled\n", Index));\r
     }\r
   }\r
 \r
@@ -888,7 +920,7 @@ UfsPassThruDriverBindingStart (
                   &Private->TimerEvent\r
                   );\r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "Ufs Create Async Tasks Event Error, Status = %r\n", Status));\r
+    DEBUG ((DEBUG_ERROR, "Ufs Create Async Tasks Event Error, Status = %r\n", Status));\r
     goto Error;\r
   }\r
 \r
@@ -898,15 +930,17 @@ UfsPassThruDriverBindingStart (
                   UFS_HC_ASYNC_TIMER\r
                   );\r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "Ufs Set Periodic Timer Error, Status = %r\n", Status));\r
+    DEBUG ((DEBUG_ERROR, "Ufs Set Periodic Timer Error, Status = %r\n", Status));\r
     goto Error;\r
   }\r
 \r
-  Status = gBS->InstallProtocolInterface (\r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
                   &Controller,\r
                   &gEfiExtScsiPassThruProtocolGuid,\r
-                  EFI_NATIVE_INTERFACE,\r
-                  &(Private->ExtScsiPassThru)\r
+                  &(Private->ExtScsiPassThru),\r
+                  &gEfiUfsDeviceConfigProtocolGuid,\r
+                  &(Private->UfsDevConfig),\r
+                  NULL\r
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
@@ -915,7 +949,7 @@ UfsPassThruDriverBindingStart (
 Error:\r
   if (Private != NULL) {\r
     if (Private->TmrlMapping != NULL) {\r
-      UfsHc->Unmap (UfsHc, Private->TmrlMapping);  \r
+      UfsHc->Unmap (UfsHc, Private->TmrlMapping);\r
     }\r
     if (Private->UtpTmrlBase != NULL) {\r
       UfsHc->FreeBuffer (UfsHc, EFI_SIZE_TO_PAGES (Private->Nutmrs * sizeof (UTP_TMRD)), Private->UtpTmrlBase);\r
@@ -990,7 +1024,7 @@ UfsPassThruDriverBindingStop (
   LIST_ENTRY                            *Entry;\r
   LIST_ENTRY                            *NextEntry;\r
 \r
-  DEBUG ((EFI_D_INFO, "==UfsPassThru Stop== Controller Controller = %x\n", Controller));\r
+  DEBUG ((DEBUG_INFO, "==UfsPassThru Stop== Controller Controller = %x\n", Controller));\r
 \r
   Status = gBS->OpenProtocol (\r
                   Controller,\r
@@ -1026,10 +1060,13 @@ UfsPassThruDriverBindingStop (
     }\r
   }\r
 \r
-  Status = gBS->UninstallProtocolInterface (\r
+  Status = gBS->UninstallMultipleProtocolInterfaces (\r
                   Controller,\r
                   &gEfiExtScsiPassThruProtocolGuid,\r
-                  &(Private->ExtScsiPassThru)\r
+                  &(Private->ExtScsiPassThru),\r
+                  &gEfiUfsDeviceConfigProtocolGuid,\r
+                  &(Private->UfsDevConfig),\r
+                  NULL\r
                   );\r
 \r
   if (EFI_ERROR (Status)) {\r