Exemplo n.º 1
0
/**
  Install EFI_ISA_ACPI_PROTOCOL.

  @param  This                 Driver Binding protocol instance pointer.
  @param  ControllerHandle     Handle of device to bind driver to.
  @param  RemainingDevicePath  Optional parameter use to pick a specific child
                               device to start.

  @retval EFI_SUCCESS          This driver is added to ControllerHandle
  @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle
  @retval other                This driver does not support this device
**/
EFI_STATUS
EFIAPI
PcatIsaAcpiDriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   Controller,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  EFI_STATUS           Status;
  EFI_PCI_IO_PROTOCOL  *PciIo;
  PCAT_ISA_ACPI_DEV    *PcatIsaAcpiDev;
  UINT64               Supports;
  BOOLEAN              Enabled;

  Enabled = FALSE;
  Supports = 0;
  PcatIsaAcpiDev = NULL;
  //
  // Open the PCI I/O Protocol Interface
  //
  PciIo = NULL;
  Status = gBS->OpenProtocol (
                  Controller,       
                  &gEfiPciIoProtocolGuid, 
                  (VOID**)&PciIo,
                  This->DriverBindingHandle,   
                  Controller,   
                  EFI_OPEN_PROTOCOL_BY_DRIVER 
                  );
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  //
  // Get supported PCI attributes
  //
  Status = PciIo->Attributes (
                    PciIo,
                    EfiPciIoAttributeOperationSupported,
                    0,
                    &Supports
                    );
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  Supports &= (EFI_PCI_IO_ATTRIBUTE_ISA_IO | EFI_PCI_IO_ATTRIBUTE_ISA_IO_16);
  if (Supports == 0 || Supports == (EFI_PCI_IO_ATTRIBUTE_ISA_IO | EFI_PCI_IO_ATTRIBUTE_ISA_IO_16)) {
    Status = EFI_UNSUPPORTED;
    goto Done;
  }  

  Enabled = TRUE;
  Status = PciIo->Attributes (
                    PciIo, 
                    EfiPciIoAttributeOperationEnable, 
                    EFI_PCI_DEVICE_ENABLE | Supports | EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO, 
                    NULL 
                    );
  if (EFI_ERROR (Status)) {
    goto Done;
  }
  
  //
  // Allocate memory for the PCAT ISA ACPI Device structure
  //
  PcatIsaAcpiDev = NULL;
  Status = gBS->AllocatePool (
                  EfiBootServicesData,
                  sizeof(PCAT_ISA_ACPI_DEV),
                  (VOID**)&PcatIsaAcpiDev
                  );
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  //
  // Initialize the PCAT ISA ACPI Device structure
  //
  PcatIsaAcpiDev->Signature = PCAT_ISA_ACPI_DEV_SIGNATURE;
  PcatIsaAcpiDev->Handle    = Controller;
  PcatIsaAcpiDev->PciIo     = PciIo;

  //
  // Initialize PcatIsaAcpiDeviceList
  //
  InitializePcatIsaAcpiDeviceList ();
  
  //
  // IsaAcpi interface
  //
  (PcatIsaAcpiDev->IsaAcpi).DeviceEnumerate  = IsaDeviceEnumerate;
  (PcatIsaAcpiDev->IsaAcpi).SetPower         = IsaDeviceSetPower;
  (PcatIsaAcpiDev->IsaAcpi).GetCurResource   = IsaGetCurrentResource;
  (PcatIsaAcpiDev->IsaAcpi).GetPosResource   = IsaGetPossibleResource;
  (PcatIsaAcpiDev->IsaAcpi).SetResource      = IsaSetResource;
  (PcatIsaAcpiDev->IsaAcpi).EnableDevice     = IsaEnableDevice;
  (PcatIsaAcpiDev->IsaAcpi).InitDevice       = IsaInitDevice;
  (PcatIsaAcpiDev->IsaAcpi).InterfaceInit    = IsaInterfaceInit;
    
  //
  // Install the ISA ACPI Protocol interface
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Controller,
                  &gEfiIsaAcpiProtocolGuid, &PcatIsaAcpiDev->IsaAcpi,
                  NULL
                  );

Done:
  if (EFI_ERROR (Status)) {
    if (PciIo != NULL && Enabled) {
      PciIo->Attributes (
               PciIo, 
               EfiPciIoAttributeOperationDisable, 
               EFI_PCI_DEVICE_ENABLE | Supports | EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO,
               NULL 
               );
    }
    gBS->CloseProtocol (
           Controller, 
           &gEfiPciIoProtocolGuid, 
           This->DriverBindingHandle, 
           Controller
           );
    if (PcatIsaAcpiDev != NULL) {
      gBS->FreePool (PcatIsaAcpiDev);
    }
    return Status;
  }
          
  return EFI_SUCCESS;
}
Exemplo n.º 2
0
/**
  Starts the device with this driver.

  @param  This                   The driver binding instance.
  @param  Controller             Handle of device to bind driver to.
  @param  RemainingDevicePath    Optional parameter use to pick a specific child
                                 device to start.

  @retval EFI_SUCCESS            The controller is controlled by the driver.
  @retval Other                  This controller cannot be started.

**/
EFI_STATUS
EFIAPI
BiosBlockIoDriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   Controller,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  EFI_STATUS                Status;
//  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;
  EFI_PCI_IO_PROTOCOL       *PciIo;
  UINT8                     DiskStart = 0x80;
  UINT8                     DiskEnd = 0xFF;
  BIOS_BLOCK_IO_DEV         *BiosBlockIoPrivate;
  EFI_DEVICE_PATH_PROTOCOL  *PciDevPath;
  UINTN                     Index;
//  UINTN                     Flags;
  UINTN                     TmpAddress;
  BOOLEAN                   DeviceEnable;

  //
  // Initialize variables
  //
  PciIo      = NULL;
  PciDevPath = NULL;
  
  DeviceEnable = FALSE; 

  //
  // See if the Legacy BIOS Protocol is available
  //
/*  Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);
  if (EFI_ERROR (Status)) {
    goto Error;
  } */
  if (mLegacy8259 == NULL) {
		Status = gBS->LocateProtocol (&gEfiLegacy8259ProtocolGuid, NULL, (VOID **) &mLegacy8259);
		if (EFI_ERROR (Status)) {
			goto Error;
		}
		
		InitializeBiosIntCaller(&mThunkContext);
		InitializeInterruptRedirection(mLegacy8259);
	}

  //
  // Open the IO Abstraction(s) needed
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiPciIoProtocolGuid,
                  (VOID **) &PciIo,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    goto Error;
  }

  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **) &PciDevPath,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );

  if (EFI_ERROR (Status)) {
    goto Error;
  }
  //
  // Enable the device and make sure VGA cycles are being forwarded to this VGA device
  //
  Status = PciIo->Attributes (
                    PciIo,
                    EfiPciIoAttributeOperationEnable,
                    EFI_PCI_DEVICE_ENABLE,
                    NULL
                    );
  if (EFI_ERROR (Status)) {
    goto Error;
  }
  
  DeviceEnable = TRUE;
  
  //
  // Check to see if there is a legacy option ROM image associated with this PCI device
  //
  //Slice - something for replacement?
/*  Status = LegacyBios->CheckPciRom (
                        LegacyBios,
                        Controller,
                        NULL,
                        NULL,
                        &Flags
                        );
  if (EFI_ERROR (Status)) {
    goto Error;
  }
  //
  // Post the legacy option ROM if it is available.
  //
  Status = LegacyBios->InstallPciRom (
                        LegacyBios,
                        Controller,
                        NULL,
                        &Flags,
                        &DiskStart,
                        &DiskEnd,
                        NULL,
                        NULL
                        );
  if (EFI_ERROR (Status)) {
    goto Error;
  }
 */
  
  //
  // All instances share a buffer under 1MB to put real mode thunk code in
  // If it has not been allocated, then we allocate it.
  //
  if (mBufferUnder1Mb == 0) {
    //
    // Should only be here if there are no active instances
    //
//    ASSERT (mActiveInstances == 0);
    if (mActiveInstances) {
      Status = EFI_OUT_OF_RESOURCES;
      goto Error;
    }
    //
    // Acquire the lock
    //
    EfiAcquireLock (&mGlobalDataLock);

    //
    // Allocate below 1MB
    //
    mBufferUnder1Mb = 0x00000000000FFFFF;
    Status          = gBS->AllocatePages (AllocateMaxAddress, EfiBootServicesData, BLOCK_IO_BUFFER_PAGE_SIZE, &mBufferUnder1Mb);

    //
    // Release the lock
    //
    EfiReleaseLock (&mGlobalDataLock);

    //
    // Check memory allocation success
    //
    if (EFI_ERROR (Status)) {
      //
      // In checked builds we want to assert if the allocate failed.
      //
   //   ASSERT_EFI_ERROR (Status);
      Status          = EFI_OUT_OF_RESOURCES;
      mBufferUnder1Mb = 0;
      goto Error;
    }

    TmpAddress = (UINTN) mBufferUnder1Mb;
    //
    // Adjusting the value to be on proper boundary
    //
    mEdd11Buffer = (VOID *) ALIGN_VARIABLE (TmpAddress);

    TmpAddress   = (UINTN) mEdd11Buffer + MAX_EDD11_XFER;
    //
    // Adjusting the value to be on proper boundary
    //
    mLegacyDriverUnder1Mb = (BIOS_LEGACY_DRIVE *) ALIGN_VARIABLE (TmpAddress);

    TmpAddress = (UINTN) mLegacyDriverUnder1Mb + sizeof (BIOS_LEGACY_DRIVE);
    //
    // Adjusting the value to be on proper boundary
    //
    mEddBufferUnder1Mb = (EDD_DEVICE_ADDRESS_PACKET *) ALIGN_VARIABLE (TmpAddress);
  }
  //
  // Allocate the private device structure for each disk
  //
  for (Index = DiskStart; Index <= DiskEnd; Index++) {

    Status = gBS->AllocatePool (
                    EfiBootServicesData,
                    sizeof (BIOS_BLOCK_IO_DEV),
                    (VOID **) &BiosBlockIoPrivate
                    );
    if (EFI_ERROR (Status)) {
      goto Error;
    }
    //
    // Zero the private device structure
    //
    ZeroMem (BiosBlockIoPrivate, sizeof (BIOS_BLOCK_IO_DEV));

    //
    // Initialize the private device structure
    //
    BiosBlockIoPrivate->Signature                 = BIOS_CONSOLE_BLOCK_IO_DEV_SIGNATURE;
    BiosBlockIoPrivate->ControllerHandle          = Controller;
 //   BiosBlockIoPrivate->LegacyBios                = LegacyBios;
    BiosBlockIoPrivate->Legacy8259   = mLegacy8259;
    BiosBlockIoPrivate->ThunkContext = &mThunkContext;
    

    BiosBlockIoPrivate->PciIo                     = PciIo;

    BiosBlockIoPrivate->Bios.Floppy               = FALSE;
    BiosBlockIoPrivate->Bios.Number               = (UINT8) Index;
    BiosBlockIoPrivate->Bios.Letter               = (UINT8) (Index - 0x80 + 'C');
    BiosBlockIoPrivate->BlockMedia.RemovableMedia = FALSE;

    if (BiosInitBlockIo (BiosBlockIoPrivate)) {
      SetBiosInitBlockIoDevicePath (PciDevPath, &BiosBlockIoPrivate->Bios, &BiosBlockIoPrivate->DevicePath);

      //
      // Install the Block Io Protocol onto a new child handle
      //
      Status = gBS->InstallMultipleProtocolInterfaces (
                      &BiosBlockIoPrivate->Handle,
                      &gEfiBlockIoProtocolGuid,
                      &BiosBlockIoPrivate->BlockIo,
                      &gEfiDevicePathProtocolGuid,
                      BiosBlockIoPrivate->DevicePath,
                      NULL
                      );
      if (EFI_ERROR (Status)) {
        gBS->FreePool (BiosBlockIoPrivate);
      }
      //
      // Open For Child Device
      //
      Status = gBS->OpenProtocol (
                      Controller,
                      &gEfiPciIoProtocolGuid,
                      (VOID **) &BiosBlockIoPrivate->PciIo,
                      This->DriverBindingHandle,
                      BiosBlockIoPrivate->Handle,
                      EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                      );

    } else {
      gBS->FreePool (BiosBlockIoPrivate);
    }
  }
  
  mBiosDrivesEnumerated = TRUE;

