mirror of
				https://github.com/acidanthera/audk.git
				synced 2025-11-04 05:25:45 +01:00 
			
		
		
		
	git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8636 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			246 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			246 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Implementation of UEFI driver Dialnostics protocol which to perform diagnostic on the IDE
 | 
						|
  Bus controller.
 | 
						|
  
 | 
						|
  Copyright (c) 2006 - 2008, Intel Corporation                                                         
 | 
						|
  All rights reserved. This program and the accompanying materials                          
 | 
						|
  are licensed and made available under the terms and conditions of the BSD License         
 | 
						|
  which accompanies this distribution.  The full text of the license may be found at        
 | 
						|
  http://opensource.org/licenses/bsd-license.php                                            
 | 
						|
 | 
						|
  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
 | 
						|
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
 | 
						|
#include "IdeBus.h"
 | 
						|
 | 
						|
#define IDE_BUS_DIAGNOSTIC_ERROR  L"PCI IDE/ATAPI Driver Diagnostics Failed"
 | 
						|
 | 
						|
//
 | 
						|
// EFI Driver Diagnostics Protocol
 | 
						|
//
 | 
						|
GLOBAL_REMOVE_IF_UNREFERENCED EFI_DRIVER_DIAGNOSTICS_PROTOCOL gIDEBusDriverDiagnostics = {
 | 
						|
  IDEBusDriverDiagnosticsRunDiagnostics,
 | 
						|
  "eng"
 | 
						|
};
 | 
						|
 | 
						|
//
 | 
						|
// EFI Driver Diagnostics 2 Protocol
 | 
						|
//
 | 
						|
