mirror of https://github.com/acidanthera/audk.git
Sync USB modules with main trunk.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3423 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
d19862fe4f
commit
50fa1b3a86
|
@ -150,10 +150,14 @@ EhcDumpBuf (
|
|||
#define EHC_DEBUG(arg) EhcDebug arg
|
||||
#define EHC_ERROR(arg) EhcError arg
|
||||
#define EHC_DUMP_QH(arg) EhcDumpQh arg
|
||||
#define EHC_DUMP_QTD(arg) EhcDumpQtd arg
|
||||
#define EHC_DUMP_BUF(arg) EhcDumpBuf arg
|
||||
#else
|
||||
#define EHC_DEBUG(arg)
|
||||
#define EHC_ERROR(arg)
|
||||
#define EHC_DUMP_QH(arg)
|
||||
#define EHC_DUMP_QTD(arg)
|
||||
#define EHC_DUMP_BUF(arg)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -771,6 +771,67 @@ EhciDelAllAsyncIntTransfers (
|
|||
}
|
||||
}
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
EhcFlushAsyncIntMap (
|
||||
IN USB2_HC_DEV *Ehc,
|
||||
IN URB *Urb
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Flush data from PCI controller specific address to mapped system
|
||||
memory address.
|
||||
|
||||
Arguments:
|
||||
|
||||
Ehc - The EHCI device
|
||||
Urb - The URB to unmap
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - Success to flush data to mapped system memory
|
||||
EFI_DEVICE_ERROR - Fail to flush data to mapped system memory
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_PHYSICAL_ADDRESS PhyAddr;
|
||||
EFI_PCI_IO_PROTOCOL_OPERATION MapOp;
|
||||
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||
UINTN Len;
|
||||
VOID *Map;
|
||||
|
||||
PciIo = Ehc->PciIo;
|
||||
Len = Urb->DataLen;
|
||||
|
||||
if (Urb->Ep.Direction == EfiUsbDataIn) {
|
||||
MapOp = EfiPciIoOperationBusMasterWrite;
|
||||
} else {
|
||||
MapOp = EfiPciIoOperationBusMasterRead;
|
||||
}
|
||||
|
||||
Status = PciIo->Unmap (PciIo, Urb->DataMap);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
Urb->DataMap = NULL;
|
||||
|
||||
Status = PciIo->Map (PciIo, MapOp, Urb->Data, &Len, &PhyAddr, &Map);
|
||||
if (EFI_ERROR (Status) || (Len != Urb->DataLen)) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
Urb->DataPhy = (VOID *) ((UINTN) PhyAddr);
|
||||
Urb->DataMap = Map;
|
||||
return EFI_SUCCESS;
|
||||
|
||||
ON_ERROR:
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
@ -873,6 +934,7 @@ EhcMoniteAsyncRequests (
|
|||
BOOLEAN Finished;
|
||||
UINT8 *ProcBuf;
|
||||
URB *Urb;
|
||||
EFI_STATUS Status;
|
||||
|
||||
OldTpl = gBS->RaiseTPL (EHC_TPL);
|
||||
Ehc = (USB2_HC_DEV *) Context;
|
||||
|
@ -890,6 +952,15 @@ EhcMoniteAsyncRequests (
|
|||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Flush any PCI posted write transactions from a PCI host
|
||||
// bridge to system memory.
|
||||
//
|
||||
Status = EhcFlushAsyncIntMap (Ehc, Urb);
|
||||
if (EFI_ERROR (Status)) {
|
||||
EHC_ERROR (("EhcMoniteAsyncRequests: Fail to Flush AsyncInt Mapped Memeory\n"));
|
||||
}
|
||||
|
||||
//
|
||||
// Allocate a buffer then copy the transferred data for user.
|
||||
// If failed to allocate the buffer, update the URB for next
|
||||
|
|
|
@ -881,20 +881,52 @@ UsbEnumeratePort (
|
|||
// connect/disconnect. Other three events are: ENABLE, SUSPEND, RESET.
|
||||
// ENABLE/RESET is used to reset port. SUSPEND isn't supported.
|
||||
//
|
||||
Status = EFI_SUCCESS;
|
||||
|
||||
if (USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_OVERCURRENT)) {
|
||||
|
||||
if (USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_OVERCURRENT)) {
|
||||
//
|
||||
// If overcurrent condition is cleared, enable the port again
|
||||
// Both OverCurrent and OverCurrentChange set, means over current occurs,
|
||||
// which probably is caused by short circuit. It has to wait system hardware
|
||||
// to perform recovery.
|
||||
//
|
||||
if (!USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_OVERCURRENT)) {
|
||||
HubApi->SetPortFeature (HubIf, Port, (EFI_USB_PORT_FEATURE) USB_HUB_PORT_POWER);
|
||||
USB_DEBUG (("UsbEnumeratePort: Critical Over Current\n", Port));
|
||||
return EFI_DEVICE_ERROR;
|
||||
|
||||
} else {
|
||||
//
|
||||
// Only OverCurrentChange set, means system has been recoveried from
|
||||
// over current. As a result, all ports are nearly power-off, so
|
||||
// it's necessary to detach and enumerate all ports again.
|
||||
//
|
||||
USB_DEBUG (("UsbEnumeratePort: 2.0 device Recovery Over Current\n", Port));
|
||||
goto ON_ENUMERATE;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} else if (USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_CONNECTION)) {
|
||||
if (USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_ENABLE)) {
|
||||
//
|
||||
// Device connected or disconnected. Either way, if there is
|
||||
// already a device present in the bus, need to remove it.
|
||||
// 1.1 roothub port reg doesn't reflect over-current state, while its counterpart
|
||||
// on 2.0 roothub does. When over-current has influence on 1.1 device, the port
|
||||
// would be disabled, so it's also necessary to detach and enumerate again.
|
||||
//
|
||||
USB_DEBUG (("UsbEnumeratePort: 1.1 device Recovery Over Current\n", Port));
|
||||
goto ON_ENUMERATE;
|
||||
}
|
||||
|
||||
if (USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_CONNECTION)) {
|
||||
//
|
||||
// Device connected or disconnected normally.
|
||||
//
|
||||
goto ON_ENUMERATE;
|
||||
}
|
||||
|
||||
ON_ENUMERATE:
|
||||
|
||||
//
|
||||
// In case there is already a device on this port logically, it's safety to remove
|
||||
// and enumerate again.
|
||||
//
|
||||
Child = UsbFindChild (HubIf, Port);
|
||||
|
||||
|
@ -913,7 +945,6 @@ UsbEnumeratePort (
|
|||
} else {
|
||||
USB_DEBUG (("UsbEnumeratePort: device disconnected event on port %d\n", Port));
|
||||
}
|
||||
}
|
||||
|
||||
HubApi->ClearPortChange (HubIf, Port);
|
||||
return Status;
|
||||
|
|
|
@ -645,11 +645,16 @@ UsbIoGetEndpointDescriptor (
|
|||
|
||||
UsbIf = USB_INTERFACE_FROM_USBIO (This);
|
||||
|
||||
if ((Descriptor == NULL) || (Index >= UsbIf->IfSetting->Desc.NumEndpoints)) {
|
||||
if ((Descriptor == NULL) || (Index > 15)) {
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (Index >= UsbIf->IfSetting->Desc.NumEndpoints) {
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
CopyMem (
|
||||
Descriptor,
|
||||
&(UsbIf->IfSetting->Endpoints[Index]->Desc),
|
||||
|
@ -813,6 +818,11 @@ UsbIoPortReset (
|
|||
UsbIf = USB_INTERFACE_FROM_USBIO (This);
|
||||
Dev = UsbIf->Device;
|
||||
|
||||
if (UsbIf->IsHub == TRUE) {
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
HubIf = Dev->ParentIf;
|
||||
Status = HubIf->HubApi->ResetPort (HubIf, Dev->ParentPort);
|
||||
|
||||
|
@ -875,7 +885,6 @@ EFI_USB_IO_PROTOCOL mUsbIoProtocol = {
|
|||
UsbIoPortReset
|
||||
};
|
||||
|
||||
//@MT: EFI_DRIVER_ENTRY_POINT (UsbBusDriverEntryPoint)
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
|
|
|
@ -26,6 +26,34 @@ Revision History
|
|||
#include "UsbMassImpl.h"
|
||||
|
||||
|
||||
EFI_TPL
|
||||
UsbGetCurrentTpl (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
return the current TPL, copied from the EDKII glue lib.
|
||||
|
||||
Arguments:
|
||||
|
||||
VOID
|
||||
|
||||
Returns:
|
||||
|
||||
Current TPL
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_TPL Tpl;
|
||||
|
||||
Tpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
|
||||
gBS->RestoreTPL (Tpl);
|
||||
|
||||
return Tpl;
|
||||
}
|
||||
|
||||
/**
|
||||
Read an UINT32 from the buffer to avoid byte alignment problems, then
|
||||
convert that to the little endia. The USB mass storage bootability spec
|
||||
|
@ -140,7 +168,7 @@ UsbBootRequestSense (
|
|||
);
|
||||
if (EFI_ERROR (Status) || CmdResult != USB_MASS_CMD_SUCCESS) {
|
||||
DEBUG ((mUsbMscError, "UsbBootRequestSense: (%r) CmdResult=0x%x\n", Status, CmdResult));
|
||||
return EFI_DEVICE_ERROR;
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -151,6 +179,9 @@ UsbBootRequestSense (
|
|||
switch (USB_BOOT_SENSE_KEY (SenseData.SenseKey)) {
|
||||
|
||||
case USB_BOOT_SENSE_NO_SENSE:
|
||||
Status = EFI_NO_RESPONSE;
|
||||
break;
|
||||
|
||||
case USB_BOOT_SENSE_RECOVERED:
|
||||
//
|
||||
// Suppose hardware can handle this case, and recover later by itself
|
||||
|
@ -159,27 +190,13 @@ UsbBootRequestSense (
|
|||
break;
|
||||
|
||||
case USB_BOOT_SENSE_NOT_READY:
|
||||
switch (SenseData.ASC) {
|
||||
case USB_BOOT_ASC_NO_MEDIA:
|
||||
Status = EFI_NO_MEDIA;
|
||||
Media->MediaPresent = FALSE;
|
||||
break;
|
||||
|
||||
case USB_BOOT_ASC_MEDIA_UPSIDE_DOWN:
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
if (SenseData.ASC == USB_BOOT_ASC_NO_MEDIA) {
|
||||
Media->MediaPresent = FALSE;
|
||||
break;
|
||||
|
||||
case USB_BOOT_ASC_NOT_READY:
|
||||
if (SenseData.ASCQ == USB_BOOT_ASCQ_IN_PROGRESS ||
|
||||
SenseData.ASCQ == USB_BOOT_ASCQ_DEVICE_BUSY) {
|
||||
//
|
||||
// Regular timeout, and need retry once more
|
||||
//
|
||||
DEBUG ((mUsbMscInfo, "UsbBootRequestSense: Not ready and need retry once more\n"));
|
||||
Status = EFI_NO_MEDIA;
|
||||
} else if (SenseData.ASC == USB_BOOT_ASC_NOT_READY) {
|
||||
Status = EFI_NOT_READY;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_BOOT_SENSE_ILLEGAL_REQUEST:
|
||||
|
@ -189,14 +206,18 @@ UsbBootRequestSense (
|
|||
case USB_BOOT_SENSE_UNIT_ATTENTION:
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
if (SenseData.ASC == USB_BOOT_ASC_MEDIA_CHANGE) {
|
||||
//
|
||||
// If MediaChange, reset ReadOnly and new MediId
|
||||
//
|
||||
Status = EFI_MEDIA_CHANGED;
|
||||
UsbMass->BlockIoMedia.MediaId++;
|
||||
Media->ReadOnly = FALSE;
|
||||
Media->MediaId++;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_BOOT_SNESE_DATA_PROTECT:
|
||||
Status = EFI_WRITE_PROTECTED;
|
||||
UsbMass->BlockIoMedia.ReadOnly = TRUE;
|
||||
Media->ReadOnly = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -270,6 +291,9 @@ UsbBootExecCmd (
|
|||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
DEBUG ((mUsbMscInfo, "UsbBootExecCmd: Fail to Exec 0x%x Cmd /w %r\n",
|
||||
*(UINT8 *)Cmd ,Status));
|
||||
|
||||
return UsbBootRequestSense (UsbMass);
|
||||
}
|
||||
|
||||
|
@ -417,7 +441,7 @@ UsbBootInquiry (
|
|||
EfiUsbDataIn,
|
||||
&InquiryData,
|
||||
sizeof (USB_BOOT_INQUIRY_DATA),
|
||||
USB_BOOT_INQUIRY_CMD_TIMEOUT
|
||||
USB_BOOT_GENERAL_CMD_TIMEOUT
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
|
@ -485,7 +509,11 @@ UsbBootReadCapacity (
|
|||
Media->LastBlock = UsbBootGetUint32 (CapacityData.LastLba);
|
||||
Media->BlockSize = UsbBootGetUint32 (CapacityData.BlockLen);
|
||||
|
||||
DEBUG ((mUsbMscInfo, "UsbBootReadCapacity Success LBA=%d BlockSize=%d\n",
|
||||
if (Media->BlockSize == 0) {
|
||||
return EFI_NOT_READY;
|
||||
}
|
||||
|
||||
DEBUG ((mUsbMscInfo, "UsbBootReadCapacity Success LBA=%ld BlockSize=%d\n",
|
||||
Media->LastBlock, Media->BlockSize));
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
@ -503,47 +531,49 @@ UsbBootReadCapacity (
|
|||
|
||||
**/
|
||||
EFI_STATUS
|
||||
UsbBootModeSense (
|
||||
UsbScsiModeSense (
|
||||
IN USB_MASS_DEVICE *UsbMass
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
USB_BOOT_MODE_SENSE_CMD ModeSenseCmd;
|
||||
USB_BOOT_MODE_PARA_HEADER ModeParaHeader;
|
||||
UINT8 CommandSet;
|
||||
USB_SCSI_MODE_SENSE6_CMD ModeSenseCmd;
|
||||
USB_SCSI_MODE_SENSE6_PARA_HEADER ModeParaHeader;
|
||||
EFI_BLOCK_IO_MEDIA *Media;
|
||||
|
||||
ZeroMem (&ModeSenseCmd, sizeof (USB_BOOT_MODE_SENSE_CMD));
|
||||
ZeroMem (&ModeParaHeader, sizeof (USB_BOOT_MODE_PARA_HEADER));
|
||||
CopyMem (
|
||||
&Media,
|
||||
&(UsbMass->BlockIoMedia),
|
||||
sizeof (EFI_BLOCK_IO_MEDIA)
|
||||
);
|
||||
|
||||
ZeroMem (&ModeSenseCmd, sizeof (USB_SCSI_MODE_SENSE6_CMD));
|
||||
ZeroMem (&ModeParaHeader, sizeof (USB_SCSI_MODE_SENSE6_PARA_HEADER));
|
||||
|
||||
//
|
||||
// overuse Context Pointer, the first field of Bot or Cbi is EFI_USB_INTERFACE_DESCRIPTOR
|
||||
// ModeSense6 command is defined in [SCSI2Spec-Page151]
|
||||
//
|
||||
CommandSet = ((EFI_USB_INTERFACE_DESCRIPTOR *) (UsbMass->Context))->InterfaceSubClass;
|
||||
|
||||
if (CommandSet == USB_MASS_STORE_SCSI) {
|
||||
//
|
||||
// Not UFI Command Set, no ModeSense Command
|
||||
//
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
ModeSenseCmd.OpCode = USB_BOOT_MODE_SENSE10_OPCODE;
|
||||
ModeSenseCmd.PageCode = 0x3f;
|
||||
ModeSenseCmd.ParaListLenLsb = (UINT8) sizeof (USB_BOOT_MODE_PARA_HEADER);
|
||||
ModeSenseCmd.OpCode = USB_SCSI_MODE_SENSE6_OPCODE;
|
||||
ModeSenseCmd.Lun = USB_BOOT_LUN (UsbMass->Lun);
|
||||
ModeSenseCmd.PageCode = 0x3F;
|
||||
ModeSenseCmd.AllocateLen = (UINT8) sizeof (USB_SCSI_MODE_SENSE6_PARA_HEADER);
|
||||
|
||||
Status = UsbBootExecCmdWithRetry (
|
||||
UsbMass,
|
||||
&ModeSenseCmd,
|
||||
sizeof (USB_BOOT_MODE_SENSE_CMD),
|
||||
sizeof (USB_SCSI_MODE_SENSE6_CMD),
|
||||
EfiUsbDataIn,
|
||||
&ModeParaHeader,
|
||||
sizeof (USB_BOOT_MODE_PARA_HEADER),
|
||||
sizeof (USB_SCSI_MODE_SENSE6_PARA_HEADER),
|
||||
USB_BOOT_GENERAL_CMD_TIMEOUT
|
||||
);
|
||||
|
||||
//
|
||||
// Did nothing with the Header here
|
||||
// But probably should
|
||||
// ModeSense(6) is used to get the information of WriteProtected. While only some of
|
||||
// devices support this command, so have a try here.
|
||||
//
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Media->ReadOnly = (ModeParaHeader.DevicePara & 0x80) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
@ -570,6 +600,15 @@ UsbBootGetParams (
|
|||
{
|
||||
EFI_BLOCK_IO_MEDIA *Media;
|
||||
EFI_STATUS Status;
|
||||
UINT8 CmdSet;
|
||||
|
||||
CopyMem (
|
||||
&Media,
|
||||
&(UsbMass->BlockIoMedia),
|
||||
sizeof (EFI_BLOCK_IO_MEDIA)
|
||||
);
|
||||
|
||||
CmdSet = ((EFI_USB_INTERFACE_DESCRIPTOR *) (UsbMass->Context))->InterfaceSubClass;
|
||||
|
||||
Status = UsbBootInquiry (UsbMass);
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
@ -577,29 +616,30 @@ UsbBootGetParams (
|
|||
return Status;
|
||||
}
|
||||
|
||||
Media = &(UsbMass->BlockIoMedia);
|
||||
//
|
||||
// Don't use the Removable bit in inquirydata to test whether the media
|
||||
// is removable because many flash disks wrongly set this bit.
|
||||
//
|
||||
if ((UsbMass->Pdt == USB_PDT_CDROM) || (UsbMass->Pdt == USB_PDT_OPTICAL)) {
|
||||
//
|
||||
// CD-Rom or Optical device
|
||||
// CD-Rom device and Non-CD optical device
|
||||
//
|
||||
UsbMass->OpticalStorage = TRUE;
|
||||
//
|
||||
// Default value 2048 Bytes, in case no media present at first time
|
||||
//
|
||||
Media->BlockSize = 0x0800;
|
||||
} else {
|
||||
//
|
||||
// Non CD-Rom device need ModeSenseCmd between InquiryCmd and ReadCapacityCmd
|
||||
//
|
||||
Status = UsbBootModeSense (UsbMass);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((mUsbMscError, "UsbBootGetParams: UsbBootModeSense (%r)\n", Status));
|
||||
return Status;
|
||||
}
|
||||
|
||||
if ((UsbMass->Pdt != USB_PDT_CDROM) && (CmdSet == USB_MASS_STORE_SCSI)) {
|
||||
//
|
||||
// ModeSense is required for the device with PDT of 0x00/0x07/0x0E,
|
||||
// which is from [MassStorageBootabilitySpec-Page7].
|
||||
// ModeSense(10) is useless here, while ModeSense(6) defined in SCSI
|
||||
// could get the information of WriteProtected.
|
||||
// Since not all device support this command, so skip if fail.
|
||||
//
|
||||
UsbScsiModeSense (UsbMass);
|
||||
}
|
||||
|
||||
return UsbBootReadCapacity (UsbMass);
|
||||
|
@ -623,6 +663,8 @@ UsbBootDetectMedia (
|
|||
{
|
||||
EFI_BLOCK_IO_MEDIA OldMedia;
|
||||
EFI_BLOCK_IO_MEDIA *Media;
|
||||
UINT8 CmdSet;
|
||||
EFI_TPL OldTpl;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Media = &UsbMass->BlockIoMedia;
|
||||
|
@ -633,54 +675,80 @@ UsbBootDetectMedia (
|
|||
sizeof (EFI_BLOCK_IO_MEDIA)
|
||||
);
|
||||
|
||||
//
|
||||
// First test whether the device is ready and get status
|
||||
// If media changed or ready, need read the device's capacity
|
||||
//
|
||||
CmdSet = ((EFI_USB_INTERFACE_DESCRIPTOR *) (UsbMass->Context))->InterfaceSubClass;
|
||||
|
||||
Status = UsbBootIsUnitReady (UsbMass);
|
||||
if ((Status == EFI_SUCCESS && Media->MediaPresent) ||
|
||||
(Status == EFI_MEDIA_CHANGED)) {
|
||||
if ((UsbMass->Pdt != USB_PDT_CDROM) &&
|
||||
(UsbMass->Pdt != USB_PDT_OPTICAL)) {
|
||||
//
|
||||
// Non CD-Rom device need ModeSenseCmd between InquiryCmd and ReadCapacityCmd
|
||||
//
|
||||
UsbBootModeSense (UsbMass);
|
||||
}
|
||||
DEBUG ((mUsbMscInfo, "UsbBootDetectMedia: Need Read Capacity\n"));
|
||||
Status = UsbBootReadCapacity (UsbMass);
|
||||
}
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
DEBUG ((mUsbMscError, "UsbBootDetectMedia: UsbBootIsUnitReady (%r)\n", Status));
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
if ((UsbMass->Pdt != USB_PDT_CDROM) && (CmdSet == USB_MASS_STORE_SCSI)) {
|
||||
//
|
||||
// ModeSense is required for the device with PDT of 0x00/0x07/0x0E,
|
||||
// which is from [MassStorageBootabilitySpec-Page7].
|
||||
// ModeSense(10) is useless here, while ModeSense(6) defined in SCSI
|
||||
// could get the information of WriteProtected.
|
||||
// Since not all device support this command, so skip if fail.
|
||||
//
|
||||
UsbScsiModeSense (UsbMass);
|
||||
}
|
||||
|
||||
Status = UsbBootReadCapacity (UsbMass);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((mUsbMscError, "UsbBootDetectMedia: UsbBootReadCapacity (%r)\n", Status));
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
||||
ON_ERROR:
|
||||
//
|
||||
// Detect whether it is necessary to reinstall the BlockIO
|
||||
//
|
||||
// MediaId may change in RequestSense for MediaChanged
|
||||
// MediaPresent may change in RequestSense for NoMedia
|
||||
// MediaReadOnly may change in RequestSense for WriteProtected or MediaChanged
|
||||
// MediaPresent/BlockSize/LastBlock may change in ReadCapacity
|
||||
//
|
||||
if ((Media->MediaId != OldMedia.MediaId) ||
|
||||
(Media->MediaPresent != OldMedia.MediaPresent) ||
|
||||
(Media->ReadOnly != OldMedia.ReadOnly) ||
|
||||
(Media->BlockSize != OldMedia.BlockSize) ||
|
||||
(Media->LastBlock != OldMedia.LastBlock)) {
|
||||
DEBUG ((mUsbMscInfo, "UsbBootDetectMedia: Need reinstall BlockIoProtocol\n"));
|
||||
Media->MediaId++;
|
||||
|
||||
OldTpl = UsbGetCurrentTpl ();
|
||||
DEBUG ((mUsbMscError, "UsbBootDetectMedia: TPL before reinstall BlockIoProtocol is %d\n", OldTpl));
|
||||
|
||||
gBS->RestoreTPL (TPL_CALLBACK);
|
||||
|
||||
gBS->ReinstallProtocolInterface (
|
||||
UsbMass->Controller,
|
||||
&gEfiBlockIoProtocolGuid,
|
||||
&UsbMass->BlockIo,
|
||||
&UsbMass->BlockIo
|
||||
);
|
||||
|
||||
DEBUG ((mUsbMscError, "UsbBootDetectMedia: TPL after reinstall is %d\n", UsbGetCurrentTpl()));
|
||||
ASSERT (UsbGetCurrentTpl () == TPL_CALLBACK);
|
||||
|
||||
gBS->RaiseTPL (OldTpl);
|
||||
|
||||
//
|
||||
// Check whether media present or media changed or write protected
|
||||
// Update MediaId after reinstall BLOCK_IO_PROTOCOL
|
||||
//
|
||||
if (Media->MediaPresent == FALSE) {
|
||||
Status = EFI_NO_MEDIA;
|
||||
if (Media->MediaPresent != OldMedia.MediaPresent) {
|
||||
if (Media->MediaPresent == TRUE) {
|
||||
Media->MediaId = 1;
|
||||
} else {
|
||||
Media->MediaId = 0;
|
||||
}
|
||||
if (Media->MediaId != OldMedia.MediaId) {
|
||||
Status = EFI_MEDIA_CHANGED;
|
||||
}
|
||||
if (Media->ReadOnly != OldMedia.ReadOnly) {
|
||||
Status = EFI_WRITE_PROTECTED;
|
||||
|
||||
if ((Media->ReadOnly != OldMedia.ReadOnly) ||
|
||||
(Media->BlockSize != OldMedia.BlockSize) ||
|
||||
(Media->LastBlock != OldMedia.LastBlock)) {
|
||||
Media->MediaId++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -728,13 +796,9 @@ UsbBootReadBlocks (
|
|||
ByteSize = (UINT32)Count * BlockSize;
|
||||
|
||||
//
|
||||
// Optical device need longer timeout than other device
|
||||
// USB command's upper limit timeout is 5s. [USB2.0-9.2.6.1]
|
||||
//
|
||||
if (UsbMass->OpticalStorage == TRUE) {
|
||||
Timeout = (UINT32)Count * USB_BOOT_OPTICAL_BLOCK_TIMEOUT;
|
||||
} else {
|
||||
Timeout = (UINT32)Count * USB_BOOT_GENERAL_BLOCK_TIMEOUT;
|
||||
}
|
||||
Timeout = (UINT32) USB_BOOT_GENERAL_CMD_TIMEOUT;
|
||||
|
||||
//
|
||||
// Fill in the command then execute
|
||||
|
@ -808,13 +872,9 @@ UsbBootWriteBlocks (
|
|||
ByteSize = (UINT32)Count * BlockSize;
|
||||
|
||||
//
|
||||
// Optical device need longer timeout than other device
|
||||
// USB command's upper limit timeout is 5s. [USB2.0-9.2.6.1]
|
||||
//
|
||||
if (UsbMass->OpticalStorage == TRUE) {
|
||||
Timeout = (UINT32)Count * USB_BOOT_OPTICAL_BLOCK_TIMEOUT;
|
||||
} else {
|
||||
Timeout = (UINT32)Count * USB_BOOT_GENERAL_BLOCK_TIMEOUT;
|
||||
}
|
||||
Timeout = (UINT32) USB_BOOT_GENERAL_CMD_TIMEOUT;
|
||||
|
||||
//
|
||||
// Fill in the write10 command block
|
||||
|
|
|
@ -39,11 +39,13 @@ enum {
|
|||
USB_BOOT_INQUIRY_OPCODE = 0x12,
|
||||
USB_BOOT_REQUEST_SENSE_OPCODE = 0x03,
|
||||
|
||||
USB_BOOT_MODE_SENSE10_OPCODE = 0x5a,
|
||||
USB_BOOT_MODE_SENSE10_OPCODE = 0x5A,
|
||||
USB_BOOT_READ_CAPACITY_OPCODE = 0x25,
|
||||
USB_BOOT_TEST_UNIT_READY_OPCODE = 0x00,
|
||||
USB_BOOT_READ10_OPCODE = 0x28,
|
||||
USB_BOOT_WRITE10_OPCODE = 0x2a,
|
||||
USB_BOOT_WRITE10_OPCODE = 0x2A,
|
||||
|
||||
USB_SCSI_MODE_SENSE6_OPCODE = 0x1A,
|
||||
|
||||
//
|
||||
// The Sense Key part of the sense data. Sense data has three levels:
|
||||
|
@ -64,13 +66,9 @@ enum {
|
|||
USB_BOOT_SENSE_MISCOMPARE = 0x0E, // Source data mis-match while verfying.
|
||||
|
||||
USB_BOOT_ASC_NOT_READY = 0x04,
|
||||
USB_BOOT_ASC_MEDIA_UPSIDE_DOWN = 0x06,
|
||||
USB_BOOT_ASC_NO_MEDIA = 0x3A,
|
||||
USB_BOOT_ASC_MEDIA_CHANGE = 0x28,
|
||||
|
||||
USB_BOOT_ASCQ_IN_PROGRESS = 0x01,
|
||||
USB_BOOT_ASCQ_DEVICE_BUSY = 0xFF,
|
||||
|
||||
//
|
||||
// Other parameters
|
||||
//
|
||||
|
@ -90,10 +88,12 @@ enum {
|
|||
//
|
||||
// Boot Transfer timeout
|
||||
//
|
||||
USB_BOOT_GENERAL_BLOCK_TIMEOUT = 200 * USB_MASS_STALL_1_MS,
|
||||
USB_BOOT_OPTICAL_BLOCK_TIMEOUT = 1 * USB_MASS_STALL_1_S,
|
||||
USB_BOOT_GENERAL_CMD_TIMEOUT = 1 * USB_MASS_STALL_1_S,
|
||||
USB_BOOT_INQUIRY_CMD_TIMEOUT = 3 * USB_MASS_STALL_1_S,
|
||||
// USB2.0 Spec define the up-limit timeout 5s for all command. USB floppy,
|
||||
// USB CD-Rom and iPod devices are much slower than USB key when reponse
|
||||
// most of commands, So we set 5s as timeout here.
|
||||
//
|
||||
//
|
||||
USB_BOOT_GENERAL_CMD_TIMEOUT = 5 * USB_MASS_STALL_1_S,
|
||||
|
||||
//
|
||||
// Supported PDT codes, or Peripheral Device Type
|
||||
|
@ -159,7 +159,7 @@ typedef struct {
|
|||
UINT8 ParaListLenLsb;
|
||||
UINT8 Reserved1;
|
||||
UINT8 Pad[2];
|
||||
} USB_BOOT_MODE_SENSE_CMD;
|
||||
} USB_BOOT_MODE_SENSE10_CMD;
|
||||
|
||||
typedef struct {
|
||||
UINT8 ModeDataLenMsb;
|
||||
|
@ -167,7 +167,7 @@ typedef struct {
|
|||
UINT8 Reserved0[4];
|
||||
UINT8 BlkDesLenMsb;
|
||||
UINT8 BlkDesLenLsb;
|
||||
} USB_BOOT_MODE_PARA_HEADER;
|
||||
} USB_BOOT_MODE_SENSE10_PARA_HEADER;
|
||||
|
||||
typedef struct {
|
||||
UINT8 OpCode;
|
||||
|
@ -209,6 +209,22 @@ typedef struct {
|
|||
UINT8 ASCQ; // Additional Sense Code Qualifier
|
||||
UINT8 Reserverd2[4];
|
||||
} USB_BOOT_REQUEST_SENSE_DATA;
|
||||
|
||||
typedef struct {
|
||||
UINT8 OpCode;
|
||||
UINT8 Lun;
|
||||
UINT8 PageCode;
|
||||
UINT8 Reserved0;
|
||||
UINT8 AllocateLen;
|
||||
UINT8 Control;
|
||||
} USB_SCSI_MODE_SENSE6_CMD;
|
||||
|
||||
typedef struct {
|
||||
UINT8 ModeDataLen;
|
||||
UINT8 MediumType;
|
||||
UINT8 DevicePara;
|
||||
UINT8 BlkDesLen;
|
||||
} USB_SCSI_MODE_SENSE6_PARA_HEADER;
|
||||
#pragma pack()
|
||||
|
||||
//
|
||||
|
|
Loading…
Reference in New Issue