Error:
  if (EFI_ERROR (Status)) {
    if (PciIo != NULL) {
      if (DeviceEnable) {
        PciIo->Attributes (
                PciIo,
                EfiPciIoAttributeOperationDisable,
                EFI_PCI_DEVICE_ENABLE,
                NULL
                );
      }
      gBS->CloseProtocol (
            Controller,
            &gEfiPciIoProtocolGuid,
            This->DriverBindingHandle,
            Controller
            );
      if (PciDevPath != NULL) {
        gBS->CloseProtocol (
              Controller,
              &gEfiDevicePathProtocolGuid,
              This->DriverBindingHandle,
              Controller
              );
      }
      if (mBufferUnder1Mb != 0 && mActiveInstances == 0) {
        gBS->FreePages (mBufferUnder1Mb, BLOCK_IO_BUFFER_PAGE_SIZE);

        //
        // Clear the buffer back to 0
        //
        EfiAcquireLock (&mGlobalDataLock);
        mBufferUnder1Mb = 0;
        EfiReleaseLock (&mGlobalDataLock);
      }
    }
  } else {
    //
    // Successfully installed, so increment the number of active instances
    //
    EfiAcquireLock (&mGlobalDataLock);
    mActiveInstances++;
    EfiReleaseLock (&mGlobalDataLock);
  }

  return Status;
}
Exemplo n.º 3
0
//
//TDS 4.3.1
//
EFI_STATUS
Attributes_Stress (
  IN EFI_BB_TEST_PROTOCOL       *This,
  IN VOID                       *ClientInterface,
  IN EFI_TEST_LEVEL             TestLevel,
  IN EFI_HANDLE                 SupportHandle
  )
{
  EFI_STATUS                            Status;
  EFI_STATUS                            Status1;
  PCI_IO_PROTOCOL_DEVICE                *PciIoDevice;
  EFI_PCI_IO_PROTOCOL                   *PciIo;
  EFI_STANDARD_TEST_LIBRARY_PROTOCOL    *StandardLib;
  EFI_TEST_ASSERTION                    AssertionType;
  UINT64                                SupportedAttributes;
  UINT64                                CurrentAttributes;
  UINT64                                OriginalAttributes;
  UINT64                                CommonAttributes;
  UINTN                                 Index;
  UINTN                                 PciIoAttributesNumber;
  UINT64                                ThisAttribute;
  CHAR16                               *DevicePathStr;



  //
  //get tested interface.
  //
  PciIo = (EFI_PCI_IO_PROTOCOL *)ClientInterface;

  //
  // Get the Standard Library Interface
  //
  Status = gtBS->HandleProtocol (
                   SupportHandle,
                   &gEfiStandardTestLibraryGuid,
                   &StandardLib
                   );

  if (EFI_ERROR(Status)) {
    return Status;
  }

  InitializeCaseEnvironment ();

  //
  //get PciIoDevice struct pointer.
  //
  PciIoDevice = NULL;
  PciIoDevice = GetPciIoDevice (PciIo);
  if (PciIoDevice == NULL) {
    return EFI_ABORTED;
  }
  //
  //print the device path of pci device.
  //
//  Status = PrintPciIoDevice (PciIoDevice->DevicePath);
//  if (EFI_ERROR(Status)) {
//    return Status;
//  }


  DevicePathStr = DevicePathToStr (PciIoDevice->DevicePath);
  if (DevicePathStr == NULL) {
    StandardLib->RecordMessage (
                   StandardLib,
                   EFI_VERBOSE_LEVEL_DEFAULT,
                   L"\r\nCannot get DevicePath"
                   );
  } else {
    StandardLib->RecordMessage (
                   StandardLib,
                   EFI_VERBOSE_LEVEL_DEFAULT,
                   L"\r\nCurrent Device: %s",
                   DevicePathStr
                   );
    gtBS->FreePool (DevicePathStr);
  }
  //
  //call Attributes with operation EfiPciIoAttributeOperationGet to
  //get current attributes.
  //
  PciIo->Attributes (
           PciIo,
           EfiPciIoAttributeOperationGet,
           0,
           &OriginalAttributes
           );

  //
  //call Attribtes with operation EfiPciIoAttributeOperationSupported to
  //get the supported attributes of the pci controller.
  //

  PciIo->Attributes (
           PciIo,
           EfiPciIoAttributeOperationSupported,
           0,
           &SupportedAttributes
           );

  //
  //for each pci io attributes call Attributes with EfiPciIoAttributeOperationSet
  //
  PciIoAttributesNumber = 19;
  for (Index = 0; Index < PciIoAttributesNumber; Index++) {

    //
    //first get current attributes.
    //
    PciIo->Attributes (
             PciIo,
             EfiPciIoAttributeOperationGet,
             0,
             &CurrentAttributes
             );

    ThisAttribute = 1 << Index;

    Status = PciIo->Attributes (
                      PciIo,
                      EfiPciIoAttributeOperationSet,
                      ThisAttribute,
                      NULL
                      );

    //
    //get current attributes after Call Set
    //
    PciIo->Attributes (
             PciIo,
             EfiPciIoAttributeOperationGet,
             0,
             &CommonAttributes
             );

    //
    //call Attributes to set the orininal value before output to console
    //
    Status1 =  PciIo->Attributes (
                        PciIo,
                        EfiPciIoAttributeOperationSet,
                        OriginalAttributes,
                        NULL
                        );

    if (EFI_ERROR(Status1)) {
      AssertionType = EFI_TEST_ASSERTION_FAILED;
      //
      //record assertion
      //
      StandardLib->RecordAssertion (
                     StandardLib,
                     AssertionType,
                     gPciIoBBTestStressAssertionGuid017,
                     L"EFI_PCI_IO_PROTOCOL.Attributes - Set Original Supported attribute the Status Must be EFI_SUCCESS",
                     L"%a:%d:Status - %r",
                     __FILE__,
                     __LINE__,
                     Status1
                     );
      return Status1;
    } else {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    }

    if (ThisAttribute & SupportedAttributes) {
      if (!EFI_ERROR(Status) || (Status == EFI_UNSUPPORTED)) {
        AssertionType = EFI_TEST_ASSERTION_PASSED;
      } else {
        AssertionType = EFI_TEST_ASSERTION_FAILED;
      }
      //
      //record assertion
      //
      StandardLib->RecordAssertion (
                     StandardLib,
                     AssertionType,
                     gPciIoBBTestStressAssertionGuid001,
                     L"EFI_PCI_IO_PROTOCOL.Attributes - Set Supported attribute status must be EFI_SUCCESS or EFI_UNSUPPORTED.",
                     L"%a:%d:Status - %r, Set Attributes - %lXh, Supported Attributes - %lXh",
                     __FILE__,
                     __LINE__,
                     Status,
                     ThisAttribute,
                     SupportedAttributes
                     );

      if (!EFI_ERROR(Status)) {
        //
        //verify the attributes was really set.
        //
        if (CommonAttributes == ThisAttribute) {
          AssertionType = EFI_TEST_ASSERTION_PASSED;
        } else {
          AssertionType = EFI_TEST_ASSERTION_FAILED;
        }

        //
        //record assertion
        //
        StandardLib->RecordAssertion (
                       StandardLib,
                       AssertionType,
                       gPciIoBBTestStressAssertionGuid002,
                       L"EFI_PCI_IO_PROTOCOL.Attributes - Supported attribute are really set",
                       L"%a:%d:Set Attributes - %lXh, Supported Attributes - %lXh, Original Attribute - %lXh, Current Attributes - %lXh",
                       __FILE__,
                       __LINE__,
                       ThisAttribute,
                       SupportedAttributes,
                       CurrentAttributes,
                       CommonAttributes
                       );
      }
    } else {
      //
      //unsupported attributes.
      //
      if (Status == EFI_UNSUPPORTED) {
        AssertionType = EFI_TEST_ASSERTION_PASSED;
      } else {
        AssertionType = EFI_TEST_ASSERTION_FAILED;
      }

      //
      //record assertion
      //
      StandardLib->RecordAssertion (
                     StandardLib,
                     AssertionType,
                     gPciIoBBTestStressAssertionGuid003,
                     L"EFI_PCI_IO_PROTOCOL.Attributes - Set UnSupported attribute status must be EFI_UNSUPPORTED",
                     L"%a:%d:Status - %r",
                     __FILE__,
                     __LINE__,
                     Status
                     );

      //
      //verify the attributes remain unchanged
      //
      if (CommonAttributes == CurrentAttributes) {
        AssertionType = EFI_TEST_ASSERTION_PASSED;
      } else {
        AssertionType = EFI_TEST_ASSERTION_FAILED;
      }

      //
      //record assertion
      //
      StandardLib->RecordAssertion (
                     StandardLib,
                     AssertionType,
                     gPciIoBBTestStressAssertionGuid004,
                     L"EFI_PCI_IO_PROTOCOL.Attributes - set UnSupported attribute the Attributes can not been changed",
                     L"%a:%d:Set Attributes - %lXh, Supported Attributes - %lXh, Original Attribute - %lXh, Current Attributes - %lXh",
                     __FILE__,
                     __LINE__,
                     ThisAttribute,
                     SupportedAttributes,
                     CurrentAttributes,
                     CommonAttributes
                     );

    }
  }

  //
  //call Attributes to set the orininal value
  //
  Status =  PciIo->Attributes (
                     PciIo,
                     EfiPciIoAttributeOperationSet,
                     OriginalAttributes,
                     NULL
                     );

  if (!EFI_ERROR(Status)) {
    AssertionType = EFI_TEST_ASSERTION_PASSED;
  } else {
    AssertionType = EFI_TEST_ASSERTION_FAILED;
  }

  //
  //record assertion
  //
  StandardLib->RecordAssertion (
                 StandardLib,
                 AssertionType,
                 gPciIoBBTestStressAssertionGuid005,
                 L"EFI_PCI_IO_PROTOCOL.Attributes - Set Original Supported attribute the Status Must be EFI_SUCCESS",
                 L"%a:%d:Status - %r",
                 __FILE__,
                 __LINE__,
                 Status
                 );
  //
  //call get attributes to verify.
  //
  PciIo->Attributes (
           PciIo,
           EfiPciIoAttributeOperationGet,
           0,
           &CommonAttributes
           );

  if (CommonAttributes == OriginalAttributes) {
    AssertionType = EFI_TEST_ASSERTION_PASSED;
  } else {
    AssertionType = EFI_TEST_ASSERTION_FAILED;
  }

  //
  //record assertion
  //
  StandardLib->RecordAssertion (
                 StandardLib,
                 AssertionType,
                 gPciIoBBTestStressAssertionGuid006,
                 L"EFI_PCI_IO_PROTOCOL.Attributes - Set Original Supported attribute the Attributes must be really set.",
                 L"%a:%d:Set attributes - %lXh, gotted attributes - %lXh",
                 __FILE__,
                 __LINE__,
                 OriginalAttributes,
                 CommonAttributes
                 );

  //
  //for each pci io attributes call Attributes with EfiPciIoAttributeOperationDisable.
  //
  PciIoAttributesNumber = 19;
  for (Index = 0; Index < PciIoAttributesNumber; Index++) {
    //
    //first get current attributes.
    //
    PciIo->Attributes (
             PciIo,
             EfiPciIoAttributeOperationGet,
             0,
             &CurrentAttributes
             );

    ThisAttribute = 1 << Index;

    Status = PciIo->Attributes (
                      PciIo,
                      EfiPciIoAttributeOperationDisable,
                      ThisAttribute,
                      NULL
                      );
    //
    //get current attributes
    //
    PciIo->Attributes (
             PciIo,
             EfiPciIoAttributeOperationGet,
             0,
             &CommonAttributes
             );

    //
    //call Attributes to set the orininal value before output to console
    //
    Status1 =  PciIo->Attributes (
                        PciIo,
                        EfiPciIoAttributeOperationSet,
                        OriginalAttributes,
                        NULL
                        );

    if (EFI_ERROR(Status1)) {
      AssertionType = EFI_TEST_ASSERTION_FAILED;
      //
      //record assertion
      //
      StandardLib->RecordAssertion (
                     StandardLib,
                     AssertionType,
                     gPciIoBBTestStressAssertionGuid017,
                     L"EFI_PCI_IO_PROTOCOL.Attributes - Set Original Supported attribute the Status Must be EFI_SUCCESS",
                     L"%a:%d:Status - %r",
                     __FILE__,
                     __LINE__,
                     Status1
                     );
      return Status;
    } else {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    }
    if ((ThisAttribute & SupportedAttributes) == ThisAttribute) {

      if (!EFI_ERROR(Status)) {
        AssertionType = EFI_TEST_ASSERTION_PASSED;
      } else {
        AssertionType = EFI_TEST_ASSERTION_FAILED;
      }

      //
      //record assertion
      //
      StandardLib->RecordAssertion (
                     StandardLib,
                     AssertionType,
                     gPciIoBBTestStressAssertionGuid007,
                     L"EFI_PCI_IO_PROTOCOL.Attributes - disable Supported attribute status must be EFI_SUCCESS",
                     L"%a:%d:Status - %r, Disabled Attributes - %lXh, Supported Attributes - %lXh",
                     __FILE__,
                     __LINE__,
                     Status,
                     ThisAttribute,
                     SupportedAttributes
                     );

      //
      //verify the attributes really disabled
      //
      if ((ThisAttribute & CommonAttributes) != ThisAttribute) {
        AssertionType = EFI_TEST_ASSERTION_PASSED;
      } else {
        AssertionType = EFI_TEST_ASSERTION_FAILED;
      }

      //
      //record assertion
      //
      StandardLib->RecordAssertion (
                     StandardLib,
                     AssertionType,
                     gPciIoBBTestStressAssertionGuid008,
                     L"EFI_PCI_IO_PROTOCOL.Attributes - disable Supported attribute are really diabled",
                     L"%a:%d:Disable Attributes - %lXh, Supported Attributes - %lXh, Original Attribute - %lXh, Current Attributes - %lXh",
                     __FILE__,
                     __LINE__,
                     ThisAttribute,
                     SupportedAttributes,
                     CurrentAttributes,
                     CommonAttributes
                     );

    } else {
      //
      //unsupported attributes
      //
      if (Status == EFI_UNSUPPORTED) {
        AssertionType = EFI_TEST_ASSERTION_PASSED;
      } else {
        AssertionType = EFI_TEST_ASSERTION_FAILED;
      }

      //
      //record assertion
      //
      StandardLib->RecordAssertion (
                     StandardLib,
                     AssertionType,
                     gPciIoBBTestStressAssertionGuid009,
                     L"EFI_PCI_IO_PROTOCOL.Attributes - disable UnSupported attribute status must be EFI_UNSUPPORTED",
                     L"%a:%d:Status - %r, Disabled Attributes - %lXh, Supported Attributes - %lXh",
                     __FILE__,
                     __LINE__,
                     Status,
                     ThisAttribute,
                     SupportedAttributes
                     );

      //
      //verify the attributes remain unchanged after Disable operation
      //
      if (CommonAttributes == CurrentAttributes) {
        AssertionType = EFI_TEST_ASSERTION_PASSED;
      } else {
        AssertionType = EFI_TEST_ASSERTION_FAILED;
      }

      //
      //record assertion
      //
      StandardLib->RecordAssertion (
                     StandardLib,
                     AssertionType,
                     gPciIoBBTestStressAssertionGuid010,
                     L"EFI_PCI_IO_PROTOCOL.Attributes - disable UnSupported attribute the Attributes can not been changed",
                     L"%a:%d:Disable Attributes - %lXh, Supported Attributes - %lXh, Original Attribute - %lXh, Current Attributes - %lXh",
                     __FILE__,
                     __LINE__,
                     ThisAttribute,
                     SupportedAttributes,
                     CurrentAttributes,
                     CommonAttributes
                     );

    }
  }

  //
  //call Attributes to set the orininal value
  //
  Status =  PciIo->Attributes (
                     PciIo,
                     EfiPciIoAttributeOperationSet,
                     OriginalAttributes,
                     NULL
                     );

  if (!EFI_ERROR(Status)) {
    AssertionType = EFI_TEST_ASSERTION_PASSED;
  } else {
    AssertionType = EFI_TEST_ASSERTION_FAILED;
  }

  //
  //record assertion
  //
  StandardLib->RecordAssertion (
                 StandardLib,
                 AssertionType,
                 gPciIoBBTestStressAssertionGuid011,
                 L"EFI_PCI_IO_PROTOCOL.Attributes - Set Original Supported attribute the Status Must be EFI_SUCCESS",
                 L"%a:%d:Status - %r",
                 __FILE__,
                 __LINE__,
                 Status
                 );
  //
  //call get attributes to verify.
  //
  PciIo->Attributes (
           PciIo,
           EfiPciIoAttributeOperationGet,
           0,
           &CommonAttributes
           );

  if (CommonAttributes == OriginalAttributes) {
    AssertionType = EFI_TEST_ASSERTION_PASSED;
  } else {
    AssertionType = EFI_TEST_ASSERTION_FAILED;
  }

  //
  //record assertion
  //
  StandardLib->RecordAssertion (
                 StandardLib,
                 AssertionType,
                 gPciIoBBTestStressAssertionGuid012,
                 L"EFI_PCI_IO_PROTOCOL.Attributes - Set Original Supported attribute the Attributes must be really set.",
                 L"%a:%d:Set Attributes - %lXh, gotted attributes - %lXh",
                 __FILE__,
                 __LINE__,
                 OriginalAttributes,
                 CommonAttributes
                 );

  //
  //for each pci io attributes call Attributes with EfiPciIoAttributeOperationEnable.
  //
  PciIoAttributesNumber = 19;
  for (Index = 1; Index <= PciIoAttributesNumber; Index++) {
    //
    //first get current attributes.
    //
    PciIo->Attributes (
             PciIo,
             EfiPciIoAttributeOperationGet,
             0,
             &CurrentAttributes
             );

    ThisAttribute = 1 << Index;

    Status = PciIo->Attributes (
                      PciIo,
                      EfiPciIoAttributeOperationEnable,
                      ThisAttribute,
                      &CommonAttributes
                      );
    //
    //get current attributes after Enable
    //
    PciIo->Attributes (
             PciIo,
             EfiPciIoAttributeOperationGet,
             0,
             &CommonAttributes
             );

    //
    //call Attributes to set the orininal value before output to console
    //
    Status1 =  PciIo->Attributes (
                        PciIo,
                        EfiPciIoAttributeOperationSet,
                        OriginalAttributes,
                        NULL
                        );

    if (EFI_ERROR(Status1)) {
      AssertionType = EFI_TEST_ASSERTION_FAILED;
      //
      //record assertion
      //
      StandardLib->RecordAssertion (
                     StandardLib,
                     AssertionType,
                     gPciIoBBTestStressAssertionGuid017,
                     L"EFI_PCI_IO_PROTOCOL.Attributes - Set Original Supported attribute the Status Must be EFI_SUCCESS",
                     L"%a:%d:Status - %r",
                     __FILE__,
                     __LINE__,
                     Status1
                     );
      return Status1;
    } else {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    }

    if ((ThisAttribute & SupportedAttributes) == ThisAttribute) {
      if (!EFI_ERROR(Status) || (Status == EFI_UNSUPPORTED)) {
        AssertionType = EFI_TEST_ASSERTION_PASSED;
      } else {
        AssertionType = EFI_TEST_ASSERTION_FAILED;
      }

      //
      //record assertion
      //
      StandardLib->RecordAssertion (
                     StandardLib,
                     AssertionType,
                     gPciIoBBTestStressAssertionGuid013,
                     L"EFI_PCI_IO_PROTOCOL.Attributes - enable Supported attribute status must be EFI_SUCCESS or EFI_UNSUPPORTED",
                     L"%a:%d:Status - %r, Enabled Attributes - %lXh, Supported Attributes - %lXh",
                     __FILE__,
                     __LINE__,
                     Status,
                     ThisAttribute,
                     SupportedAttributes
                     );

      if (!EFI_ERROR(Status)) {
        //
        //verify the attributes really enabled
        //
        if ((ThisAttribute & CommonAttributes) == ThisAttribute) {
          AssertionType = EFI_TEST_ASSERTION_PASSED;
        } else {
          AssertionType = EFI_TEST_ASSERTION_FAILED;
        }

        //
        //record assertion
        //
        StandardLib->RecordAssertion (
                       StandardLib,
                       AssertionType,
                       gPciIoBBTestStressAssertionGuid014,
                       L"EFI_PCI_IO_PROTOCOL.Attributes - enable Supported attribute are really enabled",
                       L"%a:%d:Enable Attributes - %lXh, Supported Attributes - %lXh, Original Attribute - %lXh, Current Attributes - %lXh",
                       __FILE__,
                       __LINE__,
                       ThisAttribute,
                       SupportedAttributes,
                       CurrentAttributes,
                       CommonAttributes
                       );
      }
    } else {
      //
      //unsupported attributes
      //
      if (Status == EFI_UNSUPPORTED) {
        AssertionType = EFI_TEST_ASSERTION_PASSED;
      } else {
        AssertionType = EFI_TEST_ASSERTION_FAILED;
      }

      //
      //record assertion
      //
      StandardLib->RecordAssertion (
                     StandardLib,
                     AssertionType,
                     gPciIoBBTestStressAssertionGuid015,
                     L"EFI_PCI_IO_PROTOCOL.Attributes - enable UnSupported attribute status must be EFI_UNSUPPORTED",
                     L"%a:%d:Status - %r, Enabled Attributes - %lXh, Supported Attributes - %lXh",
                     __FILE__,
                     __LINE__,
                     Status,
                     ThisAttribute,
                     SupportedAttributes
                     );

      //
      //verify the attributes remain unchanged
      //
      if (CommonAttributes == CurrentAttributes) {
        AssertionType = EFI_TEST_ASSERTION_PASSED;
      } else {
        AssertionType = EFI_TEST_ASSERTION_FAILED;
      }

      //
      //record assertion
      //
      StandardLib->RecordAssertion (
                     StandardLib,
                     AssertionType,
                     gPciIoBBTestStressAssertionGuid016,
                     L"EFI_PCI_IO_PROTOCOL.Attributes - enable UnSupported attribute the Attributes can not been changed",
                     L"%a:%d:Enalbe Attributes - %lXh, Supported Attributes - %lXh, Original Attribute - %lXh, Current Attributes - %lXh",
                     __FILE__,
                     __LINE__,
                     ThisAttribute,
                     SupportedAttributes,
                     CurrentAttributes,
                     CommonAttributes
                     );

    }
  }

  //
  //call Attributes to set the orininal value
  //
  Status =  PciIo->Attributes (
                     PciIo,
                     EfiPciIoAttributeOperationSet,
                     OriginalAttributes,
                     NULL
                     );

  if (!EFI_ERROR(Status)) {
    AssertionType = EFI_TEST_ASSERTION_PASSED;
  } else {
    AssertionType = EFI_TEST_ASSERTION_FAILED;
  }

  //
  //record assertion
  //
  StandardLib->RecordAssertion (
                 StandardLib,
                 AssertionType,
                 gPciIoBBTestStressAssertionGuid017,
                 L"EFI_PCI_IO_PROTOCOL.Attributes - Set Original Supported attribute the Status Must be EFI_SUCCESS",
                 L"%a:%d:Status - %r",
                 __FILE__,
                 __LINE__,
                 Status
                 );
  //
  //call get attributes to verify.
  //
  Status =  PciIo->Attributes (
                     PciIo,
                     EfiPciIoAttributeOperationGet,
                     0,
                     &CommonAttributes
                     );

  if (CommonAttributes == OriginalAttributes) {
    AssertionType = EFI_TEST_ASSERTION_PASSED;
  } else {
    AssertionType = EFI_TEST_ASSERTION_FAILED;
  }
  //
  //record assertion
  //
  StandardLib->RecordAssertion (
                 StandardLib,
                 AssertionType,
                 gPciIoBBTestStressAssertionGuid018,
                 L"EFI_PCI_IO_PROTOCOL.Attributes - Set Original Supported attribute the Attributes must be really set.",
                 L"%a:%d:Set Attributes - %lXh, gotted attributes - %lXh",
                 __FILE__,
                 __LINE__,
                 OriginalAttributes,
                 CommonAttributes
                 );

  //
  //done successfully
  //
  return EFI_SUCCESS;
}
Exemplo n.º 4
0
//
//TDS 4.3.2
//
EFI_STATUS
GetAndSetBarAttributes_Stress (
  IN EFI_BB_TEST_PROTOCOL       *This,
  IN VOID                       *ClientInterface,
  IN EFI_TEST_LEVEL             TestLevel,
  IN EFI_HANDLE                 SupportHandle
  )
{
  EFI_STATUS                            Status;
  PCI_IO_PROTOCOL_DEVICE                *PciIoDevice;
  EFI_PCI_IO_PROTOCOL                   *PciIo;
  EFI_STANDARD_TEST_LIBRARY_PROTOCOL    *StandardLib;
  EFI_TEST_ASSERTION                    AssertionType;
  UINTN                                 Index;
  UINTN                                 SubIndex;
  UINT8                                 BarIndex;
  UINT64                                DevSupportedAttributes;
  UINT64                                BarOriginalAttributes;
  UINT64                                AddressOffset;
  UINT64                                AddressLength;
  VOID                                  *Resources;
  UINTN                                 PciIoAttributesNumber;
  UINT64                                ThisAttribute;


  //
  //get tested interface.
  //
  PciIo = (EFI_PCI_IO_PROTOCOL *)ClientInterface;

  //
  // Get the Standard Library Interface
  //
  Status = gtBS->HandleProtocol (
                   SupportHandle,
                   &gEfiStandardTestLibraryGuid,
                   &StandardLib
                   );

  if (EFI_ERROR(Status)) {
    return Status;
  }
  //
  //get PciIoDevice struct pointer.
  //
  PciIoDevice = NULL;
  PciIoDevice = GetPciIoDevice (PciIo);
  if (PciIoDevice == NULL) {
    return EFI_ABORTED;
  }

  InitializeCaseEnvironment ();

  //
  //print the device path of pci device.
  //
  Status = PrintPciIoDevice (PciIoDevice->DevicePath);
  if (EFI_ERROR(Status)) {
    return Status;
  }

  Status = PciIo->Attributes (
                    PciIo,
                    EfiPciIoAttributeOperationSupported,
                    0,
                    &DevSupportedAttributes
                    );
  if (!EFI_ERROR(Status)) {
    AssertionType = EFI_TEST_ASSERTION_PASSED;
  } else {
    AssertionType = EFI_TEST_ASSERTION_FAILED;
  }

  //
  //record assertion
  //
  StandardLib->RecordAssertion (
                 StandardLib,
                 AssertionType,
                 gTestGenericFailureGuid,
                 L"EFI_PCI_IO_PROTOCOL.Attributes - return status must be EFI_SUCCESS.",
                 L"%a:%d:Status - %r",
                 __FILE__,
                 __LINE__,
                 Status
                 );


  for (Index = 0; Index < REGNUM; Index++) {

    BarIndex = (UINT8)Index;
    Resources = 0;
    Status = PciIo->GetBarAttributes (
                      PciIo,
                      BarIndex,
                      &BarOriginalAttributes,
                      &Resources
                      );

    if (!EFI_ERROR(Status)) {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    } else {
      AssertionType = EFI_TEST_ASSERTION_FAILED;
    }

    //
    //record assertion
    //
    StandardLib->RecordAssertion (
                   StandardLib,
                   AssertionType,
                   gPciIoBBTestStressAssertionGuid019,
                   L"EFI_PCI_IO_PROTOCOL.GetBarAttributes - return status must be EFI_SUCCESS.",
                   L"%a:%d:Status - %r, BarIndex - %d",
                   __FILE__,
                   __LINE__,
                   Status,
                   BarIndex
                   );

    if (IsValidResourceDescrptor (Resources)) {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    } else {
      AssertionType = EFI_TEST_ASSERTION_FAILED;
    }
    //
    //record assertion
    //
    StandardLib->RecordAssertion (
                   StandardLib,
                   AssertionType,
                   gPciIoBBTestStressAssertionGuid020,
                   L"EFI_PCI_IO_PROTOCOL.GetBarAttributes - the Resource Descriptor List must be valid",
                   L"%a:%d",
                   __FILE__,
                   __LINE__
                   );
    //
    //free the resources if necessory.
    //
    if (Status == EFI_SUCCESS) {
      gtBS->FreePool (Resources);
    }

    //
    //the attribute supported by this bar must be in the device supported attributes range.
    //
    if ((BarOriginalAttributes & DevSupportedAttributes) == BarOriginalAttributes) {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    } else {
     AssertionType = EFI_TEST_ASSERTION_FAILED;
    }

    //
    //record assertion
    //
    StandardLib->RecordAssertion (
                   StandardLib,
                   AssertionType,
                   gPciIoBBTestStressAssertionGuid021,
                   L"EFI_PCI_IO_PROTOCOL.GetBarAttributes - Bar supported attributes must in the range of Device supproted attributes",
                   L"%a:%d:Bar Supported - %lXh, Dev Supported - %lXh",
                   __FILE__,
                   __LINE__,
                   BarOriginalAttributes,
                   DevSupportedAttributes
                   );
    //
    //Invalid bar then continue;
    //
    if (!PciIoDevice->BarHasEffect[BarIndex]) {
      continue;
    }

    AddressOffset = 0;
    AddressLength = PciIoDevice->BarLength[BarIndex];
    PciIoAttributesNumber = 19;

    //
    //for each attributes call SetBarAttributes
    //
    for (SubIndex = 0; SubIndex < PciIoAttributesNumber; SubIndex++) {

      ThisAttribute = 1 << SubIndex;

      Status = PciIo->SetBarAttributes (
                        PciIo,
                        ThisAttribute,
                        BarIndex,
                        &AddressOffset,
                        &AddressLength
                        );

      if ((ThisAttribute & BarOriginalAttributes) == ThisAttribute) {

        if (!EFI_ERROR(Status)) {
          AssertionType = EFI_TEST_ASSERTION_PASSED;
        } else {
          AssertionType = EFI_TEST_ASSERTION_FAILED;
        }

        //
        //record assertion
        //
        StandardLib->RecordAssertion (
                       StandardLib,
                       AssertionType,
                       gPciIoBBTestStressAssertionGuid022,
                       L"EFI_PCI_IO_PROTOCOL.SetBarAttributes - Set Bar supported attributes return Staus Must be EFI_SUCCESS",
                       L"%a:%d:Set Attribute - %lXh, Supported Attributes - %lXh",
                       __FILE__,
                       __LINE__,
                       ThisAttribute,
                       BarOriginalAttributes
                       );

      } else {
        //
        //Unsupported attributes
        //
        if (Status == EFI_UNSUPPORTED) {
            AssertionType = EFI_TEST_ASSERTION_PASSED;
        } else {
          AssertionType = EFI_TEST_ASSERTION_FAILED;
        }

        //
        //record assertion
        //
        StandardLib->RecordAssertion (
                       StandardLib,
                       AssertionType,
                       gPciIoBBTestStressAssertionGuid023,
                       L"EFI_PCI_IO_PROTOCOL.SetBarAttributes - Set Unsupported attributes status must be EFI_UNSUPPORTED.",
                       L"%a:%d:Set Attribute - %lXh, Supported Attributes - %lXh",
                       __FILE__,
                       __LINE__,
                       ThisAttribute,
                       BarOriginalAttributes
                       );

      }
    }
  }

  //
  //done successfully
  //
  return EFI_SUCCESS;
}
Exemplo n.º 5
0
/**
  Start function of Driver binding protocol which start this driver on Controller
  by detecting all disks and installing BlockIo protocol on them.

  @param  This                Protocol instance pointer.
  @param  Controller          Handle of device to bind driver to.
  @param  RemainingDevicePath produce all possible children.

  @retval  EFI_SUCCESS         This driver is added to ControllerHandle.
  @retval  EFI_ALREADY_STARTED This driver is already running on ControllerHandle.
  @retval  other               This driver does not support this device.

**/
EFI_STATUS
EFIAPI
IDEBusDriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   Controller,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  EFI_STATUS                        Status;
  EFI_STATUS                        SavedStatus;
  EFI_PCI_IO_PROTOCOL               *PciIo;
  EFI_DEVICE_PATH_PROTOCOL          *ParentDevicePath;
  EFI_DEV_PATH                      *Node;
  UINT8                             IdeChannel;
  UINT8                             BeginningIdeChannel;
  UINT8                             EndIdeChannel;
  UINT8                             IdeDevice;
  UINT8                             BeginningIdeDevice;
  UINT8                             EndIdeDevice;
  IDE_BLK_IO_DEV                    *IdeBlkIoDevice[IdeMaxChannel][IdeMaxDevice];
  IDE_BLK_IO_DEV                    *IdeBlkIoDevicePtr;
  IDE_REGISTERS_BASE_ADDR           IdeRegsBaseAddr[IdeMaxChannel];
  ATA_TRANSFER_MODE                 TransferMode;
  ATA_DRIVE_PARMS                   DriveParameters;
  EFI_DEV_PATH                      NewNode;
  UINT8                             ConfigurationOptions;
  UINT16                            CommandBlockBaseAddr;
  UINT16                            ControlBlockBaseAddr;
  UINTN                             DataSize;
  IDE_BUS_DRIVER_PRIVATE_DATA       *IdeBusDriverPrivateData;
  UINT64                            Supports;

  //
  // Local variables declaration for IdeControllerInit support
  //
  EFI_IDE_CONTROLLER_INIT_PROTOCOL  *IdeInit;
  BOOLEAN                           EnumAll;
  BOOLEAN                           ChannelEnabled;
  UINT8                             MaxDevices;
  EFI_IDENTIFY_DATA                 IdentifyData;
  EFI_ATA_COLLECTIVE_MODE           *SupportedModes;

  IdeBusDriverPrivateData = NULL;
  SupportedModes          = NULL;

  //
  // Perform IdeBus initialization
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **) &ParentDevicePath,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {
    return Status;
  }

  //
  // Now open the IDE_CONTROLLER_INIT protocol. Step7.1
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiIdeControllerInitProtocolGuid,
                  (VOID **) &IdeInit,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );

  //
  // The following OpenProtocol function with _GET_PROTOCOL attribute and
  // will not return EFI_ALREADY_STARTED, so save it for now
  //
  SavedStatus = Status;

  if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {
    DEBUG ((EFI_D_ERROR, "Open Init, Status=%x", Status));
    //
    // open protocol is not SUCCESS or not ALREADY_STARTED, error exit
    //
    goto ErrorExit;
  }

  //
  // Save Enumall. Step7.2
  //
  EnumAll       = IdeInit->EnumAll;

  //
  // Consume PCI I/O protocol. Note that the OpenProtocol with _GET_PROTOCOL
  // attribute will not return EFI_ALREADY_STARTED
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiPciIoProtocolGuid,
                  (VOID **) &PciIo,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "Open PciIo, Status=%x", Status));
    goto ErrorExit;
  }

  //
  // We must check EFI_ALREADY_STARTED because many ATAPI devices are removable
  //
  if (SavedStatus != EFI_ALREADY_STARTED) {
    IdeBusDriverPrivateData = AllocatePool (sizeof (IDE_BUS_DRIVER_PRIVATE_DATA));
    if (IdeBusDriverPrivateData == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto ErrorExit;
    }

    ZeroMem (IdeBusDriverPrivateData, sizeof (IDE_BUS_DRIVER_PRIVATE_DATA));
    Status = gBS->InstallMultipleProtocolInterfaces (
                    &Controller,
                    &gEfiCallerIdGuid,
                    IdeBusDriverPrivateData,
                    NULL
                    );
    if (EFI_ERROR (Status)) {
      goto ErrorExit;
    }

  } else {
    Status = gBS->OpenProtocol (
                    Controller,
                    &gEfiCallerIdGuid,
                    (VOID **) &IdeBusDriverPrivateData,
                    This->DriverBindingHandle,
                    Controller,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (EFI_ERROR (Status)) {
      IdeBusDriverPrivateData = NULL;
      goto ErrorExit;
    }
  }

  Status = PciIo->Attributes (
                    PciIo,
                    EfiPciIoAttributeOperationSupported,
                    0,
                    &Supports
                    );
  if (!EFI_ERROR (Status)) {
    Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;
    Status = PciIo->Attributes (
                      PciIo,
                      EfiPciIoAttributeOperationEnable,
                      Supports,
                      NULL
                      );
  }

  if (EFI_ERROR (Status)) {
    goto ErrorExit;
  }

  //
  // Read the environment variable that contains the IDEBus Driver's
  // Config options that were set by the Driver Configuration Protocol
  //
  DataSize = sizeof (ConfigurationOptions);
  Status = gRT->GetVariable (
                  (CHAR16 *) L"Configuration",
                  &gEfiCallerIdGuid,
                  NULL,
                  &DataSize,
                  &ConfigurationOptions
                  );
  if (EFI_ERROR (Status)) {
    ConfigurationOptions = 0x0f;
  }

   if (EnumAll || RemainingDevicePath == NULL) {
    //
    // If IdeInit->EnumAll is TRUE or RemainingDevicePath is NULL, 
    // must enumerate all IDE devices anyway
    //
    BeginningIdeChannel = IdePrimary;
    EndIdeChannel       = IdeSecondary;
    BeginningIdeDevice  = IdeMaster;
    EndIdeDevice        = IdeSlave;

  } else if (!IsDevicePathEnd (RemainingDevicePath)) {
    //
    // If RemainingDevicePath isn't the End of Device Path Node, 
    // only scan the specified device by RemainingDevicePath
    //
    Node                = (EFI_DEV_PATH *) RemainingDevicePath;
    BeginningIdeChannel = Node->Atapi.PrimarySecondary;
    EndIdeChannel       = BeginningIdeChannel;
    BeginningIdeDevice  = Node->Atapi.SlaveMaster;
    EndIdeDevice        = BeginningIdeDevice;
    if (BeginningIdeChannel >= IdeMaxChannel || EndIdeChannel >= IdeMaxChannel) {
      Status = EFI_INVALID_PARAMETER;
      goto ErrorExit;
    }
    if (BeginningIdeDevice >= IdeMaxDevice|| EndIdeDevice >= IdeMaxDevice) {
      Status = EFI_INVALID_PARAMETER;
      goto ErrorExit;
    }

  } else {
    //
    // If RemainingDevicePath is the End of Device Path Node,
    // skip enumerate any device and return EFI_SUCESSS
    // 
    BeginningIdeChannel = IdeMaxChannel;
    EndIdeChannel       = IdeMaxChannel - 1;
    BeginningIdeDevice  = IdeMaxDevice;
    EndIdeDevice        = IdeMaxDevice - 1;
  }

  //
  // Obtain IDE IO port registers' base addresses
  //
  Status = GetIdeRegistersBaseAddr (PciIo, IdeRegsBaseAddr);
  if (EFI_ERROR (Status)) {
    goto ErrorExit;
  }

  //
  // Report status code: begin IdeBus initialization
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_RESET),
    ParentDevicePath
    );

  //
  // Strictly follow the enumeration based on IDE_CONTROLLER_INIT protocol
  //
  for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) {

    IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelEnumeration, IdeChannel);

    //
    // now obtain channel information fron IdeControllerInit protocol. Step9
    //
    Status = IdeInit->GetChannelInfo (
                        IdeInit,
                        IdeChannel,
                        &ChannelEnabled,
                        &MaxDevices
                        );
    if (EFI_ERROR (Status)) {
      DEBUG ((EFI_D_ERROR, "[GetChannel, Status=%x]", Status));
      continue;
    }

    if (!ChannelEnabled) {
      continue;
    }

    EndIdeDevice = (UINT8) MIN ((MaxDevices - 1), EndIdeDevice);
    ASSERT (EndIdeDevice < IdeMaxDevice);
    //
    // Now inform the IDE Controller Init Module. Sept10
    //
    IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelReset, IdeChannel);

    //
    // No reset channel function implemented. Sept11
    //
    IdeInit->NotifyPhase (IdeInit, EfiIdeAfterChannelReset, IdeChannel);

    //
    // Step13
    //
    IdeInit->NotifyPhase (
              IdeInit,
              EfiIdeBusBeforeDevicePresenceDetection,
              IdeChannel
              );

    //
    // Prepare to detect IDE device of this channel
    //
    InitializeIDEChannelData ();

    //
    // -- 1st inner loop --- Master/Slave ------------  Step14
    //
    for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) {
      //
      // Check whether the configuration options allow this device
      //
      if ((ConfigurationOptions & (1 << (IdeChannel * 2 + IdeDevice))) == 0) {
        continue;
      }

      //
      // The device has been scanned in another Start(), No need to scan it again
      // for perf optimization.
      //
      if (IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice]) {
        continue;
      }

      //
      // create child handle for the detected device.
      //
      IdeBlkIoDevice[IdeChannel][IdeDevice] = AllocatePool (sizeof (IDE_BLK_IO_DEV));
      if (IdeBlkIoDevice[IdeChannel][IdeDevice] == NULL) {
        continue;
      }

      IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice];

      ZeroMem (IdeBlkIoDevicePtr, sizeof (IDE_BLK_IO_DEV));

      IdeBlkIoDevicePtr->Signature  = IDE_BLK_IO_DEV_SIGNATURE;
      IdeBlkIoDevicePtr->Channel    = (EFI_IDE_CHANNEL) IdeChannel;
      IdeBlkIoDevicePtr->Device     = (EFI_IDE_DEVICE) IdeDevice;

      //
      // initialize Block IO interface's Media pointer
      //
      IdeBlkIoDevicePtr->BlkIo.Media = &IdeBlkIoDevicePtr->BlkMedia;

      //
      // Initialize IDE IO port addresses, including Command Block registers
      // and Control Block registers
      //
      IdeBlkIoDevicePtr->IoPort = AllocatePool (sizeof (IDE_BASE_REGISTERS));
      if (IdeBlkIoDevicePtr->IoPort == NULL) {
        continue;
      }

      ZeroMem (IdeBlkIoDevicePtr->IoPort, sizeof (IDE_BASE_REGISTERS));
      CommandBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].CommandBlockBaseAddr;
      ControlBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].ControlBlockBaseAddr;

      IdeBlkIoDevicePtr->IoPort->Data = CommandBlockBaseAddr;
      (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg1) = (UINT16) (CommandBlockBaseAddr + 0x01);
      IdeBlkIoDevicePtr->IoPort->SectorCount = (UINT16) (CommandBlockBaseAddr + 0x02);
      IdeBlkIoDevicePtr->IoPort->SectorNumber = (UINT16) (CommandBlockBaseAddr + 0x03);
      IdeBlkIoDevicePtr->IoPort->CylinderLsb = (UINT16) (CommandBlockBaseAddr + 0x04);
      IdeBlkIoDevicePtr->IoPort->CylinderMsb = (UINT16) (CommandBlockBaseAddr + 0x05);
      IdeBlkIoDevicePtr->IoPort->Head = (UINT16) (CommandBlockBaseAddr + 0x06);
      (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg) = (UINT16) (CommandBlockBaseAddr + 0x07);

      (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Alt) = ControlBlockBaseAddr;
      IdeBlkIoDevicePtr->IoPort->DriveAddress = (UINT16) (ControlBlockBaseAddr + 0x01);

      IdeBlkIoDevicePtr->IoPort->MasterSlave = (UINT16) ((IdeDevice == IdeMaster) ? 1 : 0);

      IdeBlkIoDevicePtr->PciIo = PciIo;
      IdeBlkIoDevicePtr->IdeBusDriverPrivateData = IdeBusDriverPrivateData;
      IdeBlkIoDevicePtr->IoPort->BusMasterBaseAddr = IdeRegsBaseAddr[IdeChannel].BusMasterBaseAddr;

      //
      // Report Status code: is about to detect IDE drive
      //
      REPORT_STATUS_CODE_EX (
        EFI_PROGRESS_CODE,
        (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_PRESENCE_DETECT),
        0,
        &gEfiCallerIdGuid,
        NULL,
        NULL,
        0
      );

      //
      // Discover device, now!
      //
      PERF_START (NULL, "DiscoverIdeDevice", "IDE", 0);
      Status = DiscoverIdeDevice (IdeBlkIoDevicePtr);
      PERF_END (NULL, "DiscoverIdeDevice", "IDE", 0);

      IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice]  = TRUE;
      IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice]    = FALSE;

      if (!EFI_ERROR (Status)) {
        //
        // Set Device Path
        //
        ZeroMem (&NewNode, sizeof (NewNode));
        NewNode.DevPath.Type    = MESSAGING_DEVICE_PATH;
        NewNode.DevPath.SubType = MSG_ATAPI_DP;
        SetDevicePathNodeLength (&NewNode.DevPath, sizeof (ATAPI_DEVICE_PATH));

        NewNode.Atapi.PrimarySecondary  = (UINT8) IdeBlkIoDevicePtr->Channel;
        NewNode.Atapi.SlaveMaster       = (UINT8) IdeBlkIoDevicePtr->Device;
        NewNode.Atapi.Lun               = IdeBlkIoDevicePtr->Lun;
        IdeBlkIoDevicePtr->DevicePath = AppendDevicePathNode (
                                          ParentDevicePath,
                                          &NewNode.DevPath
                                          );
        if (IdeBlkIoDevicePtr->DevicePath == NULL) {
          ReleaseIdeResources (IdeBlkIoDevicePtr);
          continue;
        }

        //
        // Submit identify data to IDE controller init driver
        //
        CopyMem (&IdentifyData, IdeBlkIoDevicePtr->IdData, sizeof (IdentifyData));
        IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = TRUE;
        IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, &IdentifyData);
      } else {
        //
        // Device detection failed
        //
        IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;
        IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, NULL);
        ReleaseIdeResources (IdeBlkIoDevicePtr);
        IdeBlkIoDevicePtr = NULL;
      }
      //
      // end of 1st inner loop ---
      //
    }
    //
    // end of 1st outer loop =========
    //
  }

  //
  // = 2nd outer loop == Primary/Secondary =================
  //
  for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) {

    //
    // -- 2nd inner loop --- Master/Slave --------
    //
    for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) {

      ASSERT (IdeChannel * 2 + IdeDevice < MAX_IDE_DEVICE);
      if (IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice]) {
        continue;
      }

      if (!IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice]) {
        continue;
      }

      Status = IdeInit->CalculateMode (
                          IdeInit,
                          IdeChannel,
                          IdeDevice,
                          &SupportedModes
                          );
      if (EFI_ERROR (Status)) {
        DEBUG ((EFI_D_ERROR, "[bStStp20S=%x]", Status));
        continue;
      }

      ASSERT (IdeChannel < IdeMaxChannel && IdeDevice < IdeMaxDevice);
      IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice];

      //
      // Set best supported PIO mode on this IDE device
      //
      if (SupportedModes->PioMode.Mode <= AtaPioMode2) {
        TransferMode.ModeCategory = ATA_MODE_CATEGORY_DEFAULT_PIO;
      } else {
        TransferMode.ModeCategory = ATA_MODE_CATEGORY_FLOW_PIO;
      }

      TransferMode.ModeNumber = (UINT8) (SupportedModes->PioMode.Mode);

      if (SupportedModes->ExtModeCount == 0){
        Status                  = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);

        if (EFI_ERROR (Status)) {
          IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;
          ReleaseIdeResources (IdeBlkIoDevicePtr);
          IdeBlkIoDevicePtr = NULL;
          continue;
        }
      }

      //
      // Set supported DMA mode on this IDE device. Note that UDMA & MDMA cann't
      // be set together. Only one DMA mode can be set to a device. If setting
      // DMA mode operation fails, we can continue moving on because we only use
      // PIO mode at boot time. DMA modes are used by certain kind of OS booting
      //
      if (SupportedModes->UdmaMode.Valid) {

        TransferMode.ModeCategory = ATA_MODE_CATEGORY_UDMA;
        TransferMode.ModeNumber   = (UINT8) (SupportedModes->UdmaMode.Mode);
        Status                    = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);

        if (EFI_ERROR (Status)) {
          IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;
          ReleaseIdeResources (IdeBlkIoDevicePtr);
          IdeBlkIoDevicePtr = NULL;
          continue;
        }
        //
        // Record Udma Mode
        //
        IdeBlkIoDevicePtr->UdmaMode.Valid = TRUE;
        IdeBlkIoDevicePtr->UdmaMode.Mode  = SupportedModes->UdmaMode.Mode;
        EnableInterrupt (IdeBlkIoDevicePtr);
      } else if (SupportedModes->MultiWordDmaMode.Valid) {

        TransferMode.ModeCategory = ATA_MODE_CATEGORY_MDMA;
        TransferMode.ModeNumber   = (UINT8) SupportedModes->MultiWordDmaMode.Mode;
        Status                    = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);

        if (EFI_ERROR (Status)) {
          IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;
          ReleaseIdeResources (IdeBlkIoDevicePtr);
          IdeBlkIoDevicePtr = NULL;
          continue;
        }

        EnableInterrupt (IdeBlkIoDevicePtr);
      }
      //
      // Init driver parameters
      //
      DriveParameters.Sector          = (UINT8) ((ATA5_IDENTIFY_DATA *) IdeBlkIoDevicePtr->IdData)->sectors_per_track;
      DriveParameters.Heads           = (UINT8) (((ATA5_IDENTIFY_DATA *) IdeBlkIoDevicePtr->IdData)->heads - 1);
      DriveParameters.MultipleSector  = (UINT8) IdeBlkIoDevicePtr->IdData->AtaData.multi_sector_cmd_max_sct_cnt;
      //
      // Set Parameters for the device:
      // 1) Init
      // 2) Establish the block count for READ/WRITE MULTIPLE (EXT) command
      //
      if ((IdeBlkIoDevicePtr->Type == IdeHardDisk) || (IdeBlkIoDevicePtr->Type == Ide48bitAddressingHardDisk)) {
        Status = SetDriveParameters (IdeBlkIoDevicePtr, &DriveParameters);
      }

      //
      // Record PIO mode used in private data
      //
      IdeBlkIoDevicePtr->PioMode = (ATA_PIO_MODE) SupportedModes->PioMode.Mode;

      //
      // Set IDE controller Timing Blocks in the PCI Configuration Space
      //
      IdeInit->SetTiming (IdeInit, IdeChannel, IdeDevice, SupportedModes);

      //
      // Add Component Name for the IDE/ATAPI device that was discovered.
      //
      IdeBlkIoDevicePtr->ControllerNameTable = NULL;
      ADD_IDE_ATAPI_NAME (IdeBlkIoDevicePtr);

      Status = gBS->InstallMultipleProtocolInterfaces (
                      &IdeBlkIoDevicePtr->Handle,
                      &gEfiDevicePathProtocolGuid,
                      IdeBlkIoDevicePtr->DevicePath,
                      &gEfiBlockIoProtocolGuid,
                      &IdeBlkIoDevicePtr->BlkIo,
                      &gEfiDiskInfoProtocolGuid,
                      &IdeBlkIoDevicePtr->DiskInfo,
                      NULL
                      );

      if (EFI_ERROR (Status)) {
        ReleaseIdeResources (IdeBlkIoDevicePtr);
      }

      gBS->OpenProtocol (
            Controller,
            &gEfiPciIoProtocolGuid,
            (VOID **) &PciIo,
            This->DriverBindingHandle,
            IdeBlkIoDevicePtr->Handle,
            EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
            );

      IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice] = TRUE;

      //
      // Report status code: device eanbled!
      //
      REPORT_STATUS_CODE_WITH_DEVICE_PATH (
        EFI_PROGRESS_CODE,
        (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_ENABLE),
        IdeBlkIoDevicePtr->DevicePath
        );

      //
      // Create event to clear pending IDE interrupt
      //
      Status = gBS->CreateEventEx (
                      EVT_NOTIFY_SIGNAL,
                      TPL_NOTIFY,
                      ClearInterrupt,
                      IdeBlkIoDevicePtr,
                      &gEfiEventExitBootServicesGuid,
                      &IdeBlkIoDevicePtr->ExitBootServiceEvent
                      );

      //
      // end of 2nd inner loop ----
      //
    }
    //
    // end of 2nd outer loop ==========
    //
  }

  //
  // All configurations done! Notify IdeController to do post initialization
  // work such as saving IDE controller PCI settings for S3 resume
  //
  IdeInit->NotifyPhase (IdeInit, EfiIdeBusPhaseMaximum, 0);

  if (SupportedModes != NULL) {
    FreePool (SupportedModes);
  }

  PERF_START (NULL, "Finish IDE detection", "IDE", 1);
  PERF_END (NULL, "Finish IDE detection", "IDE", 0);

  return EFI_SUCCESS;