GLOBAL_REMOVE_IF_UNREFERENCED EFI_DRIVER_DIAGNOSTICS2_PROTOCOL gIDEBusDriverDiagnostics2 = {
 | 
						|
  (EFI_DRIVER_DIAGNOSTICS2_RUN_DIAGNOSTICS) IDEBusDriverDiagnosticsRunDiagnostics,
 | 
						|
  "en"
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
  Runs diagnostics on a controller.
 | 
						|
 | 
						|
  @param  This             A pointer to the EFI_DRIVER_DIAGNOSTICS_PROTOCOLinstance.
 | 
						|
  @param  ControllerHandle The handle of the controller to run diagnostics on.
 | 
						|
  @param  ChildHandle      The handle of the child controller to run diagnostics on
 | 
						|
                           This is an optional parameter that may be NULL.  It will
 | 
						|
                           be NULL for device drivers.  It will also be NULL for a
 | 
						|
                           bus drivers that wish to run diagnostics on the bus controller. 
 | 
						|
                           It will not be NULL for a bus driver that wishes to run 
 | 
						|
                           diagnostics on one of its child controllers.
 | 
						|
  @param  DiagnosticType   Indicates type of diagnostics to perform on the controller
 | 
						|
                           specified by ControllerHandle and ChildHandle.
 | 
						|
  @param  Language         A pointer to a three character ISO 639-2 language identifier. 
 | 
						|
                           This is the language in which the optional error message should 
 | 
						|
                           be returned in Buffer, and it must match one of the languages 
 | 
						|
                           specified in SupportedLanguages. The number of languages supported by
 | 
						|
                           a driver is up to the driver writer.
 | 
						|
  @param  ErrorType        A GUID that defines the format of the data returned in Buffer.
 | 
						|
  @param  BufferSize       The size, in bytes, of the data returned in Buffer.
 | 
						|
  @param  Buffer           A buffer that contains a Null-terminated Unicode string
 | 
						|
                           plus some additional data whose format is defined by ErrorType.  
 | 
						|
                           Buffer is allocated by this function with AllocatePool(), and 
 | 
						|
                           it is the caller's responsibility to free it with a call to FreePool().
 | 
						|
 | 
						|
  @retval  EFI_SUCCESS           The controller specified by ControllerHandle and ChildHandle passed 
 | 
						|
                                 the diagnostic.
 | 
						|
  @retval  EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
 | 
						|
  @retval  EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.
 | 
						|
  @retval  EFI_INVALID_PARAMETER Language is NULL.
 | 
						|
  @retval  EFI_INVALID_PARAMETER ErrorType is NULL.
 | 
						|
  @retval  EFI_INVALID_PARAMETER BufferType is NULL.
 | 
						|
  @retval  EFI_INVALID_PARAMETER Buffer is NULL.
 | 
						|
  @retval  EFI_UNSUPPORTED       The driver specified by This does not support running 
 | 
						|
                                 diagnostics for the controller specified by ControllerHandle 
 | 
						|
                                 and ChildHandle.
 | 
						|
  @retval  EFI_UNSUPPORTED       The driver specified by This does not support the
 | 
						|
                                 type of diagnostic specified by DiagnosticType.
 | 
						|
  @retval  EFI_UNSUPPORTED       The driver specified by This does not support the language 
 | 
						|
                                 specified by Language.
 | 
						|
  @retval  EFI_OUT_OF_RESOURCES  There are not enough resources available to complete the 
 | 
						|
                                 diagnostics.
 | 
						|
  @retval  EFI_OUT_OF_RESOURCES  There are not enough resources available to return the 
 | 
						|
                                 status information in ErrorType, BufferSize,and Buffer.
 | 
						|
  @retval  EFI_DEVICE_ERROR      The controller specified by ControllerHandle and ChildHandle 
 | 
						|
                                 did not pass the diagnostic.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
IDEBusDriverDiagnosticsRunDiagnostics (
 | 
						|
  IN  EFI_DRIVER_DIAGNOSTICS_PROTOCOL               *This,
 | 
						|
  IN  EFI_HANDLE                                    ControllerHandle,
 | 
						|
  IN  EFI_HANDLE                                    ChildHandle  OPTIONAL,
 | 
						|
  IN  EFI_DRIVER_DIAGNOSTIC_TYPE                    DiagnosticType,
 | 
						|
  IN  CHAR8                                         *Language,
 | 
						|
  OUT EFI_GUID                                      **ErrorType,
 | 
						|
  OUT UINTN                                         *BufferSize,
 | 
						|
  OUT CHAR16                                        **Buffer
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS            Status;
 | 
						|
  EFI_PCI_IO_PROTOCOL   *PciIo;
 | 
						|
  EFI_BLOCK_IO_PROTOCOL *BlkIo;
 | 
						|
  IDE_BLK_IO_DEV        *IdeBlkIoDevice;
 | 
						|
  UINT32                VendorDeviceId;
 | 
						|
  VOID                  *BlockBuffer;
 | 
						|
  CHAR8                 *SupportedLanguages;
 | 
						|
  BOOLEAN               Iso639Language;
 | 
						|
  BOOLEAN               Found;
 | 
						|
  UINTN                 Index;
 | 
						|
 | 
						|
  if (Language         == NULL ||
 | 
						|
      ErrorType        == NULL ||
 | 
						|
      Buffer           == NULL ||
 | 
						|
      ControllerHandle == NULL ||
 | 
						|
      BufferSize       == NULL) {
 | 
						|
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  SupportedLanguages = This->SupportedLanguages;
 | 
						|
  Iso639Language = (BOOLEAN)(This == &gIDEBusDriverDiagnostics);
 | 
						|
  //
 | 
						|
  // Make sure Language is in the set of Supported Languages
 | 
						|
  //
 | 
						|
  Found = FALSE;
 | 
						|
  while (*SupportedLanguages != 0) {
 | 
						|
    if (Iso639Language) {
 | 
						|
      if (CompareMem (Language, SupportedLanguages, 3) == 0) {
 | 
						|
        Found = TRUE;
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      SupportedLanguages += 3;
 | 
						|
    } else {
 | 
						|
      for (Index = 0; SupportedLanguages[Index] != 0 && SupportedLanguages[Index] != ';'; Index++);
 | 
						|
      if ((AsciiStrnCmp(SupportedLanguages, Language, Index) == 0) && (Language[Index] == 0)) {
 | 
						|
        Found = TRUE;
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      SupportedLanguages += Index;
 | 
						|
      for (; *SupportedLanguages != 0 && *SupportedLanguages == ';'; SupportedLanguages++);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // If Language is not a member of SupportedLanguages, then return EFI_UNSUPPORTED
 | 
						|
  //
 | 
						|
  if (!Found) {
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  *ErrorType  = NULL;
 | 
						|
  *BufferSize = 0;
 | 
						|
 | 
						|
  if (ChildHandle == NULL) {
 | 
						|
    Status = gBS->OpenProtocol (
 | 
						|
                    ControllerHandle,
 | 
						|
                    &gEfiCallerIdGuid,
 | 
						|
                    NULL,
 | 
						|
                    gIDEBusDriverBinding.DriverBindingHandle,
 | 
						|
                    ControllerHandle,
 | 
						|
                    EFI_OPEN_PROTOCOL_TEST_PROTOCOL
 | 
						|
                    );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      return Status;
 | 
						|
    }
 | 
						|
 | 
						|
    Status = gBS->OpenProtocol (
 | 
						|
                    ControllerHandle,
 | 
						|
                    &gEfiPciIoProtocolGuid,
 | 
						|
                    (VOID **) &PciIo,
 | 
						|
                    gIDEBusDriverBinding.DriverBindingHandle,
 | 
						|
                    ControllerHandle,
 | 
						|
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
 | 
						|
                    );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      return EFI_DEVICE_ERROR;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Use services of PCI I/O Protocol to test the PCI IDE/ATAPI Controller
 | 
						|
    // The following test simply reads the Device ID and Vendor ID.
 | 
						|
    // It should never fail.  A real test would perform more advanced
 | 
						|
    // diagnostics.
 | 
						|
    //
 | 
						|
 | 
						|
    Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, 0, 1, &VendorDeviceId);
 | 
						|
    if (EFI_ERROR (Status) || VendorDeviceId == 0xffffffff) {
 | 
						|
      return EFI_DEVICE_ERROR;
 | 
						|
    }
 | 
						|
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = gBS->OpenProtocol (
 | 
						|
                  ChildHandle,
 | 
						|
                  &gEfiBlockIoProtocolGuid,
 | 
						|
                  (VOID **) &BlkIo,
 | 
						|
                  gIDEBusDriverBinding.DriverBindingHandle,
 | 
						|
                  ChildHandle,
 | 
						|
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
 | 
						|
                  );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (BlkIo);
 | 
						|
 | 
						|
  //
 | 
						|
  // Use services available from IdeBlkIoDevice to test the IDE/ATAPI device
 | 
						|
  //
 | 
						|
  Status = gBS->AllocatePool (
 | 
						|
                  EfiBootServicesData,
 | 
						|
                  IdeBlkIoDevice->BlkMedia.BlockSize,
 | 
						|
                  (VOID **) &BlockBuffer
 | 
						|
                  );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = IdeBlkIoDevice->BlkIo.ReadBlocks (
 | 
						|
                                  &IdeBlkIoDevice->BlkIo,
 | 
						|
                                  IdeBlkIoDevice->BlkMedia.MediaId,
 | 
						|
                                  0,
 | 
						|
                                  IdeBlkIoDevice->BlkMedia.BlockSize,
 | 
						|
                                  BlockBuffer
 | 
						|
                                  );
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    *ErrorType  = &gEfiCallerIdGuid;
 | 
						|
    *BufferSize = sizeof (IDE_BUS_DIAGNOSTIC_ERROR);
 | 
						|
 | 
						|
    Status = gBS->AllocatePool (
 | 
						|
                    EfiBootServicesData,
 | 
						|
                    (UINTN) (*BufferSize),
 | 
						|
                    (VOID **) Buffer
 | 
						|
                    );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      return Status;
 | 
						|
    }
 | 
						|
 | 
						|
    CopyMem (*Buffer, IDE_BUS_DIAGNOSTIC_ERROR, *BufferSize);
 | 
						|
 | 
						|
    Status = EFI_DEVICE_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  gBS->FreePool (BlockBuffer);
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 |