/*++

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.             

Module Name:

  UsbMassStorageHelper.c
    
Abstract:

  Helper functions for USB Mass Storage Driver

Revision History

--*/

#include "UsbMassStorageHelper.h"

STATIC
BOOLEAN
IsNoMedia (
  IN  REQUEST_SENSE_DATA    *SenseData,
  IN  UINTN                 SenseCounts
  );

STATIC
BOOLEAN
IsMediaError (
  IN  REQUEST_SENSE_DATA    *SenseData,
  IN  UINTN                 SenseCounts
  );

STATIC
BOOLEAN
IsMediaChange (
  IN  REQUEST_SENSE_DATA    *SenseData,
  IN  UINTN                 SenseCounts
  );

STATIC
BOOLEAN
IsDriveReady (
  IN  REQUEST_SENSE_DATA    *SenseData,
  IN  UINTN                 SenseCounts,
  OUT BOOLEAN               *NeedRetry
  );

STATIC
BOOLEAN
IsMediaWriteProtected (
  IN  REQUEST_SENSE_DATA    *SenseData,
  IN  UINTN                 SenseCounts
  );

STATIC
BOOLEAN
IsLogicalUnitCommunicationOverRun (
  IN  REQUEST_SENSE_DATA    *SenseData,
  IN  UINTN                 SenseCounts
  );

EFI_STATUS
USBFloppyPacketCommand (
  USB_FLOPPY_DEV            *UsbFloppyDevice,
  VOID                      *Command,
  UINT8                     CommandSize,
  VOID                      *DataBuffer,
  UINT32                    BufferLength,
  EFI_USB_DATA_DIRECTION    Direction,
  UINT16                    TimeOutInMilliSeconds
  )
/*++

  Routine Description:
    Sends Packet Command to USB Floppy Drive.
  
  Arguments:
    UsbFloppyDevice  -  The USB_FLOPPY_DEV instance.
    Command          -  A pointer to the command packet.
    CommandSize      -  Indicates the size of the command packet.
    DataBuffer       -  A pointer to the buffer for the data transfer
                        after the command packet.              
    BufferLength     -  Indicates the size of the Data Buffer.
    Direction        -  Transfer Direction
    TimeOutInMilliSeconds - Timeout Value
  Returns:  
    EFI_SUCCESS  - Success
--*/    
{
  EFI_USB_ATAPI_PROTOCOL  *UsbAtapiInterface;
  EFI_STATUS              Status;

  UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;
  //
  // Directly calling EFI_USB_ATAPI_PROTOCOL.UsbAtapiPacketCmd()
  // to perform the command request.
  //
  Status = UsbAtapiInterface->UsbAtapiPacketCmd (
                                UsbAtapiInterface,
                                Command,
                                CommandSize,
                                DataBuffer,
                                BufferLength,
                                Direction,
                                TimeOutInMilliSeconds
                                );

  return Status;
}

EFI_STATUS
USBFloppyIdentify (
  IN  USB_FLOPPY_DEV    *UsbFloppyDevice
  )
/*++

  Routine Description:
    Retrieves device information to tell the device type.
  
  Arguments:
    UsbFloppyDevice    The USB_FLOPPY_DEV instance.
      
  Returns:  
    EFI_DEVICE_ERROR - Hardware error
    EFI_SUCCESS      - Success
--*/    
{

  EFI_STATUS        Status;
  USB_INQUIRY_DATA  *Idata;
  BOOLEAN           MediaChange;

  //
  // Send Inquiry Packet Command to get INQUIRY data.
  //
  Status = USBFloppyInquiry (UsbFloppyDevice, &Idata);
  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }
   
  //
  // Get media removable info from INQUIRY data.
  //
  UsbFloppyDevice->BlkIo.Media->RemovableMedia = (UINT8) ((Idata->RMB & 0x80) == 0x80);

  //
  // Identify device type via INQUIRY data.
  //
  switch ((Idata->peripheral_type) & 0x1f) {
  //
  // Floppy
  //
  case 0x00:
    UsbFloppyDevice->DeviceType                 = USBFLOPPY;
    UsbFloppyDevice->BlkIo.Media->MediaId       = 0;
    UsbFloppyDevice->BlkIo.Media->MediaPresent  = FALSE;
    UsbFloppyDevice->BlkIo.Media->LastBlock     = 0;
    UsbFloppyDevice->BlkIo.Media->BlockSize     = 0x200;
    break;

  //
  // CD-ROM
  //
  case 0x05:
    UsbFloppyDevice->DeviceType                 = USBCDROM;
    UsbFloppyDevice->BlkIo.Media->MediaId       = 0;
    UsbFloppyDevice->BlkIo.Media->MediaPresent  = FALSE;
    UsbFloppyDevice->BlkIo.Media->LastBlock     = 0;
    UsbFloppyDevice->BlkIo.Media->BlockSize     = 0x800;
    UsbFloppyDevice->BlkIo.Media->ReadOnly      = TRUE;
    break;

  default:
    gBS->FreePool (Idata);
    return EFI_DEVICE_ERROR;
  };

  //
  // Initialize some device specific data.
  //
  //
  // original sense data numbers
  //
  UsbFloppyDevice->SenseDataNumber = 6;

  if (UsbFloppyDevice->SenseData != NULL) {
    gBS->FreePool (UsbFloppyDevice->SenseData);
    UsbFloppyDevice->SenseData = NULL;
  }

  UsbFloppyDevice->SenseData = AllocatePool (UsbFloppyDevice->SenseDataNumber * sizeof (REQUEST_SENSE_DATA));

  if (UsbFloppyDevice->SenseData == NULL) {
    gBS->FreePool (Idata);
    return EFI_DEVICE_ERROR;
  }
  
  //
  // Get media information.
  //
  UsbFloppyDetectMedia (UsbFloppyDevice, &MediaChange);

  gBS->FreePool (Idata);

  return EFI_SUCCESS;
}

EFI_STATUS
USBFloppyInquiry (
  IN    USB_FLOPPY_DEV        *UsbFloppyDevice,
  OUT   USB_INQUIRY_DATA      **Idata
  )
/*++

  Routine Description:
    Send Inquiry Packet Command to device and retrieve Inquiry Data.
  
  Arguments:
    UsbFloppyDevice    The USB_FLOPPY_DEV instance.
    Idata              A pointer pointing to the address of 
                       Inquiry Data.
      
  Returns:  
    EFI_DEVICE_ERROR - Hardware error
    EFI_SUCCESS      - Success
--*/      
{
  ATAPI_PACKET_COMMAND    Packet;
  EFI_STATUS              Status;
  EFI_USB_ATAPI_PROTOCOL  *UsbAtapiInterface;

  UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;

  //
  // prepare command packet for the Inquiry Packet Command.
  //
  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
  Packet.Inquiry.opcode             = INQUIRY;
  Packet.Inquiry.page_code          = 0;
  Packet.Inquiry.allocation_length  = sizeof (USB_INQUIRY_DATA);

  *Idata = AllocateZeroPool (sizeof (USB_INQUIRY_DATA));
  if (*Idata == NULL) {
    return EFI_DEVICE_ERROR;
  }
  //
  // Send command packet and retrieve requested Inquiry Data.
  //
  Status = USBFloppyPacketCommand (
            UsbFloppyDevice,
            &Packet,
            sizeof (ATAPI_PACKET_COMMAND),
            (VOID *) (*Idata),
            sizeof (USB_INQUIRY_DATA),
            EfiUsbDataIn,
            USBFLPTIMEOUT * 3
            );
  if (EFI_ERROR (Status)) {
    gBS->FreePool (*Idata);
    return EFI_DEVICE_ERROR;
  }

  return EFI_SUCCESS;
}

EFI_STATUS
USBFloppyRead10 (
  IN    USB_FLOPPY_DEV    *UsbFloppyDevice,
  IN    VOID              *Buffer,
  IN    EFI_LBA           Lba,
  IN    UINTN             NumberOfBlocks
  )
/*++

  Routine Description:
    Sends Read10 Packet Command to device to perform data transfer
    from device to host.
  
  Arguments:
    UsbFloppyDevice -   The USB_FLOPPY_DEV instance.
    Buffer          -   A pointer to the destination buffer for the data. 
                        The caller is responsible for either having implicit
                        or explicit ownership of the buffer.
    Lba             -   The starting logical block address to read from 
                        on the device.
    NumberOfBlocks  -   Indicates the number of blocks that the read 
                        operation requests.
      
  Returns:  
    EFI_DEVICE_ERROR - Hardware error
    EFI_SUCCESS      - Success
--*/      
{
  ATAPI_PACKET_COMMAND    Packet;
  READ10_CMD              *Read10Packet;
  UINT16                  MaxBlock;
  UINT16                  BlocksRemaining;
  UINT16                  SectorCount;
  UINT32                  Lba32;
  UINT32                  BlockSize;
  UINT32                  ByteCount;
  VOID                    *ptrBuffer;
  EFI_STATUS              Status;
  UINT16                  TimeOut;
  EFI_USB_ATAPI_PROTOCOL  *UsbAtapiInterface;
  UINTN                   SenseCounts;

  UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;

  //
  // prepare command packet for the Inquiry Packet Command.
  //
  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
  Read10Packet    = &Packet.Read10;
  Lba32           = (UINT32) Lba;
  ptrBuffer       = Buffer;
  BlockSize       = UsbFloppyDevice->BlkIo.Media->BlockSize;

  MaxBlock        = (UINT16) (65536 / BlockSize);
  BlocksRemaining = (UINT16) NumberOfBlocks;

  Status          = EFI_SUCCESS;
  while (BlocksRemaining > 0) {
    if (BlocksRemaining <= MaxBlock) {
      SectorCount = BlocksRemaining;
    } else {
      SectorCount = MaxBlock;
    }
    //
    // fill the Packet data structure
    //
    Read10Packet->opcode = READ_10;

    //
    // Lba0 ~ Lba3 specify the start logical block address of the data transfer.
    // Lba0 is MSB, Lba3 is LSB
    //
    Read10Packet->Lba3  = (UINT8) (Lba32 & 0xff);
    Read10Packet->Lba2  = (UINT8) (Lba32 >> 8);
    Read10Packet->Lba1  = (UINT8) (Lba32 >> 16);
    Read10Packet->Lba0  = (UINT8) (Lba32 >> 24);

    //
    // TranLen0 ~ TranLen1 specify the transfer length in block unit.
    // TranLen0 is MSB, TranLen is LSB
    //
    Read10Packet->TranLen1  = (UINT8) (SectorCount & 0xff);
    Read10Packet->TranLen0  = (UINT8) (SectorCount >> 8);

    ByteCount               = SectorCount * BlockSize;

    TimeOut                 = (UINT16) (SectorCount * USBFLPTIMEOUT);

    Status = USBFloppyPacketCommand (
              UsbFloppyDevice,
              &Packet,
              sizeof (ATAPI_PACKET_COMMAND),
              (VOID *) ptrBuffer,
              ByteCount,
              EfiUsbDataIn,
              TimeOut
              );
    if (EFI_ERROR (Status)) {

      Status = UsbFloppyRequestSense (UsbFloppyDevice, &SenseCounts);
      if (!EFI_ERROR (Status)) {
        if (IsLogicalUnitCommunicationOverRun (
              UsbFloppyDevice->SenseData,
              SenseCounts
              )) {
          Lba32           = (UINT32) Lba;
          ptrBuffer       = Buffer;
          BlocksRemaining = (UINT16) NumberOfBlocks;
          MaxBlock        = (UINT16) (MaxBlock / 4);
          if (MaxBlock < 1) {
            MaxBlock = 1;
          }

          continue;
        }
      } else {
        return EFI_DEVICE_ERROR;
      }
      //
      // retry read10 command
      //
      Status = USBFloppyPacketCommand (
                UsbFloppyDevice,
                &Packet,
                sizeof (ATAPI_PACKET_COMMAND),
                (VOID *) ptrBuffer,
                ByteCount,
                EfiUsbDataIn,
                TimeOut
                );
      if (EFI_ERROR (Status)) {
        return EFI_DEVICE_ERROR;
      }
    }

    Lba32 += SectorCount;
    ptrBuffer       = (UINT8 *) ptrBuffer + SectorCount * BlockSize;
    BlocksRemaining = (UINT16) (BlocksRemaining - SectorCount);
  }

  return Status;
}

