⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbmassstoragehelper.c

📁 Next BIOS Source code : Extensible Firmware Interface
💻 C
📖 第 1 页 / 共 3 页
字号:
          UsbFloppyModeSense1C (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)) {          
        RetryTimes ++ ;     // retry once more
        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
UsbFloppyModeSense5 (
  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:  

--*/         
{ 
  //
  // status returned by Read Capacity Packet Command
  //
  EFI_STATUS                Status;       
  ATAPI_PACKET_COMMAND      Packet;
  EFI_USB_ATAPI_PROTOCOL    *UsbAtapiInterface;
  MODE_PARAMETER_PAGE_5     ModePage5;
  EFI_LBA                   LastBlock;
  UINT32                    SectorsPerTrack;
  UINT32                    NumberOfCylinders;
  UINT32                    NumberOfHeads;
  UINT32                    DataBytesPerSector;
  
  UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;
  
  EfiZeroMem (&ModePage5,sizeof(MODE_PARAMETER_PAGE_5));
  
  EfiZeroMem (&Packet,sizeof(ATAPI_PACKET_COMMAND));
  Packet.ModeSense.opcode = MODE_SENSE ;
  Packet.ModeSense.page_code = 5 ;    // Flexible Disk Page
  Packet.ModeSense.page_control = 0;  // current values
  Packet.ModeSense.parameter_list_length_hi = 0;
  Packet.ModeSense.parameter_list_length_lo = sizeof (MODE_PARAMETER_PAGE_5); 
  Status = USBFloppyPacketCommand (UsbFloppyDevice, 
                                    &Packet,
                                    sizeof(ATAPI_PACKET_COMMAND),
                                    (VOID *)&ModePage5, 
                                    sizeof(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
UsbFloppyModeSense1C (
  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:  

--*/         
{ 
  //
  // status returned by Read Capacity Packet Command
  //
  EFI_STATUS                Status;       
  ATAPI_PACKET_COMMAND      Packet;
  EFI_USB_ATAPI_PROTOCOL    *UsbAtapiInterface;
  MODE_PARAMETER_PAGE_1C    ModePage1C;
  
  UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;
  
  EfiZeroMem (&ModePage1C,sizeof(MODE_PARAMETER_PAGE_1C));
  
  EfiZeroMem (&Packet,sizeof(ATAPI_PACKET_COMMAND));
  Packet.ModeSense.opcode = MODE_SENSE ;
  Packet.ModeSense.page_code = 0x1C;    // Flexible Disk Page
  Packet.ModeSense.page_control = 0;  // current values
  Packet.ModeSense.parameter_list_length_hi = 0;
  Packet.ModeSense.parameter_list_length_lo = sizeof (MODE_PARAMETER_PAGE_1C); 
  Status = USBFloppyPacketCommand (UsbFloppyDevice, 
                                    &Packet,
                                    sizeof(ATAPI_PACKET_COMMAND),
                                    (VOID *)&ModePage1C, 
                                    sizeof(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 ;

}



/*++

  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:  // fall through
          case ASC_MEDIA_ERR2:  // fall through
          case ASC_MEDIA_ERR3:  // fall through
          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 + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -