usbmassstoragehelper.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,603 行 · 第 1/3 页

C
1,603
字号
  }

  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;

  EfiZeroMem (&ModePage5, sizeof (UFI_MODE_PARAMETER_PAGE_5));

  EfiZeroMem (&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;

  EfiZeroMem (&ModePage1C, sizeof (UFI_MODE_PARAMETER_PAGE_1C));

  EfiZeroMem (&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);

  EfiZeroMem (&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);

  EfiZeroMem (&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;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?