EFI_STATUS
USBFloppyReadCapacity (
  IN  USB_FLOPPY_DEV    *UsbFloppyDevice
  )
/*++

  Routine Description:
    Retrieves media capacity information via 
    sending Read Capacity Packet Command.
  
  Arguments:
    UsbFloppyDevice -   The USB_FLOPPY_DEV instance.
      
  Returns:  
    EFI_DEVICE_ERROR - Hardware error
    EFI_SUCCESS      - Success
--*/        
{ 
  //
  // status returned by Read Capacity Packet Command
  //
  EFI_STATUS              Status;
  ATAPI_PACKET_COMMAND    Packet;
  EFI_USB_ATAPI_PROTOCOL  *UsbAtapiInterface;

  //
  // used for capacity data returned from Usb Floppy
  //
  READ_CAPACITY_DATA      Data;

  ZeroMem (&Data, sizeof (Data));

  UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;

  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
  Packet.Inquiry.opcode = READ_CAPACITY;
  Status = USBFloppyPacketCommand (
            UsbFloppyDevice,
            &Packet,
            sizeof (ATAPI_PACKET_COMMAND),
            (VOID *) &Data,
            sizeof (READ_CAPACITY_DATA),
            EfiUsbDataIn,
            USBFLPTIMEOUT
            );

  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  UsbFloppyDevice->BlkIo.Media->LastBlock = (Data.LastLba3 << 24) |
    (Data.LastLba2 << 16) |
    (Data.LastLba1 << 8) |
    Data.LastLba0;

  UsbFloppyDevice->BlkIo.Media->MediaPresent  = TRUE;

  UsbFloppyDevice->BlkIo.Media->BlockSize     = 0x800;

  return EFI_SUCCESS;

}

EFI_STATUS
USBFloppyReadFormatCapacity (
  IN  USB_FLOPPY_DEV    *UsbFloppyDevice
  )
/*++

  Routine Description:
    Retrieves media capacity information via sending Read Format 
    Capacity Packet Command.
  
  Arguments:
    UsbFloppyDevice  - The USB_FLOPPY_DEV instance.
      
  Returns:  
    EFI_DEVICE_ERROR - Hardware error
    EFI_SUCCESS      - Success
--*/         
{ 
  //
  // status returned by Read Capacity Packet Command
  //
  EFI_STATUS                Status;
  ATAPI_PACKET_COMMAND      Packet;
  EFI_USB_ATAPI_PROTOCOL    *UsbAtapiInterface;

  //
  // used for capacity data returned from Usb Floppy
  //
  READ_FORMAT_CAPACITY_DATA FormatData;

  ZeroMem (&FormatData, sizeof (FormatData));

  UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;

  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
  Packet.ReadFormatCapacity.opcode                = READ_FORMAT_CAPACITY;
  Packet.ReadFormatCapacity.allocation_length_lo  = 12;
  Status = USBFloppyPacketCommand (
            UsbFloppyDevice,
            &Packet,
            sizeof (ATAPI_PACKET_COMMAND),
            (VOID *) &FormatData,
            sizeof (READ_FORMAT_CAPACITY_DATA),
            EfiUsbDataIn,
            USBFLPTIMEOUT
            );

  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  if (FormatData.DesCode == 3) {
    //
    // Media is not present
    //
    UsbFloppyDevice->BlkIo.Media->MediaId       = 0;
    UsbFloppyDevice->BlkIo.Media->MediaPresent  = FALSE;
    UsbFloppyDevice->BlkIo.Media->LastBlock     = 0;
  } else {

    UsbFloppyDevice->BlkIo.Media->LastBlock = (FormatData.LastLba3 << 24) |
                                              (FormatData.LastLba2 << 16) | 
                                              (FormatData.LastLba1 << 8)  |
                                               FormatData.LastLba0;

    UsbFloppyDevice->BlkIo.Media->LastBlock--;

    UsbFloppyDevice->BlkIo.Media->BlockSize = (FormatData.BlockSize2 << 16) |
      (FormatData.BlockSize1 << 8) |
      FormatData.BlockSize0;

    UsbFloppyDevice->BlkIo.Media->MediaPresent  = TRUE;

    UsbFloppyDevice->BlkIo.Media->BlockSize     = 0x200;

  }

  return EFI_SUCCESS;

}

EFI_STATUS
UsbFloppyRequestSense (
  IN  USB_FLOPPY_DEV  *UsbFloppyDevice,
  OUT UINTN           *SenseCounts
  )
/*++

  Routine Description:
    Retrieves Sense Data from device via 
    sending Request Sense Packet Command.
  
  Arguments:
    UsbFloppyDevice - The USB_FLOPPY_DEV instance.
    SenseCounts     - A pointer to the number of Sense Data returned.
      
  Returns:  
    EFI_DEVICE_ERROR - Hardware error
    EFI_SUCCESS      - Success
--*/         
{
  EFI_STATUS              Status;
  REQUEST_SENSE_DATA      *Sense;
  UINT8                   *Ptr;
  BOOLEAN                 SenseReq;
  ATAPI_PACKET_COMMAND    Packet;
  EFI_USB_ATAPI_PROTOCOL  *UsbAtapiInterface;

  UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;

  *SenseCounts      = 0;

  ZeroMem (
    UsbFloppyDevice->SenseData,
    sizeof (REQUEST_SENSE_DATA) * (UsbFloppyDevice->SenseDataNumber)
    );
  //
  // fill command packet for Request Sense Packet Command
  //
  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
  Packet.RequestSense.opcode            = REQUEST_SENSE;
  Packet.RequestSense.allocation_length = sizeof (REQUEST_SENSE_DATA);
  
  //
  // initialize pointer
  //
  Ptr = (UINT8 *) (UsbFloppyDevice->SenseData);

  //
  //  request sense data from device continuously
  //  until no sense data exists in the device.
  //
  for (SenseReq = TRUE; SenseReq;) {

    Sense = (REQUEST_SENSE_DATA *) Ptr;

    //
    // send out Request Sense Packet Command and get one Sense
    // data from device.
    //
    Status = USBFloppyPacketCommand (
              UsbFloppyDevice,
              &Packet,
              sizeof (ATAPI_PACKET_COMMAND),
              (VOID *) Ptr,
              sizeof (REQUEST_SENSE_DATA),
              EfiUsbDataIn,
              USBFLPTIMEOUT
              );
    //
    // failed to get Sense data
    //
    if (EFI_ERROR (Status)) {
      //
      // Recovery the device back to normal state.
      //
      UsbFloppyDevice->AtapiProtocol->UsbAtapiReset (
                                        UsbFloppyDevice->AtapiProtocol,
                                        TRUE
                                        );

      if (*SenseCounts == 0) {
        //
        // never retrieved any sense data from device,
        // just return error.
        //
        return EFI_DEVICE_ERROR;
      } else {
        //
        // has retrieved some sense data from device,
        // so return success.
        //
        return EFI_SUCCESS;
      }
    }

    if (Sense->sense_key != SK_NO_SENSE) {
      //
      // Ptr is byte based pointer
      //
      Ptr += sizeof (REQUEST_SENSE_DATA);

      (*SenseCounts)++;

    } else {
      //
      // when no sense key, skip out the loop
      //
      SenseReq = FALSE;
    }
  
    //
    // If the sense key numbers exceed Sense Data Buffer size,
    // just skip the loop and do not fetch the sense key in this function.
    //
    if (*SenseCounts == UsbFloppyDevice->SenseDataNumber) {
      SenseReq = FALSE;
    }
  }

  return EFI_SUCCESS;
}

EFI_STATUS
UsbFloppyTestUnitReady (
  IN  USB_FLOPPY_DEV    *UsbFloppyDevice
  )
/*++

  Routine Description:
    Sends Test Unit ReadyPacket Command to the device.
  
  Arguments:
    UsbFloppyDevice -  The USB_FLOPPY_DEV instance.
      
  Returns:  
    EFI_DEVICE_ERROR - Hardware error
    EFI_SUCCESS      - Success
--*/  
{ 
  ATAPI_PACKET_COMMAND      Packet; 
  EFI_STATUS                Status;
  EFI_USB_ATAPI_PROTOCOL    *UsbAtapiInterface;
  UINT32                    RetryIndex;
  UINT32                    MaximumRetryTimes;
  
  UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;
  MaximumRetryTimes = 2;
  //
  // fill command packet  
  //
  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
  Packet.TestUnitReady.opcode = TEST_UNIT_READY;

  //
  // send command packet
  //
  Status = EFI_DEVICE_ERROR;

  for (RetryIndex = 0; RetryIndex < MaximumRetryTimes && EFI_ERROR (Status); RetryIndex++) {

    Status = USBFloppyPacketCommand (
              UsbFloppyDevice,
              &Packet,
              sizeof (ATAPI_PACKET_COMMAND),
              NULL,
              0,
              EfiUsbNoData,
              USBFLPTIMEOUT
              );

    if (EFI_ERROR (Status)) {
      gBS->Stall (100 * STALL_1_MILLI_SECOND);
    }
  }

  return Status;
}

EFI_STATUS
USBFloppyWrite10 (
  IN    USB_FLOPPY_DEV    *UsbFloppyDevice,
  IN    VOID              *Buffer,
  IN    EFI_LBA           Lba,
  IN    UINTN             NumberOfBlocks
  )
/*++

  Routine Description:
    Sends Write10 Packet Command to device to perform data transfer
    from host to device.
  
  Arguments:
    UsbFloppyDevice -   The USB_FLOPPY_DEV instance.
    Buffer          -   A pointer to the source buffer for the data. 
                        The caller is responsible for either having implicit
                        or explicit ownership of the buffer.
    Lba             -   The starting logical block address to written to 
                        the device.
    NumberOfBlocks  -   Indicates the number of blocks that the write 
                        operation requests.
      
  Returns:  
    EFI_DEVICE_ERROR - Hardware error
    EFI_SUCCESS      - Success
--*/      
{
  ATAPI_PACKET_COMMAND    Packet;
  READ10_CMD              *Write10Packet;
  UINT16                  MaxBlock;
  UINT16                  BlocksRemaining;
  UINT16                  SectorCount;
  UINT32                  Lba32;
  UINT32                  BlockSize;
  UINT32                  ByteCount;
  VOID                    *ptrBuffer;
  EFI_STATUS              Status;
  UINT16                  TimeOut;
  EFI_USB_ATAPI_PROTOCOL  *UsbAtapiInterface;
  UINTN                   SenseCounts;

  UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;

  //
  // prepare command packet for the Write10 Packet Command.
  //
  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
  Write10Packet   = &Packet.Read10;
  Lba32           = (UINT32) Lba;
  ptrBuffer       = Buffer;
  BlockSize       = UsbFloppyDevice->BlkIo.Media->BlockSize;

  MaxBlock        = (UINT16) (65536 / BlockSize);
  BlocksRemaining = (UINT16) NumberOfBlocks;

  Status          = EFI_SUCCESS;
  while (BlocksRemaining > 0) {

    if (BlocksRemaining <= MaxBlock) {

      SectorCount = BlocksRemaining;
    } else {

      SectorCount = MaxBlock;
    }
    //
    // fill the Packet data structure
    //
    Write10Packet->opcode = WRITE_10;

    //
    // Lba0 ~ Lba3 specify the start logical block address
    // of the data transfer.
    // Lba0 is MSB, Lba3 is LSB
    //
    Write10Packet->Lba3 = (UINT8) (Lba32 & 0xff);
    Write10Packet->Lba2 = (UINT8) (Lba32 >> 8);
    Write10Packet->Lba1 = (UINT8) (Lba32 >> 16);
    Write10Packet->Lba0 = (UINT8) (Lba32 >> 24);

    //
    // TranLen0 ~ TranLen1 specify the transfer length in block unit.
    // TranLen0 is MSB, TranLen is LSB
    //
    Write10Packet->TranLen1 = (UINT8) (SectorCount & 0xff);
    Write10Packet->TranLen0 = (UINT8) (SectorCount >> 8);

    ByteCount               = SectorCount * BlockSize;

    TimeOut                 = (UINT16) (SectorCount * USBFLPTIMEOUT);

    Status = USBFloppyPacketCommand (
              UsbFloppyDevice,
              &Packet,
              sizeof (ATAPI_PACKET_COMMAND),
              (VOID *) ptrBuffer,
              ByteCount,
              EfiUsbDataOut,
              TimeOut
              );
    if (EFI_ERROR (Status)) {
      Status = UsbFloppyRequestSense (UsbFloppyDevice, &SenseCounts);
      if (!EFI_ERROR (Status)) {
        if (IsLogicalUnitCommunicationOverRun (
              UsbFloppyDevice->SenseData,
              SenseCounts
              )) {
          Lba32           = (UINT32) Lba;
          ptrBuffer       = Buffer;
          BlocksRemaining = (UINT16) NumberOfBlocks;
          MaxBlock        = (UINT16) (MaxBlock / 4);
          if (MaxBlock < 1) {
            MaxBlock = 1;
          }

          continue;
        }
      }
      //
      // retry write10 command
      //
      Status = USBFloppyPacketCommand (
                UsbFloppyDevice,
                &Packet,
                sizeof (ATAPI_PACKET_COMMAND),
                (VOID *) ptrBuffer,
                ByteCount,
                EfiUsbDataOut,
                TimeOut
                );
      if (EFI_ERROR (Status)) {
        return EFI_DEVICE_ERROR;
      }
    }

    Lba32 += SectorCount;
    ptrBuffer       = (UINT8 *) ptrBuffer + SectorCount * BlockSize;
    BlocksRemaining = (UINT16) (BlocksRemaining - SectorCount);
  }

  return Status;
}

