git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3322 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			201 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			201 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Copyright (c) 2006, 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
 | 
						|
//
 | 
						|
EFI_DRIVER_DIAGNOSTICS_PROTOCOL gIDEBusDriverDiagnostics = {
 | 
						|
  IDEBusDriverDiagnosticsRunDiagnostics,
 | 
						|
  "eng"
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
  Runs diagnostics on a controller.
 | 
						|
 | 
						|
  @param  This A pointer to the EFI_DRIVER_DIAGNOSTICS_PROTOCOL
 | 
						|
  instance.
 | 
						|
  @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.
 | 
						|
  See "Related Definitions" for the list of supported
 | 
						|
  types.
 | 
						|
  @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
 | 
						|
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;
 | 
						|
 | 
						|
  *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 EFI_UNSUPPORTED;
 | 
						|
    }
 | 
						|
 | 
						|
    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 EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  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;
 | 
						|
}
 |