Esempio n. 1
0
/**
  The function waits for the boot manager timeout expires or hotkey is pressed.

  It calls PlatformBootManagerWaitCallback each second.

  @param     HotkeyTriggered   Input hotkey event.
**/
VOID
BdsWait (
  IN EFI_EVENT      HotkeyTriggered
  )
{
  EFI_STATUS            Status;
  UINT16                TimeoutRemain;

  DEBUG ((EFI_D_INFO, "[Bds]BdsWait ...Zzzzzzzzzzzz...\n"));

  TimeoutRemain = PcdGet16 (PcdPlatformBootTimeOut);
  while (TimeoutRemain != 0) {
    DEBUG ((EFI_D_INFO, "[Bds]BdsWait(%d)..Zzzz...\n", (UINTN) TimeoutRemain));
    PlatformBootManagerWaitCallback (TimeoutRemain);

    BdsReadKeys (); // BUGBUG: Only reading can signal HotkeyTriggered
                    //         Can be removed after all keyboard drivers invoke callback in timer callback.

    if (HotkeyTriggered != NULL) {
      Status = BdsWaitForSingleEvent (HotkeyTriggered, EFI_TIMER_PERIOD_SECONDS (1));
      if (!EFI_ERROR (Status)) {
        break;
      }
    } else {
      gBS->Stall (1000000);
    }

    //
    // 0xffff means waiting forever
    // BDS with no hotkey provided and 0xffff as timeout will "hang" in the loop
    //
    if (TimeoutRemain != 0xffff) {
      TimeoutRemain--;
    }
  }
  DEBUG ((EFI_D_INFO, "[Bds]Exit the waiting!\n"));
}
Esempio n. 2
0
/**
  Execute the USB mass storage bootability commands with retrial.

  This function executes USB mass storage bootability commands.
  If the device isn't ready, wait for it. If the device is ready
  and error occurs, retry the command again until it exceeds the
  limit of retrial times.

  @param  UsbMass                The device to issue commands to
  @param  Cmd                    The command to execute
  @param  CmdLen                 The length of the command
  @param  DataDir                The direction of data transfer
  @param  Data                   The buffer to hold the data
  @param  DataLen                The length of expected data
  @param  Timeout                The timeout used to transfer

  @retval EFI_SUCCESS            The command is executed successfully.
  @retval EFI_MEDIA_CHANGED      The device media has been changed.
  @retval Others                 Command execution failed after retrial.

**/
EFI_STATUS
UsbBootExecCmdWithRetry (
  IN USB_MASS_DEVICE          *UsbMass,
  IN VOID                     *Cmd,
  IN UINT8                    CmdLen,
  IN EFI_USB_DATA_DIRECTION   DataDir,
  IN VOID                     *Data,
  IN UINT32                   DataLen,
  IN UINT32                   Timeout
  )
{
  EFI_STATUS                  Status;
  UINTN                       Retry;
  EFI_EVENT                   TimeoutEvt;

  Retry  = 0;
  Status = EFI_SUCCESS;
  Status = gBS->CreateEvent (
                  EVT_TIMER,
                  TPL_CALLBACK,
                  NULL,
                  NULL,
                  &TimeoutEvt
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = gBS->SetTimer (TimeoutEvt, TimerRelative, EFI_TIMER_PERIOD_SECONDS(60));
  if (EFI_ERROR (Status)) {
    goto EXIT;
  }

  //
  // Execute the cmd and retry if it fails.
  //
  while (EFI_ERROR (gBS->CheckEvent (TimeoutEvt))) {
    Status = UsbBootExecCmd (
               UsbMass,
               Cmd,
               CmdLen,
               DataDir,
               Data,
               DataLen,
               Timeout
               );
    if (Status == EFI_SUCCESS || Status == EFI_MEDIA_CHANGED || Status == EFI_NO_MEDIA) {
      break;
    }
    //
    // If the sense data shows the drive is not ready, we need execute the cmd again.
    // We limit the upper boundary to 60 seconds.
    //
    if (Status == EFI_NOT_READY) {
      continue;
    }
    //
    // If the status is other error, then just retry 5 times.
    //
    if (Retry++ >= USB_BOOT_COMMAND_RETRY) {
      break;
    }
  }

EXIT:
  if (TimeoutEvt != NULL) {
    gBS->CloseEvent (TimeoutEvt);
  }

  return Status;
}
Esempio n. 3
0
/**
  Discovery SCSI Device

  @param  ScsiIoDevice    The pointer of SCSI_IO_DEV

  @retval  TRUE   Find SCSI Device and verify it.
  @retval  FALSE  Unable to find SCSI Device.

**/
BOOLEAN
DiscoverScsiDevice (
  IN OUT  SCSI_IO_DEV   *ScsiIoDevice
  )
{
  EFI_STATUS            Status;
  UINT32                InquiryDataLength;
  UINT8                 SenseDataLength;
  UINT8                 HostAdapterStatus;
  UINT8                 TargetStatus;
  EFI_SCSI_INQUIRY_DATA *InquiryData;
  UINT8                 MaxRetry;
  UINT8                 Index;
  BOOLEAN               ScsiDeviceFound;

  HostAdapterStatus = 0;
  TargetStatus      = 0;

  InquiryData = AllocateAlignedBuffer (ScsiIoDevice, sizeof (EFI_SCSI_INQUIRY_DATA));
  if (InquiryData == NULL) {
    ScsiDeviceFound = FALSE;
    goto Done;
  }

  //
  // Using Inquiry command to scan for the device
  //
  InquiryDataLength = sizeof (EFI_SCSI_INQUIRY_DATA);
  SenseDataLength   = 0;
  ZeroMem (InquiryData, InquiryDataLength);

  MaxRetry = 2;
  for (Index = 0; Index < MaxRetry; Index++) {
    Status = ScsiInquiryCommand (
              &ScsiIoDevice->ScsiIo,
              EFI_TIMER_PERIOD_SECONDS (1),
              NULL,
              &SenseDataLength,
              &HostAdapterStatus,
              &TargetStatus,
              (VOID *) InquiryData,
              &InquiryDataLength,
              FALSE
              );
    if (!EFI_ERROR (Status)) {
      break;
    } else if ((Status == EFI_BAD_BUFFER_SIZE) || 
               (Status == EFI_INVALID_PARAMETER) ||
               (Status == EFI_UNSUPPORTED)) {
      ScsiDeviceFound = FALSE;
      goto Done;
    }
  }

  if (Index == MaxRetry) {
    ScsiDeviceFound = FALSE;
    goto Done;
  }
  
  //
  // Retrieved inquiry data successfully
  //
  if ((InquiryData->Peripheral_Qualifier != 0) &&
      (InquiryData->Peripheral_Qualifier != 3)) {
    ScsiDeviceFound = FALSE;
    goto Done;
  }

  if (InquiryData->Peripheral_Qualifier == 3) {
    if (InquiryData->Peripheral_Type != 0x1f) {
      ScsiDeviceFound = FALSE;
      goto Done;
    }
  }

  if (0x1e >= InquiryData->Peripheral_Type && InquiryData->Peripheral_Type >= 0xa) {
    ScsiDeviceFound = FALSE;
    goto Done;
  }

  //
  // valid device type and peripheral qualifier combination.
  //
  ScsiIoDevice->ScsiDeviceType  = InquiryData->Peripheral_Type;
  ScsiIoDevice->RemovableDevice = InquiryData->Rmb;
  if (InquiryData->Version == 0) {
    ScsiIoDevice->ScsiVersion = 0;
  } else {
    //
    // ANSI-approved version
    //
    ScsiIoDevice->ScsiVersion = (UINT8) (InquiryData->Version & 0x07);
  }

  ScsiDeviceFound = TRUE;

Done:
  FreeAlignedBuffer (InquiryData, sizeof (EFI_SCSI_INQUIRY_DATA));

  return ScsiDeviceFound;
}