ErrorExit:

  //
  // Report error code: controller error
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_ERROR_CODE | EFI_ERROR_MINOR,
    (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_EC_CONTROLLER_ERROR),
    ParentDevicePath
    );

  gBS->CloseProtocol (
        Controller,
        &gEfiIdeControllerInitProtocolGuid,
        This->DriverBindingHandle,
        Controller
        );

  gBS->UninstallMultipleProtocolInterfaces (
        Controller,
        &gEfiCallerIdGuid,
        IdeBusDriverPrivateData,
        NULL
        );

  if (IdeBusDriverPrivateData != NULL) {
    gBS->FreePool (IdeBusDriverPrivateData);
  }

  if (SupportedModes != NULL) {
    gBS->FreePool (SupportedModes);
  }

  gBS->CloseProtocol (
        Controller,
        &gEfiPciIoProtocolGuid,
        This->DriverBindingHandle,
        Controller
        );

  gBS->CloseProtocol (
        Controller,
        &gEfiDevicePathProtocolGuid,
        This->DriverBindingHandle,
        Controller
        );

  return Status;

}
Exemplo n.º 6
0
/**
  Stop function of Driver Binding Protocol which is to stop the driver on Controller Handle and all
  child handle attached to the controller handle if there are.

  @param  This Protocol instance pointer.
  @param  Controller Handle of device to stop driver on
  @param  NumberOfChildren Not used
  @param  ChildHandleBuffer Not used

  @retval  EFI_SUCCESS This driver is removed DeviceHandle
  @retval  other This driver was not removed from this device

**/
EFI_STATUS
EFIAPI
IDEBusDriverBindingStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,
  IN  EFI_HANDLE                      Controller,
  IN  UINTN                           NumberOfChildren,
  IN  EFI_HANDLE                      *ChildHandleBuffer
  )
{
  EFI_STATUS                  Status;
  EFI_PCI_IO_PROTOCOL         *PciIo;
  BOOLEAN                     AllChildrenStopped;
  UINTN                       Index;
  IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData;
  UINT64                      Supports;

  IdeBusDriverPrivateData = NULL;

  if (NumberOfChildren == 0) {

    Status = gBS->OpenProtocol (
                    Controller,
                    &gEfiPciIoProtocolGuid,
                    (VOID **) &PciIo,
                    This->DriverBindingHandle,
                    Controller,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (!EFI_ERROR (Status)) {
      Status = PciIo->Attributes (
                        PciIo,
                        EfiPciIoAttributeOperationSupported,
                        0,
                        &Supports
                        );
      if (!EFI_ERROR (Status)) {
        Supports &= (UINT64)(EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_DEVICE_ENABLE);
        PciIo->Attributes (
                PciIo,
                EfiPciIoAttributeOperationDisable,
                Supports,
                NULL
                );
      }
    }

    gBS->OpenProtocol (
          Controller,
          &gEfiCallerIdGuid,
          (VOID **) &IdeBusDriverPrivateData,
          This->DriverBindingHandle,
          Controller,
          EFI_OPEN_PROTOCOL_GET_PROTOCOL
          );

    gBS->UninstallMultipleProtocolInterfaces (
          Controller,
          &gEfiCallerIdGuid,
          IdeBusDriverPrivateData,
          NULL
          );

    if (IdeBusDriverPrivateData != NULL) {
      gBS->FreePool (IdeBusDriverPrivateData);
    }
    //
    // Close the bus driver
    //
    gBS->CloseProtocol (
          Controller,
          &gEfiIdeControllerInitProtocolGuid,
          This->DriverBindingHandle,
          Controller
          );
    gBS->CloseProtocol (
          Controller,
          &gEfiPciIoProtocolGuid,
          This->DriverBindingHandle,
          Controller
          );
    gBS->CloseProtocol (
          Controller,
          &gEfiDevicePathProtocolGuid,
          This->DriverBindingHandle,
          Controller
          );

    return EFI_SUCCESS;
  }

  AllChildrenStopped = TRUE;

  for (Index = 0; Index < NumberOfChildren; Index++) {

    Status = DeRegisterIdeDevice (This, Controller, ChildHandleBuffer[Index]);

    if (EFI_ERROR (Status)) {
      AllChildrenStopped = FALSE;
    }
  }

  if (!AllChildrenStopped) {
    return EFI_DEVICE_ERROR;
  }

  return EFI_SUCCESS;
}
Exemplo n.º 7
0
/**
  Starting the Pci SATA Driver.

  @param  This                 Protocol instance pointer.
  @param  Controller           Handle of device to test.
  @param  RemainingDevicePath  Not used.

  @return EFI_SUCCESS          supports this device.
  @return EFI_UNSUPPORTED      do not support this device.
  @return EFI_DEVICE_ERROR     cannot be started due to device Error.
  @return EFI_OUT_OF_RESOURCES cannot allocate resources.

**/
EFI_STATUS
EFIAPI
SataSiI3132DriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL *This,
  IN EFI_HANDLE                  Controller,
  IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath
  )
{
  EFI_STATUS              Status;
  EFI_PCI_IO_PROTOCOL     *PciIo;
  UINT64                  Supports;
  UINT64                  OriginalPciAttributes;
  BOOLEAN                 PciAttributesSaved;
  UINT32                  PciID;
  SATA_SI3132_INSTANCE    *SataSiI3132Instance = NULL;

  SATA_TRACE ("SataSiI3132DriverBindingStart()");

  //TODO: Find a nicer way to do it !
  if (mbStarted) {
    return EFI_SUCCESS; // Don't restart me !
  }

  //
  // Open the PciIo Protocol
  //
  Status = gBS->OpenProtocol (
                Controller,
                &gEfiPciIoProtocolGuid,
                (VOID **) &PciIo,
                This->DriverBindingHandle,
                Controller,
                EFI_OPEN_PROTOCOL_BY_DRIVER
                );
  if (EFI_ERROR (Status)) {
      return Status;
  }

  PciAttributesSaved = FALSE;
  //
  // Save original PCI attributes
  //
  Status = PciIo->Attributes (
                  PciIo,
                  EfiPciIoAttributeOperationGet,
                  0,
                  &OriginalPciAttributes
                  );
  if (EFI_ERROR (Status)) {
      goto CLOSE_PCIIO;
  }
  PciAttributesSaved = TRUE;

  Status = PciIo->Attributes (
                  PciIo,
                  EfiPciIoAttributeOperationSupported,
                  0,
                  &Supports
                  );
  if (!EFI_ERROR (Status)) {
      Supports &= EFI_PCI_DEVICE_ENABLE;
      Status = PciIo->Attributes (
                        PciIo,
                        EfiPciIoAttributeOperationEnable,
                        Supports,
                        NULL
                        );
  }
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "SataSiI3132DriverBindingStart: failed to enable controller\n"));
    goto CLOSE_PCIIO;
  }

  //
  // Get the Pci device class code.
  //
  Status = PciIo->Pci.Read (
                      PciIo,
                      EfiPciIoWidthUint32,
                      PCI_VENDOR_ID_OFFSET,
                      1,
                      &PciID
                      );
  if (EFI_ERROR (Status)) {
    Status = EFI_UNSUPPORTED;
    goto CLOSE_PCIIO;
  }

  //
  // Test whether the controller belongs to SATA Mass Storage type
  //
  if (PciID != ((SATA_SII3132_DEVICE_ID << 16) | SATA_SII3132_VENDOR_ID)) {
    Status = EFI_UNSUPPORTED;
    goto CLOSE_PCIIO;
  }

  // Create SiI3132 Sata Instance
  Status = SataSiI3132Constructor (PciIo, &SataSiI3132Instance);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  // Initialize SiI3132 Sata Controller
  Status = SataSiI3132Initialization (SataSiI3132Instance);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  // Install Ata Pass Thru Protocol
  Status = gBS->InstallProtocolInterface (
              &Controller,
              &gEfiAtaPassThruProtocolGuid,
              EFI_NATIVE_INTERFACE,
              &(SataSiI3132Instance->AtaPassThruProtocol)
              );
  if (EFI_ERROR (Status)) {
    goto FREE_POOL;
  }