EFI_STATUS
UsbFloppyDetectMedia (
  IN  USB_FLOPPY_DEV  *UsbFloppyDevice,
  OUT BOOLEAN         *MediaChange
  )
/*++

  Routine Description:
    Retrieves media information.
  
  Arguments:
    UsbFloppyDevice  -  The USB_FLOPPY_DEV instance.
    MediaChange      -  Indicates whether media was changed.
      
  Returns:  
    EFI_DEVICE_ERROR - Hardware error
    EFI_SUCCESS      - Success
    EFI_INVALID_PARAMETER - Parameter is error
--*/        
{
  EFI_STATUS          Status;
  EFI_STATUS          FloppyStatus;
  //
  // the following variables are used to record previous media information
  //
  EFI_BLOCK_IO_MEDIA  OldMediaInfo;
  UINTN               SenseCounts;
  UINTN               RetryIndex;
  UINTN               RetryTimes;
  UINTN               MaximumRetryTimes;
  BOOLEAN             NeedRetry;

  //
  // a flag used to determine whether need to perform Read Capacity command.
  //
  BOOLEAN             NeedReadCapacity;

  REQUEST_SENSE_DATA  *SensePtr;

  //
  // init
  //
  Status            = EFI_SUCCESS;
  FloppyStatus      = EFI_SUCCESS;
  CopyMem (&OldMediaInfo, UsbFloppyDevice->BlkIo.Media, sizeof (OldMediaInfo));
  //OldMediaInfo      = *UsbFloppyDevice->BlkIo.Media;
  *MediaChange      = FALSE;
  NeedReadCapacity  = TRUE;

  //
  // if there is no media present,or media not changed,
  // the request sense command will detect faster than read capacity command.
  // read capacity command can be bypassed, thus improve performance.
  //
  SenseCounts = 0;
  Status      = UsbFloppyRequestSense (UsbFloppyDevice, &SenseCounts);

  if (!EFI_ERROR (Status)) {

    SensePtr = UsbFloppyDevice->SenseData;

    //
    // No Media
    //
    if (IsNoMedia (UsbFloppyDevice->SenseData, SenseCounts)) {

      NeedReadCapacity = FALSE;
      UsbFloppyDevice->BlkIo.Media->MediaId = 0;
      UsbFloppyDevice->BlkIo.Media->MediaPresent = FALSE;
      UsbFloppyDevice->BlkIo.Media->LastBlock = 0;
    } else {
      //
      // Media Changed
      //
      if (IsMediaChange (UsbFloppyDevice->SenseData, SenseCounts)) {
        UsbFloppyDevice->BlkIo.Media->MediaId++;
      }
        
      //
      // Media Write-protected
      //
      if (IsMediaWriteProtected (UsbFloppyDevice->SenseData, SenseCounts)) {
        UsbFloppyDevice->BlkIo.Media->ReadOnly = TRUE;
      }
        
      //
      // Media Error
      //
      if (IsMediaError (UsbFloppyDevice->SenseData, SenseCounts)) {
        //
        // if media error encountered, make it look like no media present.
        //
        UsbFloppyDevice->BlkIo.Media->MediaId       = 0;
        UsbFloppyDevice->BlkIo.Media->MediaPresent  = FALSE;
        UsbFloppyDevice->BlkIo.Media->LastBlock     = 0;
      }

    }

  }

  if (NeedReadCapacity) {
    //
    // at most retry 5 times
    //
    MaximumRetryTimes = 5;
    //
    // initial retry twice
    //
    RetryTimes        = 2;

    for (RetryIndex = 0; (RetryIndex < RetryTimes) && (RetryIndex < MaximumRetryTimes); RetryIndex++) {
      //
      // Using different command to retrieve media capacity.
      //
      switch (UsbFloppyDevice->DeviceType) {

      case USBCDROM:
        Status = USBFloppyReadCapacity (UsbFloppyDevice);
        break;

      case USBFLOPPY:
        UsbMassStorageModeSense (UsbFloppyDevice);
        Status = USBFloppyReadFormatCapacity (UsbFloppyDevice);
        if (EFI_ERROR (Status) || !UsbFloppyDevice->BlkMedia.MediaPresent) {
          //
          // retry the ReadCapacity command
          //
          UsbFloppyDevice->DeviceType = USBFLOPPY2;
          Status                      = EFI_DEVICE_ERROR;
        }
        break;

      case USBFLOPPY2:
        UsbMassStorageModeSense (UsbFloppyDevice);
        Status = USBFloppyReadCapacity (UsbFloppyDevice);
        if (EFI_ERROR (Status)) {
          //
          // retry the ReadFormatCapacity command
          //
          UsbFloppyDevice->DeviceType = USBFLOPPY;
        }
        //
        // force the BlockSize to be 0x200.
        //
        UsbFloppyDevice->BlkIo.Media->BlockSize = 0x200;
        break;

      default:
        return EFI_INVALID_PARAMETER;
      }

      if (!EFI_ERROR (Status)) {
        //
        // skip the loop when read capacity succeeds.
        //
        break;
      }

      SenseCounts   = 0;

      FloppyStatus  = UsbFloppyRequestSense (UsbFloppyDevice, &SenseCounts);

      //
      // If Request Sense data failed,retry.
      //
      if (EFI_ERROR (FloppyStatus)) {
        //
        // retry once more
        //
        RetryTimes++;
        continue;
      }
      //
      // No Media
      //
      if (IsNoMedia (UsbFloppyDevice->SenseData, SenseCounts)) {

        UsbFloppyDevice->BlkIo.Media->MediaId       = 0;
        UsbFloppyDevice->BlkIo.Media->MediaPresent  = FALSE;
        UsbFloppyDevice->BlkIo.Media->LastBlock     = 0;
        break;
      }

      if (IsMediaError (UsbFloppyDevice->SenseData, SenseCounts)) {
        //
        // if media error encountered, make it look like no media present.
        //
        UsbFloppyDevice->BlkIo.Media->MediaId       = 0;
        UsbFloppyDevice->BlkIo.Media->MediaPresent  = FALSE;
        UsbFloppyDevice->BlkIo.Media->LastBlock     = 0;
        break;
      }

      if (IsMediaWriteProtected (UsbFloppyDevice->SenseData, SenseCounts)) {
        UsbFloppyDevice->BlkIo.Media->ReadOnly = TRUE;
        continue;
      }

      if (!IsDriveReady (UsbFloppyDevice->SenseData, SenseCounts, &NeedRetry)) {
          
        //
        // Drive not ready: if NeedRetry, then retry once more;
        // else return error
        //
        if (NeedRetry) {
          //
          // Stall 0.1 second to wait for drive becoming ready
          //
          gBS->Stall (100 * STALL_1_MILLI_SECOND);
          //
          // reset retry variable to zero,
          // to make it retry for "drive in progress of becoming ready".
          //
          RetryIndex = 0;
          continue;
        } else {
          return EFI_DEVICE_ERROR;
        }
      }
      //
      // if read capacity fail not for above reasons, retry once more
      //
      RetryTimes++;

    }
    //
    // ENDFOR
    //

    //
    // tell whether the readcapacity process is successful or not
    // ("Status" variable record the latest status returned
    // by ReadCapacity AND "FloppyStatus" record the latest status
    // returned by RequestSense)
    //
    if (EFI_ERROR (Status) && EFI_ERROR (FloppyStatus)) {
      return EFI_DEVICE_ERROR;
    }

  }

  if (UsbFloppyDevice->BlkIo.Media->MediaPresent != OldMediaInfo.MediaPresent) {

    if (UsbFloppyDevice->BlkIo.Media->MediaPresent) {
      UsbFloppyDevice->BlkIo.Media->MediaId = 1;
    }

    *MediaChange = TRUE;
  }

  if (UsbFloppyDevice->BlkIo.Media->ReadOnly != OldMediaInfo.ReadOnly) {
    *MediaChange = TRUE;
    UsbFloppyDevice->BlkIo.Media->MediaId += 1;
  }

  if (UsbFloppyDevice->BlkIo.Media->BlockSize != OldMediaInfo.BlockSize) {
    *MediaChange = TRUE;
    UsbFloppyDevice->BlkIo.Media->MediaId += 1;
  }

  if (UsbFloppyDevice->BlkIo.Media->LastBlock != OldMediaInfo.LastBlock) {
    *MediaChange = TRUE;
    UsbFloppyDevice->BlkIo.Media->MediaId += 1;
  }

  if (UsbFloppyDevice->BlkIo.Media->MediaId != OldMediaInfo.MediaId) {
    *MediaChange = TRUE;
  }

  return EFI_SUCCESS;
}



