]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdeBus.c
IntelFrameworkModulePkg: Clean up source files
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Pci / IdeBusDxe / IdeBus.c
index 224b2cac8dc0c7cd59d53782efe44887ad3860ad..6648dfd541a91c6c3197828552c1886f62facd8a 100644 (file)
@@ -1,10 +1,10 @@
 /** @file\r
-  This file implement UEFI driver for IDE Bus which includes device identification, \r
-  Child device(Disk, CDROM, etc) enumeration and child handler installation, and \r
+  This file implement UEFI driver for IDE Bus which includes device identification,\r
+  Child device(Disk, CDROM, etc) enumeration and child handler installation, and\r
   driver stop.\r
-    \r
-  Copyright (c) 2006 - 2008, Intel Corporation\r
-  All rights reserved. This program and the accompanying materials\r
+\r
+  Copyright (c) 2006 - 2018, 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
@@ -42,7 +42,7 @@ EFI_DRIVER_BINDING_PROTOCOL gIDEBusDriverBinding = {
   @param  Handle Handle of device to deregister driver on\r
 \r
   @retval EFI_SUCCESS  Deregiter a specific IDE device successfully\r
-  \r
+\r
 \r
 **/\r
 EFI_STATUS\r
@@ -148,27 +148,41 @@ IDEBusDriverBindingSupported (
   EFI_DEVICE_PATH_PROTOCOL          *ParentDevicePath;\r
   EFI_DEV_PATH                      *Node;\r
   EFI_IDE_CONTROLLER_INIT_PROTOCOL  *IdeInit;\r
+  EFI_PCI_IO_PROTOCOL               *PciIo;\r
+  PCI_TYPE00                        PciData;\r
 \r
   if (RemainingDevicePath != NULL) {\r
     Node = (EFI_DEV_PATH *) RemainingDevicePath;\r
-    if (Node->DevPath.Type != MESSAGING_DEVICE_PATH ||\r
-        Node->DevPath.SubType != MSG_ATAPI_DP ||\r
-        DevicePathNodeLength(&Node->DevPath) != sizeof(ATAPI_DEVICE_PATH)) {\r
-      return EFI_UNSUPPORTED;\r
+    //\r
+    // Check if RemainingDevicePath is the End of Device Path Node,\r
+    // if yes, go on checking other conditions\r
+    //\r
+    if (!IsDevicePathEnd (Node)) {\r
+      //\r
+      // If RemainingDevicePath isn't the End of Device Path Node,\r
+      // check its validation\r
+      //\r
+      if (Node->DevPath.Type != MESSAGING_DEVICE_PATH ||\r
+          Node->DevPath.SubType != MSG_ATAPI_DP ||\r
+          DevicePathNodeLength(&Node->DevPath) != sizeof(ATAPI_DEVICE_PATH)) {\r
+        return EFI_UNSUPPORTED;\r
+      }\r
     }\r
   }\r
 \r
   //\r
-  // Open the IO Abstraction(s) needed to perform the supported test\r
+  // Verify the Ide Controller Init Protocol, which installed by the\r
+  // IdeController module.\r
   //\r
   Status = gBS->OpenProtocol (\r
                   Controller,\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  (VOID **) &ParentDevicePath,\r
+                  &gEfiIdeControllerInitProtocolGuid,\r
+                  (VOID **) &IdeInit,\r
                   This->DriverBindingHandle,\r
                   Controller,\r
                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
                   );\r
+\r
   if (Status == EFI_ALREADY_STARTED) {\r
     return EFI_SUCCESS;\r
   }\r
@@ -178,46 +192,79 @@ IDEBusDriverBindingSupported (
   }\r
 \r
   //\r
-  // Close protocol, don't use device path protocol in the .Support() function\r
+  // Close the I/O Abstraction(s) used to perform the supported test\r
   //\r
   gBS->CloseProtocol (\r
         Controller,\r
-        &gEfiDevicePathProtocolGuid,\r
+        &gEfiIdeControllerInitProtocolGuid,\r
         This->DriverBindingHandle,\r
         Controller\r
         );\r
 \r
   //\r
-  // Verify the Ide Controller Init Protocol, which installed by the\r
-  // IdeController module.\r
-  // Note 1: PciIo protocol has been opened BY_DRIVER by ide_init, so We can't\r
-  //         open BY_DRIVER here) That's why we don't check pciio protocol\r
-  // Note 2: ide_init driver check ide controller's pci config space, so we dont\r
-  //         check here any more to save code size\r
+  // Open the EFI Device Path protocol needed to perform the supported test\r
   //\r
   Status = gBS->OpenProtocol (\r
                   Controller,\r
-                  &gEfiIdeControllerInitProtocolGuid,\r
-                  (VOID **) &IdeInit,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  (VOID **) &ParentDevicePath,\r
                   This->DriverBindingHandle,\r
                   Controller,\r
                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
                   );\r
-\r
   if (Status == EFI_ALREADY_STARTED) {\r
     return EFI_SUCCESS;\r
   }\r
 \r
   //\r
-  // If protocols were opened normally, closed it\r
+  // Close protocol, don't use device path protocol in the Support() function\r
   //\r
   gBS->CloseProtocol (\r
         Controller,\r
-        &gEfiIdeControllerInitProtocolGuid,\r
+        &gEfiDevicePathProtocolGuid,\r
         This->DriverBindingHandle,\r
         Controller\r
         );\r
 \r
+  //\r
+  // Get the EfiPciIoProtocol\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  Controller,\r
+                  &gEfiPciIoProtocolGuid,\r
+                  (VOID **) &PciIo,\r
+                  This->DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Now further check the PCI header: Base class (offset 0x0B) and\r
+  // Sub Class (offset 0x0A). This controller should be an IDE controller\r
+  //\r
+  Status = PciIo->Pci.Read (\r
+                        PciIo,\r
+                        EfiPciIoWidthUint8,\r
+                        0,\r
+                        sizeof (PciData),\r
+                        &PciData\r
+                        );\r
+\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // Examine if it is IDE mode by class code\r
+    //\r
+    if ((PciData.Hdr.ClassCode[2] != PCI_CLASS_MASS_STORAGE) || (PciData.Hdr.ClassCode[1] != PCI_SUB_CLASS_IDE)) {\r
+      Status = EFI_UNSUPPORTED;\r
+    } else {\r
+      Status = EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
   return Status;\r
 }\r
 \r
@@ -386,7 +433,7 @@ IDEBusDriverBindingStart (
                     &Supports\r
                     );\r
   if (!EFI_ERROR (Status)) {\r
-    Supports &= EFI_PCI_DEVICE_ENABLE;\r
+    Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;\r
     Status = PciIo->Attributes (\r
                       PciIo,\r
                       EfiPciIoAttributeOperationEnable,\r
@@ -415,28 +462,20 @@ IDEBusDriverBindingStart (
     ConfigurationOptions = 0x0f;\r
   }\r
 \r
-  if (EnumAll) {\r
+   if (EnumAll || RemainingDevicePath == NULL) {\r
     //\r
-    // If IdeInit->EnumAll is TRUE, must enumerate all IDE device anyway\r
+    // If IdeInit->EnumAll is TRUE or RemainingDevicePath is NULL,\r
+    // must enumerate all IDE devices anyway\r
     //\r
     BeginningIdeChannel = IdePrimary;\r
     EndIdeChannel       = IdeSecondary;\r
     BeginningIdeDevice  = IdeMaster;\r
     EndIdeDevice        = IdeSlave;\r
-  } else if (RemainingDevicePath == NULL) {\r
-    //\r
-    // RemainingDevicePath is NULL, scan IDE bus for each device;\r
-    //\r
-    BeginningIdeChannel = IdePrimary;\r
-    EndIdeChannel       = IdeSecondary;\r
-    BeginningIdeDevice  = IdeMaster;\r
-    //\r
-    // default, may be redefined by IdeInit\r
-    //\r
-    EndIdeDevice = IdeSlave;\r
-  } else {\r
+\r
+  } else if (!IsDevicePathEnd (RemainingDevicePath)) {\r
     //\r
-    // RemainingDevicePath is not NULL, only scan the specified device.\r
+    // If RemainingDevicePath isn't the End of Device Path Node,\r
+    // only scan the specified device by RemainingDevicePath\r
     //\r
     Node                = (EFI_DEV_PATH *) RemainingDevicePath;\r
     BeginningIdeChannel = Node->Atapi.PrimarySecondary;\r
@@ -451,6 +490,16 @@ IDEBusDriverBindingStart (
       Status = EFI_INVALID_PARAMETER;\r
       goto ErrorExit;\r
     }\r
+\r
+  } else {\r
+    //\r
+    // If RemainingDevicePath is the End of Device Path Node,\r
+    // skip enumerate any device and return EFI_SUCESSS\r
+    //\r
+    BeginningIdeChannel = IdeMaxChannel;\r
+    EndIdeChannel       = IdeMaxChannel - 1;\r
+    BeginningIdeDevice  = IdeMaxDevice;\r
+    EndIdeDevice        = IdeMaxDevice - 1;\r
   }\r
 \r
   //\r
@@ -608,9 +657,9 @@ IDEBusDriverBindingStart (
       //\r
       // Discover device, now!\r
       //\r
-      PERF_START (0, "DiscoverIdeDevice", "IDE", 0);\r
+      PERF_START (NULL, "DiscoverIdeDevice", "IDE", 0);\r
       Status = DiscoverIdeDevice (IdeBlkIoDevicePtr);\r
-      PERF_END (0, "DiscoverIdeDevice", "IDE", 0);\r
+      PERF_END (NULL, "DiscoverIdeDevice", "IDE", 0);\r
 \r
       IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice]  = TRUE;\r
       IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice]    = FALSE;\r
@@ -670,6 +719,7 @@ IDEBusDriverBindingStart (
     //\r
     for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) {\r
 \r
+      ASSERT (IdeChannel * 2 + IdeDevice < MAX_IDE_DEVICE);\r
       if (IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice]) {\r
         continue;\r
       }\r
@@ -689,6 +739,7 @@ IDEBusDriverBindingStart (
         continue;\r
       }\r
 \r
+      ASSERT (IdeChannel < IdeMaxChannel && IdeDevice < IdeMaxDevice);\r
       IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice];\r
 \r
       //\r
@@ -755,8 +806,8 @@ IDEBusDriverBindingStart (
       //\r
       // Init driver parameters\r
       //\r
-      DriveParameters.Sector          = (UINT8) IdeBlkIoDevicePtr->IdData->AtaData.sectors_per_track;\r
-      DriveParameters.Heads           = (UINT8) (IdeBlkIoDevicePtr->IdData->AtaData.heads - 1);\r
+      DriveParameters.Sector          = (UINT8) ((ATA5_IDENTIFY_DATA *) IdeBlkIoDevicePtr->IdData)->sectors_per_track;\r
+      DriveParameters.Heads           = (UINT8) (((ATA5_IDENTIFY_DATA *) IdeBlkIoDevicePtr->IdData)->heads - 1);\r
       DriveParameters.MultipleSector  = (UINT8) IdeBlkIoDevicePtr->IdData->AtaData.multi_sector_cmd_max_sct_cnt;\r
       //\r
       // Set Parameters for the device:\r
@@ -846,11 +897,11 @@ IDEBusDriverBindingStart (
   IdeInit->NotifyPhase (IdeInit, EfiIdeBusPhaseMaximum, 0);\r
 \r
   if (SupportedModes != NULL) {\r
-    gBS->FreePool (SupportedModes);\r
+    FreePool (SupportedModes);\r
   }\r
 \r
-  PERF_START (0, "Finish IDE detection", "IDE", 1);\r
-  PERF_END (0, "Finish IDE detection", "IDE", 0);\r
+  PERF_START (NULL, "Finish IDE detection", "IDE", 1);\r
+  PERF_END (NULL, "Finish IDE detection", "IDE", 0);\r
 \r
   return EFI_SUCCESS;\r
 \r
@@ -953,7 +1004,7 @@ IDEBusDriverBindingStop (
                         &Supports\r
                         );\r
       if (!EFI_ERROR (Status)) {\r
-        Supports &= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_DEVICE_ENABLE;\r
+        Supports &= (UINT64)(EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_DEVICE_ENABLE);\r
         PciIo->Attributes (\r
                 PciIo,\r
                 EfiPciIoAttributeOperationDisable,\r
@@ -1229,7 +1280,7 @@ Done:
 /**\r
   Flushes all modified data to a physical block devices\r
 \r
-  @param  This  Indicates a pointer to the calling context which to sepcify a \r
+  @param  This  Indicates a pointer to the calling context which to sepcify a\r
                 sepcific block device\r
 \r
   @retval EFI_SUCCESS   Always return success.\r
@@ -1247,7 +1298,7 @@ IDEBlkIoFlushBlocks (
 }\r
 \r
 /**\r
-  This function is used by the IDE bus driver to get inquiry data. \r
+  This function is used by the IDE bus driver to get inquiry data.\r
   Data format of Identify data is defined by the Interface GUID.\r
 \r
   @param  This                  Pointer to the EFI_DISK_INFO_PROTOCOL instance.\r
@@ -1255,9 +1306,9 @@ IDEBlkIoFlushBlocks (
   @param  InquiryDataSize       Pointer to the value for the inquiry data size.\r
 \r
   @retval EFI_SUCCESS           The command was accepted without any errors.\r
-  @retval EFI_NOT_FOUND         Device does not support this data class \r
-  @retval EFI_DEVICE_ERROR      Error reading InquiryData from device \r
-  @retval EFI_BUFFER_TOO_SMALL  IntquiryDataSize not big enough \r
+  @retval EFI_NOT_FOUND         Device does not support this data class\r
+  @retval EFI_DEVICE_ERROR      Error reading InquiryData from device\r
+  @retval EFI_BUFFER_TOO_SMALL  IntquiryDataSize not big enough\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1288,7 +1339,7 @@ IDEDiskInfoInquiry (
 }\r
 \r
 /**\r
-  This function is used by the IDE bus driver to get identify data. \r
+  This function is used by the IDE bus driver to get identify data.\r
   Data format of Identify data is defined by the Interface GUID.\r
 \r
   @param  This                  Pointer to the EFI_DISK_INFO_PROTOCOL instance.\r
@@ -1296,9 +1347,9 @@ IDEDiskInfoInquiry (
   @param  IdentifyDataSize      Pointer to the value for the identify data size.\r
 \r
   @retval EFI_SUCCESS           The command was accepted without any errors.\r
-  @retval EFI_NOT_FOUND         Device does not support this data class \r
-  @retval EFI_DEVICE_ERROR      Error reading IdentifyData from device \r
-  @retval EFI_BUFFER_TOO_SMALL  IdentifyDataSize not big enough \r
+  @retval EFI_NOT_FOUND         Device does not support this data class\r
+  @retval EFI_DEVICE_ERROR      Error reading IdentifyData from device\r
+  @retval EFI_BUFFER_TOO_SMALL  IdentifyDataSize not big enough\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1329,18 +1380,18 @@ IDEDiskInfoIdentify (
 }\r
 \r
 /**\r
-  This function is used by the IDE bus driver to get sense data. \r
+  This function is used by the IDE bus driver to get sense data.\r
   Data format of Sense data is defined by the Interface GUID.\r
 \r
-  @param  This                  Pointer to the EFI_DISK_INFO_PROTOCOL instance. \r
-  @param  SenseData             Pointer to the SenseData. \r
-  @param  SenseDataSize         Size of SenseData in bytes. \r
+  @param  This                  Pointer to the EFI_DISK_INFO_PROTOCOL instance.\r
+  @param  SenseData             Pointer to the SenseData.\r
+  @param  SenseDataSize         Size of SenseData in bytes.\r
   @param  SenseDataNumber       Pointer to the value for the identify data size.\r
 \r
   @retval EFI_SUCCESS           The command was accepted without any errors.\r
-  @retval EFI_NOT_FOUND         Device does not support this data class \r
-  @retval EFI_DEVICE_ERROR      Error reading InquiryData from device \r
-  @retval EFI_BUFFER_TOO_SMALL  SenseDataSize not big enough \r
+  @retval EFI_NOT_FOUND         Device does not support this data class\r
+  @retval EFI_DEVICE_ERROR      Error reading InquiryData from device\r
+  @retval EFI_BUFFER_TOO_SMALL  SenseDataSize not big enough\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1358,12 +1409,12 @@ IDEDiskInfoSenseData (
 /**\r
   This function is used by the IDE bus driver to get controller information.\r
 \r
-  @param  This                  Pointer to the EFI_DISK_INFO_PROTOCOL instance. \r
+  @param  This                  Pointer to the EFI_DISK_INFO_PROTOCOL instance.\r
   @param  IdeChannel            Pointer to the Ide Channel number. Primary or secondary.\r
   @param  IdeDevice             Pointer to the Ide Device number. Master or slave.\r
 \r
-  @retval EFI_SUCCESS           IdeChannel and IdeDevice are valid \r
-  @retval EFI_UNSUPPORTED       This is not an IDE device \r
+  @retval EFI_SUCCESS           IdeChannel and IdeDevice are valid\r
+  @retval EFI_UNSUPPORTED       This is not an IDE device\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1384,11 +1435,11 @@ IDEDiskInfoWhichIde (
 }\r
 \r
 /**\r
-  The is an event(generally the event is exitBootService event) call back function. \r
+  The is an event(generally the event is exitBootService event) call back function.\r
   Clear pending IDE interrupt before OS loader/kernel take control of the IDE device.\r
 \r
   @param  Event   Pointer to this event\r
-  @param  Context Event hanlder private data\r
+  @param  Context Event handler private data\r
 \r
 **/\r
 VOID\r
@@ -1424,7 +1475,7 @@ ClearInterrupt (
   // Reset IDE device to force it de-assert interrupt pin\r
   // Note: this will reset all devices on this IDE channel\r
   //\r
-  AtaSoftReset (IdeDev);\r
+  Status = AtaSoftReset (IdeDev);\r
   if (EFI_ERROR (Status)) {\r
     return;\r
   }\r
@@ -1483,9 +1534,9 @@ ClearInterrupt (
 /**\r
   The user Entry Point for module IdeBus. The user code starts with this function.\r
 \r
-  @param[in] ImageHandle    The firmware allocated handle for the EFI image.  \r
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.\r
   @param[in] SystemTable    A pointer to the EFI System Table.\r
-  \r
+\r
   @retval EFI_SUCCESS       The entry point is executed successfully.\r
   @retval other             Some error occurs when executing this entry point.\r
 \r