/*  //
  // Create event to stop the HC when exit boot service.
  //
  Status = gBS->CreateEventEx (
                EVT_NOTIFY_SIGNAL,
                TPL_NOTIFY,
                EhcExitBootService,
                Ehc,
                &gEfiEventExitBootServicesGuid,
                &Ehc->ExitBootServiceEvent
                );
  if (EFI_ERROR (Status)) {
      goto UNINSTALL_USBHC;
  }*/

  mbStarted = TRUE;

  SATA_TRACE ("SataSiI3132DriverBindingStart() Success!");
  return EFI_SUCCESS;

FREE_POOL:
  //TODO: Free SATA Instance

CLOSE_PCIIO:
  if (PciAttributesSaved) {
      //
      // Restore original PCI attributes
      //
      PciIo->Attributes (
                      PciIo,
                      EfiPciIoAttributeOperationSet,
                      OriginalPciAttributes,
                      NULL
                      );
  }

  gBS->CloseProtocol (
       Controller,
       &gEfiPciIoProtocolGuid,
       This->DriverBindingHandle,
       Controller
       );

  return Status;
}
Exemplo n.º 8
0
/**
  Initialize the Nvm Express controller.

  @param[in] Private                 The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure.

  @retval EFI_SUCCESS                The NVM Express Controller is initialized successfully.
  @retval Others                     A device error occurred while initializing the controller.

**/
EFI_STATUS
NvmeControllerInit (
  IN NVME_CONTROLLER_PRIVATE_DATA    *Private
  )
{
  EFI_STATUS                      Status;
  EFI_PCI_IO_PROTOCOL             *PciIo;
  UINT64                          Supports;
  NVME_AQA                        Aqa;
  NVME_ASQ                        Asq;
  NVME_ACQ                        Acq;
  UINT8                           Sn[21];
  UINT8                           Mn[41];
  //
  // Save original PCI attributes and enable this controller.
  //
  PciIo  = Private->PciIo;
  Status = PciIo->Attributes (
                    PciIo,
                    EfiPciIoAttributeOperationGet,
                    0,
                    &Private->PciAttributes
                    );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = PciIo->Attributes (
                    PciIo,
                    EfiPciIoAttributeOperationSupported,
                    0,
                    &Supports
                    );

  if (!EFI_ERROR (Status)) {
    Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;
    Status    = PciIo->Attributes (
                         PciIo,
                         EfiPciIoAttributeOperationEnable,
                         Supports,
                         NULL
                         );
  }

  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_INFO, "NvmeControllerInit: failed to enable controller\n"));
    return Status;
  }

  //
  // Read the Controller Capabilities register and verify that the NVM command set is supported
  //
  Status = ReadNvmeControllerCapabilities (Private, &Private->Cap);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (Private->Cap.Css != 0x01) {
    DEBUG ((EFI_D_INFO, "NvmeControllerInit: the controller doesn't support NVMe command set\n"));
    return EFI_UNSUPPORTED;
  }

  //
  // Currently the driver only supports 4k page size.
  //
  ASSERT ((Private->Cap.Mpsmin + 12) <= EFI_PAGE_SHIFT);

  Private->Cid[0] = 0;
  Private->Cid[1] = 0;
  Private->Cid[2] = 0;
  Private->Pt[0]  = 0;
  Private->Pt[1]  = 0;
  Private->Pt[2]  = 0;
  Private->SqTdbl[0].Sqt = 0;
  Private->SqTdbl[1].Sqt = 0;
  Private->SqTdbl[2].Sqt = 0;
  Private->CqHdbl[0].Cqh = 0;
  Private->CqHdbl[1].Cqh = 0;
  Private->CqHdbl[2].Cqh = 0;
  Private->AsyncSqHead   = 0;

  Status = NvmeDisableController (Private);

  if (EFI_ERROR(Status)) {
    return Status;
  }

  //
  // set number of entries admin submission & completion queues.
  //
  Aqa.Asqs  = NVME_ASQ_SIZE;
  Aqa.Rsvd1 = 0;
  Aqa.Acqs  = NVME_ACQ_SIZE;
  Aqa.Rsvd2 = 0;

  //
  // Address of admin submission queue.
  //
  Asq = (UINT64)(UINTN)(Private->BufferPciAddr) & ~0xFFF;

  //
  // Address of admin completion queue.
  //
  Acq = (UINT64)(UINTN)(Private->BufferPciAddr + EFI_PAGE_SIZE) & ~0xFFF;

  //
  // Address of I/O submission & completion queue.
  //
  ZeroMem (Private->Buffer, EFI_PAGES_TO_SIZE (6));
  Private->SqBuffer[0]        = (NVME_SQ *)(UINTN)(Private->Buffer);
  Private->SqBufferPciAddr[0] = (NVME_SQ *)(UINTN)(Private->BufferPciAddr);
  Private->CqBuffer[0]        = (NVME_CQ *)(UINTN)(Private->Buffer + 1 * EFI_PAGE_SIZE);
  Private->CqBufferPciAddr[0] = (NVME_CQ *)(UINTN)(Private->BufferPciAddr + 1 * EFI_PAGE_SIZE);
  Private->SqBuffer[1]        = (NVME_SQ *)(UINTN)(Private->Buffer + 2 * EFI_PAGE_SIZE);
  Private->SqBufferPciAddr[1] = (NVME_SQ *)(UINTN)(Private->BufferPciAddr + 2 * EFI_PAGE_SIZE);
  Private->CqBuffer[1]        = (NVME_CQ *)(UINTN)(Private->Buffer + 3 * EFI_PAGE_SIZE);
  Private->CqBufferPciAddr[1] = (NVME_CQ *)(UINTN)(Private->BufferPciAddr + 3 * EFI_PAGE_SIZE);
  Private->SqBuffer[2]        = (NVME_SQ *)(UINTN)(Private->Buffer + 4 * EFI_PAGE_SIZE);
  Private->SqBufferPciAddr[2] = (NVME_SQ *)(UINTN)(Private->BufferPciAddr + 4 * EFI_PAGE_SIZE);
  Private->CqBuffer[2]        = (NVME_CQ *)(UINTN)(Private->Buffer + 5 * EFI_PAGE_SIZE);
  Private->CqBufferPciAddr[2] = (NVME_CQ *)(UINTN)(Private->BufferPciAddr + 5 * EFI_PAGE_SIZE);

  DEBUG ((EFI_D_INFO, "Private->Buffer = [%016X]\n", (UINT64)(UINTN)Private->Buffer));
  DEBUG ((EFI_D_INFO, "Admin     Submission Queue size (Aqa.Asqs) = [%08X]\n", Aqa.Asqs));
  DEBUG ((EFI_D_INFO, "Admin     Completion Queue size (Aqa.Acqs) = [%08X]\n", Aqa.Acqs));
  DEBUG ((EFI_D_INFO, "Admin     Submission Queue (SqBuffer[0]) = [%016X]\n", Private->SqBuffer[0]));
  DEBUG ((EFI_D_INFO, "Admin     Completion Queue (CqBuffer[0]) = [%016X]\n", Private->CqBuffer[0]));
  DEBUG ((EFI_D_INFO, "Sync  I/O Submission Queue (SqBuffer[1]) = [%016X]\n", Private->SqBuffer[1]));
  DEBUG ((EFI_D_INFO, "Sync  I/O Completion Queue (CqBuffer[1]) = [%016X]\n", Private->CqBuffer[1]));
  DEBUG ((EFI_D_INFO, "Async I/O Submission Queue (SqBuffer[2]) = [%016X]\n", Private->SqBuffer[2]));
  DEBUG ((EFI_D_INFO, "Async I/O Completion Queue (CqBuffer[2]) = [%016X]\n", Private->CqBuffer[2]));

  //
  // Program admin queue attributes.
  //
  Status = WriteNvmeAdminQueueAttributes (Private, &Aqa);

  if (EFI_ERROR(Status)) {
    return Status;
  }

  //
  // Program admin submission queue address.
  //
  Status = WriteNvmeAdminSubmissionQueueBaseAddress (Private, &Asq);

  if (EFI_ERROR(Status)) {
    return Status;
  }

  //
  // Program admin completion queue address.
  //
  Status = WriteNvmeAdminCompletionQueueBaseAddress (Private, &Acq);

  if (EFI_ERROR(Status)) {
    return Status;
  }

  Status = NvmeEnableController (Private);
  if (EFI_ERROR(Status)) {
    return Status;
  }

  //
  // Allocate buffer for Identify Controller data
  //
  if (Private->ControllerData == NULL) {
    Private->ControllerData = (NVME_ADMIN_CONTROLLER_DATA *)AllocateZeroPool (sizeof(NVME_ADMIN_CONTROLLER_DATA));
    
    if (Private->ControllerData == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
  }

  //
  // Get current Identify Controller Data
  //
  Status = NvmeIdentifyController (Private, Private->ControllerData);

  if (EFI_ERROR(Status)) {
    FreePool(Private->ControllerData);
    Private->ControllerData = NULL;
    return EFI_NOT_FOUND;
  }

  //
  // Dump NvmExpress Identify Controller Data
  //
  CopyMem (Sn, Private->ControllerData->Sn, sizeof (Private->ControllerData->Sn));
  Sn[20] = 0;
  CopyMem (Mn, Private->ControllerData->Mn, sizeof (Private->ControllerData->Mn));
  Mn[40] = 0;
  DEBUG ((EFI_D_INFO, " == NVME IDENTIFY CONTROLLER DATA ==\n"));
  DEBUG ((EFI_D_INFO, "    PCI VID   : 0x%x\n", Private->ControllerData->Vid));
  DEBUG ((EFI_D_INFO, "    PCI SSVID : 0x%x\n", Private->ControllerData->Ssvid));
  DEBUG ((EFI_D_INFO, "    SN        : %a\n",   Sn));
  DEBUG ((EFI_D_INFO, "    MN        : %a\n",   Mn));
  DEBUG ((EFI_D_INFO, "    FR        : 0x%x\n", *((UINT64*)Private->ControllerData->Fr)));
  DEBUG ((EFI_D_INFO, "    RAB       : 0x%x\n", Private->ControllerData->Rab));
  DEBUG ((EFI_D_INFO, "    IEEE      : 0x%x\n", *(UINT32*)Private->ControllerData->Ieee_oui));
  DEBUG ((EFI_D_INFO, "    AERL      : 0x%x\n", Private->ControllerData->Aerl));
  DEBUG ((EFI_D_INFO, "    SQES      : 0x%x\n", Private->ControllerData->Sqes));
  DEBUG ((EFI_D_INFO, "    CQES      : 0x%x\n", Private->ControllerData->Cqes));
  DEBUG ((EFI_D_INFO, "    NN        : 0x%x\n", Private->ControllerData->Nn));

  //
  // Create two I/O completion queues.
  // One for blocking I/O, one for non-blocking I/O.
  //
  Status = NvmeCreateIoCompletionQueue (Private);
  if (EFI_ERROR(Status)) {
   return Status;
  }

  //
  // Create two I/O Submission queues.
  // One for blocking I/O, one for non-blocking I/O.
  //
  Status = NvmeCreateIoSubmissionQueue (Private);
  if (EFI_ERROR(Status)) {
   return Status;
  }

  return Status;
}
Exemplo n.º 9
0
/**
  Starts a device controller or a bus controller.

  The Start() function is designed to be invoked from the EFI boot service
  ConnectController(). As a result, much of the error checking on the
  parameters to Start() has been moved into this common boot service. It is
  legal to call Start() from other locations, but the following calling
  restrictions must be followed or the system behavior will not be
  deterministic.
  1. ControllerHandle must be a valid EFI_HANDLE.
  2. If RemainingDevicePath is not NULL, then it must be a pointer to a
     naturally aligned EFI_DEVICE_PATH_PROTOCOL.
  3. Prior to calling Start(), the Supported() function for the driver
     specified by This must have been called with the same calling parameters,
     and Supported() must have returned EFI_SUCCESS.

  @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL
                                   instance.
  @param[in]  ControllerHandle     The handle of the controller to start. This
                                   handle must support a protocol interface
                                   that supplies an I/O abstraction to the
                                   driver.
  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a
                                   device path.  This parameter is ignored by
                                   device drivers, and is optional for bus
                                   drivers. For a bus driver, if this parameter
                                   is NULL, then handles for all the children
                                   of Controller are created by this driver. If
                                   this parameter is not NULL and the first
                                   Device Path Node is not the End of Device
                                   Path Node, then only the handle for the
                                   child device specified by the first Device
                                   Path Node of RemainingDevicePath is created
                                   by this driver. If the first Device Path
                                   Node of RemainingDevicePath is the End of
                                   Device Path Node, no child handle is created
                                   by this driver.

  @retval EFI_SUCCESS              The device was started.
  @retval EFI_DEVICE_ERROR         The device could not be started due to a
                                   device error.
  @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a
                                   lack of resources.
  @retval Others                   The driver failded to start the device.

**/
EFI_STATUS
EFIAPI
SioBusDriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
  )
{
  EFI_STATUS                     Status;
  EFI_PCI_IO_PROTOCOL            *PciIo;
  EFI_DEVICE_PATH_PROTOCOL       *ParentDevicePath;
  UINT64                         Supports;
  UINT64                         OriginalAttributes;
  UINT64                         Attributes;
  BOOLEAN                        Enabled;
  SIO_BUS_DRIVER_PRIVATE_DATA    *Private;
  UINT32                         ChildDeviceNumber;

  Enabled            = FALSE;
  Supports           = 0;
  OriginalAttributes = 0;
  Private            = NULL;

  //
  // Open the PCI I/O Protocol Interface
  //
  PciIo = NULL;
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiPciIoProtocolGuid,
                  (VOID**) &PciIo,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Open Device Path Protocol
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **) &ParentDevicePath,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    gBS->CloseProtocol (
           Controller,
           &gEfiPciIoProtocolGuid,
           This->DriverBindingHandle,
           Controller
           );
    return Status;
  }

  //
  // Get supported PCI attributes
  //
  Status = PciIo->Attributes (
                    PciIo,
                    EfiPciIoAttributeOperationSupported,
                    0,
                    &Supports
                    );
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  Supports &= (UINT64) (EFI_PCI_IO_ATTRIBUTE_ISA_IO |
                        EFI_PCI_IO_ATTRIBUTE_ISA_IO_16);
  if (Supports == 0 ||
      Supports == (EFI_PCI_IO_ATTRIBUTE_ISA_IO |
                   EFI_PCI_IO_ATTRIBUTE_ISA_IO_16)) {
    Status = EFI_UNSUPPORTED;
    goto Done;
  }

  Status = PciIo->Attributes (
                    PciIo,
                    EfiPciIoAttributeOperationGet,
                    0,
                    &OriginalAttributes
                    );
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  Attributes = EFI_PCI_DEVICE_ENABLE |
               Supports |
               EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO;
  Status = PciIo->Attributes (
                    PciIo,
                    EfiPciIoAttributeOperationEnable,
                    Attributes,
                    NULL
                    );
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  Enabled = TRUE;

  //
  // Store the OriginalAttributes for the restore in BindingStop()
  //
  Private = AllocateZeroPool (sizeof (SIO_BUS_DRIVER_PRIVATE_DATA));
  if (Private == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }
  Private->PciIo              = PciIo;
  Private->OriginalAttributes = OriginalAttributes;

  Status = gBS->InstallProtocolInterface (
                  &Controller,
                  &gEfiCallerIdGuid,
                  EFI_NATIVE_INTERFACE,
                  Private
                  );
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  //
  // Report status code for the start of general controller initialization
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_IO_BUS_LPC | EFI_IOB_PC_INIT),
    ParentDevicePath
    );

  //
  // Report status code for the start of enabling devices on the bus
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_IO_BUS_LPC | EFI_IOB_PC_ENABLE),
    ParentDevicePath
    );

  //
  // Create all the children upon the first entrance
  //
  ChildDeviceNumber = SioCreateAllChildDevices (
                        This,
                        Controller,
                        PciIo,
                        ParentDevicePath
                        );
  if (ChildDeviceNumber == 0) {
    Status = EFI_DEVICE_ERROR;
  }

Done:
  if (EFI_ERROR (Status)) {
    if (PciIo != NULL && Enabled) {
      PciIo->Attributes (
               PciIo,
               EfiPciIoAttributeOperationSet,
               OriginalAttributes,
               NULL
               );
    }

    gBS->CloseProtocol (
           Controller,
           &gEfiDevicePathProtocolGuid,
           This->DriverBindingHandle,
           Controller
           );

    gBS->CloseProtocol (
           Controller,
           &gEfiPciIoProtocolGuid,
           This->DriverBindingHandle,
           Controller
           );

    if (Private != NULL) {
      gBS->UninstallMultipleProtocolInterfaces (
             Controller,
             &gEfiCallerIdGuid,
             Private,
             NULL
             );
      FreePool (Private);
    }

    return Status;
  }

  return EFI_SUCCESS;
}
Exemplo n.º 10
0
/**
  Stops a device controller or a bus controller.

  The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
  As a result, much of the error checking on the parameters to Stop() has been moved
  into this common boot service. It is legal to call Stop() from other locations,
  but the following calling restrictions must be followed or the system behavior will not be deterministic.
  1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
     same driver's Start() function.
  2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
     EFI_HANDLE. In addition, all of these handles must have been created in this driver's
     Start() function, and the Start() function must have called OpenProtocol() on
     ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.

  @param[in]  This              A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  @param[in]  ControllerHandle  A handle to the device being stopped. The handle must
                                support a bus specific I/O protocol for the driver
                                to use to stop the device.
  @param[in]  NumberOfChildren  The number of child device handles in ChildHandleBuffer.
  @param[in]  ChildHandleBuffer An array of child handles to be freed. May be NULL
                                if NumberOfChildren is 0.

  @retval EFI_SUCCESS           The device was stopped.
  @retval EFI_DEVICE_ERROR      The device could not be stopped due to a device error.

**/
EFI_STATUS
EFIAPI
SdMmcPciHcDriverBindingStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,
  IN  EFI_HANDLE                      Controller,
  IN  UINTN                           NumberOfChildren,
  IN  EFI_HANDLE                      *ChildHandleBuffer
  )
{
  EFI_STATUS                          Status;
  EFI_SD_MMC_PASS_THRU_PROTOCOL       *PassThru;
  SD_MMC_HC_PRIVATE_DATA              *Private;
  EFI_PCI_IO_PROTOCOL                 *PciIo;
  LIST_ENTRY                          *Link;
  LIST_ENTRY                          *NextLink;
  SD_MMC_HC_TRB                       *Trb;

  DEBUG ((DEBUG_INFO, "SdMmcPciHcDriverBindingStop: Start\n"));

  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiSdMmcPassThruProtocolGuid,
                  (VOID**) &PassThru,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);
  //
  // Close Non-Blocking timer and free Task list.
  //
  if (Private->TimerEvent != NULL) {
    gBS->CloseEvent (Private->TimerEvent);
    Private->TimerEvent = NULL;
  }
  if (Private->ConnectEvent != NULL) {
    gBS->CloseEvent (Private->ConnectEvent);
    Private->ConnectEvent = NULL;
  }
  //
  // As the timer is closed, there is no needs to use TPL lock to
  // protect the critical region "queue".
  //
  for (Link = GetFirstNode (&Private->Queue);
       !IsNull (&Private->Queue, Link);
       Link = NextLink) {
    NextLink = GetNextNode (&Private->Queue, Link);
    RemoveEntryList (Link);
    Trb = SD_MMC_HC_TRB_FROM_THIS (Link);
    Trb->Packet->TransactionStatus = EFI_ABORTED;
    gBS->SignalEvent (Trb->Event);
    SdMmcFreeTrb (Trb);
  }

  //
  // Uninstall Block I/O protocol from the device handle
  //
  Status = gBS->UninstallProtocolInterface (
                  Controller,
                  &gEfiSdMmcPassThruProtocolGuid,
                  &(Private->PassThru)
                  );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  gBS->CloseProtocol (
         Controller,
         &gEfiPciIoProtocolGuid,
         This->DriverBindingHandle,
         Controller
         );
  //
  // Restore original PCI attributes
  //
  PciIo  = Private->PciIo;
  Status = PciIo->Attributes (
                    PciIo,
                    EfiPciIoAttributeOperationSet,
                    Private->PciAttributes,
                    NULL
                    );
  ASSERT_EFI_ERROR (Status);

  FreePool (Private);

  DEBUG ((DEBUG_INFO, "SdMmcPciHcDriverBindingStop: End with %r\n", Status));

  return Status;
}
Exemplo n.º 11
0
/**
  Starts a device controller or a bus controller.

  The Start() function is designed to be invoked from the EFI boot service ConnectController().
  As a result, much of the error checking on the parameters to Start() has been moved into this
  common boot service. It is legal to call Start() from other locations,
  but the following calling restrictions must be followed or the system behavior will not be deterministic.
  1. ControllerHandle must be a valid EFI_HANDLE.
  2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
     EFI_DEVICE_PATH_PROTOCOL.
  3. Prior to calling Start(), the Supported() function for the driver specified by This must
     have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.

  @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  @param[in]  ControllerHandle     The handle of the controller to start. This handle
                                   must support a protocol interface that supplies
                                   an I/O abstraction to the driver.
  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
                                   parameter is ignored by device drivers, and is optional for bus
                                   drivers. For a bus driver, if this parameter is NULL, then handles
                                   for all the children of Controller are created by this driver.
                                   If this parameter is not NULL and the first Device Path Node is
                                   not the End of Device Path Node, then only the handle for the
                                   child device specified by the first Device Path Node of
                                   RemainingDevicePath is created by this driver.
                                   If the first Device Path Node of RemainingDevicePath is
                                   the End of Device Path Node, no child handle is created by this
                                   driver.

  @retval EFI_SUCCESS              The device was started.
  @retval EFI_DEVICE_ERROR         The device could not be started due to a device error.Currently not implemented.
  @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
  @retval Others                   The driver failded to start the device.

**/
EFI_STATUS
EFIAPI
SdMmcPciHcDriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL     *This,
  IN EFI_HANDLE                      Controller,
  IN EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath
  )
{
  EFI_STATUS                      Status;
  SD_MMC_HC_PRIVATE_DATA          *Private;
  EFI_PCI_IO_PROTOCOL             *PciIo;
  UINT64                          Supports;
  UINT64                          PciAttributes;
  UINT8                           SlotNum;
  UINT8                           FirstBar;
  UINT8                           Slot;
  UINT8                           Index;
  CARD_TYPE_DETECT_ROUTINE        *Routine;
  UINT32                          RoutineNum;
  BOOLEAN                         MediaPresent;
  BOOLEAN                         Support64BitDma;

  DEBUG ((DEBUG_INFO, "SdMmcPciHcDriverBindingStart: Start\n"));

  //
  // Open PCI I/O Protocol and save pointer to open protocol
  // in private data area.
  //
  PciIo  = NULL;
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiPciIoProtocolGuid,
                  (VOID **) &PciIo,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Enable the SD Host Controller MMIO space
  //
  Private = NULL;
  Status  = PciIo->Attributes (
                     PciIo,
                     EfiPciIoAttributeOperationGet,
                     0,
                     &PciAttributes
                     );

  if (EFI_ERROR (Status)) {
    goto Done;
  }

  Status = PciIo->Attributes (
                    PciIo,
                    EfiPciIoAttributeOperationSupported,
                    0,
                    &Supports
                    );

  if (!EFI_ERROR (Status)) {
    Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;
    Status    = PciIo->Attributes (
                         PciIo,
                         EfiPciIoAttributeOperationEnable,
                         Supports,
                         NULL
                         );
  } else {
    goto Done;
  }

  Private = AllocateCopyPool (sizeof (SD_MMC_HC_PRIVATE_DATA), &gSdMmcPciHcTemplate);
  if (Private == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }

  Private->ControllerHandle = Controller;
  Private->PciIo            = PciIo;
  Private->PciAttributes    = PciAttributes;
  InitializeListHead (&Private->Queue);

  //
  // Get SD/MMC Pci Host Controller Slot info
  //
  Status = SdMmcHcGetSlotInfo (PciIo, &FirstBar, &SlotNum);
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  Support64BitDma = TRUE;
  for (Slot = FirstBar; Slot < (FirstBar + SlotNum); Slot++) {
    Private->Slot[Slot].Enable = TRUE;

    Status = SdMmcHcGetCapability (PciIo, Slot, &Private->Capability[Slot]);
    if (EFI_ERROR (Status)) {
      continue;
    }
    DumpCapabilityReg (Slot, &Private->Capability[Slot]);

    Support64BitDma &= Private->Capability[Slot].SysBus64;

    Status = SdMmcHcGetMaxCurrent (PciIo, Slot, &Private->MaxCurrent[Slot]);
    if (EFI_ERROR (Status)) {
      continue;
    }

    Private->Slot[Slot].SlotType = Private->Capability[Slot].SlotType;
    if ((Private->Slot[Slot].SlotType != RemovableSlot) && (Private->Slot[Slot].SlotType != EmbeddedSlot)) {
      DEBUG ((DEBUG_INFO, "SdMmcPciHcDxe doesn't support the slot type [%d]!!!\n", Private->Slot[Slot].SlotType));
      continue;
    }

    //
    // Reset the specified slot of the SD/MMC Pci Host Controller
    //
    Status = SdMmcHcReset (PciIo, Slot);
    if (EFI_ERROR (Status)) {
      continue;
    }
    //
    // Check whether there is a SD/MMC card attached
    //
    Status = SdMmcHcCardDetect (PciIo, Slot, &MediaPresent);
    if (EFI_ERROR (Status) && (Status != EFI_MEDIA_CHANGED)) {
      continue;
    } else if (!MediaPresent) {
      DEBUG ((DEBUG_INFO, "SdMmcHcCardDetect: No device attached in Slot[%d]!!!\n", Slot));
      continue;
    }

    Status = SdMmcHcInitHost (PciIo, Slot, Private->Capability[Slot]);
    if (EFI_ERROR (Status)) {
      continue;
    }

    Private->Slot[Slot].MediaPresent = TRUE;
    Private->Slot[Slot].Initialized  = TRUE;
    RoutineNum = sizeof (mCardTypeDetectRoutineTable) / sizeof (CARD_TYPE_DETECT_ROUTINE);
    for (Index = 0; Index < RoutineNum; Index++) {
      Routine = &mCardTypeDetectRoutineTable[Index];
      if (*Routine != NULL) {
        Status = (*Routine) (Private, Slot);
        if (!EFI_ERROR (Status)) {
          break;
        }
      }
    }
    //
    // This card doesn't get initialized correctly.
    //
    if (Index == RoutineNum) {
      Private->Slot[Slot].Initialized = FALSE;
    }
  }

  //
  // Enable 64-bit DMA support in the PCI layer if this controller
  // supports it.
  //
  if (Support64BitDma) {
    Status = PciIo->Attributes (
                      PciIo,
                      EfiPciIoAttributeOperationEnable,
                      EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE,
                      NULL
                      );
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_WARN, "SdMmcPciHcDriverBindingStart: failed to enable 64-bit DMA (%r)\n", Status));
    }
  }

  //
  // Start the asynchronous I/O monitor
  //
  Status = gBS->CreateEvent (
                  EVT_TIMER | EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  ProcessAsyncTaskList,
                  Private,
                  &Private->TimerEvent
                  );
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  Status = gBS->SetTimer (Private->TimerEvent, TimerPeriodic, SD_MMC_HC_ASYNC_TIMER);
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  //
  // Start the Sd removable device connection enumeration
  //
  Status = gBS->CreateEvent (
                  EVT_TIMER | EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  SdMmcPciHcEnumerateDevice,
                  Private,
                  &Private->ConnectEvent
                  );
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  Status = gBS->SetTimer (Private->ConnectEvent, TimerPeriodic, SD_MMC_HC_ENUM_TIMER);
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Controller,
                  &gEfiSdMmcPassThruProtocolGuid,
                  &(Private->PassThru),
                  NULL
                  );

  DEBUG ((DEBUG_INFO, "SdMmcPciHcDriverBindingStart: %r End on %x\n", Status, Controller));