EFI_STATUS
UsbFloppyModeSense5APage5 (
  IN  USB_FLOPPY_DEV    *UsbFloppyDevice
  )
/*++

  Routine Description:
    Retrieves media capacity information via sending Read Format 
    Capacity Packet Command.
  
  Arguments:
    UsbFloppyDevice  - The USB_FLOPPY_DEV instance.
      
  Returns:  
    EFI_DEVICE_ERROR - Hardware error
    EFI_SUCCESS      - Success
    
--*/         
{ 
  //
  // status returned by Read Capacity Packet Command
  //
  EFI_STATUS                Status;
  ATAPI_PACKET_COMMAND      Packet;
  EFI_USB_ATAPI_PROTOCOL    *UsbAtapiInterface;
  UFI_MODE_PARAMETER_PAGE_5 ModePage5;
  EFI_LBA                   LastBlock;
  UINT32                    SectorsPerTrack;
  UINT32                    NumberOfCylinders;
  UINT32                    NumberOfHeads;
  UINT32                    DataBytesPerSector;

  UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;

  ZeroMem (&ModePage5, sizeof (UFI_MODE_PARAMETER_PAGE_5));

  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
  Packet.ModeSenseUFI.opcode    = UFI_MODE_SENSE5A;
  //
  // Flexible Disk Page
  //
  Packet.ModeSenseUFI.page_code = 5;
  //
  // current values
  //
  Packet.ModeSenseUFI.page_control = 0;
  Packet.ModeSenseUFI.parameter_list_length_hi  = 0;
  Packet.ModeSenseUFI.parameter_list_length_lo  = sizeof (UFI_MODE_PARAMETER_PAGE_5);
  Status = USBFloppyPacketCommand (
            UsbFloppyDevice,
            &Packet,
            sizeof (ATAPI_PACKET_COMMAND),
            (VOID *) &ModePage5,
            sizeof (UFI_MODE_PARAMETER_PAGE_5),
            EfiUsbDataIn,
            USBFLPTIMEOUT
            );

  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  NumberOfHeads   = ModePage5.flex_disk_page.number_of_heads;
  SectorsPerTrack = ModePage5.flex_disk_page.sectors_per_track;
  NumberOfCylinders = ModePage5.flex_disk_page.number_of_cylinders_msb << 8 |
                      ModePage5.flex_disk_page.number_of_cylinders_lsb;

  LastBlock = SectorsPerTrack * NumberOfHeads * NumberOfCylinders;
  DataBytesPerSector = ModePage5.flex_disk_page.databytes_per_sector_msb << 8 |
                       ModePage5.flex_disk_page.databytes_per_sector_lsb;

  UsbFloppyDevice->BlkIo.Media->LastBlock = LastBlock;

  UsbFloppyDevice->BlkIo.Media->LastBlock--;

  UsbFloppyDevice->BlkIo.Media->BlockSize     = DataBytesPerSector;

  UsbFloppyDevice->BlkIo.Media->MediaPresent  = TRUE;

  UsbFloppyDevice->BlkIo.Media->ReadOnly      =
  ModePage5.mode_param_header.write_protected;

  return EFI_SUCCESS;

}

