/* Sends a SCSI Request Packet to a SCSI device that is attached to the SCSI channel. This function supports both blocking I/O and nonblocking I/O. The blocking I/O functionality is required, and the nonblocking I/O functionality is optional. */
EFI_STATUS EFIAPI IScsiExtScsiPassThruFunction(IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, IN UINT8 *Target, IN UINT64 Lun, IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet, IN EFI_EVENT Event OPTIONAL)
/* Sends a SCSI Request Packet to a SCSI device that is attached to the SCSI channel. This function supports both blocking I/O and nonblocking I/O. The blocking I/O functionality is required, and the nonblocking I/O functionality is optional. */
EFI_STATUS EFIAPI IScsiExtScsiPassThruFunction(IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, IN UINT8 *Target, IN UINT64 Lun, IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet, IN EFI_EVENT Event OPTIONAL)
{
  EFI_STATUS         Status;
  ISCSI_DRIVER_DATA  *Private;
  if (Target[0] != 0) {
    return EFI_INVALID_PARAMETER;
  }
  if ((Packet == NULL) || (Packet->Cdb == NULL)) {
    return EFI_INVALID_PARAMETER;
  }
  Status = IScsiExecuteScsiCommand (This, Target, Lun, Packet);
  if ((Status != EFI_SUCCESS) && (Status != EFI_NOT_READY)) {
    Private = ISCSI_DRIVER_DATA_FROM_EXT_SCSI_PASS_THRU (This);
    if (EFI_ERROR (IScsiSessionReinstatement (Private->Session))) {
      return EFI_DEVICE_ERROR;
    }
    Status = IScsiExecuteScsiCommand (This, Target, Lun, Packet);
  }
  return Status;
}