Done:
  if (EFI_ERROR (Status)) {
    if ((Private != NULL) && (Private->PciAttributes != 0)) {
      //
      // Restore original PCI attributes
      //
      PciIo->Attributes (
               PciIo,
               EfiPciIoAttributeOperationSet,
               Private->PciAttributes,
               NULL
               );
    }
    gBS->CloseProtocol (
          Controller,
          &gEfiPciIoProtocolGuid,
          This->DriverBindingHandle,
          Controller
          );

    if ((Private != NULL) && (Private->TimerEvent != NULL)) {
      gBS->CloseEvent (Private->TimerEvent);
    }

    if ((Private != NULL) && (Private->ConnectEvent != NULL)) {
      gBS->CloseEvent (Private->ConnectEvent);
    }

    if (Private != NULL) {
      FreePool (Private);
    }
  }

  return Status;
}
Exemplo n.º 12
0
/**
  Starts a device controller or a bus controller.

  The Start() function is designed to be invoked from the EFI boot service ConnectController().
  As a result, much of the error checking on the parameters to Start() has been moved into this
  common boot service. It is legal to call Start() from other locations,
  but the following calling restrictions must be followed or the system behavior will not be deterministic.
  1. ControllerHandle must be a valid EFI_HANDLE.
  2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
     EFI_DEVICE_PATH_PROTOCOL.
  3. Prior to calling Start(), the Supported() function for the driver specified by This must
     have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.

  @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  @param[in]  ControllerHandle     The handle of the controller to start. This handle
                                   must support a protocol interface that supplies
                                   an I/O abstraction to the driver.
  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
                                   parameter is ignored by device drivers, and is optional for bus
                                   drivers. For a bus driver, if this parameter is NULL, then handles
                                   for all the children of Controller are created by this driver.
                                   If this parameter is not NULL and the first Device Path Node is
                                   not the End of Device Path Node, then only the handle for the
                                   child device specified by the first Device Path Node of
                                   RemainingDevicePath is created by this driver.
                                   If the first Device Path Node of RemainingDevicePath is
                                   the End of Device Path Node, no child handle is created by this
                                   driver.

  @retval EFI_SUCCESS              The device was started.
  @retval EFI_DEVICE_ERROR         The device could not be started due to a device error.Currently not implemented.
  @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
  @retval Others                   The driver failded to start the device.

**/
EFI_STATUS
EFIAPI
UfsHcDriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   Controller,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  EFI_STATUS                        Status;
  EFI_PCI_IO_PROTOCOL               *PciIo;
  UFS_HOST_CONTROLLER_PRIVATE_DATA  *Private;
  UINT64                            Supports;
  UINT8                             BarIndex;
  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *BarDesc;

  PciIo    = NULL;
  Private  = NULL;
  Supports = 0;
  BarDesc  = NULL;

  //
  // Now test and open the EfiPciIoProtocol
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiPciIoProtocolGuid,
                  (VOID **) &PciIo,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  //
  // Status == 0 - A normal execution flow, SUCCESS and the program proceeds.
  // Status == ALREADY_STARTED - A non-zero Status code returned. It indicates
  //           that the protocol has been opened and should be treated as a
  //           normal condition and the program proceeds. The Protocol will not
  //           opened 'again' by this call.
  // Status != ALREADY_STARTED - Error status, terminate program execution
  //
  if (EFI_ERROR (Status)) {
    //
    // EFI_ALREADY_STARTED is also an error
    //
    return Status;
  }

  Private = AllocateCopyPool (sizeof (UFS_HOST_CONTROLLER_PRIVATE_DATA), &gUfsHcTemplate);
  if (Private == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }

  Private->PciIo = PciIo;

  for (BarIndex = 0; BarIndex < PCI_MAX_BAR; BarIndex++) {
    Status = PciIo->GetBarAttributes (
                      PciIo,
                      BarIndex,
                      NULL,
                      (VOID**) &BarDesc
                      );
    if (Status == EFI_UNSUPPORTED) {
      continue;
    } else if (EFI_ERROR (Status)) {
      goto Done;
    }

    if (BarDesc->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
      Private->BarIndex = BarIndex;
      FreePool (BarDesc);
      break;
    }

    FreePool (BarDesc);
  }

  Status = PciIo->Attributes (
                    PciIo,
                    EfiPciIoAttributeOperationGet,
                    0,
                    &Private->PciAttributes
                    );

  if (EFI_ERROR (Status)) {
    goto Done;
  }

  Status = PciIo->Attributes (
                    PciIo,
                    EfiPciIoAttributeOperationSupported,
                    0,
                    &Supports
                    );

  if (!EFI_ERROR (Status)) {
    Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;
    Status    = PciIo->Attributes (
                         PciIo,
                         EfiPciIoAttributeOperationEnable,
                         Supports,
                         NULL
                         );
  } else {
    goto Done;
  }

  ///
  /// Install UFS_HOST_CONTROLLER protocol
  ///
  Status = gBS->InstallProtocolInterface (
                  &Controller,
                  &gEdkiiUfsHostControllerProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  (VOID*)&(Private->UfsHc)
                  );