EFI_STATUS
UsbFloppyModeSense5APage1C (
  IN  USB_FLOPPY_DEV    *UsbFloppyDevice
  )
/*++

  Routine Description:
    Retrieves media capacity information via sending Read Format 
    Capacity Packet Command.
  
  Arguments:
    UsbFloppyDevice  - The USB_FLOPPY_DEV instance.
      
  Returns:  
    EFI_DEVICE_ERROR - Hardware error
    EFI_SUCCESS      - Success
    
--*/         
{ 
  //
  // status returned by Read Capacity Packet Command
  //
  EFI_STATUS                  Status;
  ATAPI_PACKET_COMMAND        Packet;
  EFI_USB_ATAPI_PROTOCOL      *UsbAtapiInterface;
  UFI_MODE_PARAMETER_PAGE_1C  ModePage1C;

  UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;

  ZeroMem (&ModePage1C, sizeof (UFI_MODE_PARAMETER_PAGE_1C));

  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
  Packet.ModeSenseUFI.opcode    = UFI_MODE_SENSE5A;
  //
  // Flexible Disk Page
  //
  Packet.ModeSenseUFI.page_code = 0x1C;
  //
  // current values
  //
  Packet.ModeSenseUFI.page_control = 0;
  Packet.ModeSenseUFI.parameter_list_length_hi  = 0;
  Packet.ModeSenseUFI.parameter_list_length_lo  = sizeof (UFI_MODE_PARAMETER_PAGE_1C);
  Status = USBFloppyPacketCommand (
            UsbFloppyDevice,
            &Packet,
            sizeof (ATAPI_PACKET_COMMAND),
            (VOID *) &ModePage1C,
            sizeof (UFI_MODE_PARAMETER_PAGE_1C),
            EfiUsbDataIn,
            USBFLPTIMEOUT
            );

  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  UsbFloppyDevice->BlkIo.Media->ReadOnly = ModePage1C.mode_param_header.write_protected;

  return EFI_SUCCESS;

}

EFI_STATUS
UsbMassStorageModeSense (
  IN  USB_FLOPPY_DEV    *UsbFloppyDevice
  )
{
  if (UsbFloppyDevice->AtapiProtocol->CommandProtocol == EFI_USB_SUBCLASS_SCSI) {
    return UsbSCSIModeSense1APage3F (UsbFloppyDevice);
  } else {
    return UsbFloppyModeSense5APage3F (UsbFloppyDevice);
  }
}

EFI_STATUS
UsbFloppyModeSense5APage3F (
  IN  USB_FLOPPY_DEV    *UsbFloppyDevice
  )
/*++

  Routine Description:
    Retrieves mode sense information via sending Mode Sense
    Packet Command.
  
  Arguments:
    UsbFloppyDevice  - The USB_FLOPPY_DEV instance.
      
  Returns:  
    EFI_DEVICE_ERROR - Hardware error
    EFI_SUCCESS      - Success

--*/         
{ 
  //
  // status returned by Read Capacity Packet Command
  //
  EFI_STATUS                Status;
  ATAPI_PACKET_COMMAND      Packet;
  EFI_USB_ATAPI_PROTOCOL    *UsbAtapiInterface;
  UFI_MODE_PARAMETER_HEADER Header;
  UINT32                    Size;

  UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;

  Size              = sizeof (UFI_MODE_PARAMETER_HEADER);

  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
  Packet.ModeSenseUFI.opcode                    = UFI_MODE_SENSE5A;
  Packet.ModeSenseUFI.page_code                 = 0x3F;
  Packet.ModeSenseUFI.page_control              = 0;
  Packet.ModeSenseUFI.parameter_list_length_hi  = 0;
  Packet.ModeSenseUFI.parameter_list_length_lo  = (UINT8) Size;
  Status = USBFloppyPacketCommand (
            UsbFloppyDevice,
            &Packet,
            sizeof (ATAPI_PACKET_COMMAND),
            &Header,
            Size,
            EfiUsbDataIn,
            USBFLPTIMEOUT
            );

  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  UsbFloppyDevice->BlkIo.Media->ReadOnly = Header.write_protected;

  return EFI_SUCCESS;

}

EFI_STATUS
UsbSCSIModeSense1APage3F (
  IN  USB_FLOPPY_DEV    *UsbFloppyDevice
  )
