📄 usbmassstoragehelper.c
字号:
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 + -