Done:
  if (EFI_ERROR (Status)) {
    if ((Private != NULL) && (Private->PciAttributes != 0)) {
      //
      // Restore original PCI attributes
      //
      PciIo->Attributes (
               PciIo,
               EfiPciIoAttributeOperationSet,
               Private->PciAttributes,
               NULL
               );
    }
    gBS->CloseProtocol (
          Controller,
          &gEfiPciIoProtocolGuid,
          This->DriverBindingHandle,
          Controller
          );
    if (Private != NULL) {
      FreePool (Private);
    }
  }

  return Status;
}
Exemplo n.º 13
0
EFI_STATUS
EFIAPI
PcatIsaAcpiDriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   Controller,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
/*++

Routine Description:
  Install EFI_ISA_ACPI_PROTOCOL

Arguments:

Returns:

--*/
{
  EFI_STATUS           Status;
  EFI_PCI_IO_PROTOCOL  *PciIo;
  PCAT_ISA_ACPI_DEV    *PcatIsaAcpiDev;
    
  PcatIsaAcpiDev = NULL;
  //
  // Open the PCI I/O Protocol Interface
  //
  PciIo = NULL;
  Status = gBS->OpenProtocol (
                  Controller,       
                  &gEfiPciIoProtocolGuid, 
                  &PciIo,
                  This->DriverBindingHandle,   
                  Controller,   
                  EFI_OPEN_PROTOCOL_BY_DRIVER 
                  );
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  Status = PciIo->Attributes (
                    PciIo, 
                    EfiPciIoAttributeOperationEnable, 
                    EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_ISA_IO | EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO, 
                    NULL 
                    );
  if (EFI_ERROR (Status)) {
    goto Done;
  }
  
  //
  // Allocate memory for the PCAT ISA ACPI Device structure
  //
  PcatIsaAcpiDev = NULL;
  Status = gBS->AllocatePool (
                  EfiBootServicesData,
                  sizeof(PCAT_ISA_ACPI_DEV),
                  &PcatIsaAcpiDev
                  );
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  //
  // Initialize the PCAT ISA ACPI Device structure
  //
  PcatIsaAcpiDev->Signature = PCAT_ISA_ACPI_DEV_SIGNATURE;
  PcatIsaAcpiDev->Handle    = Controller;
  PcatIsaAcpiDev->PciIo     = PciIo;
  
  //
  // IsaAcpi interface
  //
  (PcatIsaAcpiDev->IsaAcpi).DeviceEnumerate  = IsaDeviceEnumerate;
  (PcatIsaAcpiDev->IsaAcpi).SetPower         = IsaDeviceSetPower;
  (PcatIsaAcpiDev->IsaAcpi).GetCurResource   = IsaGetCurrentResource;
  (PcatIsaAcpiDev->IsaAcpi).GetPosResource   = IsaGetPossibleResource;
  (PcatIsaAcpiDev->IsaAcpi).SetResource      = IsaSetResource;
  (PcatIsaAcpiDev->IsaAcpi).EnableDevice     = IsaEnableDevice;
  (PcatIsaAcpiDev->IsaAcpi).InitDevice       = IsaInitDevice;
  (PcatIsaAcpiDev->IsaAcpi).InterfaceInit    = IsaInterfaceInit;
    
  //
  // Install the ISA ACPI Protocol interface
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Controller,
                  &gEfiIsaAcpiProtocolGuid, &PcatIsaAcpiDev->IsaAcpi,
                  NULL
                  );

Done:
  if (EFI_ERROR (Status)) {
    if (PciIo) {
      PciIo->Attributes (
               PciIo, 
               EfiPciIoAttributeOperationDisable, 
               EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_ISA_IO | EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO,
               NULL 
               );
    }
    gBS->CloseProtocol (
           Controller, 
           &gEfiPciIoProtocolGuid, 
           This->DriverBindingHandle, 
           Controller
           );
    if (PcatIsaAcpiDev != NULL) {
      gBS->FreePool (PcatIsaAcpiDev);
    }
    return Status;
  }
          
  return EFI_SUCCESS;
}