/*++

  Routine Description:
    Retrieves mode sense information via sending Mode Sense
    Packet Command.
  
  Arguments:
    UsbFloppyDevice  - The USB_FLOPPY_DEV instance.
      
  Returns:  
    EFI_DEVICE_ERROR - Hardware error
    EFI_SUCCESS      - Success
    
--*/  
{ 
  //
  // status returned by Read Capacity Packet Command
  //
  EFI_STATUS                  Status;
  ATAPI_PACKET_COMMAND        Packet;
  EFI_USB_ATAPI_PROTOCOL      *UsbAtapiInterface;
  SCSI_MODE_PARAMETER_HEADER6 Header;
  UINT32                      Size;

  UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;

  Size              = sizeof (SCSI_MODE_PARAMETER_HEADER6);

  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
  Packet.ModeSenseSCSI.opcode             = SCSI_MODE_SENSE1A;
  Packet.ModeSenseSCSI.page_code          = 0x3F;
  Packet.ModeSenseSCSI.page_control       = 0;
  Packet.ModeSenseSCSI.allocation_length  = (UINT8) Size;
  Status = USBFloppyPacketCommand (
            UsbFloppyDevice,
            &Packet,
            sizeof (MODE_SENSE_CMD_SCSI),
            &Header,
            Size,
            EfiUsbDataIn,
            USBFLPTIMEOUT
            );

  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  UsbFloppyDevice->BlkIo.Media->ReadOnly = Header.write_protected;
  return EFI_SUCCESS;

}

/*++

  The following functions are a set of helper functions,
  which are used to parse sense key returned by the device.

--*/
BOOLEAN
IsNoMedia (
  IN  REQUEST_SENSE_DATA    *SenseData,
  IN  UINTN                 SenseCounts
  )
{
  REQUEST_SENSE_DATA  *SensePtr;
  UINTN               Index;
  BOOLEAN             NoMedia;

  NoMedia   = FALSE;

  SensePtr  = SenseData;

  for (Index = 0; Index < SenseCounts; Index++) {

    if ((SensePtr->sense_key == SK_NOT_READY) && 
        (SensePtr->addnl_sense_code == ASC_NO_MEDIA)) {

      NoMedia = TRUE;
    }

    SensePtr++;
  }

  return NoMedia;
}


BOOLEAN
IsMediaError (
  IN  REQUEST_SENSE_DATA    *SenseData,
  IN  UINTN                 SenseCounts
  )
{
  REQUEST_SENSE_DATA  *SensePtr;
  UINTN               Index;
  BOOLEAN             IsError;

  IsError   = FALSE;
  SensePtr  = SenseData;

  for (Index = 0; Index < SenseCounts; Index++) {

    switch (SensePtr->sense_key) {
      
    //
    // Medium error case
    //
    case SK_MEDIUM_ERROR:
      switch (SensePtr->addnl_sense_code) {

      case ASC_MEDIA_ERR1:
      case ASC_MEDIA_ERR2:
      case ASC_MEDIA_ERR3:
      case ASC_MEDIA_ERR4:
        IsError = TRUE;
        break;

      default:
        break;
      }

      break;

    //
    // Medium upside-down case
    //
    case SK_NOT_READY:
      switch (SensePtr->addnl_sense_code) {
      case ASC_MEDIA_UPSIDE_DOWN:
        IsError = TRUE;
        break;

      default:
        break;
      }
      break;

    default:
      break;
    }

    SensePtr++;
  }

  return IsError;
}

BOOLEAN
IsMediaChange (
  IN  REQUEST_SENSE_DATA    *SenseData,
  IN  UINTN                 SenseCounts
  )
{
  REQUEST_SENSE_DATA  *SensePtr;
  UINTN               Index;
  BOOLEAN             MediaChanged;

  MediaChanged  = FALSE;
  SensePtr      = SenseData;

  for (Index = 0; Index < SenseCounts; Index++) {

    if ((SensePtr->sense_key == SK_UNIT_ATTENTION) &&
        (SensePtr->addnl_sense_code == ASC_MEDIA_CHANGE)) {

      MediaChanged = TRUE;
    }

    SensePtr++;
  }

  return MediaChanged;
}

BOOLEAN
IsDriveReady (
  IN  REQUEST_SENSE_DATA    *SenseData,
  IN  UINTN                 SenseCounts,
  OUT BOOLEAN               *NeedRetry
  )
{
  REQUEST_SENSE_DATA  *SensePtr;
  UINTN               Index;
  BOOLEAN             IsReady;

  IsReady     = TRUE;
  *NeedRetry  = FALSE;
  SensePtr    = SenseData;

  for (Index = 0; Index < SenseCounts; Index++) {

    if ((SensePtr->sense_key == SK_NOT_READY) &&
        (SensePtr->addnl_sense_code == ASC_NOT_READY)) {

      switch (SensePtr->addnl_sense_code_qualifier) {

      case ASCQ_IN_PROGRESS:
      case ASCQ_DEVICE_BUSY:
        IsReady     = FALSE;
        *NeedRetry  = TRUE;
        break;

      default:
        //
        // Drive is in error condition,
        // no need to retry.
        //
        IsReady     = FALSE;
        *NeedRetry  = FALSE;
        break;
      }
    }

    SensePtr++;
  }

  return IsReady;
}

BOOLEAN
IsMediaWriteProtected (
  IN  REQUEST_SENSE_DATA    *SenseData,
  IN  UINTN                 SenseCounts
  )
{
  REQUEST_SENSE_DATA  *SensePtr;
  UINTN               Index;
  BOOLEAN             IsWriteProtected;

  IsWriteProtected  = FALSE;
  SensePtr          = SenseData;

  for (Index = 0; Index < SenseCounts; Index++) {
    //
    // catch media write-protected condition.
    //
    if ((SensePtr->sense_key == SK_DATA_PROTECT) &&
        (SensePtr->addnl_sense_code == ASC_WRITE_PROTECTED)) {

      IsWriteProtected = TRUE;
    }

    SensePtr++;
  }

  return IsWriteProtected;
}

BOOLEAN
IsLogicalUnitCommunicationOverRun (
  IN  REQUEST_SENSE_DATA    *SenseData,
  IN  UINTN                 SenseCounts
  )
{
  REQUEST_SENSE_DATA  *SensePtr;
  UINTN               Index;
  BOOLEAN             IsOverRun;

  IsOverRun = FALSE;
  SensePtr  = SenseData;

  for (Index = 0; Index < SenseCounts; Index++) {

    if ((SensePtr->sense_key == SK_NOT_READY) &&
        (SensePtr->addnl_sense_code == ASC_LOGICAL_UNIT_STATUS) &&
        (SensePtr->addnl_sense_code_qualifier == ASCQ_LOGICAL_UNIT_OVERRUN)) {
      IsOverRun = TRUE;
    }

    SensePtr++;
  }

  return IsOverRun;
}
